Add starting point for IGLOO2 RISV-V demo project.
diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/.cproject b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/.cproject
new file mode 100644
index 0000000..c1655cf
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/.cproject
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>

+<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">

+	<storageModule moduleId="org.eclipse.cdt.core.settings">

+		<cconfiguration id="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.debug.2049051127">

+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.debug.2049051127" moduleId="org.eclipse.cdt.core.settings" name="Debug">

+				<externalSettings/>

+				<extensions>

+					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>

+					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>

+					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>

+					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>

+					<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>

+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>

+				</extensions>

+			</storageModule>

+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">

+				<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="${cross_rm} -rf" description="" errorParsers="org.eclipse.cdt.core.GASErrorParser;org.eclipse.cdt.core.GmakeErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.CWDLocator;org.eclipse.cdt.core.GCCErrorParser" id="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.debug.2049051127" name="Debug" parent="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.debug" postannouncebuildStep="" postbuildStep="" preannouncebuildStep="" prebuildStep="">

+					<folderInfo id="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.debug.2049051127." name="/" resourcePath="">

+						<toolChain errorParsers="" id="ilg.gnumcueclipse.managedbuild.cross.riscv.toolchain.elf.debug.1135421195" name="RISC-V Cross GCC" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.toolchain.elf.debug">

+							<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createflash.1236561658" name="Create flash image" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createflash" useByScannerDiscovery="false" value="true" valueType="boolean"/>

+							<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createlisting.197330232" name="Create extended listing" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createlisting" useByScannerDiscovery="false" value="true" valueType="boolean"/>

+							<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.printsize.306588546" name="Print size" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.printsize" useByScannerDiscovery="false" value="true" valueType="boolean"/>

+							<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.level.1940053873" name="Optimization Level" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.level" useByScannerDiscovery="true" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.level.none" valueType="enumerated"/>

+							<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.messagelength.565243439" name="Message length (-fmessage-length=0)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.messagelength" useByScannerDiscovery="true" value="true" valueType="boolean"/>

+							<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.signedchar.321222073" name="'char' is signed (-fsigned-char)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.signedchar" useByScannerDiscovery="true" value="true" valueType="boolean"/>

+							<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.functionsections.1177210712" name="Function sections (-ffunction-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.functionsections" useByScannerDiscovery="true" value="true" valueType="boolean"/>

+							<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.datasections.1159308156" name="Data sections (-fdata-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.datasections" useByScannerDiscovery="true" value="true" valueType="boolean"/>

+							<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.level.400131419" name="Debug level" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.level" useByScannerDiscovery="true" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.level.max" valueType="enumerated"/>

+							<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.format.227460743" name="Debug format" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.format" useByScannerDiscovery="true"/>

+							<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.name.39106845" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.name" useByScannerDiscovery="false" value="RISC-V GCC/Newlib" valueType="string"/>

+							<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.prefix.975904647" name="Prefix" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.prefix" useByScannerDiscovery="false" value="riscv64-unknown-elf-" valueType="string"/>

+							<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.c.629106139" name="C compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.c" useByScannerDiscovery="false" value="gcc" valueType="string"/>

+							<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.cpp.700052137" name="C++ compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.cpp" useByScannerDiscovery="false" value="g++" valueType="string"/>

+							<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.ar.1315168450" name="Archiver" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.ar" useByScannerDiscovery="false" value="ar" valueType="string"/>

+							<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objcopy.729800518" name="Hex/Bin converter" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objcopy" useByScannerDiscovery="false" value="objcopy" valueType="string"/>

+							<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objdump.1799678707" name="Listing generator" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objdump" useByScannerDiscovery="false" value="objdump" valueType="string"/>

+							<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.size.2116391716" name="Size command" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.size" useByScannerDiscovery="false" value="size" valueType="string"/>

+							<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.make.323254382" name="Build command" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.make" useByScannerDiscovery="false" value="make" valueType="string"/>

+							<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.rm.1360582657" name="Remove command" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.rm" useByScannerDiscovery="false" value="rm" valueType="string"/>

+							<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.base.1725087349" name="Architecture" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.base" useByScannerDiscovery="false" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.arch.rv32i" valueType="enumerated"/>

+							<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.multiply.1573871360" name="Multiply extension (RVM)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.multiply" useByScannerDiscovery="false" value="true" valueType="boolean"/>

+							<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.abi.integer.957415439" name="Integer ABI" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.abi.integer" useByScannerDiscovery="false" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.abi.integer.ilp32" valueType="enumerated"/>

+							<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="ilg.gnumcueclipse.managedbuild.cross.riscv.targetPlatform.1851994667" isAbstract="false" osList="all" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.targetPlatform"/>

+							<builder buildPath="${workspace_loc:/miv-rv32im-freertos-port-test}/Debug" errorParsers="org.eclipse.cdt.core.GmakeErrorParser;org.eclipse.cdt.core.CWDLocator" id="ilg.gnumcueclipse.managedbuild.cross.riscv.builder.1748717066" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.builder"/>

+							<tool command="${cross_prefix}${cross_c}${cross_suffix}" commandLinePattern="${COMMAND} ${cross_toolchain_flags} ${FLAGS} -c ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}" errorParsers="org.eclipse.cdt.core.GASErrorParser;org.eclipse.cdt.core.GCCErrorParser" id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.1205277158" name="GNU RISC-V Cross Assembler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler">

+								<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.assembler.usepreprocessor.1853992692" name="Use preprocessor" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.assembler.usepreprocessor" useByScannerDiscovery="false" value="true" valueType="boolean"/>

+								<inputType id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.input.1786331150" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.input"/>

+							</tool>

+							<tool command="${cross_prefix}${cross_c}${cross_suffix}" commandLinePattern="${COMMAND} ${cross_toolchain_flags} ${FLAGS} -c ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}" errorParsers="org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.GCCErrorParser" id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.894708922" name="GNU RISC-V Cross C Compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler">

+								<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.include.paths.1818715770" name="Include paths (-I)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.include.paths" useByScannerDiscovery="true" valueType="includePath">

+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/FreeRTOS_Source/include}&quot;"/>

+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/FreeRTOS_Source/portable/ThirdParty/GCC/RISC-V}&quot;"/>

+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}&quot;"/>

+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/drivers/CoreGPIO}&quot;"/>

+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/drivers/Core16550}&quot;"/>

+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/drivers/CoreUARTapb}&quot;"/>

+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/drivers/CoreTimer}&quot;"/>

+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/drivers/CoreSPI}&quot;"/>

+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/hal}&quot;"/>

+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/riscv_hal}&quot;"/>

+								</option>

+								<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.defs.43291576" name="Defined symbols (-D)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.defs" useByScannerDiscovery="true" valueType="definedSymbols">

+									<listOptionValue builtIn="false" value="MSCC_STDIO_THRU_CORE_UART_APB"/>

+								</option>

+								<inputType id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input.1901773760" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input"/>

+							</tool>

+							<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.compiler.1713474071" name="GNU RISC-V Cross C++ Compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.compiler"/>

+							<tool command="${cross_prefix}${cross_c}${cross_suffix}" commandLinePattern="${COMMAND} ${cross_toolchain_flags} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}" errorParsers="" id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.linker.209069143" name="GNU RISC-V Cross C Linker" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.linker">

+								<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.gcsections.991946343" name="Remove unused sections (-Xlinker --gc-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.gcsections" useByScannerDiscovery="false" value="true" valueType="boolean"/>

+								<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.scriptfile.746597241" name="Script files (-T)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.scriptfile" useByScannerDiscovery="false" valueType="stringList">

+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/riscv_hal/microsemi-riscv-ram.ld}&quot;"/>

+								</option>

+								<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.nostart.1750314954" name="Do not use standard start files (-nostartfiles)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.nostart" useByScannerDiscovery="false" value="true" valueType="boolean"/>

+								<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.usenewlibnano.991677097" name="Use newlib-nano (--specs=nano.specs)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.usenewlibnano" useByScannerDiscovery="false" value="true" valueType="boolean"/>

+								<inputType id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.linker.input.314001493" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.linker.input">

+									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>

+									<additionalInput kind="additionalinput" paths="$(LIBS)"/>

+								</inputType>

+							</tool>

+							<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.linker.1999185643" name="GNU RISC-V Cross C++ Linker" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.linker">

+								<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.gcsections.1490980679" name="Remove unused sections (-Xlinker --gc-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.gcsections" value="true" valueType="boolean"/>

+								<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.scriptfile.1026577013" name="Script files (-T)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.scriptfile" valueType="stringList">

+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/riscv_hal/microsemi-riscv-ram.ld}&quot;"/>

+								</option>

+								<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.nostart.1240127315" name="Do not use standard start files (-nostartfiles)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.nostart" value="true" valueType="boolean"/>

+								<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.usenewlibnano.89628615" name="Use newlib-nano (--specs=nano.specs)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.usenewlibnano" value="true" valueType="boolean"/>

+							</tool>

+							<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.archiver.690189418" name="GNU RISC-V Cross Archiver" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.archiver"/>

+							<tool command="${cross_prefix}${cross_objcopy}${cross_suffix}" commandLinePattern="${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT}" errorParsers="" id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createflash.1183225084" name="GNU RISC-V Cross Create Flash Image" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createflash"/>

+							<tool command="${cross_prefix}${cross_objdump}${cross_suffix}" commandLinePattern="${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT}" errorParsers="" id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createlisting.876462403" name="GNU RISC-V Cross Create Listing" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createlisting">

+								<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.source.1650627599" name="Display source (--source|-S)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.source" useByScannerDiscovery="false" value="true" valueType="boolean"/>

+								<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.allheaders.1290189840" name="Display all headers (--all-headers|-x)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.allheaders" useByScannerDiscovery="false" value="true" valueType="boolean"/>

+								<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.demangle.1153388295" name="Demangle names (--demangle|-C)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.demangle" useByScannerDiscovery="false" value="true" valueType="boolean"/>

+								<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.linenumbers.59828896" name="Display line numbers (--line-numbers|-l)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.linenumbers" useByScannerDiscovery="false" value="true" valueType="boolean"/>

+								<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.wide.2003727408" name="Wide lines (--wide|-w)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.wide" useByScannerDiscovery="false" value="true" valueType="boolean"/>

+							</tool>

+							<tool command="${cross_prefix}${cross_size}${cross_suffix}" commandLinePattern="${COMMAND} ${FLAGS}" errorParsers="" id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.printsize.1868273119" name="GNU RISC-V Cross Print Size" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.printsize">

+								<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.printsize.format.1198877735" name="Size format" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.printsize.format" useByScannerDiscovery="false"/>

+							</tool>

+						</toolChain>

+					</folderInfo>

+					<sourceEntries>

+						<entry excluding="FreeRTOS/portable/MemMang/heap_5.c|FreeRTOS/portable/MemMang/heap_4.c|FreeRTOS/portable/MemMang/heap_3.c|FreeRTOS/portable/MemMang/heap_1.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>

+					</sourceEntries>

+				</configuration>

+			</storageModule>

+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>

+		</cconfiguration>

+	</storageModule>

+	<storageModule moduleId="cdtBuildSystem" version="4.0.0">

+		<project id="miv-rv32im-freertos-port-test.ilg.gnumcueclipse.managedbuild.cross.riscv.target.elf.1563732131" name="Executable" projectType="ilg.gnumcueclipse.managedbuild.cross.riscv.target.elf"/>

+	</storageModule>

+	<storageModule moduleId="scannerConfiguration">

+		<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>

+		<scannerConfigBuildInfo instanceId="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release.1785100359;ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release.1785100359.;ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.1642196096;ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input.702511061">

+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>

+		</scannerConfigBuildInfo>

+		<scannerConfigBuildInfo instanceId="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.debug.2049051127;ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.debug.2049051127.;ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.894708922;ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input.1901773760">

+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>

+		</scannerConfigBuildInfo>

+	</storageModule>

+	<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>

+	<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>

+	<storageModule moduleId="refreshScope"/>

+</cproject>

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/.project b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/.project
new file mode 100644
index 0000000..f7313f5
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/.project
@@ -0,0 +1,162 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<projectDescription>

+	<name>RTOSDemo</name>

+	<comment></comment>

+	<projects>

+	</projects>

+	<buildSpec>

+		<buildCommand>

+			<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>

+			<triggers>clean,full,incremental,</triggers>

+			<arguments>

+			</arguments>

+		</buildCommand>

+		<buildCommand>

+			<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>

+			<triggers>full,incremental,</triggers>

+			<arguments>

+			</arguments>

+		</buildCommand>

+	</buildSpec>

+	<natures>

+		<nature>org.eclipse.cdt.core.cnature</nature>

+		<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>

+		<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>

+	</natures>

+	<linkedResources>

+		<link>

+			<name>FreeRTOS_Source</name>

+			<type>2</type>

+			<locationURI>FREERTOS_ROOT/FreeRTOS/Source</locationURI>

+		</link>

+	</linkedResources>

+	<filteredResources>

+		<filter>

+			<id>1529524430510</id>

+			<name>FreeRTOS_Source</name>

+			<type>9</type>

+			<matcher>

+				<id>org.eclipse.ui.ide.multiFilter</id>

+				<arguments>1.0-name-matches-false-false-include</arguments>

+			</matcher>

+		</filter>

+		<filter>

+			<id>1529524430514</id>

+			<name>FreeRTOS_Source</name>

+			<type>9</type>

+			<matcher>

+				<id>org.eclipse.ui.ide.multiFilter</id>

+				<arguments>1.0-name-matches-false-false-portable</arguments>

+			</matcher>

+		</filter>

+		<filter>

+			<id>1529524430518</id>

+			<name>FreeRTOS_Source</name>

+			<type>5</type>

+			<matcher>

+				<id>org.eclipse.ui.ide.multiFilter</id>

+				<arguments>1.0-name-matches-false-false-event_groups.c</arguments>

+			</matcher>

+		</filter>

+		<filter>

+			<id>1529524430521</id>

+			<name>FreeRTOS_Source</name>

+			<type>5</type>

+			<matcher>

+				<id>org.eclipse.ui.ide.multiFilter</id>

+				<arguments>1.0-name-matches-false-false-list.c</arguments>

+			</matcher>

+		</filter>

+		<filter>

+			<id>1529524430525</id>

+			<name>FreeRTOS_Source</name>

+			<type>5</type>

+			<matcher>

+				<id>org.eclipse.ui.ide.multiFilter</id>

+				<arguments>1.0-name-matches-false-false-queue.c</arguments>

+			</matcher>

+		</filter>

+		<filter>

+			<id>1529524430529</id>

+			<name>FreeRTOS_Source</name>

+			<type>5</type>

+			<matcher>

+				<id>org.eclipse.ui.ide.multiFilter</id>

+				<arguments>1.0-name-matches-false-false-stream_buffer.c</arguments>

+			</matcher>

+		</filter>

+		<filter>

+			<id>1529524430533</id>

+			<name>FreeRTOS_Source</name>

+			<type>5</type>

+			<matcher>

+				<id>org.eclipse.ui.ide.multiFilter</id>

+				<arguments>1.0-name-matches-false-false-tasks.c</arguments>

+			</matcher>

+		</filter>

+		<filter>

+			<id>1529524430538</id>

+			<name>FreeRTOS_Source</name>

+			<type>5</type>

+			<matcher>

+				<id>org.eclipse.ui.ide.multiFilter</id>

+				<arguments>1.0-name-matches-false-false-timers.c</arguments>

+			</matcher>

+		</filter>

+		<filter>

+			<id>1529524475525</id>

+			<name>FreeRTOS_Source/portable</name>

+			<type>9</type>

+			<matcher>

+				<id>org.eclipse.ui.ide.multiFilter</id>

+				<arguments>1.0-name-matches-false-false-ThirdParty</arguments>

+			</matcher>

+		</filter>

+		<filter>

+			<id>1529524475530</id>

+			<name>FreeRTOS_Source/portable</name>

+			<type>9</type>

+			<matcher>

+				<id>org.eclipse.ui.ide.multiFilter</id>

+				<arguments>1.0-name-matches-false-false-MemMang</arguments>

+			</matcher>

+		</filter>

+		<filter>

+			<id>1529524494421</id>

+			<name>FreeRTOS_Source/portable/MemMang</name>

+			<type>5</type>

+			<matcher>

+				<id>org.eclipse.ui.ide.multiFilter</id>

+				<arguments>1.0-name-matches-false-false-heap_4.c</arguments>

+			</matcher>

+		</filter>

+		<filter>

+			<id>1529524515837</id>

+			<name>FreeRTOS_Source/portable/ThirdParty</name>

+			<type>9</type>

+			<matcher>

+				<id>org.eclipse.ui.ide.multiFilter</id>

+				<arguments>1.0-name-matches-false-false-GCC</arguments>

+			</matcher>

+		</filter>

+		<filter>

+			<id>1529524627661</id>

+			<name>FreeRTOS_Source/portable/ThirdParty/GCC</name>

+			<type>9</type>

+			<matcher>

+				<id>org.eclipse.ui.ide.multiFilter</id>

+				<arguments>1.0-name-matches-false-false-RISC-V</arguments>

+			</matcher>

+		</filter>

+	</filteredResources>

+	<variableList>

+		<variable>

+			<name>FREERTOS_ROOT</name>

+			<value>$%7BPARENT-3-PROJECT_LOC%7D</value>

+		</variable>

+		<variable>

+			<name>copy_PARENT</name>

+			<value>$%7BPARENT-4-PROJECT_LOC%7D/FreeRTOS/WorkingCopy/FreeRTOS</value>

+		</variable>

+	</variableList>

+</projectDescription>

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/.settings/language.settings.xml b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/.settings/language.settings.xml
new file mode 100644
index 0000000..6dc13a6
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/.settings/language.settings.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>

+<project>

+	<configuration id="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.debug.2049051127" name="Debug">

+		<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">

+			<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>

+			<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>

+			<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>

+			<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="886405286544253612" id="ilg.gnumcueclipse.managedbuild.cross.riscv.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT RISC-V Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">

+				<language-scope id="org.eclipse.cdt.core.gcc"/>

+				<language-scope id="org.eclipse.cdt.core.g++"/>

+			</provider>

+		</extension>

+	</configuration>

+</project>

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/FreeRTOSConfig.h b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/FreeRTOSConfig.h
new file mode 100644
index 0000000..0cd797d
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/FreeRTOSConfig.h
@@ -0,0 +1,151 @@
+/*

+    FreeRTOS V8.2.3 - Copyright (C) 2015 Real Time Engineers Ltd.

+    All rights reserved

+

+    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

+

+    This file is part of the FreeRTOS distribution.

+

+    FreeRTOS is free software; you can redistribute it and/or modify it under

+    the terms of the GNU General Public License (version 2) as published by the

+    Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.

+

+    ***************************************************************************

+    >>!   NOTE: The modification to the GPL is included to allow you to     !<<

+    >>!   distribute a combined work that includes FreeRTOS without being   !<<

+    >>!   obliged to provide the source code for proprietary components     !<<

+    >>!   outside of the FreeRTOS kernel.                                   !<<

+    ***************************************************************************

+

+    FreeRTOS 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.  Full license text is available on the following

+    link: http://www.freertos.org/a00114.html

+

+    ***************************************************************************

+     *                                                                       *

+     *    FreeRTOS provides completely free yet professionally developed,    *

+     *    robust, strictly quality controlled, supported, and cross          *

+     *    platform software that is more than just the market leader, it     *

+     *    is the industry's de facto standard.                               *

+     *                                                                       *

+     *    Help yourself get started quickly while simultaneously helping     *

+     *    to support the FreeRTOS project by purchasing a FreeRTOS           *

+     *    tutorial book, reference manual, or both:                          *

+     *    http://www.FreeRTOS.org/Documentation                              *

+     *                                                                       *

+    ***************************************************************************

+

+    http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading

+    the FAQ page "My application does not run, what could be wrong?".  Have you

+    defined configASSERT()?

+

+    http://www.FreeRTOS.org/support - In return for receiving this top quality

+    embedded software for free we request you assist our global community by

+    participating in the support forum.

+

+    http://www.FreeRTOS.org/training - Investing in training allows your team to

+    be as productive as possible as early as possible.  Now you can receive

+    FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers

+    Ltd, and the world's leading authority on the world's leading RTOS.

+

+    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,

+    including FreeRTOS+Trace - an indispensable productivity tool, a DOS

+    compatible FAT file system, and our tiny thread aware UDP/IP stack.

+

+    http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.

+    Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.

+

+    http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High

+    Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS

+    licenses offer ticketed support, indemnification and commercial middleware.

+

+    http://www.SafeRTOS.com - High Integrity Systems also provide a safety

+    engineered and independently SIL3 certified version for use in safety and

+    mission critical applications that require provable dependability.

+

+    1 tab == 4 spaces!

+*/

+

+

+#ifndef FREERTOS_CONFIG_H

+#define FREERTOS_CONFIG_H

+

+

+/*-----------------------------------------------------------

+ * Application specific definitions.

+ *

+ * These definitions should be adjusted for your particular hardware and

+ * application requirements.

+ *

+ * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE

+ * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.

+ *

+ * See http://www.freertos.org/a00110.html.

+ *----------------------------------------------------------*/

+

+#include <stdint.h>

+#include <string.h>

+#include "riscv_plic.h"

+

+extern uint32_t SystemCoreClock;

+

+#define configUSE_PREEMPTION			1

+#define configUSE_IDLE_HOOK				1

+#define configUSE_TICK_HOOK				0

+#define configCPU_CLOCK_HZ			( ( unsigned long ) 83000000 )

+#define configTICK_RATE_HZ			( ( TickType_t ) 1000 )

+#define configMAX_PRIORITIES		( 5 )

+#define configMINIMAL_STACK_SIZE	( ( unsigned short ) 1024 )

+#define configTOTAL_HEAP_SIZE		( ( size_t ) ( 100 * 1024 ) )

+#define configMAX_TASK_NAME_LEN			( 16 )

+#define configUSE_TRACE_FACILITY		1

+#define configUSE_16_BIT_TICKS			0

+#define configIDLE_SHOULD_YIELD			1

+#define configUSE_MUTEXES				1

+#define configQUEUE_REGISTRY_SIZE		8

+#define configCHECK_FOR_STACK_OVERFLOW	0 //2

+#define configUSE_RECURSIVE_MUTEXES		1

+#define configUSE_MALLOC_FAILED_HOOK	1

+#define configUSE_APPLICATION_TASK_TAG	0

+#define configUSE_COUNTING_SEMAPHORES	1

+#define configGENERATE_RUN_TIME_STATS	0

+

+/* Co-routine definitions. */

+#define configUSE_CO_ROUTINES 			0

+#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )

+

+/* Software timer definitions. */

+#define configUSE_TIMERS				0

+#define configTIMER_TASK_PRIORITY		( 2 )

+#define configTIMER_QUEUE_LENGTH		2

+#define configTIMER_TASK_STACK_DEPTH	( configMINIMAL_STACK_SIZE )

+

+/* Task priorities.  Allow these to be overridden. */

+#ifndef uartPRIMARY_PRIORITY

+	#define uartPRIMARY_PRIORITY		( configMAX_PRIORITIES - 3 )

+#endif

+

+/* Set the following definitions to 1 to include the API function, or zero

+to exclude the API function. */

+#define INCLUDE_vTaskPrioritySet		1

+#define INCLUDE_uxTaskPriorityGet		1

+#define INCLUDE_vTaskDelete				1

+#define INCLUDE_vTaskCleanUpResources	1

+#define INCLUDE_vTaskSuspend			1

+#define INCLUDE_vTaskDelayUntil			1

+#define INCLUDE_vTaskDelay				1

+#define INCLUDE_eTaskGetState			1

+

+/* Normal assert() semantics without relying on the provision of an assert.h

+header file. */

+#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }

+

+/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS

+standard names - or at least those used in the unmodified vector table. */

+#define vPortSVCHandler SVCall_Handler

+#define xPortPendSVHandler PendSV_Handler

+#define vPortSysTickHandler SysTick_Handler

+

+extern void vApplicationMallocFailedHook();

+#endif /* FREERTOS_CONFIG_H */

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/README.md b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/README.md
new file mode 100644
index 0000000..211d246
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/README.md
@@ -0,0 +1,48 @@
+## FreeRTOS port for Mi-V Soft Processor

+

+### HW Platform and FPGA design:

+This project is tested on following hardware platforms:

+

+RISCV-Creative-Board

+- [RISC-V Creative board Mi-V Sample Design](https://github.com/RISCV-on-Microsemi-FPGA/RISC-V-Creative-Board/tree/master/Programming_The_Target_Device/PROC_SUBSYSTEM_MIV_RV32IMA_BaseDesign)

+

+PolarFire-Eval-Kit

+- [PolarFire Eval Kit RISC-V Sample Design](https://github.com/RISCV-on-Microsemi-FPGA/PolarFire-Eval-Kit/tree/master/Programming_The_Target_Device/MIV_RV32IMA_L1_AHB_BaseDesign)

+

+SmartFusion2-Advanced-Dev-Kit

+- [SmartFusion2 Advanced Development Kit RISC-V Sample Design](https://github.com/RISCV-on-Microsemi-FPGA/SmartFusion2-Advanced-Dev-Kit/tree/master/Programming_The_Target_Device/PROC_SUBSYSTEM_BaseDesign)

+

+### How to run the FreeRTOS RISC-V port:

+To know how to use the SoftConsole workspace, please refer the [Readme.md](https://github.com/RISCV-on-Microsemi-FPGA/SoftConsole/blob/master/README.md)

+

+The miv-rv32im-freertos-port-test is a self contained project. This project demonstrates 

+the FreeRTOS running with Microsemi RISC-V processor. This project creates  two 

+tasks and runs them at regular intervals.

+    

+This example project requires USB-UART interface to be connected to a host PC. 

+The host PC must connect to the serial port using a terminal emulator such as 

+TeraTerm or PuTTY configured as follows:

+    

+        - 115200 baud

+        - 8 data bits

+        - 1 stop bit

+        - no parity

+        - no flow control

+    

+The ./hw_platform.h file contains the design related information that is required 

+for this project. If you update the design, the hw_platform.h must be updated 

+accordingly.

+

+### FreeRTOS Configurations

+You must configure the FreeRTOS as per your applications need. Please read and modify FreeRTOSConfig.h.

+E.g. You must set configCPU_CLOCK_HZ parameter in FreeRTOSConfig.h according to the hardware platform 

+design that you are using. 

+

+The RISC-V creative board design uses 66Mhz processor clock. The PolarFire Eval Kit design uses 50Mhz processor clock. The SmartFusion2 Adv. Development kit design uses 83Mhz processor clock.

+

+### Microsemi SoftConsole Toolchain

+To know more please refer: [SoftConsole](https://github.com/RISCV-on-Microsemi-FPGA/SoftConsole)

+

+### Documentation for Microsemi RISC-V processor, SoftConsole toochain, Debug Tools, FPGA design etc.

+To know more please refer: [Documentation](https://github.com/RISCV-on-Microsemi-FPGA/Documentation)

+    

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/RTOSDemo Debug.launch b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/RTOSDemo Debug.launch
new file mode 100644
index 0000000..9bc0bf0
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/RTOSDemo Debug.launch
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>

+<launchConfiguration type="ilg.gnumcueclipse.debug.gdbjtag.openocd.launchConfigurationType">

+<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doContinue" value="true"/>

+<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doDebugInRam" value="false"/>

+<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doFirstReset" value="true"/>

+<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doGdbServerAllocateConsole" value="true"/>

+<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doGdbServerAllocateTelnetConsole" value="false"/>

+<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doSecondReset" value="false"/>

+<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doStartGdbServer" value="true"/>

+<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.enableSemihosting" value="false"/>

+<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.firstResetType" value="init"/>

+<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbClientOtherCommands" value="set mem inaccessible-by-default off&#13;&#10;set arch riscv:rv32"/>

+<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbClientOtherOptions" value=""/>

+<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerConnectionAddress" value=""/>

+<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerExecutable" value="${openocd_path}/${openocd_executable}"/>

+<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerGdbPortNumber" value="3333"/>

+<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerLog" value=""/>

+<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerOther" value="--file board/microsemi-riscv.cfg"/>

+<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerTelnetPortNumber" value="4444"/>

+<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.otherInitCommands" value=""/>

+<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.otherRunCommands" value=""/>

+<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.secondResetType" value="halt"/>

+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageFileName" value=""/>

+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageOffset" value=""/>

+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.ipAddress" value="localhost"/>

+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.jtagDevice" value="GNU MCU OpenOCD"/>

+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadImage" value="true"/>

+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadSymbols" value="true"/>

+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.pcRegister" value=""/>

+<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.portNumber" value="3333"/>

+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setPcRegister" value="false"/>

+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setResume" value="false"/>

+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setStopAt" value="true"/>

+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.stopAt" value="main"/>

+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsFileName" value=""/>

+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsOffset" value=""/>

+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForImage" value="false"/>

+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForSymbols" value="false"/>

+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForImage" value="true"/>

+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForSymbols" value="true"/>

+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useRemoteTarget" value="true"/>

+<stringAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_NAME" value="${cross_prefix}gdb${cross_suffix}"/>

+<booleanAttribute key="org.eclipse.cdt.dsf.gdb.UPDATE_THREADLIST_ON_SUSPEND" value="false"/>

+<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="2"/>

+<stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/>

+<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_REGISTER_GROUPS" value=""/>

+<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="Debug\RTOSDemo.elf"/>

+<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="RTOSDemo"/>

+<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="true"/>

+<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.debug.2049051127"/>

+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">

+<listEntry value="/RTOSDemo"/>

+</listAttribute>

+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">

+<listEntry value="4"/>

+</listAttribute>

+<stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;memoryBlockExpressionList context=&quot;Context string&quot;/&gt;&#13;&#10;"/>

+<stringAttribute key="process_factory_id" value="org.eclipse.cdt.dsf.gdb.GdbProcessFactory"/>

+</launchConfiguration>

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/Core16550/core16550_regs.h b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/Core16550/core16550_regs.h
new file mode 100644
index 0000000..0b921ce
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/Core16550/core16550_regs.h
@@ -0,0 +1,582 @@
+/*******************************************************************************

+ * (c) Copyright 2007-2015 Microsemi SoC Products Group. All rights reserved.

+ *

+ * IP core registers definitions. This file contains the definitions required

+ * for accessing the IP core through the hardware abstraction layer (HAL).

+ * This file was automatically generated, using "get_header.exe" version 0.4.0,

+ * from the IP-XACT description for:

+ *

+ *             Core16550    version: 2.0.0

+ *

+ * SVN $Revision: 7963 $

+ * SVN $Date: 2015-10-09 17:58:21 +0530 (Fri, 09 Oct 2015) $

+ *

+ *******************************************************************************/

+#ifndef CORE_16550_REGISTERS_H_

+#define CORE_16550_REGISTERS_H_ 1

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+/*******************************************************************************

+ * RBR register:

+ *------------------------------------------------------------------------------

+ * Receive Buffer Register

+ */

+#define RBR_REG_OFFSET	0x00U

+

+/*******************************************************************************

+ * THR register:

+ *------------------------------------------------------------------------------

+ * Transmit Holding Register

+ */

+#define THR_REG_OFFSET	0x00U

+

+/*******************************************************************************

+ * DLR register:

+ *------------------------------------------------------------------------------

+ * Divisor Latch(LSB) Register

+ */

+#define DLR_REG_OFFSET	0x00U

+

+/*******************************************************************************

+ * DMR register:

+ *------------------------------------------------------------------------------

+ * Divisor Latch(MSB) Register

+ */

+#define DMR_REG_OFFSET	0x04U

+

+/*******************************************************************************

+ * IER register:

+ *------------------------------------------------------------------------------

+ * Interrupt Enable Register

+ */

+#define IER_REG_OFFSET	0x04U

+

+/*------------------------------------------------------------------------------

+ * IER_ERBFI:

+ *   ERBFI field of register IER.

+ *------------------------------------------------------------------------------

+ * Enables Received Data Available Interrupt. 0 - Disabled; 1 - Enabled

+ */

+#define IER_ERBFI_OFFSET   0x04U

+#define IER_ERBFI_MASK     0x01U

+#define IER_ERBFI_SHIFT    0U

+

+/*------------------------------------------------------------------------------

+ * IER_ETBEI:

+ *   ETBEI field of register IER.

+ *------------------------------------------------------------------------------

+ * Enables the Transmitter Holding Register Empty Interrupt. 0 - Disabled; 1 - 

+ * Enabled

+ */

+#define IER_ETBEI_OFFSET   0x04U

+#define IER_ETBEI_MASK     0x02U

+#define IER_ETBEI_SHIFT    1U

+

+/*------------------------------------------------------------------------------

+ * IER_ELSI:

+ *   ELSI field of register IER.

+ *------------------------------------------------------------------------------

+ * Enables the Receiver Line Status Interrupt. 0 - Disabled; 1 - Enabled

+ */

+#define IER_ELSI_OFFSET   0x04U

+#define IER_ELSI_MASK     0x04U

+#define IER_ELSI_SHIFT    2U

+

+/*------------------------------------------------------------------------------

+ * IER_EDSSI:

+ *   EDSSI field of register IER.

+ *------------------------------------------------------------------------------

+ *  Enables the Modem Status Interrupt 0 - Disabled; 1 - Enabled

+ */

+#define IER_EDSSI_OFFSET   0x04U

+#define IER_EDSSI_MASK     0x08U

+#define IER_EDSSI_SHIFT    3U

+

+/*******************************************************************************

+ * IIR register:

+ *------------------------------------------------------------------------------

+ * Interrupt Identification

+ */

+#define IIR_REG_OFFSET	0x08U

+

+/*------------------------------------------------------------------------------

+ * IIR_IIR:

+ *   IIR field of register IIR.

+ *------------------------------------------------------------------------------

+ * Interrupt Identification bits.

+ */

+#define IIR_IIR_OFFSET   0x08U

+#define IIR_IIR_MASK     0x0FU

+#define IIR_IIR_SHIFT    0U

+

+/*------------------------------------------------------------------------------

+ * IIR_IIR:

+ *   IIR field of register IIR.

+ *------------------------------------------------------------------------------

+ * Interrupt Identification bits.

+ */

+

+/*------------------------------------------------------------------------------

+ * IIR_Mode:

+ *   Mode field of register IIR.

+ *------------------------------------------------------------------------------

+ * 11 - FIFO mode

+ */

+#define IIR_MODE_OFFSET   0x08U

+#define IIR_MODE_MASK     0xC0U

+#define IIR_MODE_SHIFT    6U

+

+/*******************************************************************************

+ * FCR register:

+ *------------------------------------------------------------------------------

+ * FIFO Control Register

+ */

+#define FCR_REG_OFFSET	0x08

+

+/*------------------------------------------------------------------------------

+ * FCR_Bit0:

+ *   Bit0 field of register FCR.

+ *------------------------------------------------------------------------------

+ * This bit enables both the TX and RX FIFOs.

+ */

+#define FCR_BIT0_OFFSET   0x08U

+#define FCR_BIT0_MASK     0x01U

+#define FCR_BIT0_SHIFT    0U

+

+#define FCR_ENABLE_OFFSET   0x08U

+#define FCR_ENABLE_MASK     0x01U

+#define FCR_ENABLE_SHIFT    0U

+

+/*------------------------------------------------------------------------------

+ * FCR_Bit1:

+ *   Bit1 field of register FCR.

+ *------------------------------------------------------------------------------

+ * Clears all bytes in the RX FIFO and resets its counter logic. The shift 

+ * register is not cleared.  0 - Disabled; 1 - Enabled

+ */

+#define FCR_BIT1_OFFSET   0x08U

+#define FCR_BIT1_MASK     0x02U

+#define FCR_BIT1_SHIFT    1U

+

+#define FCR_CLEAR_RX_OFFSET   0x08U

+#define FCR_CLEAR_RX_MASK     0x02U

+#define FCR_CLEAR_RX_SHIFT    1U

+

+/*------------------------------------------------------------------------------

+ * FCR_Bit2:

+ *   Bit2 field of register FCR.

+ *------------------------------------------------------------------------------

+ * Clears all bytes in the TX FIFO and resets its counter logic. The shift 

+ * register is not cleared.  0 - Disabled; 1 - Enabled

+ */

+#define FCR_BIT2_OFFSET   0x08U

+#define FCR_BIT2_MASK     0x04U

+#define FCR_BIT2_SHIFT    2U

+

+#define FCR_CLEAR_TX_OFFSET   0x08U

+#define FCR_CLEAR_TX_MASK     0x04U

+#define FCR_CLEAR_TX_SHIFT    2U

+

+/*------------------------------------------------------------------------------

+ * FCR_Bit3:

+ *   Bit3 field of register FCR.

+ *------------------------------------------------------------------------------

+ * Enables RXRDYN and TXRDYN pins when set to 1. Otherwise, they are disabled.

+ */

+#define FCR_BIT3_OFFSET   0x08U

+#define FCR_BIT3_MASK     0x08U

+#define FCR_BIT3_SHIFT    3U

+

+#define FCR_RDYN_EN_OFFSET   0x08U

+#define FCR_RDYN_EN_MASK     0x08U

+#define FCR_RDYN_EN_SHIFT    3U

+

+/*------------------------------------------------------------------------------

+ * FCR_Bit6:

+ *   Bit6 field of register FCR.

+ *------------------------------------------------------------------------------

+ * These bits are used to set the trigger level for the RX FIFO interrupt. RX 

+ * FIFO Trigger Level: 0 - 1; 1 - 4; 2 - 8; 3 - 14

+ */

+#define FCR_BIT6_OFFSET   0x08U

+#define FCR_BIT6_MASK     0xC0U

+#define FCR_BIT6_SHIFT    6U

+

+#define FCR_TRIG_LEVEL_OFFSET   0x08U

+#define FCR_TRIG_LEVEL_MASK     0xC0U

+#define FCR_TRIG_LEVEL_SHIFT    6U

+

+/*******************************************************************************

+ * LCR register:

+ *------------------------------------------------------------------------------

+ * Line Control Register

+ */

+#define LCR_REG_OFFSET	0x0CU

+

+/*------------------------------------------------------------------------------

+ * LCR_WLS:

+ *   WLS field of register LCR.

+ *------------------------------------------------------------------------------

+ * Word Length Select: 00 - 5 bits; 01 - 6 bits; 10 - 7 bits; 11 - 8 bits

+ */

+#define LCR_WLS_OFFSET   0x0CU

+#define LCR_WLS_MASK     0x03U

+#define LCR_WLS_SHIFT    0U

+

+/*------------------------------------------------------------------------------

+ * LCR_STB:

+ *   STB field of register LCR.

+ *------------------------------------------------------------------------------

+ * Number of Stop Bits: 0 - 1 stop bit; 1 - 1½ stop bits when WLS = 00, 2 stop 

+ * bits in other cases

+ */

+#define LCR_STB_OFFSET   0x0CU

+#define LCR_STB_MASK     0x04U

+#define LCR_STB_SHIFT    2U

+

+/*------------------------------------------------------------------------------

+ * LCR_PEN:

+ *   PEN field of register LCR.

+ *------------------------------------------------------------------------------

+ * Parity Enable 0 - Disabled; 1 - Enabled. Parity is added in transmission and 

+ * checked in receiving.

+ */

+#define LCR_PEN_OFFSET   0x0CU

+#define LCR_PEN_MASK     0x08U

+#define LCR_PEN_SHIFT    3U

+

+/*------------------------------------------------------------------------------

+ * LCR_EPS:

+ *   EPS field of register LCR.

+ *------------------------------------------------------------------------------

+ * Even Parity Select 0 - Odd parity; 1 - Even parity

+ */

+#define LCR_EPS_OFFSET   0x0CU

+#define LCR_EPS_MASK     0x10U

+#define LCR_EPS_SHIFT    4U

+

+/*------------------------------------------------------------------------------

+ * LCR_SP:

+ *   SP field of register LCR.

+ *------------------------------------------------------------------------------

+ * Stick Parity 0 - Disabled; 1 - Enabled When stick parity is enabled, it 

+ * works as follows: Bits 4..3, 11 - 0 will be sent as a parity bit, and 

+ * checked in receiving.  01 - 1 will be sent as a parity bit, and checked in 

+ * receiving.

+ */

+#define LCR_SP_OFFSET   0x0CU

+#define LCR_SP_MASK     0x20U

+#define LCR_SP_SHIFT    5U

+

+/*------------------------------------------------------------------------------

+ * LCR_SB:

+ *   SB field of register LCR.

+ *------------------------------------------------------------------------------

+ * Set Break 0 - Disabled 1 - Set break. SOUT is forced to 0. This does not 

+ * have any effect on transmitter logic. The break is disabled by setting the 

+ * bit to 0.

+ */

+#define LCR_SB_OFFSET   0x0CU

+#define LCR_SB_MASK     0x40U

+#define LCR_SB_SHIFT    6U

+

+/*------------------------------------------------------------------------------

+ * LCR_DLAB:

+ *   DLAB field of register LCR.

+ *------------------------------------------------------------------------------

+ * Divisor Latch Access Bit 0 - Disabled. Normal addressing mode in use 1 - 

+ * Enabled. Enables access to the Divisor Latch registers during read or write 

+ * operation to addresses 0 and 1.

+ */

+#define LCR_DLAB_OFFSET   0x0CU

+#define LCR_DLAB_MASK     0x80U

+#define LCR_DLAB_SHIFT    7U

+

+/*******************************************************************************

+ * MCR register:

+ *------------------------------------------------------------------------------

+ * Modem Control Register

+ */

+#define MCR_REG_OFFSET	0x10U

+

+/*------------------------------------------------------------------------------

+ * MCR_DTR:

+ *   DTR field of register MCR.

+ *------------------------------------------------------------------------------

+ * Controls the Data Terminal Ready (DTRn) output.  0 - DTRn <= 1; 1 - DTRn <= 0

+ */

+#define MCR_DTR_OFFSET   0x10U

+#define MCR_DTR_MASK     0x01U

+#define MCR_DTR_SHIFT    0U

+

+/*------------------------------------------------------------------------------

+ * MCR_RTS:

+ *   RTS field of register MCR.

+ *------------------------------------------------------------------------------

+ * Controls the Request to Send (RTSn) output.  0 - RTSn <= 1; 1 - RTSn <= 0

+ */

+#define MCR_RTS_OFFSET   0x10U

+#define MCR_RTS_MASK     0x02U

+#define MCR_RTS_SHIFT    1U

+

+/*------------------------------------------------------------------------------

+ * MCR_Out1:

+ *   Out1 field of register MCR.

+ *------------------------------------------------------------------------------

+ * Controls the Output1 (OUT1n) signal.  0 - OUT1n <= 1; 1 - OUT1n <= 0

+ */

+#define MCR_OUT1_OFFSET   0x10U

+#define MCR_OUT1_MASK     0x04U

+#define MCR_OUT1_SHIFT    2U

+

+/*------------------------------------------------------------------------------

+ * MCR_Out2:

+ *   Out2 field of register MCR.

+ *------------------------------------------------------------------------------

+ * Controls the Output2 (OUT2n) signal.  0 - OUT2n <=1; 1 - OUT2n <=0

+ */

+#define MCR_OUT2_OFFSET   0x10U

+#define MCR_OUT2_MASK     0x08U

+#define MCR_OUT2_SHIFT    3U

+

+/*------------------------------------------------------------------------------

+ * MCR_Loop:

+ *   Loop field of register MCR.

+ *------------------------------------------------------------------------------

+ * Loop enable bit 0 - Disabled; 1 - Enabled. The following happens in loop 

+ * mode: SOUT is set to 1. The SIN, DSRn, CTSn, RIn, and DCDn inputs are 

+ * disconnected.  The output of the Transmitter Shift Register is looped back 

+ * into the Receiver Shift Register. The modem control outputs (DTRn, RTSn, 

+ * OUT1n, and OUT2n) are connected internally to the modem control inputs, and 

+ * the modem control output pins are set at 1. In loopback mode, the 

+ * transmitted data is immediately received, allowing the CPU to check the 

+ * operation of the UART. The interrupts are operating in loop mode.

+ */

+#define MCR_LOOP_OFFSET   0x10U

+#define MCR_LOOP_MASK     0x10U

+#define MCR_LOOP_SHIFT    4U

+

+/*******************************************************************************

+ * LSR register:

+ *------------------------------------------------------------------------------

+ * Line Status Register

+ */

+#define LSR_REG_OFFSET	0x14U

+

+/*------------------------------------------------------------------------------

+ * LSR_DR:

+ *   DR field of register LSR.

+ *------------------------------------------------------------------------------

+ * Data Ready indicator 1 when a data byte has been received and stored in the 

+ * FIFO. DR is cleared to 0 when the CPU reads the data from the FIFO.

+ */

+#define LSR_DR_OFFSET   0x14U

+#define LSR_DR_MASK     0x01U

+#define LSR_DR_SHIFT    0U

+

+/*------------------------------------------------------------------------------

+ * LSR_OE:

+ *   OE field of register LSR.

+ *------------------------------------------------------------------------------

+ * Overrun Error indicator Indicates that the new byte was received before the 

+ * CPU read the byte from the receive buffer, and that the earlier data byte 

+ * was destroyed. OE is cleared when the CPU reads the Line Status Register. If 

+ * the data continues to fill the FIFO beyond the trigger level, an overrun 

+ * error will occur once the FIFO is full and the next character has been 

+ * completely received in the shift register. The character in the shift 

+ * register is overwritten, but it is not transferred to the FIFO.

+ */

+#define LSR_OE_OFFSET   0x14U

+#define LSR_OE_MASK     0x02U

+#define LSR_OE_SHIFT    1U

+

+/*------------------------------------------------------------------------------

+ * LSR_PE:

+ *   PE field of register LSR.

+ *------------------------------------------------------------------------------

+ * Parity Error indicator Indicates that the received byte had a parity error. 

+ * PE is cleared when the CPU reads the Line Status Register. This error is 

+ * revealed to the CPU when its associated character is at the top of the FIFO.

+ */

+#define LSR_PE_OFFSET   0x14U

+#define LSR_PE_MASK     0x04U

+#define LSR_PE_SHIFT    2U

+

+/*------------------------------------------------------------------------------

+ * LSR_FE:

+ *   FE field of register LSR.

+ *------------------------------------------------------------------------------

+ *  Framing Error indicator Indicates that the received byte did not have a 

+ * valid Stop bit. FE is cleared when the CPU reads the Line Status Register. 

+ * The UART will try to re-synchronize after a framing error. To do this, it

+ * assumes that the framing error was due to the next start bit, so it samples 

+ * this start bit twice, and then starts receiving the data.  This error is 

+ * revealed to the CPU when its associated character is at the top of the FIFO.

+ */

+#define LSR_FE_OFFSET   0x14U

+#define LSR_FE_MASK     0x08U

+#define LSR_FE_SHIFT    3U

+

+/*------------------------------------------------------------------------------

+ * LSR_BI:

+ *   BI field of register LSR.

+ *------------------------------------------------------------------------------

+ * Break Interrupt indicator Indicates that the received data is at 0 longer 

+ * than a full word transmission time (start bit + data bits + parity + stop 

+ * bits). BI is cleared when the CPU reads the Line Status Register. This error 

+ * is revealed to the CPU when its associated character is at the top of the 

+ * FIFO. When break occurs, only one zero character is loaded into the FIFO.

+ */

+#define LSR_BI_OFFSET   0x14U

+#define LSR_BI_MASK     0x10U

+#define LSR_BI_SHIFT    4U

+

+/*------------------------------------------------------------------------------

+ * LSR_THRE:

+ *   THRE field of register LSR.

+ *------------------------------------------------------------------------------

+ *  Transmitter Holding Register Empty indicator Indicates that the UART is 

+ * ready to transmit a new data byte. THRE causes an interrupt to the CPU when 

+ * bit 1 (ETBEI) in the Interrupt Enable Register is 1.  This bit is set when 

+ * the TX FIFO is empty. It is cleared when at least one byte is written to the 

+ * TX FIFO.

+ */

+#define LSR_THRE_OFFSET   0x14U

+#define LSR_THRE_MASK     0x20U

+#define LSR_THRE_SHIFT    5U

+

+/*------------------------------------------------------------------------------

+ * LSR_TEMT:

+ *   TEMT field of register LSR.

+ *------------------------------------------------------------------------------

+ *  Transmitter Empty indicator This bit is set to 1 when both the transmitter 

+ * FIFO and shift registers are empty.

+ */

+#define LSR_TEMT_OFFSET   0x14U

+#define LSR_TEMT_MASK     0x40U

+#define LSR_TEMT_SHIFT    6U

+

+/*------------------------------------------------------------------------------

+ * LSR_FIER:

+ *   FIER field of register LSR.

+ *------------------------------------------------------------------------------

+ *  This bit is set when there is at least one parity error, framing error, or 

+ * break indication in the FIFO. FIER is cleared when the CPU reads the LSR if 

+ * there are no subsequent errors in the FIFO.

+ */

+#define LSR_FIER_OFFSET   0x14U

+#define LSR_FIER_MASK     0x80U

+#define LSR_FIER_SHIFT    7U

+

+/*******************************************************************************

+ * MSR register:

+ *------------------------------------------------------------------------------

+ * Modem Status Register

+ */

+#define MSR_REG_OFFSET	0x18U

+

+/*------------------------------------------------------------------------------

+ * MSR_DCTS:

+ *   DCTS field of register MSR.

+ *------------------------------------------------------------------------------

+ * Delta Clear to Send indicator.  Indicates that the CTSn input has changed 

+ * state since the last time it was read by the CPU.

+ */

+#define MSR_DCTS_OFFSET   0x18U

+#define MSR_DCTS_MASK     0x01U

+#define MSR_DCTS_SHIFT    0U

+

+/*------------------------------------------------------------------------------

+ * MSR_DDSR:

+ *   DDSR field of register MSR.

+ *------------------------------------------------------------------------------

+ * Delta Data Set Ready indicator Indicates that the DSRn input has changed 

+ * state since the last time it was read by the CPU.

+ */

+#define MSR_DDSR_OFFSET   0x18U

+#define MSR_DDSR_MASK     0x02U

+#define MSR_DDSR_SHIFT    1U

+

+/*------------------------------------------------------------------------------

+ * MSR_TERI:

+ *   TERI field of register MSR.

+ *------------------------------------------------------------------------------

+ * Trailing Edge of Ring Indicator detector. Indicates that RI input has 

+ * changed from 0 to 1.

+ */

+#define MSR_TERI_OFFSET   0x18U

+#define MSR_TERI_MASK     0x04U

+#define MSR_TERI_SHIFT    2U

+

+/*------------------------------------------------------------------------------

+ * MSR_DDCD:

+ *   DDCD field of register MSR.

+ *------------------------------------------------------------------------------

+ * Delta Data Carrier Detect indicator Indicates that DCD input has changed 

+ * state.  NOTE: Whenever bit 0, 1, 2, or 3 is set to 1, a Modem Status 

+ * Interrupt is generated.

+ */

+#define MSR_DDCD_OFFSET   0x18U

+#define MSR_DDCD_MASK     0x08U

+#define MSR_DDCD_SHIFT    3U

+

+/*------------------------------------------------------------------------------

+ * MSR_CTS:

+ *   CTS field of register MSR.

+ *------------------------------------------------------------------------------

+ * Clear to Send The complement of the CTSn input. When bit 4 of the Modem 

+ * Control Register (MCR) is set to 1 (loop), this bit is equivalent to DTR in 

+ * the MCR.

+ */

+#define MSR_CTS_OFFSET   0x18U

+#define MSR_CTS_MASK     0x10U

+#define MSR_CTS_SHIFT    4U

+

+/*------------------------------------------------------------------------------

+ * MSR_DSR:

+ *   DSR field of register MSR.

+ *------------------------------------------------------------------------------

+ * Data Set Ready The complement of the DSR input. When bit 4 of the MCR is set 

+ * to 1 (loop), this bit is equivalent to RTSn in the MCR.

+ */

+#define MSR_DSR_OFFSET   0x18U

+#define MSR_DSR_MASK     0x20U

+#define MSR_DSR_SHIFT    5U

+

+/*------------------------------------------------------------------------------

+ * MSR_RI:

+ *   RI field of register MSR.

+ *------------------------------------------------------------------------------

+ * Ring Indicator The complement of the RIn input. When bit 4 of the MCR is set 

+ * to 1 (loop), this bit is equivalent to OUT1 in the MCR.

+ */

+#define MSR_RI_OFFSET   0x18U

+#define MSR_RI_MASK     0x40U

+#define MSR_RI_SHIFT    6U

+

+/*------------------------------------------------------------------------------

+ * MSR_DCD:

+ *   DCD field of register MSR.

+ *------------------------------------------------------------------------------

+ * Data Carrier Detect The complement of DCDn input. When bit 4 of the MCR is 

+ * set to 1 (loop), this bit is equivalent to OUT2 in the MCR.

+ */

+#define MSR_DCD_OFFSET   0x18U

+#define MSR_DCD_MASK     0x80U

+#define MSR_DCD_SHIFT    7U

+

+/*******************************************************************************

+ * SR register:

+ *------------------------------------------------------------------------------

+ * Scratch Register

+ */

+#define SR_REG_OFFSET	0x1CU

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif /* CORE_16550_REGISTERS_H_*/

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/Core16550/core_16550.c b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/Core16550/core_16550.c
new file mode 100644
index 0000000..ca735e6
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/Core16550/core_16550.c
@@ -0,0 +1,865 @@
+/*******************************************************************************

+ * (c) Copyright 2007-2015 Microsemi SoC Products Group. All rights reserved.

+ *

+ * Core16550 driver implementation. See file "core_16550.h" for a

+ * description of the functions implemented in this file.

+ *

+ * SVN $Revision: 7963 $

+ * SVN $Date: 2015-10-09 17:58:21 +0530 (Fri, 09 Oct 2015) $

+ */

+#include "hal.h"

+#include "core_16550.h"

+#include "core16550_regs.h"

+#include "hal_assert.h"

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+/*******************************************************************************

+ * Definitions for transmitter states

+ */

+#define TX_COMPLETE     0x00U

+

+/*******************************************************************************

+ * Definition for transmitter FIFO size

+ */

+#define TX_FIFO_SIZE    16U

+

+/*******************************************************************************

+ * Default receive interrupt trigger level

+ */

+#define DEFAULT_RX_TRIG_LEVEL  ((uint8_t)UART_16550_FIFO_SINGLE_BYTE)

+

+/*******************************************************************************

+ * Receiver error status mask and shift offset

+ */

+#define STATUS_ERROR_MASK   ( LSR_OE_MASK | LSR_PE_MASK |  \

+                              LSR_FE_MASK | LSR_BI_MASK | LSR_FIER_MASK)

+

+/*******************************************************************************

+ * Definitions for invalid parameters with proper type

+ */

+#define INVALID_INTERRUPT   0U

+#define INVALID_IRQ_HANDLER ( (uart_16550_irq_handler_t) 0 )

+

+/*******************************************************************************

+ * Possible values for Interrupt Identification Register Field.

+ */

+#define IIRF_MODEM_STATUS       0x00U

+#define IIRF_THRE               0x02U

+#define IIRF_RX_DATA            0x04U

+#define IIRF_RX_LINE_STATUS     0x06U

+#define IIRF_DATA_TIMEOUT       0x0CU

+

+/*******************************************************************************

+ * Null parameters with appropriate type definitions

+ */

+#define NULL_ADDR       ( ( addr_t ) 0 )

+#define NULL_INSTANCE   ( ( uart_16550_instance_t * ) 0 )

+#define NULL_BUFF       ( ( uint8_t * ) 0 )

+

+/*******************************************************************************

+ * Possible states for different register bit fields

+ */

+enum {

+    DISABLE = 0U,

+    ENABLE  = 1U

+};

+

+/*******************************************************************************

+ * Static function declarations

+ */

+static void default_tx_handler(uart_16550_instance_t * this_uart);

+

+/*******************************************************************************

+ * Public function definitions

+ */

+

+/***************************************************************************//**

+ * UART_16550_init.

+ * See core_16550.h for details of how to use this function.

+ */

+void

+UART_16550_init

+(

+    uart_16550_instance_t* this_uart,

+    addr_t base_addr,

+    uint16_t baud_value,

+    uint8_t line_config

+)

+{

+#ifndef NDEBUG

+    uint8_t dbg1;

+    uint8_t dbg2;

+#endif

+    uint8_t fifo_config;

+    uint8_t temp;

+

+    HAL_ASSERT( base_addr != NULL_ADDR );

+    HAL_ASSERT( this_uart != NULL_INSTANCE );

+

+    if( ( base_addr != NULL_ADDR ) && ( this_uart != NULL_INSTANCE ) )

+    {

+        /* disable interrupts */

+        HAL_set_8bit_reg(base_addr, IER, DISABLE);

+

+        /* reset divisor latch */

+        HAL_set_8bit_reg_field(base_addr, LCR_DLAB, ENABLE);

+#ifndef NDEBUG

+        dbg1 =  HAL_get_8bit_reg_field(base_addr, LCR_DLAB );

+        HAL_ASSERT( dbg1 == ENABLE );

+#endif

+        /* MSB of baud value */

+        temp = (uint8_t)(baud_value >> 8);

+        HAL_set_8bit_reg(base_addr, DMR, temp );

+        /* LSB of baud value */

+        HAL_set_8bit_reg(base_addr, DLR, ( (uint8_t)baud_value ) );

+#ifndef NDEBUG

+        dbg1 =  HAL_get_8bit_reg(base_addr, DMR );

+        dbg2 =  HAL_get_8bit_reg(base_addr, DLR );

+        HAL_ASSERT( ( ( ( (uint16_t) dbg1 ) << 8 ) | dbg2 ) == baud_value );

+#endif

+        /* reset divisor latch */

+        HAL_set_8bit_reg_field(base_addr, LCR_DLAB, DISABLE);

+#ifndef NDEBUG

+        dbg1 =  HAL_get_8bit_reg_field(base_addr, LCR_DLAB );

+        HAL_ASSERT( dbg1 == DISABLE );

+#endif

+        /* set the line control register (bit length, stop bits, parity) */

+        HAL_set_8bit_reg( base_addr, LCR, line_config );

+#ifndef NDEBUG

+        dbg1 =  HAL_get_8bit_reg(base_addr, LCR );

+        HAL_ASSERT( dbg1 == line_config)

+#endif

+        /* Enable and configure the RX and TX FIFOs. */

+        fifo_config = ((uint8_t)(DEFAULT_RX_TRIG_LEVEL << FCR_TRIG_LEVEL_SHIFT) |

+                                 FCR_RDYN_EN_MASK | FCR_CLEAR_RX_MASK |

+                                 FCR_CLEAR_TX_MASK | FCR_ENABLE_MASK );

+        HAL_set_8bit_reg( base_addr, FCR, fifo_config );

+

+        /* disable loopback */

+        HAL_set_8bit_reg_field( base_addr, MCR_LOOP, DISABLE );

+#ifndef NDEBUG

+        dbg1 =  HAL_get_8bit_reg_field(base_addr, MCR_LOOP);

+        HAL_ASSERT( dbg1 == DISABLE );

+#endif

+

+        /* Instance setup */

+        this_uart->base_address = base_addr;

+        this_uart->tx_buffer    = NULL_BUFF;

+        this_uart->tx_buff_size = TX_COMPLETE;

+        this_uart->tx_idx       = 0U;

+        this_uart->tx_handler   = default_tx_handler;

+

+        this_uart->rx_handler  = ( (uart_16550_irq_handler_t) 0 );

+        this_uart->linests_handler  = ( (uart_16550_irq_handler_t) 0 );

+        this_uart->modemsts_handler = ( (uart_16550_irq_handler_t) 0 );

+        this_uart->status = 0U;

+    }

+}

+

+/***************************************************************************//**

+ * UART_16550_polled_tx.

+ * See core_16550.h for details of how to use this function.

+ */

+void

+UART_16550_polled_tx

+(

+    uart_16550_instance_t * this_uart,

+    const uint8_t * pbuff,

+    uint32_t tx_size

+)

+{

+    uint32_t char_idx = 0U;

+    uint32_t size_sent;

+    uint8_t status;

+

+    HAL_ASSERT( this_uart != NULL_INSTANCE );

+    HAL_ASSERT( pbuff != NULL_BUFF );

+    HAL_ASSERT( tx_size > 0U );

+

+    if( ( this_uart != NULL_INSTANCE ) &&

+        ( pbuff != NULL_BUFF ) &&

+        ( tx_size > 0U ) )

+    {

+        /* Remain in this loop until the entire input buffer

+         * has been transferred to the UART.

+         */

+        do {

+            /* Read the Line Status Register and update the sticky record */

+            status = HAL_get_8bit_reg( this_uart->base_address, LSR );

+            this_uart->status |= status;

+

+            /* Check if TX FIFO is empty. */

+            if( status & LSR_THRE_MASK )

+            {

+                uint32_t fill_size = TX_FIFO_SIZE;

+

+                /* Calculate the number of bytes to transmit. */

+                if ( tx_size < TX_FIFO_SIZE )

+                {

+                    fill_size = tx_size;

+                }

+

+                /* Fill the TX FIFO with the calculated the number of bytes. */

+                for ( size_sent = 0U; size_sent < fill_size; ++size_sent )

+                {

+                    /* Send next character in the buffer. */

+                    HAL_set_8bit_reg( this_uart->base_address, THR,

+                                      (uint_fast8_t)pbuff[char_idx++]);

+                }

+

+                /* Calculate the number of untransmitted bytes remaining. */

+                tx_size -= size_sent;

+            }

+        } while ( tx_size );

+    }

+}

+

+/***************************************************************************//**

+ * UART_16550_polled_tx_string.

+ * See core_16550.h for details of how to use this function.

+ */

+void

+UART_16550_polled_tx_string

+(

+    uart_16550_instance_t * this_uart,

+    const uint8_t * p_sz_string

+)

+{

+    uint32_t char_idx = 0U;

+    uint32_t fill_size;

+    uint_fast8_t data_byte;

+    uint8_t status;

+

+    HAL_ASSERT( this_uart != NULL_INSTANCE );

+    HAL_ASSERT( p_sz_string != NULL_BUFF );

+

+    if( ( this_uart != NULL_INSTANCE ) && ( p_sz_string != NULL_BUFF ) )

+    {

+        char_idx = 0U;

+

+        /* Get the first data byte from the input buffer */

+        data_byte = (uint_fast8_t)p_sz_string[char_idx];

+

+        /* First check for the NULL terminator byte.

+         * Then remain in this loop until the entire string in the input buffer

+         * has been transferred to the UART.

+         */

+        while ( 0U != data_byte )

+        {

+            /* Wait until TX FIFO is empty. */

+            do {

+                status = HAL_get_8bit_reg( this_uart->base_address,LSR);

+                this_uart->status |= status;

+            } while ( !( status & LSR_THRE_MASK ) );

+

+            /* Send bytes from the input buffer until the TX FIFO is full

+             * or we reach the NULL terminator byte.

+             */

+            fill_size = 0U;

+            while ( (0U != data_byte) && (fill_size < TX_FIFO_SIZE) )

+            {

+                /* Send the data byte */

+                HAL_set_8bit_reg( this_uart->base_address, THR, data_byte );

+                ++fill_size;

+                char_idx++;

+                /* Get the next data byte from the input buffer */

+                data_byte = (uint_fast8_t)p_sz_string[char_idx];

+            }

+        }

+    }

+}

+

+

+/***************************************************************************//**

+ * UART_16550_irq_tx.

+ * See core_16550.h for details of how to use this function.

+ */

+void

+UART_16550_irq_tx

+(

+    uart_16550_instance_t * this_uart,

+    const uint8_t * pbuff,

+    uint32_t tx_size

+)

+{

+    HAL_ASSERT( this_uart != NULL_INSTANCE )

+    HAL_ASSERT( pbuff != NULL_BUFF )

+    HAL_ASSERT( tx_size > 0U )

+

+    if( ( this_uart != NULL_INSTANCE ) &&

+        ( pbuff != NULL_BUFF ) &&

+        ( tx_size > 0U ) )

+    {

+        /*Initialize the UART instance with

+          parameters required for transmission.*/

+        this_uart->tx_buffer = pbuff;

+        this_uart->tx_buff_size = tx_size;

+        /* char_idx; */

+        this_uart->tx_idx = 0U;

+        /* assign handler for default data transmission */

+        this_uart->tx_handler = default_tx_handler;

+

+        /* enables TX interrupt */

+        HAL_set_8bit_reg_field(this_uart->base_address, IER_ETBEI, ENABLE);

+    }

+}

+

+/***************************************************************************//**

+ * UART_16550_tx_complete.

+ * See core_16550.h for details of how to use this function.

+ */

+int8_t

+UART_16550_tx_complete

+(

+    uart_16550_instance_t * this_uart

+)

+{

+    int8_t returnvalue = 0;

+    uint8_t status = 0U;

+

+    HAL_ASSERT( this_uart != NULL_INSTANCE )

+

+    if( this_uart != NULL_INSTANCE )

+    {

+        status = HAL_get_8bit_reg(this_uart->base_address,LSR);

+        this_uart->status |= status;

+

+        if( ( this_uart->tx_buff_size == TX_COMPLETE ) &&

+                             ( status & LSR_TEMT_MASK ) )

+        {

+            returnvalue = (int8_t)1;

+        }

+    }

+    return returnvalue;

+}

+

+

+/***************************************************************************//**

+ * UART_16550_get_rx.

+ * See core_16550.h for details of how to use this function.

+ */

+size_t

+UART_16550_get_rx

+(

+    uart_16550_instance_t * this_uart,

+    uint8_t * rx_buff,

+    size_t buff_size

+)

+{

+    uint8_t status;

+    size_t rx_size = 0U;

+

+    HAL_ASSERT( this_uart != NULL_INSTANCE )

+    HAL_ASSERT( rx_buff != (uint8_t *)0 )

+    HAL_ASSERT( buff_size > 0U )

+

+    if( ( this_uart != NULL_INSTANCE ) &&

+        ( rx_buff != (uint8_t *)0 ) &&

+        ( buff_size > 0U ) )

+    {

+        status = HAL_get_8bit_reg( this_uart->base_address, LSR );

+        this_uart->status |= status;

+        while ( ((status & LSR_DR_MASK) != 0U) && ( rx_size < buff_size ) )

+        {

+            rx_buff[rx_size] = HAL_get_8bit_reg( this_uart->base_address, RBR );

+            rx_size++;

+            status = HAL_get_8bit_reg( this_uart->base_address, LSR );

+            this_uart->status |= status;

+        }

+    }

+    return rx_size;

+}

+

+/***************************************************************************//**

+ * UART_16550_isr.

+ * See core_16550.h for details of how to use this function.

+ */

+void

+UART_16550_isr

+(

+    uart_16550_instance_t * this_uart

+)

+{

+    uint8_t iirf;

+

+    HAL_ASSERT( this_uart != NULL_INSTANCE )

+

+    if(this_uart != NULL_INSTANCE )

+    {

+        iirf = HAL_get_8bit_reg_field( this_uart->base_address, IIR_IIR );

+

+        switch ( iirf )

+        {

+            /* Modem status interrupt */

+            case IIRF_MODEM_STATUS:

+            {

+                if( INVALID_IRQ_HANDLER != this_uart->modemsts_handler  )

+                {

+                    HAL_ASSERT( INVALID_IRQ_HANDLER != this_uart->modemsts_handler );

+                    if( INVALID_IRQ_HANDLER != this_uart->modemsts_handler )

+                    {

+                        (*(this_uart->modemsts_handler))(this_uart);

+                    }

+                }

+            }

+            break;

+            /* Transmitter Holding Register Empty interrupt */

+            case IIRF_THRE:

+            {

+                HAL_ASSERT( INVALID_IRQ_HANDLER != this_uart->tx_handler );

+                if ( INVALID_IRQ_HANDLER != this_uart->tx_handler )

+                {

+                    (*(this_uart->tx_handler))(this_uart);

+                }

+            }

+            break;

+            /* Received Data Available interrupt */

+            case IIRF_RX_DATA:

+            case IIRF_DATA_TIMEOUT:

+            {

+                HAL_ASSERT( INVALID_IRQ_HANDLER != this_uart->rx_handler );

+                if ( INVALID_IRQ_HANDLER != this_uart->rx_handler )

+                {

+                    (*(this_uart->rx_handler))(this_uart);

+                }

+            }

+            break;

+            /* Line status interrupt */

+            case IIRF_RX_LINE_STATUS:

+            {

+                HAL_ASSERT( INVALID_IRQ_HANDLER != this_uart->linests_handler );

+                if ( INVALID_IRQ_HANDLER != this_uart->linests_handler )

+                {

+                    (*(this_uart->linests_handler))(this_uart);

+                }

+            }

+            break;

+            /* Unidentified interrupt */

+            default:

+            {

+                HAL_ASSERT( INVALID_INTERRUPT )

+            }

+        }

+    }

+}

+

+/***************************************************************************//**

+ * UART_16550_set_rx_handler.

+ * See core_16550.h for details of how to use this function.

+ */

+void

+UART_16550_set_rx_handler

+(

+    uart_16550_instance_t * this_uart,

+    uart_16550_irq_handler_t handler,

+    uart_16550_rx_trig_level_t trigger_level

+)

+{

+    HAL_ASSERT( this_uart != NULL_INSTANCE )

+    HAL_ASSERT( handler != INVALID_IRQ_HANDLER)

+    HAL_ASSERT( trigger_level < UART_16550_FIFO_INVALID_TRIG_LEVEL)

+

+    if( ( this_uart != NULL_INSTANCE ) &&

+        ( handler != INVALID_IRQ_HANDLER) &&

+        ( trigger_level < UART_16550_FIFO_INVALID_TRIG_LEVEL) )

+    {

+        this_uart->rx_handler = handler;

+

+        /* Set the receive interrupt trigger level. */

+        HAL_set_8bit_reg_field( this_uart->base_address,

+                            FCR_TRIG_LEVEL, trigger_level );

+

+        /* Enable receive interrupt. */

+        HAL_set_8bit_reg_field( this_uart->base_address, IER_ERBFI, ENABLE );

+    }

+}

+

+/***************************************************************************//**

+ * UART_16550_set_loopback.

+ * See core_16550.h for details of how to use this function.

+ */

+void

+UART_16550_set_loopback

+(

+    uart_16550_instance_t * this_uart,

+    uart_16550_loopback_t loopback

+)

+{

+    HAL_ASSERT( this_uart != NULL_INSTANCE );

+    HAL_ASSERT( loopback < UART_16550_INVALID_LOOPBACK );

+

+    if( ( this_uart != NULL_INSTANCE ) &&

+        ( loopback < UART_16550_INVALID_LOOPBACK ) )

+    {

+        if ( loopback == UART_16550_LOOPBACK_OFF )

+        {

+            HAL_set_8bit_reg_field( this_uart->base_address,

+                                    MCR_LOOP,

+                                    DISABLE );

+        }

+        else

+        {

+            HAL_set_8bit_reg_field( this_uart->base_address,

+                                    MCR_LOOP,

+                                    ENABLE );

+        }

+    }

+}

+

+/***************************************************************************//**

+ * UART_16550_get_rx_status.

+ * See core_16550.h for details of how to use this function.

+ */

+uint8_t

+UART_16550_get_rx_status

+(

+    uart_16550_instance_t * this_uart

+)

+{

+    uint8_t status = UART_16550_INVALID_PARAM;

+    HAL_ASSERT( this_uart != NULL_INSTANCE );

+

+    if( ( this_uart != NULL_INSTANCE ) )

+    {

+        /*

+         * Bit 1 - Overflow error status

+         * Bit 2 - Parity error status

+         * Bit 3 - Frame error status

+         * Bit 4 - Break interrupt indicator

+         * Bit 7 - FIFO data error status

+         */

+        this_uart->status |= HAL_get_8bit_reg( this_uart->base_address, LSR );

+        status = ( this_uart->status & STATUS_ERROR_MASK );

+        /*

+         * Clear the sticky status for this instance.

+         */

+        this_uart->status = (uint8_t)0;

+    }

+    return status;

+}

+

+/***************************************************************************//**

+ * UART_16550_get_modem_status.

+ * See core_16550.h for details of how to use this function.

+ */

+uint8_t

+UART_16550_get_modem_status

+(

+    uart_16550_instance_t * this_uart

+)

+{

+    uint8_t status = UART_16550_NO_ERROR;

+    HAL_ASSERT( this_uart != NULL_INSTANCE )

+

+    if( ( this_uart != NULL_INSTANCE ) )

+    {

+        /*

+         * Extract UART error status and place in lower bits of "status".

+         * Bit 0 - Delta Clear to Send Indicator

+         * Bit 1 - Delta Clear to Receive Indicator

+         * Bit 2 - Trailing edge of Ring Indicator detector

+         * Bit 3 - Delta Data Carrier Detect indicator

+         * Bit 4 - Clear To Send

+         * Bit 5 - Data Set Ready

+         * Bit 6 - Ring Indicator

+         * Bit 7 - Data Carrier Detect

+         */

+        status = HAL_get_8bit_reg( this_uart->base_address, MSR );

+    }

+    return status;

+}

+

+/***************************************************************************//**

+ * Default TX interrupt handler to automatically transmit data from

+ * user assgined TX buffer.

+ */

+static void

+default_tx_handler

+(

+    uart_16550_instance_t * this_uart

+)

+{

+    uint8_t status;

+

+    HAL_ASSERT( NULL_INSTANCE != this_uart )

+

+    if ( this_uart != NULL_INSTANCE )

+    {

+        HAL_ASSERT( NULL_BUFF != this_uart->tx_buffer )

+        HAL_ASSERT( 0U != this_uart->tx_buff_size )

+

+        if ( ( this_uart->tx_buffer != NULL_BUFF ) &&

+             ( 0U != this_uart->tx_buff_size ) )

+        {

+            /* Read the Line Status Register and update the sticky record. */

+            status = HAL_get_8bit_reg( this_uart->base_address,LSR);

+            this_uart->status |= status;

+    

+            /*

+             * This function should only be called as a result of a THRE interrupt.

+             * Verify that this is true before proceeding to transmit data.

+             */

+            if ( status & LSR_THRE_MASK )

+            {

+                uint32_t size_sent = 0U;

+                uint32_t fill_size = TX_FIFO_SIZE;

+                uint32_t tx_remain = this_uart->tx_buff_size - this_uart->tx_idx;

+    

+                /* Calculate the number of bytes to transmit. */

+                if ( tx_remain < TX_FIFO_SIZE )

+                {

+                    fill_size = tx_remain;

+                }

+    

+                /* Fill the TX FIFO with the calculated the number of bytes. */

+                for ( size_sent = 0U; size_sent < fill_size; ++size_sent )

+                {

+                    /* Send next character in the buffer. */

+                    HAL_set_8bit_reg( this_uart->base_address, THR,

+                            (uint_fast8_t)this_uart->tx_buffer[this_uart->tx_idx]);

+                    ++this_uart->tx_idx;

+                }

+            }

+    

+            /* Flag Tx as complete if all data has been pushed into the Tx FIFO. */

+            if ( this_uart->tx_idx == this_uart->tx_buff_size )

+            {

+                this_uart->tx_buff_size = TX_COMPLETE;

+                /* disables TX interrupt */

+                HAL_set_8bit_reg_field( this_uart->base_address,

+                                        IER_ETBEI, DISABLE);

+            }

+        }

+    }

+}

+

+/***************************************************************************//**

+ * UART_16550_enable_irq.

+ * See core_16550.h for details of how to use this function.

+ */

+void

+UART_16550_enable_irq

+(

+    uart_16550_instance_t * this_uart,

+    uint8_t irq_mask

+)

+{

+    HAL_ASSERT( this_uart != NULL_INSTANCE )

+

+    if( this_uart != NULL_INSTANCE )

+    {

+        /* irq_mask encoding: 1- enable

+         * bit 0 - Receive Data Available Interrupt

+         * bit 1 - Transmitter Holding  Register Empty Interrupt

+         * bit 2 - Receiver Line Status Interrupt

+         * bit 3 - Modem Status Interrupt

+         */

+        /* read present interrupts for enabled ones*/

+        irq_mask |= HAL_get_8bit_reg( this_uart->base_address, IER );

+        /* Enable interrupts */

+        HAL_set_8bit_reg( this_uart->base_address, IER, irq_mask );

+    }

+}

+

+/***************************************************************************//**

+ * UART_16550_disable_irq.

+ * See core_16550.h for details of how to use this function.

+ */

+void

+UART_16550_disable_irq

+(

+    uart_16550_instance_t * this_uart,

+    uint8_t irq_mask

+)

+{

+    HAL_ASSERT( this_uart != NULL_INSTANCE )

+

+    if( this_uart != NULL_INSTANCE )

+    {

+        /* irq_mask encoding:  1 - disable

+         * bit 0 - Receive Data Available Interrupt

+         * bit 1 - Transmitter Holding  Register Empty Interrupt

+         * bit 2 - Receiver Line Status Interrupt

+         * bit 3 - Modem Status Interrupt

+         */

+        /* read present interrupts for enabled ones */

+        irq_mask = (( (uint8_t)~irq_mask ) & 

+                    HAL_get_8bit_reg( this_uart->base_address, IER ));

+        /* Disable interrupts */

+        HAL_set_8bit_reg( this_uart->base_address, IER, irq_mask );

+    }

+}

+

+/***************************************************************************//**

+ * UART_16550_set_rxstatus_handler.

+ * See core_16550.h for details of how to use this function.

+ */

+void

+UART_16550_set_rxstatus_handler

+(

+    uart_16550_instance_t * this_uart,

+    uart_16550_irq_handler_t handler

+)

+{

+    HAL_ASSERT( this_uart != NULL_INSTANCE )

+    HAL_ASSERT( handler != INVALID_IRQ_HANDLER)

+

+    if( ( this_uart != NULL_INSTANCE ) &&

+        ( handler != INVALID_IRQ_HANDLER) )

+    {

+        this_uart->linests_handler = handler;

+        /* Enable receiver line status interrupt. */

+        HAL_set_8bit_reg_field( this_uart->base_address, IER_ELSI, ENABLE );

+    }

+}

+

+/***************************************************************************//**

+ * UART_16550_set_tx_handler.

+ * See core_16550.h for details of how to use this function.

+ */

+void

+UART_16550_set_tx_handler

+(

+    uart_16550_instance_t * this_uart,

+    uart_16550_irq_handler_t handler

+)

+{

+    HAL_ASSERT( this_uart != NULL_INSTANCE )

+    HAL_ASSERT( handler != INVALID_IRQ_HANDLER)

+

+    if( ( this_uart != NULL_INSTANCE ) &&

+        ( handler != INVALID_IRQ_HANDLER) )

+    {

+        this_uart->tx_handler = handler;

+

+        /* Make TX buffer info invalid */

+        this_uart->tx_buffer = NULL_BUFF;

+        this_uart->tx_buff_size = 0U;

+

+        /* Enable transmitter holding register Empty interrupt. */

+        HAL_set_8bit_reg_field( this_uart->base_address, IER_ETBEI, ENABLE );

+    }

+}

+

+/***************************************************************************//**

+ * UART_16550_set_modemstatus_handler.

+ * See core_16550.h for details of how to use this function.

+ */

+void

+UART_16550_set_modemstatus_handler

+(

+    uart_16550_instance_t * this_uart,

+    uart_16550_irq_handler_t handler

+)

+{

+    HAL_ASSERT( this_uart != NULL_INSTANCE )

+    HAL_ASSERT( handler != INVALID_IRQ_HANDLER)

+

+    if( ( this_uart != NULL_INSTANCE ) &&

+        ( handler != INVALID_IRQ_HANDLER) )

+    {

+        this_uart->modemsts_handler = handler;

+        /* Enable modem status interrupt. */

+        HAL_set_8bit_reg_field( this_uart->base_address, IER_EDSSI, ENABLE );

+    }

+}

+

+/***************************************************************************//**

+ * UART_16550_fill_tx_fifo.

+ * See core_16550.h for details of how to use this function.

+ */

+size_t

+UART_16550_fill_tx_fifo

+(

+    uart_16550_instance_t * this_uart,

+    const uint8_t * tx_buffer,

+    size_t tx_size

+)

+{

+    uint8_t status;

+    size_t size_sent = 0U;

+

+    HAL_ASSERT( this_uart != NULL_INSTANCE )

+    HAL_ASSERT( tx_buffer != NULL_BUFF )

+    HAL_ASSERT( tx_size > 0U )

+

+    /* Fill the UART's Tx FIFO until the FIFO is full or the complete input

+     * buffer has been written. */

+    if( (this_uart != NULL_INSTANCE) &&

+        (tx_buffer != NULL_BUFF)   &&

+        (tx_size > 0U) )

+    {

+        /* Read the Line Status Register and update the sticky record. */

+        status = HAL_get_8bit_reg( this_uart->base_address, LSR );

+        this_uart->status |= status;

+

+        /* Check if TX FIFO is empty. */

+        if( status & LSR_THRE_MASK )

+        {

+            uint32_t fill_size = TX_FIFO_SIZE;

+

+            /* Calculate the number of bytes to transmit. */

+            if ( tx_size < TX_FIFO_SIZE )

+            {

+                fill_size = tx_size;

+            }

+

+            /* Fill the TX FIFO with the calculated the number of bytes. */

+            for ( size_sent = 0U; size_sent < fill_size; ++size_sent )

+            {

+                /* Send next character in the buffer. */

+                HAL_set_8bit_reg( this_uart->base_address, THR,

+                                  (uint_fast8_t)tx_buffer[size_sent]);

+            }

+        }

+    }

+    return size_sent;

+}

+

+/***************************************************************************//**

+ * UART_16550_get_tx_status.

+ * See core_16550.h for details of how to use this function.

+ */

+uint8_t

+UART_16550_get_tx_status

+(

+    uart_16550_instance_t * this_uart

+)

+{

+    uint8_t status = UART_16550_TX_BUSY;

+    HAL_ASSERT( this_uart != NULL_INSTANCE );

+

+    if( ( this_uart != NULL_INSTANCE ) )

+    {

+        /* Read the Line Status Register and update the sticky record. */

+        status = HAL_get_8bit_reg( this_uart->base_address, LSR );

+        this_uart->status |= status;

+        /*

+         * Extract the transmit status bits from the UART's Line Status Register.

+         * Bit 5 - Transmitter Holding Register/FIFO Empty (THRE) status. (If = 1, TX FIFO is empty)

+         * Bit 6 - Transmitter Empty (TEMT) status. (If = 1, both TX FIFO and shift register are empty)

+         */

+        status &= ( LSR_THRE_MASK | LSR_TEMT_MASK );

+    }

+    return status;

+}

+

+

+#ifdef __cplusplus

+}

+#endif

+

+

+

+

+

+

+

+

+

+

+

+

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/Core16550/core_16550.h b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/Core16550/core_16550.h
new file mode 100644
index 0000000..98b1f16
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/Core16550/core_16550.h
@@ -0,0 +1,1264 @@
+/*******************************************************************************

+ * (c) Copyright 2007-2015 Microsemi SoC Products Group. All rights reserved.

+ *

+ * This file contains the application programming interface for the Core16550

+ * bare metal driver.

+ *

+ * SVN $Revision: 7963 $

+ * SVN $Date: 2015-10-09 17:58:21 +0530 (Fri, 09 Oct 2015) $

+ */

+/*=========================================================================*//**

+  @mainpage Core16550 Bare Metal Driver.

+

+  @section intro_sec Introduction

+  The Core16550 is an implementation of the Universal Asynchronous

+  Receiver/Transmitter aimed at complete compliance to standard 16550 UART.

+  The Core16550 bare metal software driver is designed for use in systems

+  with no operating system.

+

+  The Core16550 driver provides functions for polled and interrupt driven

+  transmitting and receiving. It also provides functions for reading the

+  values from different status registers, enabling and disabling interrupts

+  at Core16550 level. The Core16550 driver is provided as C source code.

+

+  @section driver_configuration Driver Configuration

+  Your application software should configure the Core16550 driver through

+  calls to the UART_16550_init() function for each Core16550 instance in

+  the hardware design. The configuration parameters include the Core16550

+  hardware instance base address and other runtime parameters, such as baud

+  value, bit width, and parity.

+

+  No Core16550 hardware configuration parameters are needed by the driver,

+  apart from the Core16550 hardware instance base address. Hence, no

+  additional configuration files are required to use the driver.

+

+  @section theory_op Theory of Operation

+  The Core16550 software driver is designed to allow the control of multiple

+  instances of Core16550. Each instance of Core16550 in the hardware design

+  is associated with a single instance of the uart_16550_instance_t structure

+  in the software. You need to allocate memory for one unique

+  uart_16550_instance_t structure instance for each Core16550 hardware instance.

+  The contents of these data structures are initialized during calls to

+  function UART_16550_init(). A pointer to the structure is passed to

+  subsequent driver functions in order to identify the Core16550 hardware

+  instance you wish to perform the requested operation on.

+

+  Note:     Do not attempt to directly manipulate the content of

+  uart_16550_instance_t structures. This structure is only intended to be

+  modified by the driver function.

+

+  Initialization

+  The Core16550 driver is initialized through a call to the UART_16550_init()

+  function. This function takes the UARTÂ’s configuration as parameters.

+  The UART_16550_init() function must be called before any other Core16550

+  driver functions can be called.

+

+  Polled Transmission and Reception

+  The driver can be used to transmit and receive data once initialized. Polled

+  operations where the driver constantly polls the state of the UART registers

+  in order to control data transmit or data receive are performed using these

+  functions:

+         •  UART_16550_polled_tx()

+         •  UART_16550_polled_tx_string

+         •  UART_16550_fill_tx_fifo()

+         •  UART_16550_get_rx()

+

+  Data is transmitted using the UART_16550_polled_tx() function. This function

+  is blocking, meaning that it will only return once the data passed to the

+  function has been sent to the Core16550 hardware. Data received by the

+  Core16550 hardware can be read by the UART_16550_get_rx() function.

+

+  The UART_16550_polled_tx_string() function is provided to transmit a NULL (‘\0’)

+  terminated string in polled mode. This function is blocking, meaning that it

+  will only return once the data passed to the function has been sent to the

+  Core16550 hardware.

+

+  The UART_16550_fill_tx_fifo() function fills the Core16550 hardware transmit

+  FIFO with data from a buffer passed as a parameter and returns the number of

+  bytes transferred to the FIFO. If the transmit FIFO is not empty when the

+  UART_16550_fill_tx_fifo() function is called it returns immediately without

+  transferring any data to the FIFO.

+

+  Interrupt Driven Operations

+  The driver can also transmit or receive data under interrupt control, freeing

+  your application to perform other tasks until an interrupt occurs indicating

+  that the driverÂ’s attention is required. Interrupt controlled UART operations

+  are performed using these functions:

+        •   UART_16550_isr()

+        •   UART_16550_irq_tx()

+        •   UART_16550_tx_complete()

+        •   UART_16550_set_tx_handler()

+        •   UART_16550_set_rx_handler()

+        •   UART_16550_set_rxstatus_handler()

+        •   UART_16550_set_modemstatus_handler()

+        •   UART_16550_enable_irq()

+        •   UART_16550_disable_irq()

+

+  Interrupt Handlers

+  The UART_16550_isr() function is the top level interrupt handler function for

+  the Core16550 driver. You must call it from the system level

+  (CoreInterrupt and NVIC level) interrupt service routine (ISR) assigned to the

+  interrupt triggered by the Core16550 INTR signal. The UART_16550_isr() function

+  identifies the source of the Core16550 interrupt and calls the corresponding

+  handler function previously registered with the driver through calls to the

+  UART_16550_set_rx_handler(), UART_16550_set_tx_handler(),

+  UART_16550_set_rxstatus_handler(), and UART_16550_set_modemstatus_handler()

+  functions. You are responsible for creating these lower level interrupt handlers

+  as part of your application program and registering them with the driver.

+  The UART_16550_enable_irq() and UART_16550_disable_irq() functions are used to

+  enable or disable the received line status, received data available/character

+  timeout, transmit holding register empty and modem status interrupts at the

+  Core16550 level.

+

+  Transmitting Data

+  Interrupt-driven transmit is initiated by a call to UART_16550_irq_tx(),

+  specifying the block of data to transmit. Your application is then free to

+  perform other tasks and inquire later whether transmit has completed by calling

+  the UART_16550_tx_complete() function. The UART_16550_irq_tx() function enables

+  the UARTÂ’s transmit holding register empty (THRE) interrupt and then, when the

+  interrupt goes active, the driverÂ’s default THRE interrupt handler transfers

+  the data block to the UART until the entire block is transmitted.

+

+  Note:     You can use the UART_16550_set_tx_handler() function to assign an

+  alternative handler to the THRE interrupt. In this case, you must not use the

+  UART_16550_irq_tx() function to initiate the transmit, as this will re-assign

+  the driverÂ’s default THRE interrupt handler to the THRE interrupt. Instead,

+  your alternative THRE interrupt handler must include a call to the

+  UART_16550_fill_tx_fifo() function to transfer the data to the UART.

+

+  Receiving Data

+  Interrupt-driven receive is performed by first calling UART_16550_set_rx_handler()

+  to register a receive handler function that will be called by the driver whenever

+  receive data is available. You must provide this receive handler function which

+  must include a call to the UART_16550_get_rx() function to actually read the

+  received data.

+

+  UART Status

+  The function UART_16550_get_rx_status() is used to read the receiver error status.

+  This function returns the overrun, parity, framing, break, and FIFO error status

+  of the receiver.

+  The function UART_16550_get_tx_status() is used to read the transmitter status.

+  This function returns the transmit empty (TEMT) and transmit holding register

+  empty (THRE) status of the transmitter.

+  The function UART_16550_get_modem_status() is used to read the modem status flags.

+  This function returns the current value of the modem status register.

+

+  Loopback

+  The function UART_16550_set_loopback() is used to enable or disable loopback

+  between Tx and Rx lines internal to Core16550.

+*//*=========================================================================*/

+#ifndef __CORE_16550_H

+#define __CORE_16550_H 1

+

+#include "cpu_types.h"

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+/***************************************************************************//**

+ * Receiver Error Status

+ * The following defines are used to determine the UART receiver error type.

+ * These bit mask constants are used with the return value of the

+ * UART_16550_get_rx_status() function to find out if any errors occurred

+ * while receiving data.

+ */

+#define UART_16550_NO_ERROR         ( (uint8_t) 0x00 )

+#define UART_16550_OVERRUN_ERROR    ( (uint8_t) 0x02 )

+#define UART_16550_PARITY_ERROR     ( (uint8_t) 0x04 )

+#define UART_16550_FRAMING_ERROR    ( (uint8_t) 0x08 )

+#define UART_16550_BREAK_ERROR      ( (uint8_t) 0x10 )

+#define UART_16550_FIFO_ERROR       ( (uint8_t) 0x80 )

+#define UART_16550_INVALID_PARAM    ( (uint8_t) 0xFF )

+

+/***************************************************************************//**

+ * Modem Status

+ * The following defines are used to determine the modem status. These bit

+ * mask constants are used with the return value of the

+ * UART_16550_get_modem_status() function to find out the modem status of

+ * the UART.

+ */

+#define UART_16550_DCTS             ( (uint8_t) 0x01 )

+#define UART_16550_DDSR             ( (uint8_t) 0x02 )

+#define UART_16550_TERI             ( (uint8_t) 0x04 )

+#define UART_16550_DDCD             ( (uint8_t) 0x08 )

+#define UART_16550_CTS              ( (uint8_t) 0x10 )

+#define UART_16550_DSR              ( (uint8_t) 0x20 )

+#define UART_16550_RI               ( (uint8_t) 0x40 )

+#define UART_16550_DCD              ( (uint8_t) 0x80 )

+

+/***************************************************************************//**

+ * Transmitter Status

+ * The following definitions are used to determine the UART transmitter status.

+ * These bit mask constants are used with the return value of the

+ * UART_16550_get_tx_status() function to find out the status of the

+ * transmitter.

+ */

+#define UART_16550_TX_BUSY          ( (uint8_t) 0x00 )

+#define UART_16550_THRE             ( (uint8_t) 0x20 )

+#define UART_16550_TEMT             ( (uint8_t) 0x40 )

+

+/***************************************************************************//**

+ * Core16550 Interrupts

+ * The following defines are used to enable and disable Core16550 interrupts.

+ * They are used to build the value of the irq_mask parameter for the

+ * UART_16550_enable_irq() and UART_16550_disable_irq() functions. A bitwise

+ * OR of these constants is used to enable or disable multiple interrupts.

+ */

+#define UART_16550_RBF_IRQ          ( (uint8_t) 0x01 )

+#define UART_16550_TBE_IRQ          ( (uint8_t) 0x02 )

+#define UART_16550_LS_IRQ           ( (uint8_t) 0x04 )

+#define UART_16550_MS_IRQ           ( (uint8_t) 0x08 )

+

+/***************************************************************************//**

+ * Data Width

+ * The following defines are used to build the value of the UART_16550_init()

+ * function line_config parameter.

+ */

+#define UART_16550_DATA_5_BITS      ( (uint8_t) 0x00 )

+#define UART_16550_DATA_6_BITS      ( (uint8_t) 0x01 )

+#define UART_16550_DATA_7_BITS      ( (uint8_t) 0x02 )

+#define UART_16550_DATA_8_BITS      ( (uint8_t) 0x03 )

+

+/***************************************************************************//**

+ * Parity Control

+ * The following defines are used to build the value of the UART_16550_init()

+ * function line_config parameter.

+ */

+#define UART_16550_NO_PARITY            ( (uint8_t) 0x00 )

+#define UART_16550_ODD_PARITY           ( (uint8_t) 0x08 )

+#define UART_16550_EVEN_PARITY          ( (uint8_t) 0x18 )

+#define UART_16550_STICK_PARITY_1       ( (uint8_t) 0x28 )

+#define UART_16550_STICK_PARITY_0       ( (uint8_t) 0x38 )

+

+/***************************************************************************//**

+ * Number of Stop Bits

+ * The following defines are used to build the value of the UART_16550_init()

+ * function line_config parameter.

+ */

+#define UART_16550_ONE_STOP_BIT     ( (uint8_t) 0x00 )

+/*only when data bits is 5*/

+#define UART_16550_ONEHALF_STOP_BIT ( (uint8_t) 0x04 )

+/*only when data bits is not 5*/

+#define UART_16550_TWO_STOP_BITS    ( (uint8_t) 0x04 )

+

+/***************************************************************************//**

+  This enumeration specifies the receiver FIFO trigger level. This is the number

+  of bytes that must be received before the UART generates a receive data

+  available interrupt. It provides the allowed values for the

+  UART_16550_set_rx_handler() functionÂ’s trigger_level parameter.

+ */

+typedef enum {

+    UART_16550_FIFO_SINGLE_BYTE    = 0,

+    UART_16550_FIFO_FOUR_BYTES     = 1,

+    UART_16550_FIFO_EIGHT_BYTES    = 2,

+    UART_16550_FIFO_FOURTEEN_BYTES = 3,

+    UART_16550_FIFO_INVALID_TRIG_LEVEL

+} uart_16550_rx_trig_level_t;

+

+/***************************************************************************//**

+  This enumeration specifies the Loopback configuration of the UART. It provides

+  the allowed values for the UART_16550_set_loopback() functionÂ’s loopback

+  parameter.

+ */

+typedef enum {

+    UART_16550_LOOPBACK_OFF   = 0,

+    UART_16550_LOOPBACK_ON    = 1,

+    UART_16550_INVALID_LOOPBACK

+} uart_16550_loopback_t;

+

+/***************************************************************************//**

+  This is type definition for Core16550 instance. You need to create and

+  maintain a record of this type. This holds all data regarding the Core16550

+  instance.

+ */

+typedef struct uart_16550_instance uart_16550_instance_t;

+

+/***************************************************************************//**

+  This typedef specifies the function prototype for Core16550 interrupt handlers.

+  All interrupt handlers registered with the Core16550 driver must be of this

+  type. The interrupt handlers are registered with the driver through the

+  UART_16550_set_rx_handler(), UART_16550_set_tx_handler(),

+  UART_16550_set_rxstatus_handler(), and UART_16550_set_modemstatus_handler()

+  functions.

+

+  The this_uart parameter is a pointer to a uart_16550_instance_t structure that

+  holds all data regarding this instance of the Core16550.

+ */

+typedef void (*uart_16550_irq_handler_t)(uart_16550_instance_t * this_uart);

+

+/***************************************************************************//**

+  uart_16550_instance.

+  This structure is used to identify the various Core16550 hardware instances

+  in your system. Your application software should declare one instance of this

+  structure for each instance of Core16550 in your system. The function

+  UART_16550_init() initializes this structure. A pointer to an initialized

+  instance of the structure should be passed as the first parameter to the

+  Core16550 driver functions, to identify which Core16550 hardware instance

+  should perform the requested operation.

+ */

+struct uart_16550_instance{

+    /* Core16550 instance base address: */

+    addr_t      base_address;

+    /* Accumulated status: */

+    uint8_t     status;

+

+    /* transmit related info: */

+    const uint8_t*  tx_buffer;

+    uint32_t        tx_buff_size;

+    uint32_t        tx_idx;

+

+    /* line status (OE, PE, FE & BI) interrupt handler:*/

+    uart_16550_irq_handler_t linests_handler;

+    /* receive interrupt handler:*/

+    uart_16550_irq_handler_t rx_handler;

+    /* transmitter holding register interrupt handler:*/

+    uart_16550_irq_handler_t tx_handler;

+    /* modem status interrupt handler:*/

+    uart_16550_irq_handler_t modemsts_handler;

+};

+

+/***************************************************************************//**

+ * The UART_16550_init() function initializes the driverÂ’s data structures and

+ * the Core16550 hardware with the configuration passed as parameters.. The

+ * configuration parameters are the baud_value used to generate the baud rate,

+ * and the line_config used to specify the line configuration (bit length,

+ * stop bits and parity).

+ *

+ * @param this_uart     The this_uart parameter is a pointer to a

+ *                      uart_16550_instance_t structure that holds all data

+ *                      regarding this instance of the Core16550. This pointer

+ *                      is used to identify the target Core16550 hardware

+ *                      instance in subsequent calls to the Core16550 driver

+ *                      functions.

+ * @param base_addr     The base_address parameter is the base address in the

+ *                      processor's memory map for the registers of the

+ *                      Core16550 instance being initialized.

+ * @param baud_value    The baud_value parameter is used to select the baud rate

+ *                      for the UART. The baud value is calculated from the

+ *                      frequency of the system clock in Hertz and the desired

+ *                      baud rate using the following equation:

+ *

+ *                      baud_value = (clock /(baud_rate * 16))

+ *

+ *                      The baud_value parameter must be a value in the range 0

+ *                      to 65535 (or 0x0000 to 0xFFFF).

+ * @param line_config   This parameter is the line configuration specifying the

+ *                      bit length, number of stop bits and parity settings. This

+ *                      is a bitwise OR of one value from each of the following

+ *                      groups of allowed values:

+ *                      •   Data lengths:

+ *                          UART_16550_DATA_5_BITS

+ *                          UART_16550_DATA_6_BITS

+ *                          UART_16550_DATA_7_BITS

+ *                          UART_16550_DATA_8_BITS

+ *                      •   Parity types:

+ *                          UART_16550_NO_PARITY

+ *                          UART_16550_EVEN_PARITY

+ *                          UART_16550_ODD_PARITY

+ *                          UART_16550_STICK_PARITY_0

+ *                          UART_16550_STICK_PARITY_1

+ *                      •   Number of stop bits:

+ *                          UART_16550_ONE_STOP_BIT

+ *                          UART_16550_ONEHALF_STOP_BIT

+ *                          UART_16550_TWO_STOP_BITS

+ * @return              This function does not return a value.

+ *

+ * Example:

+ * @code

+ * #define UART_16550_BASE_ADDR   0x2A000000

+ * #define BAUD_VALUE_57600    26

+ *

+ * uart_16550_instance_t g_uart;

+ *

+ * UART_16550_init( &g_uart, UART_16550_BASE_ADDR, BAUD_VALUE_57600,

+ *                  (UART_16550_DATA_8_BITS |

+ *                   UART_16550_EVEN_PARITY |

+ *                   UART_16550_ONE_STOP_BIT) );

+ * @endcode

+ */

+void

+UART_16550_init

+(

+    uart_16550_instance_t* this_uart,

+    addr_t base_addr,

+    uint16_t baud_value,

+    uint8_t line_config

+);

+

+/***************************************************************************//**

+ * The UART_16550_polled_tx() function is used to transmit data. It transfers

+ * the contents of the transmitter data buffer, passed as a function parameter,

+ * into the UART's hardware transmitter FIFO. It returns when the full content

+ * of the transmitter data buffer has been transferred to the UART's transmitter

+ * FIFO. It is safe to release or reuse the memory used as the transmitter data

+ * buffer once this function returns.

+ *

+ * Note:    This function reads the UARTÂ’s line status register (LSR) to poll

+ * for the active state of the transmitter holding register empty (THRE) bit

+ * before transferring data from the data buffer to the transmitter FIFO. It

+ * transfers data to the transmitter FIFO in blocks of 16 bytes or less and

+ * allows the FIFO to empty before transferring the next block of data.

+ *

+ * Note:    The actual transmission over the serial connection will still be in

+ * progress when this function returns. Use the UART_16550_get_tx_status()

+ * function if you need to know when the transmitter is empty.

+ *

+ * @param this_uart     The this_uart parameter is a pointer to a

+ *                      uart_16550_instance_t structure that holds all

+ *                      data regarding this instance of the Core16550.

+ * @param pbuff         The pbuff parameter is a pointer to a buffer containing

+ *                      the data to be transmitted.

+ * @param tx_size       The tx_size parameter is the size, in bytes, of the

+ *                      data to be transmitted.

+ * @return              This function does not return a value.

+ *

+ * Example:

+ * @code

+ *   uint8_t testmsg1[] = {"\n\r\n\r\n\rUART_16550_polled_tx() test message 1"};

+ *   UART_16550_polled_tx(&g_uart,(const uint8_t *)testmsg1,sizeof(testmsg1));

+ * @endcode

+ */

+void

+UART_16550_polled_tx

+(

+    uart_16550_instance_t * this_uart,

+    const uint8_t * pbuff,

+    uint32_t tx_size

+);

+/***************************************************************************//**

+ * The UART_16550_polled_tx_string() function is used to transmit a NULL ('\0')

+ * terminated string. It transfers the text string, from the buffer starting at

+ * the address pointed to by p_sz_string, into the UARTÂ’s hardware transmitter

+ * FIFO. It returns when the complete string has been transferred to the UART's

+ * transmit FIFO. It is safe to release or reuse the memory used as the string

+ * buffer once this function returns.

+ *

+ * Note:    This function reads the UARTÂ’s line status register (LSR) to poll

+ * for the active state of the transmitter holding register empty (THRE) bit

+ * before transferring data from the data buffer to the transmitter FIFO. It

+ * transfers data to the transmitter FIFO in blocks of 16 bytes or less and

+ * allows the FIFO to empty before transferring the next block of data.

+ *

+ * Note:    The actual transmission over the serial connection will still be

+ * in progress when this function returns. Use the UART_16550_get_tx_status()

+ * function if you need to know when the transmitter is empty.

+ *

+ * @param this_uart     The this_uart parameter is a pointer to a

+ *                      uart_16550_instance_t structure that holds all data

+ *                      regarding this instance of the Core16550.

+ * @param p_sz_string   The p_sz_string parameter is a pointer to a buffer

+ *                      containing the NULL ('\0') terminated string to be

+ *                      transmitted.

+ * @return              This function does not return a value.

+ *

+ * Example:

+ * @code

+ *   uint8_t testmsg1[] = {"\r\n\r\nUART_16550_polled_tx_string() test message 1\0"};

+ *   UART_16550_polled_tx_string(&g_uart,(const uint8_t *)testmsg1);

+ * @endcode

+ */

+void

+UART_16550_polled_tx_string

+(

+    uart_16550_instance_t * this_uart,

+    const uint8_t * p_sz_string

+);

+

+/***************************************************************************//**

+ * The UART_16550_irq_tx() function is used to initiate an interrupt driven

+ * transmit. It returns immediately after making a note of the transmit buffer

+ * location and enabling the transmitter holding register empty (THRE) interrupt

+ * at the Core16550 level. This function takes a pointer via the pbuff parameter

+ * to a memory buffer containing the data to transmit. The memory buffer

+ * specified through this pointer must remain allocated and contain the data to

+ * transmit until the transmit completion has been detected through calls to

+ * function UART_16550_tx_complete().The actual transmission over the serial

+ * connection is still in progress until calls to the UART_16550_tx_complete()

+ * function indicate transmit completion.

+ *

+ * Note:    It is your responsibility to call UART_16550_isr(), the driverÂ’s

+ * top level interrupt handler function, from the system level (CoreInterrupt

+ * and NVIC level) interrupt handler assigned to the interrupt triggered by the

+ * Core16550 INTR signal. You must do this before using the UART_16550_irq_tx()

+ * function.

+ *

+ * Note:    It is also your responsibility to enable the system level

+ * (CoreInterrupt and NVIC level) interrupt connected to the Core16550 INTR

+ * interrupt signal.

+ *

+ * Note:    The UART_16550_irq_tx() function assigns an internal default transmit

+ * interrupt handler function to the UARTÂ’s THRE interrupt. This interrupt handler

+ * overrides any custom interrupt handler that you may have previously registered

+ * using the UART_16550_set_tx_handler() function.

+ *

+ * Note:    The UART_16550_irq_tx() functionÂ’s default transmit interrupt handler

+ * disables the UARTÂ’s THRE interrupt when all of the data has been transferred

+ * to the UART's transmit FIFO.

+ *

+ * @param this_uart     The this_uart parameter is a pointer to a

+ *                      uart_16550_instance_t structure that holds all data

+ *                      regarding this instance of the Core16550.

+ * @param pbuff         The pbuff parameter is a pointer to a buffer containing

+ *                      the data to be transmitted.

+ * @param tx_size       The tx_size parameter specifies the size, in bytes, of

+ *                      the data to be transmitted.

+ * @return              This function does not return a value.

+ *

+ * Example:

+ * @code

+ * uint8_t tx_buff[10] = "abcdefghi";

+ *

+ * UART_16550_irq_tx( &g_uart, tx_buff, sizeof(tx_buff));

+ * while ( 0 == UART_16550_tx_complete( &g_uart ) )

+ * { ; }

+ * @endcode

+ */

+void

+UART_16550_irq_tx

+(

+    uart_16550_instance_t * this_uart,

+    const uint8_t * pbuff,

+    uint32_t tx_size

+);

+

+/***************************************************************************//**

+ * The UART_16550_tx_complete() function is used to find out if the interrupt

+ * driven transmit previously initiated through a call to UART_16550_irq_tx()

+ * is complete. This function is typically used to find out when it is safe

+ * to reuse or release the memory buffer holding the transmit data.

+ *

+ * Note:    The transfer of all of the data from the memory buffer to the UARTÂ’s

+ * transmit FIFO and the actual transmission over the serial connection are both

+ * complete when a call to the UART_16550_tx_complete() function indicate

+ * transmit completion.

+ *

+ * @param this_uart     The this_uart parameter is a pointer to a

+ *                      uart_16550_instance_t structure that holds all data

+ *                      regarding this instance of the Core16550.

+ * @return              This function returns a non-zero value if transmit has

+ *                      completed, otherwise it returns zero.

+ *  Example:

+ *   See the UART_16550_irq_tx() function for an example that uses the

+ *   UART_16550_tx_complete() function.

+ */

+int8_t

+UART_16550_tx_complete

+(

+   uart_16550_instance_t * this_uart

+);

+

+/***************************************************************************//**

+ * The UART_16550_get_rx() function reads the content of the Core16550

+ * receiverÂ’s FIFO and stores it in the receive buffer that is passed via the

+ * rx_buff function parameter. It copies either the full contents of the FIFO

+ * into the receive buffer, or just enough data from the FIFO to fill the receive

+ * buffer, dependent upon the size of the receive buffer passed by the buff_size

+ * parameter. The UART_16550_get_rx() function returns the number of bytes copied

+ * into the receive buffer .This function is non-blocking and will return 0

+ * immediately if no data has been received.

+ *

+ * Note:    The UART_16550_get_rx() function reads and accumulates the receiver

+ * status of the Core16550 instance before reading each byte from the receiver's

+ * data register/FIFO. This allows the driver to maintain a sticky record of any

+ * receiver errors that occur as the UART receives each data byte; receiver errors

+ * would otherwise be lost after each read from the receiver's data register. A call

+ * to the UART_16550_get_rx_status() function returns any receiver errors accumulated

+ * during the execution of the UART_16550_get_rx() function.

+ *

+ * Note:    If you need to read the error status for each byte received, set the

+ * buff_size to 1 and read the receive line error status for each byte using the

+ * UART_16550_get_rx_status() function.

+ * The UART_16550_get_rx() function can be used in polled mode, where it is called

+ * at regular intervals to find out if any data has been received, or in interrupt

+ * driven-mode, where it is called as part of a receive handler that is called by

+ * the driver as a result of data being received.

+ *

+ * Note:    In interrupt driven mode you should call the UART_16550_get_rx()

+ * function as part of the receive handler function that you register with the

+ * Core16550 driver through a call to UART_16550_set_rx_handler().

+ *

+ * @param this_uart     The this_uart parameter is a pointer to a

+ *                      uart_16550_instance_t structure that holds all data

+ *                      regarding this instance of the Core16550.

+ * @param rx_buff       The rx_buff parameter is a pointer to a memory buffer

+ *                      where the received data is copied.

+ * @param buff_size     The buff_size parameter is the size of the receive

+ *                      buffer in bytes.

+ * @return              This function returns the number of bytes copied into

+ *                      the receive buffer.

+ * Example:

+ * @code

+ *   #define MAX_RX_DATA_SIZE    256

+ *

+ *   uint8_t rx_data[MAX_RX_DATA_SIZE];

+ *   uint8_t rx_size = 0;

+ *

+ *   rx_size = UART_16550_get_rx( &g_uart, rx_data, sizeof(rx_data) );

+ * @endcode

+ */

+size_t

+UART_16550_get_rx

+(

+   uart_16550_instance_t * this_uart,

+   uint8_t * rx_buff,

+   size_t buff_size

+);

+

+/***************************************************************************//**

+ * The UART_16550_isr() function is the top level interrupt handler function for

+ * the Core16550 driver. You must call UART_16550_isr() from the system level

+ * (CoreInterrupt and NVIC level) interrupt handler assigned to the interrupt

+ * triggered by the Core16550 INTR signal. Your system level interrupt handler

+ * must also clear the system level interrupt triggered by the Core16550 INTR

+ * signal before returning, to prevent a re-assertion of the same interrupt.

+ *

+ * Note:    This function supports all types of interrupt triggered by Core16550.

+ * It is not a complete interrupt handler by itself; rather, it is a top level

+ * wrapper that abstracts Core16550 interrupt handling by calling lower level

+ * handler functions specific to each type of Core16550 interrupt. You must

+ * create the lower level handler functions to suit your application and

+ * register them with the driver through calls to the UART_16550_set_rx_handler(),

+ * UART_16550_set_tx_handler(), UART_16550_set_rxstatus_handler() and

+ * UART_16550_set_modemstatus_handler() functions.

+ *

+ * @param this_uart     The this_uart parameter is a pointer to a

+ *                      uart_16550_instance_t structure that holds all data

+ *                      regarding this instance of the Core16550.

+ *

+ * @return              This function does not return a value.

+ *

+ * Example:

+ * @code

+ *   void CIC_irq1_handler(void)

+ *   {

+ *      UART_16550_isr( &g_uart );

+ *   }

+ * @endcode

+ */

+void

+UART_16550_isr

+(

+   uart_16550_instance_t * this_uart

+);

+

+/***************************************************************************//**

+ * The UART_16550_set_rx_handler() function is used to register a receive handler

+ * function that is called by the driver when a UART receive data available (RDA)

+ * interrupt occurs. The UART_16550_set_rx_handler() function also enables the

+ * RDA interrupt at the Core16550 level. You must create and register the receive

+ * handler function to suit your application and it must include a call to the

+ * UART_16550_get_rx() function to actually read the received data.

+ *

+ * Note:    The driverÂ’s top level interrupt handler function UART_16550_isr()

+ * will call your receive handler function in response to an RDA interrupt from

+ * the Core16550.

+ *

+ * Note:    You can disable the RDA interrupt once the data is received by calling

+ * the UART_16550_disable_irq() function. This is your choice and is dependent

+ * upon your application.

+ *

+ * @param this_uart     The this_uart parameter is a pointer to a

+ *                      uart_16550_instance_t structure that holds all data

+ *                      regarding this instance of the Core16550.

+ * @param handler       The handler parameter is a pointer to a receive interrupt

+ *                      handler function provided by your application that will be

+ *                      called as a result of a UART RDA interrupt. This handler

+ *                      function must be of type uart_16550_irq_handler_t.

+ * @param trigger_level The trigger_level parameter is the receive FIFO

+ *                      trigger level. This specifies the number of bytes that

+ *                      must be received before the UART triggers an RDA

+ *                      interrupt.

+ * @return              This function does not return a value.

+ *

+ * Example:

+ * @code

+ * #include "core_16550.h"

+ *

+ * #define RX_BUFF_SIZE    64

+ * #define UART_57600_BAUD 26

+ *

+ * uint8_t g_rx_buff[RX_BUFF_SIZE];

+ * uart_16550_instance_t g_uart;

+ * void uart_rx_handler( uart_16550_instance_t * this_uart )

+ * {

+ *     UART_16550_get_rx( this_uart, g_rx_buff, RX_BUFF_SIZE );

+ * }

+ *

+ * int main(void)

+ * {

+ *     UART_16550_init( &g_uart, UART_57600_BAUD,

+ *                       ( UART_16550_DATA_8_BITS | UART_16550_NO_PARITY ) );

+ *     UART_16550_set_rx_handler( &g_uart, uart_rx_handler,

+ *                                UART_16550_FIFO_SINGLE_BYTE);

+ *     while ( 1 )

+ *     {

+ *         ;

+ *     }

+ *     return(0);

+ * }

+ * @endcode

+ */

+void

+UART_16550_set_rx_handler

+(

+    uart_16550_instance_t * this_uart,

+    uart_16550_irq_handler_t handler,

+    uart_16550_rx_trig_level_t trigger_level

+);

+

+/***************************************************************************//**

+ * The UART_16550_set_loopback() function is used to locally loopback the Tx

+ * and Rx lines of a Core16550 UART.

+ *

+ * @param this_uart     The this_uart parameter is a pointer to a

+ *                      uart_16550_instance_t structure that holds all data

+ *                      regarding this instance of the Core16550.

+ * @param loopback      The loopback parameter indicates whether or not the

+ *                      UART's transmit and receive lines should be looped back.

+ *                      Allowed values are as follows:

+ *                      •   UART_16550_LOOPBACK_ON

+ *                      •   UART_16550_LOOPBACK_OFF

+ * @return              This function does not return a value.

+ *

+ * Example:

+ * @code

+ * #include "core_16550.h"

+ *

+ * #define UART_57600_BAUD 26

+ * #define DATA_SIZE 4

+ *

+ * uart_16550_instance_t g_uart;

+ *

+ * int main(void)

+ * {

+ *      uint8_t txbuf[DATA_SIZE] = "abc";

+ *      uint8_t rxbuf[DATA_SIZE];

+ *      UART_16550_init( &g_uart, UART_57600_BAUD,

+ *                        ( UART_16550_DATA_8_BITS | UART_16550_NO_PARITY |

+ *                                               UART_16550_ONE_STOP_BIT) );

+ *      UART_16550_set_loopback( &g_uart, UART_16550_LOOPBACK_ON );

+ *

+ *      while(1)

+ *      {

+ *          UART_16550_polled_tx( &g_uart, txbuf, DATA_SIZE);

+ *          delay(100);

+ *          UART_16550_get_rx( &g_uart, rxbuf, DATA_SIZE);

+ *      }

+ * }

+ * @endcode

+ */

+void

+UART_16550_set_loopback

+(

+    uart_16550_instance_t * this_uart,

+    uart_16550_loopback_t loopback

+);

+

+/***************************************************************************//**

+ * The UART_16550_get_rx_status() function returns the receiver error status of

+ * the Core16550 instance. It reads both the current error status of the receiver

+ * from the UARTÂ’s line status register (LSR) and the accumulated error status

+ * from preceding calls to the UART_16550_get_rx() function, and it combines

+ * them using a bitwise OR. It returns the cumulative overrun, parity, framing,

+ * break and FIFO error status of the receiver, since the previous call to

+ * UART_16550_get_rx_status(), as an 8-bit encoded value.

+ *

+ * Note:    The UART_16550_get_rx() function reads and accumulates the receiver

+ * status of the Core16550 instance before reading each byte from the receiverÂ’s

+ * data register/FIFO. The driver maintains a sticky record of the cumulative

+ * receiver error status, which persists after the UART_16550_get_rx() function

+ * returns. The UART_16550_get_rx_status() function clears the driverÂ’s sticky

+ * receiver error record before returning.

+ *

+ * Note:    The driverÂ’s transmit functions also read the line status register

+ * (LSR) as part of their implementation. When the driver reads the LSR, the

+ * UART clears any active receiver error bits in the LSR. This could result in

+ * the driver losing receiver errors. To avoid any loss of receiver errors, the

+ * transmit functions also update the driverÂ’s sticky record of the cumulative

+ * receiver error status whenever they read the LSR.

+ *

+ * @param this_uart     The this_uart parameter is a pointer to a

+ *                      uart_16550_instance_t structure that holds all data

+ *                      regarding this instance of the Core16550.

+ * @return              This function returns the UARTÂ’s receiver error status

+ *                      as an 8-bit unsigned integer. The returned value is 0

+ *                      if no receiver errors occurred. The driver provides a

+ *                      set of bit mask constants that should be compared with

+ *                      and/or used to mask the returned value to determine the

+ *                      receiver error status.

+ *                      When the return value is compared to the following bit

+ *                      masks, a non-zero result indicates that the

+ *                      corresponding error occurred:

+ *                      •   UART_16550_OVERRUN_ERROR    (bit mask = 0x02)

+ *                      •   UART_16550_PARITY_ERROR     (bit mask = 0x04)

+ *                      •   UART_16550_FRAMING_ERROR    (bit mask = 0x08)

+ *                      •   UART_16550_BREAK_ERROR      (bit mask = 0x10)

+ *                      •   UART_16550_FIFO_ERROR       (bit mask = 0x80)

+ *                      When the return value is compared to the following bit

+ *                      mask, a non-zero result indicates that no error occurred:

+ *                      •   UART_16550_NO_ERROR         (bit mask = 0x00)

+ *                      Upon unsuccessful execution, this function returns:

+ *                      •   UART_16550_INVALID_PARAM    (bit mask = 0xFF)

+ *

+ * Example:

+ * @code

+ *   uart_16550_instance_t g_uart;

+ *   uint8_t rx_data[MAX_RX_DATA_SIZE];

+ *   uint8_t err_status;

+ *

+ *   err_status = UART_16550_get_rx_status(&g_uart);

+ *   if(UART_16550_NO_ERROR == err_status )

+ *   {

+ *        rx_size = UART_16550_get_rx( &g_uart, rx_data, MAX_RX_DATA_SIZE );

+ *   }

+ * @endcode

+ */

+uint8_t

+UART_16550_get_rx_status

+(

+    uart_16550_instance_t * this_uart

+);

+/***************************************************************************//**

+ * The UART_16550_enable_irq() function enables the Core16550 interrupts

+ * specified by the irq_mask parameter. The irq_mask parameter identifies the

+ * Core16550 interrupts by bit position, as defined in the interrupt enable

+ * register (IER) of Core16550. The Core16550 interrupts and their identifying

+ * irq_mask bit positions are as follows:

+ *      •   Receive data available interrupt (RDA)      (irq_mask bit 0)

+ *      •   Transmit holding register empty interrupt (THRE)    (irq_mask bit 1)

+ *      •   Receiver line status interrupt (LS)         (irq_mask bit 2)

+ *      •   Modem status interrupt (MS)         (irq_mask bit 3)

+ * When an irq_mask bit position is set to 1, this function enables the

+ * corresponding Core16550 interrupt in the IER register. When an irq_mask

+ * bit position is set to 0, the corresponding interruptÂ’s state remains

+ * unchanged in the IER register.

+ *

+ * @param this_uart     The this_uart parameter is a pointer to a

+ *                      uart_16550_instance_t structure that holds all data

+ *                      regarding this instance of the Core16550.

+ * @param irq_mask      The irq_mask parameter is used to select which of the

+ *                      Core16550Â’s interrupts you want to enable. The allowed

+ *                      value for the irq_mask parameter is one of the

+ *                      following constants or a bitwise OR of more than one:

+ *                      •   UART_16550_RBF_IRQ      (bit mask = 0x01)

+ *                      •   UART_16550_TBE_IRQ      (bit mask = 0x02)

+ *                      •   UART_16550_LS_IRQ       (bit mask = 0x04)

+ *                      •   UART_16550_MS_IRQ       (bit mask = 0x08)

+ * @return              This function does not return a value.

+ *

+ * Example:

+ * @code

+ *   UART_16550_enable_irq( &g_uart,( UART_16550_RBF_IRQ | UART_16550_TBE_IRQ ) );

+ * @endcode

+ */

+void

+UART_16550_enable_irq

+(

+    uart_16550_instance_t * this_uart,

+    uint8_t irq_mask

+);

+

+/***************************************************************************//**

+ * The UART_16550_disable_irq() function disables the Core16550 interrupts

+ * specified by the irq_mask parameter. The irq_mask parameter identifies the

+ * Core16550 interrupts by bit position, as defined in the interrupt enable

+ * register (IER) of Core16550. The Core16550 interrupts and their identifying

+ * bit positions are as follows:

+ *      •   Receive data available interrupt (RDA)              (irq_mask bit 0)

+ *      •   Transmit holding register empty interrupt (THRE)    (irq_mask bit 1)

+ *      •   Receiver line status interrupt (LS)                 (irq_mask bit 2)

+ *      •   Modem status interrupt (MS)                         (irq_mask bit 3)

+ * When an irq_mask bit position is set to 1, this function disables the

+ * corresponding Core16550 interrupt in the IER register. When an irq_mask bit

+ * position is set to 0, the corresponding interruptÂ’s state remains unchanged

+ * in the IER register.

+ *

+ * @param this_uart     The this_uart parameter is a pointer to a

+ *                      uart_16550_instance_t structure that holds all data

+ *                      regarding this instance of the Core16550.

+ * @param irq_mask      The irq_mask parameter is used to select which of the

+ *                      Core16550Â’s interrupts you want to disable. The allowed

+ *                      value for the irq_mask parameter is one of the

+ *                      following constants or a bitwise OR of more than one:

+ *                      •   UART_16550_RBF_IRQ      (bit mask = 0x01)

+ *                      •   UART_16550_TBE_IRQ      (bit mask = 0x02)

+ *                      •   UART_16550_LS_IRQ       (bit mask = 0x04)

+ *                      •   UART_16550_MS_IRQ       (bit mask = 0x08)

+ * @return              This function does not return a value.

+ *

+ * Example:

+ * @code

+ *   UART_16550_disable_irq( &g_uart, ( UART_16550_RBF_IRQ | UART_16550_TBE_IRQ ) );

+ * @endcode

+ */

+void

+UART_16550_disable_irq

+(

+    uart_16550_instance_t * this_uart,

+    uint8_t irq_mask

+);

+

+/***************************************************************************//**

+ * The UART_16550_get_modem_status() function returns the modem status of the

+ * Core16550 instance. It reads the modem status register (MSR) and returns the

+ * 8 bit value. The bit encoding of the returned value is exactly the same as

+ * the definition of the bits in the MSR.

+ *

+ * @param this_uart     The this_uart parameter is a pointer to a

+ *                      uart_16550_instance_t structure that holds all data

+ *                      regarding this instance of the Core16550.

+ * @return              This function returns current state of the UART's MSR

+ *                      as an 8 bit unsigned integer. The driver provides the

+ *                      following set of bit mask constants that should be

+ *                      compared with and/or used to mask the returned value

+ *                      to determine the modem status:

+ *                      •   UART_16550_DCTS (bit mask = 0x01)

+ *                      •   UART_16550_DDSR (bit mask = 0x02)

+ *                      •   UART_16550_TERI (bit mask = 0x04)

+ *                      •   UART_16550_DDCD (bit mask = 0x08)

+ *                      •   UART_16550_CTS  (bit mask = 0x10)

+ *                      •   UART_16550_DSR  (bit mask = 0x20)

+ *                      •   UART_16550_RI   (bit mask = 0x40)

+ *                      •   UART_16550_DCD  (bit mask = 0x80)

+ * Example:

+ * @code

+ *   void uart_modem_status_isr(uart_16550_instance_t * this_uart)

+ *   {

+ *      uint8_t status;

+ *      status = UART_16550_get_modem_status( this_uart );

+ *      if( status & UART_16550_DCTS )

+ *      {

+ *          uart_dcts_handler();

+ *      }

+ *      if( status & UART_16550_CTS )

+ *      {

+ *          uart_cts_handler();

+ *      }

+ *   }

+ * @endcode

+ */

+uint8_t

+UART_16550_get_modem_status

+(

+    uart_16550_instance_t * this_uart

+);

+

+/***************************************************************************//**

+ * The UART_16550_set_rxstatus_handler() function is used to register a receiver

+ * status handler function that is called by the driver when a UART receiver

+ * line status (RLS) interrupt occurs. The UART_16550_set_rxstatus_handler()

+ * function also enables the RLS interrupt at the Core16550 level. You must

+ * create and register the receiver status handler function to suit your

+ * application.

+ *

+ * Note:    The driverÂ’s top level interrupt handler function UART_16550_isr()

+ * will call your receive status handler function in response to an RLS

+ * interrupt from the Core16550.

+ *

+ * Note:    You can disable the RLS interrupt when required by calling the

+ * UART_16550_disable_irq() function. This is your choice and is dependent

+ * upon your application.

+ *

+ * @param this_uart     The this_uart parameter is a pointer to a

+ *                      uart_16550_instance_t structure that holds all data

+ *                      regarding this instance of the Core16550.

+ * @param handler       The handler parameter is a pointer to a receiver line

+ *                      status interrupt handler function provided by your

+ *                      application that will be called as a result of a

+ *                      UART RLS interrupt. This handler function must be

+ *                      of type uart_16550_irq_handler_t.

+ * Example:

+ * @code

+ * #include "core_16550.h"

+ *

+ * #define UART_57600_BAUD 26

+ *

+ * uart_16550_instance_t g_uart;

+ *

+ * void uart_rxsts_handler( uart_16550_instance_t * this_uart )

+ * {

+ *      uint8_t status;

+ *      status = UART_16550_get_rx_status( this_uart );

+ *      if( status & UART_16550_OVERUN_ERROR )

+ *      {

+ *          discard_rx_data();

+ *      }

+ * }

+ *

+ * int main(void)

+ * {

+ *     UART_16550_init( &g_uart, UART_57600_BAUD,

+ *                      UART_16550_DATA_8_BITS | UART_16550_NO_PARITY |

+ *                                             UART_16550_ONE_STOP_BIT );

+ *     UART_16550_set_rxstatus_handler( &g_uart, uart_rxsts_handler );

+ *

+ *     while ( 1 )

+ *     {

+ *         ;

+ *     }

+ *     return(0);

+ * }

+ * @endcode

+ */

+void

+UART_16550_set_rxstatus_handler

+(

+    uart_16550_instance_t * this_uart,

+    uart_16550_irq_handler_t handler

+);

+

+/***************************************************************************//**

+ * The UART_16550_set_tx_handler() function is used to register a transmit

+ * handler function that is called by the driver when a UART transmit holding

+ * register empty (THRE) interrupt occurs. The UART_16550_set_tx_handler()

+ * function also enables the THRE interrupt at the Core16550 level. You must

+ * create and register the transmit handler function to suit your application.

+ * You can use the UART_16550_fill_tx_fifo() function in your transmit handler

+ * function to write data to the transmitter.

+ *

+ * Note:    The driverÂ’s top level interrupt handler function UART_16550_isr()

+ * will call your transmit handler function in response to an THRE interrupt

+ * from the Core16550.

+ *

+ * Note:    You can disable the THRE interrupt when required by calling the

+ * UART_16550_disable_irq() function. This is your choice and is dependent

+ * upon your application.

+ *

+ * Note:    The UART_16550_irq_tx() function does not use the transmit handler

+ * function that you register with the UART_16550_set_tx_handler() function.

+ * It uses its own internal THRE interrupt handler function that overrides any

+ * custom interrupt handler that you register using the

+ * UART_16550_set_tx_handler() function.

+ *

+ * @param this_uart     The this_uart parameter is a pointer to a

+ *                      uart_16550_instance_t structure that holds all data

+ *                      regarding this instance of the Core16550.

+ * @param handler       The handler parameter is a pointer to a transmitter

+ *                      interrupt handler function provided by your application,

+ *                      which will be called as a result of a UART THRE interrupt.

+ *                      This handler is of uart_16550_irq_handler_t type.

+ * @return              This function does not return a value.

+ *

+ * Example:

+ * @code

+ * #include "core_16550.h"

+ *

+ * #define UART_57600_BAUD 26

+ *

+ * uart_16550_instance_t g_uart;

+ *

+ * uint8_t * g_tx_buffer;

+ * size_t g_tx_size = 0;

+ *

+ * void uart_tx_handler( uart_16550_instance_t * this_uart )

+ * {

+ *      size_t size_in_fifo;

+ *

+ *      size_in_fifo = UART_16550_fill_tx_fifo( this_uart,

+ *                                              (const uint8_t *)g_tx_buffer,

+ *                                              g_tx_size );

+ *

+ *      if(size_in_fifo == g_tx_size)

+ *      {

+ *         g_tx_size = 0;

+ *         UART_16550_disable_irq( this_uart, UART_16550_TBE_IRQ );

+ *      }

+ *      else

+ *      {

+ *         g_tx_buffer = &g_tx_buffer[size_in_fifo];

+ *         g_tx_size = g_tx_size - size_in_fifo;

+ *      }

+ *  }

+ *

+ *  int main(void)

+ *  {

+ *      uint8_t message[12] = "Hello world";

+ *

+ *      UART_16550_init( &g_uart, UART_57600_BAUD,

+ *                       UART_16550_DATA_8_BITS | UART_16550_NO_PARITY |

+ *                                            UART_16550_ONE_STOP_BIT );

+ *

+ *      g_tx_buffer = message;

+ *      g_tx_size = sizeof(message);

+ *

+ *      UART_16550_set_tx_handler( &g_uart, uart_tx_handler);

+ *

+ *      while ( 1 )

+ *      {

+ *          ;

+ *      }

+ *      return(0);

+ *  }

+ *

+ * @endcode

+ */

+void

+UART_16550_set_tx_handler

+(

+    uart_16550_instance_t * this_uart,

+    uart_16550_irq_handler_t handler

+);

+

+/***************************************************************************//**

+ * The UART_16550_set_modemstatus_handler() function is used to register a

+ * modem status handler function that is called by the driver when a UART modem

+ * status (MS) interrupt occurs. The UART_16550_set_modemstatus_handler()

+ * function also enables the MS interrupt at the Core16550 level. You must

+ * create and register the modem status handler function to suit your

+ * application.

+ *

+ * Note:    The driverÂ’s top level interrupt handler function UART_16550_isr()

+ * will call your receive status handler function in response to an MS interrupt

+ * from the Core16550.

+ *

+ * Note:    You can disable the MS interrupt when required by calling the

+ * UART_16550_disable_irq() function. This is your choice and is dependent

+ * upon your application.

+ *

+ * @param this_uart     The this_uart parameter is a pointer to a

+ *                      uart_16550_instance_t structure that holds all data

+ *                      regarding this instance of the Core16550.

+ * @param handler       The handler parameter is a pointer to a modem status

+ *                      interrupt handler function provided by your application

+ *                      that will be called as a result of a UART MS interrupt.

+ *                      This handler function must be of type

+ *                      uart_16550_irq_handler_t.

+ * @return              This function does not return a value.

+ *

+ * Example:

+ * @code

+ * #include "core_16550.h"

+ *

+ * #define UART_57600_BAUD 26

+ *

+ * uart_16550_instance_t g_uart;

+ *

+ * void uart_modem_handler( uart_16550_instance_t * this_uart )

+ * {

+ *      uint8_t status;

+ *      status = UART_16550_get_modem_status( this_uart );

+ *      if( status & UART_16550_CTS )

+ *      {

+ *          uart_cts_handler();

+ *      }

+ * }

+ *

+ * int main(void)

+ * {

+ *     UART_16550_init( &g_uart, UART_57600_BAUD,

+ *                      UART_16550_DATA_8_BITS | UART_16550_NO_PARITY |

+                                              UART_16550_ONE_STOP_BIT);

+ *     UART_16550_set_modemstatus_handler( &g_uart, uart_modem_handler);

+ *

+ *     while ( 1 )

+ *     {

+ *         ;

+ *     }

+ *     return(0);

+ * }

+ * @endcode

+ */

+void

+UART_16550_set_modemstatus_handler

+(

+    uart_16550_instance_t * this_uart,

+    uart_16550_irq_handler_t handler

+);

+

+/***************************************************************************//**

+ * The UART_16550_fill_tx_fifo() function fills the UART's hardware transmitter

+ * FIFO with the data found in the transmitter buffer that is passed via the

+ * tx_buffer function parameter. If the transmitter FIFO is not empty when the

+ * function is called, the function returns immediately without transferring

+ * any data to the FIFO; otherwise, the function transfers data from the

+ * transmitter buffer to the FIFO until it is full or until the complete

+ * contents of the transmitter buffer have been copied into the FIFO. The

+ * function returns the number of bytes copied into the UART's transmitter FIFO.

+ *

+ * Note:    This function reads the UARTÂ’s line status register (LSR) to check

+ * for the active state of the transmitter holding register empty (THRE) bit

+ * before transferring data from the data buffer to the transmitter FIFO. If

+ * THRE is 0, the function returns immediately, without transferring any data

+ * to the FIFO. If THRE is 1, the function transfers up to 16 bytes of data to

+ * the FIFO and then returns.

+ *

+ * Note:    The actual transmission over the serial connection will still be in

+ * progress when this function returns. Use the UART_16550_get_tx_status()

+ * function if you need to know when the transmitter is empty.

+ *

+ * @param this_uart     The this_uart parameter is a pointer to a

+ *                      uart_16550_instance_t structure that holds all data

+ *                      regarding this instance of the Core16550.

+ * @param tx_buffer     The tx_buffer parameter is a pointer to a buffer

+ *                      containing the data to be transmitted.

+ * @param tx_size       The tx_size parameter is the size in bytes, of the data

+ *                      to be transmitted.

+ * @return              This function returns the number of bytes copied

+ *                      into the UART's transmitter FIFO.

+ *

+ * Example:

+ * @code

+ *   void send_using_interrupt(uint8_t * pbuff, size_t tx_size)

+ *   {

+ *       size_t size_in_fifo;

+ *       size_in_fifo = UART_16550_fill_tx_fifo( &g_uart, pbuff, tx_size );

+ *   }

+ * @endcode

+ */

+size_t

+UART_16550_fill_tx_fifo

+(

+    uart_16550_instance_t * this_uart,

+    const uint8_t * tx_buffer,

+    size_t tx_size

+);

+

+/***************************************************************************//**

+ * The UART_16550_get_tx_status() function returns the transmitter status of

+ * the Core16550 instance. It reads both the UARTÂ’s line status register (LSR)

+ * and returns the status of the transmit holding register empty (THRE) and

+ * transmitter empty (TEMT) bits.

+ *

+ * @param this_uart     The this_uart parameter is a pointer to a

+ *                      uart_16550_instance_t structure that holds all data

+ *                      regarding this instance of the Core16550.

+ * @return              This function returns the UARTÂ’s transmitter status

+ *                      as an 8-bit unsigned integer. The returned value is 0

+ *                      if the transmitter status bits are not set or the

+ *                      function execution failed. The driver provides a set

+ *                      of bit mask constants that should be compared with

+ *                      and/or used to mask the returned value to determine

+ *                      the transmitter status.

+ *                      When the return value is compared to the following

+ *                      bitmasks, a non-zero result indicates that the

+ *                      corresponding transmitter status bit is set:

+ *                      •   UART_16550_THRE     (bit mask = 0x20)

+ *                      •   UART_16550_TEMT     (bit mask = 0x40)

+ *                      When the return value is compared to the following

+ *                      bit mask, a non-zero result indicates that the

+ *                      transmitter is busy or the function execution failed.

+ *                      •   UART_16550_TX_BUSY      (bit mask = 0x00)

+ * Example:

+ * @code

+ *   uint8_t tx_buff[10] = "abcdefghi";

+ *

+ *   UART_16550_polled_tx( &g_uart, tx_buff, sizeof(tx_buff));

+ *

+ *   while ( ! (UART_16550_TEMT & UART_16550_get_tx_status( &g_uart ) )  )

+ *   {

+ *      ;

+ *   }

+ * @endcode

+ */

+uint8_t

+UART_16550_get_tx_status

+(

+    uart_16550_instance_t * this_uart

+);

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif /* __CORE_16550_H */

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreGPIO/core_gpio.c b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreGPIO/core_gpio.c
new file mode 100644
index 0000000..e5dbd7e
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreGPIO/core_gpio.c
@@ -0,0 +1,461 @@
+/*******************************************************************************

+ * (c) Copyright 2008-2015 Microsemi SoC Products Group. All rights reserved.

+ * 

+ * CoreGPIO bare metal driver implementation.

+ *

+ * SVN $Revision: 7964 $

+ * SVN $Date: 2015-10-09 18:26:53 +0530 (Fri, 09 Oct 2015) $

+ */

+#include "core_gpio.h"

+#include "hal.h"

+#include "hal_assert.h"

+#include "coregpio_regs.h"

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#define GPIO_INT_ENABLE_MASK        (uint32_t)0x00000008UL

+#define OUTPUT_BUFFER_ENABLE_MASK   0x00000004UL

+

+

+#define NB_OF_GPIO  32

+

+#define CLEAR_ALL_IRQ32     (uint32_t)0xFFFFFFFF

+#define CLEAR_ALL_IRQ16     (uint16_t)0xFFFF

+#define CLEAR_ALL_IRQ8      (uint8_t)0xFF

+

+/*-------------------------------------------------------------------------*//**

+ * GPIO_init()

+ * See "core_gpio.h" for details of how to use this function.

+ */

+void GPIO_init

+(

+    gpio_instance_t *   this_gpio,

+    addr_t              base_addr,

+    gpio_apb_width_t    bus_width

+)

+{

+    uint8_t i = 0;

+    addr_t cfg_reg_addr = base_addr;

+    

+    this_gpio->base_addr = base_addr;

+    this_gpio->apb_bus_width = bus_width;

+    

+    /* Clear configuration. */

+    for( i = 0, cfg_reg_addr = base_addr; i < NB_OF_GPIO; ++i )

+    {

+        HW_set_8bit_reg( cfg_reg_addr, 0 );

+        cfg_reg_addr += 4;

+    }

+    /* Clear any pending interrupts */

+    switch( this_gpio->apb_bus_width )

+    {

+        case GPIO_APB_32_BITS_BUS:

+            HAL_set_32bit_reg( this_gpio->base_addr, IRQ, CLEAR_ALL_IRQ32 );

+            break;

+            

+        case GPIO_APB_16_BITS_BUS:

+            HAL_set_16bit_reg( this_gpio->base_addr, IRQ0, (uint16_t)CLEAR_ALL_IRQ16 );

+            HAL_set_16bit_reg( this_gpio->base_addr, IRQ1, (uint16_t)CLEAR_ALL_IRQ16 );

+            break;

+            

+        case GPIO_APB_8_BITS_BUS:

+            HAL_set_8bit_reg( this_gpio->base_addr, IRQ0, (uint8_t)CLEAR_ALL_IRQ8 );

+            HAL_set_8bit_reg( this_gpio->base_addr, IRQ1, (uint8_t)CLEAR_ALL_IRQ8 );

+            HAL_set_8bit_reg( this_gpio->base_addr, IRQ2, (uint8_t)CLEAR_ALL_IRQ8 );

+            HAL_set_8bit_reg( this_gpio->base_addr, IRQ3, (uint8_t)CLEAR_ALL_IRQ8 );

+            break;

+            

+        default:

+            HAL_ASSERT(0);

+            break;

+    }

+}

+

+/*-------------------------------------------------------------------------*//**

+ * GPIO_config

+ * See "core_gpio.h" for details of how to use this function.

+ */

+void GPIO_config

+(

+    gpio_instance_t *   this_gpio,

+    gpio_id_t           port_id,

+    uint32_t            config

+)

+{

+    HAL_ASSERT( port_id < NB_OF_GPIO );

+    

+    if ( port_id < NB_OF_GPIO )

+    {

+        uint32_t cfg_reg_addr = this_gpio->base_addr;

+        cfg_reg_addr += (port_id * 4);

+        HW_set_32bit_reg( cfg_reg_addr, config );

+        

+        /*

+         * Verify that the configuration was correctly written. Failure to read

+         * back the expected value may indicate that the GPIO port was configured

+         * as part of the hardware flow and cannot be modified through software.

+         * It may also indicate that the base address passed as parameter to

+         * GPIO_init() was incorrect.

+         */

+        HAL_ASSERT( HW_get_32bit_reg( cfg_reg_addr ) == config );

+    }

+}

+

+/*-------------------------------------------------------------------------*//**

+ * GPIO_set_outputs

+ * See "core_gpio.h" for details of how to use this function.

+ */

+void GPIO_set_outputs

+(

+    gpio_instance_t *   this_gpio,

+    uint32_t            value

+)

+{

+    switch( this_gpio->apb_bus_width )

+    {

+        case GPIO_APB_32_BITS_BUS:

+            HAL_set_32bit_reg( this_gpio->base_addr, GPIO_OUT, value );

+            break;

+            

+        case GPIO_APB_16_BITS_BUS:

+            HAL_set_16bit_reg( this_gpio->base_addr, GPIO_OUT0, (uint16_t)value );

+            HAL_set_16bit_reg( this_gpio->base_addr, GPIO_OUT1, (uint16_t)(value >> 16) );

+            break;

+            

+        case GPIO_APB_8_BITS_BUS:

+            HAL_set_8bit_reg( this_gpio->base_addr, GPIO_OUT0, (uint8_t)value );

+            HAL_set_8bit_reg( this_gpio->base_addr, GPIO_OUT1, (uint8_t)(value >> 8) );

+            HAL_set_8bit_reg( this_gpio->base_addr, GPIO_OUT2, (uint8_t)(value >> 16) );

+            HAL_set_8bit_reg( this_gpio->base_addr, GPIO_OUT3, (uint8_t)(value >> 24) );

+            break;

+            

+        default:

+            HAL_ASSERT(0);

+            break;

+    }

+    

+    /*

+     * Verify that the output register was correctly written. Failure to read back

+     * the expected value may indicate that some of the GPIOs may not exist due to

+     * the number of GPIOs selected in the CoreGPIO hardware flow configuration.

+     * It may also indicate that the base address or APB bus width passed as

+     * parameter to the GPIO_init() function do not match the hardware design.

+     */

+    HAL_ASSERT( GPIO_get_outputs( this_gpio ) == value );

+}

+

+/*-------------------------------------------------------------------------*//**

+ * GPIO_get_inputs

+ * See "core_gpio.h" for details of how to use this function.

+ */

+uint32_t GPIO_get_inputs

+(

+    gpio_instance_t *   this_gpio

+)

+{

+    uint32_t gpio_in = 0;

+    

+    switch( this_gpio->apb_bus_width )

+    {

+        case GPIO_APB_32_BITS_BUS:

+            gpio_in = HAL_get_32bit_reg( this_gpio->base_addr, GPIO_IN );

+            break;

+            

+        case GPIO_APB_16_BITS_BUS:

+            gpio_in |= HAL_get_16bit_reg( this_gpio->base_addr, GPIO_IN0 );

+            gpio_in |= (HAL_get_16bit_reg( this_gpio->base_addr, GPIO_IN1 ) << 16);

+            break;

+            

+        case GPIO_APB_8_BITS_BUS:

+            gpio_in |= HAL_get_8bit_reg( this_gpio->base_addr, GPIO_IN0 );

+            gpio_in |= (HAL_get_8bit_reg( this_gpio->base_addr, GPIO_IN1 ) << 8);

+            gpio_in |= (HAL_get_8bit_reg( this_gpio->base_addr, GPIO_IN2 ) << 16);

+            gpio_in |= (HAL_get_8bit_reg( this_gpio->base_addr, GPIO_IN3 ) << 24);

+            break;

+            

+        default:

+            HAL_ASSERT(0);

+            break;

+    }

+    

+    return gpio_in;

+}

+

+/*-------------------------------------------------------------------------*//**

+ * GPIO_get_outputs

+ * See "core_gpio.h" for details of how to use this function.

+ */

+uint32_t GPIO_get_outputs

+(

+    gpio_instance_t *   this_gpio

+)

+{

+    uint32_t gpio_out = 0;

+    

+    switch( this_gpio->apb_bus_width )

+    {

+        case GPIO_APB_32_BITS_BUS:

+            gpio_out = HAL_get_32bit_reg( this_gpio->base_addr, GPIO_OUT );

+            break;

+            

+        case GPIO_APB_16_BITS_BUS:

+            gpio_out |= HAL_get_16bit_reg( this_gpio->base_addr, GPIO_OUT0 );

+            gpio_out |= (HAL_get_16bit_reg( this_gpio->base_addr, GPIO_OUT1 ) << 16);

+            break;

+            

+        case GPIO_APB_8_BITS_BUS:

+            gpio_out |= HAL_get_16bit_reg( this_gpio->base_addr, GPIO_OUT0 );

+            gpio_out |= (HAL_get_16bit_reg( this_gpio->base_addr, GPIO_OUT1 ) << 8);

+            gpio_out |= (HAL_get_16bit_reg( this_gpio->base_addr, GPIO_OUT2 ) << 16);

+            gpio_out |= (HAL_get_16bit_reg( this_gpio->base_addr, GPIO_OUT3 ) << 24);

+            break;

+            

+        default:

+            HAL_ASSERT(0);

+            break;

+    }

+    

+    return gpio_out;

+}

+

+/*-------------------------------------------------------------------------*//**

+ * GPIO_set_output

+ * See "core_gpio.h" for details of how to use this function.

+ */

+void GPIO_set_output

+(

+    gpio_instance_t *   this_gpio,

+    gpio_id_t           port_id,

+    uint8_t             value

+)

+{

+    HAL_ASSERT( port_id < NB_OF_GPIO );

+    

+            

+    switch( this_gpio->apb_bus_width )

+    {

+        case GPIO_APB_32_BITS_BUS:

+            {

+                uint32_t outputs_state;

+                

+                outputs_state = HAL_get_32bit_reg( this_gpio->base_addr, GPIO_OUT );

+                if ( 0 == value )

+                {

+                    outputs_state &= ~(1 << port_id);

+                }

+                else

+                {

+                    outputs_state |= 1 << port_id;

+                }

+                HAL_set_32bit_reg( this_gpio->base_addr, GPIO_OUT, outputs_state );

+                

+                /*

+                 * Verify that the output register was correctly written. Failure to read back

+                 * the expected value may indicate that some of the GPIOs may not exist due to

+                 * the number of GPIOs selected in the CoreGPIO hardware flow configuration.

+                 * It may also indicate that the base address or APB bus width passed as

+                 * parameter to the GPIO_init() function do not match the hardware design.

+                 */

+                HAL_ASSERT( HAL_get_32bit_reg( this_gpio->base_addr, GPIO_OUT ) == outputs_state );

+            }

+            break;

+            

+        case GPIO_APB_16_BITS_BUS:

+            {

+                uint16_t outputs_state;

+                uint32_t gpio_out_reg_addr = this_gpio->base_addr + GPIO_OUT_REG_OFFSET + ((port_id >> 4) * 4);

+                

+                outputs_state = HW_get_16bit_reg( gpio_out_reg_addr );

+                if ( 0 == value )

+                {

+                    outputs_state &= ~(1 << (port_id & 0x0F));

+                }

+                else

+                {

+                    outputs_state |= 1 << (port_id & 0x0F);

+                }

+                HW_set_16bit_reg( gpio_out_reg_addr, outputs_state );

+                

+                /*

+                 * Verify that the output register was correctly written. Failure to read back

+                 * the expected value may indicate that some of the GPIOs may not exist due to

+                 * the number of GPIOs selected in the CoreGPIO hardware flow configuration.

+                 * It may also indicate that the base address or APB bus width passed as

+                 * parameter to the GPIO_init() function do not match the hardware design.

+                 */

+                HAL_ASSERT( HW_get_16bit_reg( gpio_out_reg_addr ) == outputs_state );

+            }

+            break;

+            

+        case GPIO_APB_8_BITS_BUS:

+            {

+                uint8_t outputs_state;

+                uint32_t gpio_out_reg_addr = this_gpio->base_addr + GPIO_OUT_REG_OFFSET + ((port_id >> 3) * 4);

+                

+                outputs_state = HW_get_8bit_reg( gpio_out_reg_addr );

+                if ( 0 == value )

+                {

+                    outputs_state &= ~(1 << (port_id & 0x07));

+                }

+                else

+                {

+                    outputs_state |= 1 << (port_id & 0x07);

+                }

+                HW_set_8bit_reg( gpio_out_reg_addr, outputs_state );

+                

+                /*

+                 * Verify that the output register was correctly written. Failure to read back

+                 * the expected value may indicate that some of the GPIOs may not exist due to

+                 * the number of GPIOs selected in the CoreGPIO hardware flow configuration.

+                 * It may also indicate that the base address or APB bus width passed as

+                 * parameter to the GPIO_init() function do not match the hardware design.

+                 */

+                HAL_ASSERT( HW_get_8bit_reg( gpio_out_reg_addr ) == outputs_state );

+            }

+            break;

+            

+        default:

+            HAL_ASSERT(0);

+            break;

+    }

+}

+

+/*-------------------------------------------------------------------------*//**

+ * GPIO_drive_inout

+ * See "core_gpio.h" for details of how to use this function.

+ */

+void GPIO_drive_inout

+(

+    gpio_instance_t *   this_gpio,

+    gpio_id_t           port_id,

+    gpio_inout_state_t  inout_state

+)

+{

+    uint32_t config;

+    uint32_t cfg_reg_addr = this_gpio->base_addr;

+    

+    HAL_ASSERT( port_id < NB_OF_GPIO );

+

+    switch( inout_state )

+    {

+        case GPIO_DRIVE_HIGH:

+            /* Set output high */

+            GPIO_set_output( this_gpio, port_id, 1 );

+            

+            /* Enable output buffer */

+            cfg_reg_addr = this_gpio->base_addr + (port_id * 4);

+            config = HW_get_8bit_reg( cfg_reg_addr );

+            config |= OUTPUT_BUFFER_ENABLE_MASK;

+            HW_set_8bit_reg( cfg_reg_addr, config );

+            break;

+            

+        case GPIO_DRIVE_LOW:

+            /* Set output low */

+            GPIO_set_output( this_gpio, port_id, 0 );

+            

+            /* Enable output buffer */

+            cfg_reg_addr = this_gpio->base_addr + (port_id * 4);

+            config = HW_get_8bit_reg( cfg_reg_addr );

+            config |= OUTPUT_BUFFER_ENABLE_MASK;

+            HW_set_8bit_reg( cfg_reg_addr, config );

+            break;

+            

+        case GPIO_HIGH_Z:

+            /* Disable output buffer */

+            cfg_reg_addr = this_gpio->base_addr + (port_id * 4);

+            config = HW_get_8bit_reg( cfg_reg_addr );

+            config &= ~OUTPUT_BUFFER_ENABLE_MASK;

+            HW_set_8bit_reg( cfg_reg_addr, config );

+            break;

+            

+        default:

+            HAL_ASSERT(0);

+            break;

+    }

+}

+

+/*-------------------------------------------------------------------------*//**

+ * GPIO_enable_irq

+ * See "core_gpio.h" for details of how to use this function.

+ */

+void GPIO_enable_irq

+(

+    gpio_instance_t *   this_gpio,

+    gpio_id_t           port_id

+)

+{

+    uint32_t cfg_value;

+    uint32_t cfg_reg_addr = this_gpio->base_addr;

+   

+    HAL_ASSERT( port_id < NB_OF_GPIO );

+    

+    if ( port_id < NB_OF_GPIO )

+    {

+        cfg_reg_addr += (port_id * 4);

+        cfg_value = HW_get_8bit_reg( cfg_reg_addr );

+        cfg_value |= GPIO_INT_ENABLE_MASK;

+        HW_set_8bit_reg( cfg_reg_addr, cfg_value );

+    }

+}

+

+/*-------------------------------------------------------------------------*//**

+ * GPIO_disable_irq

+ * See "core_gpio.h" for details of how to use this function.

+ */

+void GPIO_disable_irq

+(

+    gpio_instance_t *   this_gpio,

+    gpio_id_t           port_id

+)

+{

+    uint32_t cfg_value;

+    uint32_t cfg_reg_addr = this_gpio->base_addr;

+   

+    HAL_ASSERT( port_id < NB_OF_GPIO );

+    

+    if ( port_id < NB_OF_GPIO )

+    {

+        cfg_reg_addr += (port_id * 4);

+        cfg_value = HW_get_8bit_reg( cfg_reg_addr );

+        cfg_value &= ~GPIO_INT_ENABLE_MASK;

+        HW_set_8bit_reg( cfg_reg_addr, cfg_value );

+    }

+}

+

+/*-------------------------------------------------------------------------*//**

+ * GPIO_clear_irq

+ * See "core_gpio.h" for details of how to use this function.

+ */

+void GPIO_clear_irq

+(

+    gpio_instance_t *   this_gpio,

+    gpio_id_t           port_id

+)

+{

+    uint32_t irq_clr_value = ((uint32_t)1) << ((uint32_t)port_id);

+    

+    switch( this_gpio->apb_bus_width )

+    {

+        case GPIO_APB_32_BITS_BUS:

+            HAL_set_32bit_reg( this_gpio->base_addr, IRQ, irq_clr_value );

+            break;

+            

+        case GPIO_APB_16_BITS_BUS:

+            HAL_set_16bit_reg( this_gpio->base_addr, IRQ0, irq_clr_value );

+            HAL_set_16bit_reg( this_gpio->base_addr, IRQ1, irq_clr_value >> 16 );

+            break;

+            

+        case GPIO_APB_8_BITS_BUS:

+            HAL_set_8bit_reg( this_gpio->base_addr, IRQ0, irq_clr_value );

+            HAL_set_8bit_reg( this_gpio->base_addr, IRQ1, irq_clr_value >> 8 );

+            HAL_set_8bit_reg( this_gpio->base_addr, IRQ2, irq_clr_value >> 16 );

+            HAL_set_8bit_reg( this_gpio->base_addr, IRQ3, irq_clr_value >> 24 );

+            break;

+            

+        default:

+            HAL_ASSERT(0);

+            break;

+    }

+}

+

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreGPIO/core_gpio.h b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreGPIO/core_gpio.h
new file mode 100644
index 0000000..68799be
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreGPIO/core_gpio.h
@@ -0,0 +1,552 @@
+/*******************************************************************************

+ * (c) Copyright 2008-2015 Microsemi SoC Products Group. All rights reserved.

+ * 

+ *  CoreGPIO bare metal driver public API.

+ *

+ * SVN $Revision: 7964 $

+ * SVN $Date: 2015-10-09 18:26:53 +0530 (Fri, 09 Oct 2015) $

+ */

+

+/*=========================================================================*//**

+  @mainpage CoreGPIO Bare Metal Driver.

+

+  @section intro_sec Introduction

+  The CoreGPIO hardware IP includes up to 32 general purpose input output GPIOs.

+  This driver provides a set of functions for controlling the GPIOs as part of a

+  bare metal system where no operating system is available. These drivers

+  can be adapted for use as part of an operating system but the implementation

+  of the adaptation layer between this driver and the operating system's driver

+  model is outside the scope of this driver.

+  

+  @section driver_configuration Driver Configuration

+  The CoreGPIO individual IOs can be configured either in the hardware flow or

+  as part of the software application through calls to the GPIO_config() function.

+  GPIOs configured as as part of the hardware is fixed and cannot be modified

+  using a call to the GPI_config() function.

+  

+  @section theory_op Theory of Operation

+  The CoreGPIO driver uses the Actel Hardware Abstraction Layer (HAL) to access

+  hardware registers. You must ensure that the Actel HAL is included as part of

+  your software project. The Actel HAL is available through the Actel Firmware

+  Catalog.

+  

+  The CoreGPIO driver functions are logically grouped into the following groups:

+    - Initiliazation

+    - Configuration

+    - Reading and writing GPIO state

+    - Interrupt control

+  

+  The CoreGPIO driver is initialized through a call to the GPIO_init() function.

+  The GPIO_init() function must be called before any other GPIO driver functions

+  can be called.

+  

+  Each GPIO port is individually configured through a call to the

+  GPIO_config() function. Configuration includes deciding if a GPIO port

+  will be used as input, output or both. GPIO ports configured as inputs can be

+  further configured to generate interrupts based on the input's state.

+  Interrupts can be level or edge sensitive.

+  Please note that a CoreGPIO hardware instance can be generated, as part of the

+  hardware flow, with a fixed configuration for some or all of its IOs. Attempting

+  to modify the configuration of such a hardware configured IO using the

+  GPIO_config() function has no effect.

+  

+  The state of the GPIO ports can be read and written using the following

+  functions:

+    - GPIO_get_inputs()

+    - GPIO_get_outputs()

+    - GPIO_set_outputs()

+    - GPIO_drive_inout()

+    

+  Interrupts generated by GPIO ports configured as inputs are controlled using

+  the following functions:

+    - GPIO_enable_irq()

+    - GPIO_disable_irq()

+    - GPIO_clear_irq()

+  

+ *//*=========================================================================*/

+#ifndef CORE_GPIO_H_

+#define CORE_GPIO_H_

+

+#include <stdint.h>

+#include "cpu_types.h"

+

+/*-------------------------------------------------------------------------*//**

+  The gpio_id_t enumeration is used to identify GPIOs as part of the

+  parameter to functions:

+    - GPIO_config(),

+    - GPIO_drive_inout(),

+    - GPIO_enable_int(),

+    - GPIO_disable_int(),

+    - GPIO_clear_int()

+ */

+typedef enum __gpio_id_t

+{

+    GPIO_0 = 0,

+    GPIO_1 = 1,

+    GPIO_2 = 2,

+    GPIO_3 = 3,

+    GPIO_4 = 4,

+    GPIO_5 = 5,

+    GPIO_6 = 6,

+    GPIO_7 = 7,

+    GPIO_8 = 8,

+    GPIO_9 = 9,

+    GPIO_10 = 10,

+    GPIO_11 = 11,

+    GPIO_12 = 12,

+    GPIO_13 = 13,

+    GPIO_14 = 14,

+    GPIO_15 = 15,

+    GPIO_16 = 16,

+    GPIO_17 = 17,

+    GPIO_18 = 18,

+    GPIO_19 = 19,

+    GPIO_20 = 20,

+    GPIO_21 = 21,

+    GPIO_22 = 22,

+    GPIO_23 = 23,

+    GPIO_24 = 24,

+    GPIO_25 = 25,

+    GPIO_26 = 26,

+    GPIO_27 = 27,

+    GPIO_28 = 28,

+    GPIO_29 = 29,

+    GPIO_30 = 30,

+    GPIO_31 = 31

+} gpio_id_t;

+

+typedef enum __gpio_apb_width_t

+{

+    GPIO_APB_8_BITS_BUS = 0,

+    GPIO_APB_16_BITS_BUS = 1,

+    GPIO_APB_32_BITS_BUS = 2,

+    GPIO_APB_UNKNOWN_BUS_WIDTH = 3

+} gpio_apb_width_t;

+

+/*-------------------------------------------------------------------------*//**

+ */

+typedef struct __gpio_instance_t

+{

+    addr_t              base_addr;

+    gpio_apb_width_t    apb_bus_width;

+} gpio_instance_t;

+

+/*-------------------------------------------------------------------------*//**

+  GPIO ports definitions used to identify GPIOs as part of the parameter to

+  function GPIO_set_outputs().

+  These definitions can also be used to identity GPIO through logical

+  operations on the return value of function GPIO_get_inputs().

+ */

+#define GPIO_0_MASK		    0x00000001UL

+#define GPIO_1_MASK		    0x00000002UL

+#define GPIO_2_MASK         0x00000004UL

+#define GPIO_3_MASK	        0x00000008UL

+#define GPIO_4_MASK	        0x00000010UL

+#define GPIO_5_MASK	        0x00000020UL

+#define GPIO_6_MASK	        0x00000040UL

+#define GPIO_7_MASK	        0x00000080UL

+#define GPIO_8_MASK	        0x00000100UL

+#define GPIO_9_MASK		    0x00000200UL

+#define GPIO_10_MASK		0x00000400UL

+#define GPIO_11_MASK		0x00000800UL

+#define GPIO_12_MASK		0x00001000UL

+#define GPIO_13_MASK		0x00002000UL

+#define GPIO_14_MASK		0x00004000UL

+#define GPIO_15_MASK		0x00008000UL

+#define GPIO_16_MASK		0x00010000UL

+#define GPIO_17_MASK		0x00020000UL

+#define GPIO_18_MASK		0x00040000UL

+#define GPIO_19_MASK		0x00080000UL

+#define GPIO_20_MASK		0x00100000UL

+#define GPIO_21_MASK		0x00200000UL

+#define GPIO_22_MASK		0x00400000UL

+#define GPIO_23_MASK		0x00800000UL

+#define GPIO_24_MASK		0x01000000UL

+#define GPIO_25_MASK		0x02000000UL

+#define GPIO_26_MASK		0x04000000UL

+#define GPIO_27_MASK		0x08000000UL

+#define GPIO_28_MASK		0x10000000UL

+#define GPIO_29_MASK		0x20000000UL

+#define GPIO_30_MASK		0x40000000UL

+#define GPIO_31_MASK		0x80000000UL

+

+/*-------------------------------------------------------------------------*//**

+ * GPIO modes

+ */

+#define GPIO_INPUT_MODE              0x0000000002UL

+#define GPIO_OUTPUT_MODE             0x0000000005UL

+#define GPIO_INOUT_MODE              0x0000000003UL

+

+/*-------------------------------------------------------------------------*//**

+ * Possible GPIO inputs interrupt configurations.

+ */

+#define GPIO_IRQ_LEVEL_HIGH			0x0000000000UL

+#define GPIO_IRQ_LEVEL_LOW			0x0000000020UL

+#define GPIO_IRQ_EDGE_POSITIVE		0x0000000040UL

+#define GPIO_IRQ_EDGE_NEGATIVE		0x0000000060UL

+#define GPIO_IRQ_EDGE_BOTH			0x0000000080UL

+

+/*-------------------------------------------------------------------------*//**

+ * Possible states for GPIO configured as INOUT.

+ */

+typedef enum gpio_inout_state

+{

+    GPIO_DRIVE_LOW = 0,

+    GPIO_DRIVE_HIGH,

+    GPIO_HIGH_Z

+} gpio_inout_state_t;

+

+/*-------------------------------------------------------------------------*//**

+  The GPIO_init() function initialises a CoreGPIO hardware instance and the data

+  structure associated with the CoreGPIO hardware instance.

+  Please note that a CoreGPIO hardware instance can be generated with a fixed

+  configuration for some or all of its IOs as part of the hardware flow. Attempting

+  to modify the configuration of such a hardware configured IO using the

+  GPIO_config() function has no effect.

+

+  @param this_gpio

+    Pointer to the gpio_instance_t data structure instance holding all data

+    regarding the CoreGPIO hardware instance being initialized. A pointer to the

+    same data structure will be used in subsequent calls to the CoreGPIO driver

+    functions in order to identify the CoreGPIO instance that should perform the

+    operation implemented by the called driver function.

+

+  @param base_addr

+    The base_addr parameter is the base address in the processor's memory map for

+    the registers of the GPIO instance being initialized.

+    

+  @param bus_width

+    The bus_width parameter informs the driver of the APB bus width selected during

+    the hardware flow configuration of the CoreGPIO hardware instance. It indicates

+    to the driver whether the CoreGPIO hardware registers will be visible as 8, 16

+    or 32 bits registers. Allowed value are:

+        - GPIO_APB_8_BITS_BUS

+        - GPIO_APB_16_BITS_BUS

+        - GPIO_APB_32_BITS_BUS

+  

+  @return

+    none.

+    

+  Example:

+  @code

+    #define COREGPIO_BASE_ADDR  0xC2000000

+    

+    gpio_instance_t g_gpio;

+    

+    void system_init( void )

+    {

+        GPIO_init( &g_gpio,	COREGPIO_BASE_ADDR, GPIO_APB_32_BITS_BUS );

+    }

+  @endcode

+  */

+void GPIO_init

+(

+    gpio_instance_t *   this_gpio,

+    addr_t              base_addr,

+    gpio_apb_width_t    bus_width

+);

+

+/*-------------------------------------------------------------------------*//**

+  The GPIO_config() function is used to configure an individual GPIO port.

+ 

+  @param this_gpio

+    The this_gpio parameter is a pointer to the gpio_instance_t structure holding

+    all data regarding the CoreGPIO instance controlled through this function call.

+

+  @param port_id

+    The port_id parameter identifies the GPIO port to be configured.

+    An enumeration item of the form GPIO_n where n is the number of the GPIO

+    port is used to identify the GPIO port. For example GPIO_0 identifies the

+    first GPIO port and GPIO_31 the last one.

+    

+  @param config

+    The config parameter specifies the configuration to be applied to the GPIO

+    port identified by the first parameter. It is a logical OR of GPIO mode and

+    the interrupt mode. The interrupt mode is only relevant if the GPIO is

+    configured as input.

+       Possible modes are:

+           - GPIO_INPUT_MODE,

+           - GPIO_OUTPUT_MODE,

+           - GPIO_INOUT_MODE.

+       Possible interrupt modes are:

+           - GPIO_IRQ_LEVEL_HIGH,

+           - GPIO_IRQ_LEVEL_LOW,

+           - GPIO_IRQ_EDGE_POSITIVE,

+           - GPIO_IRQ_EDGE_NEGATIVE,

+           - GPIO_IRQ_EDGE_BOTH

+ 

+  @return

+    none.

+    

+  For example the following call will configure GPIO 4 as an input generating

+  interrupts on a low to high transition of the input:

+  @code

+  GPIO_config( &g_gpio, GPIO_4, GPIO_INPUT_MODE | GPIO_IRQ_EDGE_POSITIVE );

+  @endcode

+ */

+void GPIO_config

+(

+    gpio_instance_t *   this_gpio,

+    gpio_id_t           port_id,

+    uint32_t            config

+);

+

+/*-------------------------------------------------------------------------*//**

+  The GPIO_set_outputs() function is used to set the state of the GPIO ports

+  configured as outputs.

+ 

+  @param this_gpio

+    The this_gpio parameter is a pointer to the gpio_instance_t structure holding

+    all data regarding the CoreGPIO instance controlled through this function call.

+

+  @param value

+    The value parameter specifies the state of the GPIO ports configured as

+    outputs. It is a bit mask of the form (GPIO_n_MASK | GPIO_m_MASK) where n

+    and m are numbers identifying GPIOs.

+    For example (GPIO_0_MASK | GPIO_1_MASK | GPIO_2_MASK ) specifies that the

+    first, second and third GPIOs' must be set high and all other outputs set

+    low.

+

+  @return

+    none.

+    

+  Example 1:

+    Set GPIOs outputs 0 and 8 high and all other GPIO outputs low.

+    @code

+        GPIO_set_outputs( &g_gpio, GPIO_0_MASK | GPIO_8_MASK );

+    @endcode

+

+  Example 2:

+    Set GPIOs outputs 2 and 4 low without affecting other GPIO outputs.

+    @code

+        uint32_t gpio_outputs;

+        gpio_outputs = GPIO_get_outputs( &g_gpio );

+        gpio_outputs &= ~( GPIO_2_MASK | GPIO_4_MASK );

+        GPIO_set_outputs( &g_gpio, gpio_outputs );

+    @endcode

+

+  @see GPIO_get_outputs()

+ */

+void GPIO_set_outputs

+(

+    gpio_instance_t *   this_gpio,

+    uint32_t            value

+);

+

+/*-------------------------------------------------------------------------*//**

+  The GPIO_set_output() function is used to set the state of a single GPIO

+  port configured as output.

+ 

+  @param this_gpio

+    The this_gpio parameter is a pointer to the gpio_instance_t structure holding

+    all data regarding the CoreGPIO instance controlled through this function call.

+

+  @param port_id

+    The port_id parameter specifies the GPIO port that will have its output set

+    by a call to this function.

+  

+  @param value

+    The value parameter specifies the desired state for the GPIO output. A value

+    of 0 will set the output low and a value of 1 will set the port high.

+  

+  @return

+    none.

+ */

+void GPIO_set_output

+(

+    gpio_instance_t *   this_gpio,

+    gpio_id_t           port_id,

+    uint8_t             value

+);

+

+/*-------------------------------------------------------------------------*//**

+  The GPIO_get_inputs() function is used to read the state of all GPIOs

+  confgured as inputs.

+ 

+  @param this_gpio

+    The this_gpio parameter is a pointer to the gpio_instance_t structure holding

+    all data regarding the CoreGPIO instance controlled through this function call.

+

+  @return

+    This function returns a 32 bit unsigned integer where each bit represents

+    the state of an input. The least significant bit representing the state of

+    GPIO 0 and the most significant bit the state of GPIO 31.

+ */

+uint32_t GPIO_get_inputs

+(

+    gpio_instance_t *   this_gpio

+);

+

+/*-------------------------------------------------------------------------*//**

+  The GPIO_get_outputs() function is used to read the current state of all

+  GPIO outputs.

+ 

+  @param this_gpio

+    The this_gpio parameter is a pointer to the gpio_instance_t structure holding

+    all data regarding the CoreGPIO instance controlled through this function call.

+

+  @return

+     This function returns a 32 bit unsigned integer where each bit represents

+     the state of an output. The least significant bit representing the state

+     of GPIO 0 and the most significant bit the state of GPIO 31.

+ */

+uint32_t GPIO_get_outputs

+(

+    gpio_instance_t *   this_gpio

+);

+

+/*-------------------------------------------------------------------------*//**

+  The GPIO_drive_inout() function is used to set the output state of a

+  GPIO configured as INOUT. An INOUT GPIO can be in one of three states:

+    - high

+    - low

+    - high impedance

+  An INOUT output would typically be used where several devices can drive the

+  state of a signal. The high and low states are equivalent to the high and low

+  states of a GPIO configured as output. The high impedance state is used to

+  prevent the GPIO from driving the state of the output and therefore allow

+  reading the state of the GPIO as an input.

+  Please note that the GPIO port you wish to use as INOUT through this function

+  must be configurable through software. Therefore the GPIO ports used as INOUT

+  must not have a fixed configuration selected as part of the hardware flow.

+ 

+  @param this_gpio

+    The this_gpio parameter is a pointer to the gpio_instance_t structure holding

+    all data regarding the CoreGPIO instance controlled through this function call.

+

+  @param port_id

+    The port_id parameter identifies the GPIO for whcih this function will

+    change the output state.

+    An enumeration item of the form GPIO_n where n is the number of the GPIO

+    port is used to identify the GPIO port. For example GPIO_0 identifies the

+    first GPIO port and GPIO_31 the last one.

+    

+  @param inout_state

+    The inout_state parameter specifies the state of the I/O identified by the

+    first parameter. Possible states are:

+                           - GPIO_DRIVE_HIGH,

+                           - GPIO_DRIVE_LOW,

+                           - GPIO_HIGH_Z (high impedance)

+

+  @return

+    none.

+    

+  Example:

+    The call to GPIO_drive_inout() below will set the GPIO 7 output to

+    high impedance state.

+    @code

+    GPIO_drive_inout( &g_gpio, GPIO_7, GPIO_HIGH_Z );

+    @endcode

+ */

+void GPIO_drive_inout

+(

+    gpio_instance_t *   this_gpio,

+    gpio_id_t           port_id,

+    gpio_inout_state_t  inout_state

+);

+

+/*-------------------------------------------------------------------------*//**

+  The GPIO_enable_irq() function is used to enable an interrupt to be

+  generated based on the state of the input identified as parameter.

+ 

+  @param this_gpio

+    The this_gpio parameter is a pointer to the gpio_instance_t structure holding

+    all data regarding the CoreGPIO instance controlled through this function call.

+

+  @param port_id

+    The port_id parameter identifies the GPIO input the call to

+    GPIO_enable_irq() will enable to generate interrupts.

+    An enumeration item of the form GPIO_n where n is the number of the GPIO

+    port is used to identify the GPIO port. For example GPIO_0 identifies the

+    first GPIO port and GPIO_31 the last one.

+    

+  @return

+    none.

+    

+  Example:

+    The call to GPIO_enable_irq() below will allow GPIO 8 to generate

+    interrupts.

+    @code

+    GPIO_enable_irq( &g_gpio, GPIO_8 );

+    @endcode

+ */

+void GPIO_enable_irq

+(

+    gpio_instance_t *   this_gpio,

+    gpio_id_t           port_id

+);

+

+/*-------------------------------------------------------------------------*//**

+  The GPIO_disable_irq() function is used to disable interrupt from being

+  generated based on the state of the input specified as parameter.

+ 

+  @param this_gpio

+    The this_gpio parameter is a pointer to the gpio_instance_t structure holding

+    all data regarding the CoreGPIO instance controlled through this function call.

+

+  @param port_id

+    The port_id parameter identifies the GPIO input the call to

+    GPIO_disable_irq() will disable from generating interrupts.

+    An enumeration item of the form GPIO_n where n is the number of the GPIO

+    port is used to identify the GPIO port. For example GPIO_0 identifies the

+    first GPIO port and GPIO_31 the last one.

+ 

+  @return

+    none.

+    

+  Example:

+    The call to GPIO_disable_irq() below will prevent GPIO 8 from generating

+    interrupts.

+    @code

+    GPIO_disable_irq( &g_gpio, GPIO_8 );

+    @endcode

+ */

+void GPIO_disable_irq

+(

+    gpio_instance_t *   this_gpio,

+    gpio_id_t           port_id

+);

+

+/*-------------------------------------------------------------------------*//**

+  The GPIO_clear_irq() function is used to clear the interrupt generated by

+  the GPIO specified as parameter. The GPIO_clear_irq() function  must be

+  called as part of a GPIO interrupt service routine (ISR) in order to prevent

+  the same interrupt event retriggering a call to the GPIO ISR.

+  Please note that interrupts may also need to be cleared in the processor's

+  interrupt controller.

+ 

+  @param this_gpio

+    The this_gpio parameter is a pointer to the gpio_instance_t structure holding

+    all data regarding the CoreGPIO instance controlled through this function call.

+

+  @param port_id

+    The port_id parameter identifies the GPIO input for which to clear the

+    interrupt.

+    An enumeration item of the form GPIO_n where n is the number of the GPIO

+    port is used to identify the GPIO port. For example GPIO_0 identifies the

+    first GPIO port and GPIO_31 the last one.

+    

+  @return

+    none.

+    

+  Example:

+    The example below demonstrates the use of the GPIO_clear_irq() function as

+    part of the GPIO 9 interrupt service routine on a Cortex-M processor.  

+    @code

+    void GPIO9_IRQHandler( void )

+    {

+        do_interrupt_processing();

+        

+        GPIO_clear_irq( &g_gpio, GPIO_9 );

+        

+        NVIC_ClearPendingIRQ( GPIO9_IRQn );

+    }

+    @endcode

+ */

+void GPIO_clear_irq

+(

+    gpio_instance_t *   this_gpio,

+    gpio_id_t           port_id

+);

+

+#endif /* CORE_GPIO_H_ */

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreGPIO/coregpio_regs.h b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreGPIO/coregpio_regs.h
new file mode 100644
index 0000000..afbbfbc
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreGPIO/coregpio_regs.h
@@ -0,0 +1,40 @@
+/*******************************************************************************

+ * (c) Copyright 2009-2015 Microsemi SoC Products Group. All rights reserved.

+ * 

+ * SVN $Revision: 7964 $

+ * SVN $Date: 2015-10-09 18:26:53 +0530 (Fri, 09 Oct 2015) $

+ */

+#ifndef __CORE_GPIO_REGISTERS_H

+#define __CORE_GPIO_REGISTERS_H		1

+

+/*------------------------------------------------------------------------------

+ * 

+ */

+#define IRQ_REG_OFFSET          0x80

+

+#define IRQ0_REG_OFFSET         0x80

+#define IRQ1_REG_OFFSET         0x84

+#define IRQ2_REG_OFFSET         0x88

+#define IRQ3_REG_OFFSET         0x8C

+

+/*------------------------------------------------------------------------------

+ * 

+ */

+#define GPIO_IN_REG_OFFSET      0x90

+

+#define GPIO_IN0_REG_OFFSET     0x90

+#define GPIO_IN1_REG_OFFSET     0x94

+#define GPIO_IN2_REG_OFFSET     0x98

+#define GPIO_IN3_REG_OFFSET     0x9C

+

+/*------------------------------------------------------------------------------

+ * 

+ */

+#define GPIO_OUT_REG_OFFSET     0xA0

+

+#define GPIO_OUT0_REG_OFFSET    0xA0

+#define GPIO_OUT1_REG_OFFSET    0xA4

+#define GPIO_OUT2_REG_OFFSET    0xA8

+#define GPIO_OUT3_REG_OFFSET    0xAC

+

+#endif /* __CORE_GPIO_REGISTERS_H */

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreI2C/core_i2c.c b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreI2C/core_i2c.c
new file mode 100644
index 0000000..daa1887
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreI2C/core_i2c.c
@@ -0,0 +1,1563 @@
+/*******************************************************************************

+ * (c) Copyright 2009-2015 Microsemi  SoC Products Group.  All rights reserved.

+ * 

+ * CoreI2C software driver implementation.

+ * 

+ * SVN $Revision: 7984 $

+ * SVN $Date: 2015-10-12 12:07:40 +0530 (Mon, 12 Oct 2015) $

+ */

+#include <stdint.h>

+#include <stdlib.h>

+#include <stddef.h>

+#include <unistd.h>

+#include <errno.h>

+#include <sys/stat.h>

+#include <sys/times.h>

+#include <stdio.h>

+#include <string.h>

+#include "cpu_types.h"

+#include "core_smbus_regs.h"

+#include "core_i2c.h"

+#include "hal.h"

+#include "hal_assert.h"

+

+

+#include <string.h>

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+/*------------------------------------------------------------------------------

+ * I2C transaction direction.

+ */

+#define WRITE_DIR    0u

+#define READ_DIR     1u

+

+/* -- TRANSACTIONS TYPES -- */

+#define NO_TRANSACTION                      0u

+#define MASTER_WRITE_TRANSACTION            1u

+#define MASTER_READ_TRANSACTION             2u

+#define MASTER_RANDOM_READ_TRANSACTION      3u

+#define WRITE_SLAVE_TRANSACTION             4u

+#define READ_SLAVE_TRANSACTION              5u

+

+/* -- SMBUS H/W STATES -- */

+/* -- MASTER STATES -- */

+#define ST_BUS_ERROR        0x00u           /* Bus error during MST or selected slave modes */

+#define ST_I2C_IDLE         0xF8u           /* No activity and no interrupt either... */

+#define ST_START            0x08u           /* start condition sent */

+#define ST_RESTART          0x10u           /* repeated start */

+#define ST_SLAW_ACK         0x18u           /* SLA+W sent, ack received */

+#define ST_SLAW_NACK        0x20u           /* SLA+W sent, nack received */

+#define ST_TX_DATA_ACK      0x28u           /* Data sent, ACK'ed */

+#define ST_TX_DATA_NACK     0x30u           /* Data sent, NACK'ed */

+#define ST_LOST_ARB         0x38u           /* Master lost arbitration */

+#define ST_SLAR_ACK         0x40u           /* SLA+R sent, ACK'ed */

+#define ST_SLAR_NACK        0x48u           /* SLA+R sent, NACK'ed */

+#define ST_RX_DATA_ACK      0x50u           /* Data received, ACK sent */

+#define ST_RX_DATA_NACK     0x58u           /* Data received, NACK sent */

+#define ST_RESET_ACTIVATED  0xD0u           /* Master reset is activated */

+#define ST_STOP_TRANSMIT    0xE0u           /* Stop has been transmitted */

+

+/* -- SLAVE STATES -- */

+#define ST_SLAVE_SLAW       0x60u           /* SLA+W received */

+#define ST_SLAVE_SLAR_ACK   0xA8u           /* SLA+R received, ACK returned */

+#define ST_SLV_LA           0x68u           /* Slave lost arbitration */

+#define ST_GCA              0x70u           /* GCA received */

+#define ST_GCA_LA           0x78u           /* GCA lost arbitration */

+#define ST_RDATA            0x80u           /* Data received */

+#define ST_SLA_NACK         0x88u           /* Slave addressed, NACK returned */

+#define ST_GCA_ACK          0x90u           /* Previously addresses with GCA, data ACKed */

+#define ST_GCA_NACK         0x98u           /* GCA addressed, NACK returned */

+#define ST_RSTOP            0xA0u           /* Stop received */

+#define ST_SLARW_LA         0xB0u           /* Arbitration lost */

+#define ST_RACK             0xB8u           /* Byte sent, ACK received */

+#define ST_SLAVE_RNACK      0xC0u           /* Byte sent, NACK received */

+#define ST_FINAL            0xC8u           /* Final byte sent, ACK received */

+#define ST_SLV_RST          0xD8u           /* Slave reset state */

+

+

+/* I2C Channel base offset */

+#define CHANNEL_BASE_SHIFT    5u

+#define CHANNEL_MASK        0x1E0u

+

+/*

+ * Maximum address offset length in slave write-read transactions.

+ * A maximum of two bytes will be interpreted as address offset within the slave

+ * tx buffer.

+ */

+#define MAX_OFFSET_LENGTH       2u

+

+/*------------------------------------------------------------------------------

+ * I2C interrupts control functions implemented "i2c_interrupt.c".

+ * the implementation of these functions depend on the underlying hardware

+ * design and how the CoreI2C interrupt line is connected to the system's

+ * interrupt controller.

+ */

+void I2C_enable_irq( i2c_instance_t * this_i2c );

+void I2C_disable_irq( i2c_instance_t * this_i2c );

+static void enable_slave_if_required(i2c_instance_t * this_i2c);

+

+/*------------------------------------------------------------------------------

+ * I2C_init()

+ * See "core_i2c.h" for details of how to use this function.

+ */

+void I2C_init

+(

+    i2c_instance_t * this_i2c,

+    addr_t base_address,

+    uint8_t ser_address,

+    i2c_clock_divider_t ser_clock_speed

+)

+{

+    psr_t saved_psr;

+    uint_fast16_t clock_speed = (uint_fast16_t)ser_clock_speed;

+    

+    /*

+     * We need to disable ints while doing this as there is no guarantee we

+     * have not been called already and the ISR is active.

+     */

+

+   saved_psr=HAL_disable_interrupts();

+    

+    /*

+     * Initialize all items of the this_i2c data structure to zero. This

+     * initializes all state variables to their init value. It relies on

+     * the fact that NO_TRANSACTION, I2C_SUCCESS and I2C_RELEASE_BUS all

+     * have an actual value of zero.

+     */

+    memset(this_i2c, 0, sizeof(i2c_instance_t));

+    

+    /*

+     * Set base address of I2C hardware used by this instance.

+     */

+    this_i2c->base_address = base_address;

+

+    /*

+     * Update Serial address of the device

+     */

+    this_i2c->ser_address = ((uint_fast8_t)ser_address << 1u);

+    

+    /*

+     * Configure hardware.

+     */

+    HAL_set_8bit_reg_field(this_i2c->base_address, ENS1, 0x00); /* Reset I2C hardware. */

+    HAL_set_8bit_reg_field(this_i2c->base_address, ENS1, 0x01); /* set enable bit */

+    HAL_set_8bit_reg_field(this_i2c->base_address, CR2, ( (clock_speed >> 2) & 0x01) );

+    HAL_set_8bit_reg_field(this_i2c->base_address, CR1, ( (clock_speed >> 1) & 0x01) );

+    HAL_set_8bit_reg_field(this_i2c->base_address, CR0, ( clock_speed & 0x01) );

+

+    HAL_set_8bit_reg(this_i2c->base_address, ADDRESS, this_i2c->ser_address);

+    HAL_set_8bit_reg(this_i2c->base_address, ADDRESS1, this_i2c->ser_address);

+    

+    /*

+     * Finally safe to enable interrupts.

+     */

+

+   	HAL_restore_interrupts( saved_psr );

+}

+/*------------------------------------------------------------------------------

+ * I2C_channel_init()

+ * See "core_i2c.h" for details of how to use this function.

+ */

+void I2C_channel_init

+(

+    i2c_instance_t * this_i2c_channel,

+    i2c_instance_t * this_i2c,

+    i2c_channel_number_t channel_number,

+    i2c_clock_divider_t ser_clock_speed

+)

+{

+    psr_t saved_psr;

+    uint_fast16_t clock_speed = (uint_fast16_t)ser_clock_speed;

+    

+    HAL_ASSERT(channel_number < I2C_MAX_CHANNELS);

+    HAL_ASSERT(I2C_CHANNEL_0 != channel_number);

+

+    /* 

+     * Cannot allow channel 0 in this function as we will trash the hardware

+     * base address and slave address.

+     */

+    if ((channel_number < I2C_MAX_CHANNELS) &&

+        (I2C_CHANNEL_0 != channel_number))

+    {

+        /*

+         * We need to disable ints while doing this as the hardware should already

+         * be active at this stage.

+         */

+

+   	saved_psr=HAL_disable_interrupts();

+        /*

+         * Initialize channel data.

+         */

+        memset(this_i2c_channel, 0, sizeof(i2c_instance_t));

+        

+        this_i2c_channel->base_address =

+               ((this_i2c->base_address) & ~((addr_t)CHANNEL_MASK)) 

+            | (((addr_t)channel_number) << CHANNEL_BASE_SHIFT);

+

+        this_i2c_channel->ser_address = this_i2c->ser_address;

+

+        HAL_set_8bit_reg_field(this_i2c_channel->base_address, ENS1, 0x00); /* Reset I2C channel hardware. */

+        HAL_set_8bit_reg_field(this_i2c_channel->base_address, ENS1, 0x01); /* set enable bit */

+        HAL_set_8bit_reg_field(this_i2c_channel->base_address, CR2, ( (clock_speed >> 2) & 0x01) );

+        HAL_set_8bit_reg_field(this_i2c_channel->base_address, CR1, ( (clock_speed >> 1) & 0x01) );

+        HAL_set_8bit_reg_field(this_i2c_channel->base_address, CR0, ( clock_speed & 0x01) );

+        /*

+         * Finally safe to enable interrupts.

+         */

+

+   	HAL_restore_interrupts( saved_psr );

+    }

+}

+

+/*------------------------------------------------------------------------------

+ * I2C_write()

+ * See "core_i2c.h" for details of how to use this function.

+ */

+void I2C_write

+(

+    i2c_instance_t * this_i2c,

+    uint8_t serial_addr,

+    const uint8_t * write_buffer,

+    uint16_t write_size,

+    uint8_t options

+)

+{

+    psr_t saved_psr;

+    volatile uint8_t stat_ctrl;

+

+

+   	saved_psr=HAL_disable_interrupts();

+

+    /* Update the transaction only when there is no transaction going on I2C */

+    if( this_i2c->transaction == NO_TRANSACTION)

+    {

+      this_i2c->transaction = MASTER_WRITE_TRANSACTION;

+    }

+

+    /* Update the Pending transaction information so that transaction can restarted */

+    this_i2c->pending_transaction = MASTER_WRITE_TRANSACTION ;

+

+    /* Update target address */

+    this_i2c->target_addr = (uint_fast8_t)serial_addr << 1u;

+    this_i2c->dir = WRITE_DIR;

+    this_i2c->master_tx_buffer = write_buffer;

+    this_i2c->master_tx_size = write_size;

+    this_i2c->master_tx_idx = 0u;

+

+    /* Set I2C status in progress */

+    this_i2c->master_status = I2C_IN_PROGRESS;

+    this_i2c->options = options;

+

+    if(I2C_IN_PROGRESS == this_i2c->slave_status)

+    {

+        this_i2c->is_transaction_pending = 1u;

+    }

+    else

+    {

+        HAL_set_8bit_reg_field(this_i2c->base_address, STA, 0x01u);

+    }

+

+    /*

+     * Clear interrupts if required (depends on repeated starts).

+     * Since the Bus is on hold, only then prior status needs to

+     * be cleared.

+     */

+    if ( I2C_HOLD_BUS == this_i2c->bus_status )

+    {

+        HAL_set_8bit_reg_field(this_i2c->base_address, SI, 0x00u);

+    }

+

+    stat_ctrl = HAL_get_8bit_reg( this_i2c->base_address, STATUS);

+    stat_ctrl = stat_ctrl;  /* Avoids lint warning. */

+

+    /* Enable the interrupt. ( Re-enable) */

+    I2C_enable_irq( this_i2c );

+

+

+   	HAL_restore_interrupts(saved_psr);

+}

+

+/*------------------------------------------------------------------------------

+ * I2C_read()

+ * See "core_i2c.h" for details of how to use this function.

+ */

+void I2C_read

+(

+    i2c_instance_t * this_i2c,

+    uint8_t serial_addr,

+    uint8_t * read_buffer,

+    uint16_t read_size,

+    uint8_t options

+)

+{

+    psr_t saved_psr;

+    volatile uint8_t stat_ctrl;

+

+

+   	saved_psr=HAL_disable_interrupts();

+    

+    /* Update the transaction only when there is no transaction going on I2C */

+    if( this_i2c->transaction == NO_TRANSACTION)

+    {

+      this_i2c->transaction = MASTER_READ_TRANSACTION;

+    }

+

+    /* Update the Pending transaction information so that transaction can restarted */

+    this_i2c->pending_transaction = MASTER_READ_TRANSACTION ;

+

+    /* Update target address */

+    this_i2c->target_addr = (uint_fast8_t)serial_addr << 1u;

+

+    this_i2c->dir = READ_DIR;

+

+    this_i2c->master_rx_buffer = read_buffer;

+    this_i2c->master_rx_size = read_size;

+    this_i2c->master_rx_idx = 0u;

+

+    /* Set I2C status in progress */

+    this_i2c->master_status = I2C_IN_PROGRESS;

+

+    this_i2c->options = options;

+    

+    if(I2C_IN_PROGRESS == this_i2c->slave_status)

+    {

+        this_i2c->is_transaction_pending = 1u;

+    }

+    else

+    {

+        HAL_set_8bit_reg_field(this_i2c->base_address, STA, 0x01u);

+    }

+

+    /*

+     * Clear interrupts if required (depends on repeated starts).

+     * Since the Bus is on hold, only then prior status needs to

+     * be cleared.

+     */

+    if ( I2C_HOLD_BUS == this_i2c->bus_status )

+    {

+        HAL_set_8bit_reg_field(this_i2c->base_address, SI, 0x00u);

+    }

+

+    stat_ctrl = HAL_get_8bit_reg( this_i2c->base_address, STATUS);

+    stat_ctrl = stat_ctrl;  /* Avoids lint warning. */

+

+    /* Enable the interrupt. ( Re-enable) */

+    I2C_enable_irq( this_i2c );

+

+   	HAL_restore_interrupts( saved_psr );

+

+}

+

+/*------------------------------------------------------------------------------

+ * I2C_write_read()

+ * See "core_i2c.h" for details of how to use this function.

+ */

+void I2C_write_read

+(

+    i2c_instance_t * this_i2c,

+    uint8_t serial_addr,

+    const uint8_t * addr_offset,

+    uint16_t offset_size,

+    uint8_t * read_buffer,

+    uint16_t read_size,

+    uint8_t options

+)

+{

+    HAL_ASSERT(offset_size > 0u);

+    HAL_ASSERT(addr_offset != (uint8_t *)0);

+    HAL_ASSERT(read_size > 0u);

+    HAL_ASSERT(read_buffer != (uint8_t *)0);

+    

+    this_i2c->master_status = I2C_FAILED;

+    

+    if((read_size > 0u) && (offset_size > 0u))

+    {

+        psr_t saved_psr;

+        volatile uint8_t stat_ctrl;

+

+

+   	saved_psr=HAL_disable_interrupts();

+

+        /* Update the transaction only when there is no transaction going on I2C */

+        if( this_i2c->transaction == NO_TRANSACTION)

+        {

+            this_i2c->transaction = MASTER_RANDOM_READ_TRANSACTION;

+        }

+

+        /* Update the Pending transaction information so that transaction can restarted */

+        this_i2c->pending_transaction = MASTER_RANDOM_READ_TRANSACTION ;

+

+        /* Update target address */

+        this_i2c->target_addr = (uint_fast8_t)serial_addr << 1u;

+

+        this_i2c->dir = WRITE_DIR;

+

+        this_i2c->master_tx_buffer = addr_offset;

+        this_i2c->master_tx_size = offset_size;

+        this_i2c->master_tx_idx = 0u;

+

+        this_i2c->master_rx_buffer = read_buffer;

+        this_i2c->master_rx_size = read_size;

+        this_i2c->master_rx_idx = 0u;

+        

+        /* Set I2C status in progress */

+        this_i2c->master_status = I2C_IN_PROGRESS;

+        this_i2c->options = options;

+        

+        if(I2C_IN_PROGRESS == this_i2c->slave_status)

+        {

+            this_i2c->is_transaction_pending = 1u;

+        }

+        else

+        {

+            HAL_set_8bit_reg_field(this_i2c->base_address, STA, 0x01u);

+        }

+

+        /*

+         * Clear interrupts if required (depends on repeated starts).

+         * Since the Bus is on hold, only then prior status needs to

+         * be cleared.

+         */

+        if ( I2C_HOLD_BUS == this_i2c->bus_status )

+        {

+            HAL_set_8bit_reg_field(this_i2c->base_address, SI, 0x00u);

+        }

+

+        stat_ctrl = HAL_get_8bit_reg( this_i2c->base_address, STATUS);

+        stat_ctrl = stat_ctrl;  /* Avoids lint warning. */

+            

+        /* Enable the interrupt. ( Re-enable) */

+        I2C_enable_irq( this_i2c );

+

+

+   	HAL_restore_interrupts( saved_psr );

+    }

+}

+

+/*------------------------------------------------------------------------------

+ * I2C_get_status()

+ * See "core_i2c.h" for details of how to use this function.

+ */

+i2c_status_t I2C_get_status

+(

+    i2c_instance_t * this_i2c

+)

+{

+    i2c_status_t i2c_status ;

+

+    i2c_status = this_i2c->master_status ;

+

+    return i2c_status;

+}

+

+/*------------------------------------------------------------------------------

+ * I2C_wait_complete()

+ * See "core_i2c.h" for details of how to use this function.

+ */

+i2c_status_t I2C_wait_complete

+(

+    i2c_instance_t * this_i2c,

+    uint32_t timeout_ms

+)

+{

+    i2c_status_t i2c_status;

+    psr_t saved_psr;

+    /*

+     * Because we have no idea of what CPU we are supposed to be running on

+     * we need to guard this write to the timeout value to avoid ISR/user code

+     * interaction issues. Checking the status below should be fine as only a

+     * single byte should change in that.

+     */

+

+   	saved_psr=HAL_disable_interrupts();

+    this_i2c->master_timeout_ms = timeout_ms;

+

+   	HAL_restore_interrupts( saved_psr );

+

+    /* Run the loop until state returns I2C_FAILED  or I2C_SUCESS*/

+    do {

+        i2c_status = this_i2c->master_status;

+    } while(I2C_IN_PROGRESS == i2c_status);

+    return i2c_status;

+}

+

+/*------------------------------------------------------------------------------

+ * I2C_system_tick()

+ * See "core_i2c.h" for details of how to use this function.

+ */

+void I2C_system_tick

+(

+    i2c_instance_t * this_i2c,

+    uint32_t ms_since_last_tick

+)

+{

+    if(this_i2c->master_timeout_ms != I2C_NO_TIMEOUT)

+    {

+       if(this_i2c->master_timeout_ms > ms_since_last_tick)

+        {

+            this_i2c->master_timeout_ms -= ms_since_last_tick;

+        }

+        else

+        {

+            psr_t saved_psr;

+            /*

+             * We need to disable interrupts here to ensure we can update the

+             * shared data without the I2C ISR interrupting us.

+             */

+

+   	saved_psr=HAL_disable_interrupts();

+

+            /*

+             * Mark current transaction as having timed out.

+             */

+            this_i2c->master_status = I2C_TIMED_OUT;

+            this_i2c->transaction = NO_TRANSACTION;

+            this_i2c->is_transaction_pending = 0;

+

+

+   	HAL_restore_interrupts( saved_psr );

+            

+            /*

+             * Make sure we do not incorrectly signal a timeout for subsequent

+             * transactions.

+             */

+            this_i2c->master_timeout_ms = I2C_NO_TIMEOUT;

+        }

+    }

+}

+

+/*------------------------------------------------------------------------------

+ * I2C_set_slave_tx_buffer()

+ * See "core_i2c.h" for details of how to use this function.

+ */

+void I2C_set_slave_tx_buffer

+(

+    i2c_instance_t * this_i2c,

+    const uint8_t * tx_buffer,

+    uint16_t tx_size

+)

+{

+    psr_t saved_psr;

+

+    /*

+     * We need to disable interrupts here to ensure we can update the

+     * shared data without the I2C ISR interrupting us.

+     */

+

+   	saved_psr=HAL_disable_interrupts();

+    

+    this_i2c->slave_tx_buffer = tx_buffer;

+    this_i2c->slave_tx_size = tx_size;

+    this_i2c->slave_tx_idx = 0u;

+    

+

+   	HAL_restore_interrupts( saved_psr );

+}

+

+/*------------------------------------------------------------------------------

+ * I2C_set_slave_rx_buffer()

+ * See "core_i2c.h" for details of how to use this function.

+ */

+void I2C_set_slave_rx_buffer

+(

+    i2c_instance_t * this_i2c,

+    uint8_t * rx_buffer,

+    uint16_t rx_size

+)

+{

+    psr_t saved_psr;

+

+    /*

+     * We need to disable interrupts here to ensure we can update the

+     * shared data without the I2C ISR interrupting us.

+     */

+

+   	saved_psr=HAL_disable_interrupts();

+

+    this_i2c->slave_rx_buffer = rx_buffer;

+    this_i2c->slave_rx_size = rx_size;

+    this_i2c->slave_rx_idx = 0u;

+

+

+   	HAL_restore_interrupts( saved_psr );

+}

+

+/*------------------------------------------------------------------------------

+ * I2C_set_slave_mem_offset_length()

+ * See "core_i2c.h" for details of how to use this function.

+ */

+void I2C_set_slave_mem_offset_length

+(

+    i2c_instance_t * this_i2c,

+    uint8_t offset_length

+)

+{

+    HAL_ASSERT(offset_length <= MAX_OFFSET_LENGTH);

+    

+    /*

+     * Single byte update, should be interrupt safe

+     */

+    if(offset_length > MAX_OFFSET_LENGTH)

+    {

+        this_i2c->slave_mem_offset_length = MAX_OFFSET_LENGTH;

+    }

+    else

+    {

+        this_i2c->slave_mem_offset_length = offset_length;

+    }

+}

+

+/*------------------------------------------------------------------------------

+ * I2C_register_write_handler()

+ * See "core_i2c.h" for details of how to use this function.

+ */

+void I2C_register_write_handler

+(

+    i2c_instance_t * this_i2c,

+    i2c_slave_wr_handler_t handler

+)

+{

+    psr_t saved_psr;

+

+    /*

+     * We need to disable interrupts here to ensure we can update the

+     * shared data without the I2C ISR interrupting us.

+     */

+

+   	saved_psr=HAL_disable_interrupts();

+

+    this_i2c->slave_write_handler = handler;

+

+

+   	HAL_restore_interrupts( saved_psr );

+}

+

+/*------------------------------------------------------------------------------

+ * I2C_enable_slave()

+ * See "core_i2c.h" for details of how to use this function.

+ */

+void I2C_enable_slave

+(

+    i2c_instance_t * this_i2c

+)

+{

+    psr_t saved_psr;

+

+    /*

+     * We need to disable interrupts here to ensure we can update the

+     * hardware register and slave mode flag without the I2C ISR interrupting

+     * us.

+     */

+

+   	saved_psr=HAL_disable_interrupts();

+

+    /* Set the Assert Acknowledge bit. */

+    HAL_set_8bit_reg_field(this_i2c->base_address, AA, 0x01u);

+

+    /* Enable slave mode */

+    this_i2c->is_slave_enabled = 1u;

+

+

+   	HAL_restore_interrupts( saved_psr );

+

+    /* Enable I2C IRQ*/

+    I2C_enable_irq( this_i2c );

+}

+

+/*------------------------------------------------------------------------------

+ * I2C_disable_slave()

+ * See "core_i2c.h" for details of how to use this function.

+ */

+void I2C_disable_slave

+(

+    i2c_instance_t * this_i2c

+)

+{

+    psr_t saved_psr;

+

+    /*

+     * We need to disable interrupts here to ensure we can update the

+     * hardware register without the I2C ISR interrupting us.

+     */

+

+   	saved_psr=HAL_disable_interrupts();

+    

+    /* Reset the assert acknowledge bit. */

+    HAL_set_8bit_reg_field(this_i2c->base_address, AA, 0x00u);

+

+    /* Disable slave mode with IRQ blocked to make whole change atomic */

+    this_i2c->is_slave_enabled = 0u;

+

+

+   	HAL_restore_interrupts( saved_psr );

+}

+

+/*------------------------------------------------------------------------------

+ * 

+ */

+static void enable_slave_if_required

+(

+    i2c_instance_t * this_i2c

+)

+{

+    /*

+     * This function is only called from within the ISR and so does not need

+     * guarding on the register access.

+     */

+    if( 0 != this_i2c->is_slave_enabled )

+    {

+        HAL_set_8bit_reg_field( this_i2c->base_address, AA, 0x01u );

+    }

+}

+/*------------------------------------------------------------------------------

+ * I2C_set_slave_second_addr()

+ * See "i2c.h" for details of how to use this function.

+ */

+void I2C_set_slave_second_addr

+(

+    i2c_instance_t * this_i2c,

+    uint8_t second_slave_addr

+)

+{

+    uint8_t second_slave_address;

+    

+    /*

+      This function does not support CoreI2C hardware configured with a fixed 

+      second slave address.  The current implementation of the ADDR1[0] register

+      bit makes it difficult for the driver to support both programmable and

+      fixed second slave address, so we choose to support programmable only.

+      With the programmable configuration, ADDR1[0] and ADDR0[0] both control

+      enable/disable of GCA recognition, as an effective OR of the 2 bit fields.

+      Therefore we set ADDR1[0] to 0 here, so that only ADDR0[0] controls GCA.

+     */

+    second_slave_address = (uint8_t)((second_slave_addr << 1u) & (~SLAVE1_EN_MASK));

+

+    /*

+     * Single byte register write, should be interrupt safe

+     */

+    HAL_set_8bit_reg(this_i2c->base_address, ADDRESS1, second_slave_address);

+}

+

+/*------------------------------------------------------------------------------

+ * I2C_disable_slave_second_addr()

+ * See "i2c.h" for details of how to use this function.

+ */

+void I2C_disable_slave_second_addr

+(

+    i2c_instance_t * this_i2c

+)

+{

+    /*

+      We are disabling the second slave address by setting the value of the 2nd

+      slave address to the primary slave address. The reason for using this method

+      of disabling 2nd slave address is that ADDRESS1[0] has different meaning 

+      depending on hardware configuration. Its use would likely interfere with

+      the intended GCA setting.

+     */

+    /*

+     * Single byte register write, should be interrupt safe

+     */

+    HAL_set_8bit_reg(this_i2c->base_address, ADDRESS1, this_i2c->ser_address);

+}

+

+/*------------------------------------------------------------------------------

+ * i2C_set_gca()

+ * See "i2c.h" for details of how to use this function.

+ */

+

+void I2C_set_gca

+(

+    i2c_instance_t * this_i2c

+)

+{

+    /* 

+     * This read modify write access should be interrupt safe as the address

+     * register is not written to in the ISR.

+     */

+    /* accept GC addressing. */

+    HAL_set_8bit_reg_field(this_i2c->base_address, GC, 0x01u);

+}

+

+/*------------------------------------------------------------------------------

+ * I2C_clear_gca()

+ * See "i2c.h" for details of how to use this function.

+ */

+void I2C_clear_gca

+(

+    i2c_instance_t * this_i2c

+)

+{

+    /* 

+     * This read modify write access should be interrupt safe as the address

+     * register is not written to in the ISR.

+     */

+    /* Clear GC addressing. */

+    HAL_set_8bit_reg_field(this_i2c->base_address, GC, 0x00u);

+}

+

+/*------------------------------------------------------------------------------

+ * I2C_isr()

+ * See "core_i2c.h" for details of how to use this function.

+ */

+void I2C_isr

+(

+    i2c_instance_t * this_i2c

+)

+{

+    volatile uint8_t status;

+    uint8_t data;

+    uint8_t hold_bus;

+    uint8_t clear_irq = 1u;

+

+    status = HAL_get_8bit_reg( this_i2c->base_address, STATUS);

+    

+    switch( status )

+    {

+        /************** MASTER TRANSMITTER / RECEIVER *******************/

+      

+        case ST_START: /* start has been xmt'd */

+        case ST_RESTART: /* repeated start has been xmt'd */

+  	    //write_hex(STDOUT_FILENO, status);

+            HAL_set_8bit_reg_field( this_i2c->base_address, STA, 0x00u);

+            HAL_set_8bit_reg( this_i2c->base_address, DATA, this_i2c->target_addr); /* write call address */

+            HAL_set_8bit_reg_field( this_i2c->base_address, DIR, this_i2c->dir); /* set direction bit */

+            if(this_i2c->dir == WRITE_DIR)

+            {

+                 this_i2c->master_tx_idx = 0u;

+            }

+            else

+            {

+                 this_i2c->master_rx_idx = 0u;

+            }

+

+            /*

+             * Clear the pending transaction. This condition will be true if the slave 

+             * has acquired the bus to carry out pending master transaction which 

+             * it had received during its slave transmission or reception mode. 

+             */

+            if(this_i2c->is_transaction_pending)

+            {

+                this_i2c->is_transaction_pending = 0u;

+            }

+

+            /*

+             * Make sure to update proper transaction after master START

+             * or RESTART

+             */

+            if(this_i2c->transaction != this_i2c->pending_transaction)

+            {

+                this_i2c->transaction = this_i2c->pending_transaction;

+            }

+            break;

+            

+        case ST_LOST_ARB:

+              /* Set start bit.  Let's keep trying!  Don't give up! */

+              HAL_set_8bit_reg_field(this_i2c->base_address, STA, 0x01u);

+              break;

+

+        case ST_STOP_TRANSMIT:

+             /* Stop has been transmitted. Do nothing */

+              break;

+

+        /******************* MASTER TRANSMITTER *************************/

+        case ST_SLAW_NACK:

+  	    //write_hex(STDOUT_FILENO, status);

+            /* SLA+W has been transmitted; not ACK has been received - let's stop. */

+            HAL_set_8bit_reg_field(this_i2c->base_address, STO, 0x01u);

+            this_i2c->master_status = I2C_FAILED;

+            this_i2c->transaction = NO_TRANSACTION;

+            enable_slave_if_required(this_i2c);

+            break;

+            

+        case ST_SLAW_ACK:

+        case ST_TX_DATA_ACK:

+  	    //write_hex(STDOUT_FILENO, status);

+            /* data byte has been xmt'd with ACK, time to send stop bit or repeated start. */

+            if (this_i2c->master_tx_idx < this_i2c->master_tx_size)

+            {    

+                HAL_set_8bit_reg(this_i2c->base_address, DATA, (uint_fast8_t)this_i2c->master_tx_buffer[this_i2c->master_tx_idx++]);

+            }

+            else if ( this_i2c->transaction == MASTER_RANDOM_READ_TRANSACTION )

+            {

+                /* We are finished sending the address offset part of a random read transaction.

+                 * It is is time to send a restart in order to change direction. */

+                 this_i2c->dir = READ_DIR;

+                 HAL_set_8bit_reg_field(this_i2c->base_address, STA, 0x01u);

+            }

+            else /* done sending. let's stop */

+            {

+                /*

+                 * Set the transaction back to NO_TRANSACTION to allow user to do further

+                 * transaction

+                 */

+                this_i2c->transaction = NO_TRANSACTION;

+                hold_bus = this_i2c->options & I2C_HOLD_BUS;

+

+                /* Store the information of current I2C bus status in the bus_status*/

+                this_i2c->bus_status  = hold_bus;

+                if ( hold_bus == 0u )

+                { 

+                    HAL_set_8bit_reg_field(this_i2c->base_address, STO, 0x01u);  /*xmt stop condition */

+                    enable_slave_if_required(this_i2c);

+                }

+                else

+                {

+                    I2C_disable_irq( this_i2c );

+                    clear_irq = 0u;

+                }

+                this_i2c->master_status = I2C_SUCCESS;

+            }

+            break;

+

+          case ST_TX_DATA_NACK:

+  	    //write_hex(STDOUT_FILENO, status);

+            /* data byte SENT, ACK to be received

+             * In fact, this means we've received a NACK (This may not be 

+             * obvious, but if we've rec'd an ACK then we would be in state 

+             * 0x28!) hence, let's send a stop bit

+             */

+            HAL_set_8bit_reg_field(this_i2c->base_address, STO, 0x01u);/* xmt stop condition */

+            this_i2c->master_status = I2C_FAILED;

+

+            /*

+             * Set the transaction back to NO_TRANSACTION to allow user to do further

+             * transaction

+             */

+            this_i2c->transaction = NO_TRANSACTION;

+            enable_slave_if_required(this_i2c);

+            break;

+              

+      /********************* MASTER (or slave?) RECEIVER *************************/

+      

+      /* STATUS codes 08H, 10H, 38H are all covered in MTX mode */

+        case ST_SLAR_ACK: /* SLA+R tx'ed. */

+//  	    //write_hex(STDOUT_FILENO, status);

+            /* Let's make sure we ACK the first data byte received (set AA bit in CTRL) unless

+             * the next byte is the last byte of the read transaction.

+             */

+            if(this_i2c->master_rx_size > 1u)

+            {

+                HAL_set_8bit_reg_field(this_i2c->base_address, AA, 0x01u);

+            }

+            else if(1u == this_i2c->master_rx_size)

+            {

+                HAL_set_8bit_reg_field(this_i2c->base_address, AA, 0x00u);

+            }

+            else /* this_i2c->master_rx_size == 0u */

+            {

+                HAL_set_8bit_reg_field(this_i2c->base_address, AA, 0x01u);

+                HAL_set_8bit_reg_field(this_i2c->base_address, STO, 0x01u);

+                this_i2c->master_status = I2C_SUCCESS;

+                this_i2c->transaction = NO_TRANSACTION;

+            }

+            break;

+            

+        case ST_SLAR_NACK: /* SLA+R tx'ed; let's release the bus (send a stop condition) */

+//  	    //write_hex(STDOUT_FILENO, status);

+            HAL_set_8bit_reg_field(this_i2c->base_address, STO, 0x01u);

+            this_i2c->master_status = I2C_FAILED;

+

+            /*

+             * Set the transaction back to NO_TRANSACTION to allow user to do further

+             * transaction

+             */

+            this_i2c->transaction = NO_TRANSACTION;

+            enable_slave_if_required(this_i2c);

+            break;

+          

+        case ST_RX_DATA_ACK: /* Data byte received, ACK returned */

+//  	    //write_hex(STDOUT_FILENO, status);

+            /* First, get the data */

+            this_i2c->master_rx_buffer[this_i2c->master_rx_idx++] = HAL_get_8bit_reg(this_i2c->base_address, DATA);

+            if( this_i2c->master_rx_idx >= (this_i2c->master_rx_size - 1u))

+            {

+                /* If we're at the second last byte, let's set AA to 0 so

+                 * we return a NACK at the last byte. */

+                HAL_set_8bit_reg_field(this_i2c->base_address, AA, 0x00u);

+            }

+            break;

+            

+        case ST_RX_DATA_NACK: /* Data byte received, NACK returned */

+//  	    //write_hex(STDOUT_FILENO, status);

+            /* Get the data, then send a stop condition */

+            this_i2c->master_rx_buffer[this_i2c->master_rx_idx] = HAL_get_8bit_reg(this_i2c->base_address, DATA);

+          

+            hold_bus = this_i2c->options & I2C_HOLD_BUS; 

+

+            /* Store the information of current I2C bus status in the bus_status*/

+            this_i2c->bus_status  = hold_bus;

+            if ( hold_bus == 0u )

+            { 

+                HAL_set_8bit_reg_field(this_i2c->base_address, STO, 0x01u);  /*xmt stop condition */

+

+                /* Bus is released, now we can start listening to bus, if it is slave */

+                   enable_slave_if_required(this_i2c);

+            }

+            else

+            {

+                I2C_disable_irq( this_i2c );

+                clear_irq = 0u;

+            }

+            /*

+             * Set the transaction back to NO_TRANSACTION to allow user to do further

+             * transaction

+             */

+            this_i2c->transaction = NO_TRANSACTION;

+            this_i2c->master_status = I2C_SUCCESS;

+            break;

+        

+        /******************** SLAVE RECEIVER **************************/

+        case ST_GCA_NACK: /* NACK after, GCA addressing */

+        case ST_SLA_NACK: /* Re-enable AA (assert ack) bit for future transmissions */

+  	    //write_hex(STDOUT_FILENO, status);

+            HAL_set_8bit_reg_field(this_i2c->base_address, AA, 0x01u);

+

+            this_i2c->transaction = NO_TRANSACTION;

+            this_i2c->slave_status = I2C_SUCCESS;

+            

+            /* Check if transaction was pending. If yes, set the START bit */

+            if(this_i2c->is_transaction_pending)

+            {

+                HAL_set_8bit_reg_field(this_i2c->base_address, STA, 0x01u);

+            }

+            break;

+            

+        case ST_GCA_LA: /* Arbitr. lost (GCA rec'd) */

+        case ST_SLV_LA: /* Arbitr. lost (SLA rec'd) */

+  	    //write_hex(STDOUT_FILENO, status);

+            /*

+             *  We lost arbitration and either the GCE or our address was the

+             *  one received so pend the master operation we were starting.

+             */

+            this_i2c->is_transaction_pending = 1u;

+            /* Fall through to normal ST processing as we are now in slave mode */

+

+        case ST_GCA: /* General call address received, ACK returned */

+        case ST_SLAVE_SLAW: /* SLA+W received, ACK returned */

+  	    //write_hex(STDOUT_FILENO, status);

+            this_i2c->transaction = WRITE_SLAVE_TRANSACTION;

+            this_i2c->slave_rx_idx = 0u;

+            this_i2c->random_read_addr = 0u;

+            /*

+             * If Start Bit is set clear it, but store that information since it is because of

+             * pending transaction

+             */

+            if(HAL_get_8bit_reg_field(this_i2c->base_address, STA))

+            {

+                HAL_set_8bit_reg_field(this_i2c->base_address, STA, 0x00u);

+                this_i2c->is_transaction_pending = 1u;

+            }

+            this_i2c->slave_status = I2C_IN_PROGRESS;

+#ifdef INCLUDE_SLA_IN_RX_PAYLOAD

+            /* Fall through to put address as first byte in payload buffer */

+#else

+            /* Only break from this case if the slave address must NOT be included at the

+             * beginning of the received write data. */

+            break;

+#endif            

+        case ST_GCA_ACK: /* DATA received; ACK sent after GCA */

+        case ST_RDATA: /* DATA received; must clear DATA register */

+  	    //write_hex(STDOUT_FILENO, status);

+            if((this_i2c->slave_rx_buffer != (uint8_t *)0)

+               && (this_i2c->slave_rx_idx < this_i2c->slave_rx_size))

+            {

+                data = HAL_get_8bit_reg(this_i2c->base_address, DATA);

+                this_i2c->slave_rx_buffer[this_i2c->slave_rx_idx++] = data;

+                

+#ifdef INCLUDE_SLA_IN_RX_PAYLOAD

+                if((ST_RDATA == status) || (ST_GCA_ACK == status))

+                {

+                    /* Ignore the slave address byte in the random read address

+                       computation in the case where INCLUDE_SLA_IN_RX_PAYLOAD

+                       is defined. */

+#endif

+                    this_i2c->random_read_addr = (this_i2c->random_read_addr << 8) + data;

+#ifdef INCLUDE_SLA_IN_RX_PAYLOAD

+                }

+#endif

+            }

+            

+            if(this_i2c->slave_rx_idx >= this_i2c->slave_rx_size)

+            {

+                /* Rx buffer is full. NACK next received byte. */

+                HAL_set_8bit_reg_field(this_i2c->base_address, AA, 0x00u); 

+            }

+            break;

+            

+        case ST_RSTOP:

+  	    //write_hex(STDOUT_FILENO, status);

+            /* STOP or repeated START occurred. */

+            /* We cannot be sure if the transaction has actually completed as

+             * this hardware state reports that either a STOP or repeated START

+             * condition has occurred. We assume that this is a repeated START

+             * if the transaction was a write from the master to this point.*/

+            if ( this_i2c->transaction == WRITE_SLAVE_TRANSACTION )

+            {

+                if ( this_i2c->slave_rx_idx == this_i2c->slave_mem_offset_length )

+                {

+                    this_i2c->slave_tx_idx = this_i2c->random_read_addr;

+                }

+                /* Call the slave's write transaction handler if it exists. */

+                if ( this_i2c->slave_write_handler != 0u )

+                {

+                    i2c_slave_handler_ret_t h_ret;

+                    h_ret = this_i2c->slave_write_handler( this_i2c, this_i2c->slave_rx_buffer, (uint16_t)this_i2c->slave_rx_idx );

+                    if ( I2C_REENABLE_SLAVE_RX == h_ret )

+                    {

+                        /* There is a small risk that the write handler could

+                         * call I2C_disable_slave() but return

+                         * I2C_REENABLE_SLAVE_RX in error so we only enable

+                         * ACKs if still in slave mode. */

+                         enable_slave_if_required(this_i2c);

+                    }

+                    else

+                    {

+                        HAL_set_8bit_reg_field( this_i2c->base_address, AA, 0x0u );

+                        /* Clear slave mode flag as well otherwise in mixed

+                         * master/slave applications, the AA bit will get set by

+                         * subsequent master operations. */

+                        this_i2c->is_slave_enabled = 0u;

+                    }

+                }

+                else

+                {

+                    /* Re-enable address acknowledge in case we were ready to nack the next received byte. */

+                    HAL_set_8bit_reg_field( this_i2c->base_address, AA, 0x01u );

+                }

+            }

+            else /* A stop or repeated start outside a write/read operation */

+            {

+                /*

+                 * Reset slave_tx_idx so that a subsequent read will result in the slave's

+                 * transmit buffer being sent from the first byte.

+                 */

+                this_i2c->slave_tx_idx = 0u;

+                /*

+                 * See if we need to re-enable acknowledgement as some error conditions, such

+                 * as a master prematurely ending a transfer, can see us get here with AA set

+                 * to 0 which will disable slave operation if we are not careful.

+                 */

+                enable_slave_if_required(this_i2c);

+            }

+

+            /* Mark any previous master write transaction as complete. */

+            this_i2c->slave_status = I2C_SUCCESS;

+            

+            /* Check if transaction was pending. If yes, set the START bit */

+            if(this_i2c->is_transaction_pending)

+            {

+                HAL_set_8bit_reg_field(this_i2c->base_address, STA, 0x01u);

+            }

+

+            /*

+             * Set the transaction back to NO_TRANSACTION to allow user to do further

+             * transaction

+             */

+            this_i2c->transaction = NO_TRANSACTION;

+

+            break;

+            

+        case ST_SLV_RST: /* SMBUS ONLY: timeout state. must clear interrupt */

+  	    //write_hex(STDOUT_FILENO, status);

+            /*

+             * Set the transaction back to NO_TRANSACTION to allow user to do further

+             * transaction.

+             */

+            this_i2c->transaction = NO_TRANSACTION;

+            /*

+             * Reset slave_tx_idx so that a subsequent read will result in the slave's

+             * transmit buffer being sent from the first byte.

+             */

+            this_i2c->slave_tx_idx = 0u;

+            /*

+             * Clear status to I2C_FAILED only if there was an operation in progress.

+             */

+            if(I2C_IN_PROGRESS == this_i2c->slave_status)

+            {

+                this_i2c->slave_status = I2C_FAILED;

+            }

+

+            enable_slave_if_required(this_i2c); /* Make sure AA is set correctly */

+

+            break;

+            

+        /****************** SLAVE TRANSMITTER **************************/

+        case ST_SLAVE_SLAR_ACK: /* SLA+R received, ACK returned */

+        case ST_SLARW_LA:       /* Arbitration lost, and: */

+        case ST_RACK:           /* Data tx'ed, ACK received */

+  	    //write_hex(STDOUT_FILENO, status);

+            if ( status == ST_SLAVE_SLAR_ACK )

+            {

+                this_i2c->transaction = READ_SLAVE_TRANSACTION;

+                this_i2c->random_read_addr = 0u;

+                this_i2c->slave_status = I2C_IN_PROGRESS;

+                /* If Start Bit is set clear it, but store that information since it is because of

+                 * pending transaction

+                 */

+                if(HAL_get_8bit_reg_field(this_i2c->base_address, STA))

+                {

+                    HAL_set_8bit_reg_field(this_i2c->base_address, STA, 0x00u);

+                    this_i2c->is_transaction_pending = 1u;

+                 }

+            }

+            if (this_i2c->slave_tx_idx >= this_i2c->slave_tx_size)

+            {

+                /* Ensure 0xFF is returned to the master when the slave specifies

+                 * an empty transmit buffer. */

+                HAL_set_8bit_reg(this_i2c->base_address, DATA, 0xFFu);

+            }

+            else

+            {

+                /* Load the data the data byte to be sent to the master. */

+                HAL_set_8bit_reg(this_i2c->base_address, DATA, (uint_fast8_t)this_i2c->slave_tx_buffer[this_i2c->slave_tx_idx++]);

+            }

+            /* Determine if this is the last data byte to send to the master. */

+            if (this_i2c->slave_tx_idx >= this_i2c->slave_tx_size) /* last byte? */

+            {

+                 HAL_set_8bit_reg_field(this_i2c->base_address, AA, 0x00u); 

+                /* Next read transaction will result in slave's transmit buffer

+                 * being sent from the first byte. */

+                this_i2c->slave_tx_idx = 0u;

+            }

+            break;

+        

+        case ST_SLAVE_RNACK:    /* Data byte has been transmitted; not-ACK has been received. */

+        case ST_FINAL: /* Last Data byte tx'ed, ACK received */

+  	    //write_hex(STDOUT_FILENO, status);

+            /* We assume that the transaction will be stopped by the master.

+             * Reset slave_tx_idx so that a subsequent read will result in the slave's

+             * transmit buffer being sent from the first byte. */

+            this_i2c->slave_tx_idx = 0u;

+            HAL_set_8bit_reg_field(this_i2c->base_address, AA, 0x01u); 

+

+            /*  Mark previous state as complete */

+            this_i2c->slave_status = I2C_SUCCESS;

+            /* Check if transaction was pending. If yes, set the START bit */

+            if(this_i2c->is_transaction_pending)

+            {

+                HAL_set_8bit_reg_field(this_i2c->base_address, STA, 0x01u);

+            }

+            /*

+             * Set the transaction back to NO_TRANSACTION to allow user to do further

+             * transaction

+             */

+            this_i2c->transaction = NO_TRANSACTION;

+

+            break;

+

+        /* Master Reset has been activated Wait 35 ms for interrupt to be set,

+         * clear interrupt and proceed to 0xF8 state. */

+        case ST_RESET_ACTIVATED:

+        case ST_BUS_ERROR: /* Bus error during MST or selected slave modes */

+        default:

+  	    //write_hex(STDOUT_FILENO, status);

+            /* Some undefined state has encountered. Clear Start bit to make

+             * sure, next good transaction happen */

+            HAL_set_8bit_reg_field(this_i2c->base_address, STA, 0x00u);

+            /*

+             * Set the transaction back to NO_TRANSACTION to allow user to do further

+             * transaction.

+             */

+            this_i2c->transaction = NO_TRANSACTION;

+            /*

+             * Reset slave_tx_idx so that a subsequent read will result in the slave's

+             * transmit buffer being sent from the first byte.

+             */

+            this_i2c->slave_tx_idx = 0u;

+            /*

+             * Clear statuses to I2C_FAILED only if there was an operation in progress.

+             */

+            if(I2C_IN_PROGRESS == this_i2c->master_status)

+            {

+                this_i2c->master_status = I2C_FAILED;

+            }

+

+            if(I2C_IN_PROGRESS == this_i2c->slave_status)

+            {

+                this_i2c->slave_status = I2C_FAILED;

+            }

+

+            break;

+    }

+    

+    if ( clear_irq )

+    {

+        /* clear interrupt. */

+        HAL_set_8bit_reg_field(this_i2c->base_address, SI, 0x00u);

+    }

+    

+    /* Read the status register to ensure the last I2C registers write took place

+     * in a system built around a bus making use of posted writes. */

+//    status = HAL_get_8bit_reg( this_i2c->base_address, STATUS);

+}

+

+/*------------------------------------------------------------------------------

+ * I2C_smbus_init()

+ * See "i2c.h" for details of how to use this function.

+ */

+ 

+/*

+ * SMBSUS_NO    = 1

+ * SMBALERT_NO  = 1

+ * SMBus enable = 1

+ */

+#define INIT_AND_ENABLE_SMBUS   0x54u

+void I2C_smbus_init

+(

+    i2c_instance_t * this_i2c

+)

+{

+    /*

+     * Single byte register write, should be interrupt safe

+     */

+    /* Enable SMBUS */

+    HAL_set_8bit_reg(this_i2c->base_address, SMBUS, INIT_AND_ENABLE_SMBUS);

+}

+

+/*------------------------------------------------------------------------------

+ * I2C_enable_smbus_irq()

+ * See "i2c.h" for details of how to use this function.

+ */

+void I2C_enable_smbus_irq

+(

+    i2c_instance_t * this_i2c,

+    uint8_t  irq_type

+)

+{

+    psr_t saved_psr;

+

+    /*

+     * We need to disable interrupts here to ensure we can update the

+     * hardware register without the SMBUS IRQs interrupting us.

+     */

+

+   	saved_psr=HAL_disable_interrupts();

+

+    if ( irq_type & I2C_SMBALERT_IRQ)

+    {

+        HAL_set_8bit_reg_field(this_i2c->base_address, SMBALERT_IE, 0x01u);

+    }

+    if ( irq_type & I2C_SMBSUS_IRQ)

+    {

+        HAL_set_8bit_reg_field(this_i2c->base_address, SMBSUS_IE, 0x01u);

+    }

+    

+

+   	HAL_restore_interrupts( saved_psr );

+}

+

+/*------------------------------------------------------------------------------

+ * I2C_disable_smbus_irq()

+ * See "i2c.h" for details of how to use this function.

+ */

+void I2C_disable_smbus_irq

+(

+    i2c_instance_t * this_i2c,

+    uint8_t  irq_type

+)

+{

+    psr_t saved_psr;

+

+    /*

+     * We need to disable interrupts here to ensure we can update the

+     * hardware register without the SMBUS IRQs interrupting us.

+     */

+

+   	saved_psr=HAL_disable_interrupts();

+

+    if ( irq_type & I2C_SMBALERT_IRQ)

+    {

+        HAL_set_8bit_reg_field(this_i2c->base_address, SMBALERT_IE, 0x00u);

+    }

+    if (irq_type & I2C_SMBSUS_IRQ )

+    {

+        HAL_set_8bit_reg_field(this_i2c->base_address, SMBSUS_IE, 0x00u);

+    }

+    

+

+   	HAL_restore_interrupts( saved_psr );

+}

+

+/*------------------------------------------------------------------------------

+ * I2C_suspend_smbus_slave()

+ * See "i2c.h" for details of how to use this function.

+ */

+void I2C_suspend_smbus_slave

+(

+    i2c_instance_t * this_i2c

+)

+{

+    psr_t saved_psr;

+

+    /*

+     * We need to disable interrupts here to ensure we can update the

+     * hardware register without the SMBUS IRQs interrupting us.

+     */

+

+   	saved_psr=HAL_disable_interrupts();

+

+    HAL_set_8bit_reg_field(this_i2c->base_address, SMBSUS_NO_CONTROL, 0x00u);

+

+

+   	HAL_restore_interrupts( saved_psr );

+}

+

+/*------------------------------------------------------------------------------

+ * I2C_resume_smbus_slave()

+ * See "i2c.h" for details of how to use this function.

+ */

+void I2C_resume_smbus_slave

+(

+    i2c_instance_t * this_i2c

+)

+{

+    psr_t saved_psr;

+

+    /*

+     * We need to disable interrupts here to ensure we can update the

+     * hardware register without the SMBUS IRQs interrupting us.

+     */

+

+   	saved_psr=HAL_disable_interrupts();

+

+    HAL_set_8bit_reg_field(this_i2c->base_address, SMBSUS_NO_CONTROL, 0x01u);

+

+

+   	HAL_restore_interrupts( saved_psr );

+}

+

+/*------------------------------------------------------------------------------

+ * I2C_reset_smbus()

+ * See "i2c.h" for details of how to use this function.

+ */

+void I2C_reset_smbus

+(

+    i2c_instance_t * this_i2c

+)

+{

+    psr_t saved_psr;

+

+    /*

+     * We need to disable interrupts here to ensure we can update the

+     * hardware register without the SMBUS IRQs interrupting us.

+     */

+

+   	saved_psr=HAL_disable_interrupts();

+    HAL_set_8bit_reg_field(this_i2c->base_address, SMBUS_MST_RESET, 0x01u);

+    

+

+   	HAL_restore_interrupts( saved_psr );

+}

+

+/*------------------------------------------------------------------------------

+ * I2C_set_smbus_alert()

+ * See "i2c.h" for details of how to use this function.

+ */

+void I2C_set_smbus_alert

+(

+    i2c_instance_t * this_i2c

+)

+{

+    psr_t saved_psr;

+

+    /*

+     * We need to disable interrupts here to ensure we can update the

+     * hardware register without the SMBUS IRQs interrupting us.

+     */

+

+   	saved_psr=HAL_disable_interrupts();

+    HAL_set_8bit_reg_field(this_i2c->base_address, SMBALERT_NO_CONTROL, 0x00u);

+

+

+   	HAL_restore_interrupts( saved_psr );

+}

+

+/*------------------------------------------------------------------------------

+ * I2C_clear_smbus_alert()

+ * See "i2c.h" for details of how to use this function.

+ */

+void I2C_clear_smbus_alert

+(

+    i2c_instance_t * this_i2c

+)

+{

+    psr_t saved_psr;

+

+    /*

+     * We need to disable interrupts here to ensure we can update the

+     * hardware register without the SMBUS IRQs interrupting us.

+     */

+

+   	saved_psr=HAL_disable_interrupts();

+

+    HAL_set_8bit_reg_field(this_i2c->base_address, SMBALERT_NO_CONTROL, 0x01u);

+

+

+   	HAL_restore_interrupts( saved_psr );

+}

+

+/*------------------------------------------------------------------------------

+ * I2C_get_irq_status()

+ * See "i2c.h" for details of how to use this function.

+ */

+uint8_t I2C_get_irq_status

+(

+    i2c_instance_t * this_i2c

+)

+{

+    uint8_t status ;

+    uint8_t irq_type = I2C_NO_IRQ ;

+

+    status = HAL_get_8bit_reg(this_i2c->base_address, SMBUS);

+

+    if( status & (uint8_t)SMBALERT_NI_STATUS_MASK )

+    {

+        irq_type |= I2C_SMBALERT_IRQ ;

+    }

+

+    if( status & (uint8_t)SMBSUS_NI_STATUS_MASK )

+    {

+        irq_type |= I2C_SMBSUS_IRQ ;

+    }

+

+    status = HAL_get_8bit_reg(this_i2c->base_address, CONTROL);

+

+    if( status & (uint8_t)SI_MASK )

+    {

+        irq_type |= I2C_INTR_IRQ ;

+    }

+    return(irq_type);

+}

+

+/*------------------------------------------------------------------------------

+ * I2C_set_slave_addr2()

+ * See "i2c.h" for details of how to use this function.

+ */

+void I2C_set_user_data

+(

+    i2c_instance_t * this_i2c,

+    void * p_user_data

+)

+{

+    this_i2c->p_user_data = p_user_data ;

+}

+

+/*------------------------------------------------------------------------------

+ * I2C_get_user_data()

+ * See "i2c.h" for details of how to use this function.

+ */

+void * I2C_get_user_data

+(

+    i2c_instance_t * this_i2c

+)

+{

+    return( this_i2c->p_user_data);

+}

+

+#ifdef __cplusplus

+}

+#endif

+

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreI2C/core_i2c.h b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreI2C/core_i2c.h
new file mode 100644
index 0000000..2b1d5ac
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreI2C/core_i2c.h
@@ -0,0 +1,2280 @@
+/*******************************************************************************

+ * (c) Copyright 2009-2015 Microsemi SoC Products Group.  All rights reserved.

+ * 

+ * CoreI2C software driver Application Programming Interface.

+ * This file contains defines and function declarations allowing to interface

+ * with the CoreI2C software driver.

+ * 

+ * SVN $Revision: 7984 $

+ * SVN $Date: 2015-10-12 12:07:40 +0530 (Mon, 12 Oct 2015) $

+ */

+/*=========================================================================*//**

+  @mainpage CoreI2C Bare Metal Driver.

+   The CoreI2C bare metal software driver supports I2C master and slave

+   operations.

+

+  @section intro_sec Introduction

+  The CoreI2C driver provides a set of functions for controlling the Microsemi

+  CoreI2C hardware IP. The driver supports up to 16 separate I2C channels per

+  CoreI2C instance, with common slave address settings shared between channels

+  on a device.

+  

+  Optional features of the CoreI2C allow it operate with I2C based protocols

+  such as System Management Bus (SMBus), Power Management Bus (PMBus) and

+  Intelligent Platform Management Interface (IPMI). This driver provides support

+  for these features when enabled in the CoreI2C IP.

+  

+  The major features provided by CoreI2C driver are:

+    - Support for configuring the I2C channels of each CoreI2C peripheral.

+    - I2C master operations.

+    - I2C slave operations.

+    - SMBus related operations.

+

+  This driver can be used as part of a bare metal system where no operating 

+  system  is available. The driver can be adapted for use as part of an 

+  operating system, but the implementation of the adaptation layer between the 

+  driver and  the operating system's driver model is outside the scope of this 

+  driver.

+  

+  @section hw_dependencies Hardware Flow Dependencies

+  Your application software should configure the CoreI2C driver through

+  calls to the I2C_init() function for each CoreI2C instance in the

+  hardware design.  The configuration parameters include the CoreI2C hardware

+  instance base address and other runtime parameters, such as the I2C serial

+  clock frequency and I2C device address.

+  

+  Once channel 0 of a CoreI2C peripheral has been initialized via I2C_init(),

+  any additional channels present should be configured by calling

+  I2C_channel_init() for each of the remaining channels.

+  

+  No CoreI2C hardware configuration parameters are used by the driver, apart

+  from the CoreI2C hardware instance base address. Hence, no additional

+  configuration files are required to use the driver. 

+  

+  Interrupt Control

+  The CoreI2C driver has to enable and disable the generation of interrupts by

+  CoreI2C at various times when it is operating. This enabling and disabling of

+  interrupts must be done through the systemÂ’s interrupt controller. For that

+  reason, the method of controlling the CoreI2C interrupt is system specific

+  and it is necessary to customize the I2C_enable_irq() and I2C_disable_irq()

+  functions. These functions are found in the file i2c_interrupt.c. Their

+  default implementation fires an assertion to attract attention to the fact

+  that these functions must be modified.

+  

+  The implementation of the I2C_enable_irq() function should permit interrupts

+  generated by a CoreI2C instance to interrupt the processor. The implementation

+  of the I2C_disable_irq() function should prevent interrupts generated by a

+  CoreI2C instance from interrupting the processor. Please refer to the provided

+  example projects for a working implementation of these functions.

+  

+  The function I2C_register_write_handler() is used to register a write handler

+  function with the CoreI2C driver that it calls on completion of an I2C write

+  transaction by the CoreI2C slave. It is your responsibility to create and

+  register the implementation of this handler function that processes or

+  trigger the processing of the received data.

+  

+  The SMBSUS and SMBALERT interrupts are related to the SMBus interface and are

+  enabled and disabled through I2C_enable_smbus_irq() and 

+  I2C_disable_smbus_irq() respectively. It is your responsibility to create

+  interrupt handler functions in your application to get the desired response

+  for the SMBus interrupts.

+

+  Note: You must include the path to any application header files that are

+        included in the i2c_interrupt.c file, as an include path in your

+        projectÂ’s compiler settings. The details of how to do this will depend

+        on your development software.

+

+  SMBus Logic options

+  SMBus related APIs will not have any effect if in CoreI2C hardware

+  configuration "Generate SMBus Logic" is not enabled. The APIs which will not

+  give desired results in case SMBus Logic is disabled are:

+  

+      I2C_smbus_init()

+      I2C_reset_smbus()

+      I2C_enable_smbus_irq()

+      I2C_disable_smbus_irq()

+      I2C_suspend_smbus_slave()

+      I2C_resume_smbus_slave()

+      I2C_set_smsbus_alert()

+      I2C_clear_smsbus_alert()

+      I2C_get_irq_status() 

+

+  Fixed Baud Rate Values

+  The serial clock frequency parameter passed to the I2C_init() and 

+  I2C_channel_init() functions may not have any effect if fixed values were

+  selected for Baud rate in the hardware configuration of CoreI2C. When fixed

+  values are selected for these baud rates, the driver cannot overwrite

+  the fixed values.

+

+  Fixed Slave Address Options Values

+  The primary slave address  parameter passed to the I2C_init() function, and

+  secondary address value passed to the I2C_set_slave_second_addr() function,

+  may not have the desired effect if fixed values were selected for the slave 0

+  address and slave 1 address respectively. Proper operation of this version of

+  the driver requires the slave addresses to be programmable.

+

+  @section theory_op Theory of Operation

+  The CoreI2C software driver is designed to allow the control of multiple

+  instances of CoreI2C with one or more I2C channels. Each channel in an

+  instance of CoreI2C in the hardware design is associated with a single 

+  instance of the i2c_instance_t structure in the software. You must allocate

+  memory for one unique i2c_instance_t structure instance for each channel of

+  each CoreI2C hardware instance. The contents of these data structures are

+  initialised during calls to I2C_init() and if necessary I2C_channel_init().

+  A pointer to the structure is passed to subsequent driver functions in order

+  to identify the CoreI2C hardware instance and channel you wish to perform the

+  requested operation.

+

+  Note: Do not attempt to directly manipulate the contents of i2c_instance_t

+       structures. These structures are only intended to be modified by the driver

+       functions.

+

+  The CoreI2C driver functions are grouped into the following categories:

+    - Initialization and configuration functions

+    - Interrupt control

+    - I2C slave addressing functions

+    - I2C master operations functions to handle write, read and write-read 

+      transactions

+    - I2C slave operations functions to handle write, read and write-read 

+      transactions

+    - Mixed master-slave operations 

+    - SMBus interface configuration and control.

+    

+  Initialization and Configuration

+    The CoreI2C device is first initialized through a call to the I2C_init()

+    function. Since each CoreI2C peripheral supports up to 16 channels, an

+    additional function, I2C_channel_init(), is required to initialize the

+    remaining channels with their own data structures.

+

+    I2C_init() initializes channel 0 of a CoreI2C and the i2c_instance_t for

+    channel 0 acts as the basis for further channel initialization as the

+    hardware base address and I2C serial address are same across all the

+    channels. I2C_init() must be called before any other  I2C driver function

+    calls. The I2C_init() call for each CoreI2C takes the I2C serial address

+    assigned to the I2C and the serial clock divider to be used to generate its

+    I2C clock as configuration parameters. 

+    

+    I2C_channel_init() takes as input parameters a pointer to the CoreI2C 

+    i2c_instance_t which has been initialized via I2C_init() and a pointer to a

+    separate i2c_instance_t which represents this new channel. Another input

+    parameter which is required by this function is serial clock divider which

+    generates its I2C clock. 

+    

+  Interrupt Control

+    The CoreI2C driver is interrupt driven and it uses each channels INT

+    interrupt to drive the state machine which is at the heart of the driver.

+    The application is responsible for providing the link between the interrupt

+    generating hardware and the CoreI2C interrupt handler and must ensure that

+    the I2C_isr() function is called with the correct i2c_instance_t structure

+    pointer for the CoreI2C channel initiating the interrupt.

+    

+    The driver enables and disables the generation of INT interrupts by CoreI2C

+    at various times when it is operating through the user supplied

+    I2C_enable_irq() and I2C_disable_irq() functions. 

+    

+    The function I2C_register_write_handler() is used to register a write

+    handler function with the CoreI2C driver which is called on completion

+    of an I2C write transaction by the CoreI2C slave. It is the user

+    applications responsibility to create and register the implementation of

+    this handler function that processes or triggers the processing of the

+    received data. 

+    

+    The other two interrupt sources in the CoreI2C, are related to SMBus

+    operation and are enabled and disabled through I2C_enable_smbus_irq() and

+    I2C_disable_smbus_irq() respectively. Due to the application specific

+    nature of the response to SMBus interrupts, you must design interrupt

+    handler functions in the application to get the desired behaviour for

+    SMBus related interrupts.

+    

+    If enabled, the SMBA_INT signal from the CoreI2C is asserted if an

+    SMBALERT condition is signalled on the SMBALERT_NI input for the channel.

+    

+    If enabled, the SMBS_INT signal from the CoreI2C is asserted if an

+    SMBSUSPEND condition is signalled on the SMBSUS_NI input for the channel.

+

+  I2C slave addressing functions

+    A CoreI2C peripheral can respond to three slave addresses:

+    - Slave address 0 - This is the primary slave address which is used for

+                        accessing a CoreI2C channel when it acts as a slave in

+                        I2C transactions. You must configure the primary slave

+                        address via I2C_init().

+                        

+    - Slave address 1 - This is the secondary slave address which might be

+                        required in certain application specific scenarios.

+                        The secondary slave address can be configured via

+                        I2C_set_slave_second_addr() and disabled via 

+                        I2C_disable_slave_second_addr().

+                        

+    - General call address - A CoreI2C slave can be configured to respond to

+                        a broadcast command by a master transmitting the

+                        general call address of 0x00. Use the I2C_set_gca()

+                        function to enable the slave to respond to the general

+                        call address. If the CoreI2C slave is not required to

+                        respond to the general call address, disable this

+                        address by calling I2C_clear_gca().

+

+    Note: All channels on a CoreI2C instance share the same slave address logic.

+          This means that they cannot have separate slave addresses and rely on

+          the separate physical I2C bus connections to distinguish them.

+          

+  Transaction Types

+    The I2C driver is designed to handle three types of I2C transaction:

+      Write transactions

+      Read transactions

+      Write-read transactions

+ 

+    Write transaction

+      The master I2C device initiates a write transaction by sending a START bit

+      as soon as the bus becomes free. The START bit is followed by the 7-bit

+      serial address of the target slave device followed by the read/write bit

+      indicating the direction of the transaction. The slave acknowledges the

+      receipt of it's address with an acknowledge bit. The master sends data one

+      byte at a time to the slave, which must acknowledge receipt of each byte

+      for the next byte to be sent. The master sends a STOP bit to complete the

+      transaction. The slave can abort the transaction by replying with a 

+      non-acknowledge bit instead of an acknowledge.

+      

+      The application programmer can choose not to send a STOP bit at the end of

+      the transaction causing the next transaction to begin with a repeated 

+      START bit.

+      

+    Read transaction

+      The master I2C device initiates a read transaction by sending a START bit

+      as soon as the bus becomes free. The START bit is followed by the 7-bit

+      serial address of the target slave device followed by the read/write bit

+      indicating the direction of the transaction. The slave acknowledges

+      receipt of it's slave address with an acknowledge bit. The slave sends

+      data one byte at a time to the master, which must acknowledge receipt of

+      each byte for the next byte to be sent. The master sends a non-acknowledge

+      bit following the last byte it wishes to read followed by a STOP bit.

+      

+      The application programmer can choose not to send a STOP bit at the end of

+      the transaction causing the next transaction to begin with a repeated 

+      START bit.

+ 

+    Write-read transaction

+      The write-read transaction is a combination of a write transaction

+      immediately followed by a read transaction. There is no STOP bit between

+      the write and read phases of a write-read transaction. A repeated START

+      bit is sent between the write and read phases.

+      

+      Whilst the write handler is being executed, the slave holds the clock line

+      low to stretch the clock until the response is ready.

+      

+      The write-read transaction is typically used to send a command or offset

+      in the write transaction specifying the logical data to be transferred

+      during the read phase.

+      

+      The application programmer can choose not to send a STOP bit at the end of

+      the transaction causing the next transaction to begin with a repeated

+      START bit.

+

+  Master Operations

+    The application can use the I2C_write(), I2C_read() and I2C_write_read()

+    functions to initiate an I2C bus transaction. The application can then wait

+    for the transaction to complete using the I2C_wait_complete() function

+    or poll the status of the I2C transaction using the I2C_get_status()

+    function until it returns a value different from I2C_IN_PROGRESS. The

+    I2C_system_tick() function can be used to set a time base for the

+    I2C_wait_complete() functionÂ’s time out delay.

+

+  Slave Operations

+    The configuration of the  I2C driver to operate as an I2C slave requires

+    the use of the following functions:

+       I2C_set_slave_tx_buffer()

+       I2C_set_slave_rx_buffer()

+       I2C_set_slave_mem_offset_length()

+       I2C_register_write_handler()

+       I2C_enable_slave()

+       

+    Use of all functions is not required if the slave I2C does not need to support

+    all types of I2C read transactions. The subsequent sections list the functions

+    that must be used to support each transaction type. 

+    

+    Responding to read transactions

+      The following functions are used to configure the  CoreI2C driver to

+      respond to I2C read transactions:

+        I2C_set_slave_tx_buffer()

+        I2C_enable_slave()

+        

+      The function I2C_set_slave_tx_buffer() specifies the data buffer that

+      will be transmitted when the I2C slave is the target of an I2C read

+      transaction. It is then up to the application to manage the content of

+      that buffer to control the data that will be transmitted to the I2C

+      master as a result of the read transaction.

+      

+      The function I2C_enable_slave() enables the  I2C hardware instance

+      to respond to I2C transactions. It must be called after the  I2C driver

+      has been configured to respond to the required transaction types.

+

+    Responding to write transactions

+      The following functions are used to configure the  I2C driver to respond

+      to I2C write transactions:

+        I2C_set_slave_rx_buffer()

+        I2C_register_write_handler()

+        I2C_enable_slave()

+        

+      The function I2C_set_slave_rx_buffer() specifies the data buffer that

+      will be used to store the data received by the I2C slave when it is the

+      target an I2C  write transaction.

+      

+      The function I2C_register_write_handler() specifies the handler function

+      that must be called on completion of the I2C write transaction. It is this

+      handler function that processes or triggers the processing of the received

+      data.

+      

+      The function I2C_enable_slave() enables the  I2C hardware instance

+      to respond to I2C transactions. It must be called after the  I2C driver

+      has been configured to respond to the required transaction types.

+

+    Responding to write-read transactions

+      The following functions are used to configure the CoreI2C driver to 

+      respond to write-read transactions:

+        I2C_set_slave_mem_offset_length()

+        I2C_set_slave_tx_buffer()

+        I2C_set_slave_rx_buffer()

+        I2C_register_write_handler()

+        I2C_enable_slave()

+        

+      The function I2C_set_slave_mem_offset_length() specifies the number of

+      bytes expected by the I2C slave during the write phase of the write-read

+      transaction.

+      

+      The function I2C_set_slave_tx_buffer() specifies the data that will be

+      transmitted to the I2C master during the read phase of the write-read

+      transaction. The value received by the I2C slave during the write phase of

+      the transaction will be used as an index into the transmit buffer

+      specified by this function to decide which part of the transmit buffer

+      will be transmitted to the I2C master as part of the read phase of the

+      write-read transaction. 

+      

+      The function I2C_set_slave_rx_buffer() specifies the data buffer that

+      will be used to store the data received by the I2C slave during the write

+      phase of the write-read transaction. This buffer must be at least large

+      enough to accommodate the number of bytes specified through the

+      I2C_set_slave_mem_offset_length() function.

+      

+      The function I2C_register_write_handler() can optionally be used to

+      specify a handler function that is called on completion of the write phase

+      of the I2C write-read transaction. If a handler function is registered, it

+      is responsible for processing the received data in the slave receive

+      buffer and populating the slave transmit buffer with the data that will be

+      transmitted to the I2C master as part of the read phase of the write-read

+      transaction.

+      

+      The function I2C_enable_slave() enables the CoreI2C hardware instance to 

+      respond to I2C transactions. It must be called after the CoreI2C driver

+      has been configured to respond to the required transaction types.

+

+  Mixed Master-Slave Operations

+    The CoreI2C device supports mixed master and slave operations. If the 

+    CoreI2C slave has a transaction in progress and your application attempts to

+    begin a master mode transaction, the CoreI2C driver queu3es the master mode

+    transaction until the bus is released and the CoreI2C can switch to master

+    mode and acquire the bus. The CoreI2C master then starts the previously

+    queued master transaction.

+    

+  SMBus Control

+    The CoreI2C driver enables the CoreI2C peripheralÂ’s SMBus functionality

+    using the I2C_smbus_init() function.

+    

+    The I2C_suspend_smbus_slave() function is used, with a master mode CoreI2C,

+    to force slave devices on the SMBus to enter their power-down/suspend mode.

+    The I2C_resume_smbus_slave() function is used to end the suspend operation

+    on the SMBus.

+    

+    The I2C_reset_smbus() function is used, with a master mode CoreI2C, to force

+    all devices on the SMBus to reset their SMBUs interface.

+    

+    The I2C_set_smsbus_alert() function is used, by a slave mode CoreI2C, to

+    force communication with the SMBus master. Once communications with the

+    master is initiated, the I2C_clear_smsbus_alert() function is used to clear

+    the alert condition.

+    

+    The I2C_enable_smbus_irq() and I2C_disable_smbus_irq() functions are used to

+    enable and disable the SMBSUS and SMBALERT SMBus interrupts.

+

+ *//*=========================================================================*/

+

+#ifndef CORE_I2C_H_

+#define CORE_I2C_H_

+

+#include "cpu_types.h"

+#ifdef __cplusplus

+extern "C" {

+#endif 

+

+/*-------------------------------------------------------------------------*//**

+  The I2C_RELEASE_BUS constant is used to specify the options parameter to

+  functions I2C_read(), I2C_write() and I2C_write_read() to indicate

+  that a STOP bit must be generated at the end of the I2C transaction to release

+  the bus.

+ */

+#define I2C_RELEASE_BUS     0x00u

+

+/*-------------------------------------------------------------------------*//**

+  The I2C_HOLD_BUS constant is used to specify the options parameter to

+  functions I2C_read(), I2C_write() and I2C_write_read() to indicate

+  that a STOP bit must not be generated at the end of the I2C transaction in

+  order to retain the bus ownership. This causes the next transaction to

+  begin with a repeated START bit and no STOP bit between the transactions.

+ */

+#define I2C_HOLD_BUS        0x01u

+

+/*-------------------------------------------------------------------------*//**

+  The following constants specify the interrupt identifier number which will be

+  solely used by driver API. This has nothing to do with hardware interrupt line.

+  I2C_INT_IRQ is the primary interrupt signal which drives the state machine

+  of the CoreI2C driver. The I2C_SMBALERT_IRQ and I2C_SMBUS_IRQ are used by

+  SMBus interrupt enable and disable functions. These IRQ numbers are also used

+  by I2C_get_irq_status().

+ */

+#define I2C_NO_IRQ             0x00u

+#define I2C_SMBALERT_IRQ       0x01u

+#define I2C_SMBSUS_IRQ         0x02u

+#define I2C_INTR_IRQ           0x04u

+

+/*-------------------------------------------------------------------------*//**

+  The I2C_NO_TIMEOUT constant is used as parameter to the I2C_wait_complete()

+  function to indicate that the wait for completion of the transaction should

+  not time out.

+ */

+#define I2C_NO_TIMEOUT  0u

+

+/*-------------------------------------------------------------------------*//**

+  The i2c_channel_number_t type is used to specify the channel number of a

+  CoreI2C instance.

+ */

+typedef enum i2c_channel_number {

+    I2C_CHANNEL_0 = 0u,

+    I2C_CHANNEL_1,

+    I2C_CHANNEL_2,

+    I2C_CHANNEL_3,

+    I2C_CHANNEL_4,

+    I2C_CHANNEL_5,

+    I2C_CHANNEL_6,

+    I2C_CHANNEL_7,

+    I2C_CHANNEL_8,

+    I2C_CHANNEL_9,

+    I2C_CHANNEL_10,

+    I2C_CHANNEL_11,

+    I2C_CHANNEL_12,

+    I2C_CHANNEL_13,

+    I2C_CHANNEL_14,

+    I2C_CHANNEL_15,

+    I2C_MAX_CHANNELS = 16u

+} i2c_channel_number_t;

+

+/*-------------------------------------------------------------------------*//**

+  The i2c_clock_divider_t type is used to specify the divider to be applied

+  to the I2C PCLK or BCLK signal in order to generate the I2C clock.

+  The I2C_BCLK_DIV_8 value selects a clock frequency based on division of BCLK,

+  all other values select a clock frequency based on division of PCLK.

+ */

+typedef enum i2c_clock_divider {

+    I2C_PCLK_DIV_256 = 0u,

+    I2C_PCLK_DIV_224,

+    I2C_PCLK_DIV_192,

+    I2C_PCLK_DIV_160,

+    I2C_PCLK_DIV_960,

+    I2C_PCLK_DIV_120,

+    I2C_PCLK_DIV_60,

+    I2C_BCLK_DIV_8

+} i2c_clock_divider_t;

+

+/*-------------------------------------------------------------------------*//**

+  The i2c_status_t type is used to report the status of I2C transactions.

+ */

+typedef enum i2c_status

+{

+    I2C_SUCCESS = 0u,

+    I2C_IN_PROGRESS,

+    I2C_FAILED,

+    I2C_TIMED_OUT

+} i2c_status_t;

+

+/*-------------------------------------------------------------------------*//**

+  The i2c_slave_handler_ret_t type is used by slave write handler functions

+  to indicate whether or not the received data buffer should be released.

+ */

+typedef enum i2c_slave_handler_ret {

+    I2C_REENABLE_SLAVE_RX = 0u,

+    I2C_PAUSE_SLAVE_RX = 1u

+} i2c_slave_handler_ret_t;

+

+typedef struct i2c_instance i2c_instance_t ;

+

+/*-------------------------------------------------------------------------*//**

+  Slave write handler functions prototype.

+  ------------------------------------------------------------------------------

+  This defines the function prototype that must be followed by  I2C slave write

+  handler functions. These functions are registered with the CoreI2C driver

+  through the I2C_register_write_handler() function.

+

+  Declaring and Implementing Slave Write Handler Functions:

+    Slave write handler functions should follow the following prototype:

+    i2c_slave_handler_ret_t write_handler

+    ( 

+        i2c_instance_t *instance, uint8_t * data, uint16_t size 

+    );

+

+    The instance parameter is a pointer to the i2c_instance_t for which this

+    slave write handler has been declared.

+    

+    The data parameter is a pointer to a buffer (received data buffer) holding

+    the data written to the I2C slave.

+    

+    Defining the macro INCLUDE_SLA_IN_RX_PAYLOAD causes the driver to insert the

+    actual address used to access the slave as the first byte in the buffer.

+    This allows applications tailor their response based on the actual address

+    used to access the slave (primary address, secondary address or GCA).

+    

+    The size parameter is the number of bytes held in the received data buffer.

+    Handler functions must return one of the following values:

+        I2C_REENABLE_SLAVE_RX

+        I2C_PAUSE_SLAVE_RX.

+        

+    If the handler function returns I2C_REENABLE_SLAVE_RX, the driver releases

+    the received data buffer and allows further I2C write transactions to the

+    I2C slave to take place.

+    

+    If the handler function returns I2C_PAUSE_SLAVE_RX, the I2C slave responds

+    to subsequent write requests with a non-acknowledge bit (NACK), until the

+    received data buffer content has been processed by some other part of the

+    software application.

+    

+    A call to I2C_enable_slave() is required at some point after returning

+    I2C_PAUSE_SLAVE_RX in order to release the received data buffer so it can

+    be used to store data received by subsequent I2C write transactions.

+ */

+typedef i2c_slave_handler_ret_t (*i2c_slave_wr_handler_t)(i2c_instance_t *instance, uint8_t *, uint16_t );

+

+

+/*-------------------------------------------------------------------------*//**

+  i2c_instance_t

+  ------------------------------------------------------------------------------

+  This structure is used to identify the various CoreI2C hardware instances in

+  your system and the I2C channels within them. Your application software should

+  declare one instance of this structure for each channel of each instance of

+  CoreI2C in your system. The functions I2C_init() and I2C_channel_init() 

+  initialize this structure depending on whether it is channel 0 or one of the

+  additional channels respectively. A pointer to an initialized instance of the

+  structure should be passed as the first parameter to the CoreI2C driver

+  functions, to identify which CoreI2C hardware instance and channel should

+  perform the requested operation.

+  

+  The contents of this data structure should not be modified or used outside of

+  the CoreI2C driver. Software using the CoreI2C driver should only need to 

+  create one single instance of this data structure for each channel of each 

+  CoreI2C hardware instance in the system then pass a pointer to these data

+  structures with each call to the CoreI2C driver in order to identify the

+  CoreI2C hardware instance it wishes to use.

+ */

+struct i2c_instance

+{

+    addr_t base_address;

+    uint_fast8_t ser_address;

+

+    /* Transmit related info:*/

+    uint_fast8_t target_addr;

+

+    /* Current transaction type (WRITE, READ, RANDOM_READ)*/

+    uint8_t transaction;

+    

+    uint_fast16_t random_read_addr;

+

+    uint8_t options;

+    

+    /* Master TX INFO: */

+    const uint8_t * master_tx_buffer;

+    uint_fast16_t master_tx_size;

+    uint_fast16_t master_tx_idx;

+    uint_fast8_t dir;

+    

+    /* Master RX INFO: */

+    uint8_t * master_rx_buffer;

+    uint_fast16_t master_rx_size;

+    uint_fast16_t master_rx_idx;

+

+    /* Master Status */

+    volatile i2c_status_t master_status;

+    uint32_t master_timeout_ms;

+

+    /* Slave TX INFO */

+    const uint8_t * slave_tx_buffer;

+    uint_fast16_t slave_tx_size;

+    uint_fast16_t slave_tx_idx;

+    

+    /* Slave RX INFO */

+    uint8_t * slave_rx_buffer;

+    uint_fast16_t slave_rx_size;

+    uint_fast16_t slave_rx_idx;

+    /* Slave Status */

+    volatile i2c_status_t slave_status;

+    

+    /* Slave data: */

+    uint_fast8_t slave_mem_offset_length;

+    i2c_slave_wr_handler_t slave_write_handler;

+    uint8_t is_slave_enabled;

+    

+    /* user  specific data */

+    void *p_user_data ;

+

+    /* I2C bus status */

+    uint8_t bus_status;

+

+    /* Is transaction pending flag */

+    uint8_t is_transaction_pending;

+

+    /* I2C Pending transaction */

+    uint8_t pending_transaction;

+};

+

+/*-------------------------------------------------------------------------*//**

+  I2C initialization routine.

+  ------------------------------------------------------------------------------

+  The I2C_init() function is used to configure channel 0 of a CoreI2C instance.

+  It sets the base hardware address which is used to locate the CoreI2C instance

+  in memory and also used internally by I2C_channel_init() to calculate the

+  register addresses for any additional channels. The slave serial address set

+  is shared by all channels on a CoreI2C instance. 

+  

+  If only one channel is configured in a CoreI2C, the address of the 

+  i2c_instance_t used in I2C_Init() will also be used in subsequent calls to the

+  CoreI2C driver functions. If more than one channel is configured in the

+  CoreI2C, I2C_channel_init() will be called after I2C_init(), which initializes

+  the i2c_instance_t data structure for a specific channel.

+  ------------------------------------------------------------------------------

+ @param this_i2c:

+    Pointer to the i2c_instance_t data structure which will hold all data

+    related to channel 0 of the CoreI2C instance being initialized. A pointer

+    to this structure will be used in all subsequent calls to CoreI2C driver

+    functions which are to operate on channel 0 of this CoreI2C instance.

+  

+  @param base_address:

+    Base address in the processor's memory map of the registers of the CoreI2C

+    instance being initialized.

+ 

+  @param ser_address:

+    This parameter sets the primary I2C serial address (SLAVE0 address) for the

+    CoreI2C being initialized. It is the principal I2C bus address to which the

+    CoreI2C instance will respond. CoreI2C can operate in master mode or slave

+    mode and the serial address is significant only in the case of I2C slave

+    mode. In master mode, CoreI2C does not require a serial address and the

+    value of this parameter is not important. If you do not intend to use the

+    CoreI2C device in slave mode, then any dummy slave address value can be

+    provided to this parameter. However, in systems where the CoreI2C may be

+    expected to switch from master mode to slave mode, it is advisable to

+    initialize the CoreI2C device with a valid serial slave address.

+    

+    You need to call the I2C_init() function whenever it is required to change 

+    the primary slave address as there is no separate function to set the

+    primary slave address of the I2C device. The serial address being

+    initialized through this function is basically the primary slave address or

+    slave address0. I2C_set_slave_second_addr() can be used to set the

+    secondary slave address or slave address 1.

+    Note : ser_address parameter does not have any affect if fixed slave 

+           address is enabled in CoreI2C hardware design. CoreI2C will 

+           be always addressed with the hardware configured fixed slave

+           address.

+    Note : ser_address parameter will not have any affect if the CoreI2C

+           instance is only used in master mode.

+

+  @param ser_clock_speed:

+    This parameter sets the I2C serial clock frequency. It selects the divider

+    that will be used to generate the serial clock from the APB PCLK or from

+    the BCLK. It can be one of the following:

+        I2C_PCLK_DIV_256

+        I2C_PCLK_DIV_224

+        I2C_PCLK_DIV_192

+        I2C_PCLK_DIV_160

+        I2C_PCLK_DIV_960

+        I2C_PCLK_DIV_120

+        I2C_PCLK_DIV_60

+        I2C_BCLK_DIV_8

+    Note: serial_clock_speed value will have no affect if Fixed baud rate is 

+          enabled in CoreI2C hardware instance configuration dialogue window. 

+          The fixed baud rate divider value will override the value

+          passed as parameter in this function.

+    Note: serial_clock_speed value is not critical for devices that only operate

+          as slaves and can be set to any of the above values.  

+

+  @return none.  

+  

+  Example:

+  @code

+    #define COREI2C_BASE_ADDR  0xC0000000u

+    #define COREI2C_SER_ADDR   0x10u

+

+    i2c_instance_t g_i2c_inst;

+

+    void system_init( void )

+    {

+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, COREI2C_SER_ADDR,

+                  I2C_PCLK_DIV_256 );

+    }

+  @endcode

+ */

+void I2C_init

+(

+    i2c_instance_t * this_i2c,

+    addr_t base_address,

+    uint8_t ser_address,

+    i2c_clock_divider_t ser_clock_speed

+);

+

+/*-------------------------------------------------------------------------*//**

+  I2C channel initialization routine.

+  ------------------------------------------------------------------------------

+  The I2C_channel_init() function initializes and configures hardware and data

+  structures of one of the additional channels of a CoreI2C instance.

+  I2C_init() must be called before calling this function to set the CoreI2C

+  instance hardware base address and I2C serial address. I2C_channel_init() also

+  initializes I2C serial clock divider to set the serial clock baud rate.  

+  The pointer to data structure i2c_instance_t used for a particular channel

+  will be used as an input parameter to subsequent CoreI2C driver functions

+  which operate on this channel.

+  ------------------------------------------------------------------------------

+  @param this_i2c_channel

+    Pointer to the i2c_instance_t data structure holding all data related to the

+    CoreI2C channel being initialized. A pointer to the same data structure will

+    be used in subsequent calls to the CoreI2C driver functions in order to

+    identify the CoreI2C channel instance that should perform the operation 

+    implemented by the called driver function.

+

+  @param this_i2c:

+    This is a pointer to an i2c_instance_t structure previously initialized by

+    I2C_init(). It holds information regarding the hardware base address and

+    I2C serial address for the CoreI2C containing the channel to be

+    initialized. This information is required by I2C_channel_init() to

+    initialize the i2c_instance_t structure pointed to by this_i2c_channel as

+    all channels in a CoreI2C instance share the same base address and serial

+    address. It is very important that the i2c_instance_t structure pointed to

+    by this_i2c has been previously initialized with a call to I2C_init().

+    

+  @param channel_number:

+    This parameter of type i2c_channel_number_t identifies the channel to be

+    initialized.

+

+  @param ser_clock_speed:

+    This parameter sets the I2C serial clock frequency. It selects the divider

+    that will be used to generate the serial clock from the APB PCLK or from

+    the BCLK. It can be one of the following:

+        I2C_PCLK_DIV_256

+        I2C_PCLK_DIV_224

+        I2C_PCLK_DIV_192

+        I2C_PCLK_DIV_160

+        I2C_PCLK_DIV_960

+        I2C_PCLK_DIV_120

+        I2C_PCLK_DIV_60

+        I2C_BCLK_DIV_8

+    

+    Note: serial_clock_speed value will have no affect if Fixed baud rate is 

+          enabled in CoreI2C hardware instance configuration dialogue window. 

+          The fixed baud rate divider value will supersede the value 

+          passed as parameter in this function.

+

+    Note: ser_clock_speed value is not critical for devices that only operate

+          as slaves and can be set to any of the above values.  

+  @return none.  

+  

+  Example:

+  @code

+    #define COREI2C_BASE_ADDR  0xC0000000u

+    #define COREI2C_SER_ADDR   0x10u

+    #define DATA_LENGTH        16u

+

+    i2c_instance_t g_i2c_inst;

+    i2c_instance_t g_i2c_channel_1_inst;

+

+    uint8_t  tx_buffer[DATA_LENGTH];

+    uint8_t  write_length = DATA_LENGTH;

+

+    void system_init( void )

+    {

+        uint8_t  target_slave_addr = 0x12;

+        

+        // Initialize base CoreI2C instance

+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, COREI2C_SER_ADDR,

+                  I2C_PCLK_DIV_256 );

+        

+        // Initialize CoreI2C channel 1 with different clock speed

+        I2C_channel_init( &g_i2c_channel_1_inst, &g_i2c_inst, I2C_CHANNEL_1,

+                          I2C_PCLK_DIV_224 );

+        

+        // Write data to Channel 1 of CoreI2C instance.

+        I2C_write( &g_i2c_channel_1_inst, target_slave_addr, tx_buffer,

+                   write_length, I2C_RELEASE_BUS );

+    }

+  @endcode

+          

+*/

+void I2C_channel_init

+(

+    i2c_instance_t * this_i2c_channel,

+    i2c_instance_t * this_i2c,

+    i2c_channel_number_t channel_number,

+    i2c_clock_divider_t ser_clock_speed

+);

+

+/*------------------------------------------------------------------------------

+  CoreI2C interrupt service routine.

+  ------------------------------------------------------------------------------

+    The function I2C_isr is the CoreI2C interrupt service routine. User must

+    call this function from their application level CoreI2C interrupt handler

+    function. This function runs the I2C state machine based on previous and 

+    current status.

+  ------------------------------------------------------------------------------

+    @param this_i2c:

+    The this_i2c parameter is a pointer to the i2c_instance_t data structure

+    holding all data related to a specific CoreI2C channel. For example, if only

+    one channel is initialized, this data structure holds the information of 

+    channel 0 of the instantiated CoreI2C hardware.

+    

+    @return none

+    

+    Example:

+    @code

+    

+    #define COREI2C_BASE_ADDR  0xC0000000u

+    #define COREINTERRUPT_BASE_ADDR  0xCC000000u

+    #define COREI2C_SER_ADDR   0x10u

+    #define I2C_IRQ_NB           2u

+    

+    i2c_instance_t g_i2c_inst;

+

+    void core_i2c_isr( void )

+    {

+       I2C_isr( &g_i2c_inst );

+    }

+    

+   void main( void )

+    {

+        CIC_init( COREINTERRUPT_BASE_ADDR );

+        NVIC_init();

+        CIC_set_irq_handler( I2C_IRQ_NB, core_i2c_isr );

+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, COREI2C_SER_ADDR,

+                  I2C_PCLK_DIV_256 );

+        NVIC_enable_interrupt( NVIC_IRQ_0 );

+    }

+    @endcode

+ */

+void I2C_isr

+(

+    i2c_instance_t * this_i2c

+);

+

+/*******************************************************************************

+ *******************************************************************************

+ * 

+ *                           Master specific functions

+ * 

+ * The following functions are only used within an I2C master's implementation.

+ */

+ 

+/*-------------------------------------------------------------------------*//**

+  I2C master write function.

+  ------------------------------------------------------------------------------

+  This function initiates an I2C master write transaction. This function returns

+  immediately after initiating the transaction. The content of the write buffer

+  passed as parameter should not be modified until the write transaction

+  completes. It also means that the memory allocated for the write buffer should

+  not be freed or should not go out of scope before the write completes. You can

+  check for the write transaction completion using the I2C_status() function.

+  ------------------------------------------------------------------------------

+  @param this_i2c:

+    The this_i2c parameter is a pointer to the i2c_instance_t data structure

+    holding all data related to a specific CoreI2C channel. For example, if only

+    one channel is initialized, this data structure holds the information of 

+    channel 0 of the instantiated CoreI2C hardware.

+

+  @param serial_addr:

+    This parameter specifies the serial address of the target I2C device.

+  

+  @param write_buffer:

+    This parameter is a pointer to a buffer holding the data to be written to

+    the target I2C device.

+    Care must be taken not to release the memory used by this buffer before the

+    write transaction completes. For example, it is not appropriate to return

+    from a function allocating this buffer as an auto array variable before the

+    write transaction completes as this would result in the buffer's memory 

+    being de-allocated from the stack when the function returns. This memory

+    could then be subsequently reused and modified causing unexpected data to 

+    be written to the target I2C device.

+  

+  @param write_size:

+    Number of bytes held in the write_buffer to be written to the target I2C

+    device.

+ 

+  @param options:

+    The options parameter is used to indicate if the I2C bus should be released

+    on completion of the write transaction. Using the I2C_RELEASE_BUS

+    constant for the options parameter causes a STOP bit to be generated at the

+    end of the write transaction causing the bus to be released for other I2C

+    devices to use. Using the I2C_HOLD_BUS constant as options parameter

+    prevents a STOP bit from being generated at the end of the write

+    transaction, preventing other I2C devices from initiating a bus transaction.

+  

+  @return none.  

+  

+  Example:

+  @code

+    #define COREI2C_BASE_ADDR  0xC0000000u

+    #define COREI2C_DUMMY_ADDR   0x10u

+    #define DATA_LENGTH           16u

+

+    i2c_instance_t g_i2c_inst;

+

+    uint8_t  tx_buffer[DATA_LENGTH];

+    uint8_t  write_length = DATA_LENGTH;     

+

+    void main( void )

+    {

+        uint8_t  target_slave_addr = 0x12;

+        i2c_status_t status;

+        

+        // Initialize base CoreI2C instance

+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, COREI2C_DUMMY_ADDR,

+                  I2C_PCLK_DIV_256 );

+        

+        // Write data to Channel 0 of CoreI2C instance.

+        I2C_write( &g_i2c_inst, target_slave_addr, tx_buffer, write_length,

+                   I2C_RELEASE_BUS );

+                   

+        // Wait for completion and record the outcome

+        status = I2C_wait_complete( &g_i2c_inst, I2C_NO_TIMEOUT );

+    }

+  @endcode

+ */

+void I2C_write

+(

+    i2c_instance_t * this_i2c,

+    uint8_t serial_addr,

+    const uint8_t * write_buffer,

+    uint16_t write_size,

+    uint8_t options

+);

+

+/*-------------------------------------------------------------------------*//**

+  I2C master read.

+  ------------------------------------------------------------------------------

+  This function initiates an I2C master read transaction. This function returns

+  immediately after initiating the transaction.

+  The contents of the read buffer passed as parameter should not be modified

+  until the read transaction completes. It also means that the memory allocated

+  for the read buffer should not be freed or should not go out of scope before

+  the read completes. You can check for the read transaction completion using 

+  the I2C_status() function.

+  ------------------------------------------------------------------------------

+  @param this_i2c:

+    The this_i2c parameter is a pointer to the i2c_instance_t data structure

+    holding all data related to a specific CoreI2C channel. For example, if only

+    one channel is initialized, this data structure holds the information of 

+    channel 0 of the instantiated CoreI2C hardware.

+  

+  @param serial_addr:

+    This parameter specifies the serial address of the target I2C device.

+  

+  @param read_buffer

+    This is a pointer to a buffer where the data received from the target device

+    will be stored.

+    Care must be taken not to release the memory used by this buffer before the

+    read transaction completes. For example, it is not appropriate to return

+    from a function allocating this buffer as an auto array variable before the

+    read transaction completes as this would result in the buffer's memory being

+    de-allocated from the stack when the function returns. This memory could

+    then be subsequently reallocated resulting in the read transaction

+    corrupting the newly allocated memory. 

+

+  @param read_size:

+    This parameter specifies the number of bytes to read from the target device.

+    This size must not exceed the size of the read_buffer buffer.

+ 

+  @param options:

+    The options parameter is used to indicate if the I2C bus should be released

+    on completion of the read transaction. Using the I2C_RELEASE_BUS

+    constant for the options parameter causes a STOP bit to be generated at the

+    end of the read transaction causing the bus to be released for other I2C

+    devices to use. Using the I2C_HOLD_BUS constant as options parameter

+    prevents a STOP bit from being generated at the end of the read transaction,

+    preventing other I2C devices from initiating a bus transaction.

+    

+  @return none.  

+  

+  Example:

+  @code

+    #define COREI2C_BASE_ADDR  0xC0000000u

+    #define COREI2C_DUMMY_ADDR   0x10u

+    #define DATA_LENGTH           16u

+

+    i2c_instance_t g_i2c_inst;

+

+    uint8_t  rx_buffer[DATA_LENGTH];

+    uint8_t  read_length = DATA_LENGTH;     

+

+    void main( void )

+    {

+        uint8_t  target_slave_addr = 0x12;

+        i2c_status_t status;

+        

+        // Initialize base CoreI2C instance

+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, COREI2C_DUMMY_ADDR,

+                  I2C_PCLK_DIV_256 );

+        

+        // Read data from target slave Channel 0 of CoreI2C instance.

+        I2C_read( &g_i2c_inst, target_slave_addr, rx_buffer, read_length,

+                  I2C_RELEASE_BUS );

+        

+        status = I2C_wait_complete( &g_i2c_inst, I2C_NO_TIMEOUT );

+    }

+  @endcode

+ */

+void I2C_read

+(

+    i2c_instance_t * this_i2c,

+    uint8_t serial_addr,

+    uint8_t * read_buffer,

+    uint16_t read_size,

+    uint8_t options

+);

+

+/*-------------------------------------------------------------------------*//**

+  I2C master write-read

+  ------------------------------------------------------------------------------

+  This function initiates an I2C write-read transaction where data is first

+  written to the target device before issuing a restart condition and changing

+  the direction of the I2C transaction in order to read from the target device.

+  

+  The same warnings about buffer allocation in I2C_write() and I2C_read() 

+  apply to this function.

+  ------------------------------------------------------------------------------

+  @param this_i2c:

+    The this_i2c parameter is a pointer to the i2c_instance_t data structure

+    holding all data related to a specific CoreI2C channel. For example, if only

+    one channel is initialized, this data structure holds the information of

+    channel 0 of the instantiated CoreI2C hardware.

+  

+  @param serial_addr:

+    This parameter specifies the serial address of the target I2C device.

+  

+  @param addr_offset:

+    This parameter is a pointer to the buffer containing the data that will be

+    sent to the slave during the write phase of the write-read transaction. This

+    data is typically used to specify an address offset specifying to the I2C

+    slave device what data it must return during the read phase of the

+    write-read transaction.

+  

+  @param offset_size:

+    This parameter specifies the number of offset bytes to be written during the

+    write phase of the write-read transaction. This is typically the size of the

+    buffer pointed to by the addr_offset parameter.

+  

+  @param read_buffer:

+    This parameter is a pointer to the buffer where the data read from the I2C

+    slave will be stored.

+  

+  @param read_size:

+    This parameter specifies the number of bytes to read from the target I2C

+    slave device. This size must not exceed the size of the buffer pointed to by

+    the read_buffer parameter.

+ 

+  @param options:

+    The options parameter is used to indicate if the I2C bus should be released

+    on completion of the write-read transaction. Using the I2C_RELEASE_BUS

+    constant for the options parameter causes a STOP bit to be generated at the

+    end of the write-read transaction causing the bus to be released for other

+    I2C devices to use. Using the I2C_HOLD_BUS constant as options parameter

+    prevents a STOP bit from being generated at the end of the write-read

+    transaction, preventing other I2C devices from initiating a bus transaction.

+        

+  @return none.  

+  

+  Example:

+  @code

+    #define COREI2C_BASE_ADDR    0xC0000000u

+    #define COREI2C_DUMMY_ADDR   0x10u

+    #define TX_LENGTH            16u

+    #define RX_LENGTH            8u

+

+    i2c_instance_t g_i2c_inst;

+    uint8_t  rx_buffer[RX_LENGTH];

+    uint8_t  read_length = RX_LENGTH;     

+    uint8_t  tx_buffer[TX_LENGTH];

+    uint8_t  write_length = TX_LENGTH;  

+    

+    void main( void )

+    {

+        uint8_t  target_slave_addr = 0x12;

+        i2c_status_t status;

+        // Initialize base CoreI2C instance

+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, COREI2C_DUMMY_ADDR,

+                  I2C_PCLK_DIV_256 );

+                  

+        I2C_write_read( &g_i2c_inst, target_slave_addr, tx_buffer, write_length,

+                        rx_buffer, read_length, I2C_RELEASE_BUS );

+                        

+        status = I2C_wait_complete( &g_i2c_inst, I2C_NO_TIMEOUT );

+    }

+  @endcode

+ */

+void I2C_write_read

+(

+    i2c_instance_t * this_i2c,

+    uint8_t serial_addr,

+    const uint8_t * addr_offset,

+    uint16_t offset_size,

+    uint8_t * read_buffer,

+    uint16_t read_size,

+    uint8_t options

+);

+    

+/*-------------------------------------------------------------------------*//**

+  I2C status

+  ------------------------------------------------------------------------------

+  This function indicates the current state of a CoreI2C channel.

+  ------------------------------------------------------------------------------

+  @param this_i2c:

+    The this_i2c parameter is a pointer to the i2c_instance_t data structure

+    holding all data related to a specific CoreI2C channel. For example, if only

+    one channel is initialized, this data structure holds the information of 

+    channel 0 of the instantiated CoreI2C hardware.

+  ------------------------------------------------------------------------------

+  @return

+    The return value indicates the current state of a CoreI2C channel or the

+    outcome of the previous transaction if no transaction is in progress. 

+    Possible return values are:

+      I2C_SUCCESS

+        The last I2C transaction has completed successfully.  

+      I2C_IN_PROGRESS

+        There is an I2C transaction in progress.

+      I2C_FAILED

+        The last I2C transaction failed.

+      I2C_TIMED_OUT

+        The request has failed to complete in the allotted time.      

+  

+  Example:

+  @code

+    i2c_instance_t g_i2c_inst;

+    

+    while( I2C_IN_PROGRESS == I2C_get_status( &g_i2c_inst ) )

+    {

+        // Do something useful while waiting for I2C operation to complete

+        our_i2c_busy_task();

+    }

+    

+    if( I2C_SUCCESS != I2C_get_status( &g_i2c_inst ) )

+    {

+        // Something went wrong... 

+        our_i2c_error_recovery( &g_i2c_inst );

+    }

+  @endcode

+ */

+i2c_status_t I2C_get_status

+(

+    i2c_instance_t * this_i2c

+);

+

+/*-------------------------------------------------------------------------*//**

+  Wait for I2C transaction completion.

+  ------------------------------------------------------------------------------

+  This function waits for the current I2C transaction to complete. The return

+  value indicates whether the last I2C transaction was successful or not.

+  ------------------------------------------------------------------------------

+  @param this_i2c:

+    The this_i2c parameter is a pointer to the i2c_instance_t data structure

+    holding all data related to a specific CoreI2C channel. For example, if only

+    one channel is initialized, this data structure holds the information of

+    channel 0 of the instantiated CoreI2C hardware.

+  @param timeout_ms:

+    The timeout_ms parameter specified the delay within which the current I2C 

+    transaction is expected to complete. The time out delay is given in 

+    milliseconds. I2C_wait_complete() will return I2C_TIMED_OUT if the current

+    transaction has not completed after the time out delay has expired. This

+    parameter can be set to I2C_NO_TIMEOUT to indicate that I2C_wait_complete()

+    must not time out.

+  ------------------------------------------------------------------------------

+  @return

+    The return value indicates the outcome of the last I2C transaction. It can

+    be one of the following: 

+      I2C_SUCCESS

+        The last I2C transaction has completed successfully.

+      I2C_FAILED

+        The last I2C transaction failed.

+      I2C_TIMED_OUT

+        The last transaction failed to complete within the time out delay given

+        as second parameter.

+

+  Example:

+  @code

+    #define COREI2C_BASE_ADDR  0xC0000000u

+    #define COREI2C_DUMMY_ADDR   0x10u

+    #define DATA_LENGTH           16u

+

+    i2c_instance_t g_i2c_inst;

+

+    uint8_t  rx_buffer[DATA_LENGTH];

+    uint8_t  read_length = DATA_LENGTH;     

+

+    void main( void )

+    {

+        uint8_t  target_slave_addr = 0x12;

+        i2c_status_t status;

+        

+        // Initialize base CoreI2C instance

+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, COREI2C_DUMMY_ADDR,

+                  I2C_PCLK_DIV_256 );

+        

+        // Read data from Channel 0 of CoreI2C instance.

+        I2C_read( &g_i2c_inst, target_slave_addr, rx_buffer, read_length,

+                  I2C_RELEASE_BUS );

+        

+        // Wait for completion and record the outcome

+        status = I2C_wait_complete( &g_i2c_inst, I2C_NO_TIMEOUT );

+    }

+  @endcode

+ */

+i2c_status_t I2C_wait_complete

+(

+    i2c_instance_t * this_i2c,

+    uint32_t timeout_ms

+);

+

+/*-------------------------------------------------------------------------*//**

+  Time out delay expiration.

+  ------------------------------------------------------------------------------

+  This function is used to control the expiration of the time out delay

+  specified as a parameter to the I2C_wait_complete() function. It must be

+  called from the interrupt service routine of a periodic interrupt source such

+  as the Cortex-M3 SysTick timer interrupt. It takes the period of the interrupt

+  source as its ms_since_last_tick parameter and uses it as the time base for

+  the I2C_wait_complete() functionÂ’s time out delay.

+  

+  Note: This function does not need to be called if the I2C_wait_complete()

+        function is called with a timeout_ms value of I2C_NO_TIMEOUT.

+  Note: If this function is not called then the I2C_wait_complete() function

+        will behave as if its timeout_ms was specified as I2C_NO_TIMEOUT and it

+        will not time out.

+  Note: If this function is being called from an interrupt handler (e.g SysTick)

+        it is important that the calling interrupt have a lower priority than

+        the CoreI2C interrupt(s) to ensure any updates to shared data are

+        protected.

+  

+  ------------------------------------------------------------------------------

+  @param this_i2c:

+    The this_i2c parameter is a pointer to the i2c_instance_t data structure

+    holding all data related to a specific CoreI2C channel. For example, if only

+    one channel is initialized, this data structure holds the information of 

+    channel 0 of the instantiated CoreI2C hardware.

+  @param ms_since_last_tick:

+    The ms_since_last_tick parameter specifies the number of milliseconds that

+    elapsed since the last call to I2C_system_tick(). This parameter would

+    typically be a constant specifying the interrupt rate of a timer used to

+    generate system ticks.

+  ------------------------------------------------------------------------------

+  @return

+    none.

+

+  Example:

+    The example below shows an example of how the I2C_system_tick() function

+    would be called in a Cortex-M3 based system. I2C_system_tick() is called for

+    each I2C channel from the Cortex-M3 SysTick timer interrupt service routine.

+    The SysTick is configured to generate an interrupt every 10 milliseconds in

+    the example below.

+  @code

+    #define SYSTICK_INTERVAL_MS 10

+   

+    void SysTick_Handler(void)

+    {

+        I2C_system_tick(&g_core_i2c0, SYSTICK_INTERVAL_MS);

+        I2C_system_tick(&g_core_i2c2, SYSTICK_INTERVAL_MS);

+    }

+  @endcode

+ */

+void I2C_system_tick

+(

+    i2c_instance_t * this_i2c,

+    uint32_t ms_since_last_tick

+);

+

+/*******************************************************************************

+ *******************************************************************************

+ * 

+ *                           Slave specific functions

+ * 

+ * The following functions are only used within the implementation of an I2C

+ * slave device.

+ */

+

+/*-------------------------------------------------------------------------*//**

+  I2C slave transmit buffer configuration.

+  ------------------------------------------------------------------------------

+  This function specifies the memory buffer holding the data that will be sent

+  to the I2C master when this CoreI2C channel is the target of an I2C read or

+  write-read transaction.

+  ------------------------------------------------------------------------------

+  @param this_i2c:

+    The this_i2c parameter is a pointer to the i2c_instance_t data structure

+    holding all data related to a specific CoreI2C channel. For example, if only

+    one channel is initialized, this data structure holds the information of 

+    channel 0 of the instantiated CoreI2C hardware.

+  

+  @param tx_buffer:

+    This parameter is a pointer to the memory buffer holding the data to be

+    returned to the I2C master when this CoreI2C channel is the target of an

+    I2C read or write-read transaction.

+  

+  @param tx_size:

+    Size of the transmit buffer pointed to by the tx_buffer parameter.

+

+  @return none.  

+      

+  Example:

+  @code

+    #define COREI2C_BASE_ADDR    0xC0000000u

+    #define SLAVE_SER_ADDR       0x10u

+    #define SLAVE_TX_BUFFER_SIZE 10u

+

+    i2c_instance_t g_i2c_inst;

+

+    uint8_t g_slave_tx_buffer[SLAVE_TX_BUFFER_SIZE] = { 1, 2, 3, 4, 5,

+                                                        6, 7, 8, 9, 10 };

+

+    void main( void )

+    {

+        // Initialize the CoreI2C driver with its base address, I2C serial

+        // address and serial clock divider.

+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, SLAVE_SER_ADDR,

+                  I2C_PCLK_DIV_256 );

+       

+        // Specify the transmit buffer containing the data that will be

+        // returned to the master during read and write-read transactions.

+        I2C_set_slave_tx_buffer( &g_i2c_inst, g_slave_tx_buffer, 

+                                 sizeof(g_slave_tx_buffer) );

+    }

+  @endcode

+ */

+void I2C_set_slave_tx_buffer

+(

+    i2c_instance_t * this_i2c,

+    const uint8_t * tx_buffer,

+    uint16_t tx_size

+);

+

+/*-------------------------------------------------------------------------*//**

+  I2C slave receive buffer configuration.

+  ------------------------------------------------------------------------------

+  This function specifies the memory buffer that will be used by the CoreI2C

+  channel to receive data when it is a slave. This buffer is the memory where

+  data will be stored when the CoreI2C channel is the target of an I2C master

+  write transaction (i.e. when it is the slave).

+  ------------------------------------------------------------------------------

+  @param this_i2c:

+    The this_i2c parameter is a pointer to the i2c_instance_t data structure

+    holding all data related to a specific CoreI2C channel. For example, if only

+    one channel is initialized, this data structure holds the information of 

+    channel 0 of the instantiated CoreI2C hardware.

+  

+  @param rx_buffer:

+    This parameter is a pointer to the memory buffer allocated by the caller

+    software to be used as a slave receive buffer.

+  

+  @param rx_size:

+    Size of the slave receive buffer. This is the amount of memory that is

+    allocated to the buffer pointed to by rx_buffer.

+    Note:   This buffer size indirectly specifies the maximum I2C write

+            transaction length this CoreI2C channel can be the target of. This

+            is because this CoreI2C channel responds to further received

+            bytes with a non-acknowledge bit (NACK) as soon as its receive

+            buffer is full. This causes the write transaction to fail.

+            

+  @return none.  

+      

+  Example:

+  @code

+    #define COREI2C_BASE_ADDR    0xC0000000u

+    #define SLAVE_SER_ADDR       0x10u

+    #define SLAVE_RX_BUFFER_SIZE 10u

+

+    i2c_instance_t g_i2c_inst;

+

+    uint8_t g_slave_rx_buffer[SLAVE_RX_BUFFER_SIZE];

+

+    void main( void )

+    {

+        // Initialize the CoreI2C driver with its base address, I2C serial

+        // address and serial clock divider.

+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, SLAVE_SER_ADDR,

+                  I2C_PCLK_DIV_256 );

+       

+        // Specify the buffer used to store the data written by the I2C master.

+        I2C_set_slave_rx_buffer( &g_i2c_inst, g_slave_rx_buffer, 

+                                 sizeof(g_slave_rx_buffer) );

+    }

+  @endcode

+ */

+void I2C_set_slave_rx_buffer

+(

+    i2c_instance_t * this_i2c,

+    uint8_t * rx_buffer,

+    uint16_t rx_size

+);

+

+/*-------------------------------------------------------------------------*//**

+  I2C slave memory offset length configuration.

+  ------------------------------------------------------------------------------

+  This function is used as part of the configuration of a CoreI2C channel for

+  operation as a slave supporting write-read transactions. It specifies the

+  number of bytes expected as part of the write phase of a write-read

+  transaction. The bytes received during the write phase of a write-read

+  transaction will be interpreted as an offset into the slave's transmit buffer.

+  This allows random access into the I2C slave transmit buffer from a remote

+  I2C master.

+  ------------------------------------------------------------------------------

+  @param this_i2c:

+    The this_i2c parameter is a pointer to the i2c_instance_t data structure

+    holding all data related to a specific CoreI2C channel. For example, if only

+    one channel is initialized, this data structure holds the information of 

+    channel 0 of the instantiated CoreI2C hardware.

+  

+  @param offset_length:

+    The offset_length parameter configures the number of bytes to be interpreted

+    by the CoreI2C slave as a memory offset value during the write phase of

+    write-read transactions. The maximum value for the offset_length parameter

+    is two. The value of offset_length has the following effect on the 

+    interpretation of the received data.

+    

+      If offset_length is 0, the offset into the transmit buffer is fixed at 0.

+      

+      If offset_length is 1, a single byte of received data is interpreted as an

+      unsigned 8 bit offset value in the range 0 to 255.

+      

+      If offset_length is 2, 2 bytes of received data are interpreted as an

+      unsigned 16 bit offset value in the range 0 to 65535. The first byte

+      received in this case provides the high order bits of the offset and

+      the second byte provides the low order bits.

+      

+    If the number of bytes received does not match the non 0 value of

+    offset_length the transmit buffer offset is set to 0.

+            

+  @return none.  

+      

+  Example:

+  @code

+    #define COREI2C_BASE_ADDR    0xC0000000u

+    #define SLAVE_SER_ADDR       0x10u

+    #define SLAVE_TX_BUFFER_SIZE 10u

+

+    i2c_instance_t g_i2c_inst;

+

+    uint8_t g_slave_tx_buffer[SLAVE_TX_BUFFER_SIZE] = { 1, 2, 3, 4, 5,

+                                                        6, 7, 8, 9, 10 };

+

+    void main( void )

+    {

+        // Initialize the CoreI2C driver with its base address, I2C serial

+        // address and serial clock divider.

+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, SLAVE_SER_ADDR,

+                  I2C_PCLK_DIV_256 );

+        I2C_set_slave_tx_buffer( &g_i2c_inst, g_slave_tx_buffer, 

+                                 sizeof(g_slave_tx_buffer) );

+        I2C_set_slave_mem_offset_length( &g_i2c_inst, 1 );

+    }

+  @endcode        

+ */

+void I2C_set_slave_mem_offset_length

+(

+    i2c_instance_t * this_i2c,

+    uint8_t offset_length

+);

+

+/*-------------------------------------------------------------------------*//**

+  I2C write handler registration. 

+  ------------------------------------------------------------------------------

+  Register the function that is called to process the data written to this

+  CoreI2C channel when it is the slave in an I2C write transaction.

+  Note: If a write handler is registered, it is called on completion of the

+        write phase of a write-read transaction and responsible for processing

+        the received data in the slave receive buffer and populating the slave

+        transmit buffer with the data that will be transmitted to the I2C master

+        as part of the read phase of the write-read transaction. If a write

+        handler is not registered, the write data of a write read transaction is

+        interpreted as an offset into the slaveÂ’s transmit buffer and handled by

+        the driver.

+  ------------------------------------------------------------------------------

+  @param this_i2c:

+    The this_i2c parameter is a pointer to the i2c_instance_t data structure

+    holding all data related to a specific CoreI2C channel. For example, if only

+    one channel is initialized, this data structure holds the information of 

+    channel 0 of the instantiated CoreI2C hardware.

+  

+  @param handler:

+    Pointer to the function that will process the I2C write request.

+            

+  @return none.  

+      

+  Example:

+  @code

+    #define COREI2C_BASE_ADDR    0xC0000000u

+    #define SLAVE_SER_ADDR       0x10u

+    #define SLAVE_TX_BUFFER_SIZE 10u

+

+    i2c_instance_t g_i2c_inst;

+

+    uint8_t g_slave_tx_buffer[SLAVE_TX_BUFFER_SIZE] = { 1, 2, 3, 4, 5,

+                                                       6, 7, 8, 9, 10 };

+

+    // local function prototype

+    void slave_write_handler

+    (

+        i2c_instance_t * this_i2c,

+        uint8_t * p_rx_data,

+        uint16_t rx_size

+    );

+

+    void main( void )

+    {

+        // Initialize the CoreI2C driver with its base address, I2C serial

+        // address and serial clock divider.

+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, SLAVE_SER_ADDR, 

+                  I2C_PCLK_DIV_256 );

+        I2C_set_slave_tx_buffer( &g_i2c_inst, g_slave_tx_buffer, 

+                                 sizeof(g_slave_tx_buffer) );

+        I2C_set_slave_mem_offset_length( &g_i2c_inst, 1 );

+        I2C_register_write_handler( &g_i2c_inst, slave_write_handler );

+    }

+  @endcode    

+*/

+void I2C_register_write_handler

+(

+    i2c_instance_t * this_i2c,

+    i2c_slave_wr_handler_t handler

+);

+

+/*-------------------------------------------------------------------------*//**

+  I2C slave enable.

+  ------------------------------------------------------------------------------

+  This function enables slave mode operation for a CoreI2C channel. It enables 

+  the CoreI2C slave to receive data when it is the target of an I2C read, write

+  or write-read transaction.

+  ------------------------------------------------------------------------------

+  @param this_i2c:

+    The this_i2c parameter is a pointer to the i2c_instance_t data structure

+    holding all data related to a specific CoreI2C channel. For example, if only

+    one channel is initialized, this data structure holds the information of 

+    channel 0 of the instantiated CoreI2C hardware.

+

+  @return none.

+

+  Example:

+  @code

+    // Enable I2C slave

+    I2C_enable_slave( &g_i2c_inst );

+  @endcode

+ */

+void I2C_enable_slave

+(

+    i2c_instance_t * this_i2c

+);

+

+/*-------------------------------------------------------------------------*//**

+  I2C slave disable.

+  ------------------------------------------------------------------------------

+  This function disables slave mode operation for a CoreI2C channel. It stops

+  the CoreI2C slave acknowledging I2C read, write or write-read transactions

+  targeted at it.

+  ------------------------------------------------------------------------------

+  @param this_i2c:

+    The this_i2c parameter is a pointer to the i2c_instance_t data structure

+    holding all data related to a specific CoreI2C channel. For example, if only

+    one channel is initialized, this data structure holds the information of 

+    channel 0 of the instantiated CoreI2C hardware.

+

+  @return none.

+

+  Example:

+  @code

+   // Disable I2C slave

+   I2C_disable_slave( &g_i2c_inst );

+  @endcode

+ */

+void I2C_disable_slave

+(

+    i2c_instance_t * this_i2c

+);

+/*-------------------------------------------------------------------------*//**

+  Set I2C slave second address.

+  ------------------------------------------------------------------------------

+  The function I2C_set_slave_second_addr() sets the secondary slave address for

+  a CoreI2C slave device. This is an additional slave address which might be

+  required in certain applications, for example to enable fail-safe operation in

+  a system. As the CoreI2C device supports 7-bit addressing, the highest value

+  which can be assigned to second slave address is 127 (0x7F).

+  Note: This function does not support CoreI2C hardware configured with a fixed 

+      second slave address.  The current implementation of the ADDR1[0] register

+      bit makes it difficult for the driver to support both programmable and

+      fixed second slave address, so we choose to support programmable only.

+  ------------------------------------------------------------------------------

+  @param this_i2c:

+    The this_i2c parameter is a pointer to the i2c_instance_t data structure

+    holding all data related to a specific CoreI2C channel. For example, if only

+    one channel is initialized, this data structure holds the information of 

+    channel 0 of the instantiated CoreI2C hardware.

+

+  @param second_slave_addr:

+    The second_slave_addr parameter is the secondary slave address of the I2C

+    device.

+

+  @return

+    none.

+

+  Example:

+  @code

+    #define COREI2C_BASE_ADDR  0xC0000000u

+    #define SLAVE_SER_ADDR     0x10u

+    #define SECOND_SLAVE_ADDR  0x20u

+

+    i2c_instance_t g_i2c_inst;

+    void main( void )

+    {

+        // Initialize the CoreI2C driver with its base address, primary I2C

+        // serial address and serial clock divider.

+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, SLAVE_SER_ADDR, 

+                  I2C_PCLK_DIV_256 );

+        I2C_set_slave_second_addr( &g_i2c_inst, SECOND_SLAVE_ADDR );

+    }

+  @endcode

+ */

+void I2C_set_slave_second_addr

+(

+    i2c_instance_t * this_i2c,

+    uint8_t second_slave_addr

+);

+

+/*-------------------------------------------------------------------------*//**

+  Disable second slave address.

+  ------------------------------------------------------------------------------

+  The function I2C_disable_slave_second_addr() disables the secondary slave

+  address of the CoreI2C slave device. 

+  Note: This version of the driver only supports CoreI2C hardware configured

+        with a programmable second slave address.

+  ------------------------------------------------------------------------------

+  @param this_i2c:

+    The this_i2c parameter is a pointer to the i2c_instance_t data structure

+    holding all data related to a specific CoreI2C channel. For example, if only

+    one channel is initialized, this data structure holds the information of 

+    channel 0 of the instantiated CoreI2C hardware.

+

+  @return

+    none.

+

+  Example:

+  @code

+    i2c_instance_t g_i2c_inst;

+    I2C_disable_slave_second_addr( &g_i2c_inst);

+  @endcode

+ */

+void I2C_disable_slave_second_addr

+(

+    i2c_instance_t * this_i2c

+);

+

+/*-------------------------------------------------------------------------*//**

+  The I2C_set_gca() function is used to set the general call acknowledgement bit

+  of a CoreI2C slave device. This allows all channels of the CoreI2C slave

+  device respond to a general call or broadcast message from an I2C master.

+  ------------------------------------------------------------------------------

+  @param this_i2c:

+    The this_i2c parameter is a pointer to the i2c_instance_t data structure

+    holding all data related to a specific CoreI2C channel. For example, if only

+    one channel is initialized, this data structure holds the information of 

+    channel 0 of the instantiated CoreI2C hardware.

+

+  @return

+    none.

+

+  Example:

+  @code

+    i2c_instance_t g_i2c_inst;

+

+    // Enable recognition of the General Call Address

+    I2C_set_gca( &g_i2c_inst ); 

+  @endcode

+ */

+void I2C_set_gca

+(

+    i2c_instance_t * this_i2c

+);

+

+/*-------------------------------------------------------------------------*//**

+  The I2C_clear_gca() function is used to clear the general call acknowledgement

+  bit of a CoreI2C slave device. This will stop all channels of the I2C slave

+  device responding to any general call or broadcast message from the master.

+  ------------------------------------------------------------------------------

+  @param this_i2c:

+    The this_i2c parameter is a pointer to the i2c_instance_t data structure

+    holding all data related to a specific CoreI2C channel. For example, if only

+    one channel is initialized, this data structure holds the information of 

+    channel 0 of the instantiated CoreI2C hardware.

+

+  @return

+    none.

+

+  Example:

+  @code

+    i2c_instance_t g_i2c_inst;

+

+    // Disable recognition of the General Call Address

+    I2C_clear_gca( &g_i2c_inst );

+  @endcode

+ */

+

+void I2C_clear_gca

+(

+    i2c_instance_t * this_i2c

+);

+

+/*------------------------------------------------------------------------------

+                      I2C SMBUS specific APIs

+ ----------------------------------------------------------------------------*/

+

+/*-------------------------------------------------------------------------*//**

+  The I2C_smbus_init() function enables SMBus timeouts and status logic for a

+  CoreI2C channel.

+  Note: This and any of the other SMBus related functionality will only have an

+        effect if the CoreI2C was instantiated with the Generate SMBus Logic

+        option checked.

+  Note: If the CoreI2C was instantiated with the Generate IPMI Logic option

+        checked this function will enable the IPMI 3mS SCL low timeout but none

+        of the other SMBus functions will have any effect.

+  ------------------------------------------------------------------------------

+  @param this_i2c:

+    The this_i2c parameter is a pointer to the i2c_instance_t data structure

+    holding all data related to a specific CoreI2C channel. For example, if only

+    one channel is initialized, this data structure holds the information of 

+    channel 0 of the instantiated CoreI2C hardware.

+

+  @return

+    none.

+

+  Example:

+  @code

+   #define COREI2C_BASE_ADDR  0xC0000000u

+   #define SLAVE_SER_ADDR     0x10u

+

+   i2c_instance_t g_i2c_inst;

+

+   void system_init( void )

+   {

+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, SLAVE_SER_ADDR,

+                  I2C_PCLK_DIV_256 );

+        

+        // Initialize SMBus feature

+        I2C_smbus_init( &g_i2c_inst);

+   }

+  @endcode    

+ */

+void I2C_smbus_init

+(

+    i2c_instance_t * this_i2c

+);

+

+/*-------------------------------------------------------------------------*//**

+  The I2C_enable_smbus_irq() function is used to enable the CoreI2C channelÂ’s 

+  SMBSUS and SMBALERT SMBus interrupts.

+  ------------------------------------------------------------------------------

+  @param this_i2c:

+    The this_i2c parameter is a pointer to the i2c_instance_t data structure

+    holding all data related to a specific CoreI2C channel. For example, if only

+    one channel is initialized, this data structure holds the information of 

+    channel 0 of the instantiated CoreI2C hardware.

+

+  @param irq_type

+    The irq_type specify the SMBUS interrupt(s) which will be enabled.

+    The two possible interrupts are:

+      I2C_SMBALERT_IRQ

+      I2C_SMBSUS_IRQ

+    To enable both ints in one call, use I2C_SMBALERT_IRQ | I2C_SMBSUS_IRQ.

+    

+  @return

+    none

+  

+  Example:

+  @code

+    #define COREI2C_BASE_ADDR  0xC0000000u

+    #define SLAVE_SER_ADDR     0x10u

+

+    i2c_instance_t g_i2c_inst;

+

+    void main( void )

+    {

+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, SLAVE_SER_ADDR,

+                  I2C_PCLK_DIV_256 );

+        

+        // Initialize SMBus feature

+        I2C_smbus_init( &g_i2c_inst );

+        

+        // Enable both I2C_SMBALERT_IRQ & I2C_SMBSUS_IRQ interrupts

+        I2C_enable_smbus_irq( &g_i2c_inst,

+                              (uint8_t)(I2C_SMBALERT_IRQ | I2C_SMBSUS_IRQ) );

+   }

+   @endcode

+ */

+void I2C_enable_smbus_irq

+(

+    i2c_instance_t * this_i2c,

+    uint8_t  irq_type

+);

+

+/*-------------------------------------------------------------------------*//**

+  The I2C_disable_smbus_irq() function is used to disable the CoreI2C channelÂ’s

+  SMBSUS and SMBALERT SMBus interrupts.

+  ------------------------------------------------------------------------------

+  @param this_i2c:

+    The this_i2c parameter is a pointer to the i2c_instance_t data structure

+    holding all data related to a specific CoreI2C channel. For example, if only

+    one channel is initialized, this data structure holds the information of 

+    channel 0 of the instantiated CoreI2C hardware.

+

+  @param irq_type

+    The irq_type specifies the SMBUS interrupt(s) which will be disabled.

+    The two possible interrupts are:

+      I2C_SMBALERT_IRQ

+      I2C_SMBSUS_IRQ

+    To disable both ints in one call, use I2C_SMBALERT_IRQ | I2C_SMBSUS_IRQ.

+

+  @return

+    none.

+      

+  Example:

+  @code

+    #define COREI2C_BASE_ADDR  0xC0000000u

+    #define SLAVE_SER_ADDR     0x10u

+

+    i2c_instance_t g_i2c_inst;

+

+    void main( void )

+    {

+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, SLAVE_SER_ADDR,

+                  I2C_PCLK_DIV_256 );

+        

+        // Initialize SMBus feature

+        I2C_smbus_init( &g_i2c_inst );

+        

+        // Enable both SMBALERT & SMBSUS interrupts

+        I2C_enable_smbus_irq( &g_i2c_inst,

+                              (uint8_t)(I2C_SMBALERT_IRQ | I2C_SMBSUS_IRQ));

+        

+        ...        

+

+        // Disable the SMBALERT interrupt

+        I2C_disable_smbus_irq( &g_i2c_inst, I2C_SMBALERT_IRQ );

+    }

+  @endcode

+ */

+void I2C_disable_smbus_irq

+(

+    i2c_instance_t * this_i2c,

+    uint8_t  irq_type

+);

+

+/*-------------------------------------------------------------------------*//**

+  The function I2C_suspend_smbus_slave() forces any SMBUS slave devices

+  connected to a CoreI2C channel into power down or suspend mode by asserting

+  the channel's SMBSUS signal. The CoreI2C channel is the SMBus master in this

+  case.

+  ------------------------------------------------------------------------------

+  @param this_i2c:

+    The this_i2c parameter is a pointer to the i2c_instance_t data structure

+    holding all data related to a specific CoreI2C channel. For example, if only

+    one channel is initialized, this data structure holds the information of 

+    channel 0 of the instantiated CoreI2C hardware.

+

+  @return

+    none.

+    

+  Example:

+  @code

+    #define COREI2C_BASE_ADDR  0xC0000000u

+    #define SLAVE_SER_ADDR     0x10u

+

+    i2c_instance_t g_i2c_inst;

+    

+    void main( void )

+    {

+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, SLAVE_SER_ADDR, 

+                  I2C_PCLK_DIV_256 );

+

+        // Initialize SMBus feature

+        I2C_smbus_init( &g_i2c_inst );

+

+        // suspend SMBus slaves

+        I2C_suspend_smbus_slave( &g_i2c_inst );

+

+        ...

+

+        // Re-enable SMBus slaves

+        I2C_resume_smbus_slave( &g_i2c_inst );

+    }

+  @endcode

+ */

+void I2C_suspend_smbus_slave

+(

+    i2c_instance_t * this_i2c

+);

+

+/*-------------------------------------------------------------------------*//**

+  The function I2C_resume_smbus_slave() de-asserts the CoreI2C channel's SMBSUS

+  signal to take any connected slave devices out of suspend mode. The CoreI2C

+  channel is the SMBus master in this case.

+  ------------------------------------------------------------------------------

+  @param this_i2c:

+    The this_i2c parameter is a pointer to the i2c_instance_t data structure

+    holding all data related to a specific CoreI2C channel. For example, if only

+    one channel is initialized, this data structure holds the information of 

+    channel 0 of the instantiated CoreI2C hardware.

+

+  @return

+    none.

+    

+  Example:

+  @code

+    #define COREI2C_BASE_ADDR  0xC0000000u

+    #define SLAVE_SER_ADDR     0x10u

+

+    i2c_instance_t g_i2c_inst;

+    

+    void main( void )

+    {

+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, SLAVE_SER_ADDR, 

+                  I2C_PCLK_DIV_256 );

+

+        // Initialize SMBus feature

+        I2C_smbus_init( &g_i2c_inst );

+

+        // suspend SMBus slaves

+        I2C_suspend_smbus_slave( &g_i2c_inst );

+

+        ...

+

+        // Re-enable SMBus slaves

+        I2C_resume_smbus_slave( &g_i2c_inst );

+    }

+  @endcode

+ */

+void I2C_resume_smbus_slave

+(

+    i2c_instance_t * this_i2c

+);

+

+/*-------------------------------------------------------------------------*//**

+  The I2C_reset_smbus() function resets the CoreI2C channel's SMBus connection

+  by forcing SCLK low for 35mS. The reset is automatically cleared after 35ms

+  have elapsed. The CoreI2C channel is the SMBus master in this case.

+  ------------------------------------------------------------------------------

+  @param this_i2c:

+    The this_i2c parameter is a pointer to the i2c_instance_t data structure

+    holding all data related to a specific CoreI2C channel. For example, if only

+    one channel is initialized, this data structure holds the information of 

+    channel 0 of the instantiated CoreI2C hardware.

+

+  @return

+    none.

+

+  Example:

+  @code

+    #define COREI2C_BASE_ADDR  0xC0000000u

+    #define SLAVE_SER_ADDR     0x10u

+

+    i2c_instance_t g_i2c_inst;

+    

+    void main( void )

+    {

+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, SLAVE_SER_ADDR, 

+                  I2C_PCLK_DIV_256 );

+

+        // Initialize SMBus feature

+        I2C_smbus_init( &g_i2c_inst );

+

+        // Make sure the SMBus channel is in a known state by resetting it

+        I2C_reset_smbus( &g_i2c_inst ); 

+    }

+  @endcode

+ */

+void I2C_reset_smbus

+(

+    i2c_instance_t * this_i2c

+);

+

+/*-------------------------------------------------------------------------*//**

+  The I2C_set_smbus_alert() function is used to force master communication with

+  an I2C slave device by asserting the CoreI2C channelÂ’s SMBALERT signal. The

+  CoreI2C channel is the SMBus slave in this case.

+  ------------------------------------------------------------------------------

+  @param this_i2c:

+    The this_i2c parameter is a pointer to the i2c_instance_t data structure

+    holding all data related to a specific CoreI2C channel. For example, if only

+    one channel is initialized, this data structure holds the information of 

+    channel 0 of the instantiated CoreI2C hardware.

+

+  @return

+    none.

+

+  Example:

+  @code

+    #define COREI2C_BASE_ADDR  0xC0000000u

+    #define SLAVE_SER_ADDR     0x10u

+

+    i2c_instance_t g_i2c_inst;

+    

+    void main( void )

+    {

+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, SLAVE_SER_ADDR, 

+                  I2C_PCLK_DIV_256 );

+

+        // Initialize SMBus feature

+        I2C_smbus_init( &g_i2c_inst );

+

+        // Get the SMBus masters attention

+        I2C_set_smbus_alert( &g_i2c_inst );

+

+        ...

+

+        // Once we are happy, drop the alert

+        I2C_clear_smbus_alert( &g_i2c_inst );

+    }

+  @endcode

+ */

+void I2C_set_smbus_alert

+(

+    i2c_instance_t * this_i2c

+);

+

+/*-------------------------------------------------------------------------*//**

+  The I2C_clear_smbus_alert() function is used de-assert the CoreI2C channelÂ’s 

+  SMBALERT signal once a slave device has had a response from the master. The

+  CoreI2C channel is the SMBus slave in this case.

+  ------------------------------------------------------------------------------

+  @param this_i2c:

+    The this_i2c parameter is a pointer to the i2c_instance_t data structure

+    holding all data related to a specific CoreI2C channel. For example, if only

+    one channel is initialized, this data structure holds the information of 

+    channel 0 of the instantiated CoreI2C hardware.

+

+  @return

+    none.

+    

+  Example:

+  @code

+    #define COREI2C_BASE_ADDR  0xC0000000u

+    #define SLAVE_SER_ADDR     0x10u

+

+    i2c_instance_t g_i2c_inst;

+    

+    void main( void )

+    {

+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, SLAVE_SER_ADDR, 

+                  I2C_PCLK_DIV_256 );

+

+        // Initialize SMBus feature

+        I2C_smbus_init( &g_i2c_inst );

+

+        // Get the SMBus masters attention

+        I2C_set_smbus_alert( &g_i2c_inst );

+

+        ...

+

+        // Once we are happy, drop the alert

+        I2C_clear_smbus_alert( &g_i2c_inst );

+    }

+  @endcode

+ */

+void I2C_clear_smbus_alert

+(

+    i2c_instance_t * this_i2c

+);

+

+/*-------------------------------------------------------------------------*//**

+  The I2C_get_irq_status function returns information on which interrupts are

+  currently pending in a CoreI2C channel.

+  The interrupts supported by CoreI2C are:

+    * SMBUSALERT

+    * SMBSUS

+    * INTR

+  The macros I2C_NO_IRQ, I2C_SMBALERT_IRQ, I2C_SMBSUS_IRQ and I2C_INTR_IRQ are

+  provided for use with this function.

+  ------------------------------------------------------------------------------

+  @param this_i2c:

+    The this_i2c parameter is a pointer to the i2c_instance_t data structure

+    holding all data related to a specific CoreI2C channel. For example, if only

+    one channel is initialized, this data structure holds the information of 

+    channel 0 of the instantiated CoreI2C hardware.

+

+  @return

+    This function returns the status of the CoreI2C channelÂ’s interrupts as a 

+    single byte bitmap where a bit is set to indicate a pending interrupt.

+    The following are the bit positions associated with each interrupt type:

+        Bit 0 - SMBUS_ALERT_IRQ

+        Bit 1 - SMBSUS_IRQ

+        Bit 2 - INTR_IRQ

+    It returns 0, if there are no pending interrupts.

+

+  Example

+  @code

+   #define COREI2C_BASE_ADDR  0xC0000000u

+   #define SLAVE_SER_ADDR     0x10u

+

+   i2c_instance_t g_i2c_inst;

+   

+   void main( void )

+   {

+        uint8_t irq_to_enable = I2C_SMBALERT_IRQ | I2C_SMBSUS_IRQ;

+        uint8_t pending_irq = 0u;

+        

+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, SLAVE_SER_ADDR,

+                  I2C_PCLK_DIV_256 );

+

+        // Initialize SMBus feature

+        I2C_smbus_init( &g_i2c_inst );

+

+        // Enable both I2C_SMBALERT_IRQ & I2C_SMBSUS_IRQ irq

+        I2C_enable_smbus_irq( &g_i2c_inst, irq_to_enable );

+

+        // Get I2C IRQ type

+        pending_irq = I2C_get_irq_status( &g_i2c_inst );

+

+        // Let's assume, in system, INTR and SMBALERT IRQ is pending.

+        // So pending_irq will return status of both the IRQs

+

+        if( pending_irq & I2C_SMBALERT_IRQ )

+        {

+           // if true, it means SMBALERT_IRQ is there in pending IRQ list

+        }

+        if( pending_irq & I2C_INTR_IRQ )

+        {

+           // if true, it means I2C_INTR_IRQ is there in pending IRQ list

+        }

+   }

+  @endcode

+ */

+uint8_t I2C_get_irq_status

+(

+    i2c_instance_t * this_i2c

+);

+

+/*-------------------------------------------------------------------------*//**

+  The I2C_set_user_data() function is used to allow the association of a block

+  of application specific data with a CoreI2C channel. The composition of the 

+  data block is an application matter and the driver simply provides the means

+  for the application to set and retrieve the pointer. This may for example be

+  used to provide additional channel specific information to the slave write 

+  handler.

+  ------------------------------------------------------------------------------

+  @param this_i2c:

+    The this_i2c parameter is a pointer to the i2c_instance_t data structure

+    holding all data related to a specific CoreI2C channel. For example, if only

+    one channel is initialized, this data structure holds the information of 

+    channel 0 of the instantiated CoreI2C hardware.

+

+  @param p_user_data:

+    The p_user_data parameter is a pointer to the user specific data block for

+    this channel. It is defined as void * as the driver does not know the actual

+    type of data being pointed to and simply stores the pointer for later

+    retrieval by the application.

+

+  @return

+    none.

+    

+  Example

+  @code

+    #define COREI2C_BASE_ADDR  0xC0000000u

+    #define SLAVE_SER_ADDR     0x10u

+

+    i2c_instance_t g_i2c_inst;

+    app_data_t channel_xdata;

+  

+    void main( void )

+    {

+        app_data_t *p_xdata;

+

+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, SLAVE_SER_ADDR, 

+                  I2C_PCLK_DIV_256 );

+

+        // Store location of user data in instance structure

+        I2C_set_user_data( &g_i2c_inst, (void *)&channel_xdata );

+

+        ...

+

+        // Retrieve location of user data and do some work on it

+        p_xdata = (app_data_t *)I2C_get_user_data( &g_i2c_inst );

+        if( NULL != p_xdata )

+        {

+            p_xdata->foo = 123;

+        }

+    }

+  @endcode

+ */

+void I2C_set_user_data

+(

+    i2c_instance_t * this_i2c,

+    void * p_user_data

+);

+

+/*-------------------------------------------------------------------------*//**

+  The I2C_get_user_data() function is used to allow the retrieval of the address

+  of a block of application specific data associated with a CoreI2C channel.

+  The composition of the data block is an application matter and the driver 

+  simply provides the means for the application to set and retrieve the pointer.

+  This may for example be used to provide additional channel specific

+  information to the slave write handler.

+  ------------------------------------------------------------------------------

+  @param this_i2c:

+    The this_i2c parameter is a pointer to the i2c_instance_t data structure

+    holding all data related to a specific CoreI2C channel. For example, if only

+    one channel is initialized, this data structure holds the information of 

+    channel 0 of the instantiated CoreI2C hardware.

+

+  @return

+    This function returns a pointer to the user specific data block for this 

+    channel. It is defined as void * as the driver does not know the actual type

+    of data being pointed. If no user data has been registered for this channel

+    a NULL pointer is returned.

+    

+  Example

+  @code

+    #define COREI2C_BASE_ADDR  0xC0000000u

+    #define SLAVE_SER_ADDR     0x10u

+

+    i2c_instance_t g_i2c_inst;

+    app_data_t channel_xdata;

+  

+    void main( void )

+    {

+        app_data_t *p_xdata;

+

+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, SLAVE_SER_ADDR,

+                  I2C_PCLK_DIV_256 );

+

+        // Store location of user data in instance structure

+        I2C_set_user_data( &g_i2c_inst, (void *)&channel_xdata );

+

+        ...

+        

+        // Retrieve location of user data and do some work on it

+        p_xdata = (app_data_t *)I2C_get_user_data( &g_i2c_inst );

+        if( NULL != p_xdata )

+        {

+            p_xdata->foo = 123;

+        }

+    }

+  @endcode

+ */

+void * I2C_get_user_data

+(

+    i2c_instance_t * this_i2c

+);

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreI2C/core_smbus_regs.h b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreI2C/core_smbus_regs.h
new file mode 100644
index 0000000..67da7a5
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreI2C/core_smbus_regs.h
@@ -0,0 +1,190 @@
+/*******************************************************************************

+ * (c) Copyright 2009-2015 Microsemi SoC Products Group.  All rights reserved.

+ * 

+ * SVN $Revision: 7984 $

+ * SVN $Date: 2015-10-12 12:07:40 +0530 (Mon, 12 Oct 2015) $

+ */

+

+#ifndef __CORE_SMBUS_REGISTERS

+#define __CORE_SMBUS_REGISTERS    1

+

+/*------------------------------------------------------------------------------

+ * CONTROL register details

+ */

+#define CONTROL_REG_OFFSET    0x00u

+

+/*

+ * CR0 bits.

+ */

+#define CR0_OFFSET   0x00u

+#define CR0_MASK     0x01u

+#define CR0_SHIFT    0u

+

+/*

+ * CR1 bits.

+ */

+#define CR1_OFFSET   0x00u

+#define CR1_MASK     0x02u

+#define CR1_SHIFT    1u

+

+/*

+ * AA bits.

+ */

+#define AA_OFFSET   0x00u

+#define AA_MASK     0x04u

+#define AA_SHIFT    2u

+

+/*

+ * SI bits.

+ */

+#define SI_OFFSET   0x00u

+#define SI_MASK     0x08u

+#define SI_SHIFT    3u

+

+/*

+ * STO bits.

+ */

+#define STO_OFFSET   0x00u

+#define STO_MASK     0x10u

+#define STO_SHIFT    4u

+

+/*

+ * STA bits.

+ */

+#define STA_OFFSET   0x00u

+#define STA_MASK     0x20u

+#define STA_SHIFT    5u

+

+/*

+ * ENS1 bits.

+ */

+#define ENS1_OFFSET   0x00u

+#define ENS1_MASK     0x40u

+#define ENS1_SHIFT    6u

+

+/*

+ * CR2 bits.

+ */

+#define CR2_OFFSET   0x00u

+#define CR2_MASK     0x80u

+#define CR2_SHIFT    7u

+

+/*------------------------------------------------------------------------------

+ * STATUS register details

+ */

+#define STATUS_REG_OFFSET    0x04u

+

+/*------------------------------------------------------------------------------

+ * DATA register details

+ */

+#define DATA_REG_OFFSET    0x08u

+

+/*

+ * TARGET_ADDR bits.

+ */

+#define TARGET_ADDR_OFFSET    0x08u

+#define TARGET_ADDR_MASK      0xFEu

+#define TARGET_ADDR_SHIFT     1u

+ 

+/*

+ * DIR bit.

+ */

+#define DIR_OFFSET   0x08u

+#define DIR_MASK     0x01u

+#define DIR_SHIFT    0u

+

+

+/*------------------------------------------------------------------------------

+ * ADDRESS register details

+ */

+#define ADDRESS_REG_OFFSET    0x0Cu

+

+/*

+ * GC bits.

+ */

+#define GC_OFFSET   0x0Cu

+#define GC_MASK     0x01u

+#define GC_SHIFT    0u

+

+/*

+ * ADR bits.

+ */

+#define OWN_SLAVE_ADDR_OFFSET   0x0Cu

+#define OWN_SLAVE_ADDR_MASK     0xFEu

+#define OWN_SLAVE_ADDR_SHIFT    1u

+

+/*------------------------------------------------------------------------------

+ * SMBUS register details

+ */

+#define SMBUS_REG_OFFSET    0x10u

+

+/*

+ * SMBALERT_IE bits.

+ */

+#define SMBALERT_IE_OFFSET   0x10u

+#define SMBALERT_IE_MASK     0x01u

+#define SMBALERT_IE_SHIFT    0u

+

+/*

+ * SMBSUS_IE bits.

+ */

+#define SMBSUS_IE_OFFSET   0x10u

+#define SMBSUS_IE_MASK     0x02u

+#define SMBSUS_IE_SHIFT    1u

+

+/*

+ * SMB_IPMI_EN bits.

+ */

+#define SMB_IPMI_EN_OFFSET   0x10u

+#define SMB_IPMI_EN_MASK     0x04u

+#define SMB_IPMI_EN_SHIFT    2u

+

+/*

+ * SMBALERT_NI_STATUS bits.

+ */

+#define SMBALERT_NI_STATUS_OFFSET   0x10u

+#define SMBALERT_NI_STATUS_MASK     0x08u

+#define SMBALERT_NI_STATUS_SHIFT    3u

+

+/*

+ * SMBALERT_NO_CONTROL bits.

+ */

+#define SMBALERT_NO_CONTROL_OFFSET   0x10u

+#define SMBALERT_NO_CONTROL_MASK     0x10u

+#define SMBALERT_NO_CONTROL_SHIFT    4u

+

+/*

+ * SMBSUS_NI_STATUS bits.

+ */

+#define SMBSUS_NI_STATUS_OFFSET   0x10u

+#define SMBSUS_NI_STATUS_MASK     0x20u

+#define SMBSUS_NI_STATUS_SHIFT    5u

+

+/*

+ * SMBSUS_NO_CONTROL bits.

+ */

+#define SMBSUS_NO_CONTROL_OFFSET   0x10u

+#define SMBSUS_NO_CONTROL_MASK     0x40u

+#define SMBSUS_NO_CONTROL_SHIFT    6u

+

+/*

+ * SMBUS_MST_RESET bits.

+ */

+#define SMBUS_MST_RESET_OFFSET   0x10u

+#define SMBUS_MST_RESET_MASK     0x80u

+#define SMBUS_MST_RESET_SHIFT    7u

+

+/*------------------------------------------------------------------------------

+ * SLAVE ADDRESS 1 register details

+ */

+

+#define ADDRESS1_REG_OFFSET    0x1Cu

+

+/*

+ * SLAVE1_EN bit of Slave Address 1 .

+ */

+#define SLAVE1_EN_OFFSET      0x1Cu

+#define SLAVE1_EN_MASK        0x01u

+#define SLAVE1_EN_SHIFT          0u

+

+#endif    /* __CORE_SMBUS_REGISTERS */

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreI2C/i2c_interrupt.c b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreI2C/i2c_interrupt.c
new file mode 100644
index 0000000..f918b8c
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreI2C/i2c_interrupt.c
@@ -0,0 +1,35 @@
+/*******************************************************************************

+ * (c) Copyright 2009-2015 Microsemi SoC Products Group.  All rights reserved.

+ * 

+ * CoreI2C driver interrupt control.

+ * 

+ * SVN $Revision: 7984 $

+ * SVN $Date: 2015-10-12 12:07:40 +0530 (Mon, 12 Oct 2015) $

+ */

+#include "hal.h"

+#include "hal_assert.h"

+#include "core_i2c.h"

+#include "riscv_hal.h"

+

+

+#define I2C_IRQn					    External_29_IRQn

+

+/*------------------------------------------------------------------------------

+ * This function must be modified to enable interrupts generated from the

+ * CoreI2C instance identified as parameter.

+ */

+void I2C_enable_irq( i2c_instance_t * this_i2c )

+{

+	PLIC_EnableIRQ(I2C_IRQn);

+//    HAL_ASSERT(0)

+}

+

+/*------------------------------------------------------------------------------

+ * This function must be modified to disable interrupts generated from the

+ * CoreI2C instance identified as parameter.

+ */

+void I2C_disable_irq( i2c_instance_t * this_i2c )

+{

+	PLIC_DisableIRQ(I2C_IRQn);

+//    HAL_ASSERT(0)

+}

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreTimer/core_timer.c b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreTimer/core_timer.c
new file mode 100644
index 0000000..3f6720b
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreTimer/core_timer.c
@@ -0,0 +1,158 @@
+/*******************************************************************************

+ * (c) Copyright 2007-2015 Microsemi SoC Products Group. All rights reserved.

+ * 

+ * CoreTimer driver implementation.

+ * 

+ * SVN $Revision: 7967 $

+ * SVN $Date: 2015-10-09 18:48:26 +0530 (Fri, 09 Oct 2015) $

+ */

+

+#include "core_timer.h"

+#include "coretimer_regs.h"

+#include "hal.h"

+#include "hal_assert.h"

+

+#ifndef NDEBUG

+static timer_instance_t* NULL_timer_instance;

+#endif

+

+/***************************************************************************//**

+ * TMR_init()

+ * See "core_timer.h" for details of how to use this function.

+ */

+void 

+TMR_init

+(

+	timer_instance_t * this_timer,

+	addr_t address,

+	uint8_t mode,

+	uint32_t prescale,

+	uint32_t load_value

+)

+{

+	HAL_ASSERT( this_timer != NULL_timer_instance )

+	HAL_ASSERT( prescale <= PRESCALER_DIV_1024 )

+	HAL_ASSERT( load_value != 0 )

+    

+    this_timer->base_address = address;

+

+    /* Disable interrupts. */

+    HAL_set_32bit_reg_field( address, InterruptEnable,0 );

+

+    /* Disable timer. */

+    HAL_set_32bit_reg_field( address, TimerEnable, 0 );

+

+    /* Clear pending interrupt. */

+    HAL_set_32bit_reg( address, TimerIntClr, 1 );

+

+    /* Configure prescaler and load value. */	

+    HAL_set_32bit_reg( address, TimerPrescale, prescale );

+    HAL_set_32bit_reg( address, TimerLoad, load_value );

+

+    /* Set the interrupt mode. */

+    if ( mode == TMR_CONTINUOUS_MODE )

+    {

+        HAL_set_32bit_reg_field( address, TimerMode, 0 );

+    }

+    else

+    {

+        /* TMR_ONE_SHOT_MODE */

+        HAL_set_32bit_reg_field( address, TimerMode, 1 );

+    }

+}

+

+/***************************************************************************//**

+ * TMR_start()

+ * See "core_timer.h" for details of how to use this function.

+ */

+void

+TMR_start

+(

+    timer_instance_t * this_timer

+)

+{

+	HAL_ASSERT( this_timer != NULL_timer_instance )

+    

+    HAL_set_32bit_reg_field( this_timer->base_address, TimerEnable, 1 );

+}

+

+/***************************************************************************//**

+ * TMR_stop()

+ * See "core_timer.h" for details of how to use this function.

+ */

+void

+TMR_stop

+(

+    timer_instance_t * this_timer

+)

+{

+	HAL_ASSERT( this_timer != NULL_timer_instance )

+    

+    HAL_set_32bit_reg_field( this_timer->base_address, TimerEnable, 0 );

+}

+

+

+/***************************************************************************//**

+ * TMR_enable_int()

+ * See "core_timer.h" for details of how to use this function.

+ */

+void

+TMR_enable_int

+(

+    timer_instance_t * this_timer

+)

+{

+	HAL_ASSERT( this_timer != NULL_timer_instance )

+    

+    HAL_set_32bit_reg_field( this_timer->base_address, InterruptEnable, 1 );

+}

+

+/***************************************************************************//**

+ * TMR_clear_int()

+ * See "core_timer.h" for details of how to use this function.

+ */

+void

+TMR_clear_int

+(

+    timer_instance_t * this_timer

+)

+{

+	HAL_ASSERT( this_timer != NULL_timer_instance )

+    

+    HAL_set_32bit_reg( this_timer->base_address, TimerIntClr, 0x01 );

+}

+

+/***************************************************************************//**

+ * TMR_current_value()

+ * See "core_timer.h" for details of how to use this function.

+ */

+uint32_t

+TMR_current_value

+(

+    timer_instance_t * this_timer

+)

+{

+	uint32_t value = 0;

+	HAL_ASSERT( this_timer != NULL_timer_instance )

+    

+    value = HAL_get_32bit_reg( this_timer->base_address, TimerValue );

+    

+	return value;

+}

+

+/***************************************************************************//**

+ * TMR_reload()

+ * See "core_timer.h" for details of how to use this function.

+ */

+void TMR_reload

+(

+	timer_instance_t * this_timer,

+	uint32_t load_value

+)

+{

+	HAL_ASSERT( this_timer != NULL_timer_instance )

+	HAL_ASSERT( load_value != 0 )

+	

+	HAL_set_32bit_reg(this_timer->base_address, TimerLoad, load_value );

+}

+

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreTimer/core_timer.h b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreTimer/core_timer.h
new file mode 100644
index 0000000..04b7a6e
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreTimer/core_timer.h
@@ -0,0 +1,206 @@
+/*******************************************************************************

+ * (c) Copyright 2007-2015 Microsemi SoC Products Group. All rights reserved.

+ * 

+ * CoreTimer public API.

+ * 

+ * SVN $Revision: 7967 $

+ * SVN $Date: 2015-10-09 18:48:26 +0530 (Fri, 09 Oct 2015) $

+ */

+#ifndef CORE_TIMER_H_

+#define CORE_TIMER_H_

+

+#include "cpu_types.h"

+

+/***************************************************************************//**

+ * The following definitions are used to select the CoreTimer driver operating

+ * mode. They allow selecting continuous or one-shot mode.

+ * 1. Continuous Mode

+ * In continuous mode the timer's counter is decremented from the load value 

+ * until it reaches zero. The timer counter is automatically reloaded, with the

+ * load value, upon reaching zero. An interrupt is generated every time the

+ * counter reaches zero if interrupt is enabled.

+ * This mode is typically used to generate an interrupt at constant time

+ * intervals.

+ * 2. One-shot mode: 

+ * In one-shot mode, the counter decrements from the load value and until it

+ * reaches zero. An interrupt can be generated, if enabled, when the counter

+ * reaches zero. The timer's counter must be reloaded to begin counting down

+ * again.

+ */

+#define TMR_CONTINUOUS_MODE		0

+#define TMR_ONE_SHOT_MODE		1

+

+/***************************************************************************//**

+ * The following definitions are used to configure the CoreTimer prescaler.

+ * The prescaler is used to divide down the clock used to decrement the

+ * CoreTimer counter. It can be configure to divide the clock by 2, 4, 8,

+ * 16, 32, 64, 128, 256, 512, or 1024.

+ */

+#define PRESCALER_DIV_2			0

+#define PRESCALER_DIV_4			1

+#define PRESCALER_DIV_8			2

+#define PRESCALER_DIV_16		3

+#define PRESCALER_DIV_32		4

+#define PRESCALER_DIV_64		5

+#define PRESCALER_DIV_128		6

+#define PRESCALER_DIV_256		7

+#define PRESCALER_DIV_512		8

+#define PRESCALER_DIV_1024		9

+

+/***************************************************************************//**

+ * There should be one instance of this structure for each instance of CoreTimer

+ * in your system. The function TMR_init() initializes this structure. It is

+ * used to identify the various CoreTimer hardware instances in your system.

+ * An initialized timer instance structure should be passed as first parameter to

+ * CoreTimer driver functions to identify which CoreTimer instance should perform

+ * the requested operation.

+ * Software using this driver should only need to create one single instance of 

+ * this data structure for each hardware timer instance in the system.

+ */

+typedef struct __timer_instance_t

+{

+	addr_t base_address;

+} timer_instance_t;

+

+/***************************************************************************//**

+ * The function TMR_init() initializes the data structures and sets relevant

+ * CoreTimer registers. This function will prepare the Timer for use in a given

+ * hardware/software configuration. It should be called before any other Timer

+ * API functions.

+ * The timer will not start counting down immediately after this function is

+ * called. It is necessary to call TMR_start() to start the timer decrementing.

+ * The CoreTimer interrupt is disabled as part of this function.

+ *

+ * @param this_timer    Pointer to a timer_instance_t structure holding all 

+ *                      relevant data associated with the target timer hardware

+ * 						instance. This pointer will be used to identify the

+ * 						target CoreTimer hardware instance in subsequent calls

+ * 						to the CoreTimer functions.

+ * @param address       Base address in the processor's memory map of the 

+ *                      registers of the CoreTimer instance being initialized.

+ * @param mode          This parameter is used to select the operating mode of

+ * 						the timer driver. This can be either TMR_CONTINUOUS_MODE

+ * 						or TMR_ONE_SHOT_MODE.

+ * @param prescale    	This parameter is used to select the prescaler divider

+ * 						used to divide down the clock used to decrement the

+ * 						timerÂ’s counter. This can be set using one of the 

+ * 						PRESCALER_DIV_<n> definitions, where <n> is the

+ * 						dividerÂ’s value.  

+ * @param load_value	This parameter is used to set the timerÂ’s load value

+ * 						from which the CoreTimer counter will decrement.

+ * 						In Continuous mode, this value will be used to reload 

+ * 						the timerÂ’s counter whenever it reaches zero.

+ */

+void

+TMR_init

+(

+	timer_instance_t * this_timer,

+	addr_t address,

+	uint8_t mode,

+	uint32_t prescale,

+	uint32_t load_value

+);

+

+/***************************************************************************//**

+ * The function TMR_start() enables the timer to start counting down.

+ * This function only needs to be called once after the timer has been

+ * initialized through a call to TMR_init(). It does not need to be called after

+ * each call to TMR_reload() when the timer is used in one-shot mode.

+ *

+ * @param this_timer    Pointer to a timer_instance_t structure holding all 

+ *                      relevant data associated with the target timer hardware

+ * 						instance. This pointer is used to identify the target

+ * 						CoreTimer hardware instance.

+ */

+void

+TMR_start

+(

+    timer_instance_t * this_timer

+);

+

+/***************************************************************************//**

+ * The function TMR_stop() stops the timer counting down. It can be used to 

+ * stop interrupts from being generated when continuous mode is used and

+ * interrupts must be paused from being generated.

+ *

+ * @param this_timer    Pointer to a timer_instance_t structure holding all 

+ *                      relevant data associated with the target timer hardware

+ * 						instance. This pointer is used to identify the target

+ * 						CoreTimer hardware instance.

+ */

+void

+TMR_stop

+(

+    timer_instance_t * this_timer

+);

+

+/***************************************************************************//**

+ * The function TMR_enable_int() enables the timer interrupt. A call to this

+ * function will allow the interrupt signal coming out of CoreTimer to be

+ * asserted. 

+ *

+ * @param this_timer    Pointer to a timer_instance_t structure holding all 

+ *                      relevant data associated with the target timer hardware

+ * 						instance. This pointer is used to identify the target

+ * 						CoreTimer hardware instance.

+ */

+void

+TMR_enable_int

+(

+    timer_instance_t * this_timer

+);

+

+/***************************************************************************//**

+ * The function TMR_clear_int() clears the timer interrupt. This function should

+ * be called within the interrupt handler servicing interrupts from the timer.

+ * Failure to clear the timer interrupt will result in the interrupt signal

+ * generating from CoreTimer to remain asserted. This assertion may cause the

+ * interrupt service routine to be continuously called, causing the system to

+ * lock up.

+ *

+ * @param this_timer    Pointer to a timer_instance_t structure holding all 

+ *                      relevant data associated with the target timer hardware

+ * 						instance. This pointer is used to identify the target

+ * 						CoreTimer hardware instance.

+ */

+void

+TMR_clear_int

+(

+    timer_instance_t * this_timer

+);

+

+/***************************************************************************//**

+ * The TMR_current_value() function returns the current value of the counter.

+ *

+ * @param this_timer    Pointer to a timer_instance_t structure holding all 

+ *                      relevant data associated with the target timer hardware

+ * 						instance. This pointer is used to identify the target

+ * 						CoreTimer hardware instance.

+ *

+ * @return              Returns the current value of the timer counter value.

+ */

+uint32_t

+TMR_current_value

+(

+    timer_instance_t * this_timer

+);

+

+/***************************************************************************//**

+ * The TMR_reload() function is used in one-shot mode. It reloads the timer

+ * counter with the values passed as parameter. This will result in an interrupt

+ * being generated when the timer counter reaches 0 if interrupt is enabled.

+ * 

+ * @param this_timer    Pointer to a timer_instance_t structure holding all 

+ *                      relevant data associated with the target timer hardware

+ * 						instance. This pointer is used to identify the target

+ * 						CoreTimer hardware instance.

+ * @param load_value	This parameter sets the value from which the CoreTimer

+ * 						counter will decrement. 

+ */

+void TMR_reload

+(

+	timer_instance_t * this_timer,

+	uint32_t load_value

+);

+	

+#endif /* CORE_TIMER_H_ */

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreTimer/coretimer_regs.h b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreTimer/coretimer_regs.h
new file mode 100644
index 0000000..5d7c67d
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreTimer/coretimer_regs.h
@@ -0,0 +1,109 @@
+/*******************************************************************************

+ * (c) Copyright 2007-2015 Microsemi SoC Products Group. All rights reserved.

+ * 

+ * SVN $Revision: 7967 $

+ * SVN $Date: 2015-10-09 18:48:26 +0530 (Fri, 09 Oct 2015) $

+ */

+

+#ifndef __CORE_TIMER_REGISTERS

+#define __CORE_TIMER_REGISTERS	1

+

+/*------------------------------------------------------------------------------

+ * TimerLoad register details

+ */

+#define TimerLoad_REG_OFFSET	0x00

+

+/*

+ * LoadValue bits.

+ */

+#define LoadValue_OFFSET   0x00

+#define LoadValue_MASK     0xFFFFFFFF

+#define LoadValue_SHIFT    0

+

+/*------------------------------------------------------------------------------

+ * TimerValue register details

+ */

+#define TimerValue_REG_OFFSET	0x04

+

+/*

+ * CurrentValue bits.

+ */

+#define CurrentValue_OFFSET   0x04

+#define CurrentValue_MASK     0xFFFFFFFF

+#define CurrentValue_SHIFT    0

+

+/*------------------------------------------------------------------------------

+ * TimerControl register details

+ */

+#define TimerControl_REG_OFFSET	0x08

+

+/*

+ * TimerEnable bits.

+ */

+#define TimerEnable_OFFSET   0x08

+#define TimerEnable_MASK     0x00000001

+#define TimerEnable_SHIFT    0

+

+/*

+ * InterruptEnable bits.

+ */

+#define InterruptEnable_OFFSET   0x08

+#define InterruptEnable_MASK     0x00000002

+#define InterruptEnable_SHIFT    1

+

+/*

+ * TimerMode bits.

+ */

+#define TimerMode_OFFSET   0x08

+#define TimerMode_MASK     0x00000004

+#define TimerMode_SHIFT    2

+

+/*------------------------------------------------------------------------------

+ * TimerPrescale register details

+ */

+#define TimerPrescale_REG_OFFSET	0x0C

+

+/*

+ * Prescale bits.

+ */

+#define Prescale_OFFSET   0x0C

+#define Prescale_MASK     0x0000000F

+#define Prescale_SHIFT    0

+

+/*------------------------------------------------------------------------------

+ * TimerIntClr register details

+ */

+#define TimerIntClr_REG_OFFSET	0x10

+

+/*

+ * TimerIntClr bits.

+ */

+#define TimerIntClr_OFFSET   0x10

+#define TimerIntClr_MASK     0xFFFFFFFF

+#define TimerIntClr_SHIFT    0

+

+/*------------------------------------------------------------------------------

+ * TimerRIS register details

+ */

+#define TimerRIS_REG_OFFSET	0x14

+

+/*

+ * RawTimerInterrupt bits.

+ */

+#define RawTimerInterrupt_OFFSET   0x14

+#define RawTimerInterrupt_MASK     0x00000001

+#define RawTimerInterrupt_SHIFT    0

+

+/*------------------------------------------------------------------------------

+ * TimerMIS register details

+ */

+#define TimerMIS_REG_OFFSET	0x18

+

+/*

+ * TimerInterrupt bits.

+ */

+#define TimerInterrupt_OFFSET   0x18

+#define TimerInterrupt_MASK     0x00000001

+#define TimerInterrupt_SHIFT    0

+

+#endif /* __CORE_TIMER_REGISTERS */

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreUARTapb/core_uart_apb.c b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreUARTapb/core_uart_apb.c
new file mode 100644
index 0000000..b4f40dc
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreUARTapb/core_uart_apb.c
@@ -0,0 +1,296 @@
+/*******************************************************************************

+ * (c) Copyright 2007-2017 Microsemi SoC Products Group. All rights reserved.

+ * 

+ * CoreUARTapb driver implementation. See file "core_uart_apb.h" for a

+ * description of the functions implemented in this file.

+ * 

+ * SVN $Revision: 9082 $

+ * SVN $Date: 2017-04-28 11:51:36 +0530 (Fri, 28 Apr 2017) $

+ */

+#include "hal.h"

+#include "coreuartapb_regs.h"

+#include "core_uart_apb.h"

+#include "hal_assert.h"

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+#define NULL_INSTANCE ( ( UART_instance_t* ) 0 )

+#define NULL_BUFFER   ( ( uint8_t* ) 0 )

+

+#define MAX_LINE_CONFIG     ( ( uint8_t )( DATA_8_BITS | ODD_PARITY ) )

+#define MAX_BAUD_VALUE      ( ( uint16_t )( 0x1FFF ) )

+#define STATUS_ERROR_MASK   ( ( uint8_t )( STATUS_PARITYERR_MASK | \

+                                           STATUS_OVERFLOW_MASK  | \

+                                           STATUS_FRAMERR_MASK ) )

+#define BAUDVALUE_LSB ( (uint16_t) (0x00FF) )

+#define BAUDVALUE_MSB ( (uint16_t) (0xFF00) )

+#define BAUDVALUE_SHIFT ( (uint8_t) (5) )

+

+#define STATUS_ERROR_OFFSET STATUS_PARITYERR_SHIFT 

+

+/***************************************************************************//**

+ * UART_init()

+ * See "core_uart_apb.h" for details of how to use this function.

+ */

+void

+UART_init

+(

+    UART_instance_t * this_uart,

+    addr_t base_addr,

+    uint16_t baud_value,

+    uint8_t line_config

+)

+{

+    uint8_t rx_full;

+    

+    HAL_ASSERT( this_uart != NULL_INSTANCE )

+    HAL_ASSERT( line_config <= MAX_LINE_CONFIG )

+    HAL_ASSERT( baud_value <= MAX_BAUD_VALUE )

+

+    if( ( this_uart != NULL_INSTANCE ) &&

+        ( line_config <= MAX_LINE_CONFIG ) &&

+        ( baud_value <= MAX_BAUD_VALUE ) )

+    {

+        /*

+         * Store lower 8-bits of baud value in CTRL1.

+         */

+        HAL_set_8bit_reg( base_addr, CTRL1, (uint_fast8_t)(baud_value &

+                                                       BAUDVALUE_LSB ) );

+    

+        /*

+         * Extract higher 5-bits of baud value and store in higher 5-bits 

+         * of CTRL2, along with line configuration in lower 3 three bits.

+         */

+        HAL_set_8bit_reg( base_addr, CTRL2, (uint_fast8_t)line_config | 

+                                           (uint_fast8_t)((baud_value &

+                                   BAUDVALUE_MSB) >> BAUDVALUE_SHIFT ) );

+    

+        this_uart->base_address = base_addr;

+#ifndef NDEBUG

+        {

+            uint8_t  config;

+            uint8_t  temp;

+            uint16_t baud_val;

+            baud_val = HAL_get_8bit_reg( this_uart->base_address, CTRL1 );

+            config =  HAL_get_8bit_reg( this_uart->base_address, CTRL2 );

+            /*

+             * To resolve operator precedence between & and <<

+             */

+            temp =  ( config  &  (uint8_t)(CTRL2_BAUDVALUE_MASK ) );

+            baud_val |= (uint16_t)( (uint16_t)(temp) << BAUDVALUE_SHIFT );

+            config &= (uint8_t)(~CTRL2_BAUDVALUE_MASK);

+            HAL_ASSERT( baud_val == baud_value );

+            HAL_ASSERT( config == line_config );

+        }        

+#endif

+        

+        /*

+         * Flush the receive FIFO of data that may have been received before the

+         * driver was initialized.

+         */

+        rx_full = HAL_get_8bit_reg( this_uart->base_address, STATUS ) &

+                                                    STATUS_RXFULL_MASK;

+        while ( rx_full )

+        {

+            HAL_get_8bit_reg( this_uart->base_address, RXDATA );

+            rx_full = HAL_get_8bit_reg( this_uart->base_address, STATUS ) &

+                                                        STATUS_RXFULL_MASK;

+        }

+

+        /*

+         * Clear status of the UART instance.

+         */

+        this_uart->status = (uint8_t)0;

+    }

+}

+

+/***************************************************************************//**

+ * UART_send()

+ * See "core_uart_apb.h" for details of how to use this function.

+ */

+void

+UART_send

+(

+    UART_instance_t * this_uart,

+    const uint8_t * tx_buffer,

+    size_t tx_size

+)

+{

+    size_t char_idx;

+    uint8_t tx_ready;

+

+    HAL_ASSERT( this_uart != NULL_INSTANCE )

+    HAL_ASSERT( tx_buffer != NULL_BUFFER )

+    HAL_ASSERT( tx_size > 0 )

+      

+    if( (this_uart != NULL_INSTANCE) &&

+        (tx_buffer != NULL_BUFFER)   &&

+        (tx_size > (size_t)0) )

+    {

+        for ( char_idx = (size_t)0; char_idx < tx_size; char_idx++ )

+        {

+            /* Wait for UART to become ready to transmit. */

+            do {

+                tx_ready = HAL_get_8bit_reg( this_uart->base_address, STATUS ) &

+                                                              STATUS_TXRDY_MASK;

+            } while ( !tx_ready );

+            /* Send next character in the buffer. */

+            HAL_set_8bit_reg( this_uart->base_address, TXDATA,

+                              (uint_fast8_t)tx_buffer[char_idx] );

+        }

+    }

+}

+

+/***************************************************************************//**

+ * UART_fill_tx_fifo()

+ * See "core_uart_apb.h" for details of how to use this function.

+ */

+size_t

+UART_fill_tx_fifo

+(

+    UART_instance_t * this_uart,

+    const uint8_t * tx_buffer,

+    size_t tx_size

+)

+{

+    uint8_t tx_ready;

+    size_t size_sent = 0u;

+    

+    HAL_ASSERT( this_uart != NULL_INSTANCE )

+    HAL_ASSERT( tx_buffer != NULL_BUFFER )

+    HAL_ASSERT( tx_size > 0 )

+      

+    /* Fill the UART's Tx FIFO until the FIFO is full or the complete input 

+     * buffer has been written. */

+    if( (this_uart != NULL_INSTANCE) &&

+        (tx_buffer != NULL_BUFFER)   &&

+        (tx_size > 0u) )

+    {

+        tx_ready = HAL_get_8bit_reg( this_uart->base_address, STATUS ) &

+                                                      STATUS_TXRDY_MASK;

+        if ( tx_ready )

+        {

+            do {

+                HAL_set_8bit_reg( this_uart->base_address, TXDATA,

+                                  (uint_fast8_t)tx_buffer[size_sent] );

+                size_sent++;

+                tx_ready = HAL_get_8bit_reg( this_uart->base_address, STATUS ) &

+                                                              STATUS_TXRDY_MASK;

+            } while ( (tx_ready) && ( size_sent < tx_size ) );

+        }

+    }    

+    return size_sent;

+}

+

+/***************************************************************************//**

+ * UART_get_rx()

+ * See "core_uart_apb.h" for details of how to use this function.

+ */

+size_t

+UART_get_rx

+(

+    UART_instance_t * this_uart,

+    uint8_t * rx_buffer,

+    size_t buff_size

+)

+{

+    uint8_t new_status;

+    uint8_t rx_full;

+    size_t rx_idx = 0u;

+    

+    HAL_ASSERT( this_uart != NULL_INSTANCE )

+    HAL_ASSERT( rx_buffer != NULL_BUFFER )

+    HAL_ASSERT( buff_size > 0 )

+      

+    if( (this_uart != NULL_INSTANCE) &&

+        (rx_buffer != NULL_BUFFER)   &&

+        (buff_size > 0u) )

+    {

+        rx_idx = 0u;

+        new_status = HAL_get_8bit_reg( this_uart->base_address, STATUS );

+        this_uart->status |= new_status;

+        rx_full = new_status & STATUS_RXFULL_MASK;

+        while ( ( rx_full ) && ( rx_idx < buff_size ) )

+        {

+            rx_buffer[rx_idx] = HAL_get_8bit_reg( this_uart->base_address,

+                                                  RXDATA );

+            rx_idx++;

+            new_status = HAL_get_8bit_reg( this_uart->base_address, STATUS );

+            this_uart->status |= new_status;

+            rx_full = new_status & STATUS_RXFULL_MASK;

+        }

+    }

+    return rx_idx;

+}

+

+/***************************************************************************//**

+ * UART_polled_tx_string()

+ * See "core_uart_apb.h" for details of how to use this function.

+ */

+void 

+UART_polled_tx_string

+( 

+    UART_instance_t * this_uart, 

+    const uint8_t * p_sz_string

+)

+{

+    uint32_t char_idx;

+    uint8_t tx_ready;

+

+    HAL_ASSERT( this_uart != NULL_INSTANCE )

+    HAL_ASSERT( p_sz_string != NULL_BUFFER )

+    

+    if( ( this_uart != NULL_INSTANCE ) && ( p_sz_string != NULL_BUFFER ) )

+    {

+        char_idx = 0U;

+        while( 0U != p_sz_string[char_idx] )

+        {

+            /* Wait for UART to become ready to transmit. */

+            do {

+                tx_ready = HAL_get_8bit_reg( this_uart->base_address, STATUS ) &

+                                                              STATUS_TXRDY_MASK;

+            } while ( !tx_ready );

+            /* Send next character in the buffer. */

+            HAL_set_8bit_reg( this_uart->base_address, TXDATA,

+                              (uint_fast8_t)p_sz_string[char_idx] );

+            char_idx++;

+        }

+    }

+}

+

+/***************************************************************************//**

+ * UART_get_rx_status()

+ * See "core_uart_apb.h" for details of how to use this function.

+ */

+uint8_t

+UART_get_rx_status

+(

+    UART_instance_t * this_uart

+)

+{

+    uint8_t status = UART_APB_INVALID_PARAM;

+

+    HAL_ASSERT( this_uart != NULL_INSTANCE )

+    /*

+     * Extract UART error status and place in lower bits of "status".

+     * Bit 0 - Parity error status

+     * Bit 1 - Overflow error status

+     * Bit 2 - Frame error status

+     */

+    if( this_uart != NULL_INSTANCE )

+    {

+        status = ( ( this_uart->status & STATUS_ERROR_MASK ) >> 

+                                          STATUS_ERROR_OFFSET );

+        /*

+         * Clear the sticky status for this instance.

+         */

+        this_uart->status = (uint8_t)0;

+    }

+    return status;

+}

+

+#ifdef __cplusplus

+}

+#endif

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreUARTapb/core_uart_apb.h b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreUARTapb/core_uart_apb.h
new file mode 100644
index 0000000..680b68d
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreUARTapb/core_uart_apb.h
@@ -0,0 +1,407 @@
+/*******************************************************************************

+ * (c) Copyright 2007-2017 Microsemi SoC Products Group. All rights reserved.

+ * 

+ * This file contains the application programming interface for the CoreUARTapb

+ * bare metal driver.

+ * 

+ * SVN $Revision: 9082 $

+ * SVN $Date: 2017-04-28 11:51:36 +0530 (Fri, 28 Apr 2017) $

+ */

+/*=========================================================================*//**

+  @mainpage CoreUARTapb Bare Metal Driver.

+

+  @section intro_sec Introduction

+  CoreUARTapb is an implementation of the Universal Asynchronous 

+  Receiver/Transmitter aimed at a minimal FPGA tile usage within an Microsemi

+  FPGA. The CoreUARTapb bare metal software driver is designed for use in 

+  systems with no operating system.

+

+  The CoreUARTapb driver provides functions for basic polled transmitting and 

+  receiving operations. It also provides functions allowing use of the 

+  CoreUARTapb in interrupt-driven mode, but leaves the management of interrupts 

+  to the calling application, as interrupt enabling and disabling cannot be 

+  controlled through the CoreUARTapb registers. The CoreUARTapb driver is 

+  provided as C source code.

+

+  @section driver_configuration Driver Configuration

+  Your application software should configure the CoreUARTapb driver, through 

+  calls to the UART_init() function for each CoreUARTapb instance in the 

+  hardware design. The configuration parameters include the CoreUARTapb 

+  hardware instance base address and other runtime parameters, such as baud 

+  rate, bit width, and parity. No CoreUARTapb hardware configuration parameters 

+  are needed by the driver, apart from the CoreUARTapb hardware instance base 

+  address. Hence, no additional configuration files are required to use the driver.

+

+  A CoreUARTapb hardware instance can be generated with fixed baud value, 

+  character size and parity configuration settings as part of the hardware flow. 

+  The baud_value and line_config parameter values passed to the UART_init() 

+  function will not have any effect if fixed values were selected for the 

+  baud value, character size and parity in the hardware configuration of 

+  CoreUARTapb. When fixed values are selected for these hardware configuration 

+  parameters, the driver cannot overwrite the fixed values in the CoreUARTapb 

+  control registers, CTRL1 and CTRL2.

+

+  @section theory_op Theory of Operation

+  The CoreUARTapb software driver is designed to allow the control of multiple 

+  instances of CoreUARTapb. Each instance of CoreUARTapb in the hardware design 

+  is associated with a single instance of the UART_instance_t structure in the 

+  software. You need to allocate memory for one unique UART_instance_t  

+  structure instance for each CoreUARTapb hardware instance. The contents of 

+  these data structures are initialized during calls to function UART_init(). 

+  A pointer to the structure is passed to subsequent driver functions in order

+  to identify the CoreUARTapb hardware instance you wish to perform the 

+  requested operation on.

+  

+  Note: Do not attempt to directly manipulate the content of UART_instance_t 

+  structures. This structure is only intended to be modified by the driver 

+  function.

+

+  The driver can be used to transmit and receive data once initialized. 

+  Transmit can be performed using the UART_send() function. This function

+  is blocking, meaning that it will only return once the data passed to 

+  the function has been sent to the CoreUARTapb hardware. Data received 

+  by the CoreUARTapb hardware can be read by the user application using 

+  the UART_get_rx() function.

+

+  The function UART_fill_tx_fifo() is also provided to be used as part of 

+  interrupt-driven transmit. This function fills the CoreUARTapb hardware 

+  transmit FIFO with the content of a data buffer passed as a parameter before 

+  returning. The control of the interrupts must be implemented outside the 

+  driver as the CoreUARTapb hardware does not provide the ability to enable 

+  or disable its interrupt sources.

+

+  The function UART_polled_tx_string() is provided to transmit a NULL 

+  terminated string in polled mode. This function is blocking, meaning that it 

+  will only return once the data passed to the function has been sent to the 

+  CoreUARTapb hardware.

+

+  The function UART_get_rx_status() returns the error status of the CoreUARTapb

+  receiver. This can be used by applications to take appropriate action in case

+  of receiver errors.

+*//*=========================================================================*/

+#ifndef __CORE_UART_APB_H

+#define __CORE_UART_APB_H 1

+

+#include "cpu_types.h"

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+/***************************************************************************//**

+ * Data bits length defines:

+ */

+#define DATA_7_BITS     0x00u

+#define DATA_8_BITS     0x01u

+

+/***************************************************************************//**

+ * Parity defines:

+ */

+#define NO_PARITY       0x00u

+#define EVEN_PARITY     0x02u

+#define ODD_PARITY      0x06u

+

+/***************************************************************************//**

+ * Error Status definitions:

+ */

+#define UART_APB_PARITY_ERROR    0x01u

+#define UART_APB_OVERFLOW_ERROR  0x02u

+#define UART_APB_FRAMING_ERROR   0x04u

+#define UART_APB_NO_ERROR        0x00u

+#define UART_APB_INVALID_PARAM   0xFFu

+

+/***************************************************************************//**

+ * UART_instance_t

+ * 

+ * There should be one instance of this structure for each instance of CoreUARTapb

+ * in your system. This structure instance is used to identify the various UARTs

+ * in a system and should be passed as first parameter to UART functions to 

+ * identify which UART should perform the requested operation. The 'status' 

+ * element in the structure is used to provide sticky status information. 

+ */

+typedef struct

+{

+    addr_t      base_address;

+    uint8_t     status;

+} UART_instance_t;

+

+/***************************************************************************//**

+ * The function UART_init() initializes the UART with the configuration passed 

+ * as parameters. The configuration parameters are the baud_value used to 

+ * generate the baud rate and the line configuration (bit length and parity).

+ *

+ * @param this_uart   The this_uart parameter is a pointer to a UART_instance_t

+ *                    structure which holds all data regarding this instance of

+ *                    the CoreUARTapb. This pointer will be used to identify 

+ *                    the target CoreUARTapb hardware instance in subsequent 

+ *                    calls to the CoreUARTapb functions.

+ * @param base_addr   The base_address parameter is the base address in the 

+ *                    processor's memory map for the registers of the 

+ *                    CoreUARTapb instance being initialized.

+ * @param baud_value  The baud_value parameter is used to select the baud rate 

+ *                    for the UART. The baud value is calculated from the 

+ *                    frequency of the system clock in hertz and the desired 

+ *                    baud rate using the following equation: 

+ *                    

+ *                    baud_value = (clock /(baud_rate * 16)) - 1.

+ * 

+ *                    The baud_value parameter must be a value in the range 0 

+ *                    to 8191 (or 0x0000 to 0x1FFF).

+ * @param line_config This parameter is the line configuration specifying the 

+ *                    bit length and parity settings. This is a logical OR of:

+ *                      - DATA_7_BITS

+ *                    - DATA_8_BITS

+ *                    - NO_PARITY

+ *                    - EVEN_PARITY

+ *                    - ODD_PARITY

+ *                    For example, 8 bits even parity would be specified as 

+ *                    (DATA_8_BITS | EVEN_PARITY). 

+ * @return            This function does not return a value.

+ * Example:

+ * @code

+ *   #define BAUD_VALUE_57600    25

+ *   

+ *   #define COREUARTAPB0_BASE_ADDR      0xC3000000UL

+ *   

+ *   UART_instance_t g_uart;

+ *   int main()

+ *   {

+ *      UART_init(&g_uart, COREUARTAPB0_BASE_ADDR, 

+                  BAUD_VALUE_57600, (DATA_8_BITS | EVEN_PARITY));

+ *   }

+ * @endcode

+ */

+void

+UART_init

+(

+    UART_instance_t * this_uart,

+    addr_t base_addr,

+    uint16_t baud_value,

+    uint8_t line_config

+);

+

+/***************************************************************************//**

+ * The function UART_send() is used to transmit data. It transfers the contents

+ * of the transmitter data buffer, passed as a function parameter, into the 

+ * UART's hardware transmitter FIFO. It returns when the full content of the 

+ * transmitter data buffer has been transferred to the UART's transmitter FIFO. 

+ *

+ * Note: you cannot assume that the data you are sending using this function has

+ * been received at the other end by the time this function returns. The actual

+ * transmit over the serial connection will still be taking place at the time of

+ * the function return. It is safe to release or reuse the memory used as the

+ * transmit buffer once this function returns.

+ *

+ * @param this_uart     The this_uart parameter is a pointer to a 

+ *                      UART_instance_t structure which holds all data regarding 

+ *                      this instance of the CoreUARTapbUART.

+ * @param tx_buffer     The tx_buffer parameter is a pointer to a buffer 

+ *                      containing the data to be transmitted.

+ * @param tx_size       The tx_size parameter is the size, in bytes, of 

+ *                      the data to be transmitted.

+ *

+ * @return              This function does not return a value.

+ *

+ * Example:

+ * @code

+ *   uint8_t testmsg1[] = {"\n\r\n\r\n\rUART_send() test message 1"};

+ *   UART_send(&g_uart,(const uint8_t *)&testmsg1,sizeof(testmsg1));

+ * @endcode

+ */

+void

+UART_send

+(

+    UART_instance_t * this_uart,

+    const uint8_t * tx_buffer,

+    size_t tx_size

+);

+

+/***************************************************************************//**

+ * The function UART_fill_tx_fifo() fills the UART's transmitter hardware FIFO 

+ * with the data found in the transmitter buffer that is passed in as a 

+ * function parameter. The function returns either when the FIFO is full or 

+ * when the complete contents of the transmitter buffer have been copied into 

+ * the FIFO. It returns the number of bytes copied into the UART's transmitter

+ * hardware FIFO. This function is intended to be used as part of 

+ * interrupt-driven transmission.

+ *

+ * Note:    You cannot assume that the data you transmit using this function has 

+ *          been received at the other end by the time this function returns. 

+ *          The actual transmission over the serial connection will still be 

+ *          taking place at the time of the function return. 

+ *

+ * @param this_uart     The this_uart parameter is a pointer to a UART_instance_t

+ *                      structure which holds all data regarding this instance of

+ *                      the UART.

+ * @param tx_buffer     The tx_buffer parameter is a pointer to a buffer 

+ *                      containing the data to be transmitted.

+ * @param tx_size       The tx_size parameter is the size in bytes, of the data 

+ *                      to be transmitted.

+ * @return              This function returns the number of bytes copied 

+ *                      into the UART's transmitter hardware FIFO. 

+ *

+ * Example:

+ * @code

+ *   void send_using_interrupt

+ *   (

+ *       uint8_t * pbuff,

+ *       size_t tx_size

+ *   )

+ *   {

+ *       size_t size_in_fifo;

+ *       size_in_fifo = UART_fill_tx_fifo( &g_uart, pbuff, tx_size );

+ *   }

+ * @endcode

+ */

+size_t

+UART_fill_tx_fifo

+(

+    UART_instance_t * this_uart,

+    const uint8_t * tx_buffer,

+    size_t tx_size

+);

+

+/***************************************************************************//**

+ * The function UART_get_rx() reads the content of the UART's receiver hardware 

+ * FIFO and stores it in the receiver buffer that is passed in as a function 

+ * parameter. It copies either the full contents of the FIFO into the receiver 

+ * buffer, or just enough data from the FIFO to fill the receiver buffer, 

+ * dependent upon the size of the receiver buffer.  The size of the receiver 

+ * buffer is passed in as a function parameter. UART_get_rx() returns the number

+ * of bytes copied into the receiver buffer. If no data was received at the time

+ * the function is called, the function returns 0.

+ *

+ * Note:    This function reads and accumulates the receiver status of the 

+ *          CoreUARTapb instance before reading each byte from the receiver's 

+ *          data register/FIFO. This allows the driver to maintain a sticky 

+ *          record of any receiver errors that occur as the UART receives each 

+ *          data byte; receiver errors would otherwise be lost after each read 

+ *          from the receiver's data register. A call to the UART_get_rx_status()

+ *          function returns any receiver errors accumulated during the execution

+ *          of the UART_get_rx() function.

+ * Note:    When FIFO mode is disabled in the CoreUARTapb hardware configuration,

+ *          the driver accumulates a sticky record of any parity errors, framing 

+ *          errors or overflow errors. When FIFO mode is enabled, the driver 

+ *          accumulates a sticky record of overflow errors only; in this case 

+ *          interrupts must be used to handle parity errors or framing errors.

+ *

+ * @param this_uart     The this_uart parameter is a pointer to a UART_instance_t 

+ *                      structure which holds all data regarding this instance of 

+ *                      the UART.

+ * @param rx_buffer     The rx_buffer parameter is a pointer to a buffer where the 

+ *                      received data will be copied.

+ * @param buff_size     The buff_size parameter is the size of the receive buffer 

+ *                      in bytes.

+ * @return              This function returns the number of bytes copied into the 

+ *                      receive buffer.

+ *

+ * Example:

+ * @code

+ *   #define MAX_RX_DATA_SIZE    256

+ *   

+ *   uint8_t rx_data[MAX_RX_DATA_SIZE];

+ *   uint8_t rx_size = 0;

+ *           

+ *   rx_size = UART_get_rx( &g_uart, rx_data, sizeof(rx_data) );

+ * @endcode

+ */

+size_t

+UART_get_rx

+(

+    UART_instance_t * this_uart,

+    uint8_t * rx_buffer,

+    size_t buff_size

+);

+

+/***************************************************************************//**

+ * The function UART_polled_tx_string() is used to transmit a NULL ('\0') 

+ * terminated string. Internally, it polls for the transmit ready status and

+ * transfers the text starting at the address pointed to by p_sz_string into

+ * the UART's hardware transmitter FIFO. It is a blocking function and returns

+ * only when the complete string has been transferred to the UART's transmit 

+ * FIFO.

+ *

+ * Note:    You cannot assume that the data you transmit using this function 

+ *          has been received at the other end by the time this function 

+ *          returns. The actual transmission over the serial connection will

+ *          still be taking place at the time of the function return.

+ *

+ * @param this_uart     The this_uart parameter is a pointer to a 

+ *                      UART_instance_t structure which holds

+ *                      all data regarding this instance of the UART.

+ * @param p_sz_string   The p_sz_string parameter is a pointer to a buffer

+ *                      containing the NULL ('\0') terminated string to be 

+ *                      transmitted.

+ * @return              This function does not return a value.

+ *

+ * Example:

+ * @code

+ *   uint8_t testmsg1[] = {"\r\n\r\nUART_polled_tx_string() test message 1\0"};

+ *   UART_polled_tx_string(&g_uart,(const uint8_t *)&testmsg1);

+ * @endcode

+ */

+void 

+UART_polled_tx_string

+( 

+    UART_instance_t * this_uart, 

+    const uint8_t * p_sz_string

+);

+

+/***************************************************************************//**

+ * The UART_get_rx_status() function returns the receiver error status of the 

+ * CoreUARTapb instance. It reads both the current error status of the receiver

+ * and the accumulated error status from preceding calls to the UART_get_rx() 

+ * function and combines them using a bitwise OR. It returns the cumulative 

+ * parity, framing and overflow error status of the receiver, since the 

+ * previous call to UART_get_rx_status(), as an 8-bit encoded value.

+ *

+ * Note:    The UART_get_rx() function reads and accumulates the receiver status 

+ *          of the CoreUARTapb instance before reading each byte from the 

+ *          receiver's data register/FIFO. The driver maintains a sticky record 

+ *          of the cumulative error status, which persists after the 

+ *          UART_get_rx() function returns. The UART_get_rx_status() function 

+ *          clears this accumulated record of receiver errors before returning.

+ * 

+ * @param this_uart     The this_uart parameter is a pointer to a UART_instance_t

+ *                      structure which holds all data regarding this instance 

+ *                      of the UART.

+ * @return              This function returns the UART receiver error status as 

+ *                      an 8-bit encoded value. The returned value is 0 if no 

+ *                      receiver errors occurred. The driver provides a set of 

+ *                      bit mask constants which should be compared with and/or

+ *                      used to mask the returned value to determine the 

+ *                      receiver error status. 

+ *                      When the return value is compared to the following bit 

+ *                      masks, a non-zero result indicates that the 

+ *                      corresponding error occurred:

+ *                      UART_APB_PARITY_ERROR    (bit mask = 0x01)

+ *                      UART_APB_OVERFLOW_ERROR  (bit mask = 0x02)

+ *                      UART_APB_FRAMING_ERROR   (bit mask = 0x04)

+ *                      When the return value is compared to the following bit 

+ *                      mask, a non-zero result indicates that no error occurred:

+ *                      UART_APB_NO_ERROR        (0x00)

+ *

+ * Example:

+ * @code

+ *   UART_instance_t g_uart;

+ *   uint8_t rx_data[MAX_RX_DATA_SIZE];

+ *   uint8_t err_status;

+ *   err_status = UART_get_err_status(&g_uart);

+ *   

+ *   if(UART_APB_NO_ERROR == err_status )

+ *   {

+ *        rx_size = UART_get_rx( &g_uart, rx_data, MAX_RX_DATA_SIZE );

+ *   }

+ * @endcode

+ */

+uint8_t

+UART_get_rx_status

+(

+    UART_instance_t * this_uart

+);

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif /* __CORE_UART_APB_H */

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreUARTapb/coreuartapb_regs.h b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreUARTapb/coreuartapb_regs.h
new file mode 100644
index 0000000..e6cc8c1
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreUARTapb/coreuartapb_regs.h
@@ -0,0 +1,130 @@
+/*******************************************************************************

+ * (c) Copyright 2007-2017 Microsemi SoC Products Group. All rights reserved.

+ * 

+ * SVN $Revision: 9082 $

+ * SVN $Date: 2017-04-28 11:51:36 +0530 (Fri, 28 Apr 2017) $

+ */

+

+#ifndef __CORE_UART_APB_REGISTERS

+#define __CORE_UART_APB_REGISTERS   1

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+/*------------------------------------------------------------------------------

+ * TxData register details

+ */

+#define TXDATA_REG_OFFSET   0x0u

+

+/*

+ * TxData bits.

+ */

+#define TXDATA_OFFSET   0x0u

+#define TXDATA_MASK     0xFFu

+#define TXDATA_SHIFT    0u

+

+/*------------------------------------------------------------------------------

+ * RxData register details

+ */

+#define RXDATA_REG_OFFSET   0x4u

+

+/*

+ * RxData bits.

+ */

+#define RXDATA_OFFSET   0x4u

+#define RXDATA_MASK     0xFFu

+#define RXDATA_SHIFT    0u

+

+/*------------------------------------------------------------------------------

+ * ControReg1 register details

+ */

+#define CTRL1_REG_OFFSET        0x8u

+

+/*

+ * Baud value (Lower 8-bits)

+ */

+#define CTRL1_BAUDVALUE_OFFSET   0x8u

+#define CTRL1_BAUDVALUE_MASK     0xFFu

+#define CTRL1_BAUDVALUE_SHIFT    0u

+

+/*------------------------------------------------------------------------------

+ * ControReg2 register details

+ */

+#define CTRL2_REG_OFFSET          0xCu

+

+/*

+ * Bit length

+ */

+#define CTRL2_BIT_LENGTH_OFFSET   0xCu

+#define CTRL2_BIT_LENGTH_MASK     0x01u

+#define CTRL2_BIT_LENGTH_SHIFT    0u

+

+/*

+ * Parity enable.

+ */

+#define CTRL2_PARITY_EN_OFFSET    0xCu

+#define CTRL2_PARITY_EN_MASK      0x02u

+#define CTRL2_PARITY_EN_SHIFT     1u

+

+/*

+ * Odd/even parity selection.

+ */

+#define CTRL2_ODD_EVEN_OFFSET     0xCu

+#define CTRL2_ODD_EVEN_MASK       0x04u

+#define CTRL2_ODD_EVEN_SHIFT      2u

+

+/*

+ *  Baud value (Higher 5-bits)

+ */

+#define CTRL2_BAUDVALUE_OFFSET    0xCu

+#define CTRL2_BAUDVALUE_MASK      0xF8u

+#define CTRL2_BAUDVALUE_SHIFT     3u

+

+/*------------------------------------------------------------------------------

+ * StatusReg register details

+ */

+#define StatusReg_REG_OFFSET    0x10u

+

+#define STATUS_REG_OFFSET       0x10u

+

+/*

+ * Transmit ready.

+ */

+#define STATUS_TXRDY_OFFSET   0x10u

+#define STATUS_TXRDY_MASK     0x01u

+#define STATUS_TXRDY_SHIFT    0u

+

+/*

+ * Receive full.

+ */

+#define STATUS_RXFULL_OFFSET   0x10u

+#define STATUS_RXFULL_MASK     0x02u

+#define STATUS_RXFULL_SHIFT    1u

+

+/*

+ * Parity error.

+ */

+#define STATUS_PARITYERR_OFFSET   0x10u

+#define STATUS_PARITYERR_MASK     0x04u

+#define STATUS_PARITYERR_SHIFT    2u

+

+/*

+ * Overflow.

+ */

+#define STATUS_OVERFLOW_OFFSET   0x10u

+#define STATUS_OVERFLOW_MASK     0x08u

+#define STATUS_OVERFLOW_SHIFT    3u

+

+/*

+ * Frame Error.

+ */

+#define STATUS_FRAMERR_OFFSET   0x10u

+#define STATUS_FRAMERR_MASK     0x10u

+#define STATUS_FRAMERR_SHIFT    4u

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif	/* __CORE_UART_APB_REGISTERS */

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/hal/cpu_types.h b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/hal/cpu_types.h
new file mode 100644
index 0000000..1beae8c
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/hal/cpu_types.h
@@ -0,0 +1,31 @@
+/*******************************************************************************

+ * (c) Copyright 2007-2018 Microsemi SoC Products Group. All rights reserved.

+ * 

+ * SVN $Revision: 9661 $

+ * SVN $Date: 2018-01-15 16:13:33 +0530 (Mon, 15 Jan 2018) $

+ */

+#ifndef __CPU_TYPES_H

+#define __CPU_TYPES_H   1

+

+#include <stdint.h>

+

+/*------------------------------------------------------------------------------

+ */

+typedef unsigned int size_t;

+

+/*------------------------------------------------------------------------------

+ * addr_t: address type.

+ * Used to specify the address of peripherals present in the processor's memory

+ * map.

+ */

+typedef unsigned int addr_t;

+

+/*------------------------------------------------------------------------------

+ * psr_t: processor state register.

+ * Used by HAL_disable_interrupts() and HAL_restore_interrupts() to store the

+ * processor's state between disabling and restoring interrupts.

+ */

+typedef unsigned int psr_t;

+

+#endif  /* __CPU_TYPES_H */

+

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/hal/hal.h b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/hal/hal.h
new file mode 100644
index 0000000..5b82ed0
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/hal/hal.h
@@ -0,0 +1,207 @@
+/***************************************************************************//**

+ * (c) Copyright 2007-2018 Microsemi SoC Products Group. All rights reserved.

+ * 

+ * Hardware abstraction layer functions.

+ * 

+ * SVN $Revision: 9661 $

+ * SVN $Date: 2018-01-15 16:13:33 +0530 (Mon, 15 Jan 2018) $

+ */

+#ifndef HAL_H_

+#define HAL_H_

+

+#include "cpu_types.h"

+#include "hw_reg_access.h"

+

+/***************************************************************************//**

+ * Enable all interrupts at the processor level.

+ */

+void HAL_enable_interrupts( void );

+

+/***************************************************************************//**

+ * Disable all interrupts at the processor core level.

+ * Return the interrupts enable state before disabling occured so that it can 

+ * later be restored. 

+ */

+psr_t HAL_disable_interrupts( void );

+

+/***************************************************************************//**

+ * Restore the interrupts enable state at the processor core level.

+ * This function is normally passed the value returned from a previous call to

+ * HAL_disable_interrupts(). 

+ */

+void HAL_restore_interrupts( psr_t saved_psr );

+

+/***************************************************************************//**

+ */

+#define FIELD_OFFSET(FIELD_NAME)  (FIELD_NAME##_OFFSET)

+#define FIELD_SHIFT(FIELD_NAME)   (FIELD_NAME##_SHIFT)

+#define FIELD_MASK(FIELD_NAME)    (FIELD_NAME##_MASK)

+

+/***************************************************************************//**

+ * The macro HAL_set_32bit_reg() allows writing a 32 bits wide register.

+ *

+ * BASE_ADDR:   A variable of type addr_t specifying the base address of the

+ *              peripheral containing the register.

+ * REG_NAME:    A string identifying the register to write. These strings are

+ *              specified in a header file associated with the peripheral.

+ * VALUE:       A variable of type uint32_t containing the value to write.

+ */

+#define HAL_set_32bit_reg(BASE_ADDR, REG_NAME, VALUE) \

+          (HW_set_32bit_reg( ((BASE_ADDR) + (REG_NAME##_REG_OFFSET)), (VALUE) ))

+

+/***************************************************************************//**

+ * The macro HAL_get_32bit_reg() is used to read the value  of a 32 bits wide

+ * register.

+ * 

+ * BASE_ADDR:   A variable of type addr_t specifying the base address of the

+ *              peripheral containing the register.

+ * REG_NAME:    A string identifying the register to read. These strings are

+ *              specified in a header file associated with the peripheral.

+ * RETURN:      This function-like macro returns a uint32_t value.

+ */

+#define HAL_get_32bit_reg(BASE_ADDR, REG_NAME) \

+          (HW_get_32bit_reg( ((BASE_ADDR) + (REG_NAME##_REG_OFFSET)) ))

+

+/***************************************************************************//**

+ * The macro HAL_set_32bit_reg_field() is used to write a field within a

+ * 32 bits wide register. The field written can be one or more bits.

+ * 

+ * BASE_ADDR:   A variable of type addr_t specifying the base address of the

+ *              peripheral containing the register.

+ * FIELD_NAME:  A string identifying the register field to write. These strings

+ *              are specified in a header file associated with the peripheral.

+ * VALUE:       A variable of type uint32_t containing the field value to write.

+ */

+#define HAL_set_32bit_reg_field(BASE_ADDR, FIELD_NAME, VALUE) \

+            (HW_set_32bit_reg_field(\

+                (BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\

+                FIELD_SHIFT(FIELD_NAME),\

+                FIELD_MASK(FIELD_NAME),\

+                (VALUE)))

+  

+/***************************************************************************//**

+ * The macro HAL_get_32bit_reg_field() is used to read a register field from

+ * within a 32 bit wide peripheral register. The field can be one or more bits.

+ * 

+ * BASE_ADDR:   A variable of type addr_t specifying the base address of the

+ *              peripheral containing the register.

+ * FIELD_NAME:  A string identifying the register field to write. These strings

+ *              are specified in a header file associated with the peripheral.

+ * RETURN:      This function-like macro returns a uint32_t value.

+ */

+#define HAL_get_32bit_reg_field(BASE_ADDR, FIELD_NAME) \

+            (HW_get_32bit_reg_field(\

+                (BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\

+                FIELD_SHIFT(FIELD_NAME),\

+                FIELD_MASK(FIELD_NAME)))

+  

+/***************************************************************************//**

+ * The macro HAL_set_16bit_reg() allows writing a 16 bits wide register.

+ *

+ * BASE_ADDR:   A variable of type addr_t specifying the base address of the

+ *              peripheral containing the register.

+ * REG_NAME:    A string identifying the register to write. These strings are

+ *              specified in a header file associated with the peripheral.

+ * VALUE:       A variable of type uint_fast16_t containing the value to write.

+ */

+#define HAL_set_16bit_reg(BASE_ADDR, REG_NAME, VALUE) \

+            (HW_set_16bit_reg( ((BASE_ADDR) + (REG_NAME##_REG_OFFSET)), (VALUE) ))

+

+/***************************************************************************//**

+ * The macro HAL_get_16bit_reg() is used to read the value  of a 16 bits wide

+ * register.

+ * 

+ * BASE_ADDR:   A variable of type addr_t specifying the base address of the

+ *              peripheral containing the register.

+ * REG_NAME:    A string identifying the register to read. These strings are

+ *              specified in a header file associated with the peripheral.

+ * RETURN:      This function-like macro returns a uint16_t value.

+ */

+#define HAL_get_16bit_reg(BASE_ADDR, REG_NAME) \

+            (HW_get_16bit_reg( (BASE_ADDR) + (REG_NAME##_REG_OFFSET) ))

+

+/***************************************************************************//**

+ * The macro HAL_set_16bit_reg_field() is used to write a field within a

+ * 16 bits wide register. The field written can be one or more bits.

+ * 

+ * BASE_ADDR:   A variable of type addr_t specifying the base address of the

+ *              peripheral containing the register.

+ * FIELD_NAME:  A string identifying the register field to write. These strings

+ *              are specified in a header file associated with the peripheral.

+ * VALUE:       A variable of type uint16_t containing the field value to write.

+ */

+#define HAL_set_16bit_reg_field(BASE_ADDR, FIELD_NAME, VALUE) \

+            (HW_set_16bit_reg_field(\

+                (BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\

+                FIELD_SHIFT(FIELD_NAME),\

+                FIELD_MASK(FIELD_NAME),\

+                (VALUE)))  

+

+/***************************************************************************//**

+ * The macro HAL_get_16bit_reg_field() is used to read a register field from

+ * within a 8 bit wide peripheral register. The field can be one or more bits.

+ * 

+ * BASE_ADDR:   A variable of type addr_t specifying the base address of the

+ *              peripheral containing the register.

+ * FIELD_NAME:  A string identifying the register field to write. These strings

+ *              are specified in a header file associated with the peripheral.

+ * RETURN:      This function-like macro returns a uint16_t value.

+ */

+#define HAL_get_16bit_reg_field(BASE_ADDR, FIELD_NAME) \

+            (HW_get_16bit_reg_field(\

+                (BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\

+                FIELD_SHIFT(FIELD_NAME),\

+                FIELD_MASK(FIELD_NAME)))

+

+/***************************************************************************//**

+ * The macro HAL_set_8bit_reg() allows writing a 8 bits wide register.

+ *

+ * BASE_ADDR:   A variable of type addr_t specifying the base address of the

+ *              peripheral containing the register.

+ * REG_NAME:    A string identifying the register to write. These strings are

+ *              specified in a header file associated with the peripheral.

+ * VALUE:       A variable of type uint_fast8_t containing the value to write.

+ */

+#define HAL_set_8bit_reg(BASE_ADDR, REG_NAME, VALUE) \

+          (HW_set_8bit_reg( ((BASE_ADDR) + (REG_NAME##_REG_OFFSET)), (VALUE) ))

+

+/***************************************************************************//**

+ * The macro HAL_get_8bit_reg() is used to read the value of a 8 bits wide

+ * register.

+ * 

+ * BASE_ADDR:   A variable of type addr_t specifying the base address of the

+ *              peripheral containing the register.

+ * REG_NAME:    A string identifying the register to read. These strings are

+ *              specified in a header file associated with the peripheral.

+ * RETURN:      This function-like macro returns a uint8_t value.

+ */

+#define HAL_get_8bit_reg(BASE_ADDR, REG_NAME) \

+          (HW_get_8bit_reg( (BASE_ADDR) + (REG_NAME##_REG_OFFSET) ))

+

+/***************************************************************************//**

+ */

+#define HAL_set_8bit_reg_field(BASE_ADDR, FIELD_NAME, VALUE) \

+            (HW_set_8bit_reg_field(\

+                (BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\

+                FIELD_SHIFT(FIELD_NAME),\

+                FIELD_MASK(FIELD_NAME),\

+                (VALUE)))

+

+/***************************************************************************//**

+ * The macro HAL_get_8bit_reg_field() is used to read a register field from

+ * within a 8 bit wide peripheral register. The field can be one or more bits.

+ * 

+ * BASE_ADDR:   A variable of type addr_t specifying the base address of the

+ *              peripheral containing the register.

+ * FIELD_NAME:  A string identifying the register field to write. These strings

+ *              are specified in a header file associated with the peripheral.

+ * RETURN:      This function-like macro returns a uint8_t value.

+ */

+#define HAL_get_8bit_reg_field(BASE_ADDR, FIELD_NAME) \

+            (HW_get_8bit_reg_field(\

+                (BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\

+                FIELD_SHIFT(FIELD_NAME),\

+                FIELD_MASK(FIELD_NAME)))

+  

+#endif /*HAL_H_*/

+

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/hal/hal_assert.h b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/hal/hal_assert.h
new file mode 100644
index 0000000..db8ab77
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/hal/hal_assert.h
@@ -0,0 +1,29 @@
+/*******************************************************************************

+ * (c) Copyright 2008-2018 Microsemi SoC Products Group. All rights reserved.

+ * 

+ * SVN $Revision: 9661 $

+ * SVN $Date: 2018-01-15 16:13:33 +0530 (Mon, 15 Jan 2018) $

+ */

+#ifndef HAL_ASSERT_HEADER

+#define HAL_ASSERT_HEADER

+

+#define NDEBUG 1

+

+#if defined(NDEBUG)

+/***************************************************************************//**

+ * HAL_ASSERT() is defined out when the NDEBUG symbol is used.

+ ******************************************************************************/

+#define HAL_ASSERT(CHECK)

+

+#else

+/***************************************************************************//**

+ * Default behaviour for HAL_ASSERT() macro:

+ *------------------------------------------------------------------------------

+  The behaviour is toolchain specific and project setting specific.

+ ******************************************************************************/

+#define HAL_ASSERT(CHECK)     ASSERT(CHECK);

+

+#endif  /* NDEBUG */

+

+#endif  /* HAL_ASSERT_HEADER */

+

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/hal/hal_irq.c b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/hal/hal_irq.c
new file mode 100644
index 0000000..52f6301
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/hal/hal_irq.c
@@ -0,0 +1,36 @@
+/***************************************************************************//**

+ * (c) Copyright 2007-2018 Microsemi SoC Products Group. All rights reserved.

+ * 

+ * Legacy interrupt control functions for the Microsemi driver library hardware

+ * abstraction layer.

+ *

+ * SVN $Revision: 9661 $

+ * SVN $Date: 2018-01-15 16:13:33 +0530 (Mon, 15 Jan 2018) $

+ */

+#include "hal.h"

+#include "riscv_hal.h"

+

+/*------------------------------------------------------------------------------

+ * 

+ */

+void HAL_enable_interrupts(void) {

+    __enable_irq();

+}

+

+/*------------------------------------------------------------------------------

+ * 

+ */

+psr_t HAL_disable_interrupts(void) {

+    psr_t psr;

+    psr = read_csr(mstatus);

+    __disable_irq();

+    return(psr);

+}

+

+/*------------------------------------------------------------------------------

+ * 

+ */

+void HAL_restore_interrupts(psr_t saved_psr) {

+    write_csr(mstatus, saved_psr);

+}

+

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/hal/hw_macros.h b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/hal/hw_macros.h
new file mode 100644
index 0000000..2149544
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/hal/hw_macros.h
@@ -0,0 +1,97 @@
+/*******************************************************************************

+ * (c) Copyright 2007-2018 Microsemi SoC Products Group. All rights reserved.

+ * 

+ *  Hardware registers access macros.

+ * 

+ *  THE MACROS DEFINED IN THIS FILE ARE DEPRECATED. DO NOT USED FOR NEW 

+ *  DEVELOPMENT.

+ *

+ * These macros are used to access peripheral's registers. They allow access to

+ * 8, 16 and 32 bit wide registers. All accesses to peripheral registers should

+ * be done through these macros in order to ease porting across different 

+ * processors/bus architectures.

+ * 

+ * Some of these macros also allow to access a specific register field.

+ * 

+ * SVN $Revision: 9661 $

+ * SVN $Date: 2018-01-15 16:13:33 +0530 (Mon, 15 Jan 2018) $

+ */

+#ifndef __HW_REGISTER_MACROS_H

+#define __HW_REGISTER_MACROS_H 1

+

+/*------------------------------------------------------------------------------

+ * 32 bits registers access:

+ */

+#define HW_get_uint32_reg(BASE_ADDR, REG_OFFSET) (*((uint32_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)))

+

+#define HW_set_uint32_reg(BASE_ADDR, REG_OFFSET, VALUE) (*((uint32_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)) = (VALUE))

+

+#define HW_set_uint32_reg_field(BASE_ADDR, FIELD, VALUE) \

+            (*((uint32_t volatile *)(BASE_ADDR + FIELD##_OFFSET)) =  \

+                ( \

+                    (uint32_t) \

+                    ( \

+                    (*((uint32_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & ~FIELD##_MASK) | \

+                    (uint32_t)(((VALUE) << FIELD##_SHIFT) & FIELD##_MASK) \

+                ) \

+            )

+

+#define HW_get_uint32_reg_field( BASE_ADDR, FIELD ) \

+            (( (*((uint32_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & FIELD##_MASK) >> FIELD##_SHIFT)

+

+/*------------------------------------------------------------------------------

+ * 32 bits memory access:

+ */

+#define HW_get_uint32(BASE_ADDR) (*((uint32_t volatile *)(BASE_ADDR)))

+

+#define HW_set_uint32(BASE_ADDR, VALUE) (*((uint32_t volatile *)(BASE_ADDR)) = (VALUE))

+

+/*------------------------------------------------------------------------------

+ * 16 bits registers access:

+ */

+#define HW_get_uint16_reg(BASE_ADDR, REG_OFFSET) (*((uint16_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)))

+

+#define HW_set_uint16_reg(BASE_ADDR, REG_OFFSET, VALUE) (*((uint16_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)) = (VALUE))

+

+#define HW_set_uint16_reg_field(BASE_ADDR, FIELD, VALUE) \

+            (*((uint16_t volatile *)(BASE_ADDR + FIELD##_OFFSET)) =  \

+                ( \

+                    (uint16_t) \

+                    ( \

+                    (*((uint16_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & ~FIELD##_MASK) | \

+                    (uint16_t)(((VALUE) << FIELD##_SHIFT) & FIELD##_MASK) \

+                ) \

+            )

+

+#define HW_get_uint16_reg_field( BASE_ADDR, FIELD ) \

+            (( (*((uint16_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & FIELD##_MASK) >> FIELD##_SHIFT)

+

+/*------------------------------------------------------------------------------

+ * 8 bits registers access:

+ */

+#define HW_get_uint8_reg(BASE_ADDR, REG_OFFSET) (*((uint8_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)))

+

+#define HW_set_uint8_reg(BASE_ADDR, REG_OFFSET, VALUE) (*((uint8_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)) = (VALUE))

+ 

+#define HW_set_uint8_reg_field(BASE_ADDR, FIELD, VALUE) \

+            (*((uint8_t volatile *)(BASE_ADDR + FIELD##_OFFSET)) =  \

+                ( \

+                    (uint8_t) \

+                    ( \

+                    (*((uint8_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & ~FIELD##_MASK) | \

+                    (uint8_t)(((VALUE) << FIELD##_SHIFT) & FIELD##_MASK) \

+                ) \

+            )

+

+#define HW_get_uint8_reg_field( BASE_ADDR, FIELD ) \

+            (( (*((uint8_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & FIELD##_MASK) >> FIELD##_SHIFT)

+

+/*------------------------------------------------------------------------------

+ * 8 bits memory access:

+ */

+#define HW_get_uint8(BASE_ADDR) (*((uint8_t volatile *)(BASE_ADDR)))

+

+#define HW_set_uint8(BASE_ADDR, VALUE) (*((uint8_t volatile *)(BASE_ADDR)) = (VALUE))

+ 

+#endif  /* __HW_REGISTER_MACROS_H */

+

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/hal/hw_reg_access.S b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/hal/hw_reg_access.S
new file mode 100644
index 0000000..68d93dd
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/hal/hw_reg_access.S
@@ -0,0 +1,209 @@
+/***************************************************************************//**

+ * (c) Copyright 2007-2018 Microsemi SoC Products Group. All rights reserved.

+ *

+ * Hardware registers access functions.

+ * The implementation of these function is platform and toolchain specific.

+ * The functions declared here are implemented using assembler as part of the

+ * processor/toolchain specific HAL.

+ *

+ * SVN $Revision: 9661 $

+ * SVN $Date: 2018-01-15 16:13:33 +0530 (Mon, 15 Jan 2018) $

+ */

+

+.section .text

+    .globl HW_set_32bit_reg

+    .globl HW_get_32bit_reg

+    .globl HW_set_32bit_reg_field

+    .globl HW_get_32bit_reg_field

+    .globl HW_set_16bit_reg

+    .globl HW_get_16bit_reg

+    .globl HW_set_16bit_reg_field

+    .globl HW_get_16bit_reg_field

+    .globl HW_set_8bit_reg

+    .globl HW_get_8bit_reg

+    .globl HW_set_8bit_reg_field

+    .globl HW_get_8bit_reg_field

+

+

+/***************************************************************************//**

+ * HW_set_32bit_reg is used to write the content of a 32 bits wide peripheral

+ * register.

+ *

+ * a0:   addr_t reg_addr

+ * a1:   uint32_t value

+ */

+HW_set_32bit_reg:

+    sw a1, 0(a0)

+    ret

+

+/***************************************************************************//**

+ * HW_get_32bit_reg is used to read the content of a 32 bits wide peripheral

+ * register.

+ *

+ * R0:   addr_t reg_addr

+ * @return          32 bits value read from the peripheral register.

+ */

+HW_get_32bit_reg:

+    lw a0, 0(a0)

+    ret

+

+/***************************************************************************//**

+ * HW_set_32bit_reg_field is used to set the content of a field in a 32 bits

+ * wide peripheral register.

+ *

+ * a0:   addr_t reg_addr

+ * a1:   int_fast8_t shift

+ * a2:   uint32_t mask

+ * a3:   uint32_t value

+ */

+HW_set_32bit_reg_field:

+    mv t3, a3

+    sll t3, t3, a1

+    and  t3, t3, a2

+    lw t1, 0(a0)

+    mv t2, a2

+    not t2, t2

+    and t1, t1, t2

+    or t1, t1, t3

+    sw t1, 0(a0)

+    ret

+

+/***************************************************************************//**

+ * HW_get_32bit_reg_field is used to read the content of a field out of a

+ * 32 bits wide peripheral register.

+ *

+ * a0:   addr_t reg_addr

+ * a1:   int_fast8_t shift

+ * a2:   uint32_t mask

+ *

+ * @return          32 bits value containing the register field value specified

+ *                  as parameter.

+ */

+HW_get_32bit_reg_field:

+    lw a0, 0(a0)

+    and a0, a0, a2

+    srl a0, a0, a1

+    ret

+

+/***************************************************************************//**

+ * HW_set_16bit_reg is used to write the content of a 16 bits wide peripheral

+ * register.

+ *

+ * a0:   addr_t reg_addr

+ * a1:   uint_fast16_t value

+ */

+HW_set_16bit_reg:

+    sh a1, 0(a0)

+    ret

+

+/***************************************************************************//**

+ * HW_get_16bit_reg is used to read the content of a 16 bits wide peripheral

+ * register.

+ *

+ * a0:   addr_t reg_addr

+ * @return          16 bits value read from the peripheral register.

+ */

+HW_get_16bit_reg:

+    lh a0, (a0)

+    ret

+

+/***************************************************************************//**

+ * HW_set_16bit_reg_field is used to set the content of a field in a 16 bits

+ * wide peripheral register.

+ *

+ * a0:   addr_t reg_addr

+ * a1:   int_fast8_t shift

+ * a2:   uint_fast16_t mask

+ * a3:   uint_fast16_t value

+ * @param value     Value to be written in the specified field.

+ */

+HW_set_16bit_reg_field:

+    mv t3, a3

+    sll t3, t3, a1

+    and  t3, t3, a2

+    lh t1, 0(a0)

+    mv t2, a2

+    not t2, t2

+    and t1, t1, t2

+    or t1, t1, t3

+    sh t1, 0(a0)

+    ret

+

+/***************************************************************************//**

+ * HW_get_16bit_reg_field is used to read the content of a field from a

+ * 16 bits wide peripheral register.

+ *

+ * a0:   addr_t reg_addr

+ * a1:   int_fast8_t shift

+ * a2:   uint_fast16_t mask

+ *

+ * @return          16 bits value containing the register field value specified

+ *                  as parameter.

+ */

+HW_get_16bit_reg_field:

+    lh a0, 0(a0)

+    and a0, a0, a2

+    srl a0, a0, a1

+    ret

+

+/***************************************************************************//**

+ * HW_set_8bit_reg is used to write the content of a 8 bits wide peripheral

+ * register.

+ *

+ * a0:   addr_t reg_addr

+ * a1:   uint_fast8_t value

+ */

+HW_set_8bit_reg:

+    sb a1, 0(a0)

+    ret

+

+/***************************************************************************//**

+ * HW_get_8bit_reg is used to read the content of a 8 bits wide peripheral

+ * register.

+ *

+ * a0:   addr_t reg_addr

+ * @return          8 bits value read from the peripheral register.

+ */

+HW_get_8bit_reg:

+    lb a0, 0(a0)

+    ret

+

+/***************************************************************************//**

+ * HW_set_8bit_reg_field is used to set the content of a field in a 8 bits

+ * wide peripheral register.

+ *

+ * a0:   addr_t reg_addr,

+ * a1:   int_fast8_t shift

+ * a2:   uint_fast8_t mask

+ * a3:   uint_fast8_t value

+ */

+HW_set_8bit_reg_field:

+    mv t3, a3

+    sll t3, t3, a1

+    and  t3, t3, a2

+    lb t1, 0(a0)

+    mv t2, a2

+    not t2, t2

+    and t1, t1, t2

+    or t1, t1, t3

+    sb t1, 0(a0)

+    ret

+

+/***************************************************************************//**

+ * HW_get_8bit_reg_field is used to read the content of a field from a

+ * 8 bits wide peripheral register.

+ *

+ * a0:   addr_t reg_addr

+ * a1:   int_fast8_t shift

+ * a2:   uint_fast8_t mask

+ *

+ * @return          8 bits value containing the register field value specified

+ *                  as parameter.

+ */

+HW_get_8bit_reg_field:

+    lb a0, 0(a0)

+    and a0, a0, a2

+    srl a0, a0, a1

+    ret

+

+.end

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/hal/hw_reg_access.h b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/hal/hw_reg_access.h
new file mode 100644
index 0000000..bc3dd65
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/hal/hw_reg_access.h
@@ -0,0 +1,229 @@
+/***************************************************************************//**

+ * (c) Copyright 2007-2018 Microsemi SoC Products Group. All rights reserved.

+ * 

+ * Hardware registers access functions.

+ * The implementation of these function is platform and toolchain specific.

+ * The functions declared here are implemented using assembler as part of the 

+ * processor/toolchain specific HAL.

+ * 

+ * SVN $Revision: 9661 $

+ * SVN $Date: 2018-01-15 16:13:33 +0530 (Mon, 15 Jan 2018) $

+ */

+#ifndef HW_REG_ACCESS

+#define HW_REG_ACCESS

+

+#include "cpu_types.h"

+/***************************************************************************//**

+ * HW_set_32bit_reg is used to write the content of a 32 bits wide peripheral

+ * register.

+ * 

+ * @param reg_addr  Address in the processor's memory map of the register to

+ *                  write.

+ * @param value     Value to be written into the peripheral register.

+ */

+void

+HW_set_32bit_reg

+(

+    addr_t reg_addr,

+    uint32_t value

+);

+

+/***************************************************************************//**

+ * HW_get_32bit_reg is used to read the content of a 32 bits wide peripheral

+ * register.

+ * 

+ * @param reg_addr  Address in the processor's memory map of the register to

+ *                  read.

+ * @return          32 bits value read from the peripheral register.

+ */

+uint32_t

+HW_get_32bit_reg

+(

+    addr_t reg_addr

+);

+

+/***************************************************************************//**

+ * HW_set_32bit_reg_field is used to set the content of a field in a 32 bits 

+ * wide peripheral register.

+ * 

+ * @param reg_addr  Address in the processor's memory map of the register to

+ *                  be written.

+ * @param shift     Bit offset of the register field to be read within the 

+ *                  register.

+ * @param mask      Bit mask to be applied to the raw register value to filter

+ *                  out the other register fields values.

+ * @param value     Value to be written in the specified field.

+ */

+void

+HW_set_32bit_reg_field

+(

+    addr_t reg_addr,

+    int_fast8_t shift,

+    uint32_t mask,

+    uint32_t value

+);

+

+/***************************************************************************//**

+ * HW_get_32bit_reg_field is used to read the content of a field out of a 

+ * 32 bits wide peripheral register.

+ * 

+ * @param reg_addr  Address in the processor's memory map of the register to

+ *                  read.

+ * @param shift     Bit offset of the register field to be written within the 

+ *                  register.

+ * @param mask      Bit mask to be applied to the raw register value to filter

+ *                  out the other register fields values.

+ *

+ * @return          32 bits value containing the register field value specified

+ *                  as parameter.

+ */

+uint32_t 

+HW_get_32bit_reg_field

+(

+    addr_t reg_addr,

+    int_fast8_t shift,

+    uint32_t mask

+);

+

+/***************************************************************************//**

+ * HW_set_16bit_reg is used to write the content of a 16 bits wide peripheral

+ * register.

+ * 

+ * @param reg_addr  Address in the processor's memory map of the register to

+ *                  write.

+ * @param value     Value to be written into the peripheral register.

+ */

+void

+HW_set_16bit_reg

+(

+    addr_t reg_addr,

+    uint_fast16_t value

+);

+

+/***************************************************************************//**

+ * HW_get_16bit_reg is used to read the content of a 16 bits wide peripheral

+ * register.

+ * 

+ * @param reg_addr  Address in the processor's memory map of the register to

+ *                  read.

+ * @return          16 bits value read from the peripheral register.

+ */

+uint16_t

+HW_get_16bit_reg

+(

+    addr_t reg_addr

+);

+

+/***************************************************************************//**

+ * HW_set_16bit_reg_field is used to set the content of a field in a 16 bits 

+ * wide peripheral register.

+ * 

+ * @param reg_addr  Address in the processor's memory map of the register to

+ *                  be written.

+ * @param shift     Bit offset of the register field to be read within the 

+ *                  register.

+ * @param mask      Bit mask to be applied to the raw register value to filter

+ *                  out the other register fields values.

+ * @param value     Value to be written in the specified field.

+ */

+void HW_set_16bit_reg_field

+(

+    addr_t reg_addr,

+    int_fast8_t shift,

+    uint_fast16_t mask,

+    uint_fast16_t value

+);

+

+/***************************************************************************//**

+ * HW_get_16bit_reg_field is used to read the content of a field from a 

+ * 16 bits wide peripheral register.

+ * 

+ * @param reg_addr  Address in the processor's memory map of the register to

+ *                  read.

+ * @param shift     Bit offset of the register field to be written within the 

+ *                  register.

+ * @param mask      Bit mask to be applied to the raw register value to filter

+ *                  out the other register fields values.

+ *

+ * @return          16 bits value containing the register field value specified

+ *                  as parameter.

+ */

+uint16_t HW_get_16bit_reg_field

+(

+    addr_t reg_addr,

+    int_fast8_t shift,

+    uint_fast16_t mask

+);

+

+/***************************************************************************//**

+ * HW_set_8bit_reg is used to write the content of a 8 bits wide peripheral

+ * register.

+ * 

+ * @param reg_addr  Address in the processor's memory map of the register to

+ *                  write.

+ * @param value     Value to be written into the peripheral register.

+ */

+void

+HW_set_8bit_reg

+(

+    addr_t reg_addr,

+    uint_fast8_t value

+);

+

+/***************************************************************************//**

+ * HW_get_8bit_reg is used to read the content of a 8 bits wide peripheral

+ * register.

+ * 

+ * @param reg_addr  Address in the processor's memory map of the register to

+ *                  read.

+ * @return          8 bits value read from the peripheral register.

+ */

+uint8_t

+HW_get_8bit_reg

+(

+    addr_t reg_addr

+);

+

+/***************************************************************************//**

+ * HW_set_8bit_reg_field is used to set the content of a field in a 8 bits 

+ * wide peripheral register.

+ * 

+ * @param reg_addr  Address in the processor's memory map of the register to

+ *                  be written.

+ * @param shift     Bit offset of the register field to be read within the 

+ *                  register.

+ * @param mask      Bit mask to be applied to the raw register value to filter

+ *                  out the other register fields values.

+ * @param value     Value to be written in the specified field.

+ */

+void HW_set_8bit_reg_field

+(

+    addr_t reg_addr,

+    int_fast8_t shift,

+    uint_fast8_t mask,

+    uint_fast8_t value

+);

+

+/***************************************************************************//**

+ * HW_get_8bit_reg_field is used to read the content of a field from a 

+ * 8 bits wide peripheral register.

+ * 

+ * @param reg_addr  Address in the processor's memory map of the register to

+ *                  read.

+ * @param shift     Bit offset of the register field to be written within the 

+ *                  register.

+ * @param mask      Bit mask to be applied to the raw register value to filter

+ *                  out the other register fields values.

+ *

+ * @return          8 bits value containing the register field value specified

+ *                  as parameter.

+ */

+uint8_t HW_get_8bit_reg_field

+(

+    addr_t reg_addr,

+    int_fast8_t shift,

+    uint_fast8_t mask

+);

+

+#endif /* HW_REG_ACCESS */

+

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/hw_platform.h b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/hw_platform.h
new file mode 100644
index 0000000..268eba6
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/hw_platform.h
@@ -0,0 +1,119 @@
+/*******************************************************************************

+ * (c) Copyright 2016-2017 Microsemi Corporation.  All rights reserved.

+ *

+ * Platform definitions

+ * Version based on requirements of RISCV-HAL

+ *

+ * SVN $Revision: 9587 $

+ * SVN $Date: 2017-11-16 12:53:31 +0530 (Thu, 16 Nov 2017) $

+ */

+ /*=========================================================================*//**

+  @mainpage Sample file detailing how hw_platform.h should be constructed for 

+    the Mi-V processors.

+

+    @section intro_sec Introduction

+    The hw_platform.h is to be located in the project root directory.

+    Currently this file must be hand crafted when using the Mi-V Soft Processor.

+    

+    You can use this file as sample.

+    Rename this file from sample_hw_platform.h to hw_platform.h and store it in

+    the root folder of your project. Then customize it per your HW design.

+

+    @section driver_configuration Project configuration Instructions

+    1. Change SYS_CLK_FREQ define to frequency of Mi-V Soft processor clock

+    2  Add all other core BASE addresses

+    3. Add peripheral Core Interrupt to Mi-V Soft processor interrupt mappings

+    4. Define MSCC_STDIO_UART_BASE_ADDR if you want a CoreUARTapb mapped to STDIO

+*//*=========================================================================*/

+

+#ifndef HW_PLATFORM_H

+#define HW_PLATFORM_H

+

+/***************************************************************************//**

+ * Soft-processor clock definition

+ * This is the only clock brought over from the Mi-V Soft processor Libero design.

+ */

+#ifndef SYS_CLK_FREQ

+#define SYS_CLK_FREQ                    83000000UL

+#endif

+

+/***************************************************************************//**

+ * Non-memory Peripheral base addresses

+ * Format of define is:

+ * <corename>_<instance>_BASE_ADDR

+ */

+#define COREUARTAPB0_BASE_ADDR          0x70001000UL

+#define COREGPIO_IN_BASE_ADDR           0x70002000UL

+#define CORETIMER0_BASE_ADDR            0x70003000UL

+#define CORETIMER1_BASE_ADDR            0x70004000UL

+#define COREGPIO_OUT_BASE_ADDR          0x70005000UL

+#define FLASH_CORE_SPI_BASE             0x70006000UL

+#define CORE16550_BASE_ADDR             0x70007000UL

+

+/***************************************************************************//**

+ * Peripheral Interrupts are mapped to the corresponding Mi-V Soft processor

+ * interrupt from the Libero design.

+ * There can be up to 31 external interrupts (IRQ[30:0] pins) on the Mi-V Soft

+ * processor.The Mi-V Soft processor external interrupts are defined in the

+ * riscv_plic.h

+ * These are of the form

+ * typedef enum

+{

+    NoInterrupt_IRQn = 0,

+    External_1_IRQn  = 1,

+    External_2_IRQn  = 2,

+    .

+    .

+    .

+    External_31_IRQn = 31

+} IRQn_Type;

+ 

+ The interrupt 0 on RISC-V processor is not used. The pin IRQ[0] should map to

+ External_1_IRQn likewise IRQ[30] should map to External_31_IRQn

+ * Format of define is:

+ * <corename>_<instance>_<core interrupt name>

+ */

+

+#define TIMER0_IRQn                     External_30_IRQn

+#define TIMER1_IRQn                     External_31_IRQn

+

+/****************************************************************************

+ * Baud value to achieve a 115200 baud rate with a 83MHz system clock.

+ * This value is calculated using the following equation:

+ *      BAUD_VALUE = (CLOCK / (16 * BAUD_RATE)) - 1

+ *****************************************************************************/

+#define BAUD_VALUE_115200               (SYS_CLK_FREQ / (16 * 115200)) - 1

+

+/***************************************************************************//**

+ * User edit section- Edit sections below if required

+ */

+#ifdef MSCC_STDIO_THRU_CORE_UART_APB

+/*

+ * A base address mapping for the STDIO printf/scanf mapping to CortUARTapb

+ * must be provided if it is being used

+ *

+ * e.g. #define MSCC_STDIO_UART_BASE_ADDR COREUARTAPB1_BASE_ADDR

+ */

+#define MSCC_STDIO_UART_BASE_ADDR COREUARTAPB0_BASE_ADDR

+

+#ifndef MSCC_STDIO_UART_BASE_ADDR

+#error MSCC_STDIO_UART_BASE_ADDR not defined- e.g. #define MSCC_STDIO_UART_BASE_ADDR COREUARTAPB1_BASE_ADDR

+#endif

+

+#ifndef MSCC_STDIO_BAUD_VALUE

+/*

+ * The MSCC_STDIO_BAUD_VALUE define should be set in your project's settings to

+ * specify the baud value used by the standard output CoreUARTapb instance for

+ * generating the UART's baud rate if you want a different baud rate from the

+ * default of 115200 baud

+ */

+#define MSCC_STDIO_BAUD_VALUE           115200

+#endif  /*MSCC_STDIO_BAUD_VALUE*/

+

+#endif  /* end of MSCC_STDIO_THRU_CORE_UART_APB */

+/*******************************************************************************

+ * End of user edit section

+ */

+#endif /* HW_PLATFORM_H */

+

+

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/main.c b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/main.c
new file mode 100644
index 0000000..4ec3a71
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/main.c
@@ -0,0 +1,136 @@
+#include "FreeRTOS.h"

+#include "task.h"

+#include "queue.h"

+#include "timers.h"

+

+#include "hw_platform.h"

+#include "core_uart_apb.h"

+#include "task.h"

+

+const char * g_hello_msg = "\r\nFreeRTOS Example\r\n";

+

+

+/* A block time of zero simply means "don't block". */

+#define mainDONT_BLOCK						( 0UL )

+

+/******************************************************************************

+ * CoreUARTapb instance data.

+ *****************************************************************************/

+UART_instance_t g_uart;

+/*-----------------------------------------------------------*/

+

+static void vUartTestTask1( void *pvParameters );

+static void vUartTestTask2( void *pvParameters );

+

+/*

+ * FreeRTOS hook for when malloc fails, enable in FreeRTOSConfig.

+ */

+void vApplicationMallocFailedHook( void );

+

+/*

+ * FreeRTOS hook for when FreeRtos is idling, enable in FreeRTOSConfig.

+ */

+void vApplicationIdleHook( void );

+

+/*

+ * FreeRTOS hook for when a stack overflow occurs, enable in FreeRTOSConfig.

+ */

+void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName );

+

+/*-----------------------------------------------------------*/

+

+int main( void )

+{

+    PLIC_init();

+

+    /**************************************************************************

+    * Initialize CoreUART with its base address, baud value, and line

+    * configuration.

+    *************************************************************************/

+    UART_init(&g_uart, COREUARTAPB0_BASE_ADDR, BAUD_VALUE_115200,

+             (DATA_8_BITS | NO_PARITY) );

+

+    UART_polled_tx_string( &g_uart, (const uint8_t *)"\r\n\r\n		Sample Demonstration of FreeRTOS port for Mi-V processor.\r\n\r\n" );

+    UART_polled_tx_string( &g_uart, (const uint8_t *)"		This project creates  two tasks and runs them at regular intervals.\r\n" );

+

+    /* Create the two test tasks. */

+	xTaskCreate( vUartTestTask1, "UArt1", 1000, NULL, uartPRIMARY_PRIORITY, NULL );

+	xTaskCreate( vUartTestTask2, "UArt2", 1000, NULL, uartPRIMARY_PRIORITY, NULL );

+

+	/* Start the kernel.  From here on, only tasks and interrupts will run. */

+	vTaskStartScheduler();

+

+	/* Exit FreeRTOS */

+	return 0;

+}

+

+/*-----------------------------------------------------------*/

+

+void vApplicationMallocFailedHook( void )

+{

+	/* vApplicationMallocFailedHook() will only be called if

+	configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h.  It is a hook

+	function that will get called if a call to pvPortMalloc() fails.

+	pvPortMalloc() is called internally by the kernel whenever a task, queue,

+	timer or semaphore is created.  It is also called by various parts of the

+	demo application.  If heap_1.c or heap_2.c are used, then the size of the

+	heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in

+	FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used

+	to query the size of free heap space that remains (although it does not

+	provide information on how the remaining heap might be fragmented). */

+	taskDISABLE_INTERRUPTS();

+	for( ;; );

+}

+/*-----------------------------------------------------------*/

+

+void vApplicationIdleHook( void )

+{

+	/* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set

+	to 1 in FreeRTOSConfig.h.  It will be called on each iteration of the idle

+	task.  It is essential that code added to this hook function never attempts

+	to block in any way (for example, call xQueueReceive() with a block time

+	specified, or call vTaskDelay()).  If the application makes use of the

+	vTaskDelete() API function (as this demo application does) then it is also

+	important that vApplicationIdleHook() is permitted to return to its calling

+	function, because it is the responsibility of the idle task to clean up

+	memory allocated by the kernel to any task that has since been deleted. */

+}

+/*-----------------------------------------------------------*/

+

+void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )

+{

+	( void ) pcTaskName;

+	( void ) pxTask;

+

+	/* Run time stack overflow checking is performed if

+	configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2.  This hook

+	function is called if a stack overflow is detected. */

+	taskDISABLE_INTERRUPTS();

+	for( ;; );

+}

+/*-----------------------------------------------------------*/

+

+static void vUartTestTask1( void *pvParameters )

+{

+	( void ) pvParameters;

+

+	for( ;; )

+	{

+		UART_polled_tx_string( &g_uart, (const uint8_t *)"Task - 1\r\n" );

+	    vTaskDelay(10);

+	}

+}

+

+

+/*-----------------------------------------------------------*/

+

+static void vUartTestTask2( void *pvParameters )

+{

+	( void ) pvParameters;

+

+	for( ;; )

+	{

+		UART_polled_tx_string( &g_uart, (const uint8_t *)"Task - 2\r\n" );

+	    vTaskDelay(5);

+	}

+}

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/encoding.h b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/encoding.h
new file mode 100644
index 0000000..aa379ee
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/encoding.h
@@ -0,0 +1,596 @@
+/*******************************************************************************

+ * (c) Copyright 2016-2018 Microsemi SoC Products Group.  All rights reserved.

+ *

+ * @file encodings.h

+ * @author Microsemi SoC Products Group

+ * @brief Mi-V soft processor register bit mask and shift constants encodings.

+ *

+ * SVN $Revision: 9825 $

+ * SVN $Date: 2018-03-19 10:31:41 +0530 (Mon, 19 Mar 2018) $

+ */

+#ifndef RISCV_CSR_ENCODING_H

+#define RISCV_CSR_ENCODING_H

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+#define MSTATUS_UIE         0x00000001

+#define MSTATUS_SIE         0x00000002

+#define MSTATUS_HIE         0x00000004

+#define MSTATUS_MIE         0x00000008

+#define MSTATUS_UPIE        0x00000010

+#define MSTATUS_SPIE        0x00000020

+#define MSTATUS_HPIE        0x00000040

+#define MSTATUS_MPIE        0x00000080

+#define MSTATUS_SPP         0x00000100

+#define MSTATUS_HPP         0x00000600

+#define MSTATUS_MPP         0x00001800

+#define MSTATUS_FS          0x00006000

+#define MSTATUS_XS          0x00018000

+#define MSTATUS_MPRV        0x00020000

+#define MSTATUS_SUM         0x00040000      /*changed in v1.10*/

+#define MSTATUS_MXR         0x00080000      /*changed in v1.10*/

+#define MSTATUS_TVM         0x00100000      /*changed in v1.10*/

+#define MSTATUS_TW          0x00200000      /*changed in v1.10*/

+#define MSTATUS_TSR         0x00400000      /*changed in v1.10*/

+#define MSTATUS_RES         0x7F800000      /*changed in v1.10*/

+#define MSTATUS32_SD        0x80000000

+#define MSTATUS64_SD        0x8000000000000000

+

+#define MCAUSE32_CAUSE       0x7FFFFFFF

+#define MCAUSE64_CAUSE       0x7FFFFFFFFFFFFFFF

+#define MCAUSE32_INT         0x80000000

+#define MCAUSE64_INT         0x8000000000000000

+

+#define SSTATUS_UIE         0x00000001

+#define SSTATUS_SIE         0x00000002

+#define SSTATUS_UPIE        0x00000010

+#define SSTATUS_SPIE        0x00000020

+#define SSTATUS_SPP         0x00000100

+#define SSTATUS_FS          0x00006000

+#define SSTATUS_XS          0x00018000

+#define SSTATUS_PUM         0x00040000

+#define SSTATUS32_SD        0x80000000

+#define SSTATUS64_SD        0x8000000000000000

+

+#define MIP_SSIP            (1u << IRQ_S_SOFT)

+#define MIP_HSIP            (1u << IRQ_H_SOFT)

+#define MIP_MSIP            (1u << IRQ_M_SOFT)

+#define MIP_STIP            (1u << IRQ_S_TIMER)

+#define MIP_HTIP            (1u << IRQ_H_TIMER)

+#define MIP_MTIP            (1u << IRQ_M_TIMER)

+#define MIP_SEIP            (1u << IRQ_S_EXT)

+#define MIP_HEIP            (1u << IRQ_H_EXT)

+#define MIP_MEIP            (1u << IRQ_M_EXT)

+

+#define SIP_SSIP            MIP_SSIP

+#define SIP_STIP            MIP_STIP

+

+#define PRV_U               0

+#define PRV_S               1

+#define PRV_H               2

+#define PRV_M               3

+

+#define VM_MBARE            0

+#define VM_MBB              1

+#define VM_MBBID            2

+#define VM_SV32             8

+#define VM_SV39             9

+#define VM_SV48             10

+

+#define IRQ_S_SOFT          1

+#define IRQ_H_SOFT          2

+#define IRQ_M_SOFT          3

+#define IRQ_S_TIMER         5

+#define IRQ_H_TIMER         6

+#define IRQ_M_TIMER         7

+#define IRQ_S_EXT           9

+#define IRQ_H_EXT           10

+#define IRQ_M_EXT           11

+

+#define DEFAULT_RSTVEC      0x00001000

+#define DEFAULT_NMIVEC      0x00001004

+#define DEFAULT_MTVEC       0x00001010

+#define CONFIG_STRING_ADDR  0x0000100C

+#define EXT_IO_BASE         0x40000000

+#define DRAM_BASE           0x80000000

+

+/* page table entry (PTE) fields */

+#define PTE_V               0x001       /* Valid */

+#define PTE_TYPE            0x01E       /* Type  */

+#define PTE_R               0x020       /* Referenced */

+#define PTE_D               0x040       /* Dirty */

+#define PTE_SOFT            0x380       /* Reserved for Software */

+

+#define PTE_TYPE_TABLE        0x00

+#define PTE_TYPE_TABLE_GLOBAL 0x02

+#define PTE_TYPE_URX_SR       0x04

+#define PTE_TYPE_URWX_SRW     0x06

+#define PTE_TYPE_UR_SR        0x08

+#define PTE_TYPE_URW_SRW      0x0A

+#define PTE_TYPE_URX_SRX      0x0C

+#define PTE_TYPE_URWX_SRWX    0x0E

+#define PTE_TYPE_SR           0x10

+#define PTE_TYPE_SRW          0x12

+#define PTE_TYPE_SRX          0x14

+#define PTE_TYPE_SRWX         0x16

+#define PTE_TYPE_SR_GLOBAL    0x18

+#define PTE_TYPE_SRW_GLOBAL   0x1A

+#define PTE_TYPE_SRX_GLOBAL   0x1C

+#define PTE_TYPE_SRWX_GLOBAL  0x1E

+

+#define PTE_PPN_SHIFT 10

+

+#define PTE_TABLE(PTE) ((0x0000000AU >> ((PTE) & 0x1F)) & 1)

+#define PTE_UR(PTE)    ((0x0000AAA0U >> ((PTE) & 0x1F)) & 1)

+#define PTE_UW(PTE)    ((0x00008880U >> ((PTE) & 0x1F)) & 1)

+#define PTE_UX(PTE)    ((0x0000A0A0U >> ((PTE) & 0x1F)) & 1)

+#define PTE_SR(PTE)    ((0xAAAAAAA0U >> ((PTE) & 0x1F)) & 1)

+#define PTE_SW(PTE)    ((0x88888880U >> ((PTE) & 0x1F)) & 1)

+#define PTE_SX(PTE)    ((0xA0A0A000U >> ((PTE) & 0x1F)) & 1)

+

+#define PTE_CHECK_PERM(PTE, SUPERVISOR, STORE, FETCH) \

+  ((STORE) ? ((SUPERVISOR) ? PTE_SW(PTE) : PTE_UW(PTE)) : \

+   (FETCH) ? ((SUPERVISOR) ? PTE_SX(PTE) : PTE_UX(PTE)) : \

+             ((SUPERVISOR) ? PTE_SR(PTE) : PTE_UR(PTE)))

+

+#ifdef __riscv

+

+#if __riscv_xlen == 64

+# define MSTATUS_SD             MSTATUS64_SD

+# define SSTATUS_SD             SSTATUS64_SD

+# define MCAUSE_INT             MCAUSE64_INT

+# define MCAUSE_CAUSE           MCAUSE64_CAUSE

+# define RISCV_PGLEVEL_BITS     9

+#else

+# define MSTATUS_SD             MSTATUS32_SD

+# define SSTATUS_SD             SSTATUS32_SD

+# define RISCV_PGLEVEL_BITS     10

+# define MCAUSE_INT             MCAUSE32_INT

+# define MCAUSE_CAUSE           MCAUSE32_CAUSE

+#endif

+

+#define RISCV_PGSHIFT           12

+#define RISCV_PGSIZE            (1 << RISCV_PGSHIFT)

+

+#ifndef __ASSEMBLER__

+

+#ifdef __GNUC__

+

+#define read_csr(reg) ({ unsigned long __tmp; \

+  asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \

+  __tmp; })

+

+#define write_csr(reg, val) ({ \

+  if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \

+    asm volatile ("csrw " #reg ", %0" :: "i"(val)); \

+  else \

+    asm volatile ("csrw " #reg ", %0" :: "r"(val)); })

+

+#define swap_csr(reg, val) ({ unsigned long __tmp; \

+  if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \

+    asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "i"(val)); \

+  else \

+    asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "r"(val)); \

+  __tmp; })

+

+#define set_csr(reg, bit) ({ unsigned long __tmp; \

+  if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \

+    asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \

+  else \

+    asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \

+  __tmp; })

+

+#define clear_csr(reg, bit) ({ unsigned long __tmp; \

+  if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \

+    asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \

+  else \

+    asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \

+  __tmp; })

+

+#define rdtime() read_csr(time)

+#define rdcycle() read_csr(cycle)

+#define rdinstret() read_csr(instret)

+

+#ifdef __riscv_atomic

+

+#define MASK(nr)                    (1UL << nr)

+#define MASK_NOT(nr)                (~(1UL << nr))

+

+/**

+ * atomic_read - read atomic variable

+ * @v: pointer of type int

+ *

+ * Atomically reads the value of @v.

+ */

+static inline int atomic_read(const int *v)

+{

+    return *((volatile int *)(v));

+}

+

+/**

+ * atomic_set - set atomic variable

+ * @v: pointer of type int

+ * @i: required value

+ *

+ * Atomically sets the value of @v to @i.

+ */

+static inline void atomic_set(int *v, int i)

+{

+    *v = i;

+}

+

+/**

+ * atomic_add - add integer to atomic variable

+ * @i: integer value to add

+ * @v: pointer of type int

+ *

+ * Atomically adds @i to @v.

+ */

+static inline void atomic_add(int i, int *v)

+{

+    __asm__ __volatile__ (

+        "amoadd.w zero, %1, %0"

+        : "+A" (*v)

+        : "r" (i));

+}

+

+static inline int atomic_fetch_add(unsigned int mask, int *v)

+{

+    int out;

+

+    __asm__ __volatile__ (

+        "amoadd.w %2, %1, %0"

+        : "+A" (*v), "=r" (out)

+        : "r" (mask));

+    return out;

+}

+

+/**

+ * atomic_sub - subtract integer from atomic variable

+ * @i: integer value to subtract

+ * @v: pointer of type int

+ *

+ * Atomically subtracts @i from @v.

+ */

+static inline void atomic_sub(int i, int *v)

+{

+    atomic_add(-i, v);

+}

+

+static inline int atomic_fetch_sub(unsigned int mask, int *v)

+{

+    int out;

+

+    __asm__ __volatile__ (

+        "amosub.w %2, %1, %0"

+        : "+A" (*v), "=r" (out)

+        : "r" (mask));

+    return out;

+}

+

+/**

+ * atomic_add_return - add integer to atomic variable

+ * @i: integer value to add

+ * @v: pointer of type int

+ *

+ * Atomically adds @i to @v and returns the result

+ */

+static inline int atomic_add_return(int i, int *v)

+{

+    register int c;

+    __asm__ __volatile__ (

+        "amoadd.w %0, %2, %1"

+        : "=r" (c), "+A" (*v)

+        : "r" (i));

+    return (c + i);

+}

+

+/**

+ * atomic_sub_return - subtract integer from atomic variable

+ * @i: integer value to subtract

+ * @v: pointer of type int

+ *

+ * Atomically subtracts @i from @v and returns the result

+ */

+static inline int atomic_sub_return(int i, int *v)

+{

+    return atomic_add_return(-i, v);

+}

+

+/**

+ * atomic_inc - increment atomic variable

+ * @v: pointer of type int

+ *

+ * Atomically increments @v by 1.

+ */

+static inline void atomic_inc(int *v)

+{

+    atomic_add(1, v);

+}

+

+/**

+ * atomic_dec - decrement atomic variable

+ * @v: pointer of type int

+ *

+ * Atomically decrements @v by 1.

+ */

+static inline void atomic_dec(int *v)

+{

+    atomic_add(-1, v);

+}

+

+static inline int atomic_inc_return(int *v)

+{

+    return atomic_add_return(1, v);

+}

+

+static inline int atomic_dec_return(int *v)

+{

+    return atomic_sub_return(1, v);

+}

+

+/**

+ * atomic_sub_and_test - subtract value from variable and test result

+ * @i: integer value to subtract

+ * @v: pointer of type int

+ *

+ * Atomically subtracts @i from @v and returns

+ * true if the result is zero, or false for all

+ * other cases.

+ */

+static inline int atomic_sub_and_test(int i, int *v)

+{

+    return (atomic_sub_return(i, v) == 0);

+}

+

+/**

+ * atomic_inc_and_test - increment and test

+ * @v: pointer of type int

+ *

+ * Atomically increments @v by 1

+ * and returns true if the result is zero, or false for all

+ * other cases.

+ */

+static inline int atomic_inc_and_test(int *v)

+{

+    return (atomic_inc_return(v) == 0);

+}

+

+/**

+ * atomic_dec_and_test - decrement and test

+ * @v: pointer of type int

+ *

+ * Atomically decrements @v by 1 and

+ * returns true if the result is 0, or false for all other

+ * cases.

+ */

+static inline int atomic_dec_and_test(int *v)

+{

+    return (atomic_dec_return(v) == 0);

+}

+

+/**

+ * atomic_add_negative - add and test if negative

+ * @i: integer value to add

+ * @v: pointer of type int

+ *

+ * Atomically adds @i to @v and returns true

+ * if the result is negative, or false when

+ * result is greater than or equal to zero.

+ */

+static inline int atomic_add_negative(int i, int *v)

+{

+    return (atomic_add_return(i, v) < 0);

+}

+

+static inline int atomic_xchg(int *v, int n)

+{

+    register int c;

+    __asm__ __volatile__ (

+        "amoswap.w %0, %2, %1"

+        : "=r" (c), "+A" (*v)

+        : "r" (n));

+    return c;

+}

+

+/**

+ * atomic_and - Atomically clear bits in atomic variable

+ * @mask: Mask of the bits to be retained

+ * @v: pointer of type int

+ *

+ * Atomically retains the bits set in @mask from @v

+ */

+static inline void atomic_and(unsigned int mask, int *v)

+{

+    __asm__ __volatile__ (

+        "amoand.w zero, %1, %0"

+        : "+A" (*v)

+        : "r" (mask));

+}

+

+static inline int atomic_fetch_and(unsigned int mask, int *v)

+{

+    int out;

+    __asm__ __volatile__ (

+        "amoand.w %2, %1, %0"

+        : "+A" (*v), "=r" (out)

+        : "r" (mask));

+    return out;

+}

+

+/**

+ * atomic_or - Atomically set bits in atomic variable

+ * @mask: Mask of the bits to be set

+ * @v: pointer of type int

+ *

+ * Atomically sets the bits set in @mask in @v

+ */

+static inline void atomic_or(unsigned int mask, int *v)

+{

+    __asm__ __volatile__ (

+        "amoor.w zero, %1, %0"

+        : "+A" (*v)

+        : "r" (mask));

+}

+

+static inline int atomic_fetch_or(unsigned int mask, int *v)

+{

+    int out;

+    __asm__ __volatile__ (

+        "amoor.w %2, %1, %0"

+        : "+A" (*v), "=r" (out)

+        : "r" (mask));

+    return out;

+}

+

+/**

+ * atomic_xor - Atomically flips bits in atomic variable

+ * @mask: Mask of the bits to be flipped

+ * @v: pointer of type int

+ *

+ * Atomically flips the bits set in @mask in @v

+ */

+static inline void atomic_xor(unsigned int mask, int *v)

+{

+    __asm__ __volatile__ (

+        "amoxor.w zero, %1, %0"

+        : "+A" (*v)

+        : "r" (mask));

+}

+

+static inline int atomic_fetch_xor(unsigned int mask, int *v)

+{

+    int out;

+    __asm__ __volatile__ (

+        "amoxor.w %2, %1, %0"

+        : "+A" (*v), "=r" (out)

+        : "r" (mask));

+    return out;

+}

+

+/*----------------------------------------------------*/

+

+/**

+ * test_and_set_bit - Set a bit and return its old value

+ * @nr: Bit to set

+ * @addr: Address to count from

+ *

+ * This operation is atomic and cannot be reordered.

+ * It also implies a memory barrier.

+ */

+static inline int test_and_set_bit(int nr, volatile unsigned long *addr)

+{

+    unsigned long __res, __mask;

+    __mask = MASK(nr);

+    __asm__ __volatile__ (                \

+        "amoor.w %0, %2, %1"            \

+        : "=r" (__res), "+A" (*addr)    \

+        : "r" (__mask));                \

+

+        return ((__res & __mask) != 0);

+}

+

+

+/**

+ * test_and_clear_bit - Clear a bit and return its old value

+ * @nr: Bit to clear

+ * @addr: Address to count from

+ *

+ * This operation is atomic and cannot be reordered.

+ * It also implies a memory barrier.

+ */

+static inline int test_and_clear_bit(int nr, volatile unsigned long *addr)

+{

+    unsigned long __res, __mask;

+    __mask = MASK_NOT(nr);

+    __asm__ __volatile__ (                \

+        "amoand.w %0, %2, %1"            \

+        : "=r" (__res), "+A" (*addr)    \

+        : "r" (__mask));                \

+

+        return ((__res & __mask) != 0);

+}

+

+/**

+ * test_and_change_bit - Change a bit and return its old value

+ * @nr: Bit to change

+ * @addr: Address to count from

+ *

+ * This operation is atomic and cannot be reordered.

+ * It also implies a memory barrier.

+ */

+static inline int test_and_change_bit(int nr, volatile unsigned long *addr)

+{

+

+    unsigned long __res, __mask;

+    __mask = MASK(nr);

+    __asm__ __volatile__ (                \

+        "amoxor.w %0, %2, %1"            \

+        : "=r" (__res), "+A" (*addr)    \

+        : "r" (__mask));                \

+

+        return ((__res & __mask) != 0);

+}

+

+/**

+ * set_bit - Atomically set a bit in memory

+ * @nr: the bit to set

+ * @addr: the address to start counting from

+ *

+ * This function is atomic and may not be reordered. 

+ */

+

+static inline void set_bit(int nr, volatile unsigned long *addr)

+{

+    __asm__ __volatile__ (                    \

+        "AMOOR.w zero, %1, %0"            \

+        : "+A" (*addr)            \

+        : "r" (MASK(nr)));

+}

+

+/**

+ * clear_bit - Clears a bit in memory

+ * @nr: Bit to clear

+ * @addr: Address to start counting from

+ *

+ * clear_bit() is atomic and may not be reordered.  

+ */

+static inline void clear_bit(int nr, volatile unsigned long *addr)

+{

+    __asm__ __volatile__ (                    \

+        "AMOAND.w zero, %1, %0"            \

+        : "+A" (*addr)            \

+        : "r" (MASK_NOT(nr)));

+}

+

+/**

+ * change_bit - Toggle a bit in memory

+ * @nr: Bit to change

+ * @addr: Address to start counting from

+ *

+ * change_bit() is atomic and may not be reordered.

+ */

+static inline void change_bit(int nr, volatile unsigned long *addr)

+{

+    __asm__ __volatile__ (                    \

+            "AMOXOR.w zero, %1, %0"            \

+            : "+A" (*addr)            \

+            : "r" (MASK(nr)));

+}

+

+#endif /* __riscv_atomic */

+

+#endif  /*__GNUC__*/

+

+#endif  /*__ASSEMBLER__*/

+

+#endif  /*__riscv*/

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif    /*RISCV_CSR_ENCODING_H*/

+

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/entry.S b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/entry.S
new file mode 100644
index 0000000..6e3ef92
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/entry.S
@@ -0,0 +1,160 @@
+/*******************************************************************************

+ * (c) Copyright 2016-2018 Microsemi SoC Products Group.  All rights reserved.

+ *

+ * @file entry.S

+ * @author Microsemi SoC Products Group

+ * @brief Mi-V soft processor vectors, trap handling and startup code.

+ *

+ * SVN $Revision: 9947 $

+ * SVN $Date: 2018-04-30 20:28:49 +0530 (Mon, 30 Apr 2018) $

+ */

+#ifndef ENTRY_S

+#define ENTRY_S

+

+#include "encoding.h"

+

+#if __riscv_xlen == 64

+# define LREG ld

+# define SREG sd

+# define REGBYTES 8

+#else

+# define LREG lw

+# define SREG sw

+# define REGBYTES 4

+#endif

+

+  .section      .text.entry

+  .globl _start

+

+_start:

+  j handle_reset

+

+nmi_vector:

+  j nmi_vector

+

+trap_vector:

+  j trap_entry

+

+handle_reset:

+  la t0, trap_entry

+  csrw mtvec, t0

+  csrwi mstatus, 0

+  csrwi mie, 0

+

+/*Floating point support configuration*/

+

+#ifdef __riscv_flen

+  csrr t0, mstatus

+  lui t1, 0xffffa

+  addi t1, t1, -1

+  and t0, t0, t1

+  lui t1, 0x4

+  or t1, t0, t1

+  csrw mstatus, t1

+

+  lui t0, 0x0

+  fscsr t0

+#endif

+.option push

+

+# Ensure the instruction is not optimized, since gp is not yet set

+

+.option norelax

+  # initialize global pointer

+  la gp, __global_pointer$

+

+.option pop

+

+  # initialize stack pointer

+  la sp, __stack_top

+

+  # perform the rest of initialization in C

+  j _init

+

+

+trap_entry:

+  addi sp, sp, -32*REGBYTES

+

+  SREG x1, 0 * REGBYTES(sp)

+  SREG x2, 1 * REGBYTES(sp)

+  SREG x3, 2 * REGBYTES(sp)

+  SREG x4, 3 * REGBYTES(sp)

+  SREG x5, 4 * REGBYTES(sp)

+  SREG x6, 5 * REGBYTES(sp)

+  SREG x7, 6 * REGBYTES(sp)

+  SREG x8, 7 * REGBYTES(sp)

+  SREG x9, 8 * REGBYTES(sp)

+  SREG x10, 9 * REGBYTES(sp)

+  SREG x11, 10 * REGBYTES(sp)

+  SREG x12, 11 * REGBYTES(sp)

+  SREG x13, 12 * REGBYTES(sp)

+  SREG x14, 13 * REGBYTES(sp)

+  SREG x15, 14 * REGBYTES(sp)

+  SREG x16, 15 * REGBYTES(sp)

+  SREG x17, 16 * REGBYTES(sp)

+  SREG x18, 17 * REGBYTES(sp)

+  SREG x19, 18 * REGBYTES(sp)

+  SREG x20, 19 * REGBYTES(sp)

+  SREG x21, 20 * REGBYTES(sp)

+  SREG x22, 21 * REGBYTES(sp)

+  SREG x23, 22 * REGBYTES(sp)

+  SREG x24, 23 * REGBYTES(sp)

+  SREG x25, 24 * REGBYTES(sp)

+  SREG x26, 25 * REGBYTES(sp)

+  SREG x27, 26 * REGBYTES(sp)

+  SREG x28, 27 * REGBYTES(sp)

+  SREG x29, 28 * REGBYTES(sp)

+  SREG x30, 29 * REGBYTES(sp)

+  SREG x31, 30 * REGBYTES(sp)

+

+

+  csrr t0, mepc

+  SREG t0, 31 * REGBYTES(sp)

+

+  csrr a0, mcause

+  csrr a1, mepc

+  mv a2, sp

+  jal handle_trap

+  csrw mepc, a0

+

+  # Remain in M-mode after mret

+  li t0, MSTATUS_MPP

+  csrs mstatus, t0

+

+  LREG x1, 0 * REGBYTES(sp)

+  LREG x2, 1 * REGBYTES(sp)

+  LREG x3, 2 * REGBYTES(sp)

+  LREG x4, 3 * REGBYTES(sp)

+  LREG x5, 4 * REGBYTES(sp)

+  LREG x6, 5 * REGBYTES(sp)

+  LREG x7, 6 * REGBYTES(sp)

+  LREG x8, 7 * REGBYTES(sp)

+  LREG x9, 8 * REGBYTES(sp)

+  LREG x10, 9 * REGBYTES(sp)

+  LREG x11, 10 * REGBYTES(sp)

+  LREG x12, 11 * REGBYTES(sp)

+  LREG x13, 12 * REGBYTES(sp)

+  LREG x14, 13 * REGBYTES(sp)

+  LREG x15, 14 * REGBYTES(sp)

+  LREG x16, 15 * REGBYTES(sp)

+  LREG x17, 16 * REGBYTES(sp)

+  LREG x18, 17 * REGBYTES(sp)

+  LREG x19, 18 * REGBYTES(sp)

+  LREG x20, 19 * REGBYTES(sp)

+  LREG x21, 20 * REGBYTES(sp)

+  LREG x22, 21 * REGBYTES(sp)

+  LREG x23, 22 * REGBYTES(sp)

+  LREG x24, 23 * REGBYTES(sp)

+  LREG x25, 24 * REGBYTES(sp)

+  LREG x26, 25 * REGBYTES(sp)

+  LREG x27, 26 * REGBYTES(sp)

+  LREG x28, 27 * REGBYTES(sp)

+  LREG x29, 28 * REGBYTES(sp)

+  LREG x30, 29 * REGBYTES(sp)

+  LREG x31, 30 * REGBYTES(sp)

+

+  addi sp, sp, 32*REGBYTES

+  mret

+

+#endif

+

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/init.c b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/init.c
new file mode 100644
index 0000000..8c5998f
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/init.c
@@ -0,0 +1,80 @@
+/*******************************************************************************

+ * (c) Copyright 2016-2018 Microsemi SoC Products Group.  All rights reserved.

+ *

+ * @file init.c

+ * @author Microsemi SoC Products Group

+ * @brief Mi-V soft processor memory section initializations and start-up code.

+ *

+ * SVN $Revision: 9661 $

+ * SVN $Date: 2018-01-15 16:13:33 +0530 (Mon, 15 Jan 2018) $

+ */

+

+#include <stdlib.h>

+#include <stdint.h>

+#include <unistd.h>

+

+#include "encoding.h"

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+extern uint32_t     __sdata_load;

+extern uint32_t     __sdata_start;

+extern uint32_t     __sdata_end;

+

+extern uint32_t     __data_load;

+extern uint32_t     __data_start;

+extern uint32_t     __data_end;

+

+extern uint32_t     __sbss_start;

+extern uint32_t     __sbss_end;

+extern uint32_t     __bss_start;

+extern uint32_t     __bss_end;

+

+

+static void copy_section(uint32_t * p_load, uint32_t * p_vma, uint32_t * p_vma_end)

+{

+    while(p_vma <= p_vma_end)

+    {

+        *p_vma = *p_load;

+        ++p_load;

+        ++p_vma;

+    }

+}

+

+static void zero_section(uint32_t * start, uint32_t * end)

+{

+    uint32_t * p_zero = start;

+    

+    while(p_zero <= end)

+    {

+        *p_zero = 0;

+        ++p_zero;

+    }

+}

+

+void _init(void)

+{

+    extern int main(int, char**);

+    const char *argv0 = "hello";

+    char *argv[] = {(char *)argv0, NULL, NULL};

+

+    copy_section(&__sdata_load, &__sdata_start, &__sdata_end);

+    copy_section(&__data_load, &__data_start, &__data_end);

+    zero_section(&__sbss_start, &__sbss_end);

+    zero_section(&__bss_start, &__bss_end);

+    

+    main(1, argv);

+}

+

+/* Function called after main() finishes */

+void

+_fini()

+{

+}

+

+#ifdef __cplusplus

+}

+#endif

+

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/microsemi-riscv-igloo2.ld b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/microsemi-riscv-igloo2.ld
new file mode 100644
index 0000000..11d0697
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/microsemi-riscv-igloo2.ld
@@ -0,0 +1,137 @@
+/*******************************************************************************

+ * (c) Copyright 2016-2018 Microsemi SoC Products Group.  All rights reserved.

+ * 

+ * file name : microsemi-riscv-igloo2.ld

+ * Mi-V soft processor linker script for creating a SoftConsole downloadable

+ * image executing in eNVM.

+ * 

+ * This linker script assumes that the eNVM is connected at on the Mi-V soft

+ * processor memory space. 

+ *

+ * SVN $Revision: 9661 $

+ * SVN $Date: 2018-01-15 16:13:33 +0530 (Mon, 15 Jan 2018) $

+ */

+ 

+OUTPUT_ARCH( "riscv" )

+ENTRY(_start)

+

+

+MEMORY

+{

+    envm (rx) : ORIGIN = 0x60000000, LENGTH = 240k

+    ram (rwx) : ORIGIN = 0x80000000, LENGTH = 64k

+}

+

+RAM_START_ADDRESS   = 0x80000000;       /* Must be the same value MEMORY region ram ORIGIN above. */

+RAM_SIZE            = 64k;              /* Must be the same value MEMORY region ram LENGTH above. */

+STACK_SIZE          = 2k;               /* needs to be calculated for your application */             

+HEAP_SIZE           = 2k;               /* needs to be calculated for your application */

+

+SECTIONS

+{

+  .text : ALIGN(0x10)

+  {

+    KEEP (*(SORT_NONE(.text.entry)))   

+    . = ALIGN(0x10);

+    *(.text .text.* .gnu.linkonce.t.*)

+    *(.plt)

+    . = ALIGN(0x10);

+    

+    KEEP (*crtbegin.o(.ctors))

+    KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))

+    KEEP (*(SORT(.ctors.*)))

+    KEEP (*crtend.o(.ctors))

+    KEEP (*crtbegin.o(.dtors))

+    KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))

+    KEEP (*(SORT(.dtors.*)))

+    KEEP (*crtend.o(.dtors))

+    

+    *(.rodata .rodata.* .gnu.linkonce.r.*)

+    *(.gcc_except_table) 

+    *(.eh_frame_hdr)

+    *(.eh_frame)

+    

+    KEEP (*(.init))

+    KEEP (*(.fini))

+

+    PROVIDE_HIDDEN (__preinit_array_start = .);

+    KEEP (*(.preinit_array))

+    PROVIDE_HIDDEN (__preinit_array_end = .);

+    PROVIDE_HIDDEN (__init_array_start = .);

+    KEEP (*(SORT(.init_array.*)))

+    KEEP (*(.init_array))

+    PROVIDE_HIDDEN (__init_array_end = .);

+    PROVIDE_HIDDEN (__fini_array_start = .);

+    KEEP (*(.fini_array))

+    KEEP (*(SORT(.fini_array.*)))

+    PROVIDE_HIDDEN (__fini_array_end = .);

+    . = ALIGN(0x10);

+    

+  } >envm

+

+  /* short/global data section */

+  .sdata : ALIGN(0x10)

+  {

+    __sdata_load = LOADADDR(.sdata);

+    __sdata_start = .; 

+    PROVIDE( __global_pointer$ = . + 0x800);

+    *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2)

+    *(.srodata*)

+    *(.sdata .sdata.* .gnu.linkonce.s.*)

+    . = ALIGN(0x10);

+    __sdata_end = .;

+  } >ram AT>envm

+

+  /* data section */

+  .data : ALIGN(0x10)

+  { 

+    __data_load = LOADADDR(.data);

+    __data_start = .; 

+    *(.got.plt) *(.got)

+    *(.shdata)

+    *(.data .data.* .gnu.linkonce.d.*)

+    . = ALIGN(0x10);

+    __data_end = .;

+  } >ram AT>envm

+

+  /* sbss section */

+  .sbss : ALIGN(0x10)

+  {

+    __sbss_start = .;

+    *(.sbss .sbss.* .gnu.linkonce.sb.*)

+    *(.scommon)

+    . = ALIGN(0x10);

+    __sbss_end = .;

+  } > ram

+  

+  /* sbss section */

+  .bss : ALIGN(0x10)

+  { 

+    __bss_start = .;

+    *(.shbss)

+    *(.bss .bss.* .gnu.linkonce.b.*)

+    *(COMMON)

+    . = ALIGN(0x10);

+    __bss_end = .;

+  } > ram

+

+  /* End of uninitialized data segment */

+  _end = .;

+  

+  .heap : ALIGN(0x10)

+  {

+    __heap_start = .;

+    . += HEAP_SIZE;

+    __heap_end = .;

+    . = ALIGN(0x10);

+    _heap_end = __heap_end;

+  } > ram

+  

+  .stack : ALIGN(0x10)

+  {

+    __stack_bottom = .;

+    . += STACK_SIZE;

+    __stack_top = .;

+  } > ram

+}

+

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/microsemi-riscv-ram.ld b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/microsemi-riscv-ram.ld
new file mode 100644
index 0000000..d63709e
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/microsemi-riscv-ram.ld
@@ -0,0 +1,137 @@
+/*******************************************************************************

+ * (c) Copyright 2016-2018 Microsemi SoC Products Group.  All rights reserved.

+ * 

+ * file name : microsemi-riscv-ram.ld

+ * Mi-V soft processor linker script for creating a SoftConsole downloadable

+ * debug image executing in SRAM.

+ * 

+ * This linker script assumes that the SRAM is connected at on the Mi-V soft

+ * processor memory space. The start address and size of the memory space must

+ * be correct as per the Libero design.

+ *

+ * SVN $Revision: 9661 $

+ * SVN $Date: 2018-01-15 16:13:33 +0530 (Mon, 15 Jan 2018) $

+ */

+ 

+OUTPUT_ARCH( "riscv" )

+ENTRY(_start)

+

+

+MEMORY

+{

+    ram (rwx) : ORIGIN = 0x80000000, LENGTH = 512k

+}

+

+RAM_START_ADDRESS   = 0x80000000;       /* Must be the same value MEMORY region ram ORIGIN above. */

+RAM_SIZE            = 512k;              /* Must be the same value MEMORY region ram LENGTH above. */

+STACK_SIZE          = 64k;               /* needs to be calculated for your application */             

+HEAP_SIZE           = 64k;               /* needs to be calculated for your application */

+

+SECTIONS

+{

+  .text : ALIGN(0x10)

+  {

+    KEEP (*(SORT_NONE(.text.entry)))   

+    . = ALIGN(0x10);

+    *(.text .text.* .gnu.linkonce.t.*)

+    *(.plt)

+    . = ALIGN(0x10);

+    

+    KEEP (*crtbegin.o(.ctors))

+    KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))

+    KEEP (*(SORT(.ctors.*)))

+    KEEP (*crtend.o(.ctors))

+    KEEP (*crtbegin.o(.dtors))

+    KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))

+    KEEP (*(SORT(.dtors.*)))

+    KEEP (*crtend.o(.dtors))

+    

+    *(.rodata .rodata.* .gnu.linkonce.r.*)

+    *(.gcc_except_table) 

+    *(.eh_frame_hdr)

+    *(.eh_frame)

+    

+    KEEP (*(.init))

+    KEEP (*(.fini))

+

+    PROVIDE_HIDDEN (__preinit_array_start = .);

+    KEEP (*(.preinit_array))

+    PROVIDE_HIDDEN (__preinit_array_end = .);

+    PROVIDE_HIDDEN (__init_array_start = .);

+    KEEP (*(SORT(.init_array.*)))

+    KEEP (*(.init_array))

+    PROVIDE_HIDDEN (__init_array_end = .);

+    PROVIDE_HIDDEN (__fini_array_start = .);

+    KEEP (*(.fini_array))

+    KEEP (*(SORT(.fini_array.*)))

+    PROVIDE_HIDDEN (__fini_array_end = .);

+    . = ALIGN(0x10);

+    

+  } > ram

+

+  /* short/global data section */

+  .sdata : ALIGN(0x10)

+  {

+    __sdata_load = LOADADDR(.sdata);

+    __sdata_start = .; 

+    PROVIDE( __global_pointer$ = . + 0x800);

+    *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2)

+    *(.srodata*)

+    *(.sdata .sdata.* .gnu.linkonce.s.*)

+    . = ALIGN(0x10);

+    __sdata_end = .;

+  } > ram

+

+  /* data section */

+  .data : ALIGN(0x10)

+  { 

+    __data_load = LOADADDR(.data);

+    __data_start = .; 

+    *(.got.plt) *(.got)

+    *(.shdata)

+    *(.data .data.* .gnu.linkonce.d.*)

+    . = ALIGN(0x10);

+    __data_end = .;

+  } > ram

+

+  /* sbss section */

+  .sbss : ALIGN(0x10)

+  {

+    __sbss_start = .;

+    *(.sbss .sbss.* .gnu.linkonce.sb.*)

+    *(.scommon)

+    . = ALIGN(0x10);

+    __sbss_end = .;

+  } > ram

+  

+  /* sbss section */

+  .bss : ALIGN(0x10)

+  { 

+    __bss_start = .;

+    *(.shbss)

+    *(.bss .bss.* .gnu.linkonce.b.*)

+    *(COMMON)

+    . = ALIGN(0x10);

+    __bss_end = .;

+  } > ram

+

+  /* End of uninitialized data segment */

+  _end = .;

+  

+  .heap : ALIGN(0x10)

+  {

+    __heap_start = .;

+    . += HEAP_SIZE;

+    __heap_end = .;

+    . = ALIGN(0x10);

+    _heap_end = __heap_end;

+  } > ram

+  

+  .stack : ALIGN(0x10)

+  {

+    __stack_bottom = .;

+    . += STACK_SIZE;

+    __stack_top = .;

+  } > ram

+}

+

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/riscv_hal.c b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/riscv_hal.c
new file mode 100644
index 0000000..f7be82c
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/riscv_hal.c
@@ -0,0 +1,251 @@
+/*******************************************************************************

+ * (c) Copyright 2016-2018 Microsemi SoC Products Group. All rights reserved.

+ *

+ * @file riscv_hal.c

+ * @author Microsemi SoC Products Group

+ * @brief Implementation of Hardware Abstraction Layer for Mi-V soft processors

+ *

+ * SVN $Revision: 9835 $

+ * SVN $Date: 2018-03-19 19:11:35 +0530 (Mon, 19 Mar 2018) $

+ */

+#include <stdlib.h>

+#include <stdint.h>

+#include <unistd.h>

+

+#include "riscv_hal.h"

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+#define RTC_PRESCALER 100UL

+

+#define SUCCESS 0U

+#define ERROR   1U

+

+/*------------------------------------------------------------------------------

+ *

+ */

+uint8_t Invalid_IRQHandler(void);

+uint8_t External_1_IRQHandler(void);

+uint8_t External_2_IRQHandler(void);

+uint8_t External_3_IRQHandler(void);

+uint8_t External_4_IRQHandler(void);

+uint8_t External_5_IRQHandler(void);

+uint8_t External_6_IRQHandler(void);

+uint8_t External_7_IRQHandler(void);

+uint8_t External_8_IRQHandler(void);

+uint8_t External_9_IRQHandler(void);

+uint8_t External_10_IRQHandler(void);

+uint8_t External_11_IRQHandler(void);

+uint8_t External_12_IRQHandler(void);

+uint8_t External_13_IRQHandler(void);

+uint8_t External_14_IRQHandler(void);

+uint8_t External_15_IRQHandler(void);

+uint8_t External_16_IRQHandler(void);

+uint8_t External_17_IRQHandler(void);

+uint8_t External_18_IRQHandler(void);

+uint8_t External_19_IRQHandler(void);

+uint8_t External_20_IRQHandler(void);

+uint8_t External_21_IRQHandler(void);

+uint8_t External_22_IRQHandler(void);

+uint8_t External_23_IRQHandler(void);

+uint8_t External_24_IRQHandler(void);

+uint8_t External_25_IRQHandler(void);

+uint8_t External_26_IRQHandler(void);

+uint8_t External_27_IRQHandler(void);

+uint8_t External_28_IRQHandler(void);

+uint8_t External_29_IRQHandler(void);

+uint8_t External_30_IRQHandler(void);

+uint8_t External_31_IRQHandler(void);

+

+/*------------------------------------------------------------------------------

+ *

+ */

+extern void Software_IRQHandler(void);

+

+/*------------------------------------------------------------------------------

+ * Increment value for the mtimecmp register in order to achieve a system tick

+ * interrupt as specified through the SysTick_Config() function.

+ */

+static uint64_t g_systick_increment = 0U;

+

+/*------------------------------------------------------------------------------

+ * Disable all interrupts.

+ */

+void __disable_irq(void)

+{

+    clear_csr(mstatus, MSTATUS_MPIE);

+    clear_csr(mstatus, MSTATUS_MIE);

+}

+

+/*------------------------------------------------------------------------------

+ * Enabler all interrupts.

+ */

+void __enable_irq(void)

+{

+    set_csr(mstatus, MSTATUS_MIE);

+}

+

+/*------------------------------------------------------------------------------

+ * Configure the machine timer to generate an interrupt.

+ */

+uint32_t SysTick_Config(uint32_t ticks)

+{

+    uint32_t ret_val = ERROR;

+

+    g_systick_increment = (uint64_t)(ticks) / RTC_PRESCALER;

+

+    if (g_systick_increment > 0U)

+    {

+        uint32_t mhart_id = read_csr(mhartid);

+

+        PRCI->MTIMECMP[mhart_id] = PRCI->MTIME + g_systick_increment;

+

+        set_csr(mie, MIP_MTIP);

+

+        __enable_irq();

+

+        ret_val = SUCCESS;

+    }

+

+    return ret_val;

+}

+

+/*------------------------------------------------------------------------------

+ * RISC-V interrupt handler for machine timer interrupts.

+ */

+static void handle_m_timer_interrupt(void)

+{

+    clear_csr(mie, MIP_MTIP);

+

+    SysTick_Handler();

+

+    PRCI->MTIMECMP[read_csr(mhartid)] = PRCI->MTIME + g_systick_increment;

+

+    set_csr(mie, MIP_MTIP);

+}

+

+/*------------------------------------------------------------------------------

+ * RISC-V interrupt handler for external interrupts.

+ */

+uint8_t (*ext_irq_handler_table[32])(void) =

+{

+    Invalid_IRQHandler,

+    External_1_IRQHandler,

+    External_2_IRQHandler,

+    External_3_IRQHandler,

+    External_4_IRQHandler,

+    External_5_IRQHandler,

+    External_6_IRQHandler,

+    External_7_IRQHandler,

+    External_8_IRQHandler,

+    External_9_IRQHandler,

+    External_10_IRQHandler,

+    External_11_IRQHandler,

+    External_12_IRQHandler,

+    External_13_IRQHandler,

+    External_14_IRQHandler,

+    External_15_IRQHandler,

+    External_16_IRQHandler,

+    External_17_IRQHandler,

+    External_18_IRQHandler,

+    External_19_IRQHandler,

+    External_20_IRQHandler,

+    External_21_IRQHandler,

+    External_22_IRQHandler,

+    External_23_IRQHandler,

+    External_24_IRQHandler,

+    External_25_IRQHandler,

+    External_26_IRQHandler,

+    External_27_IRQHandler,

+    External_28_IRQHandler,

+    External_29_IRQHandler,

+    External_30_IRQHandler,

+    External_31_IRQHandler

+};

+

+/*------------------------------------------------------------------------------

+ *

+ */

+static void handle_m_ext_interrupt(void)

+{

+    uint32_t int_num  = PLIC_ClaimIRQ();

+    uint8_t disable = EXT_IRQ_KEEP_ENABLED;

+

+    disable = ext_irq_handler_table[int_num]();

+

+    PLIC_CompleteIRQ(int_num);

+

+    if(EXT_IRQ_DISABLE == disable)

+    {

+        PLIC_DisableIRQ((IRQn_Type)int_num);

+    }

+}

+

+static void handle_m_soft_interrupt(void)

+{

+    Software_IRQHandler();

+

+    /*Clear software interrupt*/

+    PRCI->MSIP[0] = 0x00U;

+}

+

+/*------------------------------------------------------------------------------

+ * Trap/Interrupt handler

+ */

+uintptr_t handle_trap(uintptr_t mcause, uintptr_t mepc)

+{

+    if ((mcause & MCAUSE_INT) && ((mcause & MCAUSE_CAUSE)  == IRQ_M_EXT))

+    {

+        handle_m_ext_interrupt();

+    }

+    else if ((mcause & MCAUSE_INT) && ((mcause & MCAUSE_CAUSE)  == IRQ_M_TIMER))

+    {

+        handle_m_timer_interrupt();

+    }

+    else if ( (mcause & MCAUSE_INT) && ((mcause & MCAUSE_CAUSE)  == IRQ_M_SOFT))

+    {

+        handle_m_soft_interrupt();

+    }

+    else

+    {

+#ifndef NDEBUG

+        /*

+         Arguments supplied to this function are mcause, mepc (exception PC) and stack pointer

+         based onprivileged-isa specification

+         mcause values and meanings are:

+         0 Instruction address misaligned (mtval/mbadaddr is the address)

+         1 Instruction access fault       (mtval/mbadaddr is the address)

+         2 Illegal instruction            (mtval/mbadaddr contains the offending instruction opcode)

+         3 Breakpoint

+         4 Load address misaligned        (mtval/mbadaddr is the address)

+         5 Load address fault             (mtval/mbadaddr is the address)

+         6 Store/AMO address fault        (mtval/mbadaddr is the address)

+         7 Store/AMO access fault         (mtval/mbadaddr is the address)

+         8 Environment call from U-mode

+         9 Environment call from S-mode

+         A Environment call from M-mode

+         B Instruction page fault

+         C Load page fault                (mtval/mbadaddr is the address)

+         E Store page fault               (mtval/mbadaddr is the address)

+        */

+

+         uintptr_t mip      = read_csr(mip);      /* interrupt pending */

+         uintptr_t mbadaddr = read_csr(mbadaddr); /* additional info and meaning depends on mcause */

+         uintptr_t mtvec    = read_csr(mtvec);    /* trap vector */

+         uintptr_t mscratch = read_csr(mscratch); /* temporary, sometimes might hold temporary value of a0 */

+         uintptr_t mstatus  = read_csr(mstatus);  /* status contains many smaller fields: */

+

+		/* breakpoint*/

+        __asm("ebreak");

+#else

+        _exit(1 + mcause);

+#endif

+    }

+    return mepc;

+}

+

+#ifdef __cplusplus

+}

+#endif

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/riscv_hal.h b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/riscv_hal.h
new file mode 100644
index 0000000..7c3835f
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/riscv_hal.h
@@ -0,0 +1,55 @@
+/*******************************************************************************

+ * (c) Copyright 2016-2018 Microsemi SoC Products Group. All rights reserved.

+ *

+ * @file riscv_hal.h

+ * @author Microsemi SoC Products Group

+ * @brief Hardware Abstraction Layer functions for Mi-V soft processors

+ *

+ * SVN $Revision: 9835 $

+ * SVN $Date: 2018-03-19 19:11:35 +0530 (Mon, 19 Mar 2018) $

+ */

+

+#ifndef RISCV_HAL_H

+#define RISCV_HAL_H

+

+#include "riscv_plic.h"

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+/*

+ *Return value from External IRQ handler. This will be used to disable the External

+ *interrupt.

+ */

+#define EXT_IRQ_KEEP_ENABLED                0U

+#define EXT_IRQ_DISABLE                     1U

+

+/*------------------------------------------------------------------------------

+ * Interrupt enable/disable.

+ */

+void __disable_irq(void);

+void __enable_irq(void);

+

+/*------------------------------------------------------------------------------

+ *  System tick handler. This is generated from the RISC-V machine timer.

+ */

+void SysTick_Handler(void);

+

+/*------------------------------------------------------------------------------

+ * System tick configuration.

+ * Configures the machine timer to generate a system tick interrupt at regular

+ * intervals.

+ * Takes the number of system clock ticks between interrupts.

+ *

+ * Returns 0 if successful.

+ * Returns 1 if the interrupt interval cannot be achieved.

+ */

+uint32_t SysTick_Config(uint32_t ticks);

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif  /* RISCV_HAL_H */

+

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/riscv_hal_stubs.c b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/riscv_hal_stubs.c
new file mode 100644
index 0000000..29a4f40
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/riscv_hal_stubs.c
@@ -0,0 +1,227 @@
+/*******************************************************************************

+ * (c) Copyright 2016-2018 Microsemi SoC Products Group. All rights reserved.

+ *

+ * @file riscv_hal_stubs.c

+ * @author Microsemi SoC Products Group

+ * @brief Mi-V soft processor Interrupt Function stubs.

+ * The functions below will only be linked with the application code if the user

+ * does not provide an implementation for these functions. These functions are

+ * defined with weak linking so that they can be overridden by a function with

+ * same prototype in the user's application code.

+ *

+ * SVN $Revision: 9835 $

+ * SVN $Date: 2018-03-19 19:11:35 +0530 (Mon, 19 Mar 2018) $

+ */

+#include <unistd.h>

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+/*Weakly linked handler. Will be replaced with user's definition if provided*/

+__attribute__((weak)) void Software_IRQHandler(void)

+{

+    _exit(10);

+}

+

+/*Weakly linked handler. Will be replaced with user's definition if provided*/

+__attribute__((weak)) void SysTick_Handler(void)

+{

+	/*Default handler*/

+}

+

+/*Weakly linked handler. Will be replaced with user's definition if provided*/

+__attribute__((weak)) uint8_t Invalid_IRQHandler(void)

+{

+    return(0U); /*Default handler*/

+}

+

+/*Weakly linked handler. Will be replaced with user's definition if provided*/

+__attribute__((weak)) uint8_t External_1_IRQHandler(void)

+{

+    return(0U); /*Default handler*/

+}

+

+/*Weakly linked handler. Will be replaced with user's definition if provided*/

+__attribute__((weak)) uint8_t External_2_IRQHandler(void)

+{

+    return(0U); /*Default handler*/

+}

+

+/*Weakly linked handler. Will be replaced with user's definition if provided*/

+__attribute__((weak)) uint8_t External_3_IRQHandler(void)

+{

+    return(0U); /*Default handler*/

+}

+

+/*Weakly linked handler. Will be replaced with user's definition if provided*/

+__attribute__((weak)) uint8_t External_4_IRQHandler(void)

+{

+	return(0U); /*Default handler*/

+}

+

+/*Weakly linked handler. Will be replaced with user's definition if provided*/

+__attribute__((weak)) uint8_t External_5_IRQHandler(void)

+{

+    return(0U); /*Default handler*/

+}

+

+/*Weakly linked handler. Will be replaced with user's definition if provided*/

+__attribute__((weak)) uint8_t External_6_IRQHandler(void)

+{

+    return(0U); /*Default handler*/

+}

+

+/*Weakly linked handler. Will be replaced with user's definition if provided*/

+__attribute__((weak)) uint8_t External_7_IRQHandler(void)

+{

+    return(0U); /*Default handler*/

+}

+

+/*Weakly linked handler. Will be replaced with user's definition if provided*/

+__attribute__((weak)) uint8_t External_8_IRQHandler(void)

+{

+    return(0U); /*Default handler*/

+}

+

+/*Weakly linked handler. Will be replaced with user's definition if provided*/

+__attribute__((weak)) uint8_t External_9_IRQHandler(void)

+{

+    return(0U); /*Default handler*/

+}

+

+/*Weakly linked handler. Will be replaced with user's definition if provided*/

+__attribute__((weak)) uint8_t External_10_IRQHandler(void)

+{

+    return(0U); /*Default handler*/

+}

+

+/*Weakly linked handler. Will be replaced with user's definition if provided*/

+__attribute__((weak)) uint8_t External_11_IRQHandler(void)

+{

+    return(0U); /*Default handler*/

+}

+

+/*Weakly linked handler. Will be replaced with user's definition if provided*/

+__attribute__((weak)) uint8_t External_12_IRQHandler(void)

+{

+	return(0U); /*Default handler*/

+}

+

+/*Weakly linked handler. Will be replaced with user's definition if provided*/

+__attribute__((weak)) uint8_t External_13_IRQHandler(void)

+{

+	return(0U); /*Default handler*/

+}

+

+/*Weakly linked handler. Will be replaced with user's definition if provided*/

+__attribute__((weak)) uint8_t External_14_IRQHandler(void)

+{

+	return(0U); /*Default handler*/

+}

+

+/*Weakly linked handler. Will be replaced with user's definition if provided*/

+__attribute__((weak)) uint8_t External_15_IRQHandler(void)

+{

+	return(0U); /*Default handler*/

+}

+

+/*Weakly linked handler. Will be replaced with user's definition if provided*/

+__attribute__((weak)) uint8_t External_16_IRQHandler(void)

+{

+	return(0U); /*Default handler*/

+}

+

+/*Weakly linked handler. Will be replaced with user's definition if provided*/

+__attribute__((weak)) uint8_t External_17_IRQHandler(void)

+{

+	return(0U); /*Default handler*/

+}

+

+/*Weakly linked handler. Will be replaced with user's definition if provided*/

+__attribute__((weak)) uint8_t External_18_IRQHandler(void)

+{

+	return(0U); /*Default handler*/

+}

+

+/*Weakly linked handler. Will be replaced with user's definition if provided*/

+__attribute__((weak)) uint8_t External_19_IRQHandler(void)

+{

+	return(0U); /*Default handler*/

+}

+

+/*Weakly linked handler. Will be replaced with user's definition if provided*/

+__attribute__((weak)) uint8_t External_20_IRQHandler(void)

+{

+	return(0U); /*Default handler*/

+}

+

+/*Weakly linked handler. Will be replaced with user's definition if provided*/

+__attribute__((weak)) uint8_t External_21_IRQHandler(void)

+{

+	return(0U); /*Default handler*/

+}

+

+/*Weakly linked handler. Will be replaced with user's definition if provided*/

+__attribute__((weak)) uint8_t External_22_IRQHandler(void)

+{

+	return(0U); /*Default handler*/

+}

+

+/*Weakly linked handler. Will be replaced with user's definition if provided*/

+__attribute__((weak)) uint8_t External_23_IRQHandler(void)

+{

+	return(0U); /*Default handler*/

+}

+

+/*Weakly linked handler. Will be replaced with user's definition if provided*/

+__attribute__((weak)) uint8_t External_24_IRQHandler(void)

+{

+	return(0U); /*Default handler*/

+}

+

+/*Weakly linked handler. Will be replaced with user's definition if provided*/

+__attribute__((weak)) uint8_t External_25_IRQHandler(void)

+{

+	return(0U); /*Default handler*/

+}

+

+/*Weakly linked handler. Will be replaced with user's definition if provided*/

+__attribute__((weak)) uint8_t External_26_IRQHandler(void)

+{

+	return(0U); /*Default handler*/

+}

+

+/*Weakly linked handler. Will be replaced with user's definition if provided*/

+__attribute__((weak)) uint8_t External_27_IRQHandler(void)

+{

+	return(0U); /*Default handler*/

+}

+

+/*Weakly linked handler. Will be replaced with user's definition if provided*/

+__attribute__((weak)) uint8_t External_28_IRQHandler(void)

+{

+	return(0U); /*Default handler*/

+}

+

+/*Weakly linked handler. Will be replaced with user's definition if provided*/

+__attribute__((weak)) uint8_t External_29_IRQHandler(void)

+{

+	return(0U); /*Default handler*/

+}

+

+/*Weakly linked handler. Will be replaced with user's definition if provided*/

+__attribute__((weak)) uint8_t External_30_IRQHandler(void)

+{

+	return(0U); /*Default handler*/

+}

+

+/*Weakly linked handler. Will be replaced with user's definition if provide*/

+__attribute__((weak)) uint8_t External_31_IRQHandler(void)

+{

+	return(0U); /*Default handler*/

+}

+

+#ifdef __cplusplus

+}

+#endif

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/riscv_plic.h b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/riscv_plic.h
new file mode 100644
index 0000000..2d09518
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/riscv_plic.h
@@ -0,0 +1,249 @@
+/*******************************************************************************

+ * (c) Copyright 2016-2018 Microsemi SoC Products Group.  All rights reserved.

+ *

+ * @file riscv_plic.h

+ * @author Microsemi SoC Products Group

+ * @brief Mi-V soft processor PLIC and PRCI access data structures and functions.

+ *

+ * SVN $Revision: 9838 $

+ * SVN $Date: 2018-03-19 19:22:54 +0530 (Mon, 19 Mar 2018) $

+ */

+#ifndef RISCV_PLIC_H

+#define RISCV_PLIC_H

+

+#include <stdint.h>

+

+#include "encoding.h"

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+#define PLIC_NUM_SOURCES 31

+#define PLIC_NUM_PRIORITIES 0

+

+/*==============================================================================

+ * Interrupt numbers:

+ */

+typedef enum

+{

+    NoInterrupt_IRQn = 0,

+    External_1_IRQn  = 1,

+    External_2_IRQn  = 2,

+    External_3_IRQn  = 3, 

+    External_4_IRQn  = 4,

+    External_5_IRQn  = 5,

+    External_6_IRQn  = 6,

+    External_7_IRQn  = 7,

+    External_8_IRQn  = 8,

+    External_9_IRQn  = 9,

+    External_10_IRQn = 10,

+    External_11_IRQn = 11,

+    External_12_IRQn = 12,

+    External_13_IRQn = 13,

+    External_14_IRQn = 14,

+    External_15_IRQn = 15,

+    External_16_IRQn = 16,

+    External_17_IRQn = 17,

+    External_18_IRQn = 18,

+    External_19_IRQn = 19,

+    External_20_IRQn = 20,

+    External_21_IRQn = 21,

+    External_22_IRQn = 22,

+    External_23_IRQn = 23,

+    External_24_IRQn = 24,

+    External_25_IRQn = 25,

+    External_26_IRQn = 26,

+    External_27_IRQn = 27,

+    External_28_IRQn = 28,

+    External_29_IRQn = 29,

+    External_30_IRQn = 30,

+    External_31_IRQn = 31

+} IRQn_Type;

+

+

+/*==============================================================================

+ * PLIC: Platform Level Interrupt Controller

+ */

+#define PLIC_BASE_ADDR 0x40000000UL

+

+typedef struct

+{

+    volatile uint32_t PRIORITY_THRESHOLD;

+    volatile uint32_t CLAIM_COMPLETE;

+    volatile uint32_t reserved[1022];

+} IRQ_Target_Type;

+

+typedef struct

+{

+    volatile uint32_t ENABLES[32];

+} Target_Enables_Type;

+

+typedef struct

+{

+    /*-------------------- Source Priority --------------------*/

+    volatile uint32_t SOURCE_PRIORITY[1024];

+    

+    /*-------------------- Pending array --------------------*/

+    volatile const uint32_t PENDING_ARRAY[32];

+    volatile uint32_t RESERVED1[992];

+    

+    /*-------------------- Target enables --------------------*/

+    volatile Target_Enables_Type TARGET_ENABLES[15808];

+

+    volatile uint32_t RESERVED2[16384];

+    

+    /*--- Target Priority threshold and claim/complete---------*/

+    IRQ_Target_Type TARGET[15872];

+    

+} PLIC_Type;

+

+

+#define PLIC    ((PLIC_Type *)PLIC_BASE_ADDR)

+

+/*==============================================================================

+ * PRCI: Power, Reset, Clock, Interrupt

+ */

+#define PRCI_BASE   0x44000000UL

+

+typedef struct

+{

+    volatile uint32_t MSIP[4095];

+    volatile uint32_t reserved;

+    volatile uint64_t MTIMECMP[4095];

+    volatile const uint64_t MTIME;

+} PRCI_Type;

+

+#define PRCI    ((PRCI_Type *)PRCI_BASE) 

+

+/*==============================================================================

+ * The function PLIC_init() initializes the PLIC controller and enables the 

+ * global external interrupt bit.

+ */

+static inline void PLIC_init(void)

+{

+    uint32_t inc;

+    unsigned long hart_id = read_csr(mhartid);

+

+    /* Disable all interrupts for the current hart. */

+    for(inc = 0; inc < ((PLIC_NUM_SOURCES + 32u) / 32u); ++inc)

+    {

+        PLIC->TARGET_ENABLES[hart_id].ENABLES[inc] = 0;

+    }

+

+    /* Set priorities to zero. */

+    /* Should this really be done??? Calling PLIC_init() on one hart will cause

+    * the priorities previously set by other harts to be messed up. */

+    for(inc = 0; inc < PLIC_NUM_SOURCES; ++inc)

+    {

+        PLIC->SOURCE_PRIORITY[inc] = 0;

+    }

+

+    /* Set the threshold to zero. */

+    PLIC->TARGET[hart_id].PRIORITY_THRESHOLD = 0;

+

+    /* Enable machine external interrupts. */

+    set_csr(mie, MIP_MEIP);

+}

+

+/*==============================================================================

+ * The function PLIC_EnableIRQ() enables the external interrupt for the interrupt

+ * number indicated by the parameter IRQn.

+ */

+static inline void PLIC_EnableIRQ(IRQn_Type IRQn)

+{

+    unsigned long hart_id = read_csr(mhartid);

+    uint32_t current = PLIC->TARGET_ENABLES[hart_id].ENABLES[IRQn / 32];

+    current |= (uint32_t)1 << (IRQn % 32);

+    PLIC->TARGET_ENABLES[hart_id].ENABLES[IRQn / 32] = current;

+}

+

+/*==============================================================================

+ * The function PLIC_DisableIRQ() disables the external interrupt for the interrupt

+ * number indicated by the parameter IRQn.

+

+ * NOTE:

+ * 	This function can be used to disable the external interrupt from outside

+ * 	external interrupt handler function.

+ * 	This function MUST NOT be used from within the External Interrupt handler.

+ * 	If you wish to disable the external interrupt while the interrupt handler

+ * 	for that external interrupt is executing then you must use the return value

+ * 	EXT_IRQ_DISABLE to return from the extern interrupt handler.

+ */

+static inline void PLIC_DisableIRQ(IRQn_Type IRQn)

+{

+    unsigned long hart_id = read_csr(mhartid);

+    uint32_t current = PLIC->TARGET_ENABLES[hart_id].ENABLES[IRQn / 32];

+

+    current &= ~((uint32_t)1 << (IRQn % 32));

+

+    PLIC->TARGET_ENABLES[hart_id].ENABLES[IRQn / 32] = current;

+}

+

+/*==============================================================================

+ * The function PLIC_SetPriority() sets the priority for the external interrupt 

+ * for the interrupt number indicated by the parameter IRQn.

+ */

+static inline void PLIC_SetPriority(IRQn_Type IRQn, uint32_t priority) 

+{

+    PLIC->SOURCE_PRIORITY[IRQn] = priority;

+}

+

+/*==============================================================================

+ * The function PLIC_GetPriority() returns the priority for the external interrupt 

+ * for the interrupt number indicated by the parameter IRQn.

+ */

+static inline uint32_t PLIC_GetPriority(IRQn_Type IRQn)

+{

+    return PLIC->SOURCE_PRIORITY[IRQn];

+}

+

+/*==============================================================================

+ * The function PLIC_ClaimIRQ() claims the interrupt from the PLIC controller.

+ */

+static inline uint32_t PLIC_ClaimIRQ(void)

+{

+    unsigned long hart_id = read_csr(mhartid);

+

+    return PLIC->TARGET[hart_id].CLAIM_COMPLETE;

+}

+

+/*==============================================================================

+ * The function PLIC_CompleteIRQ() indicates to the PLIC controller the interrupt

+ * is processed and claim is complete.

+ */

+static inline void PLIC_CompleteIRQ(uint32_t source)

+{

+    unsigned long hart_id = read_csr(mhartid);

+

+    PLIC->TARGET[hart_id].CLAIM_COMPLETE = source;

+}

+

+/*==============================================================================

+ * The function raise_soft_interrupt() raises a synchronous software interrupt by

+ * writing into the MSIP register.

+ */

+static inline void raise_soft_interrupt()

+{

+    unsigned long hart_id = read_csr(mhartid);

+

+    /*You need to make sure that the global interrupt is enabled*/

+    set_csr(mie, MIP_MSIP);       /*Enable software interrupt bit */

+    PRCI->MSIP[hart_id] = 0x01;   /*raise soft interrupt for hart0*/

+}

+

+/*==============================================================================

+ * The function clear_soft_interrupt() clears a synchronous software interrupt by

+ * clearing the MSIP register.

+ */

+static inline void clear_soft_interrupt()

+{

+    unsigned long hart_id = read_csr(mhartid);

+    PRCI->MSIP[hart_id] = 0x00;   /*clear soft interrupt for hart0*/

+}

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif  /* RISCV_PLIC_H */

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/sample_hw_platform.h b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/sample_hw_platform.h
new file mode 100644
index 0000000..2990bd0
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/sample_hw_platform.h
@@ -0,0 +1,120 @@
+/*******************************************************************************

+ * (c) Copyright 2016-2018 Microsemi Corporation.  All rights reserved.

+ *

+ * Platform definitions

+ * Version based on requirements of RISCV-HAL

+ *

+ * SVN $Revision: 9946 $

+ * SVN $Date: 2018-04-30 20:26:55 +0530 (Mon, 30 Apr 2018) $

+ */

+ /*=========================================================================*//**

+  @mainpage Sample file detailing how hw_platform.h should be constructed for 

+    the Mi-V processors.

+

+    @section intro_sec Introduction

+    The hw_platform.h is to be located in the project root directory.

+    Currently this file must be hand crafted when using the Mi-V Soft Processor.

+    

+    You can use this file as sample.

+    Rename this file from sample_hw_platform.h to hw_platform.h and store it in

+    the root folder of your project. Then customize it per your HW design.

+

+    @section driver_configuration Project configuration Instructions

+    1. Change SYS_CLK_FREQ define to frequency of Mi-V Soft processor clock

+    2  Add all other core BASE addresses

+    3. Add peripheral Core Interrupt to Mi-V Soft processor interrupt mappings

+    4. Define MSCC_STDIO_UART_BASE_ADDR if you want a CoreUARTapb mapped to STDIO

+*//*=========================================================================*/

+

+#ifndef HW_PLATFORM_H

+#define HW_PLATFORM_H

+

+/***************************************************************************//**

+ * Soft-processor clock definition

+ * This is the only clock brought over from the Mi-V Soft processor Libero design.

+ */

+#ifndef SYS_CLK_FREQ

+#define SYS_CLK_FREQ                    83000000UL

+#endif

+

+

+/***************************************************************************//**

+ * Non-memory Peripheral base addresses

+ * Format of define is:

+ * <corename>_<instance>_BASE_ADDR

+ */

+#define COREUARTAPB0_BASE_ADDR          0x70001000UL

+#define COREGPIO_IN_BASE_ADDR           0x70002000UL

+#define CORETIMER0_BASE_ADDR            0x70003000UL

+#define CORETIMER1_BASE_ADDR            0x70004000UL

+#define COREGPIO_OUT_BASE_ADDR          0x70005000UL

+#define FLASH_CORE_SPI_BASE             0x70006000UL

+#define CORE16550_BASE_ADDR             0x70007000UL

+

+/***************************************************************************//**

+ * Peripheral Interrupts are mapped to the corresponding Mi-V Soft processor

+ * interrupt from the Libero design.

+ * There can be up to 31 external interrupts (IRQ[30:0] pins) on the Mi-V Soft

+ * processor.The Mi-V Soft processor external interrupts are defined in the

+ * riscv_plic.h

+ * These are of the form

+ * typedef enum

+{

+    NoInterrupt_IRQn = 0,

+    External_1_IRQn  = 1,

+    External_2_IRQn  = 2,

+    .

+    .

+    .

+    External_31_IRQn = 31

+} IRQn_Type;

+ 

+ The interrupt 0 on RISC-V processor is not used. The pin IRQ[0] should map to

+ External_1_IRQn likewise IRQ[30] should map to External_31_IRQn

+ * Format of define is:

+ * <corename>_<instance>_<core interrupt name>

+ */

+

+#define TIMER0_IRQn                     External_30_IRQn

+#define TIMER1_IRQn                     External_31_IRQn

+

+/****************************************************************************

+ * Baud value to achieve a 115200 baud rate with a 83MHz system clock.

+ * This value is calculated using the following equation:

+ *      BAUD_VALUE = (CLOCK / (16 * BAUD_RATE)) - 1

+ *****************************************************************************/

+#define BAUD_VALUE_115200               (SYS_CLK_FREQ / (16 * 115200)) - 1

+

+/***************************************************************************//**

+ * User edit section- Edit sections below if required

+ */

+#ifdef MSCC_STDIO_THRU_CORE_UART_APB

+/*

+ * A base address mapping for the STDIO printf/scanf mapping to CortUARTapb

+ * must be provided if it is being used

+ *

+ * e.g. #define MSCC_STDIO_UART_BASE_ADDR COREUARTAPB1_BASE_ADDR

+ */

+#define MSCC_STDIO_UART_BASE_ADDR COREUARTAPB0_BASE_ADDR

+

+#ifndef MSCC_STDIO_UART_BASE_ADDR

+#error MSCC_STDIO_UART_BASE_ADDR not defined- e.g. #define MSCC_STDIO_UART_BASE_ADDR COREUARTAPB1_BASE_ADDR

+#endif

+

+#ifndef MSCC_STDIO_BAUD_VALUE

+/*

+ * The MSCC_STDIO_BAUD_VALUE define should be set in your project's settings to

+ * specify the baud value used by the standard output CoreUARTapb instance for

+ * generating the UART's baud rate if you want a different baud rate from the

+ * default of 115200 baud

+ */

+#define MSCC_STDIO_BAUD_VALUE           115200

+#endif  /*MSCC_STDIO_BAUD_VALUE*/

+

+#endif  /* end of MSCC_STDIO_THRU_CORE_UART_APB */

+/*******************************************************************************

+ * End of user edit section

+ */

+#endif /* HW_PLATFORM_H */

+

+

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/syscall.c b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/syscall.c
new file mode 100644
index 0000000..4c99f80
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/syscall.c
@@ -0,0 +1,266 @@
+/*******************************************************************************

+ * (c) Copyright 2016-2018 Microsemi SoC Products Group.  All rights reserved.

+ *

+ * @file syscall.c

+ * @author Microsemi SoC Products Group

+ * @brief Stubs for system calls.

+ *

+ * SVN $Revision: 9661 $

+ * SVN $Date: 2018-01-15 16:13:33 +0530 (Mon, 15 Jan 2018) $

+ */

+#include <stdint.h>

+#include <stdlib.h>

+#include <stddef.h>

+#include <unistd.h>

+#include <errno.h>

+#include <sys/stat.h>

+#include <sys/times.h>

+#include <stdio.h>

+#include <string.h>

+

+#include "encoding.h"

+

+#ifdef MSCC_STDIO_THRU_CORE_UART_APB

+

+#include "core_uart_apb.h"

+#include "hw_platform.h"

+

+#endif  /*MSCC_STDIO_THRU_CORE_UART_APB*/

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+#ifdef MSCC_STDIO_THRU_CORE_UART_APB

+

+/*------------------------------------------------------------------------------

+ * CoreUARTapb instance data for the CoreUARTapb instance used for standard

+ * output.

+ */

+static UART_instance_t g_stdio_uart;

+

+/*==============================================================================

+ * Flag used to indicate if the UART driver needs to be initialized.

+ */

+static int g_stdio_uart_init_done = 0;

+#endif /*MSCC_STDIO_THRU_CORE_UART_APB*/

+

+#undef errno

+int errno;

+

+char *__env[1] = { 0 };

+char **environ = __env;

+

+void write_hex(int fd, uint32_t hex)

+{

+    uint8_t ii;

+    uint8_t jj;

+    char towrite;

+    uint8_t digit;

+

+    write( fd , "0x", 2 );

+

+    for (ii = 8 ; ii > 0; ii--)

+    {

+        jj = ii-1;

+        digit = ((hex & (0xF << (jj*4))) >> (jj*4));

+        towrite = digit < 0xA ? ('0' + digit) : ('A' +  (digit - 0xA));

+        write( fd, &towrite, 1);

+    }

+}

+

+               

+void _exit(int code)

+{

+#ifdef MSCC_STDIO_THRU_CORE_UART_APB

+    const char * message = "\nProgam has exited with code:";

+

+    write(STDERR_FILENO, message, strlen(message));

+    write_hex(STDERR_FILENO, code);

+#endif

+

+    while (1);

+}

+

+void *_sbrk(ptrdiff_t incr)

+{

+    extern char _end[];

+    extern char _heap_end[];

+    static char *curbrk = _end;

+

+    if ((curbrk + incr < _end) || (curbrk + incr > _heap_end))

+    {

+        return ((char *) - 1);

+    }

+

+    curbrk += incr;

+    return curbrk - incr;

+}

+

+int _isatty(int fd)

+{

+    if (fd == STDOUT_FILENO || fd == STDERR_FILENO)

+    {

+        return 1;

+    }

+

+    errno = EBADF;

+    return 0;

+}

+

+static int stub(int err)

+{

+    errno = err;

+    return -1;

+}

+

+int _open(const char* name, int flags, int mode)

+{

+    return stub(ENOENT);

+}

+

+int _openat(int dirfd, const char* name, int flags, int mode)

+{

+    return stub(ENOENT);

+}

+

+int _close(int fd)

+{

+    return stub(EBADF);

+}

+

+int _execve(const char* name, char* const argv[], char* const env[])

+{

+    return stub(ENOMEM);

+}

+

+int _fork()

+{

+    return stub(EAGAIN);

+}

+

+int _fstat(int fd, struct stat *st)

+{

+    if (isatty(fd))

+    {

+        st->st_mode = S_IFCHR;

+        return 0;

+    }

+

+    return stub(EBADF);

+}

+

+int _getpid()

+{

+    return 1;

+}

+

+int _kill(int pid, int sig)

+{

+    return stub(EINVAL);

+}

+

+int _link(const char *old_name, const char *new_name)

+{

+    return stub(EMLINK);

+}

+

+off_t _lseek(int fd, off_t ptr, int dir)

+{

+    if (_isatty(fd))

+    {

+        return 0;

+    }

+

+    return stub(EBADF);

+}

+

+ssize_t _read(int fd, void* ptr, size_t len)

+{

+#ifdef MSCC_STDIO_THRU_CORE_UART_APB

+    if (_isatty(fd))

+    {

+        /*--------------------------------------------------------------------------

+        * Initialize the UART driver if it is the first time this function is

+        * called.

+        */

+        if ( !g_stdio_uart_init_done )

+        {

+            /******************************************************************************

+            * Baud value:

+            * This value is calculated using the following equation:

+            *      BAUD_VALUE = (CLOCK / (16 * BAUD_RATE)) - 1

+            *****************************************************************************/

+            UART_init( &g_stdio_uart, MSCC_STDIO_UART_BASE_ADDR, ((SYS_CLK_FREQ/(16 * MSCC_STDIO_BAUD_VALUE))-1), (DATA_8_BITS | NO_PARITY));

+            g_stdio_uart_init_done = 1;

+        }

+

+        return UART_get_rx(&g_stdio_uart, (uint8_t*) ptr, len);

+    }

+#endif

+

+    return stub(EBADF);

+}

+

+int _stat(const char* file, struct stat* st)

+{

+    return stub(EACCES);

+}

+

+clock_t _times(struct tms* buf)

+{

+    return stub(EACCES);

+}

+

+int _unlink(const char* name)

+{

+    return stub(ENOENT);

+}

+

+int _wait(int* status)

+{

+    return stub(ECHILD);

+}

+

+ssize_t _write(int fd, const void* ptr, size_t len)

+{

+

+#ifdef MSCC_STDIO_THRU_CORE_UART_APB

+  const uint8_t * current = (const uint8_t *) ptr;

+  size_t jj;

+

+  if (_isatty(fd))

+  {

+        /*--------------------------------------------------------------------------

+        * Initialize the UART driver if it is the first time this function is

+        * called.

+        */

+        if ( !g_stdio_uart_init_done )

+        {

+            /******************************************************************************

+            * Baud value:

+            * This value is calculated using the following equation:

+            *      BAUD_VALUE = (CLOCK / (16 * BAUD_RATE)) - 1

+            *****************************************************************************/

+            UART_init( &g_stdio_uart, MSCC_STDIO_UART_BASE_ADDR, ((SYS_CLK_FREQ/(16 * MSCC_STDIO_BAUD_VALUE))-1), (DATA_8_BITS | NO_PARITY));

+            g_stdio_uart_init_done = 1;

+        }

+

+    for (jj = 0; jj < len; jj++)

+    {

+        UART_send(&g_stdio_uart, current + jj, 1);

+        if (current[jj] == '\n')

+        {

+            UART_send(&g_stdio_uart, (const uint8_t *)"\r", 1);

+        }

+    }

+    return len;

+  }

+#endif

+

+  return stub(EBADF);

+}

+

+#ifdef __cplusplus

+}

+#endif