]> git.sur5r.net Git - freertos/commitdiff
Add starting point for IGLOO2 RISV-V demo project.
authorrtel <rtel@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Wed, 20 Jun 2018 21:18:14 +0000 (21:18 +0000)
committerrtel <rtel@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Wed, 20 Jun 2018 21:18:14 +0000 (21:18 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2553 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

42 files changed:
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/.cproject [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/.project [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/.settings/language.settings.xml [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/FreeRTOSConfig.h [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/README.md [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/RTOSDemo Debug.launch [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/Core16550/core16550_regs.h [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/Core16550/core_16550.c [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/Core16550/core_16550.h [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreGPIO/core_gpio.c [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreGPIO/core_gpio.h [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreGPIO/coregpio_regs.h [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreI2C/core_i2c.c [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreI2C/core_i2c.h [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreI2C/core_smbus_regs.h [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreI2C/i2c_interrupt.c [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreTimer/core_timer.c [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreTimer/core_timer.h [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreTimer/coretimer_regs.h [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreUARTapb/core_uart_apb.c [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreUARTapb/core_uart_apb.h [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/drivers/CoreUARTapb/coreuartapb_regs.h [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/hal/cpu_types.h [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/hal/hal.h [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/hal/hal_assert.h [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/hal/hal_irq.c [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/hal/hw_macros.h [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/hal/hw_reg_access.S [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/hal/hw_reg_access.h [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/hw_platform.h [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/main.c [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/encoding.h [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/entry.S [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/init.c [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/microsemi-riscv-igloo2.ld [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/microsemi-riscv-ram.ld [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/riscv_hal.c [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/riscv_hal.h [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/riscv_hal_stubs.c [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/riscv_plic.h [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/sample_hw_platform.h [new file with mode: 0644]
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/syscall.c [new file with mode: 0644]

diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/.cproject b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/.cproject
new file mode 100644 (file)
index 0000000..c1655cf
--- /dev/null
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>\r
+<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">\r
+       <storageModule moduleId="org.eclipse.cdt.core.settings">\r
+               <cconfiguration id="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.debug.2049051127">\r
+                       <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">\r
+                               <externalSettings/>\r
+                               <extensions>\r
+                                       <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>\r
+                                       <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>\r
+                                       <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>\r
+                                       <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>\r
+                                       <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>\r
+                                       <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>\r
+                               </extensions>\r
+                       </storageModule>\r
+                       <storageModule moduleId="cdtBuildSystem" version="4.0.0">\r
+                               <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="">\r
+                                       <folderInfo id="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.debug.2049051127." name="/" resourcePath="">\r
+                                               <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">\r
+                                                       <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"/>\r
+                                                       <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"/>\r
+                                                       <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"/>\r
+                                                       <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"/>\r
+                                                       <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"/>\r
+                                                       <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"/>\r
+                                                       <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"/>\r
+                                                       <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"/>\r
+                                                       <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"/>\r
+                                                       <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"/>\r
+                                                       <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"/>\r
+                                                       <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"/>\r
+                                                       <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"/>\r
+                                                       <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"/>\r
+                                                       <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"/>\r
+                                                       <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"/>\r
+                                                       <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"/>\r
+                                                       <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"/>\r
+                                                       <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"/>\r
+                                                       <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"/>\r
+                                                       <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"/>\r
+                                                       <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"/>\r
+                                                       <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"/>\r
+                                                       <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"/>\r
+                                                       <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"/>\r
+                                                       <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">\r
+                                                               <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"/>\r
+                                                               <inputType id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.input.1786331150" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.input"/>\r
+                                                       </tool>\r
+                                                       <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">\r
+                                                               <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">\r
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/FreeRTOS_Source/include}&quot;"/>\r
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/FreeRTOS_Source/portable/ThirdParty/GCC/RISC-V}&quot;"/>\r
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}&quot;"/>\r
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/drivers/CoreGPIO}&quot;"/>\r
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/drivers/Core16550}&quot;"/>\r
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/drivers/CoreUARTapb}&quot;"/>\r
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/drivers/CoreTimer}&quot;"/>\r
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/drivers/CoreSPI}&quot;"/>\r
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/hal}&quot;"/>\r
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/riscv_hal}&quot;"/>\r
+                                                               </option>\r
+                                                               <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">\r
+                                                                       <listOptionValue builtIn="false" value="MSCC_STDIO_THRU_CORE_UART_APB"/>\r
+                                                               </option>\r
+                                                               <inputType id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input.1901773760" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input"/>\r
+                                                       </tool>\r
+                                                       <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"/>\r
+                                                       <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">\r
+                                                               <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"/>\r
+                                                               <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">\r
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/riscv_hal/microsemi-riscv-ram.ld}&quot;"/>\r
+                                                               </option>\r
+                                                               <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"/>\r
+                                                               <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"/>\r
+                                                               <inputType id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.linker.input.314001493" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.linker.input">\r
+                                                                       <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>\r
+                                                                       <additionalInput kind="additionalinput" paths="$(LIBS)"/>\r
+                                                               </inputType>\r
+                                                       </tool>\r
+                                                       <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">\r
+                                                               <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"/>\r
+                                                               <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">\r
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/riscv_hal/microsemi-riscv-ram.ld}&quot;"/>\r
+                                                               </option>\r
+                                                               <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"/>\r
+                                                               <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"/>\r
+                                                       </tool>\r
+                                                       <tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.archiver.690189418" name="GNU RISC-V Cross Archiver" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.archiver"/>\r
+                                                       <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"/>\r
+                                                       <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">\r
+                                                               <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"/>\r
+                                                               <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"/>\r
+                                                               <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"/>\r
+                                                               <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"/>\r
+                                                               <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"/>\r
+                                                       </tool>\r
+                                                       <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">\r
+                                                               <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"/>\r
+                                                       </tool>\r
+                                               </toolChain>\r
+                                       </folderInfo>\r
+                                       <sourceEntries>\r
+                                               <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=""/>\r
+                                       </sourceEntries>\r
+                               </configuration>\r
+                       </storageModule>\r
+                       <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>\r
+               </cconfiguration>\r
+       </storageModule>\r
+       <storageModule moduleId="cdtBuildSystem" version="4.0.0">\r
+               <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"/>\r
+       </storageModule>\r
+       <storageModule moduleId="scannerConfiguration">\r
+               <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>\r
+               <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">\r
+                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>\r
+               </scannerConfigBuildInfo>\r
+               <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">\r
+                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>\r
+               </scannerConfigBuildInfo>\r
+       </storageModule>\r
+       <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>\r
+       <storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>\r
+       <storageModule moduleId="refreshScope"/>\r
+</cproject>\r
diff --git a/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/.project b/FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/.project
new file mode 100644 (file)
index 0000000..f7313f5
--- /dev/null
@@ -0,0 +1,162 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+       <name>RTOSDemo</name>\r
+       <comment></comment>\r
+       <projects>\r
+       </projects>\r
+       <buildSpec>\r
+               <buildCommand>\r
+                       <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>\r
+                       <triggers>clean,full,incremental,</triggers>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>\r
+                       <triggers>full,incremental,</triggers>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+       </buildSpec>\r
+       <natures>\r
+               <nature>org.eclipse.cdt.core.cnature</nature>\r
+               <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>\r
+               <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>\r
+       </natures>\r
+       <linkedResources>\r
+               <link>\r
+                       <name>FreeRTOS_Source</name>\r
+                       <type>2</type>\r
+                       <locationURI>FREERTOS_ROOT/FreeRTOS/Source</locationURI>\r
+               </link>\r
+       </linkedResources>\r
+       <filteredResources>\r
+               <filter>\r
+                       <id>1529524430510</id>\r
+                       <name>FreeRTOS_Source</name>\r
+                       <type>9</type>\r
+                       <matcher>\r
+                               <id>org.eclipse.ui.ide.multiFilter</id>\r
+                               <arguments>1.0-name-matches-false-false-include</arguments>\r
+                       </matcher>\r
+               </filter>\r
+               <filter>\r
+                       <id>1529524430514</id>\r
+                       <name>FreeRTOS_Source</name>\r
+                       <type>9</type>\r
+                       <matcher>\r
+                               <id>org.eclipse.ui.ide.multiFilter</id>\r
+                               <arguments>1.0-name-matches-false-false-portable</arguments>\r
+                       </matcher>\r
+               </filter>\r
+               <filter>\r
+                       <id>1529524430518</id>\r
+                       <name>FreeRTOS_Source</name>\r
+                       <type>5</type>\r
+                       <matcher>\r
+                               <id>org.eclipse.ui.ide.multiFilter</id>\r
+                               <arguments>1.0-name-matches-false-false-event_groups.c</arguments>\r
+                       </matcher>\r
+               </filter>\r
+               <filter>\r
+                       <id>1529524430521</id>\r
+                       <name>FreeRTOS_Source</name>\r
+                       <type>5</type>\r
+                       <matcher>\r
+                               <id>org.eclipse.ui.ide.multiFilter</id>\r
+                               <arguments>1.0-name-matches-false-false-list.c</arguments>\r
+                       </matcher>\r
+               </filter>\r
+               <filter>\r
+                       <id>1529524430525</id>\r
+                       <name>FreeRTOS_Source</name>\r
+                       <type>5</type>\r
+                       <matcher>\r
+                               <id>org.eclipse.ui.ide.multiFilter</id>\r
+                               <arguments>1.0-name-matches-false-false-queue.c</arguments>\r
+                       </matcher>\r
+               </filter>\r
+               <filter>\r
+                       <id>1529524430529</id>\r
+                       <name>FreeRTOS_Source</name>\r
+                       <type>5</type>\r
+                       <matcher>\r
+                               <id>org.eclipse.ui.ide.multiFilter</id>\r
+                               <arguments>1.0-name-matches-false-false-stream_buffer.c</arguments>\r
+                       </matcher>\r
+               </filter>\r
+               <filter>\r
+                       <id>1529524430533</id>\r
+                       <name>FreeRTOS_Source</name>\r
+                       <type>5</type>\r
+                       <matcher>\r
+                               <id>org.eclipse.ui.ide.multiFilter</id>\r
+                               <arguments>1.0-name-matches-false-false-tasks.c</arguments>\r
+                       </matcher>\r
+               </filter>\r
+               <filter>\r
+                       <id>1529524430538</id>\r
+                       <name>FreeRTOS_Source</name>\r
+                       <type>5</type>\r
+                       <matcher>\r
+                               <id>org.eclipse.ui.ide.multiFilter</id>\r
+                               <arguments>1.0-name-matches-false-false-timers.c</arguments>\r
+                       </matcher>\r
+               </filter>\r
+               <filter>\r
+                       <id>1529524475525</id>\r
+                       <name>FreeRTOS_Source/portable</name>\r
+                       <type>9</type>\r
+                       <matcher>\r
+                               <id>org.eclipse.ui.ide.multiFilter</id>\r
+                               <arguments>1.0-name-matches-false-false-ThirdParty</arguments>\r
+                       </matcher>\r
+               </filter>\r
+               <filter>\r
+                       <id>1529524475530</id>\r
+                       <name>FreeRTOS_Source/portable</name>\r
+                       <type>9</type>\r
+                       <matcher>\r
+                               <id>org.eclipse.ui.ide.multiFilter</id>\r
+                               <arguments>1.0-name-matches-false-false-MemMang</arguments>\r
+                       </matcher>\r
+               </filter>\r
+               <filter>\r
+                       <id>1529524494421</id>\r
+                       <name>FreeRTOS_Source/portable/MemMang</name>\r
+                       <type>5</type>\r
+                       <matcher>\r
+                               <id>org.eclipse.ui.ide.multiFilter</id>\r
+                               <arguments>1.0-name-matches-false-false-heap_4.c</arguments>\r
+                       </matcher>\r
+               </filter>\r
+               <filter>\r
+                       <id>1529524515837</id>\r
+                       <name>FreeRTOS_Source/portable/ThirdParty</name>\r
+                       <type>9</type>\r
+                       <matcher>\r
+                               <id>org.eclipse.ui.ide.multiFilter</id>\r
+                               <arguments>1.0-name-matches-false-false-GCC</arguments>\r
+                       </matcher>\r
+               </filter>\r
+               <filter>\r
+                       <id>1529524627661</id>\r
+                       <name>FreeRTOS_Source/portable/ThirdParty/GCC</name>\r
+                       <type>9</type>\r
+                       <matcher>\r
+                               <id>org.eclipse.ui.ide.multiFilter</id>\r
+                               <arguments>1.0-name-matches-false-false-RISC-V</arguments>\r
+                       </matcher>\r
+               </filter>\r
+       </filteredResources>\r
+       <variableList>\r
+               <variable>\r
+                       <name>FREERTOS_ROOT</name>\r
+                       <value>$%7BPARENT-3-PROJECT_LOC%7D</value>\r
+               </variable>\r
+               <variable>\r
+                       <name>copy_PARENT</name>\r
+                       <value>$%7BPARENT-4-PROJECT_LOC%7D/FreeRTOS/WorkingCopy/FreeRTOS</value>\r
+               </variable>\r
+       </variableList>\r
+</projectDescription>\r
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 (file)
index 0000000..6dc13a6
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>\r
+<project>\r
+       <configuration id="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.debug.2049051127" name="Debug">\r
+               <extension point="org.eclipse.cdt.core.LanguageSettingsProvider">\r
+                       <provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>\r
+                       <provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>\r
+                       <provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>\r
+                       <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">\r
+                               <language-scope id="org.eclipse.cdt.core.gcc"/>\r
+                               <language-scope id="org.eclipse.cdt.core.g++"/>\r
+                       </provider>\r
+               </extension>\r
+       </configuration>\r
+</project>\r
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 (file)
index 0000000..0cd797d
--- /dev/null
@@ -0,0 +1,151 @@
+/*\r
+    FreeRTOS V8.2.3 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+    All rights reserved\r
+\r
+    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
+\r
+    This file is part of the FreeRTOS distribution.\r
+\r
+    FreeRTOS is free software; you can redistribute it and/or modify it under\r
+    the terms of the GNU General Public License (version 2) as published by the\r
+    Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.\r
+\r
+    ***************************************************************************\r
+    >>!   NOTE: The modification to the GPL is included to allow you to     !<<\r
+    >>!   distribute a combined work that includes FreeRTOS without being   !<<\r
+    >>!   obliged to provide the source code for proprietary components     !<<\r
+    >>!   outside of the FreeRTOS kernel.                                   !<<\r
+    ***************************************************************************\r
+\r
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
+    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
+    FOR A PARTICULAR PURPOSE.  Full license text is available on the following\r
+    link: http://www.freertos.org/a00114.html\r
+\r
+    ***************************************************************************\r
+     *                                                                       *\r
+     *    FreeRTOS provides completely free yet professionally developed,    *\r
+     *    robust, strictly quality controlled, supported, and cross          *\r
+     *    platform software that is more than just the market leader, it     *\r
+     *    is the industry's de facto standard.                               *\r
+     *                                                                       *\r
+     *    Help yourself get started quickly while simultaneously helping     *\r
+     *    to support the FreeRTOS project by purchasing a FreeRTOS           *\r
+     *    tutorial book, reference manual, or both:                          *\r
+     *    http://www.FreeRTOS.org/Documentation                              *\r
+     *                                                                       *\r
+    ***************************************************************************\r
+\r
+    http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading\r
+    the FAQ page "My application does not run, what could be wrong?".  Have you\r
+    defined configASSERT()?\r
+\r
+    http://www.FreeRTOS.org/support - In return for receiving this top quality\r
+    embedded software for free we request you assist our global community by\r
+    participating in the support forum.\r
+\r
+    http://www.FreeRTOS.org/training - Investing in training allows your team to\r
+    be as productive as possible as early as possible.  Now you can receive\r
+    FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
+    Ltd, and the world's leading authority on the world's leading RTOS.\r
+\r
+    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+    including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
+    compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
+\r
+    http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
+    Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
+\r
+    http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
+    Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS\r
+    licenses offer ticketed support, indemnification and commercial middleware.\r
+\r
+    http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
+    engineered and independently SIL3 certified version for use in safety and\r
+    mission critical applications that require provable dependability.\r
+\r
+    1 tab == 4 spaces!\r
+*/\r
+\r
+\r
+#ifndef FREERTOS_CONFIG_H\r
+#define FREERTOS_CONFIG_H\r
+\r
+\r
+/*-----------------------------------------------------------\r
+ * Application specific definitions.\r
+ *\r
+ * These definitions should be adjusted for your particular hardware and\r
+ * application requirements.\r
+ *\r
+ * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE\r
+ * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.\r
+ *\r
+ * See http://www.freertos.org/a00110.html.\r
+ *----------------------------------------------------------*/\r
+\r
+#include <stdint.h>\r
+#include <string.h>\r
+#include "riscv_plic.h"\r
+\r
+extern uint32_t SystemCoreClock;\r
+\r
+#define configUSE_PREEMPTION                   1\r
+#define configUSE_IDLE_HOOK                            1\r
+#define configUSE_TICK_HOOK                            0\r
+#define configCPU_CLOCK_HZ                     ( ( unsigned long ) 83000000 )\r
+#define configTICK_RATE_HZ                     ( ( TickType_t ) 1000 )\r
+#define configMAX_PRIORITIES           ( 5 )\r
+#define configMINIMAL_STACK_SIZE       ( ( unsigned short ) 1024 )\r
+#define configTOTAL_HEAP_SIZE          ( ( size_t ) ( 100 * 1024 ) )\r
+#define configMAX_TASK_NAME_LEN                        ( 16 )\r
+#define configUSE_TRACE_FACILITY               1\r
+#define configUSE_16_BIT_TICKS                 0\r
+#define configIDLE_SHOULD_YIELD                        1\r
+#define configUSE_MUTEXES                              1\r
+#define configQUEUE_REGISTRY_SIZE              8\r
+#define configCHECK_FOR_STACK_OVERFLOW 0 //2\r
+#define configUSE_RECURSIVE_MUTEXES            1\r
+#define configUSE_MALLOC_FAILED_HOOK   1\r
+#define configUSE_APPLICATION_TASK_TAG 0\r
+#define configUSE_COUNTING_SEMAPHORES  1\r
+#define configGENERATE_RUN_TIME_STATS  0\r
+\r
+/* Co-routine definitions. */\r
+#define configUSE_CO_ROUTINES                  0\r
+#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )\r
+\r
+/* Software timer definitions. */\r
+#define configUSE_TIMERS                               0\r
+#define configTIMER_TASK_PRIORITY              ( 2 )\r
+#define configTIMER_QUEUE_LENGTH               2\r
+#define configTIMER_TASK_STACK_DEPTH   ( configMINIMAL_STACK_SIZE )\r
+\r
+/* Task priorities.  Allow these to be overridden. */\r
+#ifndef uartPRIMARY_PRIORITY\r
+       #define uartPRIMARY_PRIORITY            ( configMAX_PRIORITIES - 3 )\r
+#endif\r
+\r
+/* Set the following definitions to 1 to include the API function, or zero\r
+to exclude the API function. */\r
+#define INCLUDE_vTaskPrioritySet               1\r
+#define INCLUDE_uxTaskPriorityGet              1\r
+#define INCLUDE_vTaskDelete                            1\r
+#define INCLUDE_vTaskCleanUpResources  1\r
+#define INCLUDE_vTaskSuspend                   1\r
+#define INCLUDE_vTaskDelayUntil                        1\r
+#define INCLUDE_vTaskDelay                             1\r
+#define INCLUDE_eTaskGetState                  1\r
+\r
+/* Normal assert() semantics without relying on the provision of an assert.h\r
+header file. */\r
+#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }\r
+\r
+/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS\r
+standard names - or at least those used in the unmodified vector table. */\r
+#define vPortSVCHandler SVCall_Handler\r
+#define xPortPendSVHandler PendSV_Handler\r
+#define vPortSysTickHandler SysTick_Handler\r
+\r
+extern void vApplicationMallocFailedHook();\r
+#endif /* FREERTOS_CONFIG_H */\r
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 (file)
index 0000000..211d246
--- /dev/null
@@ -0,0 +1,48 @@
+## FreeRTOS port for Mi-V Soft Processor\r
+\r
+### HW Platform and FPGA design:\r
+This project is tested on following hardware platforms:\r
+\r
+RISCV-Creative-Board\r
+- [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)\r
+\r
+PolarFire-Eval-Kit\r
+- [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)\r
+\r
+SmartFusion2-Advanced-Dev-Kit\r
+- [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)\r
+\r
+### How to run the FreeRTOS RISC-V port:\r
+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)\r
+\r
+The miv-rv32im-freertos-port-test is a self contained project. This project demonstrates \r
+the FreeRTOS running with Microsemi RISC-V processor. This project creates  two \r
+tasks and runs them at regular intervals.\r
+    \r
+This example project requires USB-UART interface to be connected to a host PC. \r
+The host PC must connect to the serial port using a terminal emulator such as \r
+TeraTerm or PuTTY configured as follows:\r
+    \r
+        - 115200 baud\r
+        - 8 data bits\r
+        - 1 stop bit\r
+        - no parity\r
+        - no flow control\r
+    \r
+The ./hw_platform.h file contains the design related information that is required \r
+for this project. If you update the design, the hw_platform.h must be updated \r
+accordingly.\r
+\r
+### FreeRTOS Configurations\r
+You must configure the FreeRTOS as per your applications need. Please read and modify FreeRTOSConfig.h.\r
+E.g. You must set configCPU_CLOCK_HZ parameter in FreeRTOSConfig.h according to the hardware platform \r
+design that you are using. \r
+\r
+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.\r
+\r
+### Microsemi SoftConsole Toolchain\r
+To know more please refer: [SoftConsole](https://github.com/RISCV-on-Microsemi-FPGA/SoftConsole)\r
+\r
+### Documentation for Microsemi RISC-V processor, SoftConsole toochain, Debug Tools, FPGA design etc.\r
+To know more please refer: [Documentation](https://github.com/RISCV-on-Microsemi-FPGA/Documentation)\r
+    \r
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 (file)
index 0000000..9bc0bf0
--- /dev/null
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>\r
+<launchConfiguration type="ilg.gnumcueclipse.debug.gdbjtag.openocd.launchConfigurationType">\r
+<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doContinue" value="true"/>\r
+<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doDebugInRam" value="false"/>\r
+<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doFirstReset" value="true"/>\r
+<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doGdbServerAllocateConsole" value="true"/>\r
+<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doGdbServerAllocateTelnetConsole" value="false"/>\r
+<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doSecondReset" value="false"/>\r
+<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doStartGdbServer" value="true"/>\r
+<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.enableSemihosting" value="false"/>\r
+<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.firstResetType" value="init"/>\r
+<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbClientOtherCommands" value="set mem inaccessible-by-default off&#13;&#10;set arch riscv:rv32"/>\r
+<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbClientOtherOptions" value=""/>\r
+<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerConnectionAddress" value=""/>\r
+<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerExecutable" value="${openocd_path}/${openocd_executable}"/>\r
+<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerGdbPortNumber" value="3333"/>\r
+<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerLog" value=""/>\r
+<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerOther" value="--file board/microsemi-riscv.cfg"/>\r
+<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerTelnetPortNumber" value="4444"/>\r
+<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.otherInitCommands" value=""/>\r
+<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.otherRunCommands" value=""/>\r
+<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.secondResetType" value="halt"/>\r
+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageFileName" value=""/>\r
+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageOffset" value=""/>\r
+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.ipAddress" value="localhost"/>\r
+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.jtagDevice" value="GNU MCU OpenOCD"/>\r
+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadImage" value="true"/>\r
+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadSymbols" value="true"/>\r
+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.pcRegister" value=""/>\r
+<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.portNumber" value="3333"/>\r
+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setPcRegister" value="false"/>\r
+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setResume" value="false"/>\r
+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setStopAt" value="true"/>\r
+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.stopAt" value="main"/>\r
+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsFileName" value=""/>\r
+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsOffset" value=""/>\r
+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForImage" value="false"/>\r
+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForSymbols" value="false"/>\r
+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForImage" value="true"/>\r
+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForSymbols" value="true"/>\r
+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useRemoteTarget" value="true"/>\r
+<stringAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_NAME" value="${cross_prefix}gdb${cross_suffix}"/>\r
+<booleanAttribute key="org.eclipse.cdt.dsf.gdb.UPDATE_THREADLIST_ON_SUSPEND" value="false"/>\r
+<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="2"/>\r
+<stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/>\r
+<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_REGISTER_GROUPS" value=""/>\r
+<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="Debug\RTOSDemo.elf"/>\r
+<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="RTOSDemo"/>\r
+<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="true"/>\r
+<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.debug.2049051127"/>\r
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">\r
+<listEntry value="/RTOSDemo"/>\r
+</listAttribute>\r
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">\r
+<listEntry value="4"/>\r
+</listAttribute>\r
+<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;"/>\r
+<stringAttribute key="process_factory_id" value="org.eclipse.cdt.dsf.gdb.GdbProcessFactory"/>\r
+</launchConfiguration>\r
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 (file)
index 0000000..0b921ce
--- /dev/null
@@ -0,0 +1,582 @@
+/*******************************************************************************\r
+ * (c) Copyright 2007-2015 Microsemi SoC Products Group. All rights reserved.\r
+ *\r
+ * IP core registers definitions. This file contains the definitions required\r
+ * for accessing the IP core through the hardware abstraction layer (HAL).\r
+ * This file was automatically generated, using "get_header.exe" version 0.4.0,\r
+ * from the IP-XACT description for:\r
+ *\r
+ *             Core16550    version: 2.0.0\r
+ *\r
+ * SVN $Revision: 7963 $\r
+ * SVN $Date: 2015-10-09 17:58:21 +0530 (Fri, 09 Oct 2015) $\r
+ *\r
+ *******************************************************************************/\r
+#ifndef CORE_16550_REGISTERS_H_\r
+#define CORE_16550_REGISTERS_H_ 1\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+/*******************************************************************************\r
+ * RBR register:\r
+ *------------------------------------------------------------------------------\r
+ * Receive Buffer Register\r
+ */\r
+#define RBR_REG_OFFSET 0x00U\r
+\r
+/*******************************************************************************\r
+ * THR register:\r
+ *------------------------------------------------------------------------------\r
+ * Transmit Holding Register\r
+ */\r
+#define THR_REG_OFFSET 0x00U\r
+\r
+/*******************************************************************************\r
+ * DLR register:\r
+ *------------------------------------------------------------------------------\r
+ * Divisor Latch(LSB) Register\r
+ */\r
+#define DLR_REG_OFFSET 0x00U\r
+\r
+/*******************************************************************************\r
+ * DMR register:\r
+ *------------------------------------------------------------------------------\r
+ * Divisor Latch(MSB) Register\r
+ */\r
+#define DMR_REG_OFFSET 0x04U\r
+\r
+/*******************************************************************************\r
+ * IER register:\r
+ *------------------------------------------------------------------------------\r
+ * Interrupt Enable Register\r
+ */\r
+#define IER_REG_OFFSET 0x04U\r
+\r
+/*------------------------------------------------------------------------------\r
+ * IER_ERBFI:\r
+ *   ERBFI field of register IER.\r
+ *------------------------------------------------------------------------------\r
+ * Enables Received Data Available Interrupt. 0 - Disabled; 1 - Enabled\r
+ */\r
+#define IER_ERBFI_OFFSET   0x04U\r
+#define IER_ERBFI_MASK     0x01U\r
+#define IER_ERBFI_SHIFT    0U\r
+\r
+/*------------------------------------------------------------------------------\r
+ * IER_ETBEI:\r
+ *   ETBEI field of register IER.\r
+ *------------------------------------------------------------------------------\r
+ * Enables the Transmitter Holding Register Empty Interrupt. 0 - Disabled; 1 - \r
+ * Enabled\r
+ */\r
+#define IER_ETBEI_OFFSET   0x04U\r
+#define IER_ETBEI_MASK     0x02U\r
+#define IER_ETBEI_SHIFT    1U\r
+\r
+/*------------------------------------------------------------------------------\r
+ * IER_ELSI:\r
+ *   ELSI field of register IER.\r
+ *------------------------------------------------------------------------------\r
+ * Enables the Receiver Line Status Interrupt. 0 - Disabled; 1 - Enabled\r
+ */\r
+#define IER_ELSI_OFFSET   0x04U\r
+#define IER_ELSI_MASK     0x04U\r
+#define IER_ELSI_SHIFT    2U\r
+\r
+/*------------------------------------------------------------------------------\r
+ * IER_EDSSI:\r
+ *   EDSSI field of register IER.\r
+ *------------------------------------------------------------------------------\r
+ *  Enables the Modem Status Interrupt 0 - Disabled; 1 - Enabled\r
+ */\r
+#define IER_EDSSI_OFFSET   0x04U\r
+#define IER_EDSSI_MASK     0x08U\r
+#define IER_EDSSI_SHIFT    3U\r
+\r
+/*******************************************************************************\r
+ * IIR register:\r
+ *------------------------------------------------------------------------------\r
+ * Interrupt Identification\r
+ */\r
+#define IIR_REG_OFFSET 0x08U\r
+\r
+/*------------------------------------------------------------------------------\r
+ * IIR_IIR:\r
+ *   IIR field of register IIR.\r
+ *------------------------------------------------------------------------------\r
+ * Interrupt Identification bits.\r
+ */\r
+#define IIR_IIR_OFFSET   0x08U\r
+#define IIR_IIR_MASK     0x0FU\r
+#define IIR_IIR_SHIFT    0U\r
+\r
+/*------------------------------------------------------------------------------\r
+ * IIR_IIR:\r
+ *   IIR field of register IIR.\r
+ *------------------------------------------------------------------------------\r
+ * Interrupt Identification bits.\r
+ */\r
+\r
+/*------------------------------------------------------------------------------\r
+ * IIR_Mode:\r
+ *   Mode field of register IIR.\r
+ *------------------------------------------------------------------------------\r
+ * 11 - FIFO mode\r
+ */\r
+#define IIR_MODE_OFFSET   0x08U\r
+#define IIR_MODE_MASK     0xC0U\r
+#define IIR_MODE_SHIFT    6U\r
+\r
+/*******************************************************************************\r
+ * FCR register:\r
+ *------------------------------------------------------------------------------\r
+ * FIFO Control Register\r
+ */\r
+#define FCR_REG_OFFSET 0x08\r
+\r
+/*------------------------------------------------------------------------------\r
+ * FCR_Bit0:\r
+ *   Bit0 field of register FCR.\r
+ *------------------------------------------------------------------------------\r
+ * This bit enables both the TX and RX FIFOs.\r
+ */\r
+#define FCR_BIT0_OFFSET   0x08U\r
+#define FCR_BIT0_MASK     0x01U\r
+#define FCR_BIT0_SHIFT    0U\r
+\r
+#define FCR_ENABLE_OFFSET   0x08U\r
+#define FCR_ENABLE_MASK     0x01U\r
+#define FCR_ENABLE_SHIFT    0U\r
+\r
+/*------------------------------------------------------------------------------\r
+ * FCR_Bit1:\r
+ *   Bit1 field of register FCR.\r
+ *------------------------------------------------------------------------------\r
+ * Clears all bytes in the RX FIFO and resets its counter logic. The shift \r
+ * register is not cleared.  0 - Disabled; 1 - Enabled\r
+ */\r
+#define FCR_BIT1_OFFSET   0x08U\r
+#define FCR_BIT1_MASK     0x02U\r
+#define FCR_BIT1_SHIFT    1U\r
+\r
+#define FCR_CLEAR_RX_OFFSET   0x08U\r
+#define FCR_CLEAR_RX_MASK     0x02U\r
+#define FCR_CLEAR_RX_SHIFT    1U\r
+\r
+/*------------------------------------------------------------------------------\r
+ * FCR_Bit2:\r
+ *   Bit2 field of register FCR.\r
+ *------------------------------------------------------------------------------\r
+ * Clears all bytes in the TX FIFO and resets its counter logic. The shift \r
+ * register is not cleared.  0 - Disabled; 1 - Enabled\r
+ */\r
+#define FCR_BIT2_OFFSET   0x08U\r
+#define FCR_BIT2_MASK     0x04U\r
+#define FCR_BIT2_SHIFT    2U\r
+\r
+#define FCR_CLEAR_TX_OFFSET   0x08U\r
+#define FCR_CLEAR_TX_MASK     0x04U\r
+#define FCR_CLEAR_TX_SHIFT    2U\r
+\r
+/*------------------------------------------------------------------------------\r
+ * FCR_Bit3:\r
+ *   Bit3 field of register FCR.\r
+ *------------------------------------------------------------------------------\r
+ * Enables RXRDYN and TXRDYN pins when set to 1. Otherwise, they are disabled.\r
+ */\r
+#define FCR_BIT3_OFFSET   0x08U\r
+#define FCR_BIT3_MASK     0x08U\r
+#define FCR_BIT3_SHIFT    3U\r
+\r
+#define FCR_RDYN_EN_OFFSET   0x08U\r
+#define FCR_RDYN_EN_MASK     0x08U\r
+#define FCR_RDYN_EN_SHIFT    3U\r
+\r
+/*------------------------------------------------------------------------------\r
+ * FCR_Bit6:\r
+ *   Bit6 field of register FCR.\r
+ *------------------------------------------------------------------------------\r
+ * These bits are used to set the trigger level for the RX FIFO interrupt. RX \r
+ * FIFO Trigger Level: 0 - 1; 1 - 4; 2 - 8; 3 - 14\r
+ */\r
+#define FCR_BIT6_OFFSET   0x08U\r
+#define FCR_BIT6_MASK     0xC0U\r
+#define FCR_BIT6_SHIFT    6U\r
+\r
+#define FCR_TRIG_LEVEL_OFFSET   0x08U\r
+#define FCR_TRIG_LEVEL_MASK     0xC0U\r
+#define FCR_TRIG_LEVEL_SHIFT    6U\r
+\r
+/*******************************************************************************\r
+ * LCR register:\r
+ *------------------------------------------------------------------------------\r
+ * Line Control Register\r
+ */\r
+#define LCR_REG_OFFSET 0x0CU\r
+\r
+/*------------------------------------------------------------------------------\r
+ * LCR_WLS:\r
+ *   WLS field of register LCR.\r
+ *------------------------------------------------------------------------------\r
+ * Word Length Select: 00 - 5 bits; 01 - 6 bits; 10 - 7 bits; 11 - 8 bits\r
+ */\r
+#define LCR_WLS_OFFSET   0x0CU\r
+#define LCR_WLS_MASK     0x03U\r
+#define LCR_WLS_SHIFT    0U\r
+\r
+/*------------------------------------------------------------------------------\r
+ * LCR_STB:\r
+ *   STB field of register LCR.\r
+ *------------------------------------------------------------------------------\r
+ * Number of Stop Bits: 0 - 1 stop bit; 1 - 1½ stop bits when WLS = 00, 2 stop \r
+ * bits in other cases\r
+ */\r
+#define LCR_STB_OFFSET   0x0CU\r
+#define LCR_STB_MASK     0x04U\r
+#define LCR_STB_SHIFT    2U\r
+\r
+/*------------------------------------------------------------------------------\r
+ * LCR_PEN:\r
+ *   PEN field of register LCR.\r
+ *------------------------------------------------------------------------------\r
+ * Parity Enable 0 - Disabled; 1 - Enabled. Parity is added in transmission and \r
+ * checked in receiving.\r
+ */\r
+#define LCR_PEN_OFFSET   0x0CU\r
+#define LCR_PEN_MASK     0x08U\r
+#define LCR_PEN_SHIFT    3U\r
+\r
+/*------------------------------------------------------------------------------\r
+ * LCR_EPS:\r
+ *   EPS field of register LCR.\r
+ *------------------------------------------------------------------------------\r
+ * Even Parity Select 0 - Odd parity; 1 - Even parity\r
+ */\r
+#define LCR_EPS_OFFSET   0x0CU\r
+#define LCR_EPS_MASK     0x10U\r
+#define LCR_EPS_SHIFT    4U\r
+\r
+/*------------------------------------------------------------------------------\r
+ * LCR_SP:\r
+ *   SP field of register LCR.\r
+ *------------------------------------------------------------------------------\r
+ * Stick Parity 0 - Disabled; 1 - Enabled When stick parity is enabled, it \r
+ * works as follows: Bits 4..3, 11 - 0 will be sent as a parity bit, and \r
+ * checked in receiving.  01 - 1 will be sent as a parity bit, and checked in \r
+ * receiving.\r
+ */\r
+#define LCR_SP_OFFSET   0x0CU\r
+#define LCR_SP_MASK     0x20U\r
+#define LCR_SP_SHIFT    5U\r
+\r
+/*------------------------------------------------------------------------------\r
+ * LCR_SB:\r
+ *   SB field of register LCR.\r
+ *------------------------------------------------------------------------------\r
+ * Set Break 0 - Disabled 1 - Set break. SOUT is forced to 0. This does not \r
+ * have any effect on transmitter logic. The break is disabled by setting the \r
+ * bit to 0.\r
+ */\r
+#define LCR_SB_OFFSET   0x0CU\r
+#define LCR_SB_MASK     0x40U\r
+#define LCR_SB_SHIFT    6U\r
+\r
+/*------------------------------------------------------------------------------\r
+ * LCR_DLAB:\r
+ *   DLAB field of register LCR.\r
+ *------------------------------------------------------------------------------\r
+ * Divisor Latch Access Bit 0 - Disabled. Normal addressing mode in use 1 - \r
+ * Enabled. Enables access to the Divisor Latch registers during read or write \r
+ * operation to addresses 0 and 1.\r
+ */\r
+#define LCR_DLAB_OFFSET   0x0CU\r
+#define LCR_DLAB_MASK     0x80U\r
+#define LCR_DLAB_SHIFT    7U\r
+\r
+/*******************************************************************************\r
+ * MCR register:\r
+ *------------------------------------------------------------------------------\r
+ * Modem Control Register\r
+ */\r
+#define MCR_REG_OFFSET 0x10U\r
+\r
+/*------------------------------------------------------------------------------\r
+ * MCR_DTR:\r
+ *   DTR field of register MCR.\r
+ *------------------------------------------------------------------------------\r
+ * Controls the Data Terminal Ready (DTRn) output.  0 - DTRn <= 1; 1 - DTRn <= 0\r
+ */\r
+#define MCR_DTR_OFFSET   0x10U\r
+#define MCR_DTR_MASK     0x01U\r
+#define MCR_DTR_SHIFT    0U\r
+\r
+/*------------------------------------------------------------------------------\r
+ * MCR_RTS:\r
+ *   RTS field of register MCR.\r
+ *------------------------------------------------------------------------------\r
+ * Controls the Request to Send (RTSn) output.  0 - RTSn <= 1; 1 - RTSn <= 0\r
+ */\r
+#define MCR_RTS_OFFSET   0x10U\r
+#define MCR_RTS_MASK     0x02U\r
+#define MCR_RTS_SHIFT    1U\r
+\r
+/*------------------------------------------------------------------------------\r
+ * MCR_Out1:\r
+ *   Out1 field of register MCR.\r
+ *------------------------------------------------------------------------------\r
+ * Controls the Output1 (OUT1n) signal.  0 - OUT1n <= 1; 1 - OUT1n <= 0\r
+ */\r
+#define MCR_OUT1_OFFSET   0x10U\r
+#define MCR_OUT1_MASK     0x04U\r
+#define MCR_OUT1_SHIFT    2U\r
+\r
+/*------------------------------------------------------------------------------\r
+ * MCR_Out2:\r
+ *   Out2 field of register MCR.\r
+ *------------------------------------------------------------------------------\r
+ * Controls the Output2 (OUT2n) signal.  0 - OUT2n <=1; 1 - OUT2n <=0\r
+ */\r
+#define MCR_OUT2_OFFSET   0x10U\r
+#define MCR_OUT2_MASK     0x08U\r
+#define MCR_OUT2_SHIFT    3U\r
+\r
+/*------------------------------------------------------------------------------\r
+ * MCR_Loop:\r
+ *   Loop field of register MCR.\r
+ *------------------------------------------------------------------------------\r
+ * Loop enable bit 0 - Disabled; 1 - Enabled. The following happens in loop \r
+ * mode: SOUT is set to 1. The SIN, DSRn, CTSn, RIn, and DCDn inputs are \r
+ * disconnected.  The output of the Transmitter Shift Register is looped back \r
+ * into the Receiver Shift Register. The modem control outputs (DTRn, RTSn, \r
+ * OUT1n, and OUT2n) are connected internally to the modem control inputs, and \r
+ * the modem control output pins are set at 1. In loopback mode, the \r
+ * transmitted data is immediately received, allowing the CPU to check the \r
+ * operation of the UART. The interrupts are operating in loop mode.\r
+ */\r
+#define MCR_LOOP_OFFSET   0x10U\r
+#define MCR_LOOP_MASK     0x10U\r
+#define MCR_LOOP_SHIFT    4U\r
+\r
+/*******************************************************************************\r
+ * LSR register:\r
+ *------------------------------------------------------------------------------\r
+ * Line Status Register\r
+ */\r
+#define LSR_REG_OFFSET 0x14U\r
+\r
+/*------------------------------------------------------------------------------\r
+ * LSR_DR:\r
+ *   DR field of register LSR.\r
+ *------------------------------------------------------------------------------\r
+ * Data Ready indicator 1 when a data byte has been received and stored in the \r
+ * FIFO. DR is cleared to 0 when the CPU reads the data from the FIFO.\r
+ */\r
+#define LSR_DR_OFFSET   0x14U\r
+#define LSR_DR_MASK     0x01U\r
+#define LSR_DR_SHIFT    0U\r
+\r
+/*------------------------------------------------------------------------------\r
+ * LSR_OE:\r
+ *   OE field of register LSR.\r
+ *------------------------------------------------------------------------------\r
+ * Overrun Error indicator Indicates that the new byte was received before the \r
+ * CPU read the byte from the receive buffer, and that the earlier data byte \r
+ * was destroyed. OE is cleared when the CPU reads the Line Status Register. If \r
+ * the data continues to fill the FIFO beyond the trigger level, an overrun \r
+ * error will occur once the FIFO is full and the next character has been \r
+ * completely received in the shift register. The character in the shift \r
+ * register is overwritten, but it is not transferred to the FIFO.\r
+ */\r
+#define LSR_OE_OFFSET   0x14U\r
+#define LSR_OE_MASK     0x02U\r
+#define LSR_OE_SHIFT    1U\r
+\r
+/*------------------------------------------------------------------------------\r
+ * LSR_PE:\r
+ *   PE field of register LSR.\r
+ *------------------------------------------------------------------------------\r
+ * Parity Error indicator Indicates that the received byte had a parity error. \r
+ * PE is cleared when the CPU reads the Line Status Register. This error is \r
+ * revealed to the CPU when its associated character is at the top of the FIFO.\r
+ */\r
+#define LSR_PE_OFFSET   0x14U\r
+#define LSR_PE_MASK     0x04U\r
+#define LSR_PE_SHIFT    2U\r
+\r
+/*------------------------------------------------------------------------------\r
+ * LSR_FE:\r
+ *   FE field of register LSR.\r
+ *------------------------------------------------------------------------------\r
+ *  Framing Error indicator Indicates that the received byte did not have a \r
+ * valid Stop bit. FE is cleared when the CPU reads the Line Status Register. \r
+ * The UART will try to re-synchronize after a framing error. To do this, it\r
+ * assumes that the framing error was due to the next start bit, so it samples \r
+ * this start bit twice, and then starts receiving the data.  This error is \r
+ * revealed to the CPU when its associated character is at the top of the FIFO.\r
+ */\r
+#define LSR_FE_OFFSET   0x14U\r
+#define LSR_FE_MASK     0x08U\r
+#define LSR_FE_SHIFT    3U\r
+\r
+/*------------------------------------------------------------------------------\r
+ * LSR_BI:\r
+ *   BI field of register LSR.\r
+ *------------------------------------------------------------------------------\r
+ * Break Interrupt indicator Indicates that the received data is at 0 longer \r
+ * than a full word transmission time (start bit + data bits + parity + stop \r
+ * bits). BI is cleared when the CPU reads the Line Status Register. This error \r
+ * is revealed to the CPU when its associated character is at the top of the \r
+ * FIFO. When break occurs, only one zero character is loaded into the FIFO.\r
+ */\r
+#define LSR_BI_OFFSET   0x14U\r
+#define LSR_BI_MASK     0x10U\r
+#define LSR_BI_SHIFT    4U\r
+\r
+/*------------------------------------------------------------------------------\r
+ * LSR_THRE:\r
+ *   THRE field of register LSR.\r
+ *------------------------------------------------------------------------------\r
+ *  Transmitter Holding Register Empty indicator Indicates that the UART is \r
+ * ready to transmit a new data byte. THRE causes an interrupt to the CPU when \r
+ * bit 1 (ETBEI) in the Interrupt Enable Register is 1.  This bit is set when \r
+ * the TX FIFO is empty. It is cleared when at least one byte is written to the \r
+ * TX FIFO.\r
+ */\r
+#define LSR_THRE_OFFSET   0x14U\r
+#define LSR_THRE_MASK     0x20U\r
+#define LSR_THRE_SHIFT    5U\r
+\r
+/*------------------------------------------------------------------------------\r
+ * LSR_TEMT:\r
+ *   TEMT field of register LSR.\r
+ *------------------------------------------------------------------------------\r
+ *  Transmitter Empty indicator This bit is set to 1 when both the transmitter \r
+ * FIFO and shift registers are empty.\r
+ */\r
+#define LSR_TEMT_OFFSET   0x14U\r
+#define LSR_TEMT_MASK     0x40U\r
+#define LSR_TEMT_SHIFT    6U\r
+\r
+/*------------------------------------------------------------------------------\r
+ * LSR_FIER:\r
+ *   FIER field of register LSR.\r
+ *------------------------------------------------------------------------------\r
+ *  This bit is set when there is at least one parity error, framing error, or \r
+ * break indication in the FIFO. FIER is cleared when the CPU reads the LSR if \r
+ * there are no subsequent errors in the FIFO.\r
+ */\r
+#define LSR_FIER_OFFSET   0x14U\r
+#define LSR_FIER_MASK     0x80U\r
+#define LSR_FIER_SHIFT    7U\r
+\r
+/*******************************************************************************\r
+ * MSR register:\r
+ *------------------------------------------------------------------------------\r
+ * Modem Status Register\r
+ */\r
+#define MSR_REG_OFFSET 0x18U\r
+\r
+/*------------------------------------------------------------------------------\r
+ * MSR_DCTS:\r
+ *   DCTS field of register MSR.\r
+ *------------------------------------------------------------------------------\r
+ * Delta Clear to Send indicator.  Indicates that the CTSn input has changed \r
+ * state since the last time it was read by the CPU.\r
+ */\r
+#define MSR_DCTS_OFFSET   0x18U\r
+#define MSR_DCTS_MASK     0x01U\r
+#define MSR_DCTS_SHIFT    0U\r
+\r
+/*------------------------------------------------------------------------------\r
+ * MSR_DDSR:\r
+ *   DDSR field of register MSR.\r
+ *------------------------------------------------------------------------------\r
+ * Delta Data Set Ready indicator Indicates that the DSRn input has changed \r
+ * state since the last time it was read by the CPU.\r
+ */\r
+#define MSR_DDSR_OFFSET   0x18U\r
+#define MSR_DDSR_MASK     0x02U\r
+#define MSR_DDSR_SHIFT    1U\r
+\r
+/*------------------------------------------------------------------------------\r
+ * MSR_TERI:\r
+ *   TERI field of register MSR.\r
+ *------------------------------------------------------------------------------\r
+ * Trailing Edge of Ring Indicator detector. Indicates that RI input has \r
+ * changed from 0 to 1.\r
+ */\r
+#define MSR_TERI_OFFSET   0x18U\r
+#define MSR_TERI_MASK     0x04U\r
+#define MSR_TERI_SHIFT    2U\r
+\r
+/*------------------------------------------------------------------------------\r
+ * MSR_DDCD:\r
+ *   DDCD field of register MSR.\r
+ *------------------------------------------------------------------------------\r
+ * Delta Data Carrier Detect indicator Indicates that DCD input has changed \r
+ * state.  NOTE: Whenever bit 0, 1, 2, or 3 is set to 1, a Modem Status \r
+ * Interrupt is generated.\r
+ */\r
+#define MSR_DDCD_OFFSET   0x18U\r
+#define MSR_DDCD_MASK     0x08U\r
+#define MSR_DDCD_SHIFT    3U\r
+\r
+/*------------------------------------------------------------------------------\r
+ * MSR_CTS:\r
+ *   CTS field of register MSR.\r
+ *------------------------------------------------------------------------------\r
+ * Clear to Send The complement of the CTSn input. When bit 4 of the Modem \r
+ * Control Register (MCR) is set to 1 (loop), this bit is equivalent to DTR in \r
+ * the MCR.\r
+ */\r
+#define MSR_CTS_OFFSET   0x18U\r
+#define MSR_CTS_MASK     0x10U\r
+#define MSR_CTS_SHIFT    4U\r
+\r
+/*------------------------------------------------------------------------------\r
+ * MSR_DSR:\r
+ *   DSR field of register MSR.\r
+ *------------------------------------------------------------------------------\r
+ * Data Set Ready The complement of the DSR input. When bit 4 of the MCR is set \r
+ * to 1 (loop), this bit is equivalent to RTSn in the MCR.\r
+ */\r
+#define MSR_DSR_OFFSET   0x18U\r
+#define MSR_DSR_MASK     0x20U\r
+#define MSR_DSR_SHIFT    5U\r
+\r
+/*------------------------------------------------------------------------------\r
+ * MSR_RI:\r
+ *   RI field of register MSR.\r
+ *------------------------------------------------------------------------------\r
+ * Ring Indicator The complement of the RIn input. When bit 4 of the MCR is set \r
+ * to 1 (loop), this bit is equivalent to OUT1 in the MCR.\r
+ */\r
+#define MSR_RI_OFFSET   0x18U\r
+#define MSR_RI_MASK     0x40U\r
+#define MSR_RI_SHIFT    6U\r
+\r
+/*------------------------------------------------------------------------------\r
+ * MSR_DCD:\r
+ *   DCD field of register MSR.\r
+ *------------------------------------------------------------------------------\r
+ * Data Carrier Detect The complement of DCDn input. When bit 4 of the MCR is \r
+ * set to 1 (loop), this bit is equivalent to OUT2 in the MCR.\r
+ */\r
+#define MSR_DCD_OFFSET   0x18U\r
+#define MSR_DCD_MASK     0x80U\r
+#define MSR_DCD_SHIFT    7U\r
+\r
+/*******************************************************************************\r
+ * SR register:\r
+ *------------------------------------------------------------------------------\r
+ * Scratch Register\r
+ */\r
+#define SR_REG_OFFSET  0x1CU\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* CORE_16550_REGISTERS_H_*/\r
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 (file)
index 0000000..ca735e6
--- /dev/null
@@ -0,0 +1,865 @@
+/*******************************************************************************\r
+ * (c) Copyright 2007-2015 Microsemi SoC Products Group. All rights reserved.\r
+ *\r
+ * Core16550 driver implementation. See file "core_16550.h" for a\r
+ * description of the functions implemented in this file.\r
+ *\r
+ * SVN $Revision: 7963 $\r
+ * SVN $Date: 2015-10-09 17:58:21 +0530 (Fri, 09 Oct 2015) $\r
+ */\r
+#include "hal.h"\r
+#include "core_16550.h"\r
+#include "core16550_regs.h"\r
+#include "hal_assert.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+/*******************************************************************************\r
+ * Definitions for transmitter states\r
+ */\r
+#define TX_COMPLETE     0x00U\r
+\r
+/*******************************************************************************\r
+ * Definition for transmitter FIFO size\r
+ */\r
+#define TX_FIFO_SIZE    16U\r
+\r
+/*******************************************************************************\r
+ * Default receive interrupt trigger level\r
+ */\r
+#define DEFAULT_RX_TRIG_LEVEL  ((uint8_t)UART_16550_FIFO_SINGLE_BYTE)\r
+\r
+/*******************************************************************************\r
+ * Receiver error status mask and shift offset\r
+ */\r
+#define STATUS_ERROR_MASK   ( LSR_OE_MASK | LSR_PE_MASK |  \\r
+                              LSR_FE_MASK | LSR_BI_MASK | LSR_FIER_MASK)\r
+\r
+/*******************************************************************************\r
+ * Definitions for invalid parameters with proper type\r
+ */\r
+#define INVALID_INTERRUPT   0U\r
+#define INVALID_IRQ_HANDLER ( (uart_16550_irq_handler_t) 0 )\r
+\r
+/*******************************************************************************\r
+ * Possible values for Interrupt Identification Register Field.\r
+ */\r
+#define IIRF_MODEM_STATUS       0x00U\r
+#define IIRF_THRE               0x02U\r
+#define IIRF_RX_DATA            0x04U\r
+#define IIRF_RX_LINE_STATUS     0x06U\r
+#define IIRF_DATA_TIMEOUT       0x0CU\r
+\r
+/*******************************************************************************\r
+ * Null parameters with appropriate type definitions\r
+ */\r
+#define NULL_ADDR       ( ( addr_t ) 0 )\r
+#define NULL_INSTANCE   ( ( uart_16550_instance_t * ) 0 )\r
+#define NULL_BUFF       ( ( uint8_t * ) 0 )\r
+\r
+/*******************************************************************************\r
+ * Possible states for different register bit fields\r
+ */\r
+enum {\r
+    DISABLE = 0U,\r
+    ENABLE  = 1U\r
+};\r
+\r
+/*******************************************************************************\r
+ * Static function declarations\r
+ */\r
+static void default_tx_handler(uart_16550_instance_t * this_uart);\r
+\r
+/*******************************************************************************\r
+ * Public function definitions\r
+ */\r
+\r
+/***************************************************************************//**\r
+ * UART_16550_init.\r
+ * See core_16550.h for details of how to use this function.\r
+ */\r
+void\r
+UART_16550_init\r
+(\r
+    uart_16550_instance_t* this_uart,\r
+    addr_t base_addr,\r
+    uint16_t baud_value,\r
+    uint8_t line_config\r
+)\r
+{\r
+#ifndef NDEBUG\r
+    uint8_t dbg1;\r
+    uint8_t dbg2;\r
+#endif\r
+    uint8_t fifo_config;\r
+    uint8_t temp;\r
+\r
+    HAL_ASSERT( base_addr != NULL_ADDR );\r
+    HAL_ASSERT( this_uart != NULL_INSTANCE );\r
+\r
+    if( ( base_addr != NULL_ADDR ) && ( this_uart != NULL_INSTANCE ) )\r
+    {\r
+        /* disable interrupts */\r
+        HAL_set_8bit_reg(base_addr, IER, DISABLE);\r
+\r
+        /* reset divisor latch */\r
+        HAL_set_8bit_reg_field(base_addr, LCR_DLAB, ENABLE);\r
+#ifndef NDEBUG\r
+        dbg1 =  HAL_get_8bit_reg_field(base_addr, LCR_DLAB );\r
+        HAL_ASSERT( dbg1 == ENABLE );\r
+#endif\r
+        /* MSB of baud value */\r
+        temp = (uint8_t)(baud_value >> 8);\r
+        HAL_set_8bit_reg(base_addr, DMR, temp );\r
+        /* LSB of baud value */\r
+        HAL_set_8bit_reg(base_addr, DLR, ( (uint8_t)baud_value ) );\r
+#ifndef NDEBUG\r
+        dbg1 =  HAL_get_8bit_reg(base_addr, DMR );\r
+        dbg2 =  HAL_get_8bit_reg(base_addr, DLR );\r
+        HAL_ASSERT( ( ( ( (uint16_t) dbg1 ) << 8 ) | dbg2 ) == baud_value );\r
+#endif\r
+        /* reset divisor latch */\r
+        HAL_set_8bit_reg_field(base_addr, LCR_DLAB, DISABLE);\r
+#ifndef NDEBUG\r
+        dbg1 =  HAL_get_8bit_reg_field(base_addr, LCR_DLAB );\r
+        HAL_ASSERT( dbg1 == DISABLE );\r
+#endif\r
+        /* set the line control register (bit length, stop bits, parity) */\r
+        HAL_set_8bit_reg( base_addr, LCR, line_config );\r
+#ifndef NDEBUG\r
+        dbg1 =  HAL_get_8bit_reg(base_addr, LCR );\r
+        HAL_ASSERT( dbg1 == line_config)\r
+#endif\r
+        /* Enable and configure the RX and TX FIFOs. */\r
+        fifo_config = ((uint8_t)(DEFAULT_RX_TRIG_LEVEL << FCR_TRIG_LEVEL_SHIFT) |\r
+                                 FCR_RDYN_EN_MASK | FCR_CLEAR_RX_MASK |\r
+                                 FCR_CLEAR_TX_MASK | FCR_ENABLE_MASK );\r
+        HAL_set_8bit_reg( base_addr, FCR, fifo_config );\r
+\r
+        /* disable loopback */\r
+        HAL_set_8bit_reg_field( base_addr, MCR_LOOP, DISABLE );\r
+#ifndef NDEBUG\r
+        dbg1 =  HAL_get_8bit_reg_field(base_addr, MCR_LOOP);\r
+        HAL_ASSERT( dbg1 == DISABLE );\r
+#endif\r
+\r
+        /* Instance setup */\r
+        this_uart->base_address = base_addr;\r
+        this_uart->tx_buffer    = NULL_BUFF;\r
+        this_uart->tx_buff_size = TX_COMPLETE;\r
+        this_uart->tx_idx       = 0U;\r
+        this_uart->tx_handler   = default_tx_handler;\r
+\r
+        this_uart->rx_handler  = ( (uart_16550_irq_handler_t) 0 );\r
+        this_uart->linests_handler  = ( (uart_16550_irq_handler_t) 0 );\r
+        this_uart->modemsts_handler = ( (uart_16550_irq_handler_t) 0 );\r
+        this_uart->status = 0U;\r
+    }\r
+}\r
+\r
+/***************************************************************************//**\r
+ * UART_16550_polled_tx.\r
+ * See core_16550.h for details of how to use this function.\r
+ */\r
+void\r
+UART_16550_polled_tx\r
+(\r
+    uart_16550_instance_t * this_uart,\r
+    const uint8_t * pbuff,\r
+    uint32_t tx_size\r
+)\r
+{\r
+    uint32_t char_idx = 0U;\r
+    uint32_t size_sent;\r
+    uint8_t status;\r
+\r
+    HAL_ASSERT( this_uart != NULL_INSTANCE );\r
+    HAL_ASSERT( pbuff != NULL_BUFF );\r
+    HAL_ASSERT( tx_size > 0U );\r
+\r
+    if( ( this_uart != NULL_INSTANCE ) &&\r
+        ( pbuff != NULL_BUFF ) &&\r
+        ( tx_size > 0U ) )\r
+    {\r
+        /* Remain in this loop until the entire input buffer\r
+         * has been transferred to the UART.\r
+         */\r
+        do {\r
+            /* Read the Line Status Register and update the sticky record */\r
+            status = HAL_get_8bit_reg( this_uart->base_address, LSR );\r
+            this_uart->status |= status;\r
+\r
+            /* Check if TX FIFO is empty. */\r
+            if( status & LSR_THRE_MASK )\r
+            {\r
+                uint32_t fill_size = TX_FIFO_SIZE;\r
+\r
+                /* Calculate the number of bytes to transmit. */\r
+                if ( tx_size < TX_FIFO_SIZE )\r
+                {\r
+                    fill_size = tx_size;\r
+                }\r
+\r
+                /* Fill the TX FIFO with the calculated the number of bytes. */\r
+                for ( size_sent = 0U; size_sent < fill_size; ++size_sent )\r
+                {\r
+                    /* Send next character in the buffer. */\r
+                    HAL_set_8bit_reg( this_uart->base_address, THR,\r
+                                      (uint_fast8_t)pbuff[char_idx++]);\r
+                }\r
+\r
+                /* Calculate the number of untransmitted bytes remaining. */\r
+                tx_size -= size_sent;\r
+            }\r
+        } while ( tx_size );\r
+    }\r
+}\r
+\r
+/***************************************************************************//**\r
+ * UART_16550_polled_tx_string.\r
+ * See core_16550.h for details of how to use this function.\r
+ */\r
+void\r
+UART_16550_polled_tx_string\r
+(\r
+    uart_16550_instance_t * this_uart,\r
+    const uint8_t * p_sz_string\r
+)\r
+{\r
+    uint32_t char_idx = 0U;\r
+    uint32_t fill_size;\r
+    uint_fast8_t data_byte;\r
+    uint8_t status;\r
+\r
+    HAL_ASSERT( this_uart != NULL_INSTANCE );\r
+    HAL_ASSERT( p_sz_string != NULL_BUFF );\r
+\r
+    if( ( this_uart != NULL_INSTANCE ) && ( p_sz_string != NULL_BUFF ) )\r
+    {\r
+        char_idx = 0U;\r
+\r
+        /* Get the first data byte from the input buffer */\r
+        data_byte = (uint_fast8_t)p_sz_string[char_idx];\r
+\r
+        /* First check for the NULL terminator byte.\r
+         * Then remain in this loop until the entire string in the input buffer\r
+         * has been transferred to the UART.\r
+         */\r
+        while ( 0U != data_byte )\r
+        {\r
+            /* Wait until TX FIFO is empty. */\r
+            do {\r
+                status = HAL_get_8bit_reg( this_uart->base_address,LSR);\r
+                this_uart->status |= status;\r
+            } while ( !( status & LSR_THRE_MASK ) );\r
+\r
+            /* Send bytes from the input buffer until the TX FIFO is full\r
+             * or we reach the NULL terminator byte.\r
+             */\r
+            fill_size = 0U;\r
+            while ( (0U != data_byte) && (fill_size < TX_FIFO_SIZE) )\r
+            {\r
+                /* Send the data byte */\r
+                HAL_set_8bit_reg( this_uart->base_address, THR, data_byte );\r
+                ++fill_size;\r
+                char_idx++;\r
+                /* Get the next data byte from the input buffer */\r
+                data_byte = (uint_fast8_t)p_sz_string[char_idx];\r
+            }\r
+        }\r
+    }\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * UART_16550_irq_tx.\r
+ * See core_16550.h for details of how to use this function.\r
+ */\r
+void\r
+UART_16550_irq_tx\r
+(\r
+    uart_16550_instance_t * this_uart,\r
+    const uint8_t * pbuff,\r
+    uint32_t tx_size\r
+)\r
+{\r
+    HAL_ASSERT( this_uart != NULL_INSTANCE )\r
+    HAL_ASSERT( pbuff != NULL_BUFF )\r
+    HAL_ASSERT( tx_size > 0U )\r
+\r
+    if( ( this_uart != NULL_INSTANCE ) &&\r
+        ( pbuff != NULL_BUFF ) &&\r
+        ( tx_size > 0U ) )\r
+    {\r
+        /*Initialize the UART instance with\r
+          parameters required for transmission.*/\r
+        this_uart->tx_buffer = pbuff;\r
+        this_uart->tx_buff_size = tx_size;\r
+        /* char_idx; */\r
+        this_uart->tx_idx = 0U;\r
+        /* assign handler for default data transmission */\r
+        this_uart->tx_handler = default_tx_handler;\r
+\r
+        /* enables TX interrupt */\r
+        HAL_set_8bit_reg_field(this_uart->base_address, IER_ETBEI, ENABLE);\r
+    }\r
+}\r
+\r
+/***************************************************************************//**\r
+ * UART_16550_tx_complete.\r
+ * See core_16550.h for details of how to use this function.\r
+ */\r
+int8_t\r
+UART_16550_tx_complete\r
+(\r
+    uart_16550_instance_t * this_uart\r
+)\r
+{\r
+    int8_t returnvalue = 0;\r
+    uint8_t status = 0U;\r
+\r
+    HAL_ASSERT( this_uart != NULL_INSTANCE )\r
+\r
+    if( this_uart != NULL_INSTANCE )\r
+    {\r
+        status = HAL_get_8bit_reg(this_uart->base_address,LSR);\r
+        this_uart->status |= status;\r
+\r
+        if( ( this_uart->tx_buff_size == TX_COMPLETE ) &&\r
+                             ( status & LSR_TEMT_MASK ) )\r
+        {\r
+            returnvalue = (int8_t)1;\r
+        }\r
+    }\r
+    return returnvalue;\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * UART_16550_get_rx.\r
+ * See core_16550.h for details of how to use this function.\r
+ */\r
+size_t\r
+UART_16550_get_rx\r
+(\r
+    uart_16550_instance_t * this_uart,\r
+    uint8_t * rx_buff,\r
+    size_t buff_size\r
+)\r
+{\r
+    uint8_t status;\r
+    size_t rx_size = 0U;\r
+\r
+    HAL_ASSERT( this_uart != NULL_INSTANCE )\r
+    HAL_ASSERT( rx_buff != (uint8_t *)0 )\r
+    HAL_ASSERT( buff_size > 0U )\r
+\r
+    if( ( this_uart != NULL_INSTANCE ) &&\r
+        ( rx_buff != (uint8_t *)0 ) &&\r
+        ( buff_size > 0U ) )\r
+    {\r
+        status = HAL_get_8bit_reg( this_uart->base_address, LSR );\r
+        this_uart->status |= status;\r
+        while ( ((status & LSR_DR_MASK) != 0U) && ( rx_size < buff_size ) )\r
+        {\r
+            rx_buff[rx_size] = HAL_get_8bit_reg( this_uart->base_address, RBR );\r
+            rx_size++;\r
+            status = HAL_get_8bit_reg( this_uart->base_address, LSR );\r
+            this_uart->status |= status;\r
+        }\r
+    }\r
+    return rx_size;\r
+}\r
+\r
+/***************************************************************************//**\r
+ * UART_16550_isr.\r
+ * See core_16550.h for details of how to use this function.\r
+ */\r
+void\r
+UART_16550_isr\r
+(\r
+    uart_16550_instance_t * this_uart\r
+)\r
+{\r
+    uint8_t iirf;\r
+\r
+    HAL_ASSERT( this_uart != NULL_INSTANCE )\r
+\r
+    if(this_uart != NULL_INSTANCE )\r
+    {\r
+        iirf = HAL_get_8bit_reg_field( this_uart->base_address, IIR_IIR );\r
+\r
+        switch ( iirf )\r
+        {\r
+            /* Modem status interrupt */\r
+            case IIRF_MODEM_STATUS:\r
+            {\r
+                if( INVALID_IRQ_HANDLER != this_uart->modemsts_handler  )\r
+                {\r
+                    HAL_ASSERT( INVALID_IRQ_HANDLER != this_uart->modemsts_handler );\r
+                    if( INVALID_IRQ_HANDLER != this_uart->modemsts_handler )\r
+                    {\r
+                        (*(this_uart->modemsts_handler))(this_uart);\r
+                    }\r
+                }\r
+            }\r
+            break;\r
+            /* Transmitter Holding Register Empty interrupt */\r
+            case IIRF_THRE:\r
+            {\r
+                HAL_ASSERT( INVALID_IRQ_HANDLER != this_uart->tx_handler );\r
+                if ( INVALID_IRQ_HANDLER != this_uart->tx_handler )\r
+                {\r
+                    (*(this_uart->tx_handler))(this_uart);\r
+                }\r
+            }\r
+            break;\r
+            /* Received Data Available interrupt */\r
+            case IIRF_RX_DATA:\r
+            case IIRF_DATA_TIMEOUT:\r
+            {\r
+                HAL_ASSERT( INVALID_IRQ_HANDLER != this_uart->rx_handler );\r
+                if ( INVALID_IRQ_HANDLER != this_uart->rx_handler )\r
+                {\r
+                    (*(this_uart->rx_handler))(this_uart);\r
+                }\r
+            }\r
+            break;\r
+            /* Line status interrupt */\r
+            case IIRF_RX_LINE_STATUS:\r
+            {\r
+                HAL_ASSERT( INVALID_IRQ_HANDLER != this_uart->linests_handler );\r
+                if ( INVALID_IRQ_HANDLER != this_uart->linests_handler )\r
+                {\r
+                    (*(this_uart->linests_handler))(this_uart);\r
+                }\r
+            }\r
+            break;\r
+            /* Unidentified interrupt */\r
+            default:\r
+            {\r
+                HAL_ASSERT( INVALID_INTERRUPT )\r
+            }\r
+        }\r
+    }\r
+}\r
+\r
+/***************************************************************************//**\r
+ * UART_16550_set_rx_handler.\r
+ * See core_16550.h for details of how to use this function.\r
+ */\r
+void\r
+UART_16550_set_rx_handler\r
+(\r
+    uart_16550_instance_t * this_uart,\r
+    uart_16550_irq_handler_t handler,\r
+    uart_16550_rx_trig_level_t trigger_level\r
+)\r
+{\r
+    HAL_ASSERT( this_uart != NULL_INSTANCE )\r
+    HAL_ASSERT( handler != INVALID_IRQ_HANDLER)\r
+    HAL_ASSERT( trigger_level < UART_16550_FIFO_INVALID_TRIG_LEVEL)\r
+\r
+    if( ( this_uart != NULL_INSTANCE ) &&\r
+        ( handler != INVALID_IRQ_HANDLER) &&\r
+        ( trigger_level < UART_16550_FIFO_INVALID_TRIG_LEVEL) )\r
+    {\r
+        this_uart->rx_handler = handler;\r
+\r
+        /* Set the receive interrupt trigger level. */\r
+        HAL_set_8bit_reg_field( this_uart->base_address,\r
+                            FCR_TRIG_LEVEL, trigger_level );\r
+\r
+        /* Enable receive interrupt. */\r
+        HAL_set_8bit_reg_field( this_uart->base_address, IER_ERBFI, ENABLE );\r
+    }\r
+}\r
+\r
+/***************************************************************************//**\r
+ * UART_16550_set_loopback.\r
+ * See core_16550.h for details of how to use this function.\r
+ */\r
+void\r
+UART_16550_set_loopback\r
+(\r
+    uart_16550_instance_t * this_uart,\r
+    uart_16550_loopback_t loopback\r
+)\r
+{\r
+    HAL_ASSERT( this_uart != NULL_INSTANCE );\r
+    HAL_ASSERT( loopback < UART_16550_INVALID_LOOPBACK );\r
+\r
+    if( ( this_uart != NULL_INSTANCE ) &&\r
+        ( loopback < UART_16550_INVALID_LOOPBACK ) )\r
+    {\r
+        if ( loopback == UART_16550_LOOPBACK_OFF )\r
+        {\r
+            HAL_set_8bit_reg_field( this_uart->base_address,\r
+                                    MCR_LOOP,\r
+                                    DISABLE );\r
+        }\r
+        else\r
+        {\r
+            HAL_set_8bit_reg_field( this_uart->base_address,\r
+                                    MCR_LOOP,\r
+                                    ENABLE );\r
+        }\r
+    }\r
+}\r
+\r
+/***************************************************************************//**\r
+ * UART_16550_get_rx_status.\r
+ * See core_16550.h for details of how to use this function.\r
+ */\r
+uint8_t\r
+UART_16550_get_rx_status\r
+(\r
+    uart_16550_instance_t * this_uart\r
+)\r
+{\r
+    uint8_t status = UART_16550_INVALID_PARAM;\r
+    HAL_ASSERT( this_uart != NULL_INSTANCE );\r
+\r
+    if( ( this_uart != NULL_INSTANCE ) )\r
+    {\r
+        /*\r
+         * Bit 1 - Overflow error status\r
+         * Bit 2 - Parity error status\r
+         * Bit 3 - Frame error status\r
+         * Bit 4 - Break interrupt indicator\r
+         * Bit 7 - FIFO data error status\r
+         */\r
+        this_uart->status |= HAL_get_8bit_reg( this_uart->base_address, LSR );\r
+        status = ( this_uart->status & STATUS_ERROR_MASK );\r
+        /*\r
+         * Clear the sticky status for this instance.\r
+         */\r
+        this_uart->status = (uint8_t)0;\r
+    }\r
+    return status;\r
+}\r
+\r
+/***************************************************************************//**\r
+ * UART_16550_get_modem_status.\r
+ * See core_16550.h for details of how to use this function.\r
+ */\r
+uint8_t\r
+UART_16550_get_modem_status\r
+(\r
+    uart_16550_instance_t * this_uart\r
+)\r
+{\r
+    uint8_t status = UART_16550_NO_ERROR;\r
+    HAL_ASSERT( this_uart != NULL_INSTANCE )\r
+\r
+    if( ( this_uart != NULL_INSTANCE ) )\r
+    {\r
+        /*\r
+         * Extract UART error status and place in lower bits of "status".\r
+         * Bit 0 - Delta Clear to Send Indicator\r
+         * Bit 1 - Delta Clear to Receive Indicator\r
+         * Bit 2 - Trailing edge of Ring Indicator detector\r
+         * Bit 3 - Delta Data Carrier Detect indicator\r
+         * Bit 4 - Clear To Send\r
+         * Bit 5 - Data Set Ready\r
+         * Bit 6 - Ring Indicator\r
+         * Bit 7 - Data Carrier Detect\r
+         */\r
+        status = HAL_get_8bit_reg( this_uart->base_address, MSR );\r
+    }\r
+    return status;\r
+}\r
+\r
+/***************************************************************************//**\r
+ * Default TX interrupt handler to automatically transmit data from\r
+ * user assgined TX buffer.\r
+ */\r
+static void\r
+default_tx_handler\r
+(\r
+    uart_16550_instance_t * this_uart\r
+)\r
+{\r
+    uint8_t status;\r
+\r
+    HAL_ASSERT( NULL_INSTANCE != this_uart )\r
+\r
+    if ( this_uart != NULL_INSTANCE )\r
+    {\r
+        HAL_ASSERT( NULL_BUFF != this_uart->tx_buffer )\r
+        HAL_ASSERT( 0U != this_uart->tx_buff_size )\r
+\r
+        if ( ( this_uart->tx_buffer != NULL_BUFF ) &&\r
+             ( 0U != this_uart->tx_buff_size ) )\r
+        {\r
+            /* Read the Line Status Register and update the sticky record. */\r
+            status = HAL_get_8bit_reg( this_uart->base_address,LSR);\r
+            this_uart->status |= status;\r
+    \r
+            /*\r
+             * This function should only be called as a result of a THRE interrupt.\r
+             * Verify that this is true before proceeding to transmit data.\r
+             */\r
+            if ( status & LSR_THRE_MASK )\r
+            {\r
+                uint32_t size_sent = 0U;\r
+                uint32_t fill_size = TX_FIFO_SIZE;\r
+                uint32_t tx_remain = this_uart->tx_buff_size - this_uart->tx_idx;\r
+    \r
+                /* Calculate the number of bytes to transmit. */\r
+                if ( tx_remain < TX_FIFO_SIZE )\r
+                {\r
+                    fill_size = tx_remain;\r
+                }\r
+    \r
+                /* Fill the TX FIFO with the calculated the number of bytes. */\r
+                for ( size_sent = 0U; size_sent < fill_size; ++size_sent )\r
+                {\r
+                    /* Send next character in the buffer. */\r
+                    HAL_set_8bit_reg( this_uart->base_address, THR,\r
+                            (uint_fast8_t)this_uart->tx_buffer[this_uart->tx_idx]);\r
+                    ++this_uart->tx_idx;\r
+                }\r
+            }\r
+    \r
+            /* Flag Tx as complete if all data has been pushed into the Tx FIFO. */\r
+            if ( this_uart->tx_idx == this_uart->tx_buff_size )\r
+            {\r
+                this_uart->tx_buff_size = TX_COMPLETE;\r
+                /* disables TX interrupt */\r
+                HAL_set_8bit_reg_field( this_uart->base_address,\r
+                                        IER_ETBEI, DISABLE);\r
+            }\r
+        }\r
+    }\r
+}\r
+\r
+/***************************************************************************//**\r
+ * UART_16550_enable_irq.\r
+ * See core_16550.h for details of how to use this function.\r
+ */\r
+void\r
+UART_16550_enable_irq\r
+(\r
+    uart_16550_instance_t * this_uart,\r
+    uint8_t irq_mask\r
+)\r
+{\r
+    HAL_ASSERT( this_uart != NULL_INSTANCE )\r
+\r
+    if( this_uart != NULL_INSTANCE )\r
+    {\r
+        /* irq_mask encoding: 1- enable\r
+         * bit 0 - Receive Data Available Interrupt\r
+         * bit 1 - Transmitter Holding  Register Empty Interrupt\r
+         * bit 2 - Receiver Line Status Interrupt\r
+         * bit 3 - Modem Status Interrupt\r
+         */\r
+        /* read present interrupts for enabled ones*/\r
+        irq_mask |= HAL_get_8bit_reg( this_uart->base_address, IER );\r
+        /* Enable interrupts */\r
+        HAL_set_8bit_reg( this_uart->base_address, IER, irq_mask );\r
+    }\r
+}\r
+\r
+/***************************************************************************//**\r
+ * UART_16550_disable_irq.\r
+ * See core_16550.h for details of how to use this function.\r
+ */\r
+void\r
+UART_16550_disable_irq\r
+(\r
+    uart_16550_instance_t * this_uart,\r
+    uint8_t irq_mask\r
+)\r
+{\r
+    HAL_ASSERT( this_uart != NULL_INSTANCE )\r
+\r
+    if( this_uart != NULL_INSTANCE )\r
+    {\r
+        /* irq_mask encoding:  1 - disable\r
+         * bit 0 - Receive Data Available Interrupt\r
+         * bit 1 - Transmitter Holding  Register Empty Interrupt\r
+         * bit 2 - Receiver Line Status Interrupt\r
+         * bit 3 - Modem Status Interrupt\r
+         */\r
+        /* read present interrupts for enabled ones */\r
+        irq_mask = (( (uint8_t)~irq_mask ) & \r
+                    HAL_get_8bit_reg( this_uart->base_address, IER ));\r
+        /* Disable interrupts */\r
+        HAL_set_8bit_reg( this_uart->base_address, IER, irq_mask );\r
+    }\r
+}\r
+\r
+/***************************************************************************//**\r
+ * UART_16550_set_rxstatus_handler.\r
+ * See core_16550.h for details of how to use this function.\r
+ */\r
+void\r
+UART_16550_set_rxstatus_handler\r
+(\r
+    uart_16550_instance_t * this_uart,\r
+    uart_16550_irq_handler_t handler\r
+)\r
+{\r
+    HAL_ASSERT( this_uart != NULL_INSTANCE )\r
+    HAL_ASSERT( handler != INVALID_IRQ_HANDLER)\r
+\r
+    if( ( this_uart != NULL_INSTANCE ) &&\r
+        ( handler != INVALID_IRQ_HANDLER) )\r
+    {\r
+        this_uart->linests_handler = handler;\r
+        /* Enable receiver line status interrupt. */\r
+        HAL_set_8bit_reg_field( this_uart->base_address, IER_ELSI, ENABLE );\r
+    }\r
+}\r
+\r
+/***************************************************************************//**\r
+ * UART_16550_set_tx_handler.\r
+ * See core_16550.h for details of how to use this function.\r
+ */\r
+void\r
+UART_16550_set_tx_handler\r
+(\r
+    uart_16550_instance_t * this_uart,\r
+    uart_16550_irq_handler_t handler\r
+)\r
+{\r
+    HAL_ASSERT( this_uart != NULL_INSTANCE )\r
+    HAL_ASSERT( handler != INVALID_IRQ_HANDLER)\r
+\r
+    if( ( this_uart != NULL_INSTANCE ) &&\r
+        ( handler != INVALID_IRQ_HANDLER) )\r
+    {\r
+        this_uart->tx_handler = handler;\r
+\r
+        /* Make TX buffer info invalid */\r
+        this_uart->tx_buffer = NULL_BUFF;\r
+        this_uart->tx_buff_size = 0U;\r
+\r
+        /* Enable transmitter holding register Empty interrupt. */\r
+        HAL_set_8bit_reg_field( this_uart->base_address, IER_ETBEI, ENABLE );\r
+    }\r
+}\r
+\r
+/***************************************************************************//**\r
+ * UART_16550_set_modemstatus_handler.\r
+ * See core_16550.h for details of how to use this function.\r
+ */\r
+void\r
+UART_16550_set_modemstatus_handler\r
+(\r
+    uart_16550_instance_t * this_uart,\r
+    uart_16550_irq_handler_t handler\r
+)\r
+{\r
+    HAL_ASSERT( this_uart != NULL_INSTANCE )\r
+    HAL_ASSERT( handler != INVALID_IRQ_HANDLER)\r
+\r
+    if( ( this_uart != NULL_INSTANCE ) &&\r
+        ( handler != INVALID_IRQ_HANDLER) )\r
+    {\r
+        this_uart->modemsts_handler = handler;\r
+        /* Enable modem status interrupt. */\r
+        HAL_set_8bit_reg_field( this_uart->base_address, IER_EDSSI, ENABLE );\r
+    }\r
+}\r
+\r
+/***************************************************************************//**\r
+ * UART_16550_fill_tx_fifo.\r
+ * See core_16550.h for details of how to use this function.\r
+ */\r
+size_t\r
+UART_16550_fill_tx_fifo\r
+(\r
+    uart_16550_instance_t * this_uart,\r
+    const uint8_t * tx_buffer,\r
+    size_t tx_size\r
+)\r
+{\r
+    uint8_t status;\r
+    size_t size_sent = 0U;\r
+\r
+    HAL_ASSERT( this_uart != NULL_INSTANCE )\r
+    HAL_ASSERT( tx_buffer != NULL_BUFF )\r
+    HAL_ASSERT( tx_size > 0U )\r
+\r
+    /* Fill the UART's Tx FIFO until the FIFO is full or the complete input\r
+     * buffer has been written. */\r
+    if( (this_uart != NULL_INSTANCE) &&\r
+        (tx_buffer != NULL_BUFF)   &&\r
+        (tx_size > 0U) )\r
+    {\r
+        /* Read the Line Status Register and update the sticky record. */\r
+        status = HAL_get_8bit_reg( this_uart->base_address, LSR );\r
+        this_uart->status |= status;\r
+\r
+        /* Check if TX FIFO is empty. */\r
+        if( status & LSR_THRE_MASK )\r
+        {\r
+            uint32_t fill_size = TX_FIFO_SIZE;\r
+\r
+            /* Calculate the number of bytes to transmit. */\r
+            if ( tx_size < TX_FIFO_SIZE )\r
+            {\r
+                fill_size = tx_size;\r
+            }\r
+\r
+            /* Fill the TX FIFO with the calculated the number of bytes. */\r
+            for ( size_sent = 0U; size_sent < fill_size; ++size_sent )\r
+            {\r
+                /* Send next character in the buffer. */\r
+                HAL_set_8bit_reg( this_uart->base_address, THR,\r
+                                  (uint_fast8_t)tx_buffer[size_sent]);\r
+            }\r
+        }\r
+    }\r
+    return size_sent;\r
+}\r
+\r
+/***************************************************************************//**\r
+ * UART_16550_get_tx_status.\r
+ * See core_16550.h for details of how to use this function.\r
+ */\r
+uint8_t\r
+UART_16550_get_tx_status\r
+(\r
+    uart_16550_instance_t * this_uart\r
+)\r
+{\r
+    uint8_t status = UART_16550_TX_BUSY;\r
+    HAL_ASSERT( this_uart != NULL_INSTANCE );\r
+\r
+    if( ( this_uart != NULL_INSTANCE ) )\r
+    {\r
+        /* Read the Line Status Register and update the sticky record. */\r
+        status = HAL_get_8bit_reg( this_uart->base_address, LSR );\r
+        this_uart->status |= status;\r
+        /*\r
+         * Extract the transmit status bits from the UART's Line Status Register.\r
+         * Bit 5 - Transmitter Holding Register/FIFO Empty (THRE) status. (If = 1, TX FIFO is empty)\r
+         * Bit 6 - Transmitter Empty (TEMT) status. (If = 1, both TX FIFO and shift register are empty)\r
+         */\r
+        status &= ( LSR_THRE_MASK | LSR_TEMT_MASK );\r
+    }\r
+    return status;\r
+}\r
+\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
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 (file)
index 0000000..98b1f16
--- /dev/null
@@ -0,0 +1,1264 @@
+/*******************************************************************************\r
+ * (c) Copyright 2007-2015 Microsemi SoC Products Group. All rights reserved.\r
+ *\r
+ * This file contains the application programming interface for the Core16550\r
+ * bare metal driver.\r
+ *\r
+ * SVN $Revision: 7963 $\r
+ * SVN $Date: 2015-10-09 17:58:21 +0530 (Fri, 09 Oct 2015) $\r
+ */\r
+/*=========================================================================*//**\r
+  @mainpage Core16550 Bare Metal Driver.\r
+\r
+  @section intro_sec Introduction\r
+  The Core16550 is an implementation of the Universal Asynchronous\r
+  Receiver/Transmitter aimed at complete compliance to standard 16550 UART.\r
+  The Core16550 bare metal software driver is designed for use in systems\r
+  with no operating system.\r
+\r
+  The Core16550 driver provides functions for polled and interrupt driven\r
+  transmitting and receiving. It also provides functions for reading the\r
+  values from different status registers, enabling and disabling interrupts\r
+  at Core16550 level. The Core16550 driver is provided as C source code.\r
+\r
+  @section driver_configuration Driver Configuration\r
+  Your application software should configure the Core16550 driver through\r
+  calls to the UART_16550_init() function for each Core16550 instance in\r
+  the hardware design. The configuration parameters include the Core16550\r
+  hardware instance base address and other runtime parameters, such as baud\r
+  value, bit width, and parity.\r
+\r
+  No Core16550 hardware configuration parameters are needed by the driver,\r
+  apart from the Core16550 hardware instance base address. Hence, no\r
+  additional configuration files are required to use the driver.\r
+\r
+  @section theory_op Theory of Operation\r
+  The Core16550 software driver is designed to allow the control of multiple\r
+  instances of Core16550. Each instance of Core16550 in the hardware design\r
+  is associated with a single instance of the uart_16550_instance_t structure\r
+  in the software. You need to allocate memory for one unique\r
+  uart_16550_instance_t structure instance for each Core16550 hardware instance.\r
+  The contents of these data structures are initialized during calls to\r
+  function UART_16550_init(). A pointer to the structure is passed to\r
+  subsequent driver functions in order to identify the Core16550 hardware\r
+  instance you wish to perform the requested operation on.\r
+\r
+  Note:     Do not attempt to directly manipulate the content of\r
+  uart_16550_instance_t structures. This structure is only intended to be\r
+  modified by the driver function.\r
+\r
+  Initialization\r
+  The Core16550 driver is initialized through a call to the UART_16550_init()\r
+  function. This function takes the UART\92s configuration as parameters.\r
+  The UART_16550_init() function must be called before any other Core16550\r
+  driver functions can be called.\r
+\r
+  Polled Transmission and Reception\r
+  The driver can be used to transmit and receive data once initialized. Polled\r
+  operations where the driver constantly polls the state of the UART registers\r
+  in order to control data transmit or data receive are performed using these\r
+  functions:\r
+         \95  UART_16550_polled_tx()\r
+         \95  UART_16550_polled_tx_string\r
+         \95  UART_16550_fill_tx_fifo()\r
+         \95  UART_16550_get_rx()\r
+\r
+  Data is transmitted using the UART_16550_polled_tx() function. This function\r
+  is blocking, meaning that it will only return once the data passed to the\r
+  function has been sent to the Core16550 hardware. Data received by the\r
+  Core16550 hardware can be read by the UART_16550_get_rx() function.\r
+\r
+  The UART_16550_polled_tx_string() function is provided to transmit a NULL (\91\0\92)\r
+  terminated string in polled mode. This function is blocking, meaning that it\r
+  will only return once the data passed to the function has been sent to the\r
+  Core16550 hardware.\r
+\r
+  The UART_16550_fill_tx_fifo() function fills the Core16550 hardware transmit\r
+  FIFO with data from a buffer passed as a parameter and returns the number of\r
+  bytes transferred to the FIFO. If the transmit FIFO is not empty when the\r
+  UART_16550_fill_tx_fifo() function is called it returns immediately without\r
+  transferring any data to the FIFO.\r
+\r
+  Interrupt Driven Operations\r
+  The driver can also transmit or receive data under interrupt control, freeing\r
+  your application to perform other tasks until an interrupt occurs indicating\r
+  that the driver\92s attention is required. Interrupt controlled UART operations\r
+  are performed using these functions:\r
+        \95   UART_16550_isr()\r
+        \95   UART_16550_irq_tx()\r
+        \95   UART_16550_tx_complete()\r
+        \95   UART_16550_set_tx_handler()\r
+        \95   UART_16550_set_rx_handler()\r
+        \95   UART_16550_set_rxstatus_handler()\r
+        \95   UART_16550_set_modemstatus_handler()\r
+        \95   UART_16550_enable_irq()\r
+        \95   UART_16550_disable_irq()\r
+\r
+  Interrupt Handlers\r
+  The UART_16550_isr() function is the top level interrupt handler function for\r
+  the Core16550 driver. You must call it from the system level\r
+  (CoreInterrupt and NVIC level) interrupt service routine (ISR) assigned to the\r
+  interrupt triggered by the Core16550 INTR signal. The UART_16550_isr() function\r
+  identifies the source of the Core16550 interrupt and calls the corresponding\r
+  handler function previously registered with the driver through calls to the\r
+  UART_16550_set_rx_handler(), UART_16550_set_tx_handler(),\r
+  UART_16550_set_rxstatus_handler(), and UART_16550_set_modemstatus_handler()\r
+  functions. You are responsible for creating these lower level interrupt handlers\r
+  as part of your application program and registering them with the driver.\r
+  The UART_16550_enable_irq() and UART_16550_disable_irq() functions are used to\r
+  enable or disable the received line status, received data available/character\r
+  timeout, transmit holding register empty and modem status interrupts at the\r
+  Core16550 level.\r
+\r
+  Transmitting Data\r
+  Interrupt-driven transmit is initiated by a call to UART_16550_irq_tx(),\r
+  specifying the block of data to transmit. Your application is then free to\r
+  perform other tasks and inquire later whether transmit has completed by calling\r
+  the UART_16550_tx_complete() function. The UART_16550_irq_tx() function enables\r
+  the UART\92s transmit holding register empty (THRE) interrupt and then, when the\r
+  interrupt goes active, the driver\92s default THRE interrupt handler transfers\r
+  the data block to the UART until the entire block is transmitted.\r
+\r
+  Note:     You can use the UART_16550_set_tx_handler() function to assign an\r
+  alternative handler to the THRE interrupt. In this case, you must not use the\r
+  UART_16550_irq_tx() function to initiate the transmit, as this will re-assign\r
+  the driver\92s default THRE interrupt handler to the THRE interrupt. Instead,\r
+  your alternative THRE interrupt handler must include a call to the\r
+  UART_16550_fill_tx_fifo() function to transfer the data to the UART.\r
+\r
+  Receiving Data\r
+  Interrupt-driven receive is performed by first calling UART_16550_set_rx_handler()\r
+  to register a receive handler function that will be called by the driver whenever\r
+  receive data is available. You must provide this receive handler function which\r
+  must include a call to the UART_16550_get_rx() function to actually read the\r
+  received data.\r
+\r
+  UART Status\r
+  The function UART_16550_get_rx_status() is used to read the receiver error status.\r
+  This function returns the overrun, parity, framing, break, and FIFO error status\r
+  of the receiver.\r
+  The function UART_16550_get_tx_status() is used to read the transmitter status.\r
+  This function returns the transmit empty (TEMT) and transmit holding register\r
+  empty (THRE) status of the transmitter.\r
+  The function UART_16550_get_modem_status() is used to read the modem status flags.\r
+  This function returns the current value of the modem status register.\r
+\r
+  Loopback\r
+  The function UART_16550_set_loopback() is used to enable or disable loopback\r
+  between Tx and Rx lines internal to Core16550.\r
+*//*=========================================================================*/\r
+#ifndef __CORE_16550_H\r
+#define __CORE_16550_H 1\r
+\r
+#include "cpu_types.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+/***************************************************************************//**\r
+ * Receiver Error Status\r
+ * The following defines are used to determine the UART receiver error type.\r
+ * These bit mask constants are used with the return value of the\r
+ * UART_16550_get_rx_status() function to find out if any errors occurred\r
+ * while receiving data.\r
+ */\r
+#define UART_16550_NO_ERROR         ( (uint8_t) 0x00 )\r
+#define UART_16550_OVERRUN_ERROR    ( (uint8_t) 0x02 )\r
+#define UART_16550_PARITY_ERROR     ( (uint8_t) 0x04 )\r
+#define UART_16550_FRAMING_ERROR    ( (uint8_t) 0x08 )\r
+#define UART_16550_BREAK_ERROR      ( (uint8_t) 0x10 )\r
+#define UART_16550_FIFO_ERROR       ( (uint8_t) 0x80 )\r
+#define UART_16550_INVALID_PARAM    ( (uint8_t) 0xFF )\r
+\r
+/***************************************************************************//**\r
+ * Modem Status\r
+ * The following defines are used to determine the modem status. These bit\r
+ * mask constants are used with the return value of the\r
+ * UART_16550_get_modem_status() function to find out the modem status of\r
+ * the UART.\r
+ */\r
+#define UART_16550_DCTS             ( (uint8_t) 0x01 )\r
+#define UART_16550_DDSR             ( (uint8_t) 0x02 )\r
+#define UART_16550_TERI             ( (uint8_t) 0x04 )\r
+#define UART_16550_DDCD             ( (uint8_t) 0x08 )\r
+#define UART_16550_CTS              ( (uint8_t) 0x10 )\r
+#define UART_16550_DSR              ( (uint8_t) 0x20 )\r
+#define UART_16550_RI               ( (uint8_t) 0x40 )\r
+#define UART_16550_DCD              ( (uint8_t) 0x80 )\r
+\r
+/***************************************************************************//**\r
+ * Transmitter Status\r
+ * The following definitions are used to determine the UART transmitter status.\r
+ * These bit mask constants are used with the return value of the\r
+ * UART_16550_get_tx_status() function to find out the status of the\r
+ * transmitter.\r
+ */\r
+#define UART_16550_TX_BUSY          ( (uint8_t) 0x00 )\r
+#define UART_16550_THRE             ( (uint8_t) 0x20 )\r
+#define UART_16550_TEMT             ( (uint8_t) 0x40 )\r
+\r
+/***************************************************************************//**\r
+ * Core16550 Interrupts\r
+ * The following defines are used to enable and disable Core16550 interrupts.\r
+ * They are used to build the value of the irq_mask parameter for the\r
+ * UART_16550_enable_irq() and UART_16550_disable_irq() functions. A bitwise\r
+ * OR of these constants is used to enable or disable multiple interrupts.\r
+ */\r
+#define UART_16550_RBF_IRQ          ( (uint8_t) 0x01 )\r
+#define UART_16550_TBE_IRQ          ( (uint8_t) 0x02 )\r
+#define UART_16550_LS_IRQ           ( (uint8_t) 0x04 )\r
+#define UART_16550_MS_IRQ           ( (uint8_t) 0x08 )\r
+\r
+/***************************************************************************//**\r
+ * Data Width\r
+ * The following defines are used to build the value of the UART_16550_init()\r
+ * function line_config parameter.\r
+ */\r
+#define UART_16550_DATA_5_BITS      ( (uint8_t) 0x00 )\r
+#define UART_16550_DATA_6_BITS      ( (uint8_t) 0x01 )\r
+#define UART_16550_DATA_7_BITS      ( (uint8_t) 0x02 )\r
+#define UART_16550_DATA_8_BITS      ( (uint8_t) 0x03 )\r
+\r
+/***************************************************************************//**\r
+ * Parity Control\r
+ * The following defines are used to build the value of the UART_16550_init()\r
+ * function line_config parameter.\r
+ */\r
+#define UART_16550_NO_PARITY            ( (uint8_t) 0x00 )\r
+#define UART_16550_ODD_PARITY           ( (uint8_t) 0x08 )\r
+#define UART_16550_EVEN_PARITY          ( (uint8_t) 0x18 )\r
+#define UART_16550_STICK_PARITY_1       ( (uint8_t) 0x28 )\r
+#define UART_16550_STICK_PARITY_0       ( (uint8_t) 0x38 )\r
+\r
+/***************************************************************************//**\r
+ * Number of Stop Bits\r
+ * The following defines are used to build the value of the UART_16550_init()\r
+ * function line_config parameter.\r
+ */\r
+#define UART_16550_ONE_STOP_BIT     ( (uint8_t) 0x00 )\r
+/*only when data bits is 5*/\r
+#define UART_16550_ONEHALF_STOP_BIT ( (uint8_t) 0x04 )\r
+/*only when data bits is not 5*/\r
+#define UART_16550_TWO_STOP_BITS    ( (uint8_t) 0x04 )\r
+\r
+/***************************************************************************//**\r
+  This enumeration specifies the receiver FIFO trigger level. This is the number\r
+  of bytes that must be received before the UART generates a receive data\r
+  available interrupt. It provides the allowed values for the\r
+  UART_16550_set_rx_handler() function\92s trigger_level parameter.\r
+ */\r
+typedef enum {\r
+    UART_16550_FIFO_SINGLE_BYTE    = 0,\r
+    UART_16550_FIFO_FOUR_BYTES     = 1,\r
+    UART_16550_FIFO_EIGHT_BYTES    = 2,\r
+    UART_16550_FIFO_FOURTEEN_BYTES = 3,\r
+    UART_16550_FIFO_INVALID_TRIG_LEVEL\r
+} uart_16550_rx_trig_level_t;\r
+\r
+/***************************************************************************//**\r
+  This enumeration specifies the Loopback configuration of the UART. It provides\r
+  the allowed values for the UART_16550_set_loopback() function\92s loopback\r
+  parameter.\r
+ */\r
+typedef enum {\r
+    UART_16550_LOOPBACK_OFF   = 0,\r
+    UART_16550_LOOPBACK_ON    = 1,\r
+    UART_16550_INVALID_LOOPBACK\r
+} uart_16550_loopback_t;\r
+\r
+/***************************************************************************//**\r
+  This is type definition for Core16550 instance. You need to create and\r
+  maintain a record of this type. This holds all data regarding the Core16550\r
+  instance.\r
+ */\r
+typedef struct uart_16550_instance uart_16550_instance_t;\r
+\r
+/***************************************************************************//**\r
+  This typedef specifies the function prototype for Core16550 interrupt handlers.\r
+  All interrupt handlers registered with the Core16550 driver must be of this\r
+  type. The interrupt handlers are registered with the driver through the\r
+  UART_16550_set_rx_handler(), UART_16550_set_tx_handler(),\r
+  UART_16550_set_rxstatus_handler(), and UART_16550_set_modemstatus_handler()\r
+  functions.\r
+\r
+  The this_uart parameter is a pointer to a uart_16550_instance_t structure that\r
+  holds all data regarding this instance of the Core16550.\r
+ */\r
+typedef void (*uart_16550_irq_handler_t)(uart_16550_instance_t * this_uart);\r
+\r
+/***************************************************************************//**\r
+  uart_16550_instance.\r
+  This structure is used to identify the various Core16550 hardware instances\r
+  in your system. Your application software should declare one instance of this\r
+  structure for each instance of Core16550 in your system. The function\r
+  UART_16550_init() initializes this structure. A pointer to an initialized\r
+  instance of the structure should be passed as the first parameter to the\r
+  Core16550 driver functions, to identify which Core16550 hardware instance\r
+  should perform the requested operation.\r
+ */\r
+struct uart_16550_instance{\r
+    /* Core16550 instance base address: */\r
+    addr_t      base_address;\r
+    /* Accumulated status: */\r
+    uint8_t     status;\r
+\r
+    /* transmit related info: */\r
+    const uint8_t*  tx_buffer;\r
+    uint32_t        tx_buff_size;\r
+    uint32_t        tx_idx;\r
+\r
+    /* line status (OE, PE, FE & BI) interrupt handler:*/\r
+    uart_16550_irq_handler_t linests_handler;\r
+    /* receive interrupt handler:*/\r
+    uart_16550_irq_handler_t rx_handler;\r
+    /* transmitter holding register interrupt handler:*/\r
+    uart_16550_irq_handler_t tx_handler;\r
+    /* modem status interrupt handler:*/\r
+    uart_16550_irq_handler_t modemsts_handler;\r
+};\r
+\r
+/***************************************************************************//**\r
+ * The UART_16550_init() function initializes the driver\92s data structures and\r
+ * the Core16550 hardware with the configuration passed as parameters.. The\r
+ * configuration parameters are the baud_value used to generate the baud rate,\r
+ * and the line_config used to specify the line configuration (bit length,\r
+ * stop bits and parity).\r
+ *\r
+ * @param this_uart     The this_uart parameter is a pointer to a\r
+ *                      uart_16550_instance_t structure that holds all data\r
+ *                      regarding this instance of the Core16550. This pointer\r
+ *                      is used to identify the target Core16550 hardware\r
+ *                      instance in subsequent calls to the Core16550 driver\r
+ *                      functions.\r
+ * @param base_addr     The base_address parameter is the base address in the\r
+ *                      processor's memory map for the registers of the\r
+ *                      Core16550 instance being initialized.\r
+ * @param baud_value    The baud_value parameter is used to select the baud rate\r
+ *                      for the UART. The baud value is calculated from the\r
+ *                      frequency of the system clock in Hertz and the desired\r
+ *                      baud rate using the following equation:\r
+ *\r
+ *                      baud_value = (clock /(baud_rate * 16))\r
+ *\r
+ *                      The baud_value parameter must be a value in the range 0\r
+ *                      to 65535 (or 0x0000 to 0xFFFF).\r
+ * @param line_config   This parameter is the line configuration specifying the\r
+ *                      bit length, number of stop bits and parity settings. This\r
+ *                      is a bitwise OR of one value from each of the following\r
+ *                      groups of allowed values:\r
+ *                      \95   Data lengths:\r
+ *                          UART_16550_DATA_5_BITS\r
+ *                          UART_16550_DATA_6_BITS\r
+ *                          UART_16550_DATA_7_BITS\r
+ *                          UART_16550_DATA_8_BITS\r
+ *                      \95   Parity types:\r
+ *                          UART_16550_NO_PARITY\r
+ *                          UART_16550_EVEN_PARITY\r
+ *                          UART_16550_ODD_PARITY\r
+ *                          UART_16550_STICK_PARITY_0\r
+ *                          UART_16550_STICK_PARITY_1\r
+ *                      \95   Number of stop bits:\r
+ *                          UART_16550_ONE_STOP_BIT\r
+ *                          UART_16550_ONEHALF_STOP_BIT\r
+ *                          UART_16550_TWO_STOP_BITS\r
+ * @return              This function does not return a value.\r
+ *\r
+ * Example:\r
+ * @code\r
+ * #define UART_16550_BASE_ADDR   0x2A000000\r
+ * #define BAUD_VALUE_57600    26\r
+ *\r
+ * uart_16550_instance_t g_uart;\r
+ *\r
+ * UART_16550_init( &g_uart, UART_16550_BASE_ADDR, BAUD_VALUE_57600,\r
+ *                  (UART_16550_DATA_8_BITS |\r
+ *                   UART_16550_EVEN_PARITY |\r
+ *                   UART_16550_ONE_STOP_BIT) );\r
+ * @endcode\r
+ */\r
+void\r
+UART_16550_init\r
+(\r
+    uart_16550_instance_t* this_uart,\r
+    addr_t base_addr,\r
+    uint16_t baud_value,\r
+    uint8_t line_config\r
+);\r
+\r
+/***************************************************************************//**\r
+ * The UART_16550_polled_tx() function is used to transmit data. It transfers\r
+ * the contents of the transmitter data buffer, passed as a function parameter,\r
+ * into the UART's hardware transmitter FIFO. It returns when the full content\r
+ * of the transmitter data buffer has been transferred to the UART's transmitter\r
+ * FIFO. It is safe to release or reuse the memory used as the transmitter data\r
+ * buffer once this function returns.\r
+ *\r
+ * Note:    This function reads the UART\92s line status register (LSR) to poll\r
+ * for the active state of the transmitter holding register empty (THRE) bit\r
+ * before transferring data from the data buffer to the transmitter FIFO. It\r
+ * transfers data to the transmitter FIFO in blocks of 16 bytes or less and\r
+ * allows the FIFO to empty before transferring the next block of data.\r
+ *\r
+ * Note:    The actual transmission over the serial connection will still be in\r
+ * progress when this function returns. Use the UART_16550_get_tx_status()\r
+ * function if you need to know when the transmitter is empty.\r
+ *\r
+ * @param this_uart     The this_uart parameter is a pointer to a\r
+ *                      uart_16550_instance_t structure that holds all\r
+ *                      data regarding this instance of the Core16550.\r
+ * @param pbuff         The pbuff parameter is a pointer to a buffer containing\r
+ *                      the data to be transmitted.\r
+ * @param tx_size       The tx_size parameter is the size, in bytes, of the\r
+ *                      data to be transmitted.\r
+ * @return              This function does not return a value.\r
+ *\r
+ * Example:\r
+ * @code\r
+ *   uint8_t testmsg1[] = {"\n\r\n\r\n\rUART_16550_polled_tx() test message 1"};\r
+ *   UART_16550_polled_tx(&g_uart,(const uint8_t *)testmsg1,sizeof(testmsg1));\r
+ * @endcode\r
+ */\r
+void\r
+UART_16550_polled_tx\r
+(\r
+    uart_16550_instance_t * this_uart,\r
+    const uint8_t * pbuff,\r
+    uint32_t tx_size\r
+);\r
+/***************************************************************************//**\r
+ * The UART_16550_polled_tx_string() function is used to transmit a NULL ('\0')\r
+ * terminated string. It transfers the text string, from the buffer starting at\r
+ * the address pointed to by p_sz_string, into the UART\92s hardware transmitter\r
+ * FIFO. It returns when the complete string has been transferred to the UART's\r
+ * transmit FIFO. It is safe to release or reuse the memory used as the string\r
+ * buffer once this function returns.\r
+ *\r
+ * Note:    This function reads the UART\92s line status register (LSR) to poll\r
+ * for the active state of the transmitter holding register empty (THRE) bit\r
+ * before transferring data from the data buffer to the transmitter FIFO. It\r
+ * transfers data to the transmitter FIFO in blocks of 16 bytes or less and\r
+ * allows the FIFO to empty before transferring the next block of data.\r
+ *\r
+ * Note:    The actual transmission over the serial connection will still be\r
+ * in progress when this function returns. Use the UART_16550_get_tx_status()\r
+ * function if you need to know when the transmitter is empty.\r
+ *\r
+ * @param this_uart     The this_uart parameter is a pointer to a\r
+ *                      uart_16550_instance_t structure that holds all data\r
+ *                      regarding this instance of the Core16550.\r
+ * @param p_sz_string   The p_sz_string parameter is a pointer to a buffer\r
+ *                      containing the NULL ('\0') terminated string to be\r
+ *                      transmitted.\r
+ * @return              This function does not return a value.\r
+ *\r
+ * Example:\r
+ * @code\r
+ *   uint8_t testmsg1[] = {"\r\n\r\nUART_16550_polled_tx_string() test message 1\0"};\r
+ *   UART_16550_polled_tx_string(&g_uart,(const uint8_t *)testmsg1);\r
+ * @endcode\r
+ */\r
+void\r
+UART_16550_polled_tx_string\r
+(\r
+    uart_16550_instance_t * this_uart,\r
+    const uint8_t * p_sz_string\r
+);\r
+\r
+/***************************************************************************//**\r
+ * The UART_16550_irq_tx() function is used to initiate an interrupt driven\r
+ * transmit. It returns immediately after making a note of the transmit buffer\r
+ * location and enabling the transmitter holding register empty (THRE) interrupt\r
+ * at the Core16550 level. This function takes a pointer via the pbuff parameter\r
+ * to a memory buffer containing the data to transmit. The memory buffer\r
+ * specified through this pointer must remain allocated and contain the data to\r
+ * transmit until the transmit completion has been detected through calls to\r
+ * function UART_16550_tx_complete().The actual transmission over the serial\r
+ * connection is still in progress until calls to the UART_16550_tx_complete()\r
+ * function indicate transmit completion.\r
+ *\r
+ * Note:    It is your responsibility to call UART_16550_isr(), the driver\92s\r
+ * top level interrupt handler function, from the system level (CoreInterrupt\r
+ * and NVIC level) interrupt handler assigned to the interrupt triggered by the\r
+ * Core16550 INTR signal. You must do this before using the UART_16550_irq_tx()\r
+ * function.\r
+ *\r
+ * Note:    It is also your responsibility to enable the system level\r
+ * (CoreInterrupt and NVIC level) interrupt connected to the Core16550 INTR\r
+ * interrupt signal.\r
+ *\r
+ * Note:    The UART_16550_irq_tx() function assigns an internal default transmit\r
+ * interrupt handler function to the UART\92s THRE interrupt. This interrupt handler\r
+ * overrides any custom interrupt handler that you may have previously registered\r
+ * using the UART_16550_set_tx_handler() function.\r
+ *\r
+ * Note:    The UART_16550_irq_tx() function\92s default transmit interrupt handler\r
+ * disables the UART\92s THRE interrupt when all of the data has been transferred\r
+ * to the UART's transmit FIFO.\r
+ *\r
+ * @param this_uart     The this_uart parameter is a pointer to a\r
+ *                      uart_16550_instance_t structure that holds all data\r
+ *                      regarding this instance of the Core16550.\r
+ * @param pbuff         The pbuff parameter is a pointer to a buffer containing\r
+ *                      the data to be transmitted.\r
+ * @param tx_size       The tx_size parameter specifies the size, in bytes, of\r
+ *                      the data to be transmitted.\r
+ * @return              This function does not return a value.\r
+ *\r
+ * Example:\r
+ * @code\r
+ * uint8_t tx_buff[10] = "abcdefghi";\r
+ *\r
+ * UART_16550_irq_tx( &g_uart, tx_buff, sizeof(tx_buff));\r
+ * while ( 0 == UART_16550_tx_complete( &g_uart ) )\r
+ * { ; }\r
+ * @endcode\r
+ */\r
+void\r
+UART_16550_irq_tx\r
+(\r
+    uart_16550_instance_t * this_uart,\r
+    const uint8_t * pbuff,\r
+    uint32_t tx_size\r
+);\r
+\r
+/***************************************************************************//**\r
+ * The UART_16550_tx_complete() function is used to find out if the interrupt\r
+ * driven transmit previously initiated through a call to UART_16550_irq_tx()\r
+ * is complete. This function is typically used to find out when it is safe\r
+ * to reuse or release the memory buffer holding the transmit data.\r
+ *\r
+ * Note:    The transfer of all of the data from the memory buffer to the UART\92s\r
+ * transmit FIFO and the actual transmission over the serial connection are both\r
+ * complete when a call to the UART_16550_tx_complete() function indicate\r
+ * transmit completion.\r
+ *\r
+ * @param this_uart     The this_uart parameter is a pointer to a\r
+ *                      uart_16550_instance_t structure that holds all data\r
+ *                      regarding this instance of the Core16550.\r
+ * @return              This function returns a non-zero value if transmit has\r
+ *                      completed, otherwise it returns zero.\r
+ *  Example:\r
+ *   See the UART_16550_irq_tx() function for an example that uses the\r
+ *   UART_16550_tx_complete() function.\r
+ */\r
+int8_t\r
+UART_16550_tx_complete\r
+(\r
+   uart_16550_instance_t * this_uart\r
+);\r
+\r
+/***************************************************************************//**\r
+ * The UART_16550_get_rx() function reads the content of the Core16550\r
+ * receiver\92s FIFO and stores it in the receive buffer that is passed via the\r
+ * rx_buff function parameter. It copies either the full contents of the FIFO\r
+ * into the receive buffer, or just enough data from the FIFO to fill the receive\r
+ * buffer, dependent upon the size of the receive buffer passed by the buff_size\r
+ * parameter. The UART_16550_get_rx() function returns the number of bytes copied\r
+ * into the receive buffer .This function is non-blocking and will return 0\r
+ * immediately if no data has been received.\r
+ *\r
+ * Note:    The UART_16550_get_rx() function reads and accumulates the receiver\r
+ * status of the Core16550 instance before reading each byte from the receiver's\r
+ * data register/FIFO. This allows the driver to maintain a sticky record of any\r
+ * receiver errors that occur as the UART receives each data byte; receiver errors\r
+ * would otherwise be lost after each read from the receiver's data register. A call\r
+ * to the UART_16550_get_rx_status() function returns any receiver errors accumulated\r
+ * during the execution of the UART_16550_get_rx() function.\r
+ *\r
+ * Note:    If you need to read the error status for each byte received, set the\r
+ * buff_size to 1 and read the receive line error status for each byte using the\r
+ * UART_16550_get_rx_status() function.\r
+ * The UART_16550_get_rx() function can be used in polled mode, where it is called\r
+ * at regular intervals to find out if any data has been received, or in interrupt\r
+ * driven-mode, where it is called as part of a receive handler that is called by\r
+ * the driver as a result of data being received.\r
+ *\r
+ * Note:    In interrupt driven mode you should call the UART_16550_get_rx()\r
+ * function as part of the receive handler function that you register with the\r
+ * Core16550 driver through a call to UART_16550_set_rx_handler().\r
+ *\r
+ * @param this_uart     The this_uart parameter is a pointer to a\r
+ *                      uart_16550_instance_t structure that holds all data\r
+ *                      regarding this instance of the Core16550.\r
+ * @param rx_buff       The rx_buff parameter is a pointer to a memory buffer\r
+ *                      where the received data is copied.\r
+ * @param buff_size     The buff_size parameter is the size of the receive\r
+ *                      buffer in bytes.\r
+ * @return              This function returns the number of bytes copied into\r
+ *                      the receive buffer.\r
+ * Example:\r
+ * @code\r
+ *   #define MAX_RX_DATA_SIZE    256\r
+ *\r
+ *   uint8_t rx_data[MAX_RX_DATA_SIZE];\r
+ *   uint8_t rx_size = 0;\r
+ *\r
+ *   rx_size = UART_16550_get_rx( &g_uart, rx_data, sizeof(rx_data) );\r
+ * @endcode\r
+ */\r
+size_t\r
+UART_16550_get_rx\r
+(\r
+   uart_16550_instance_t * this_uart,\r
+   uint8_t * rx_buff,\r
+   size_t buff_size\r
+);\r
+\r
+/***************************************************************************//**\r
+ * The UART_16550_isr() function is the top level interrupt handler function for\r
+ * the Core16550 driver. You must call UART_16550_isr() from the system level\r
+ * (CoreInterrupt and NVIC level) interrupt handler assigned to the interrupt\r
+ * triggered by the Core16550 INTR signal. Your system level interrupt handler\r
+ * must also clear the system level interrupt triggered by the Core16550 INTR\r
+ * signal before returning, to prevent a re-assertion of the same interrupt.\r
+ *\r
+ * Note:    This function supports all types of interrupt triggered by Core16550.\r
+ * It is not a complete interrupt handler by itself; rather, it is a top level\r
+ * wrapper that abstracts Core16550 interrupt handling by calling lower level\r
+ * handler functions specific to each type of Core16550 interrupt. You must\r
+ * create the lower level handler functions to suit your application and\r
+ * register them with the driver through calls to the UART_16550_set_rx_handler(),\r
+ * UART_16550_set_tx_handler(), UART_16550_set_rxstatus_handler() and\r
+ * UART_16550_set_modemstatus_handler() functions.\r
+ *\r
+ * @param this_uart     The this_uart parameter is a pointer to a\r
+ *                      uart_16550_instance_t structure that holds all data\r
+ *                      regarding this instance of the Core16550.\r
+ *\r
+ * @return              This function does not return a value.\r
+ *\r
+ * Example:\r
+ * @code\r
+ *   void CIC_irq1_handler(void)\r
+ *   {\r
+ *      UART_16550_isr( &g_uart );\r
+ *   }\r
+ * @endcode\r
+ */\r
+void\r
+UART_16550_isr\r
+(\r
+   uart_16550_instance_t * this_uart\r
+);\r
+\r
+/***************************************************************************//**\r
+ * The UART_16550_set_rx_handler() function is used to register a receive handler\r
+ * function that is called by the driver when a UART receive data available (RDA)\r
+ * interrupt occurs. The UART_16550_set_rx_handler() function also enables the\r
+ * RDA interrupt at the Core16550 level. You must create and register the receive\r
+ * handler function to suit your application and it must include a call to the\r
+ * UART_16550_get_rx() function to actually read the received data.\r
+ *\r
+ * Note:    The driver\92s top level interrupt handler function UART_16550_isr()\r
+ * will call your receive handler function in response to an RDA interrupt from\r
+ * the Core16550.\r
+ *\r
+ * Note:    You can disable the RDA interrupt once the data is received by calling\r
+ * the UART_16550_disable_irq() function. This is your choice and is dependent\r
+ * upon your application.\r
+ *\r
+ * @param this_uart     The this_uart parameter is a pointer to a\r
+ *                      uart_16550_instance_t structure that holds all data\r
+ *                      regarding this instance of the Core16550.\r
+ * @param handler       The handler parameter is a pointer to a receive interrupt\r
+ *                      handler function provided by your application that will be\r
+ *                      called as a result of a UART RDA interrupt. This handler\r
+ *                      function must be of type uart_16550_irq_handler_t.\r
+ * @param trigger_level The trigger_level parameter is the receive FIFO\r
+ *                      trigger level. This specifies the number of bytes that\r
+ *                      must be received before the UART triggers an RDA\r
+ *                      interrupt.\r
+ * @return              This function does not return a value.\r
+ *\r
+ * Example:\r
+ * @code\r
+ * #include "core_16550.h"\r
+ *\r
+ * #define RX_BUFF_SIZE    64\r
+ * #define UART_57600_BAUD 26\r
+ *\r
+ * uint8_t g_rx_buff[RX_BUFF_SIZE];\r
+ * uart_16550_instance_t g_uart;\r
+ * void uart_rx_handler( uart_16550_instance_t * this_uart )\r
+ * {\r
+ *     UART_16550_get_rx( this_uart, g_rx_buff, RX_BUFF_SIZE );\r
+ * }\r
+ *\r
+ * int main(void)\r
+ * {\r
+ *     UART_16550_init( &g_uart, UART_57600_BAUD,\r
+ *                       ( UART_16550_DATA_8_BITS | UART_16550_NO_PARITY ) );\r
+ *     UART_16550_set_rx_handler( &g_uart, uart_rx_handler,\r
+ *                                UART_16550_FIFO_SINGLE_BYTE);\r
+ *     while ( 1 )\r
+ *     {\r
+ *         ;\r
+ *     }\r
+ *     return(0);\r
+ * }\r
+ * @endcode\r
+ */\r
+void\r
+UART_16550_set_rx_handler\r
+(\r
+    uart_16550_instance_t * this_uart,\r
+    uart_16550_irq_handler_t handler,\r
+    uart_16550_rx_trig_level_t trigger_level\r
+);\r
+\r
+/***************************************************************************//**\r
+ * The UART_16550_set_loopback() function is used to locally loopback the Tx\r
+ * and Rx lines of a Core16550 UART.\r
+ *\r
+ * @param this_uart     The this_uart parameter is a pointer to a\r
+ *                      uart_16550_instance_t structure that holds all data\r
+ *                      regarding this instance of the Core16550.\r
+ * @param loopback      The loopback parameter indicates whether or not the\r
+ *                      UART's transmit and receive lines should be looped back.\r
+ *                      Allowed values are as follows:\r
+ *                      \95   UART_16550_LOOPBACK_ON\r
+ *                      \95   UART_16550_LOOPBACK_OFF\r
+ * @return              This function does not return a value.\r
+ *\r
+ * Example:\r
+ * @code\r
+ * #include "core_16550.h"\r
+ *\r
+ * #define UART_57600_BAUD 26\r
+ * #define DATA_SIZE 4\r
+ *\r
+ * uart_16550_instance_t g_uart;\r
+ *\r
+ * int main(void)\r
+ * {\r
+ *      uint8_t txbuf[DATA_SIZE] = "abc";\r
+ *      uint8_t rxbuf[DATA_SIZE];\r
+ *      UART_16550_init( &g_uart, UART_57600_BAUD,\r
+ *                        ( UART_16550_DATA_8_BITS | UART_16550_NO_PARITY |\r
+ *                                               UART_16550_ONE_STOP_BIT) );\r
+ *      UART_16550_set_loopback( &g_uart, UART_16550_LOOPBACK_ON );\r
+ *\r
+ *      while(1)\r
+ *      {\r
+ *          UART_16550_polled_tx( &g_uart, txbuf, DATA_SIZE);\r
+ *          delay(100);\r
+ *          UART_16550_get_rx( &g_uart, rxbuf, DATA_SIZE);\r
+ *      }\r
+ * }\r
+ * @endcode\r
+ */\r
+void\r
+UART_16550_set_loopback\r
+(\r
+    uart_16550_instance_t * this_uart,\r
+    uart_16550_loopback_t loopback\r
+);\r
+\r
+/***************************************************************************//**\r
+ * The UART_16550_get_rx_status() function returns the receiver error status of\r
+ * the Core16550 instance. It reads both the current error status of the receiver\r
+ * from the UART\92s line status register (LSR) and the accumulated error status\r
+ * from preceding calls to the UART_16550_get_rx() function, and it combines\r
+ * them using a bitwise OR. It returns the cumulative overrun, parity, framing,\r
+ * break and FIFO error status of the receiver, since the previous call to\r
+ * UART_16550_get_rx_status(), as an 8-bit encoded value.\r
+ *\r
+ * Note:    The UART_16550_get_rx() function reads and accumulates the receiver\r
+ * status of the Core16550 instance before reading each byte from the receiver\92s\r
+ * data register/FIFO. The driver maintains a sticky record of the cumulative\r
+ * receiver error status, which persists after the UART_16550_get_rx() function\r
+ * returns. The UART_16550_get_rx_status() function clears the driver\92s sticky\r
+ * receiver error record before returning.\r
+ *\r
+ * Note:    The driver\92s transmit functions also read the line status register\r
+ * (LSR) as part of their implementation. When the driver reads the LSR, the\r
+ * UART clears any active receiver error bits in the LSR. This could result in\r
+ * the driver losing receiver errors. To avoid any loss of receiver errors, the\r
+ * transmit functions also update the driver\92s sticky record of the cumulative\r
+ * receiver error status whenever they read the LSR.\r
+ *\r
+ * @param this_uart     The this_uart parameter is a pointer to a\r
+ *                      uart_16550_instance_t structure that holds all data\r
+ *                      regarding this instance of the Core16550.\r
+ * @return              This function returns the UART\92s receiver error status\r
+ *                      as an 8-bit unsigned integer. The returned value is 0\r
+ *                      if no receiver errors occurred. The driver provides a\r
+ *                      set of bit mask constants that should be compared with\r
+ *                      and/or used to mask the returned value to determine the\r
+ *                      receiver error status.\r
+ *                      When the return value is compared to the following bit\r
+ *                      masks, a non-zero result indicates that the\r
+ *                      corresponding error occurred:\r
+ *                      \95   UART_16550_OVERRUN_ERROR    (bit mask = 0x02)\r
+ *                      \95   UART_16550_PARITY_ERROR     (bit mask = 0x04)\r
+ *                      \95   UART_16550_FRAMING_ERROR    (bit mask = 0x08)\r
+ *                      \95   UART_16550_BREAK_ERROR      (bit mask = 0x10)\r
+ *                      \95   UART_16550_FIFO_ERROR       (bit mask = 0x80)\r
+ *                      When the return value is compared to the following bit\r
+ *                      mask, a non-zero result indicates that no error occurred:\r
+ *                      \95   UART_16550_NO_ERROR         (bit mask = 0x00)\r
+ *                      Upon unsuccessful execution, this function returns:\r
+ *                      \95   UART_16550_INVALID_PARAM    (bit mask = 0xFF)\r
+ *\r
+ * Example:\r
+ * @code\r
+ *   uart_16550_instance_t g_uart;\r
+ *   uint8_t rx_data[MAX_RX_DATA_SIZE];\r
+ *   uint8_t err_status;\r
+ *\r
+ *   err_status = UART_16550_get_rx_status(&g_uart);\r
+ *   if(UART_16550_NO_ERROR == err_status )\r
+ *   {\r
+ *        rx_size = UART_16550_get_rx( &g_uart, rx_data, MAX_RX_DATA_SIZE );\r
+ *   }\r
+ * @endcode\r
+ */\r
+uint8_t\r
+UART_16550_get_rx_status\r
+(\r
+    uart_16550_instance_t * this_uart\r
+);\r
+/***************************************************************************//**\r
+ * The UART_16550_enable_irq() function enables the Core16550 interrupts\r
+ * specified by the irq_mask parameter. The irq_mask parameter identifies the\r
+ * Core16550 interrupts by bit position, as defined in the interrupt enable\r
+ * register (IER) of Core16550. The Core16550 interrupts and their identifying\r
+ * irq_mask bit positions are as follows:\r
+ *      \95   Receive data available interrupt (RDA)      (irq_mask bit 0)\r
+ *      \95   Transmit holding register empty interrupt (THRE)    (irq_mask bit 1)\r
+ *      \95   Receiver line status interrupt (LS)         (irq_mask bit 2)\r
+ *      \95   Modem status interrupt (MS)         (irq_mask bit 3)\r
+ * When an irq_mask bit position is set to 1, this function enables the\r
+ * corresponding Core16550 interrupt in the IER register. When an irq_mask\r
+ * bit position is set to 0, the corresponding interrupt\92s state remains\r
+ * unchanged in the IER register.\r
+ *\r
+ * @param this_uart     The this_uart parameter is a pointer to a\r
+ *                      uart_16550_instance_t structure that holds all data\r
+ *                      regarding this instance of the Core16550.\r
+ * @param irq_mask      The irq_mask parameter is used to select which of the\r
+ *                      Core16550\92s interrupts you want to enable. The allowed\r
+ *                      value for the irq_mask parameter is one of the\r
+ *                      following constants or a bitwise OR of more than one:\r
+ *                      \95   UART_16550_RBF_IRQ      (bit mask = 0x01)\r
+ *                      \95   UART_16550_TBE_IRQ      (bit mask = 0x02)\r
+ *                      \95   UART_16550_LS_IRQ       (bit mask = 0x04)\r
+ *                      \95   UART_16550_MS_IRQ       (bit mask = 0x08)\r
+ * @return              This function does not return a value.\r
+ *\r
+ * Example:\r
+ * @code\r
+ *   UART_16550_enable_irq( &g_uart,( UART_16550_RBF_IRQ | UART_16550_TBE_IRQ ) );\r
+ * @endcode\r
+ */\r
+void\r
+UART_16550_enable_irq\r
+(\r
+    uart_16550_instance_t * this_uart,\r
+    uint8_t irq_mask\r
+);\r
+\r
+/***************************************************************************//**\r
+ * The UART_16550_disable_irq() function disables the Core16550 interrupts\r
+ * specified by the irq_mask parameter. The irq_mask parameter identifies the\r
+ * Core16550 interrupts by bit position, as defined in the interrupt enable\r
+ * register (IER) of Core16550. The Core16550 interrupts and their identifying\r
+ * bit positions are as follows:\r
+ *      \95   Receive data available interrupt (RDA)              (irq_mask bit 0)\r
+ *      \95   Transmit holding register empty interrupt (THRE)    (irq_mask bit 1)\r
+ *      \95   Receiver line status interrupt (LS)                 (irq_mask bit 2)\r
+ *      \95   Modem status interrupt (MS)                         (irq_mask bit 3)\r
+ * When an irq_mask bit position is set to 1, this function disables the\r
+ * corresponding Core16550 interrupt in the IER register. When an irq_mask bit\r
+ * position is set to 0, the corresponding interrupt\92s state remains unchanged\r
+ * in the IER register.\r
+ *\r
+ * @param this_uart     The this_uart parameter is a pointer to a\r
+ *                      uart_16550_instance_t structure that holds all data\r
+ *                      regarding this instance of the Core16550.\r
+ * @param irq_mask      The irq_mask parameter is used to select which of the\r
+ *                      Core16550\92s interrupts you want to disable. The allowed\r
+ *                      value for the irq_mask parameter is one of the\r
+ *                      following constants or a bitwise OR of more than one:\r
+ *                      \95   UART_16550_RBF_IRQ      (bit mask = 0x01)\r
+ *                      \95   UART_16550_TBE_IRQ      (bit mask = 0x02)\r
+ *                      \95   UART_16550_LS_IRQ       (bit mask = 0x04)\r
+ *                      \95   UART_16550_MS_IRQ       (bit mask = 0x08)\r
+ * @return              This function does not return a value.\r
+ *\r
+ * Example:\r
+ * @code\r
+ *   UART_16550_disable_irq( &g_uart, ( UART_16550_RBF_IRQ | UART_16550_TBE_IRQ ) );\r
+ * @endcode\r
+ */\r
+void\r
+UART_16550_disable_irq\r
+(\r
+    uart_16550_instance_t * this_uart,\r
+    uint8_t irq_mask\r
+);\r
+\r
+/***************************************************************************//**\r
+ * The UART_16550_get_modem_status() function returns the modem status of the\r
+ * Core16550 instance. It reads the modem status register (MSR) and returns the\r
+ * 8 bit value. The bit encoding of the returned value is exactly the same as\r
+ * the definition of the bits in the MSR.\r
+ *\r
+ * @param this_uart     The this_uart parameter is a pointer to a\r
+ *                      uart_16550_instance_t structure that holds all data\r
+ *                      regarding this instance of the Core16550.\r
+ * @return              This function returns current state of the UART's MSR\r
+ *                      as an 8 bit unsigned integer. The driver provides the\r
+ *                      following set of bit mask constants that should be\r
+ *                      compared with and/or used to mask the returned value\r
+ *                      to determine the modem status:\r
+ *                      \95   UART_16550_DCTS (bit mask = 0x01)\r
+ *                      \95   UART_16550_DDSR (bit mask = 0x02)\r
+ *                      \95   UART_16550_TERI (bit mask = 0x04)\r
+ *                      \95   UART_16550_DDCD (bit mask = 0x08)\r
+ *                      \95   UART_16550_CTS  (bit mask = 0x10)\r
+ *                      \95   UART_16550_DSR  (bit mask = 0x20)\r
+ *                      \95   UART_16550_RI   (bit mask = 0x40)\r
+ *                      \95   UART_16550_DCD  (bit mask = 0x80)\r
+ * Example:\r
+ * @code\r
+ *   void uart_modem_status_isr(uart_16550_instance_t * this_uart)\r
+ *   {\r
+ *      uint8_t status;\r
+ *      status = UART_16550_get_modem_status( this_uart );\r
+ *      if( status & UART_16550_DCTS )\r
+ *      {\r
+ *          uart_dcts_handler();\r
+ *      }\r
+ *      if( status & UART_16550_CTS )\r
+ *      {\r
+ *          uart_cts_handler();\r
+ *      }\r
+ *   }\r
+ * @endcode\r
+ */\r
+uint8_t\r
+UART_16550_get_modem_status\r
+(\r
+    uart_16550_instance_t * this_uart\r
+);\r
+\r
+/***************************************************************************//**\r
+ * The UART_16550_set_rxstatus_handler() function is used to register a receiver\r
+ * status handler function that is called by the driver when a UART receiver\r
+ * line status (RLS) interrupt occurs. The UART_16550_set_rxstatus_handler()\r
+ * function also enables the RLS interrupt at the Core16550 level. You must\r
+ * create and register the receiver status handler function to suit your\r
+ * application.\r
+ *\r
+ * Note:    The driver\92s top level interrupt handler function UART_16550_isr()\r
+ * will call your receive status handler function in response to an RLS\r
+ * interrupt from the Core16550.\r
+ *\r
+ * Note:    You can disable the RLS interrupt when required by calling the\r
+ * UART_16550_disable_irq() function. This is your choice and is dependent\r
+ * upon your application.\r
+ *\r
+ * @param this_uart     The this_uart parameter is a pointer to a\r
+ *                      uart_16550_instance_t structure that holds all data\r
+ *                      regarding this instance of the Core16550.\r
+ * @param handler       The handler parameter is a pointer to a receiver line\r
+ *                      status interrupt handler function provided by your\r
+ *                      application that will be called as a result of a\r
+ *                      UART RLS interrupt. This handler function must be\r
+ *                      of type uart_16550_irq_handler_t.\r
+ * Example:\r
+ * @code\r
+ * #include "core_16550.h"\r
+ *\r
+ * #define UART_57600_BAUD 26\r
+ *\r
+ * uart_16550_instance_t g_uart;\r
+ *\r
+ * void uart_rxsts_handler( uart_16550_instance_t * this_uart )\r
+ * {\r
+ *      uint8_t status;\r
+ *      status = UART_16550_get_rx_status( this_uart );\r
+ *      if( status & UART_16550_OVERUN_ERROR )\r
+ *      {\r
+ *          discard_rx_data();\r
+ *      }\r
+ * }\r
+ *\r
+ * int main(void)\r
+ * {\r
+ *     UART_16550_init( &g_uart, UART_57600_BAUD,\r
+ *                      UART_16550_DATA_8_BITS | UART_16550_NO_PARITY |\r
+ *                                             UART_16550_ONE_STOP_BIT );\r
+ *     UART_16550_set_rxstatus_handler( &g_uart, uart_rxsts_handler );\r
+ *\r
+ *     while ( 1 )\r
+ *     {\r
+ *         ;\r
+ *     }\r
+ *     return(0);\r
+ * }\r
+ * @endcode\r
+ */\r
+void\r
+UART_16550_set_rxstatus_handler\r
+(\r
+    uart_16550_instance_t * this_uart,\r
+    uart_16550_irq_handler_t handler\r
+);\r
+\r
+/***************************************************************************//**\r
+ * The UART_16550_set_tx_handler() function is used to register a transmit\r
+ * handler function that is called by the driver when a UART transmit holding\r
+ * register empty (THRE) interrupt occurs. The UART_16550_set_tx_handler()\r
+ * function also enables the THRE interrupt at the Core16550 level. You must\r
+ * create and register the transmit handler function to suit your application.\r
+ * You can use the UART_16550_fill_tx_fifo() function in your transmit handler\r
+ * function to write data to the transmitter.\r
+ *\r
+ * Note:    The driver\92s top level interrupt handler function UART_16550_isr()\r
+ * will call your transmit handler function in response to an THRE interrupt\r
+ * from the Core16550.\r
+ *\r
+ * Note:    You can disable the THRE interrupt when required by calling the\r
+ * UART_16550_disable_irq() function. This is your choice and is dependent\r
+ * upon your application.\r
+ *\r
+ * Note:    The UART_16550_irq_tx() function does not use the transmit handler\r
+ * function that you register with the UART_16550_set_tx_handler() function.\r
+ * It uses its own internal THRE interrupt handler function that overrides any\r
+ * custom interrupt handler that you register using the\r
+ * UART_16550_set_tx_handler() function.\r
+ *\r
+ * @param this_uart     The this_uart parameter is a pointer to a\r
+ *                      uart_16550_instance_t structure that holds all data\r
+ *                      regarding this instance of the Core16550.\r
+ * @param handler       The handler parameter is a pointer to a transmitter\r
+ *                      interrupt handler function provided by your application,\r
+ *                      which will be called as a result of a UART THRE interrupt.\r
+ *                      This handler is of uart_16550_irq_handler_t type.\r
+ * @return              This function does not return a value.\r
+ *\r
+ * Example:\r
+ * @code\r
+ * #include "core_16550.h"\r
+ *\r
+ * #define UART_57600_BAUD 26\r
+ *\r
+ * uart_16550_instance_t g_uart;\r
+ *\r
+ * uint8_t * g_tx_buffer;\r
+ * size_t g_tx_size = 0;\r
+ *\r
+ * void uart_tx_handler( uart_16550_instance_t * this_uart )\r
+ * {\r
+ *      size_t size_in_fifo;\r
+ *\r
+ *      size_in_fifo = UART_16550_fill_tx_fifo( this_uart,\r
+ *                                              (const uint8_t *)g_tx_buffer,\r
+ *                                              g_tx_size );\r
+ *\r
+ *      if(size_in_fifo == g_tx_size)\r
+ *      {\r
+ *         g_tx_size = 0;\r
+ *         UART_16550_disable_irq( this_uart, UART_16550_TBE_IRQ );\r
+ *      }\r
+ *      else\r
+ *      {\r
+ *         g_tx_buffer = &g_tx_buffer[size_in_fifo];\r
+ *         g_tx_size = g_tx_size - size_in_fifo;\r
+ *      }\r
+ *  }\r
+ *\r
+ *  int main(void)\r
+ *  {\r
+ *      uint8_t message[12] = "Hello world";\r
+ *\r
+ *      UART_16550_init( &g_uart, UART_57600_BAUD,\r
+ *                       UART_16550_DATA_8_BITS | UART_16550_NO_PARITY |\r
+ *                                            UART_16550_ONE_STOP_BIT );\r
+ *\r
+ *      g_tx_buffer = message;\r
+ *      g_tx_size = sizeof(message);\r
+ *\r
+ *      UART_16550_set_tx_handler( &g_uart, uart_tx_handler);\r
+ *\r
+ *      while ( 1 )\r
+ *      {\r
+ *          ;\r
+ *      }\r
+ *      return(0);\r
+ *  }\r
+ *\r
+ * @endcode\r
+ */\r
+void\r
+UART_16550_set_tx_handler\r
+(\r
+    uart_16550_instance_t * this_uart,\r
+    uart_16550_irq_handler_t handler\r
+);\r
+\r
+/***************************************************************************//**\r
+ * The UART_16550_set_modemstatus_handler() function is used to register a\r
+ * modem status handler function that is called by the driver when a UART modem\r
+ * status (MS) interrupt occurs. The UART_16550_set_modemstatus_handler()\r
+ * function also enables the MS interrupt at the Core16550 level. You must\r
+ * create and register the modem status handler function to suit your\r
+ * application.\r
+ *\r
+ * Note:    The driver\92s top level interrupt handler function UART_16550_isr()\r
+ * will call your receive status handler function in response to an MS interrupt\r
+ * from the Core16550.\r
+ *\r
+ * Note:    You can disable the MS interrupt when required by calling the\r
+ * UART_16550_disable_irq() function. This is your choice and is dependent\r
+ * upon your application.\r
+ *\r
+ * @param this_uart     The this_uart parameter is a pointer to a\r
+ *                      uart_16550_instance_t structure that holds all data\r
+ *                      regarding this instance of the Core16550.\r
+ * @param handler       The handler parameter is a pointer to a modem status\r
+ *                      interrupt handler function provided by your application\r
+ *                      that will be called as a result of a UART MS interrupt.\r
+ *                      This handler function must be of type\r
+ *                      uart_16550_irq_handler_t.\r
+ * @return              This function does not return a value.\r
+ *\r
+ * Example:\r
+ * @code\r
+ * #include "core_16550.h"\r
+ *\r
+ * #define UART_57600_BAUD 26\r
+ *\r
+ * uart_16550_instance_t g_uart;\r
+ *\r
+ * void uart_modem_handler( uart_16550_instance_t * this_uart )\r
+ * {\r
+ *      uint8_t status;\r
+ *      status = UART_16550_get_modem_status( this_uart );\r
+ *      if( status & UART_16550_CTS )\r
+ *      {\r
+ *          uart_cts_handler();\r
+ *      }\r
+ * }\r
+ *\r
+ * int main(void)\r
+ * {\r
+ *     UART_16550_init( &g_uart, UART_57600_BAUD,\r
+ *                      UART_16550_DATA_8_BITS | UART_16550_NO_PARITY |\r
+                                              UART_16550_ONE_STOP_BIT);\r
+ *     UART_16550_set_modemstatus_handler( &g_uart, uart_modem_handler);\r
+ *\r
+ *     while ( 1 )\r
+ *     {\r
+ *         ;\r
+ *     }\r
+ *     return(0);\r
+ * }\r
+ * @endcode\r
+ */\r
+void\r
+UART_16550_set_modemstatus_handler\r
+(\r
+    uart_16550_instance_t * this_uart,\r
+    uart_16550_irq_handler_t handler\r
+);\r
+\r
+/***************************************************************************//**\r
+ * The UART_16550_fill_tx_fifo() function fills the UART's hardware transmitter\r
+ * FIFO with the data found in the transmitter buffer that is passed via the\r
+ * tx_buffer function parameter. If the transmitter FIFO is not empty when the\r
+ * function is called, the function returns immediately without transferring\r
+ * any data to the FIFO; otherwise, the function transfers data from the\r
+ * transmitter buffer to the FIFO until it is full or until the complete\r
+ * contents of the transmitter buffer have been copied into the FIFO. The\r
+ * function returns the number of bytes copied into the UART's transmitter FIFO.\r
+ *\r
+ * Note:    This function reads the UART\92s line status register (LSR) to check\r
+ * for the active state of the transmitter holding register empty (THRE) bit\r
+ * before transferring data from the data buffer to the transmitter FIFO. If\r
+ * THRE is 0, the function returns immediately, without transferring any data\r
+ * to the FIFO. If THRE is 1, the function transfers up to 16 bytes of data to\r
+ * the FIFO and then returns.\r
+ *\r
+ * Note:    The actual transmission over the serial connection will still be in\r
+ * progress when this function returns. Use the UART_16550_get_tx_status()\r
+ * function if you need to know when the transmitter is empty.\r
+ *\r
+ * @param this_uart     The this_uart parameter is a pointer to a\r
+ *                      uart_16550_instance_t structure that holds all data\r
+ *                      regarding this instance of the Core16550.\r
+ * @param tx_buffer     The tx_buffer parameter is a pointer to a buffer\r
+ *                      containing the data to be transmitted.\r
+ * @param tx_size       The tx_size parameter is the size in bytes, of the data\r
+ *                      to be transmitted.\r
+ * @return              This function returns the number of bytes copied\r
+ *                      into the UART's transmitter FIFO.\r
+ *\r
+ * Example:\r
+ * @code\r
+ *   void send_using_interrupt(uint8_t * pbuff, size_t tx_size)\r
+ *   {\r
+ *       size_t size_in_fifo;\r
+ *       size_in_fifo = UART_16550_fill_tx_fifo( &g_uart, pbuff, tx_size );\r
+ *   }\r
+ * @endcode\r
+ */\r
+size_t\r
+UART_16550_fill_tx_fifo\r
+(\r
+    uart_16550_instance_t * this_uart,\r
+    const uint8_t * tx_buffer,\r
+    size_t tx_size\r
+);\r
+\r
+/***************************************************************************//**\r
+ * The UART_16550_get_tx_status() function returns the transmitter status of\r
+ * the Core16550 instance. It reads both the UART\92s line status register (LSR)\r
+ * and returns the status of the transmit holding register empty (THRE) and\r
+ * transmitter empty (TEMT) bits.\r
+ *\r
+ * @param this_uart     The this_uart parameter is a pointer to a\r
+ *                      uart_16550_instance_t structure that holds all data\r
+ *                      regarding this instance of the Core16550.\r
+ * @return              This function returns the UART\92s transmitter status\r
+ *                      as an 8-bit unsigned integer. The returned value is 0\r
+ *                      if the transmitter status bits are not set or the\r
+ *                      function execution failed. The driver provides a set\r
+ *                      of bit mask constants that should be compared with\r
+ *                      and/or used to mask the returned value to determine\r
+ *                      the transmitter status.\r
+ *                      When the return value is compared to the following\r
+ *                      bitmasks, a non-zero result indicates that the\r
+ *                      corresponding transmitter status bit is set:\r
+ *                      \95   UART_16550_THRE     (bit mask = 0x20)\r
+ *                      \95   UART_16550_TEMT     (bit mask = 0x40)\r
+ *                      When the return value is compared to the following\r
+ *                      bit mask, a non-zero result indicates that the\r
+ *                      transmitter is busy or the function execution failed.\r
+ *                      \95   UART_16550_TX_BUSY      (bit mask = 0x00)\r
+ * Example:\r
+ * @code\r
+ *   uint8_t tx_buff[10] = "abcdefghi";\r
+ *\r
+ *   UART_16550_polled_tx( &g_uart, tx_buff, sizeof(tx_buff));\r
+ *\r
+ *   while ( ! (UART_16550_TEMT & UART_16550_get_tx_status( &g_uart ) )  )\r
+ *   {\r
+ *      ;\r
+ *   }\r
+ * @endcode\r
+ */\r
+uint8_t\r
+UART_16550_get_tx_status\r
+(\r
+    uart_16550_instance_t * this_uart\r
+);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* __CORE_16550_H */\r
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 (file)
index 0000000..e5dbd7e
--- /dev/null
@@ -0,0 +1,461 @@
+/*******************************************************************************\r
+ * (c) Copyright 2008-2015 Microsemi SoC Products Group. All rights reserved.\r
+ * \r
+ * CoreGPIO bare metal driver implementation.\r
+ *\r
+ * SVN $Revision: 7964 $\r
+ * SVN $Date: 2015-10-09 18:26:53 +0530 (Fri, 09 Oct 2015) $\r
+ */\r
+#include "core_gpio.h"\r
+#include "hal.h"\r
+#include "hal_assert.h"\r
+#include "coregpio_regs.h"\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+ *\r
+ */\r
+#define GPIO_INT_ENABLE_MASK        (uint32_t)0x00000008UL\r
+#define OUTPUT_BUFFER_ENABLE_MASK   0x00000004UL\r
+\r
+\r
+#define NB_OF_GPIO  32\r
+\r
+#define CLEAR_ALL_IRQ32     (uint32_t)0xFFFFFFFF\r
+#define CLEAR_ALL_IRQ16     (uint16_t)0xFFFF\r
+#define CLEAR_ALL_IRQ8      (uint8_t)0xFF\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+ * GPIO_init()\r
+ * See "core_gpio.h" for details of how to use this function.\r
+ */\r
+void GPIO_init\r
+(\r
+    gpio_instance_t *   this_gpio,\r
+    addr_t              base_addr,\r
+    gpio_apb_width_t    bus_width\r
+)\r
+{\r
+    uint8_t i = 0;\r
+    addr_t cfg_reg_addr = base_addr;\r
+    \r
+    this_gpio->base_addr = base_addr;\r
+    this_gpio->apb_bus_width = bus_width;\r
+    \r
+    /* Clear configuration. */\r
+    for( i = 0, cfg_reg_addr = base_addr; i < NB_OF_GPIO; ++i )\r
+    {\r
+        HW_set_8bit_reg( cfg_reg_addr, 0 );\r
+        cfg_reg_addr += 4;\r
+    }\r
+    /* Clear any pending interrupts */\r
+    switch( this_gpio->apb_bus_width )\r
+    {\r
+        case GPIO_APB_32_BITS_BUS:\r
+            HAL_set_32bit_reg( this_gpio->base_addr, IRQ, CLEAR_ALL_IRQ32 );\r
+            break;\r
+            \r
+        case GPIO_APB_16_BITS_BUS:\r
+            HAL_set_16bit_reg( this_gpio->base_addr, IRQ0, (uint16_t)CLEAR_ALL_IRQ16 );\r
+            HAL_set_16bit_reg( this_gpio->base_addr, IRQ1, (uint16_t)CLEAR_ALL_IRQ16 );\r
+            break;\r
+            \r
+        case GPIO_APB_8_BITS_BUS:\r
+            HAL_set_8bit_reg( this_gpio->base_addr, IRQ0, (uint8_t)CLEAR_ALL_IRQ8 );\r
+            HAL_set_8bit_reg( this_gpio->base_addr, IRQ1, (uint8_t)CLEAR_ALL_IRQ8 );\r
+            HAL_set_8bit_reg( this_gpio->base_addr, IRQ2, (uint8_t)CLEAR_ALL_IRQ8 );\r
+            HAL_set_8bit_reg( this_gpio->base_addr, IRQ3, (uint8_t)CLEAR_ALL_IRQ8 );\r
+            break;\r
+            \r
+        default:\r
+            HAL_ASSERT(0);\r
+            break;\r
+    }\r
+}\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+ * GPIO_config\r
+ * See "core_gpio.h" for details of how to use this function.\r
+ */\r
+void GPIO_config\r
+(\r
+    gpio_instance_t *   this_gpio,\r
+    gpio_id_t           port_id,\r
+    uint32_t            config\r
+)\r
+{\r
+    HAL_ASSERT( port_id < NB_OF_GPIO );\r
+    \r
+    if ( port_id < NB_OF_GPIO )\r
+    {\r
+        uint32_t cfg_reg_addr = this_gpio->base_addr;\r
+        cfg_reg_addr += (port_id * 4);\r
+        HW_set_32bit_reg( cfg_reg_addr, config );\r
+        \r
+        /*\r
+         * Verify that the configuration was correctly written. Failure to read\r
+         * back the expected value may indicate that the GPIO port was configured\r
+         * as part of the hardware flow and cannot be modified through software.\r
+         * It may also indicate that the base address passed as parameter to\r
+         * GPIO_init() was incorrect.\r
+         */\r
+        HAL_ASSERT( HW_get_32bit_reg( cfg_reg_addr ) == config );\r
+    }\r
+}\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+ * GPIO_set_outputs\r
+ * See "core_gpio.h" for details of how to use this function.\r
+ */\r
+void GPIO_set_outputs\r
+(\r
+    gpio_instance_t *   this_gpio,\r
+    uint32_t            value\r
+)\r
+{\r
+    switch( this_gpio->apb_bus_width )\r
+    {\r
+        case GPIO_APB_32_BITS_BUS:\r
+            HAL_set_32bit_reg( this_gpio->base_addr, GPIO_OUT, value );\r
+            break;\r
+            \r
+        case GPIO_APB_16_BITS_BUS:\r
+            HAL_set_16bit_reg( this_gpio->base_addr, GPIO_OUT0, (uint16_t)value );\r
+            HAL_set_16bit_reg( this_gpio->base_addr, GPIO_OUT1, (uint16_t)(value >> 16) );\r
+            break;\r
+            \r
+        case GPIO_APB_8_BITS_BUS:\r
+            HAL_set_8bit_reg( this_gpio->base_addr, GPIO_OUT0, (uint8_t)value );\r
+            HAL_set_8bit_reg( this_gpio->base_addr, GPIO_OUT1, (uint8_t)(value >> 8) );\r
+            HAL_set_8bit_reg( this_gpio->base_addr, GPIO_OUT2, (uint8_t)(value >> 16) );\r
+            HAL_set_8bit_reg( this_gpio->base_addr, GPIO_OUT3, (uint8_t)(value >> 24) );\r
+            break;\r
+            \r
+        default:\r
+            HAL_ASSERT(0);\r
+            break;\r
+    }\r
+    \r
+    /*\r
+     * Verify that the output register was correctly written. Failure to read back\r
+     * the expected value may indicate that some of the GPIOs may not exist due to\r
+     * the number of GPIOs selected in the CoreGPIO hardware flow configuration.\r
+     * It may also indicate that the base address or APB bus width passed as\r
+     * parameter to the GPIO_init() function do not match the hardware design.\r
+     */\r
+    HAL_ASSERT( GPIO_get_outputs( this_gpio ) == value );\r
+}\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+ * GPIO_get_inputs\r
+ * See "core_gpio.h" for details of how to use this function.\r
+ */\r
+uint32_t GPIO_get_inputs\r
+(\r
+    gpio_instance_t *   this_gpio\r
+)\r
+{\r
+    uint32_t gpio_in = 0;\r
+    \r
+    switch( this_gpio->apb_bus_width )\r
+    {\r
+        case GPIO_APB_32_BITS_BUS:\r
+            gpio_in = HAL_get_32bit_reg( this_gpio->base_addr, GPIO_IN );\r
+            break;\r
+            \r
+        case GPIO_APB_16_BITS_BUS:\r
+            gpio_in |= HAL_get_16bit_reg( this_gpio->base_addr, GPIO_IN0 );\r
+            gpio_in |= (HAL_get_16bit_reg( this_gpio->base_addr, GPIO_IN1 ) << 16);\r
+            break;\r
+            \r
+        case GPIO_APB_8_BITS_BUS:\r
+            gpio_in |= HAL_get_8bit_reg( this_gpio->base_addr, GPIO_IN0 );\r
+            gpio_in |= (HAL_get_8bit_reg( this_gpio->base_addr, GPIO_IN1 ) << 8);\r
+            gpio_in |= (HAL_get_8bit_reg( this_gpio->base_addr, GPIO_IN2 ) << 16);\r
+            gpio_in |= (HAL_get_8bit_reg( this_gpio->base_addr, GPIO_IN3 ) << 24);\r
+            break;\r
+            \r
+        default:\r
+            HAL_ASSERT(0);\r
+            break;\r
+    }\r
+    \r
+    return gpio_in;\r
+}\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+ * GPIO_get_outputs\r
+ * See "core_gpio.h" for details of how to use this function.\r
+ */\r
+uint32_t GPIO_get_outputs\r
+(\r
+    gpio_instance_t *   this_gpio\r
+)\r
+{\r
+    uint32_t gpio_out = 0;\r
+    \r
+    switch( this_gpio->apb_bus_width )\r
+    {\r
+        case GPIO_APB_32_BITS_BUS:\r
+            gpio_out = HAL_get_32bit_reg( this_gpio->base_addr, GPIO_OUT );\r
+            break;\r
+            \r
+        case GPIO_APB_16_BITS_BUS:\r
+            gpio_out |= HAL_get_16bit_reg( this_gpio->base_addr, GPIO_OUT0 );\r
+            gpio_out |= (HAL_get_16bit_reg( this_gpio->base_addr, GPIO_OUT1 ) << 16);\r
+            break;\r
+            \r
+        case GPIO_APB_8_BITS_BUS:\r
+            gpio_out |= HAL_get_16bit_reg( this_gpio->base_addr, GPIO_OUT0 );\r
+            gpio_out |= (HAL_get_16bit_reg( this_gpio->base_addr, GPIO_OUT1 ) << 8);\r
+            gpio_out |= (HAL_get_16bit_reg( this_gpio->base_addr, GPIO_OUT2 ) << 16);\r
+            gpio_out |= (HAL_get_16bit_reg( this_gpio->base_addr, GPIO_OUT3 ) << 24);\r
+            break;\r
+            \r
+        default:\r
+            HAL_ASSERT(0);\r
+            break;\r
+    }\r
+    \r
+    return gpio_out;\r
+}\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+ * GPIO_set_output\r
+ * See "core_gpio.h" for details of how to use this function.\r
+ */\r
+void GPIO_set_output\r
+(\r
+    gpio_instance_t *   this_gpio,\r
+    gpio_id_t           port_id,\r
+    uint8_t             value\r
+)\r
+{\r
+    HAL_ASSERT( port_id < NB_OF_GPIO );\r
+    \r
+            \r
+    switch( this_gpio->apb_bus_width )\r
+    {\r
+        case GPIO_APB_32_BITS_BUS:\r
+            {\r
+                uint32_t outputs_state;\r
+                \r
+                outputs_state = HAL_get_32bit_reg( this_gpio->base_addr, GPIO_OUT );\r
+                if ( 0 == value )\r
+                {\r
+                    outputs_state &= ~(1 << port_id);\r
+                }\r
+                else\r
+                {\r
+                    outputs_state |= 1 << port_id;\r
+                }\r
+                HAL_set_32bit_reg( this_gpio->base_addr, GPIO_OUT, outputs_state );\r
+                \r
+                /*\r
+                 * Verify that the output register was correctly written. Failure to read back\r
+                 * the expected value may indicate that some of the GPIOs may not exist due to\r
+                 * the number of GPIOs selected in the CoreGPIO hardware flow configuration.\r
+                 * It may also indicate that the base address or APB bus width passed as\r
+                 * parameter to the GPIO_init() function do not match the hardware design.\r
+                 */\r
+                HAL_ASSERT( HAL_get_32bit_reg( this_gpio->base_addr, GPIO_OUT ) == outputs_state );\r
+            }\r
+            break;\r
+            \r
+        case GPIO_APB_16_BITS_BUS:\r
+            {\r
+                uint16_t outputs_state;\r
+                uint32_t gpio_out_reg_addr = this_gpio->base_addr + GPIO_OUT_REG_OFFSET + ((port_id >> 4) * 4);\r
+                \r
+                outputs_state = HW_get_16bit_reg( gpio_out_reg_addr );\r
+                if ( 0 == value )\r
+                {\r
+                    outputs_state &= ~(1 << (port_id & 0x0F));\r
+                }\r
+                else\r
+                {\r
+                    outputs_state |= 1 << (port_id & 0x0F);\r
+                }\r
+                HW_set_16bit_reg( gpio_out_reg_addr, outputs_state );\r
+                \r
+                /*\r
+                 * Verify that the output register was correctly written. Failure to read back\r
+                 * the expected value may indicate that some of the GPIOs may not exist due to\r
+                 * the number of GPIOs selected in the CoreGPIO hardware flow configuration.\r
+                 * It may also indicate that the base address or APB bus width passed as\r
+                 * parameter to the GPIO_init() function do not match the hardware design.\r
+                 */\r
+                HAL_ASSERT( HW_get_16bit_reg( gpio_out_reg_addr ) == outputs_state );\r
+            }\r
+            break;\r
+            \r
+        case GPIO_APB_8_BITS_BUS:\r
+            {\r
+                uint8_t outputs_state;\r
+                uint32_t gpio_out_reg_addr = this_gpio->base_addr + GPIO_OUT_REG_OFFSET + ((port_id >> 3) * 4);\r
+                \r
+                outputs_state = HW_get_8bit_reg( gpio_out_reg_addr );\r
+                if ( 0 == value )\r
+                {\r
+                    outputs_state &= ~(1 << (port_id & 0x07));\r
+                }\r
+                else\r
+                {\r
+                    outputs_state |= 1 << (port_id & 0x07);\r
+                }\r
+                HW_set_8bit_reg( gpio_out_reg_addr, outputs_state );\r
+                \r
+                /*\r
+                 * Verify that the output register was correctly written. Failure to read back\r
+                 * the expected value may indicate that some of the GPIOs may not exist due to\r
+                 * the number of GPIOs selected in the CoreGPIO hardware flow configuration.\r
+                 * It may also indicate that the base address or APB bus width passed as\r
+                 * parameter to the GPIO_init() function do not match the hardware design.\r
+                 */\r
+                HAL_ASSERT( HW_get_8bit_reg( gpio_out_reg_addr ) == outputs_state );\r
+            }\r
+            break;\r
+            \r
+        default:\r
+            HAL_ASSERT(0);\r
+            break;\r
+    }\r
+}\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+ * GPIO_drive_inout\r
+ * See "core_gpio.h" for details of how to use this function.\r
+ */\r
+void GPIO_drive_inout\r
+(\r
+    gpio_instance_t *   this_gpio,\r
+    gpio_id_t           port_id,\r
+    gpio_inout_state_t  inout_state\r
+)\r
+{\r
+    uint32_t config;\r
+    uint32_t cfg_reg_addr = this_gpio->base_addr;\r
+    \r
+    HAL_ASSERT( port_id < NB_OF_GPIO );\r
+\r
+    switch( inout_state )\r
+    {\r
+        case GPIO_DRIVE_HIGH:\r
+            /* Set output high */\r
+            GPIO_set_output( this_gpio, port_id, 1 );\r
+            \r
+            /* Enable output buffer */\r
+            cfg_reg_addr = this_gpio->base_addr + (port_id * 4);\r
+            config = HW_get_8bit_reg( cfg_reg_addr );\r
+            config |= OUTPUT_BUFFER_ENABLE_MASK;\r
+            HW_set_8bit_reg( cfg_reg_addr, config );\r
+            break;\r
+            \r
+        case GPIO_DRIVE_LOW:\r
+            /* Set output low */\r
+            GPIO_set_output( this_gpio, port_id, 0 );\r
+            \r
+            /* Enable output buffer */\r
+            cfg_reg_addr = this_gpio->base_addr + (port_id * 4);\r
+            config = HW_get_8bit_reg( cfg_reg_addr );\r
+            config |= OUTPUT_BUFFER_ENABLE_MASK;\r
+            HW_set_8bit_reg( cfg_reg_addr, config );\r
+            break;\r
+            \r
+        case GPIO_HIGH_Z:\r
+            /* Disable output buffer */\r
+            cfg_reg_addr = this_gpio->base_addr + (port_id * 4);\r
+            config = HW_get_8bit_reg( cfg_reg_addr );\r
+            config &= ~OUTPUT_BUFFER_ENABLE_MASK;\r
+            HW_set_8bit_reg( cfg_reg_addr, config );\r
+            break;\r
+            \r
+        default:\r
+            HAL_ASSERT(0);\r
+            break;\r
+    }\r
+}\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+ * GPIO_enable_irq\r
+ * See "core_gpio.h" for details of how to use this function.\r
+ */\r
+void GPIO_enable_irq\r
+(\r
+    gpio_instance_t *   this_gpio,\r
+    gpio_id_t           port_id\r
+)\r
+{\r
+    uint32_t cfg_value;\r
+    uint32_t cfg_reg_addr = this_gpio->base_addr;\r
+   \r
+    HAL_ASSERT( port_id < NB_OF_GPIO );\r
+    \r
+    if ( port_id < NB_OF_GPIO )\r
+    {\r
+        cfg_reg_addr += (port_id * 4);\r
+        cfg_value = HW_get_8bit_reg( cfg_reg_addr );\r
+        cfg_value |= GPIO_INT_ENABLE_MASK;\r
+        HW_set_8bit_reg( cfg_reg_addr, cfg_value );\r
+    }\r
+}\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+ * GPIO_disable_irq\r
+ * See "core_gpio.h" for details of how to use this function.\r
+ */\r
+void GPIO_disable_irq\r
+(\r
+    gpio_instance_t *   this_gpio,\r
+    gpio_id_t           port_id\r
+)\r
+{\r
+    uint32_t cfg_value;\r
+    uint32_t cfg_reg_addr = this_gpio->base_addr;\r
+   \r
+    HAL_ASSERT( port_id < NB_OF_GPIO );\r
+    \r
+    if ( port_id < NB_OF_GPIO )\r
+    {\r
+        cfg_reg_addr += (port_id * 4);\r
+        cfg_value = HW_get_8bit_reg( cfg_reg_addr );\r
+        cfg_value &= ~GPIO_INT_ENABLE_MASK;\r
+        HW_set_8bit_reg( cfg_reg_addr, cfg_value );\r
+    }\r
+}\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+ * GPIO_clear_irq\r
+ * See "core_gpio.h" for details of how to use this function.\r
+ */\r
+void GPIO_clear_irq\r
+(\r
+    gpio_instance_t *   this_gpio,\r
+    gpio_id_t           port_id\r
+)\r
+{\r
+    uint32_t irq_clr_value = ((uint32_t)1) << ((uint32_t)port_id);\r
+    \r
+    switch( this_gpio->apb_bus_width )\r
+    {\r
+        case GPIO_APB_32_BITS_BUS:\r
+            HAL_set_32bit_reg( this_gpio->base_addr, IRQ, irq_clr_value );\r
+            break;\r
+            \r
+        case GPIO_APB_16_BITS_BUS:\r
+            HAL_set_16bit_reg( this_gpio->base_addr, IRQ0, irq_clr_value );\r
+            HAL_set_16bit_reg( this_gpio->base_addr, IRQ1, irq_clr_value >> 16 );\r
+            break;\r
+            \r
+        case GPIO_APB_8_BITS_BUS:\r
+            HAL_set_8bit_reg( this_gpio->base_addr, IRQ0, irq_clr_value );\r
+            HAL_set_8bit_reg( this_gpio->base_addr, IRQ1, irq_clr_value >> 8 );\r
+            HAL_set_8bit_reg( this_gpio->base_addr, IRQ2, irq_clr_value >> 16 );\r
+            HAL_set_8bit_reg( this_gpio->base_addr, IRQ3, irq_clr_value >> 24 );\r
+            break;\r
+            \r
+        default:\r
+            HAL_ASSERT(0);\r
+            break;\r
+    }\r
+}\r
+\r
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 (file)
index 0000000..68799be
--- /dev/null
@@ -0,0 +1,552 @@
+/*******************************************************************************\r
+ * (c) Copyright 2008-2015 Microsemi SoC Products Group. All rights reserved.\r
+ * \r
+ *  CoreGPIO bare metal driver public API.\r
+ *\r
+ * SVN $Revision: 7964 $\r
+ * SVN $Date: 2015-10-09 18:26:53 +0530 (Fri, 09 Oct 2015) $\r
+ */\r
+\r
+/*=========================================================================*//**\r
+  @mainpage CoreGPIO Bare Metal Driver.\r
+\r
+  @section intro_sec Introduction\r
+  The CoreGPIO hardware IP includes up to 32 general purpose input output GPIOs.\r
+  This driver provides a set of functions for controlling the GPIOs as part of a\r
+  bare metal system where no operating system is available. These drivers\r
+  can be adapted for use as part of an operating system but the implementation\r
+  of the adaptation layer between this driver and the operating system's driver\r
+  model is outside the scope of this driver.\r
+  \r
+  @section driver_configuration Driver Configuration\r
+  The CoreGPIO individual IOs can be configured either in the hardware flow or\r
+  as part of the software application through calls to the GPIO_config() function.\r
+  GPIOs configured as as part of the hardware is fixed and cannot be modified\r
+  using a call to the GPI_config() function.\r
+  \r
+  @section theory_op Theory of Operation\r
+  The CoreGPIO driver uses the Actel Hardware Abstraction Layer (HAL) to access\r
+  hardware registers. You must ensure that the Actel HAL is included as part of\r
+  your software project. The Actel HAL is available through the Actel Firmware\r
+  Catalog.\r
+  \r
+  The CoreGPIO driver functions are logically grouped into the following groups:\r
+    - Initiliazation\r
+    - Configuration\r
+    - Reading and writing GPIO state\r
+    - Interrupt control\r
+  \r
+  The CoreGPIO driver is initialized through a call to the GPIO_init() function.\r
+  The GPIO_init() function must be called before any other GPIO driver functions\r
+  can be called.\r
+  \r
+  Each GPIO port is individually configured through a call to the\r
+  GPIO_config() function. Configuration includes deciding if a GPIO port\r
+  will be used as input, output or both. GPIO ports configured as inputs can be\r
+  further configured to generate interrupts based on the input's state.\r
+  Interrupts can be level or edge sensitive.\r
+  Please note that a CoreGPIO hardware instance can be generated, as part of the\r
+  hardware flow, with a fixed configuration for some or all of its IOs. Attempting\r
+  to modify the configuration of such a hardware configured IO using the\r
+  GPIO_config() function has no effect.\r
+  \r
+  The state of the GPIO ports can be read and written using the following\r
+  functions:\r
+    - GPIO_get_inputs()\r
+    - GPIO_get_outputs()\r
+    - GPIO_set_outputs()\r
+    - GPIO_drive_inout()\r
+    \r
+  Interrupts generated by GPIO ports configured as inputs are controlled using\r
+  the following functions:\r
+    - GPIO_enable_irq()\r
+    - GPIO_disable_irq()\r
+    - GPIO_clear_irq()\r
+  \r
+ *//*=========================================================================*/\r
+#ifndef CORE_GPIO_H_\r
+#define CORE_GPIO_H_\r
+\r
+#include <stdint.h>\r
+#include "cpu_types.h"\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  The gpio_id_t enumeration is used to identify GPIOs as part of the\r
+  parameter to functions:\r
+    - GPIO_config(),\r
+    - GPIO_drive_inout(),\r
+    - GPIO_enable_int(),\r
+    - GPIO_disable_int(),\r
+    - GPIO_clear_int()\r
+ */\r
+typedef enum __gpio_id_t\r
+{\r
+    GPIO_0 = 0,\r
+    GPIO_1 = 1,\r
+    GPIO_2 = 2,\r
+    GPIO_3 = 3,\r
+    GPIO_4 = 4,\r
+    GPIO_5 = 5,\r
+    GPIO_6 = 6,\r
+    GPIO_7 = 7,\r
+    GPIO_8 = 8,\r
+    GPIO_9 = 9,\r
+    GPIO_10 = 10,\r
+    GPIO_11 = 11,\r
+    GPIO_12 = 12,\r
+    GPIO_13 = 13,\r
+    GPIO_14 = 14,\r
+    GPIO_15 = 15,\r
+    GPIO_16 = 16,\r
+    GPIO_17 = 17,\r
+    GPIO_18 = 18,\r
+    GPIO_19 = 19,\r
+    GPIO_20 = 20,\r
+    GPIO_21 = 21,\r
+    GPIO_22 = 22,\r
+    GPIO_23 = 23,\r
+    GPIO_24 = 24,\r
+    GPIO_25 = 25,\r
+    GPIO_26 = 26,\r
+    GPIO_27 = 27,\r
+    GPIO_28 = 28,\r
+    GPIO_29 = 29,\r
+    GPIO_30 = 30,\r
+    GPIO_31 = 31\r
+} gpio_id_t;\r
+\r
+typedef enum __gpio_apb_width_t\r
+{\r
+    GPIO_APB_8_BITS_BUS = 0,\r
+    GPIO_APB_16_BITS_BUS = 1,\r
+    GPIO_APB_32_BITS_BUS = 2,\r
+    GPIO_APB_UNKNOWN_BUS_WIDTH = 3\r
+} gpio_apb_width_t;\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+ */\r
+typedef struct __gpio_instance_t\r
+{\r
+    addr_t              base_addr;\r
+    gpio_apb_width_t    apb_bus_width;\r
+} gpio_instance_t;\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  GPIO ports definitions used to identify GPIOs as part of the parameter to\r
+  function GPIO_set_outputs().\r
+  These definitions can also be used to identity GPIO through logical\r
+  operations on the return value of function GPIO_get_inputs().\r
+ */\r
+#define GPIO_0_MASK                0x00000001UL\r
+#define GPIO_1_MASK                0x00000002UL\r
+#define GPIO_2_MASK         0x00000004UL\r
+#define GPIO_3_MASK            0x00000008UL\r
+#define GPIO_4_MASK            0x00000010UL\r
+#define GPIO_5_MASK            0x00000020UL\r
+#define GPIO_6_MASK            0x00000040UL\r
+#define GPIO_7_MASK            0x00000080UL\r
+#define GPIO_8_MASK            0x00000100UL\r
+#define GPIO_9_MASK                0x00000200UL\r
+#define GPIO_10_MASK           0x00000400UL\r
+#define GPIO_11_MASK           0x00000800UL\r
+#define GPIO_12_MASK           0x00001000UL\r
+#define GPIO_13_MASK           0x00002000UL\r
+#define GPIO_14_MASK           0x00004000UL\r
+#define GPIO_15_MASK           0x00008000UL\r
+#define GPIO_16_MASK           0x00010000UL\r
+#define GPIO_17_MASK           0x00020000UL\r
+#define GPIO_18_MASK           0x00040000UL\r
+#define GPIO_19_MASK           0x00080000UL\r
+#define GPIO_20_MASK           0x00100000UL\r
+#define GPIO_21_MASK           0x00200000UL\r
+#define GPIO_22_MASK           0x00400000UL\r
+#define GPIO_23_MASK           0x00800000UL\r
+#define GPIO_24_MASK           0x01000000UL\r
+#define GPIO_25_MASK           0x02000000UL\r
+#define GPIO_26_MASK           0x04000000UL\r
+#define GPIO_27_MASK           0x08000000UL\r
+#define GPIO_28_MASK           0x10000000UL\r
+#define GPIO_29_MASK           0x20000000UL\r
+#define GPIO_30_MASK           0x40000000UL\r
+#define GPIO_31_MASK           0x80000000UL\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+ * GPIO modes\r
+ */\r
+#define GPIO_INPUT_MODE              0x0000000002UL\r
+#define GPIO_OUTPUT_MODE             0x0000000005UL\r
+#define GPIO_INOUT_MODE              0x0000000003UL\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+ * Possible GPIO inputs interrupt configurations.\r
+ */\r
+#define GPIO_IRQ_LEVEL_HIGH                    0x0000000000UL\r
+#define GPIO_IRQ_LEVEL_LOW                     0x0000000020UL\r
+#define GPIO_IRQ_EDGE_POSITIVE         0x0000000040UL\r
+#define GPIO_IRQ_EDGE_NEGATIVE         0x0000000060UL\r
+#define GPIO_IRQ_EDGE_BOTH                     0x0000000080UL\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+ * Possible states for GPIO configured as INOUT.\r
+ */\r
+typedef enum gpio_inout_state\r
+{\r
+    GPIO_DRIVE_LOW = 0,\r
+    GPIO_DRIVE_HIGH,\r
+    GPIO_HIGH_Z\r
+} gpio_inout_state_t;\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  The GPIO_init() function initialises a CoreGPIO hardware instance and the data\r
+  structure associated with the CoreGPIO hardware instance.\r
+  Please note that a CoreGPIO hardware instance can be generated with a fixed\r
+  configuration for some or all of its IOs as part of the hardware flow. Attempting\r
+  to modify the configuration of such a hardware configured IO using the\r
+  GPIO_config() function has no effect.\r
+\r
+  @param this_gpio\r
+    Pointer to the gpio_instance_t data structure instance holding all data\r
+    regarding the CoreGPIO hardware instance being initialized. A pointer to the\r
+    same data structure will be used in subsequent calls to the CoreGPIO driver\r
+    functions in order to identify the CoreGPIO instance that should perform the\r
+    operation implemented by the called driver function.\r
+\r
+  @param base_addr\r
+    The base_addr parameter is the base address in the processor's memory map for\r
+    the registers of the GPIO instance being initialized.\r
+    \r
+  @param bus_width\r
+    The bus_width parameter informs the driver of the APB bus width selected during\r
+    the hardware flow configuration of the CoreGPIO hardware instance. It indicates\r
+    to the driver whether the CoreGPIO hardware registers will be visible as 8, 16\r
+    or 32 bits registers. Allowed value are:\r
+        - GPIO_APB_8_BITS_BUS\r
+        - GPIO_APB_16_BITS_BUS\r
+        - GPIO_APB_32_BITS_BUS\r
+  \r
+  @return\r
+    none.\r
+    \r
+  Example:\r
+  @code\r
+    #define COREGPIO_BASE_ADDR  0xC2000000\r
+    \r
+    gpio_instance_t g_gpio;\r
+    \r
+    void system_init( void )\r
+    {\r
+        GPIO_init( &g_gpio,    COREGPIO_BASE_ADDR, GPIO_APB_32_BITS_BUS );\r
+    }\r
+  @endcode\r
+  */\r
+void GPIO_init\r
+(\r
+    gpio_instance_t *   this_gpio,\r
+    addr_t              base_addr,\r
+    gpio_apb_width_t    bus_width\r
+);\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  The GPIO_config() function is used to configure an individual GPIO port.\r
\r
+  @param this_gpio\r
+    The this_gpio parameter is a pointer to the gpio_instance_t structure holding\r
+    all data regarding the CoreGPIO instance controlled through this function call.\r
+\r
+  @param port_id\r
+    The port_id parameter identifies the GPIO port to be configured.\r
+    An enumeration item of the form GPIO_n where n is the number of the GPIO\r
+    port is used to identify the GPIO port. For example GPIO_0 identifies the\r
+    first GPIO port and GPIO_31 the last one.\r
+    \r
+  @param config\r
+    The config parameter specifies the configuration to be applied to the GPIO\r
+    port identified by the first parameter. It is a logical OR of GPIO mode and\r
+    the interrupt mode. The interrupt mode is only relevant if the GPIO is\r
+    configured as input.\r
+       Possible modes are:\r
+           - GPIO_INPUT_MODE,\r
+           - GPIO_OUTPUT_MODE,\r
+           - GPIO_INOUT_MODE.\r
+       Possible interrupt modes are:\r
+           - GPIO_IRQ_LEVEL_HIGH,\r
+           - GPIO_IRQ_LEVEL_LOW,\r
+           - GPIO_IRQ_EDGE_POSITIVE,\r
+           - GPIO_IRQ_EDGE_NEGATIVE,\r
+           - GPIO_IRQ_EDGE_BOTH\r
\r
+  @return\r
+    none.\r
+    \r
+  For example the following call will configure GPIO 4 as an input generating\r
+  interrupts on a low to high transition of the input:\r
+  @code\r
+  GPIO_config( &g_gpio, GPIO_4, GPIO_INPUT_MODE | GPIO_IRQ_EDGE_POSITIVE );\r
+  @endcode\r
+ */\r
+void GPIO_config\r
+(\r
+    gpio_instance_t *   this_gpio,\r
+    gpio_id_t           port_id,\r
+    uint32_t            config\r
+);\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  The GPIO_set_outputs() function is used to set the state of the GPIO ports\r
+  configured as outputs.\r
\r
+  @param this_gpio\r
+    The this_gpio parameter is a pointer to the gpio_instance_t structure holding\r
+    all data regarding the CoreGPIO instance controlled through this function call.\r
+\r
+  @param value\r
+    The value parameter specifies the state of the GPIO ports configured as\r
+    outputs. It is a bit mask of the form (GPIO_n_MASK | GPIO_m_MASK) where n\r
+    and m are numbers identifying GPIOs.\r
+    For example (GPIO_0_MASK | GPIO_1_MASK | GPIO_2_MASK ) specifies that the\r
+    first, second and third GPIOs' must be set high and all other outputs set\r
+    low.\r
+\r
+  @return\r
+    none.\r
+    \r
+  Example 1:\r
+    Set GPIOs outputs 0 and 8 high and all other GPIO outputs low.\r
+    @code\r
+        GPIO_set_outputs( &g_gpio, GPIO_0_MASK | GPIO_8_MASK );\r
+    @endcode\r
+\r
+  Example 2:\r
+    Set GPIOs outputs 2 and 4 low without affecting other GPIO outputs.\r
+    @code\r
+        uint32_t gpio_outputs;\r
+        gpio_outputs = GPIO_get_outputs( &g_gpio );\r
+        gpio_outputs &= ~( GPIO_2_MASK | GPIO_4_MASK );\r
+        GPIO_set_outputs( &g_gpio, gpio_outputs );\r
+    @endcode\r
+\r
+  @see GPIO_get_outputs()\r
+ */\r
+void GPIO_set_outputs\r
+(\r
+    gpio_instance_t *   this_gpio,\r
+    uint32_t            value\r
+);\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  The GPIO_set_output() function is used to set the state of a single GPIO\r
+  port configured as output.\r
\r
+  @param this_gpio\r
+    The this_gpio parameter is a pointer to the gpio_instance_t structure holding\r
+    all data regarding the CoreGPIO instance controlled through this function call.\r
+\r
+  @param port_id\r
+    The port_id parameter specifies the GPIO port that will have its output set\r
+    by a call to this function.\r
+  \r
+  @param value\r
+    The value parameter specifies the desired state for the GPIO output. A value\r
+    of 0 will set the output low and a value of 1 will set the port high.\r
+  \r
+  @return\r
+    none.\r
+ */\r
+void GPIO_set_output\r
+(\r
+    gpio_instance_t *   this_gpio,\r
+    gpio_id_t           port_id,\r
+    uint8_t             value\r
+);\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  The GPIO_get_inputs() function is used to read the state of all GPIOs\r
+  confgured as inputs.\r
\r
+  @param this_gpio\r
+    The this_gpio parameter is a pointer to the gpio_instance_t structure holding\r
+    all data regarding the CoreGPIO instance controlled through this function call.\r
+\r
+  @return\r
+    This function returns a 32 bit unsigned integer where each bit represents\r
+    the state of an input. The least significant bit representing the state of\r
+    GPIO 0 and the most significant bit the state of GPIO 31.\r
+ */\r
+uint32_t GPIO_get_inputs\r
+(\r
+    gpio_instance_t *   this_gpio\r
+);\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  The GPIO_get_outputs() function is used to read the current state of all\r
+  GPIO outputs.\r
\r
+  @param this_gpio\r
+    The this_gpio parameter is a pointer to the gpio_instance_t structure holding\r
+    all data regarding the CoreGPIO instance controlled through this function call.\r
+\r
+  @return\r
+     This function returns a 32 bit unsigned integer where each bit represents\r
+     the state of an output. The least significant bit representing the state\r
+     of GPIO 0 and the most significant bit the state of GPIO 31.\r
+ */\r
+uint32_t GPIO_get_outputs\r
+(\r
+    gpio_instance_t *   this_gpio\r
+);\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  The GPIO_drive_inout() function is used to set the output state of a\r
+  GPIO configured as INOUT. An INOUT GPIO can be in one of three states:\r
+    - high\r
+    - low\r
+    - high impedance\r
+  An INOUT output would typically be used where several devices can drive the\r
+  state of a signal. The high and low states are equivalent to the high and low\r
+  states of a GPIO configured as output. The high impedance state is used to\r
+  prevent the GPIO from driving the state of the output and therefore allow\r
+  reading the state of the GPIO as an input.\r
+  Please note that the GPIO port you wish to use as INOUT through this function\r
+  must be configurable through software. Therefore the GPIO ports used as INOUT\r
+  must not have a fixed configuration selected as part of the hardware flow.\r
\r
+  @param this_gpio\r
+    The this_gpio parameter is a pointer to the gpio_instance_t structure holding\r
+    all data regarding the CoreGPIO instance controlled through this function call.\r
+\r
+  @param port_id\r
+    The port_id parameter identifies the GPIO for whcih this function will\r
+    change the output state.\r
+    An enumeration item of the form GPIO_n where n is the number of the GPIO\r
+    port is used to identify the GPIO port. For example GPIO_0 identifies the\r
+    first GPIO port and GPIO_31 the last one.\r
+    \r
+  @param inout_state\r
+    The inout_state parameter specifies the state of the I/O identified by the\r
+    first parameter. Possible states are:\r
+                           - GPIO_DRIVE_HIGH,\r
+                           - GPIO_DRIVE_LOW,\r
+                           - GPIO_HIGH_Z (high impedance)\r
+\r
+  @return\r
+    none.\r
+    \r
+  Example:\r
+    The call to GPIO_drive_inout() below will set the GPIO 7 output to\r
+    high impedance state.\r
+    @code\r
+    GPIO_drive_inout( &g_gpio, GPIO_7, GPIO_HIGH_Z );\r
+    @endcode\r
+ */\r
+void GPIO_drive_inout\r
+(\r
+    gpio_instance_t *   this_gpio,\r
+    gpio_id_t           port_id,\r
+    gpio_inout_state_t  inout_state\r
+);\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  The GPIO_enable_irq() function is used to enable an interrupt to be\r
+  generated based on the state of the input identified as parameter.\r
\r
+  @param this_gpio\r
+    The this_gpio parameter is a pointer to the gpio_instance_t structure holding\r
+    all data regarding the CoreGPIO instance controlled through this function call.\r
+\r
+  @param port_id\r
+    The port_id parameter identifies the GPIO input the call to\r
+    GPIO_enable_irq() will enable to generate interrupts.\r
+    An enumeration item of the form GPIO_n where n is the number of the GPIO\r
+    port is used to identify the GPIO port. For example GPIO_0 identifies the\r
+    first GPIO port and GPIO_31 the last one.\r
+    \r
+  @return\r
+    none.\r
+    \r
+  Example:\r
+    The call to GPIO_enable_irq() below will allow GPIO 8 to generate\r
+    interrupts.\r
+    @code\r
+    GPIO_enable_irq( &g_gpio, GPIO_8 );\r
+    @endcode\r
+ */\r
+void GPIO_enable_irq\r
+(\r
+    gpio_instance_t *   this_gpio,\r
+    gpio_id_t           port_id\r
+);\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  The GPIO_disable_irq() function is used to disable interrupt from being\r
+  generated based on the state of the input specified as parameter.\r
\r
+  @param this_gpio\r
+    The this_gpio parameter is a pointer to the gpio_instance_t structure holding\r
+    all data regarding the CoreGPIO instance controlled through this function call.\r
+\r
+  @param port_id\r
+    The port_id parameter identifies the GPIO input the call to\r
+    GPIO_disable_irq() will disable from generating interrupts.\r
+    An enumeration item of the form GPIO_n where n is the number of the GPIO\r
+    port is used to identify the GPIO port. For example GPIO_0 identifies the\r
+    first GPIO port and GPIO_31 the last one.\r
\r
+  @return\r
+    none.\r
+    \r
+  Example:\r
+    The call to GPIO_disable_irq() below will prevent GPIO 8 from generating\r
+    interrupts.\r
+    @code\r
+    GPIO_disable_irq( &g_gpio, GPIO_8 );\r
+    @endcode\r
+ */\r
+void GPIO_disable_irq\r
+(\r
+    gpio_instance_t *   this_gpio,\r
+    gpio_id_t           port_id\r
+);\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  The GPIO_clear_irq() function is used to clear the interrupt generated by\r
+  the GPIO specified as parameter. The GPIO_clear_irq() function  must be\r
+  called as part of a GPIO interrupt service routine (ISR) in order to prevent\r
+  the same interrupt event retriggering a call to the GPIO ISR.\r
+  Please note that interrupts may also need to be cleared in the processor's\r
+  interrupt controller.\r
\r
+  @param this_gpio\r
+    The this_gpio parameter is a pointer to the gpio_instance_t structure holding\r
+    all data regarding the CoreGPIO instance controlled through this function call.\r
+\r
+  @param port_id\r
+    The port_id parameter identifies the GPIO input for which to clear the\r
+    interrupt.\r
+    An enumeration item of the form GPIO_n where n is the number of the GPIO\r
+    port is used to identify the GPIO port. For example GPIO_0 identifies the\r
+    first GPIO port and GPIO_31 the last one.\r
+    \r
+  @return\r
+    none.\r
+    \r
+  Example:\r
+    The example below demonstrates the use of the GPIO_clear_irq() function as\r
+    part of the GPIO 9 interrupt service routine on a Cortex-M processor.  \r
+    @code\r
+    void GPIO9_IRQHandler( void )\r
+    {\r
+        do_interrupt_processing();\r
+        \r
+        GPIO_clear_irq( &g_gpio, GPIO_9 );\r
+        \r
+        NVIC_ClearPendingIRQ( GPIO9_IRQn );\r
+    }\r
+    @endcode\r
+ */\r
+void GPIO_clear_irq\r
+(\r
+    gpio_instance_t *   this_gpio,\r
+    gpio_id_t           port_id\r
+);\r
+\r
+#endif /* CORE_GPIO_H_ */\r
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 (file)
index 0000000..afbbfbc
--- /dev/null
@@ -0,0 +1,40 @@
+/*******************************************************************************\r
+ * (c) Copyright 2009-2015 Microsemi SoC Products Group. All rights reserved.\r
+ * \r
+ * SVN $Revision: 7964 $\r
+ * SVN $Date: 2015-10-09 18:26:53 +0530 (Fri, 09 Oct 2015) $\r
+ */\r
+#ifndef __CORE_GPIO_REGISTERS_H\r
+#define __CORE_GPIO_REGISTERS_H                1\r
+\r
+/*------------------------------------------------------------------------------\r
+ * \r
+ */\r
+#define IRQ_REG_OFFSET          0x80\r
+\r
+#define IRQ0_REG_OFFSET         0x80\r
+#define IRQ1_REG_OFFSET         0x84\r
+#define IRQ2_REG_OFFSET         0x88\r
+#define IRQ3_REG_OFFSET         0x8C\r
+\r
+/*------------------------------------------------------------------------------\r
+ * \r
+ */\r
+#define GPIO_IN_REG_OFFSET      0x90\r
+\r
+#define GPIO_IN0_REG_OFFSET     0x90\r
+#define GPIO_IN1_REG_OFFSET     0x94\r
+#define GPIO_IN2_REG_OFFSET     0x98\r
+#define GPIO_IN3_REG_OFFSET     0x9C\r
+\r
+/*------------------------------------------------------------------------------\r
+ * \r
+ */\r
+#define GPIO_OUT_REG_OFFSET     0xA0\r
+\r
+#define GPIO_OUT0_REG_OFFSET    0xA0\r
+#define GPIO_OUT1_REG_OFFSET    0xA4\r
+#define GPIO_OUT2_REG_OFFSET    0xA8\r
+#define GPIO_OUT3_REG_OFFSET    0xAC\r
+\r
+#endif /* __CORE_GPIO_REGISTERS_H */\r
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 (file)
index 0000000..daa1887
--- /dev/null
@@ -0,0 +1,1563 @@
+/*******************************************************************************\r
+ * (c) Copyright 2009-2015 Microsemi  SoC Products Group.  All rights reserved.\r
+ * \r
+ * CoreI2C software driver implementation.\r
+ * \r
+ * SVN $Revision: 7984 $\r
+ * SVN $Date: 2015-10-12 12:07:40 +0530 (Mon, 12 Oct 2015) $\r
+ */\r
+#include <stdint.h>\r
+#include <stdlib.h>\r
+#include <stddef.h>\r
+#include <unistd.h>\r
+#include <errno.h>\r
+#include <sys/stat.h>\r
+#include <sys/times.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include "cpu_types.h"\r
+#include "core_smbus_regs.h"\r
+#include "core_i2c.h"\r
+#include "hal.h"\r
+#include "hal_assert.h"\r
+\r
+\r
+#include <string.h>\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+/*------------------------------------------------------------------------------\r
+ * I2C transaction direction.\r
+ */\r
+#define WRITE_DIR    0u\r
+#define READ_DIR     1u\r
+\r
+/* -- TRANSACTIONS TYPES -- */\r
+#define NO_TRANSACTION                      0u\r
+#define MASTER_WRITE_TRANSACTION            1u\r
+#define MASTER_READ_TRANSACTION             2u\r
+#define MASTER_RANDOM_READ_TRANSACTION      3u\r
+#define WRITE_SLAVE_TRANSACTION             4u\r
+#define READ_SLAVE_TRANSACTION              5u\r
+\r
+/* -- SMBUS H/W STATES -- */\r
+/* -- MASTER STATES -- */\r
+#define ST_BUS_ERROR        0x00u           /* Bus error during MST or selected slave modes */\r
+#define ST_I2C_IDLE         0xF8u           /* No activity and no interrupt either... */\r
+#define ST_START            0x08u           /* start condition sent */\r
+#define ST_RESTART          0x10u           /* repeated start */\r
+#define ST_SLAW_ACK         0x18u           /* SLA+W sent, ack received */\r
+#define ST_SLAW_NACK        0x20u           /* SLA+W sent, nack received */\r
+#define ST_TX_DATA_ACK      0x28u           /* Data sent, ACK'ed */\r
+#define ST_TX_DATA_NACK     0x30u           /* Data sent, NACK'ed */\r
+#define ST_LOST_ARB         0x38u           /* Master lost arbitration */\r
+#define ST_SLAR_ACK         0x40u           /* SLA+R sent, ACK'ed */\r
+#define ST_SLAR_NACK        0x48u           /* SLA+R sent, NACK'ed */\r
+#define ST_RX_DATA_ACK      0x50u           /* Data received, ACK sent */\r
+#define ST_RX_DATA_NACK     0x58u           /* Data received, NACK sent */\r
+#define ST_RESET_ACTIVATED  0xD0u           /* Master reset is activated */\r
+#define ST_STOP_TRANSMIT    0xE0u           /* Stop has been transmitted */\r
+\r
+/* -- SLAVE STATES -- */\r
+#define ST_SLAVE_SLAW       0x60u           /* SLA+W received */\r
+#define ST_SLAVE_SLAR_ACK   0xA8u           /* SLA+R received, ACK returned */\r
+#define ST_SLV_LA           0x68u           /* Slave lost arbitration */\r
+#define ST_GCA              0x70u           /* GCA received */\r
+#define ST_GCA_LA           0x78u           /* GCA lost arbitration */\r
+#define ST_RDATA            0x80u           /* Data received */\r
+#define ST_SLA_NACK         0x88u           /* Slave addressed, NACK returned */\r
+#define ST_GCA_ACK          0x90u           /* Previously addresses with GCA, data ACKed */\r
+#define ST_GCA_NACK         0x98u           /* GCA addressed, NACK returned */\r
+#define ST_RSTOP            0xA0u           /* Stop received */\r
+#define ST_SLARW_LA         0xB0u           /* Arbitration lost */\r
+#define ST_RACK             0xB8u           /* Byte sent, ACK received */\r
+#define ST_SLAVE_RNACK      0xC0u           /* Byte sent, NACK received */\r
+#define ST_FINAL            0xC8u           /* Final byte sent, ACK received */\r
+#define ST_SLV_RST          0xD8u           /* Slave reset state */\r
+\r
+\r
+/* I2C Channel base offset */\r
+#define CHANNEL_BASE_SHIFT    5u\r
+#define CHANNEL_MASK        0x1E0u\r
+\r
+/*\r
+ * Maximum address offset length in slave write-read transactions.\r
+ * A maximum of two bytes will be interpreted as address offset within the slave\r
+ * tx buffer.\r
+ */\r
+#define MAX_OFFSET_LENGTH       2u\r
+\r
+/*------------------------------------------------------------------------------\r
+ * I2C interrupts control functions implemented "i2c_interrupt.c".\r
+ * the implementation of these functions depend on the underlying hardware\r
+ * design and how the CoreI2C interrupt line is connected to the system's\r
+ * interrupt controller.\r
+ */\r
+void I2C_enable_irq( i2c_instance_t * this_i2c );\r
+void I2C_disable_irq( i2c_instance_t * this_i2c );\r
+static void enable_slave_if_required(i2c_instance_t * this_i2c);\r
+\r
+/*------------------------------------------------------------------------------\r
+ * I2C_init()\r
+ * See "core_i2c.h" for details of how to use this function.\r
+ */\r
+void I2C_init\r
+(\r
+    i2c_instance_t * this_i2c,\r
+    addr_t base_address,\r
+    uint8_t ser_address,\r
+    i2c_clock_divider_t ser_clock_speed\r
+)\r
+{\r
+    psr_t saved_psr;\r
+    uint_fast16_t clock_speed = (uint_fast16_t)ser_clock_speed;\r
+    \r
+    /*\r
+     * We need to disable ints while doing this as there is no guarantee we\r
+     * have not been called already and the ISR is active.\r
+     */\r
+\r
+   saved_psr=HAL_disable_interrupts();\r
+    \r
+    /*\r
+     * Initialize all items of the this_i2c data structure to zero. This\r
+     * initializes all state variables to their init value. It relies on\r
+     * the fact that NO_TRANSACTION, I2C_SUCCESS and I2C_RELEASE_BUS all\r
+     * have an actual value of zero.\r
+     */\r
+    memset(this_i2c, 0, sizeof(i2c_instance_t));\r
+    \r
+    /*\r
+     * Set base address of I2C hardware used by this instance.\r
+     */\r
+    this_i2c->base_address = base_address;\r
+\r
+    /*\r
+     * Update Serial address of the device\r
+     */\r
+    this_i2c->ser_address = ((uint_fast8_t)ser_address << 1u);\r
+    \r
+    /*\r
+     * Configure hardware.\r
+     */\r
+    HAL_set_8bit_reg_field(this_i2c->base_address, ENS1, 0x00); /* Reset I2C hardware. */\r
+    HAL_set_8bit_reg_field(this_i2c->base_address, ENS1, 0x01); /* set enable bit */\r
+    HAL_set_8bit_reg_field(this_i2c->base_address, CR2, ( (clock_speed >> 2) & 0x01) );\r
+    HAL_set_8bit_reg_field(this_i2c->base_address, CR1, ( (clock_speed >> 1) & 0x01) );\r
+    HAL_set_8bit_reg_field(this_i2c->base_address, CR0, ( clock_speed & 0x01) );\r
+\r
+    HAL_set_8bit_reg(this_i2c->base_address, ADDRESS, this_i2c->ser_address);\r
+    HAL_set_8bit_reg(this_i2c->base_address, ADDRESS1, this_i2c->ser_address);\r
+    \r
+    /*\r
+     * Finally safe to enable interrupts.\r
+     */\r
+\r
+       HAL_restore_interrupts( saved_psr );\r
+}\r
+/*------------------------------------------------------------------------------\r
+ * I2C_channel_init()\r
+ * See "core_i2c.h" for details of how to use this function.\r
+ */\r
+void I2C_channel_init\r
+(\r
+    i2c_instance_t * this_i2c_channel,\r
+    i2c_instance_t * this_i2c,\r
+    i2c_channel_number_t channel_number,\r
+    i2c_clock_divider_t ser_clock_speed\r
+)\r
+{\r
+    psr_t saved_psr;\r
+    uint_fast16_t clock_speed = (uint_fast16_t)ser_clock_speed;\r
+    \r
+    HAL_ASSERT(channel_number < I2C_MAX_CHANNELS);\r
+    HAL_ASSERT(I2C_CHANNEL_0 != channel_number);\r
+\r
+    /* \r
+     * Cannot allow channel 0 in this function as we will trash the hardware\r
+     * base address and slave address.\r
+     */\r
+    if ((channel_number < I2C_MAX_CHANNELS) &&\r
+        (I2C_CHANNEL_0 != channel_number))\r
+    {\r
+        /*\r
+         * We need to disable ints while doing this as the hardware should already\r
+         * be active at this stage.\r
+         */\r
+\r
+       saved_psr=HAL_disable_interrupts();\r
+        /*\r
+         * Initialize channel data.\r
+         */\r
+        memset(this_i2c_channel, 0, sizeof(i2c_instance_t));\r
+        \r
+        this_i2c_channel->base_address =\r
+               ((this_i2c->base_address) & ~((addr_t)CHANNEL_MASK)) \r
+            | (((addr_t)channel_number) << CHANNEL_BASE_SHIFT);\r
+\r
+        this_i2c_channel->ser_address = this_i2c->ser_address;\r
+\r
+        HAL_set_8bit_reg_field(this_i2c_channel->base_address, ENS1, 0x00); /* Reset I2C channel hardware. */\r
+        HAL_set_8bit_reg_field(this_i2c_channel->base_address, ENS1, 0x01); /* set enable bit */\r
+        HAL_set_8bit_reg_field(this_i2c_channel->base_address, CR2, ( (clock_speed >> 2) & 0x01) );\r
+        HAL_set_8bit_reg_field(this_i2c_channel->base_address, CR1, ( (clock_speed >> 1) & 0x01) );\r
+        HAL_set_8bit_reg_field(this_i2c_channel->base_address, CR0, ( clock_speed & 0x01) );\r
+        /*\r
+         * Finally safe to enable interrupts.\r
+         */\r
+\r
+       HAL_restore_interrupts( saved_psr );\r
+    }\r
+}\r
+\r
+/*------------------------------------------------------------------------------\r
+ * I2C_write()\r
+ * See "core_i2c.h" for details of how to use this function.\r
+ */\r
+void I2C_write\r
+(\r
+    i2c_instance_t * this_i2c,\r
+    uint8_t serial_addr,\r
+    const uint8_t * write_buffer,\r
+    uint16_t write_size,\r
+    uint8_t options\r
+)\r
+{\r
+    psr_t saved_psr;\r
+    volatile uint8_t stat_ctrl;\r
+\r
+\r
+       saved_psr=HAL_disable_interrupts();\r
+\r
+    /* Update the transaction only when there is no transaction going on I2C */\r
+    if( this_i2c->transaction == NO_TRANSACTION)\r
+    {\r
+      this_i2c->transaction = MASTER_WRITE_TRANSACTION;\r
+    }\r
+\r
+    /* Update the Pending transaction information so that transaction can restarted */\r
+    this_i2c->pending_transaction = MASTER_WRITE_TRANSACTION ;\r
+\r
+    /* Update target address */\r
+    this_i2c->target_addr = (uint_fast8_t)serial_addr << 1u;\r
+    this_i2c->dir = WRITE_DIR;\r
+    this_i2c->master_tx_buffer = write_buffer;\r
+    this_i2c->master_tx_size = write_size;\r
+    this_i2c->master_tx_idx = 0u;\r
+\r
+    /* Set I2C status in progress */\r
+    this_i2c->master_status = I2C_IN_PROGRESS;\r
+    this_i2c->options = options;\r
+\r
+    if(I2C_IN_PROGRESS == this_i2c->slave_status)\r
+    {\r
+        this_i2c->is_transaction_pending = 1u;\r
+    }\r
+    else\r
+    {\r
+        HAL_set_8bit_reg_field(this_i2c->base_address, STA, 0x01u);\r
+    }\r
+\r
+    /*\r
+     * Clear interrupts if required (depends on repeated starts).\r
+     * Since the Bus is on hold, only then prior status needs to\r
+     * be cleared.\r
+     */\r
+    if ( I2C_HOLD_BUS == this_i2c->bus_status )\r
+    {\r
+        HAL_set_8bit_reg_field(this_i2c->base_address, SI, 0x00u);\r
+    }\r
+\r
+    stat_ctrl = HAL_get_8bit_reg( this_i2c->base_address, STATUS);\r
+    stat_ctrl = stat_ctrl;  /* Avoids lint warning. */\r
+\r
+    /* Enable the interrupt. ( Re-enable) */\r
+    I2C_enable_irq( this_i2c );\r
+\r
+\r
+       HAL_restore_interrupts(saved_psr);\r
+}\r
+\r
+/*------------------------------------------------------------------------------\r
+ * I2C_read()\r
+ * See "core_i2c.h" for details of how to use this function.\r
+ */\r
+void I2C_read\r
+(\r
+    i2c_instance_t * this_i2c,\r
+    uint8_t serial_addr,\r
+    uint8_t * read_buffer,\r
+    uint16_t read_size,\r
+    uint8_t options\r
+)\r
+{\r
+    psr_t saved_psr;\r
+    volatile uint8_t stat_ctrl;\r
+\r
+\r
+       saved_psr=HAL_disable_interrupts();\r
+    \r
+    /* Update the transaction only when there is no transaction going on I2C */\r
+    if( this_i2c->transaction == NO_TRANSACTION)\r
+    {\r
+      this_i2c->transaction = MASTER_READ_TRANSACTION;\r
+    }\r
+\r
+    /* Update the Pending transaction information so that transaction can restarted */\r
+    this_i2c->pending_transaction = MASTER_READ_TRANSACTION ;\r
+\r
+    /* Update target address */\r
+    this_i2c->target_addr = (uint_fast8_t)serial_addr << 1u;\r
+\r
+    this_i2c->dir = READ_DIR;\r
+\r
+    this_i2c->master_rx_buffer = read_buffer;\r
+    this_i2c->master_rx_size = read_size;\r
+    this_i2c->master_rx_idx = 0u;\r
+\r
+    /* Set I2C status in progress */\r
+    this_i2c->master_status = I2C_IN_PROGRESS;\r
+\r
+    this_i2c->options = options;\r
+    \r
+    if(I2C_IN_PROGRESS == this_i2c->slave_status)\r
+    {\r
+        this_i2c->is_transaction_pending = 1u;\r
+    }\r
+    else\r
+    {\r
+        HAL_set_8bit_reg_field(this_i2c->base_address, STA, 0x01u);\r
+    }\r
+\r
+    /*\r
+     * Clear interrupts if required (depends on repeated starts).\r
+     * Since the Bus is on hold, only then prior status needs to\r
+     * be cleared.\r
+     */\r
+    if ( I2C_HOLD_BUS == this_i2c->bus_status )\r
+    {\r
+        HAL_set_8bit_reg_field(this_i2c->base_address, SI, 0x00u);\r
+    }\r
+\r
+    stat_ctrl = HAL_get_8bit_reg( this_i2c->base_address, STATUS);\r
+    stat_ctrl = stat_ctrl;  /* Avoids lint warning. */\r
+\r
+    /* Enable the interrupt. ( Re-enable) */\r
+    I2C_enable_irq( this_i2c );\r
+\r
+       HAL_restore_interrupts( saved_psr );\r
+\r
+}\r
+\r
+/*------------------------------------------------------------------------------\r
+ * I2C_write_read()\r
+ * See "core_i2c.h" for details of how to use this function.\r
+ */\r
+void I2C_write_read\r
+(\r
+    i2c_instance_t * this_i2c,\r
+    uint8_t serial_addr,\r
+    const uint8_t * addr_offset,\r
+    uint16_t offset_size,\r
+    uint8_t * read_buffer,\r
+    uint16_t read_size,\r
+    uint8_t options\r
+)\r
+{\r
+    HAL_ASSERT(offset_size > 0u);\r
+    HAL_ASSERT(addr_offset != (uint8_t *)0);\r
+    HAL_ASSERT(read_size > 0u);\r
+    HAL_ASSERT(read_buffer != (uint8_t *)0);\r
+    \r
+    this_i2c->master_status = I2C_FAILED;\r
+    \r
+    if((read_size > 0u) && (offset_size > 0u))\r
+    {\r
+        psr_t saved_psr;\r
+        volatile uint8_t stat_ctrl;\r
+\r
+\r
+       saved_psr=HAL_disable_interrupts();\r
+\r
+        /* Update the transaction only when there is no transaction going on I2C */\r
+        if( this_i2c->transaction == NO_TRANSACTION)\r
+        {\r
+            this_i2c->transaction = MASTER_RANDOM_READ_TRANSACTION;\r
+        }\r
+\r
+        /* Update the Pending transaction information so that transaction can restarted */\r
+        this_i2c->pending_transaction = MASTER_RANDOM_READ_TRANSACTION ;\r
+\r
+        /* Update target address */\r
+        this_i2c->target_addr = (uint_fast8_t)serial_addr << 1u;\r
+\r
+        this_i2c->dir = WRITE_DIR;\r
+\r
+        this_i2c->master_tx_buffer = addr_offset;\r
+        this_i2c->master_tx_size = offset_size;\r
+        this_i2c->master_tx_idx = 0u;\r
+\r
+        this_i2c->master_rx_buffer = read_buffer;\r
+        this_i2c->master_rx_size = read_size;\r
+        this_i2c->master_rx_idx = 0u;\r
+        \r
+        /* Set I2C status in progress */\r
+        this_i2c->master_status = I2C_IN_PROGRESS;\r
+        this_i2c->options = options;\r
+        \r
+        if(I2C_IN_PROGRESS == this_i2c->slave_status)\r
+        {\r
+            this_i2c->is_transaction_pending = 1u;\r
+        }\r
+        else\r
+        {\r
+            HAL_set_8bit_reg_field(this_i2c->base_address, STA, 0x01u);\r
+        }\r
+\r
+        /*\r
+         * Clear interrupts if required (depends on repeated starts).\r
+         * Since the Bus is on hold, only then prior status needs to\r
+         * be cleared.\r
+         */\r
+        if ( I2C_HOLD_BUS == this_i2c->bus_status )\r
+        {\r
+            HAL_set_8bit_reg_field(this_i2c->base_address, SI, 0x00u);\r
+        }\r
+\r
+        stat_ctrl = HAL_get_8bit_reg( this_i2c->base_address, STATUS);\r
+        stat_ctrl = stat_ctrl;  /* Avoids lint warning. */\r
+            \r
+        /* Enable the interrupt. ( Re-enable) */\r
+        I2C_enable_irq( this_i2c );\r
+\r
+\r
+       HAL_restore_interrupts( saved_psr );\r
+    }\r
+}\r
+\r
+/*------------------------------------------------------------------------------\r
+ * I2C_get_status()\r
+ * See "core_i2c.h" for details of how to use this function.\r
+ */\r
+i2c_status_t I2C_get_status\r
+(\r
+    i2c_instance_t * this_i2c\r
+)\r
+{\r
+    i2c_status_t i2c_status ;\r
+\r
+    i2c_status = this_i2c->master_status ;\r
+\r
+    return i2c_status;\r
+}\r
+\r
+/*------------------------------------------------------------------------------\r
+ * I2C_wait_complete()\r
+ * See "core_i2c.h" for details of how to use this function.\r
+ */\r
+i2c_status_t I2C_wait_complete\r
+(\r
+    i2c_instance_t * this_i2c,\r
+    uint32_t timeout_ms\r
+)\r
+{\r
+    i2c_status_t i2c_status;\r
+    psr_t saved_psr;\r
+    /*\r
+     * Because we have no idea of what CPU we are supposed to be running on\r
+     * we need to guard this write to the timeout value to avoid ISR/user code\r
+     * interaction issues. Checking the status below should be fine as only a\r
+     * single byte should change in that.\r
+     */\r
+\r
+       saved_psr=HAL_disable_interrupts();\r
+    this_i2c->master_timeout_ms = timeout_ms;\r
+\r
+       HAL_restore_interrupts( saved_psr );\r
+\r
+    /* Run the loop until state returns I2C_FAILED  or I2C_SUCESS*/\r
+    do {\r
+        i2c_status = this_i2c->master_status;\r
+    } while(I2C_IN_PROGRESS == i2c_status);\r
+    return i2c_status;\r
+}\r
+\r
+/*------------------------------------------------------------------------------\r
+ * I2C_system_tick()\r
+ * See "core_i2c.h" for details of how to use this function.\r
+ */\r
+void I2C_system_tick\r
+(\r
+    i2c_instance_t * this_i2c,\r
+    uint32_t ms_since_last_tick\r
+)\r
+{\r
+    if(this_i2c->master_timeout_ms != I2C_NO_TIMEOUT)\r
+    {\r
+       if(this_i2c->master_timeout_ms > ms_since_last_tick)\r
+        {\r
+            this_i2c->master_timeout_ms -= ms_since_last_tick;\r
+        }\r
+        else\r
+        {\r
+            psr_t saved_psr;\r
+            /*\r
+             * We need to disable interrupts here to ensure we can update the\r
+             * shared data without the I2C ISR interrupting us.\r
+             */\r
+\r
+       saved_psr=HAL_disable_interrupts();\r
+\r
+            /*\r
+             * Mark current transaction as having timed out.\r
+             */\r
+            this_i2c->master_status = I2C_TIMED_OUT;\r
+            this_i2c->transaction = NO_TRANSACTION;\r
+            this_i2c->is_transaction_pending = 0;\r
+\r
+\r
+       HAL_restore_interrupts( saved_psr );\r
+            \r
+            /*\r
+             * Make sure we do not incorrectly signal a timeout for subsequent\r
+             * transactions.\r
+             */\r
+            this_i2c->master_timeout_ms = I2C_NO_TIMEOUT;\r
+        }\r
+    }\r
+}\r
+\r
+/*------------------------------------------------------------------------------\r
+ * I2C_set_slave_tx_buffer()\r
+ * See "core_i2c.h" for details of how to use this function.\r
+ */\r
+void I2C_set_slave_tx_buffer\r
+(\r
+    i2c_instance_t * this_i2c,\r
+    const uint8_t * tx_buffer,\r
+    uint16_t tx_size\r
+)\r
+{\r
+    psr_t saved_psr;\r
+\r
+    /*\r
+     * We need to disable interrupts here to ensure we can update the\r
+     * shared data without the I2C ISR interrupting us.\r
+     */\r
+\r
+       saved_psr=HAL_disable_interrupts();\r
+    \r
+    this_i2c->slave_tx_buffer = tx_buffer;\r
+    this_i2c->slave_tx_size = tx_size;\r
+    this_i2c->slave_tx_idx = 0u;\r
+    \r
+\r
+       HAL_restore_interrupts( saved_psr );\r
+}\r
+\r
+/*------------------------------------------------------------------------------\r
+ * I2C_set_slave_rx_buffer()\r
+ * See "core_i2c.h" for details of how to use this function.\r
+ */\r
+void I2C_set_slave_rx_buffer\r
+(\r
+    i2c_instance_t * this_i2c,\r
+    uint8_t * rx_buffer,\r
+    uint16_t rx_size\r
+)\r
+{\r
+    psr_t saved_psr;\r
+\r
+    /*\r
+     * We need to disable interrupts here to ensure we can update the\r
+     * shared data without the I2C ISR interrupting us.\r
+     */\r
+\r
+       saved_psr=HAL_disable_interrupts();\r
+\r
+    this_i2c->slave_rx_buffer = rx_buffer;\r
+    this_i2c->slave_rx_size = rx_size;\r
+    this_i2c->slave_rx_idx = 0u;\r
+\r
+\r
+       HAL_restore_interrupts( saved_psr );\r
+}\r
+\r
+/*------------------------------------------------------------------------------\r
+ * I2C_set_slave_mem_offset_length()\r
+ * See "core_i2c.h" for details of how to use this function.\r
+ */\r
+void I2C_set_slave_mem_offset_length\r
+(\r
+    i2c_instance_t * this_i2c,\r
+    uint8_t offset_length\r
+)\r
+{\r
+    HAL_ASSERT(offset_length <= MAX_OFFSET_LENGTH);\r
+    \r
+    /*\r
+     * Single byte update, should be interrupt safe\r
+     */\r
+    if(offset_length > MAX_OFFSET_LENGTH)\r
+    {\r
+        this_i2c->slave_mem_offset_length = MAX_OFFSET_LENGTH;\r
+    }\r
+    else\r
+    {\r
+        this_i2c->slave_mem_offset_length = offset_length;\r
+    }\r
+}\r
+\r
+/*------------------------------------------------------------------------------\r
+ * I2C_register_write_handler()\r
+ * See "core_i2c.h" for details of how to use this function.\r
+ */\r
+void I2C_register_write_handler\r
+(\r
+    i2c_instance_t * this_i2c,\r
+    i2c_slave_wr_handler_t handler\r
+)\r
+{\r
+    psr_t saved_psr;\r
+\r
+    /*\r
+     * We need to disable interrupts here to ensure we can update the\r
+     * shared data without the I2C ISR interrupting us.\r
+     */\r
+\r
+       saved_psr=HAL_disable_interrupts();\r
+\r
+    this_i2c->slave_write_handler = handler;\r
+\r
+\r
+       HAL_restore_interrupts( saved_psr );\r
+}\r
+\r
+/*------------------------------------------------------------------------------\r
+ * I2C_enable_slave()\r
+ * See "core_i2c.h" for details of how to use this function.\r
+ */\r
+void I2C_enable_slave\r
+(\r
+    i2c_instance_t * this_i2c\r
+)\r
+{\r
+    psr_t saved_psr;\r
+\r
+    /*\r
+     * We need to disable interrupts here to ensure we can update the\r
+     * hardware register and slave mode flag without the I2C ISR interrupting\r
+     * us.\r
+     */\r
+\r
+       saved_psr=HAL_disable_interrupts();\r
+\r
+    /* Set the Assert Acknowledge bit. */\r
+    HAL_set_8bit_reg_field(this_i2c->base_address, AA, 0x01u);\r
+\r
+    /* Enable slave mode */\r
+    this_i2c->is_slave_enabled = 1u;\r
+\r
+\r
+       HAL_restore_interrupts( saved_psr );\r
+\r
+    /* Enable I2C IRQ*/\r
+    I2C_enable_irq( this_i2c );\r
+}\r
+\r
+/*------------------------------------------------------------------------------\r
+ * I2C_disable_slave()\r
+ * See "core_i2c.h" for details of how to use this function.\r
+ */\r
+void I2C_disable_slave\r
+(\r
+    i2c_instance_t * this_i2c\r
+)\r
+{\r
+    psr_t saved_psr;\r
+\r
+    /*\r
+     * We need to disable interrupts here to ensure we can update the\r
+     * hardware register without the I2C ISR interrupting us.\r
+     */\r
+\r
+       saved_psr=HAL_disable_interrupts();\r
+    \r
+    /* Reset the assert acknowledge bit. */\r
+    HAL_set_8bit_reg_field(this_i2c->base_address, AA, 0x00u);\r
+\r
+    /* Disable slave mode with IRQ blocked to make whole change atomic */\r
+    this_i2c->is_slave_enabled = 0u;\r
+\r
+\r
+       HAL_restore_interrupts( saved_psr );\r
+}\r
+\r
+/*------------------------------------------------------------------------------\r
+ * \r
+ */\r
+static void enable_slave_if_required\r
+(\r
+    i2c_instance_t * this_i2c\r
+)\r
+{\r
+    /*\r
+     * This function is only called from within the ISR and so does not need\r
+     * guarding on the register access.\r
+     */\r
+    if( 0 != this_i2c->is_slave_enabled )\r
+    {\r
+        HAL_set_8bit_reg_field( this_i2c->base_address, AA, 0x01u );\r
+    }\r
+}\r
+/*------------------------------------------------------------------------------\r
+ * I2C_set_slave_second_addr()\r
+ * See "i2c.h" for details of how to use this function.\r
+ */\r
+void I2C_set_slave_second_addr\r
+(\r
+    i2c_instance_t * this_i2c,\r
+    uint8_t second_slave_addr\r
+)\r
+{\r
+    uint8_t second_slave_address;\r
+    \r
+    /*\r
+      This function does not support CoreI2C hardware configured with a fixed \r
+      second slave address.  The current implementation of the ADDR1[0] register\r
+      bit makes it difficult for the driver to support both programmable and\r
+      fixed second slave address, so we choose to support programmable only.\r
+      With the programmable configuration, ADDR1[0] and ADDR0[0] both control\r
+      enable/disable of GCA recognition, as an effective OR of the 2 bit fields.\r
+      Therefore we set ADDR1[0] to 0 here, so that only ADDR0[0] controls GCA.\r
+     */\r
+    second_slave_address = (uint8_t)((second_slave_addr << 1u) & (~SLAVE1_EN_MASK));\r
+\r
+    /*\r
+     * Single byte register write, should be interrupt safe\r
+     */\r
+    HAL_set_8bit_reg(this_i2c->base_address, ADDRESS1, second_slave_address);\r
+}\r
+\r
+/*------------------------------------------------------------------------------\r
+ * I2C_disable_slave_second_addr()\r
+ * See "i2c.h" for details of how to use this function.\r
+ */\r
+void I2C_disable_slave_second_addr\r
+(\r
+    i2c_instance_t * this_i2c\r
+)\r
+{\r
+    /*\r
+      We are disabling the second slave address by setting the value of the 2nd\r
+      slave address to the primary slave address. The reason for using this method\r
+      of disabling 2nd slave address is that ADDRESS1[0] has different meaning \r
+      depending on hardware configuration. Its use would likely interfere with\r
+      the intended GCA setting.\r
+     */\r
+    /*\r
+     * Single byte register write, should be interrupt safe\r
+     */\r
+    HAL_set_8bit_reg(this_i2c->base_address, ADDRESS1, this_i2c->ser_address);\r
+}\r
+\r
+/*------------------------------------------------------------------------------\r
+ * i2C_set_gca()\r
+ * See "i2c.h" for details of how to use this function.\r
+ */\r
+\r
+void I2C_set_gca\r
+(\r
+    i2c_instance_t * this_i2c\r
+)\r
+{\r
+    /* \r
+     * This read modify write access should be interrupt safe as the address\r
+     * register is not written to in the ISR.\r
+     */\r
+    /* accept GC addressing. */\r
+    HAL_set_8bit_reg_field(this_i2c->base_address, GC, 0x01u);\r
+}\r
+\r
+/*------------------------------------------------------------------------------\r
+ * I2C_clear_gca()\r
+ * See "i2c.h" for details of how to use this function.\r
+ */\r
+void I2C_clear_gca\r
+(\r
+    i2c_instance_t * this_i2c\r
+)\r
+{\r
+    /* \r
+     * This read modify write access should be interrupt safe as the address\r
+     * register is not written to in the ISR.\r
+     */\r
+    /* Clear GC addressing. */\r
+    HAL_set_8bit_reg_field(this_i2c->base_address, GC, 0x00u);\r
+}\r
+\r
+/*------------------------------------------------------------------------------\r
+ * I2C_isr()\r
+ * See "core_i2c.h" for details of how to use this function.\r
+ */\r
+void I2C_isr\r
+(\r
+    i2c_instance_t * this_i2c\r
+)\r
+{\r
+    volatile uint8_t status;\r
+    uint8_t data;\r
+    uint8_t hold_bus;\r
+    uint8_t clear_irq = 1u;\r
+\r
+    status = HAL_get_8bit_reg( this_i2c->base_address, STATUS);\r
+    \r
+    switch( status )\r
+    {\r
+        /************** MASTER TRANSMITTER / RECEIVER *******************/\r
+      \r
+        case ST_START: /* start has been xmt'd */\r
+        case ST_RESTART: /* repeated start has been xmt'd */\r
+           //write_hex(STDOUT_FILENO, status);\r
+            HAL_set_8bit_reg_field( this_i2c->base_address, STA, 0x00u);\r
+            HAL_set_8bit_reg( this_i2c->base_address, DATA, this_i2c->target_addr); /* write call address */\r
+            HAL_set_8bit_reg_field( this_i2c->base_address, DIR, this_i2c->dir); /* set direction bit */\r
+            if(this_i2c->dir == WRITE_DIR)\r
+            {\r
+                 this_i2c->master_tx_idx = 0u;\r
+            }\r
+            else\r
+            {\r
+                 this_i2c->master_rx_idx = 0u;\r
+            }\r
+\r
+            /*\r
+             * Clear the pending transaction. This condition will be true if the slave \r
+             * has acquired the bus to carry out pending master transaction which \r
+             * it had received during its slave transmission or reception mode. \r
+             */\r
+            if(this_i2c->is_transaction_pending)\r
+            {\r
+                this_i2c->is_transaction_pending = 0u;\r
+            }\r
+\r
+            /*\r
+             * Make sure to update proper transaction after master START\r
+             * or RESTART\r
+             */\r
+            if(this_i2c->transaction != this_i2c->pending_transaction)\r
+            {\r
+                this_i2c->transaction = this_i2c->pending_transaction;\r
+            }\r
+            break;\r
+            \r
+        case ST_LOST_ARB:\r
+              /* Set start bit.  Let's keep trying!  Don't give up! */\r
+              HAL_set_8bit_reg_field(this_i2c->base_address, STA, 0x01u);\r
+              break;\r
+\r
+        case ST_STOP_TRANSMIT:\r
+             /* Stop has been transmitted. Do nothing */\r
+              break;\r
+\r
+        /******************* MASTER TRANSMITTER *************************/\r
+        case ST_SLAW_NACK:\r
+           //write_hex(STDOUT_FILENO, status);\r
+            /* SLA+W has been transmitted; not ACK has been received - let's stop. */\r
+            HAL_set_8bit_reg_field(this_i2c->base_address, STO, 0x01u);\r
+            this_i2c->master_status = I2C_FAILED;\r
+            this_i2c->transaction = NO_TRANSACTION;\r
+            enable_slave_if_required(this_i2c);\r
+            break;\r
+            \r
+        case ST_SLAW_ACK:\r
+        case ST_TX_DATA_ACK:\r
+           //write_hex(STDOUT_FILENO, status);\r
+            /* data byte has been xmt'd with ACK, time to send stop bit or repeated start. */\r
+            if (this_i2c->master_tx_idx < this_i2c->master_tx_size)\r
+            {    \r
+                HAL_set_8bit_reg(this_i2c->base_address, DATA, (uint_fast8_t)this_i2c->master_tx_buffer[this_i2c->master_tx_idx++]);\r
+            }\r
+            else if ( this_i2c->transaction == MASTER_RANDOM_READ_TRANSACTION )\r
+            {\r
+                /* We are finished sending the address offset part of a random read transaction.\r
+                 * It is is time to send a restart in order to change direction. */\r
+                 this_i2c->dir = READ_DIR;\r
+                 HAL_set_8bit_reg_field(this_i2c->base_address, STA, 0x01u);\r
+            }\r
+            else /* done sending. let's stop */\r
+            {\r
+                /*\r
+                 * Set the transaction back to NO_TRANSACTION to allow user to do further\r
+                 * transaction\r
+                 */\r
+                this_i2c->transaction = NO_TRANSACTION;\r
+                hold_bus = this_i2c->options & I2C_HOLD_BUS;\r
+\r
+                /* Store the information of current I2C bus status in the bus_status*/\r
+                this_i2c->bus_status  = hold_bus;\r
+                if ( hold_bus == 0u )\r
+                { \r
+                    HAL_set_8bit_reg_field(this_i2c->base_address, STO, 0x01u);  /*xmt stop condition */\r
+                    enable_slave_if_required(this_i2c);\r
+                }\r
+                else\r
+                {\r
+                    I2C_disable_irq( this_i2c );\r
+                    clear_irq = 0u;\r
+                }\r
+                this_i2c->master_status = I2C_SUCCESS;\r
+            }\r
+            break;\r
+\r
+          case ST_TX_DATA_NACK:\r
+           //write_hex(STDOUT_FILENO, status);\r
+            /* data byte SENT, ACK to be received\r
+             * In fact, this means we've received a NACK (This may not be \r
+             * obvious, but if we've rec'd an ACK then we would be in state \r
+             * 0x28!) hence, let's send a stop bit\r
+             */\r
+            HAL_set_8bit_reg_field(this_i2c->base_address, STO, 0x01u);/* xmt stop condition */\r
+            this_i2c->master_status = I2C_FAILED;\r
+\r
+            /*\r
+             * Set the transaction back to NO_TRANSACTION to allow user to do further\r
+             * transaction\r
+             */\r
+            this_i2c->transaction = NO_TRANSACTION;\r
+            enable_slave_if_required(this_i2c);\r
+            break;\r
+              \r
+      /********************* MASTER (or slave?) RECEIVER *************************/\r
+      \r
+      /* STATUS codes 08H, 10H, 38H are all covered in MTX mode */\r
+        case ST_SLAR_ACK: /* SLA+R tx'ed. */\r
+//         //write_hex(STDOUT_FILENO, status);\r
+            /* Let's make sure we ACK the first data byte received (set AA bit in CTRL) unless\r
+             * the next byte is the last byte of the read transaction.\r
+             */\r
+            if(this_i2c->master_rx_size > 1u)\r
+            {\r
+                HAL_set_8bit_reg_field(this_i2c->base_address, AA, 0x01u);\r
+            }\r
+            else if(1u == this_i2c->master_rx_size)\r
+            {\r
+                HAL_set_8bit_reg_field(this_i2c->base_address, AA, 0x00u);\r
+            }\r
+            else /* this_i2c->master_rx_size == 0u */\r
+            {\r
+                HAL_set_8bit_reg_field(this_i2c->base_address, AA, 0x01u);\r
+                HAL_set_8bit_reg_field(this_i2c->base_address, STO, 0x01u);\r
+                this_i2c->master_status = I2C_SUCCESS;\r
+                this_i2c->transaction = NO_TRANSACTION;\r
+            }\r
+            break;\r
+            \r
+        case ST_SLAR_NACK: /* SLA+R tx'ed; let's release the bus (send a stop condition) */\r
+//         //write_hex(STDOUT_FILENO, status);\r
+            HAL_set_8bit_reg_field(this_i2c->base_address, STO, 0x01u);\r
+            this_i2c->master_status = I2C_FAILED;\r
+\r
+            /*\r
+             * Set the transaction back to NO_TRANSACTION to allow user to do further\r
+             * transaction\r
+             */\r
+            this_i2c->transaction = NO_TRANSACTION;\r
+            enable_slave_if_required(this_i2c);\r
+            break;\r
+          \r
+        case ST_RX_DATA_ACK: /* Data byte received, ACK returned */\r
+//         //write_hex(STDOUT_FILENO, status);\r
+            /* First, get the data */\r
+            this_i2c->master_rx_buffer[this_i2c->master_rx_idx++] = HAL_get_8bit_reg(this_i2c->base_address, DATA);\r
+            if( this_i2c->master_rx_idx >= (this_i2c->master_rx_size - 1u))\r
+            {\r
+                /* If we're at the second last byte, let's set AA to 0 so\r
+                 * we return a NACK at the last byte. */\r
+                HAL_set_8bit_reg_field(this_i2c->base_address, AA, 0x00u);\r
+            }\r
+            break;\r
+            \r
+        case ST_RX_DATA_NACK: /* Data byte received, NACK returned */\r
+//         //write_hex(STDOUT_FILENO, status);\r
+            /* Get the data, then send a stop condition */\r
+            this_i2c->master_rx_buffer[this_i2c->master_rx_idx] = HAL_get_8bit_reg(this_i2c->base_address, DATA);\r
+          \r
+            hold_bus = this_i2c->options & I2C_HOLD_BUS; \r
+\r
+            /* Store the information of current I2C bus status in the bus_status*/\r
+            this_i2c->bus_status  = hold_bus;\r
+            if ( hold_bus == 0u )\r
+            { \r
+                HAL_set_8bit_reg_field(this_i2c->base_address, STO, 0x01u);  /*xmt stop condition */\r
+\r
+                /* Bus is released, now we can start listening to bus, if it is slave */\r
+                   enable_slave_if_required(this_i2c);\r
+            }\r
+            else\r
+            {\r
+                I2C_disable_irq( this_i2c );\r
+                clear_irq = 0u;\r
+            }\r
+            /*\r
+             * Set the transaction back to NO_TRANSACTION to allow user to do further\r
+             * transaction\r
+             */\r
+            this_i2c->transaction = NO_TRANSACTION;\r
+            this_i2c->master_status = I2C_SUCCESS;\r
+            break;\r
+        \r
+        /******************** SLAVE RECEIVER **************************/\r
+        case ST_GCA_NACK: /* NACK after, GCA addressing */\r
+        case ST_SLA_NACK: /* Re-enable AA (assert ack) bit for future transmissions */\r
+           //write_hex(STDOUT_FILENO, status);\r
+            HAL_set_8bit_reg_field(this_i2c->base_address, AA, 0x01u);\r
+\r
+            this_i2c->transaction = NO_TRANSACTION;\r
+            this_i2c->slave_status = I2C_SUCCESS;\r
+            \r
+            /* Check if transaction was pending. If yes, set the START bit */\r
+            if(this_i2c->is_transaction_pending)\r
+            {\r
+                HAL_set_8bit_reg_field(this_i2c->base_address, STA, 0x01u);\r
+            }\r
+            break;\r
+            \r
+        case ST_GCA_LA: /* Arbitr. lost (GCA rec'd) */\r
+        case ST_SLV_LA: /* Arbitr. lost (SLA rec'd) */\r
+           //write_hex(STDOUT_FILENO, status);\r
+            /*\r
+             *  We lost arbitration and either the GCE or our address was the\r
+             *  one received so pend the master operation we were starting.\r
+             */\r
+            this_i2c->is_transaction_pending = 1u;\r
+            /* Fall through to normal ST processing as we are now in slave mode */\r
+\r
+        case ST_GCA: /* General call address received, ACK returned */\r
+        case ST_SLAVE_SLAW: /* SLA+W received, ACK returned */\r
+           //write_hex(STDOUT_FILENO, status);\r
+            this_i2c->transaction = WRITE_SLAVE_TRANSACTION;\r
+            this_i2c->slave_rx_idx = 0u;\r
+            this_i2c->random_read_addr = 0u;\r
+            /*\r
+             * If Start Bit is set clear it, but store that information since it is because of\r
+             * pending transaction\r
+             */\r
+            if(HAL_get_8bit_reg_field(this_i2c->base_address, STA))\r
+            {\r
+                HAL_set_8bit_reg_field(this_i2c->base_address, STA, 0x00u);\r
+                this_i2c->is_transaction_pending = 1u;\r
+            }\r
+            this_i2c->slave_status = I2C_IN_PROGRESS;\r
+#ifdef INCLUDE_SLA_IN_RX_PAYLOAD\r
+            /* Fall through to put address as first byte in payload buffer */\r
+#else\r
+            /* Only break from this case if the slave address must NOT be included at the\r
+             * beginning of the received write data. */\r
+            break;\r
+#endif            \r
+        case ST_GCA_ACK: /* DATA received; ACK sent after GCA */\r
+        case ST_RDATA: /* DATA received; must clear DATA register */\r
+           //write_hex(STDOUT_FILENO, status);\r
+            if((this_i2c->slave_rx_buffer != (uint8_t *)0)\r
+               && (this_i2c->slave_rx_idx < this_i2c->slave_rx_size))\r
+            {\r
+                data = HAL_get_8bit_reg(this_i2c->base_address, DATA);\r
+                this_i2c->slave_rx_buffer[this_i2c->slave_rx_idx++] = data;\r
+                \r
+#ifdef INCLUDE_SLA_IN_RX_PAYLOAD\r
+                if((ST_RDATA == status) || (ST_GCA_ACK == status))\r
+                {\r
+                    /* Ignore the slave address byte in the random read address\r
+                       computation in the case where INCLUDE_SLA_IN_RX_PAYLOAD\r
+                       is defined. */\r
+#endif\r
+                    this_i2c->random_read_addr = (this_i2c->random_read_addr << 8) + data;\r
+#ifdef INCLUDE_SLA_IN_RX_PAYLOAD\r
+                }\r
+#endif\r
+            }\r
+            \r
+            if(this_i2c->slave_rx_idx >= this_i2c->slave_rx_size)\r
+            {\r
+                /* Rx buffer is full. NACK next received byte. */\r
+                HAL_set_8bit_reg_field(this_i2c->base_address, AA, 0x00u); \r
+            }\r
+            break;\r
+            \r
+        case ST_RSTOP:\r
+           //write_hex(STDOUT_FILENO, status);\r
+            /* STOP or repeated START occurred. */\r
+            /* We cannot be sure if the transaction has actually completed as\r
+             * this hardware state reports that either a STOP or repeated START\r
+             * condition has occurred. We assume that this is a repeated START\r
+             * if the transaction was a write from the master to this point.*/\r
+            if ( this_i2c->transaction == WRITE_SLAVE_TRANSACTION )\r
+            {\r
+                if ( this_i2c->slave_rx_idx == this_i2c->slave_mem_offset_length )\r
+                {\r
+                    this_i2c->slave_tx_idx = this_i2c->random_read_addr;\r
+                }\r
+                /* Call the slave's write transaction handler if it exists. */\r
+                if ( this_i2c->slave_write_handler != 0u )\r
+                {\r
+                    i2c_slave_handler_ret_t h_ret;\r
+                    h_ret = this_i2c->slave_write_handler( this_i2c, this_i2c->slave_rx_buffer, (uint16_t)this_i2c->slave_rx_idx );\r
+                    if ( I2C_REENABLE_SLAVE_RX == h_ret )\r
+                    {\r
+                        /* There is a small risk that the write handler could\r
+                         * call I2C_disable_slave() but return\r
+                         * I2C_REENABLE_SLAVE_RX in error so we only enable\r
+                         * ACKs if still in slave mode. */\r
+                         enable_slave_if_required(this_i2c);\r
+                    }\r
+                    else\r
+                    {\r
+                        HAL_set_8bit_reg_field( this_i2c->base_address, AA, 0x0u );\r
+                        /* Clear slave mode flag as well otherwise in mixed\r
+                         * master/slave applications, the AA bit will get set by\r
+                         * subsequent master operations. */\r
+                        this_i2c->is_slave_enabled = 0u;\r
+                    }\r
+                }\r
+                else\r
+                {\r
+                    /* Re-enable address acknowledge in case we were ready to nack the next received byte. */\r
+                    HAL_set_8bit_reg_field( this_i2c->base_address, AA, 0x01u );\r
+                }\r
+            }\r
+            else /* A stop or repeated start outside a write/read operation */\r
+            {\r
+                /*\r
+                 * Reset slave_tx_idx so that a subsequent read will result in the slave's\r
+                 * transmit buffer being sent from the first byte.\r
+                 */\r
+                this_i2c->slave_tx_idx = 0u;\r
+                /*\r
+                 * See if we need to re-enable acknowledgement as some error conditions, such\r
+                 * as a master prematurely ending a transfer, can see us get here with AA set\r
+                 * to 0 which will disable slave operation if we are not careful.\r
+                 */\r
+                enable_slave_if_required(this_i2c);\r
+            }\r
+\r
+            /* Mark any previous master write transaction as complete. */\r
+            this_i2c->slave_status = I2C_SUCCESS;\r
+            \r
+            /* Check if transaction was pending. If yes, set the START bit */\r
+            if(this_i2c->is_transaction_pending)\r
+            {\r
+                HAL_set_8bit_reg_field(this_i2c->base_address, STA, 0x01u);\r
+            }\r
+\r
+            /*\r
+             * Set the transaction back to NO_TRANSACTION to allow user to do further\r
+             * transaction\r
+             */\r
+            this_i2c->transaction = NO_TRANSACTION;\r
+\r
+            break;\r
+            \r
+        case ST_SLV_RST: /* SMBUS ONLY: timeout state. must clear interrupt */\r
+           //write_hex(STDOUT_FILENO, status);\r
+            /*\r
+             * Set the transaction back to NO_TRANSACTION to allow user to do further\r
+             * transaction.\r
+             */\r
+            this_i2c->transaction = NO_TRANSACTION;\r
+            /*\r
+             * Reset slave_tx_idx so that a subsequent read will result in the slave's\r
+             * transmit buffer being sent from the first byte.\r
+             */\r
+            this_i2c->slave_tx_idx = 0u;\r
+            /*\r
+             * Clear status to I2C_FAILED only if there was an operation in progress.\r
+             */\r
+            if(I2C_IN_PROGRESS == this_i2c->slave_status)\r
+            {\r
+                this_i2c->slave_status = I2C_FAILED;\r
+            }\r
+\r
+            enable_slave_if_required(this_i2c); /* Make sure AA is set correctly */\r
+\r
+            break;\r
+            \r
+        /****************** SLAVE TRANSMITTER **************************/\r
+        case ST_SLAVE_SLAR_ACK: /* SLA+R received, ACK returned */\r
+        case ST_SLARW_LA:       /* Arbitration lost, and: */\r
+        case ST_RACK:           /* Data tx'ed, ACK received */\r
+           //write_hex(STDOUT_FILENO, status);\r
+            if ( status == ST_SLAVE_SLAR_ACK )\r
+            {\r
+                this_i2c->transaction = READ_SLAVE_TRANSACTION;\r
+                this_i2c->random_read_addr = 0u;\r
+                this_i2c->slave_status = I2C_IN_PROGRESS;\r
+                /* If Start Bit is set clear it, but store that information since it is because of\r
+                 * pending transaction\r
+                 */\r
+                if(HAL_get_8bit_reg_field(this_i2c->base_address, STA))\r
+                {\r
+                    HAL_set_8bit_reg_field(this_i2c->base_address, STA, 0x00u);\r
+                    this_i2c->is_transaction_pending = 1u;\r
+                 }\r
+            }\r
+            if (this_i2c->slave_tx_idx >= this_i2c->slave_tx_size)\r
+            {\r
+                /* Ensure 0xFF is returned to the master when the slave specifies\r
+                 * an empty transmit buffer. */\r
+                HAL_set_8bit_reg(this_i2c->base_address, DATA, 0xFFu);\r
+            }\r
+            else\r
+            {\r
+                /* Load the data the data byte to be sent to the master. */\r
+                HAL_set_8bit_reg(this_i2c->base_address, DATA, (uint_fast8_t)this_i2c->slave_tx_buffer[this_i2c->slave_tx_idx++]);\r
+            }\r
+            /* Determine if this is the last data byte to send to the master. */\r
+            if (this_i2c->slave_tx_idx >= this_i2c->slave_tx_size) /* last byte? */\r
+            {\r
+                 HAL_set_8bit_reg_field(this_i2c->base_address, AA, 0x00u); \r
+                /* Next read transaction will result in slave's transmit buffer\r
+                 * being sent from the first byte. */\r
+                this_i2c->slave_tx_idx = 0u;\r
+            }\r
+            break;\r
+        \r
+        case ST_SLAVE_RNACK:    /* Data byte has been transmitted; not-ACK has been received. */\r
+        case ST_FINAL: /* Last Data byte tx'ed, ACK received */\r
+           //write_hex(STDOUT_FILENO, status);\r
+            /* We assume that the transaction will be stopped by the master.\r
+             * Reset slave_tx_idx so that a subsequent read will result in the slave's\r
+             * transmit buffer being sent from the first byte. */\r
+            this_i2c->slave_tx_idx = 0u;\r
+            HAL_set_8bit_reg_field(this_i2c->base_address, AA, 0x01u); \r
+\r
+            /*  Mark previous state as complete */\r
+            this_i2c->slave_status = I2C_SUCCESS;\r
+            /* Check if transaction was pending. If yes, set the START bit */\r
+            if(this_i2c->is_transaction_pending)\r
+            {\r
+                HAL_set_8bit_reg_field(this_i2c->base_address, STA, 0x01u);\r
+            }\r
+            /*\r
+             * Set the transaction back to NO_TRANSACTION to allow user to do further\r
+             * transaction\r
+             */\r
+            this_i2c->transaction = NO_TRANSACTION;\r
+\r
+            break;\r
+\r
+        /* Master Reset has been activated Wait 35 ms for interrupt to be set,\r
+         * clear interrupt and proceed to 0xF8 state. */\r
+        case ST_RESET_ACTIVATED:\r
+        case ST_BUS_ERROR: /* Bus error during MST or selected slave modes */\r
+        default:\r
+           //write_hex(STDOUT_FILENO, status);\r
+            /* Some undefined state has encountered. Clear Start bit to make\r
+             * sure, next good transaction happen */\r
+            HAL_set_8bit_reg_field(this_i2c->base_address, STA, 0x00u);\r
+            /*\r
+             * Set the transaction back to NO_TRANSACTION to allow user to do further\r
+             * transaction.\r
+             */\r
+            this_i2c->transaction = NO_TRANSACTION;\r
+            /*\r
+             * Reset slave_tx_idx so that a subsequent read will result in the slave's\r
+             * transmit buffer being sent from the first byte.\r
+             */\r
+            this_i2c->slave_tx_idx = 0u;\r
+            /*\r
+             * Clear statuses to I2C_FAILED only if there was an operation in progress.\r
+             */\r
+            if(I2C_IN_PROGRESS == this_i2c->master_status)\r
+            {\r
+                this_i2c->master_status = I2C_FAILED;\r
+            }\r
+\r
+            if(I2C_IN_PROGRESS == this_i2c->slave_status)\r
+            {\r
+                this_i2c->slave_status = I2C_FAILED;\r
+            }\r
+\r
+            break;\r
+    }\r
+    \r
+    if ( clear_irq )\r
+    {\r
+        /* clear interrupt. */\r
+        HAL_set_8bit_reg_field(this_i2c->base_address, SI, 0x00u);\r
+    }\r
+    \r
+    /* Read the status register to ensure the last I2C registers write took place\r
+     * in a system built around a bus making use of posted writes. */\r
+//    status = HAL_get_8bit_reg( this_i2c->base_address, STATUS);\r
+}\r
+\r
+/*------------------------------------------------------------------------------\r
+ * I2C_smbus_init()\r
+ * See "i2c.h" for details of how to use this function.\r
+ */\r
\r
+/*\r
+ * SMBSUS_NO    = 1\r
+ * SMBALERT_NO  = 1\r
+ * SMBus enable = 1\r
+ */\r
+#define INIT_AND_ENABLE_SMBUS   0x54u\r
+void I2C_smbus_init\r
+(\r
+    i2c_instance_t * this_i2c\r
+)\r
+{\r
+    /*\r
+     * Single byte register write, should be interrupt safe\r
+     */\r
+    /* Enable SMBUS */\r
+    HAL_set_8bit_reg(this_i2c->base_address, SMBUS, INIT_AND_ENABLE_SMBUS);\r
+}\r
+\r
+/*------------------------------------------------------------------------------\r
+ * I2C_enable_smbus_irq()\r
+ * See "i2c.h" for details of how to use this function.\r
+ */\r
+void I2C_enable_smbus_irq\r
+(\r
+    i2c_instance_t * this_i2c,\r
+    uint8_t  irq_type\r
+)\r
+{\r
+    psr_t saved_psr;\r
+\r
+    /*\r
+     * We need to disable interrupts here to ensure we can update the\r
+     * hardware register without the SMBUS IRQs interrupting us.\r
+     */\r
+\r
+       saved_psr=HAL_disable_interrupts();\r
+\r
+    if ( irq_type & I2C_SMBALERT_IRQ)\r
+    {\r
+        HAL_set_8bit_reg_field(this_i2c->base_address, SMBALERT_IE, 0x01u);\r
+    }\r
+    if ( irq_type & I2C_SMBSUS_IRQ)\r
+    {\r
+        HAL_set_8bit_reg_field(this_i2c->base_address, SMBSUS_IE, 0x01u);\r
+    }\r
+    \r
+\r
+       HAL_restore_interrupts( saved_psr );\r
+}\r
+\r
+/*------------------------------------------------------------------------------\r
+ * I2C_disable_smbus_irq()\r
+ * See "i2c.h" for details of how to use this function.\r
+ */\r
+void I2C_disable_smbus_irq\r
+(\r
+    i2c_instance_t * this_i2c,\r
+    uint8_t  irq_type\r
+)\r
+{\r
+    psr_t saved_psr;\r
+\r
+    /*\r
+     * We need to disable interrupts here to ensure we can update the\r
+     * hardware register without the SMBUS IRQs interrupting us.\r
+     */\r
+\r
+       saved_psr=HAL_disable_interrupts();\r
+\r
+    if ( irq_type & I2C_SMBALERT_IRQ)\r
+    {\r
+        HAL_set_8bit_reg_field(this_i2c->base_address, SMBALERT_IE, 0x00u);\r
+    }\r
+    if (irq_type & I2C_SMBSUS_IRQ )\r
+    {\r
+        HAL_set_8bit_reg_field(this_i2c->base_address, SMBSUS_IE, 0x00u);\r
+    }\r
+    \r
+\r
+       HAL_restore_interrupts( saved_psr );\r
+}\r
+\r
+/*------------------------------------------------------------------------------\r
+ * I2C_suspend_smbus_slave()\r
+ * See "i2c.h" for details of how to use this function.\r
+ */\r
+void I2C_suspend_smbus_slave\r
+(\r
+    i2c_instance_t * this_i2c\r
+)\r
+{\r
+    psr_t saved_psr;\r
+\r
+    /*\r
+     * We need to disable interrupts here to ensure we can update the\r
+     * hardware register without the SMBUS IRQs interrupting us.\r
+     */\r
+\r
+       saved_psr=HAL_disable_interrupts();\r
+\r
+    HAL_set_8bit_reg_field(this_i2c->base_address, SMBSUS_NO_CONTROL, 0x00u);\r
+\r
+\r
+       HAL_restore_interrupts( saved_psr );\r
+}\r
+\r
+/*------------------------------------------------------------------------------\r
+ * I2C_resume_smbus_slave()\r
+ * See "i2c.h" for details of how to use this function.\r
+ */\r
+void I2C_resume_smbus_slave\r
+(\r
+    i2c_instance_t * this_i2c\r
+)\r
+{\r
+    psr_t saved_psr;\r
+\r
+    /*\r
+     * We need to disable interrupts here to ensure we can update the\r
+     * hardware register without the SMBUS IRQs interrupting us.\r
+     */\r
+\r
+       saved_psr=HAL_disable_interrupts();\r
+\r
+    HAL_set_8bit_reg_field(this_i2c->base_address, SMBSUS_NO_CONTROL, 0x01u);\r
+\r
+\r
+       HAL_restore_interrupts( saved_psr );\r
+}\r
+\r
+/*------------------------------------------------------------------------------\r
+ * I2C_reset_smbus()\r
+ * See "i2c.h" for details of how to use this function.\r
+ */\r
+void I2C_reset_smbus\r
+(\r
+    i2c_instance_t * this_i2c\r
+)\r
+{\r
+    psr_t saved_psr;\r
+\r
+    /*\r
+     * We need to disable interrupts here to ensure we can update the\r
+     * hardware register without the SMBUS IRQs interrupting us.\r
+     */\r
+\r
+       saved_psr=HAL_disable_interrupts();\r
+    HAL_set_8bit_reg_field(this_i2c->base_address, SMBUS_MST_RESET, 0x01u);\r
+    \r
+\r
+       HAL_restore_interrupts( saved_psr );\r
+}\r
+\r
+/*------------------------------------------------------------------------------\r
+ * I2C_set_smbus_alert()\r
+ * See "i2c.h" for details of how to use this function.\r
+ */\r
+void I2C_set_smbus_alert\r
+(\r
+    i2c_instance_t * this_i2c\r
+)\r
+{\r
+    psr_t saved_psr;\r
+\r
+    /*\r
+     * We need to disable interrupts here to ensure we can update the\r
+     * hardware register without the SMBUS IRQs interrupting us.\r
+     */\r
+\r
+       saved_psr=HAL_disable_interrupts();\r
+    HAL_set_8bit_reg_field(this_i2c->base_address, SMBALERT_NO_CONTROL, 0x00u);\r
+\r
+\r
+       HAL_restore_interrupts( saved_psr );\r
+}\r
+\r
+/*------------------------------------------------------------------------------\r
+ * I2C_clear_smbus_alert()\r
+ * See "i2c.h" for details of how to use this function.\r
+ */\r
+void I2C_clear_smbus_alert\r
+(\r
+    i2c_instance_t * this_i2c\r
+)\r
+{\r
+    psr_t saved_psr;\r
+\r
+    /*\r
+     * We need to disable interrupts here to ensure we can update the\r
+     * hardware register without the SMBUS IRQs interrupting us.\r
+     */\r
+\r
+       saved_psr=HAL_disable_interrupts();\r
+\r
+    HAL_set_8bit_reg_field(this_i2c->base_address, SMBALERT_NO_CONTROL, 0x01u);\r
+\r
+\r
+       HAL_restore_interrupts( saved_psr );\r
+}\r
+\r
+/*------------------------------------------------------------------------------\r
+ * I2C_get_irq_status()\r
+ * See "i2c.h" for details of how to use this function.\r
+ */\r
+uint8_t I2C_get_irq_status\r
+(\r
+    i2c_instance_t * this_i2c\r
+)\r
+{\r
+    uint8_t status ;\r
+    uint8_t irq_type = I2C_NO_IRQ ;\r
+\r
+    status = HAL_get_8bit_reg(this_i2c->base_address, SMBUS);\r
+\r
+    if( status & (uint8_t)SMBALERT_NI_STATUS_MASK )\r
+    {\r
+        irq_type |= I2C_SMBALERT_IRQ ;\r
+    }\r
+\r
+    if( status & (uint8_t)SMBSUS_NI_STATUS_MASK )\r
+    {\r
+        irq_type |= I2C_SMBSUS_IRQ ;\r
+    }\r
+\r
+    status = HAL_get_8bit_reg(this_i2c->base_address, CONTROL);\r
+\r
+    if( status & (uint8_t)SI_MASK )\r
+    {\r
+        irq_type |= I2C_INTR_IRQ ;\r
+    }\r
+    return(irq_type);\r
+}\r
+\r
+/*------------------------------------------------------------------------------\r
+ * I2C_set_slave_addr2()\r
+ * See "i2c.h" for details of how to use this function.\r
+ */\r
+void I2C_set_user_data\r
+(\r
+    i2c_instance_t * this_i2c,\r
+    void * p_user_data\r
+)\r
+{\r
+    this_i2c->p_user_data = p_user_data ;\r
+}\r
+\r
+/*------------------------------------------------------------------------------\r
+ * I2C_get_user_data()\r
+ * See "i2c.h" for details of how to use this function.\r
+ */\r
+void * I2C_get_user_data\r
+(\r
+    i2c_instance_t * this_i2c\r
+)\r
+{\r
+    return( this_i2c->p_user_data);\r
+}\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
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 (file)
index 0000000..2b1d5ac
--- /dev/null
@@ -0,0 +1,2280 @@
+/*******************************************************************************\r
+ * (c) Copyright 2009-2015 Microsemi SoC Products Group.  All rights reserved.\r
+ * \r
+ * CoreI2C software driver Application Programming Interface.\r
+ * This file contains defines and function declarations allowing to interface\r
+ * with the CoreI2C software driver.\r
+ * \r
+ * SVN $Revision: 7984 $\r
+ * SVN $Date: 2015-10-12 12:07:40 +0530 (Mon, 12 Oct 2015) $\r
+ */\r
+/*=========================================================================*//**\r
+  @mainpage CoreI2C Bare Metal Driver.\r
+   The CoreI2C bare metal software driver supports I2C master and slave\r
+   operations.\r
+\r
+  @section intro_sec Introduction\r
+  The CoreI2C driver provides a set of functions for controlling the Microsemi\r
+  CoreI2C hardware IP. The driver supports up to 16 separate I2C channels per\r
+  CoreI2C instance, with common slave address settings shared between channels\r
+  on a device.\r
+  \r
+  Optional features of the CoreI2C allow it operate with I2C based protocols\r
+  such as System Management Bus (SMBus), Power Management Bus (PMBus) and\r
+  Intelligent Platform Management Interface (IPMI). This driver provides support\r
+  for these features when enabled in the CoreI2C IP.\r
+  \r
+  The major features provided by CoreI2C driver are:\r
+    - Support for configuring the I2C channels of each CoreI2C peripheral.\r
+    - I2C master operations.\r
+    - I2C slave operations.\r
+    - SMBus related operations.\r
+\r
+  This driver can be used as part of a bare metal system where no operating \r
+  system  is available. The driver can be adapted for use as part of an \r
+  operating system, but the implementation of the adaptation layer between the \r
+  driver and  the operating system's driver model is outside the scope of this \r
+  driver.\r
+  \r
+  @section hw_dependencies Hardware Flow Dependencies\r
+  Your application software should configure the CoreI2C driver through\r
+  calls to the I2C_init() function for each CoreI2C instance in the\r
+  hardware design.  The configuration parameters include the CoreI2C hardware\r
+  instance base address and other runtime parameters, such as the I2C serial\r
+  clock frequency and I2C device address.\r
+  \r
+  Once channel 0 of a CoreI2C peripheral has been initialized via I2C_init(),\r
+  any additional channels present should be configured by calling\r
+  I2C_channel_init() for each of the remaining channels.\r
+  \r
+  No CoreI2C hardware configuration parameters are used by the driver, apart\r
+  from the CoreI2C hardware instance base address. Hence, no additional\r
+  configuration files are required to use the driver. \r
+  \r
+  Interrupt Control\r
+  The CoreI2C driver has to enable and disable the generation of interrupts by\r
+  CoreI2C at various times when it is operating. This enabling and disabling of\r
+  interrupts must be done through the system\92s interrupt controller. For that\r
+  reason, the method of controlling the CoreI2C interrupt is system specific\r
+  and it is necessary to customize the I2C_enable_irq() and I2C_disable_irq()\r
+  functions. These functions are found in the file i2c_interrupt.c. Their\r
+  default implementation fires an assertion to attract attention to the fact\r
+  that these functions must be modified.\r
+  \r
+  The implementation of the I2C_enable_irq() function should permit interrupts\r
+  generated by a CoreI2C instance to interrupt the processor. The implementation\r
+  of the I2C_disable_irq() function should prevent interrupts generated by a\r
+  CoreI2C instance from interrupting the processor. Please refer to the provided\r
+  example projects for a working implementation of these functions.\r
+  \r
+  The function I2C_register_write_handler() is used to register a write handler\r
+  function with the CoreI2C driver that it calls on completion of an I2C write\r
+  transaction by the CoreI2C slave. It is your responsibility to create and\r
+  register the implementation of this handler function that processes or\r
+  trigger the processing of the received data.\r
+  \r
+  The SMBSUS and SMBALERT interrupts are related to the SMBus interface and are\r
+  enabled and disabled through I2C_enable_smbus_irq() and \r
+  I2C_disable_smbus_irq() respectively. It is your responsibility to create\r
+  interrupt handler functions in your application to get the desired response\r
+  for the SMBus interrupts.\r
+\r
+  Note: You must include the path to any application header files that are\r
+        included in the i2c_interrupt.c file, as an include path in your\r
+        project\92s compiler settings. The details of how to do this will depend\r
+        on your development software.\r
+\r
+  SMBus Logic options\r
+  SMBus related APIs will not have any effect if in CoreI2C hardware\r
+  configuration "Generate SMBus Logic" is not enabled. The APIs which will not\r
+  give desired results in case SMBus Logic is disabled are:\r
+  \r
+      I2C_smbus_init()\r
+      I2C_reset_smbus()\r
+      I2C_enable_smbus_irq()\r
+      I2C_disable_smbus_irq()\r
+      I2C_suspend_smbus_slave()\r
+      I2C_resume_smbus_slave()\r
+      I2C_set_smsbus_alert()\r
+      I2C_clear_smsbus_alert()\r
+      I2C_get_irq_status() \r
+\r
+  Fixed Baud Rate Values\r
+  The serial clock frequency parameter passed to the I2C_init() and \r
+  I2C_channel_init() functions may not have any effect if fixed values were\r
+  selected for Baud rate in the hardware configuration of CoreI2C. When fixed\r
+  values are selected for these baud rates, the driver cannot overwrite\r
+  the fixed values.\r
+\r
+  Fixed Slave Address Options Values\r
+  The primary slave address  parameter passed to the I2C_init() function, and\r
+  secondary address value passed to the I2C_set_slave_second_addr() function,\r
+  may not have the desired effect if fixed values were selected for the slave 0\r
+  address and slave 1 address respectively. Proper operation of this version of\r
+  the driver requires the slave addresses to be programmable.\r
+\r
+  @section theory_op Theory of Operation\r
+  The CoreI2C software driver is designed to allow the control of multiple\r
+  instances of CoreI2C with one or more I2C channels. Each channel in an\r
+  instance of CoreI2C in the hardware design is associated with a single \r
+  instance of the i2c_instance_t structure in the software. You must allocate\r
+  memory for one unique i2c_instance_t structure instance for each channel of\r
+  each CoreI2C hardware instance. The contents of these data structures are\r
+  initialised during calls to I2C_init() and if necessary I2C_channel_init().\r
+  A pointer to the structure is passed to subsequent driver functions in order\r
+  to identify the CoreI2C hardware instance and channel you wish to perform the\r
+  requested operation.\r
+\r
+  Note: Do not attempt to directly manipulate the contents of i2c_instance_t\r
+       structures. These structures are only intended to be modified by the driver\r
+       functions.\r
+\r
+  The CoreI2C driver functions are grouped into the following categories:\r
+    - Initialization and configuration functions\r
+    - Interrupt control\r
+    - I2C slave addressing functions\r
+    - I2C master operations functions to handle write, read and write-read \r
+      transactions\r
+    - I2C slave operations functions to handle write, read and write-read \r
+      transactions\r
+    - Mixed master-slave operations \r
+    - SMBus interface configuration and control.\r
+    \r
+  Initialization and Configuration\r
+    The CoreI2C device is first initialized through a call to the I2C_init()\r
+    function. Since each CoreI2C peripheral supports up to 16 channels, an\r
+    additional function, I2C_channel_init(), is required to initialize the\r
+    remaining channels with their own data structures.\r
+\r
+    I2C_init() initializes channel 0 of a CoreI2C and the i2c_instance_t for\r
+    channel 0 acts as the basis for further channel initialization as the\r
+    hardware base address and I2C serial address are same across all the\r
+    channels. I2C_init() must be called before any other  I2C driver function\r
+    calls. The I2C_init() call for each CoreI2C takes the I2C serial address\r
+    assigned to the I2C and the serial clock divider to be used to generate its\r
+    I2C clock as configuration parameters. \r
+    \r
+    I2C_channel_init() takes as input parameters a pointer to the CoreI2C \r
+    i2c_instance_t which has been initialized via I2C_init() and a pointer to a\r
+    separate i2c_instance_t which represents this new channel. Another input\r
+    parameter which is required by this function is serial clock divider which\r
+    generates its I2C clock. \r
+    \r
+  Interrupt Control\r
+    The CoreI2C driver is interrupt driven and it uses each channels INT\r
+    interrupt to drive the state machine which is at the heart of the driver.\r
+    The application is responsible for providing the link between the interrupt\r
+    generating hardware and the CoreI2C interrupt handler and must ensure that\r
+    the I2C_isr() function is called with the correct i2c_instance_t structure\r
+    pointer for the CoreI2C channel initiating the interrupt.\r
+    \r
+    The driver enables and disables the generation of INT interrupts by CoreI2C\r
+    at various times when it is operating through the user supplied\r
+    I2C_enable_irq() and I2C_disable_irq() functions. \r
+    \r
+    The function I2C_register_write_handler() is used to register a write\r
+    handler function with the CoreI2C driver which is called on completion\r
+    of an I2C write transaction by the CoreI2C slave. It is the user\r
+    applications responsibility to create and register the implementation of\r
+    this handler function that processes or triggers the processing of the\r
+    received data. \r
+    \r
+    The other two interrupt sources in the CoreI2C, are related to SMBus\r
+    operation and are enabled and disabled through I2C_enable_smbus_irq() and\r
+    I2C_disable_smbus_irq() respectively. Due to the application specific\r
+    nature of the response to SMBus interrupts, you must design interrupt\r
+    handler functions in the application to get the desired behaviour for\r
+    SMBus related interrupts.\r
+    \r
+    If enabled, the SMBA_INT signal from the CoreI2C is asserted if an\r
+    SMBALERT condition is signalled on the SMBALERT_NI input for the channel.\r
+    \r
+    If enabled, the SMBS_INT signal from the CoreI2C is asserted if an\r
+    SMBSUSPEND condition is signalled on the SMBSUS_NI input for the channel.\r
+\r
+  I2C slave addressing functions\r
+    A CoreI2C peripheral can respond to three slave addresses:\r
+    - Slave address 0 - This is the primary slave address which is used for\r
+                        accessing a CoreI2C channel when it acts as a slave in\r
+                        I2C transactions. You must configure the primary slave\r
+                        address via I2C_init().\r
+                        \r
+    - Slave address 1 - This is the secondary slave address which might be\r
+                        required in certain application specific scenarios.\r
+                        The secondary slave address can be configured via\r
+                        I2C_set_slave_second_addr() and disabled via \r
+                        I2C_disable_slave_second_addr().\r
+                        \r
+    - General call address - A CoreI2C slave can be configured to respond to\r
+                        a broadcast command by a master transmitting the\r
+                        general call address of 0x00. Use the I2C_set_gca()\r
+                        function to enable the slave to respond to the general\r
+                        call address. If the CoreI2C slave is not required to\r
+                        respond to the general call address, disable this\r
+                        address by calling I2C_clear_gca().\r
+\r
+    Note: All channels on a CoreI2C instance share the same slave address logic.\r
+          This means that they cannot have separate slave addresses and rely on\r
+          the separate physical I2C bus connections to distinguish them.\r
+          \r
+  Transaction Types\r
+    The I2C driver is designed to handle three types of I2C transaction:\r
+      Write transactions\r
+      Read transactions\r
+      Write-read transactions\r
\r
+    Write transaction\r
+      The master I2C device initiates a write transaction by sending a START bit\r
+      as soon as the bus becomes free. The START bit is followed by the 7-bit\r
+      serial address of the target slave device followed by the read/write bit\r
+      indicating the direction of the transaction. The slave acknowledges the\r
+      receipt of it's address with an acknowledge bit. The master sends data one\r
+      byte at a time to the slave, which must acknowledge receipt of each byte\r
+      for the next byte to be sent. The master sends a STOP bit to complete the\r
+      transaction. The slave can abort the transaction by replying with a \r
+      non-acknowledge bit instead of an acknowledge.\r
+      \r
+      The application programmer can choose not to send a STOP bit at the end of\r
+      the transaction causing the next transaction to begin with a repeated \r
+      START bit.\r
+      \r
+    Read transaction\r
+      The master I2C device initiates a read transaction by sending a START bit\r
+      as soon as the bus becomes free. The START bit is followed by the 7-bit\r
+      serial address of the target slave device followed by the read/write bit\r
+      indicating the direction of the transaction. The slave acknowledges\r
+      receipt of it's slave address with an acknowledge bit. The slave sends\r
+      data one byte at a time to the master, which must acknowledge receipt of\r
+      each byte for the next byte to be sent. The master sends a non-acknowledge\r
+      bit following the last byte it wishes to read followed by a STOP bit.\r
+      \r
+      The application programmer can choose not to send a STOP bit at the end of\r
+      the transaction causing the next transaction to begin with a repeated \r
+      START bit.\r
\r
+    Write-read transaction\r
+      The write-read transaction is a combination of a write transaction\r
+      immediately followed by a read transaction. There is no STOP bit between\r
+      the write and read phases of a write-read transaction. A repeated START\r
+      bit is sent between the write and read phases.\r
+      \r
+      Whilst the write handler is being executed, the slave holds the clock line\r
+      low to stretch the clock until the response is ready.\r
+      \r
+      The write-read transaction is typically used to send a command or offset\r
+      in the write transaction specifying the logical data to be transferred\r
+      during the read phase.\r
+      \r
+      The application programmer can choose not to send a STOP bit at the end of\r
+      the transaction causing the next transaction to begin with a repeated\r
+      START bit.\r
+\r
+  Master Operations\r
+    The application can use the I2C_write(), I2C_read() and I2C_write_read()\r
+    functions to initiate an I2C bus transaction. The application can then wait\r
+    for the transaction to complete using the I2C_wait_complete() function\r
+    or poll the status of the I2C transaction using the I2C_get_status()\r
+    function until it returns a value different from I2C_IN_PROGRESS. The\r
+    I2C_system_tick() function can be used to set a time base for the\r
+    I2C_wait_complete() function\92s time out delay.\r
+\r
+  Slave Operations\r
+    The configuration of the  I2C driver to operate as an I2C slave requires\r
+    the use of the following functions:\r
+       I2C_set_slave_tx_buffer()\r
+       I2C_set_slave_rx_buffer()\r
+       I2C_set_slave_mem_offset_length()\r
+       I2C_register_write_handler()\r
+       I2C_enable_slave()\r
+       \r
+    Use of all functions is not required if the slave I2C does not need to support\r
+    all types of I2C read transactions. The subsequent sections list the functions\r
+    that must be used to support each transaction type. \r
+    \r
+    Responding to read transactions\r
+      The following functions are used to configure the  CoreI2C driver to\r
+      respond to I2C read transactions:\r
+        I2C_set_slave_tx_buffer()\r
+        I2C_enable_slave()\r
+        \r
+      The function I2C_set_slave_tx_buffer() specifies the data buffer that\r
+      will be transmitted when the I2C slave is the target of an I2C read\r
+      transaction. It is then up to the application to manage the content of\r
+      that buffer to control the data that will be transmitted to the I2C\r
+      master as a result of the read transaction.\r
+      \r
+      The function I2C_enable_slave() enables the  I2C hardware instance\r
+      to respond to I2C transactions. It must be called after the  I2C driver\r
+      has been configured to respond to the required transaction types.\r
+\r
+    Responding to write transactions\r
+      The following functions are used to configure the  I2C driver to respond\r
+      to I2C write transactions:\r
+        I2C_set_slave_rx_buffer()\r
+        I2C_register_write_handler()\r
+        I2C_enable_slave()\r
+        \r
+      The function I2C_set_slave_rx_buffer() specifies the data buffer that\r
+      will be used to store the data received by the I2C slave when it is the\r
+      target an I2C  write transaction.\r
+      \r
+      The function I2C_register_write_handler() specifies the handler function\r
+      that must be called on completion of the I2C write transaction. It is this\r
+      handler function that processes or triggers the processing of the received\r
+      data.\r
+      \r
+      The function I2C_enable_slave() enables the  I2C hardware instance\r
+      to respond to I2C transactions. It must be called after the  I2C driver\r
+      has been configured to respond to the required transaction types.\r
+\r
+    Responding to write-read transactions\r
+      The following functions are used to configure the CoreI2C driver to \r
+      respond to write-read transactions:\r
+        I2C_set_slave_mem_offset_length()\r
+        I2C_set_slave_tx_buffer()\r
+        I2C_set_slave_rx_buffer()\r
+        I2C_register_write_handler()\r
+        I2C_enable_slave()\r
+        \r
+      The function I2C_set_slave_mem_offset_length() specifies the number of\r
+      bytes expected by the I2C slave during the write phase of the write-read\r
+      transaction.\r
+      \r
+      The function I2C_set_slave_tx_buffer() specifies the data that will be\r
+      transmitted to the I2C master during the read phase of the write-read\r
+      transaction. The value received by the I2C slave during the write phase of\r
+      the transaction will be used as an index into the transmit buffer\r
+      specified by this function to decide which part of the transmit buffer\r
+      will be transmitted to the I2C master as part of the read phase of the\r
+      write-read transaction. \r
+      \r
+      The function I2C_set_slave_rx_buffer() specifies the data buffer that\r
+      will be used to store the data received by the I2C slave during the write\r
+      phase of the write-read transaction. This buffer must be at least large\r
+      enough to accommodate the number of bytes specified through the\r
+      I2C_set_slave_mem_offset_length() function.\r
+      \r
+      The function I2C_register_write_handler() can optionally be used to\r
+      specify a handler function that is called on completion of the write phase\r
+      of the I2C write-read transaction. If a handler function is registered, it\r
+      is responsible for processing the received data in the slave receive\r
+      buffer and populating the slave transmit buffer with the data that will be\r
+      transmitted to the I2C master as part of the read phase of the write-read\r
+      transaction.\r
+      \r
+      The function I2C_enable_slave() enables the CoreI2C hardware instance to \r
+      respond to I2C transactions. It must be called after the CoreI2C driver\r
+      has been configured to respond to the required transaction types.\r
+\r
+  Mixed Master-Slave Operations\r
+    The CoreI2C device supports mixed master and slave operations. If the \r
+    CoreI2C slave has a transaction in progress and your application attempts to\r
+    begin a master mode transaction, the CoreI2C driver queu3es the master mode\r
+    transaction until the bus is released and the CoreI2C can switch to master\r
+    mode and acquire the bus. The CoreI2C master then starts the previously\r
+    queued master transaction.\r
+    \r
+  SMBus Control\r
+    The CoreI2C driver enables the CoreI2C peripheral\92s SMBus functionality\r
+    using the I2C_smbus_init() function.\r
+    \r
+    The I2C_suspend_smbus_slave() function is used, with a master mode CoreI2C,\r
+    to force slave devices on the SMBus to enter their power-down/suspend mode.\r
+    The I2C_resume_smbus_slave() function is used to end the suspend operation\r
+    on the SMBus.\r
+    \r
+    The I2C_reset_smbus() function is used, with a master mode CoreI2C, to force\r
+    all devices on the SMBus to reset their SMBUs interface.\r
+    \r
+    The I2C_set_smsbus_alert() function is used, by a slave mode CoreI2C, to\r
+    force communication with the SMBus master. Once communications with the\r
+    master is initiated, the I2C_clear_smsbus_alert() function is used to clear\r
+    the alert condition.\r
+    \r
+    The I2C_enable_smbus_irq() and I2C_disable_smbus_irq() functions are used to\r
+    enable and disable the SMBSUS and SMBALERT SMBus interrupts.\r
+\r
+ *//*=========================================================================*/\r
+\r
+#ifndef CORE_I2C_H_\r
+#define CORE_I2C_H_\r
+\r
+#include "cpu_types.h"\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif \r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  The I2C_RELEASE_BUS constant is used to specify the options parameter to\r
+  functions I2C_read(), I2C_write() and I2C_write_read() to indicate\r
+  that a STOP bit must be generated at the end of the I2C transaction to release\r
+  the bus.\r
+ */\r
+#define I2C_RELEASE_BUS     0x00u\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  The I2C_HOLD_BUS constant is used to specify the options parameter to\r
+  functions I2C_read(), I2C_write() and I2C_write_read() to indicate\r
+  that a STOP bit must not be generated at the end of the I2C transaction in\r
+  order to retain the bus ownership. This causes the next transaction to\r
+  begin with a repeated START bit and no STOP bit between the transactions.\r
+ */\r
+#define I2C_HOLD_BUS        0x01u\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  The following constants specify the interrupt identifier number which will be\r
+  solely used by driver API. This has nothing to do with hardware interrupt line.\r
+  I2C_INT_IRQ is the primary interrupt signal which drives the state machine\r
+  of the CoreI2C driver. The I2C_SMBALERT_IRQ and I2C_SMBUS_IRQ are used by\r
+  SMBus interrupt enable and disable functions. These IRQ numbers are also used\r
+  by I2C_get_irq_status().\r
+ */\r
+#define I2C_NO_IRQ             0x00u\r
+#define I2C_SMBALERT_IRQ       0x01u\r
+#define I2C_SMBSUS_IRQ         0x02u\r
+#define I2C_INTR_IRQ           0x04u\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  The I2C_NO_TIMEOUT constant is used as parameter to the I2C_wait_complete()\r
+  function to indicate that the wait for completion of the transaction should\r
+  not time out.\r
+ */\r
+#define I2C_NO_TIMEOUT  0u\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  The i2c_channel_number_t type is used to specify the channel number of a\r
+  CoreI2C instance.\r
+ */\r
+typedef enum i2c_channel_number {\r
+    I2C_CHANNEL_0 = 0u,\r
+    I2C_CHANNEL_1,\r
+    I2C_CHANNEL_2,\r
+    I2C_CHANNEL_3,\r
+    I2C_CHANNEL_4,\r
+    I2C_CHANNEL_5,\r
+    I2C_CHANNEL_6,\r
+    I2C_CHANNEL_7,\r
+    I2C_CHANNEL_8,\r
+    I2C_CHANNEL_9,\r
+    I2C_CHANNEL_10,\r
+    I2C_CHANNEL_11,\r
+    I2C_CHANNEL_12,\r
+    I2C_CHANNEL_13,\r
+    I2C_CHANNEL_14,\r
+    I2C_CHANNEL_15,\r
+    I2C_MAX_CHANNELS = 16u\r
+} i2c_channel_number_t;\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  The i2c_clock_divider_t type is used to specify the divider to be applied\r
+  to the I2C PCLK or BCLK signal in order to generate the I2C clock.\r
+  The I2C_BCLK_DIV_8 value selects a clock frequency based on division of BCLK,\r
+  all other values select a clock frequency based on division of PCLK.\r
+ */\r
+typedef enum i2c_clock_divider {\r
+    I2C_PCLK_DIV_256 = 0u,\r
+    I2C_PCLK_DIV_224,\r
+    I2C_PCLK_DIV_192,\r
+    I2C_PCLK_DIV_160,\r
+    I2C_PCLK_DIV_960,\r
+    I2C_PCLK_DIV_120,\r
+    I2C_PCLK_DIV_60,\r
+    I2C_BCLK_DIV_8\r
+} i2c_clock_divider_t;\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  The i2c_status_t type is used to report the status of I2C transactions.\r
+ */\r
+typedef enum i2c_status\r
+{\r
+    I2C_SUCCESS = 0u,\r
+    I2C_IN_PROGRESS,\r
+    I2C_FAILED,\r
+    I2C_TIMED_OUT\r
+} i2c_status_t;\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  The i2c_slave_handler_ret_t type is used by slave write handler functions\r
+  to indicate whether or not the received data buffer should be released.\r
+ */\r
+typedef enum i2c_slave_handler_ret {\r
+    I2C_REENABLE_SLAVE_RX = 0u,\r
+    I2C_PAUSE_SLAVE_RX = 1u\r
+} i2c_slave_handler_ret_t;\r
+\r
+typedef struct i2c_instance i2c_instance_t ;\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  Slave write handler functions prototype.\r
+  ------------------------------------------------------------------------------\r
+  This defines the function prototype that must be followed by  I2C slave write\r
+  handler functions. These functions are registered with the CoreI2C driver\r
+  through the I2C_register_write_handler() function.\r
+\r
+  Declaring and Implementing Slave Write Handler Functions:\r
+    Slave write handler functions should follow the following prototype:\r
+    i2c_slave_handler_ret_t write_handler\r
+    ( \r
+        i2c_instance_t *instance, uint8_t * data, uint16_t size \r
+    );\r
+\r
+    The instance parameter is a pointer to the i2c_instance_t for which this\r
+    slave write handler has been declared.\r
+    \r
+    The data parameter is a pointer to a buffer (received data buffer) holding\r
+    the data written to the I2C slave.\r
+    \r
+    Defining the macro INCLUDE_SLA_IN_RX_PAYLOAD causes the driver to insert the\r
+    actual address used to access the slave as the first byte in the buffer.\r
+    This allows applications tailor their response based on the actual address\r
+    used to access the slave (primary address, secondary address or GCA).\r
+    \r
+    The size parameter is the number of bytes held in the received data buffer.\r
+    Handler functions must return one of the following values:\r
+        I2C_REENABLE_SLAVE_RX\r
+        I2C_PAUSE_SLAVE_RX.\r
+        \r
+    If the handler function returns I2C_REENABLE_SLAVE_RX, the driver releases\r
+    the received data buffer and allows further I2C write transactions to the\r
+    I2C slave to take place.\r
+    \r
+    If the handler function returns I2C_PAUSE_SLAVE_RX, the I2C slave responds\r
+    to subsequent write requests with a non-acknowledge bit (NACK), until the\r
+    received data buffer content has been processed by some other part of the\r
+    software application.\r
+    \r
+    A call to I2C_enable_slave() is required at some point after returning\r
+    I2C_PAUSE_SLAVE_RX in order to release the received data buffer so it can\r
+    be used to store data received by subsequent I2C write transactions.\r
+ */\r
+typedef i2c_slave_handler_ret_t (*i2c_slave_wr_handler_t)(i2c_instance_t *instance, uint8_t *, uint16_t );\r
+\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  i2c_instance_t\r
+  ------------------------------------------------------------------------------\r
+  This structure is used to identify the various CoreI2C hardware instances in\r
+  your system and the I2C channels within them. Your application software should\r
+  declare one instance of this structure for each channel of each instance of\r
+  CoreI2C in your system. The functions I2C_init() and I2C_channel_init() \r
+  initialize this structure depending on whether it is channel 0 or one of the\r
+  additional channels respectively. A pointer to an initialized instance of the\r
+  structure should be passed as the first parameter to the CoreI2C driver\r
+  functions, to identify which CoreI2C hardware instance and channel should\r
+  perform the requested operation.\r
+  \r
+  The contents of this data structure should not be modified or used outside of\r
+  the CoreI2C driver. Software using the CoreI2C driver should only need to \r
+  create one single instance of this data structure for each channel of each \r
+  CoreI2C hardware instance in the system then pass a pointer to these data\r
+  structures with each call to the CoreI2C driver in order to identify the\r
+  CoreI2C hardware instance it wishes to use.\r
+ */\r
+struct i2c_instance\r
+{\r
+    addr_t base_address;\r
+    uint_fast8_t ser_address;\r
+\r
+    /* Transmit related info:*/\r
+    uint_fast8_t target_addr;\r
+\r
+    /* Current transaction type (WRITE, READ, RANDOM_READ)*/\r
+    uint8_t transaction;\r
+    \r
+    uint_fast16_t random_read_addr;\r
+\r
+    uint8_t options;\r
+    \r
+    /* Master TX INFO: */\r
+    const uint8_t * master_tx_buffer;\r
+    uint_fast16_t master_tx_size;\r
+    uint_fast16_t master_tx_idx;\r
+    uint_fast8_t dir;\r
+    \r
+    /* Master RX INFO: */\r
+    uint8_t * master_rx_buffer;\r
+    uint_fast16_t master_rx_size;\r
+    uint_fast16_t master_rx_idx;\r
+\r
+    /* Master Status */\r
+    volatile i2c_status_t master_status;\r
+    uint32_t master_timeout_ms;\r
+\r
+    /* Slave TX INFO */\r
+    const uint8_t * slave_tx_buffer;\r
+    uint_fast16_t slave_tx_size;\r
+    uint_fast16_t slave_tx_idx;\r
+    \r
+    /* Slave RX INFO */\r
+    uint8_t * slave_rx_buffer;\r
+    uint_fast16_t slave_rx_size;\r
+    uint_fast16_t slave_rx_idx;\r
+    /* Slave Status */\r
+    volatile i2c_status_t slave_status;\r
+    \r
+    /* Slave data: */\r
+    uint_fast8_t slave_mem_offset_length;\r
+    i2c_slave_wr_handler_t slave_write_handler;\r
+    uint8_t is_slave_enabled;\r
+    \r
+    /* user  specific data */\r
+    void *p_user_data ;\r
+\r
+    /* I2C bus status */\r
+    uint8_t bus_status;\r
+\r
+    /* Is transaction pending flag */\r
+    uint8_t is_transaction_pending;\r
+\r
+    /* I2C Pending transaction */\r
+    uint8_t pending_transaction;\r
+};\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  I2C initialization routine.\r
+  ------------------------------------------------------------------------------\r
+  The I2C_init() function is used to configure channel 0 of a CoreI2C instance.\r
+  It sets the base hardware address which is used to locate the CoreI2C instance\r
+  in memory and also used internally by I2C_channel_init() to calculate the\r
+  register addresses for any additional channels. The slave serial address set\r
+  is shared by all channels on a CoreI2C instance. \r
+  \r
+  If only one channel is configured in a CoreI2C, the address of the \r
+  i2c_instance_t used in I2C_Init() will also be used in subsequent calls to the\r
+  CoreI2C driver functions. If more than one channel is configured in the\r
+  CoreI2C, I2C_channel_init() will be called after I2C_init(), which initializes\r
+  the i2c_instance_t data structure for a specific channel.\r
+  ------------------------------------------------------------------------------\r
+ @param this_i2c:\r
+    Pointer to the i2c_instance_t data structure which will hold all data\r
+    related to channel 0 of the CoreI2C instance being initialized. A pointer\r
+    to this structure will be used in all subsequent calls to CoreI2C driver\r
+    functions which are to operate on channel 0 of this CoreI2C instance.\r
+  \r
+  @param base_address:\r
+    Base address in the processor's memory map of the registers of the CoreI2C\r
+    instance being initialized.\r
\r
+  @param ser_address:\r
+    This parameter sets the primary I2C serial address (SLAVE0 address) for the\r
+    CoreI2C being initialized. It is the principal I2C bus address to which the\r
+    CoreI2C instance will respond. CoreI2C can operate in master mode or slave\r
+    mode and the serial address is significant only in the case of I2C slave\r
+    mode. In master mode, CoreI2C does not require a serial address and the\r
+    value of this parameter is not important. If you do not intend to use the\r
+    CoreI2C device in slave mode, then any dummy slave address value can be\r
+    provided to this parameter. However, in systems where the CoreI2C may be\r
+    expected to switch from master mode to slave mode, it is advisable to\r
+    initialize the CoreI2C device with a valid serial slave address.\r
+    \r
+    You need to call the I2C_init() function whenever it is required to change \r
+    the primary slave address as there is no separate function to set the\r
+    primary slave address of the I2C device. The serial address being\r
+    initialized through this function is basically the primary slave address or\r
+    slave address0. I2C_set_slave_second_addr() can be used to set the\r
+    secondary slave address or slave address 1.\r
+    Note : ser_address parameter does not have any affect if fixed slave \r
+           address is enabled in CoreI2C hardware design. CoreI2C will \r
+           be always addressed with the hardware configured fixed slave\r
+           address.\r
+    Note : ser_address parameter will not have any affect if the CoreI2C\r
+           instance is only used in master mode.\r
+\r
+  @param ser_clock_speed:\r
+    This parameter sets the I2C serial clock frequency. It selects the divider\r
+    that will be used to generate the serial clock from the APB PCLK or from\r
+    the BCLK. It can be one of the following:\r
+        I2C_PCLK_DIV_256\r
+        I2C_PCLK_DIV_224\r
+        I2C_PCLK_DIV_192\r
+        I2C_PCLK_DIV_160\r
+        I2C_PCLK_DIV_960\r
+        I2C_PCLK_DIV_120\r
+        I2C_PCLK_DIV_60\r
+        I2C_BCLK_DIV_8\r
+    Note: serial_clock_speed value will have no affect if Fixed baud rate is \r
+          enabled in CoreI2C hardware instance configuration dialogue window. \r
+          The fixed baud rate divider value will override the value\r
+          passed as parameter in this function.\r
+    Note: serial_clock_speed value is not critical for devices that only operate\r
+          as slaves and can be set to any of the above values.  \r
+\r
+  @return none.  \r
+  \r
+  Example:\r
+  @code\r
+    #define COREI2C_BASE_ADDR  0xC0000000u\r
+    #define COREI2C_SER_ADDR   0x10u\r
+\r
+    i2c_instance_t g_i2c_inst;\r
+\r
+    void system_init( void )\r
+    {\r
+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, COREI2C_SER_ADDR,\r
+                  I2C_PCLK_DIV_256 );\r
+    }\r
+  @endcode\r
+ */\r
+void I2C_init\r
+(\r
+    i2c_instance_t * this_i2c,\r
+    addr_t base_address,\r
+    uint8_t ser_address,\r
+    i2c_clock_divider_t ser_clock_speed\r
+);\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  I2C channel initialization routine.\r
+  ------------------------------------------------------------------------------\r
+  The I2C_channel_init() function initializes and configures hardware and data\r
+  structures of one of the additional channels of a CoreI2C instance.\r
+  I2C_init() must be called before calling this function to set the CoreI2C\r
+  instance hardware base address and I2C serial address. I2C_channel_init() also\r
+  initializes I2C serial clock divider to set the serial clock baud rate.  \r
+  The pointer to data structure i2c_instance_t used for a particular channel\r
+  will be used as an input parameter to subsequent CoreI2C driver functions\r
+  which operate on this channel.\r
+  ------------------------------------------------------------------------------\r
+  @param this_i2c_channel\r
+    Pointer to the i2c_instance_t data structure holding all data related to the\r
+    CoreI2C channel being initialized. A pointer to the same data structure will\r
+    be used in subsequent calls to the CoreI2C driver functions in order to\r
+    identify the CoreI2C channel instance that should perform the operation \r
+    implemented by the called driver function.\r
+\r
+  @param this_i2c:\r
+    This is a pointer to an i2c_instance_t structure previously initialized by\r
+    I2C_init(). It holds information regarding the hardware base address and\r
+    I2C serial address for the CoreI2C containing the channel to be\r
+    initialized. This information is required by I2C_channel_init() to\r
+    initialize the i2c_instance_t structure pointed to by this_i2c_channel as\r
+    all channels in a CoreI2C instance share the same base address and serial\r
+    address. It is very important that the i2c_instance_t structure pointed to\r
+    by this_i2c has been previously initialized with a call to I2C_init().\r
+    \r
+  @param channel_number:\r
+    This parameter of type i2c_channel_number_t identifies the channel to be\r
+    initialized.\r
+\r
+  @param ser_clock_speed:\r
+    This parameter sets the I2C serial clock frequency. It selects the divider\r
+    that will be used to generate the serial clock from the APB PCLK or from\r
+    the BCLK. It can be one of the following:\r
+        I2C_PCLK_DIV_256\r
+        I2C_PCLK_DIV_224\r
+        I2C_PCLK_DIV_192\r
+        I2C_PCLK_DIV_160\r
+        I2C_PCLK_DIV_960\r
+        I2C_PCLK_DIV_120\r
+        I2C_PCLK_DIV_60\r
+        I2C_BCLK_DIV_8\r
+    \r
+    Note: serial_clock_speed value will have no affect if Fixed baud rate is \r
+          enabled in CoreI2C hardware instance configuration dialogue window. \r
+          The fixed baud rate divider value will supersede the value \r
+          passed as parameter in this function.\r
+\r
+    Note: ser_clock_speed value is not critical for devices that only operate\r
+          as slaves and can be set to any of the above values.  \r
+  @return none.  \r
+  \r
+  Example:\r
+  @code\r
+    #define COREI2C_BASE_ADDR  0xC0000000u\r
+    #define COREI2C_SER_ADDR   0x10u\r
+    #define DATA_LENGTH        16u\r
+\r
+    i2c_instance_t g_i2c_inst;\r
+    i2c_instance_t g_i2c_channel_1_inst;\r
+\r
+    uint8_t  tx_buffer[DATA_LENGTH];\r
+    uint8_t  write_length = DATA_LENGTH;\r
+\r
+    void system_init( void )\r
+    {\r
+        uint8_t  target_slave_addr = 0x12;\r
+        \r
+        // Initialize base CoreI2C instance\r
+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, COREI2C_SER_ADDR,\r
+                  I2C_PCLK_DIV_256 );\r
+        \r
+        // Initialize CoreI2C channel 1 with different clock speed\r
+        I2C_channel_init( &g_i2c_channel_1_inst, &g_i2c_inst, I2C_CHANNEL_1,\r
+                          I2C_PCLK_DIV_224 );\r
+        \r
+        // Write data to Channel 1 of CoreI2C instance.\r
+        I2C_write( &g_i2c_channel_1_inst, target_slave_addr, tx_buffer,\r
+                   write_length, I2C_RELEASE_BUS );\r
+    }\r
+  @endcode\r
+          \r
+*/\r
+void I2C_channel_init\r
+(\r
+    i2c_instance_t * this_i2c_channel,\r
+    i2c_instance_t * this_i2c,\r
+    i2c_channel_number_t channel_number,\r
+    i2c_clock_divider_t ser_clock_speed\r
+);\r
+\r
+/*------------------------------------------------------------------------------\r
+  CoreI2C interrupt service routine.\r
+  ------------------------------------------------------------------------------\r
+    The function I2C_isr is the CoreI2C interrupt service routine. User must\r
+    call this function from their application level CoreI2C interrupt handler\r
+    function. This function runs the I2C state machine based on previous and \r
+    current status.\r
+  ------------------------------------------------------------------------------\r
+    @param this_i2c:\r
+    The this_i2c parameter is a pointer to the i2c_instance_t data structure\r
+    holding all data related to a specific CoreI2C channel. For example, if only\r
+    one channel is initialized, this data structure holds the information of \r
+    channel 0 of the instantiated CoreI2C hardware.\r
+    \r
+    @return none\r
+    \r
+    Example:\r
+    @code\r
+    \r
+    #define COREI2C_BASE_ADDR  0xC0000000u\r
+    #define COREINTERRUPT_BASE_ADDR  0xCC000000u\r
+    #define COREI2C_SER_ADDR   0x10u\r
+    #define I2C_IRQ_NB           2u\r
+    \r
+    i2c_instance_t g_i2c_inst;\r
+\r
+    void core_i2c_isr( void )\r
+    {\r
+       I2C_isr( &g_i2c_inst );\r
+    }\r
+    \r
+   void main( void )\r
+    {\r
+        CIC_init( COREINTERRUPT_BASE_ADDR );\r
+        NVIC_init();\r
+        CIC_set_irq_handler( I2C_IRQ_NB, core_i2c_isr );\r
+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, COREI2C_SER_ADDR,\r
+                  I2C_PCLK_DIV_256 );\r
+        NVIC_enable_interrupt( NVIC_IRQ_0 );\r
+    }\r
+    @endcode\r
+ */\r
+void I2C_isr\r
+(\r
+    i2c_instance_t * this_i2c\r
+);\r
+\r
+/*******************************************************************************\r
+ *******************************************************************************\r
+ * \r
+ *                           Master specific functions\r
+ * \r
+ * The following functions are only used within an I2C master's implementation.\r
+ */\r
\r
+/*-------------------------------------------------------------------------*//**\r
+  I2C master write function.\r
+  ------------------------------------------------------------------------------\r
+  This function initiates an I2C master write transaction. This function returns\r
+  immediately after initiating the transaction. The content of the write buffer\r
+  passed as parameter should not be modified until the write transaction\r
+  completes. It also means that the memory allocated for the write buffer should\r
+  not be freed or should not go out of scope before the write completes. You can\r
+  check for the write transaction completion using the I2C_status() function.\r
+  ------------------------------------------------------------------------------\r
+  @param this_i2c:\r
+    The this_i2c parameter is a pointer to the i2c_instance_t data structure\r
+    holding all data related to a specific CoreI2C channel. For example, if only\r
+    one channel is initialized, this data structure holds the information of \r
+    channel 0 of the instantiated CoreI2C hardware.\r
+\r
+  @param serial_addr:\r
+    This parameter specifies the serial address of the target I2C device.\r
+  \r
+  @param write_buffer:\r
+    This parameter is a pointer to a buffer holding the data to be written to\r
+    the target I2C device.\r
+    Care must be taken not to release the memory used by this buffer before the\r
+    write transaction completes. For example, it is not appropriate to return\r
+    from a function allocating this buffer as an auto array variable before the\r
+    write transaction completes as this would result in the buffer's memory \r
+    being de-allocated from the stack when the function returns. This memory\r
+    could then be subsequently reused and modified causing unexpected data to \r
+    be written to the target I2C device.\r
+  \r
+  @param write_size:\r
+    Number of bytes held in the write_buffer to be written to the target I2C\r
+    device.\r
\r
+  @param options:\r
+    The options parameter is used to indicate if the I2C bus should be released\r
+    on completion of the write transaction. Using the I2C_RELEASE_BUS\r
+    constant for the options parameter causes a STOP bit to be generated at the\r
+    end of the write transaction causing the bus to be released for other I2C\r
+    devices to use. Using the I2C_HOLD_BUS constant as options parameter\r
+    prevents a STOP bit from being generated at the end of the write\r
+    transaction, preventing other I2C devices from initiating a bus transaction.\r
+  \r
+  @return none.  \r
+  \r
+  Example:\r
+  @code\r
+    #define COREI2C_BASE_ADDR  0xC0000000u\r
+    #define COREI2C_DUMMY_ADDR   0x10u\r
+    #define DATA_LENGTH           16u\r
+\r
+    i2c_instance_t g_i2c_inst;\r
+\r
+    uint8_t  tx_buffer[DATA_LENGTH];\r
+    uint8_t  write_length = DATA_LENGTH;     \r
+\r
+    void main( void )\r
+    {\r
+        uint8_t  target_slave_addr = 0x12;\r
+        i2c_status_t status;\r
+        \r
+        // Initialize base CoreI2C instance\r
+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, COREI2C_DUMMY_ADDR,\r
+                  I2C_PCLK_DIV_256 );\r
+        \r
+        // Write data to Channel 0 of CoreI2C instance.\r
+        I2C_write( &g_i2c_inst, target_slave_addr, tx_buffer, write_length,\r
+                   I2C_RELEASE_BUS );\r
+                   \r
+        // Wait for completion and record the outcome\r
+        status = I2C_wait_complete( &g_i2c_inst, I2C_NO_TIMEOUT );\r
+    }\r
+  @endcode\r
+ */\r
+void I2C_write\r
+(\r
+    i2c_instance_t * this_i2c,\r
+    uint8_t serial_addr,\r
+    const uint8_t * write_buffer,\r
+    uint16_t write_size,\r
+    uint8_t options\r
+);\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  I2C master read.\r
+  ------------------------------------------------------------------------------\r
+  This function initiates an I2C master read transaction. This function returns\r
+  immediately after initiating the transaction.\r
+  The contents of the read buffer passed as parameter should not be modified\r
+  until the read transaction completes. It also means that the memory allocated\r
+  for the read buffer should not be freed or should not go out of scope before\r
+  the read completes. You can check for the read transaction completion using \r
+  the I2C_status() function.\r
+  ------------------------------------------------------------------------------\r
+  @param this_i2c:\r
+    The this_i2c parameter is a pointer to the i2c_instance_t data structure\r
+    holding all data related to a specific CoreI2C channel. For example, if only\r
+    one channel is initialized, this data structure holds the information of \r
+    channel 0 of the instantiated CoreI2C hardware.\r
+  \r
+  @param serial_addr:\r
+    This parameter specifies the serial address of the target I2C device.\r
+  \r
+  @param read_buffer\r
+    This is a pointer to a buffer where the data received from the target device\r
+    will be stored.\r
+    Care must be taken not to release the memory used by this buffer before the\r
+    read transaction completes. For example, it is not appropriate to return\r
+    from a function allocating this buffer as an auto array variable before the\r
+    read transaction completes as this would result in the buffer's memory being\r
+    de-allocated from the stack when the function returns. This memory could\r
+    then be subsequently reallocated resulting in the read transaction\r
+    corrupting the newly allocated memory. \r
+\r
+  @param read_size:\r
+    This parameter specifies the number of bytes to read from the target device.\r
+    This size must not exceed the size of the read_buffer buffer.\r
\r
+  @param options:\r
+    The options parameter is used to indicate if the I2C bus should be released\r
+    on completion of the read transaction. Using the I2C_RELEASE_BUS\r
+    constant for the options parameter causes a STOP bit to be generated at the\r
+    end of the read transaction causing the bus to be released for other I2C\r
+    devices to use. Using the I2C_HOLD_BUS constant as options parameter\r
+    prevents a STOP bit from being generated at the end of the read transaction,\r
+    preventing other I2C devices from initiating a bus transaction.\r
+    \r
+  @return none.  \r
+  \r
+  Example:\r
+  @code\r
+    #define COREI2C_BASE_ADDR  0xC0000000u\r
+    #define COREI2C_DUMMY_ADDR   0x10u\r
+    #define DATA_LENGTH           16u\r
+\r
+    i2c_instance_t g_i2c_inst;\r
+\r
+    uint8_t  rx_buffer[DATA_LENGTH];\r
+    uint8_t  read_length = DATA_LENGTH;     \r
+\r
+    void main( void )\r
+    {\r
+        uint8_t  target_slave_addr = 0x12;\r
+        i2c_status_t status;\r
+        \r
+        // Initialize base CoreI2C instance\r
+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, COREI2C_DUMMY_ADDR,\r
+                  I2C_PCLK_DIV_256 );\r
+        \r
+        // Read data from target slave Channel 0 of CoreI2C instance.\r
+        I2C_read( &g_i2c_inst, target_slave_addr, rx_buffer, read_length,\r
+                  I2C_RELEASE_BUS );\r
+        \r
+        status = I2C_wait_complete( &g_i2c_inst, I2C_NO_TIMEOUT );\r
+    }\r
+  @endcode\r
+ */\r
+void I2C_read\r
+(\r
+    i2c_instance_t * this_i2c,\r
+    uint8_t serial_addr,\r
+    uint8_t * read_buffer,\r
+    uint16_t read_size,\r
+    uint8_t options\r
+);\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  I2C master write-read\r
+  ------------------------------------------------------------------------------\r
+  This function initiates an I2C write-read transaction where data is first\r
+  written to the target device before issuing a restart condition and changing\r
+  the direction of the I2C transaction in order to read from the target device.\r
+  \r
+  The same warnings about buffer allocation in I2C_write() and I2C_read() \r
+  apply to this function.\r
+  ------------------------------------------------------------------------------\r
+  @param this_i2c:\r
+    The this_i2c parameter is a pointer to the i2c_instance_t data structure\r
+    holding all data related to a specific CoreI2C channel. For example, if only\r
+    one channel is initialized, this data structure holds the information of\r
+    channel 0 of the instantiated CoreI2C hardware.\r
+  \r
+  @param serial_addr:\r
+    This parameter specifies the serial address of the target I2C device.\r
+  \r
+  @param addr_offset:\r
+    This parameter is a pointer to the buffer containing the data that will be\r
+    sent to the slave during the write phase of the write-read transaction. This\r
+    data is typically used to specify an address offset specifying to the I2C\r
+    slave device what data it must return during the read phase of the\r
+    write-read transaction.\r
+  \r
+  @param offset_size:\r
+    This parameter specifies the number of offset bytes to be written during the\r
+    write phase of the write-read transaction. This is typically the size of the\r
+    buffer pointed to by the addr_offset parameter.\r
+  \r
+  @param read_buffer:\r
+    This parameter is a pointer to the buffer where the data read from the I2C\r
+    slave will be stored.\r
+  \r
+  @param read_size:\r
+    This parameter specifies the number of bytes to read from the target I2C\r
+    slave device. This size must not exceed the size of the buffer pointed to by\r
+    the read_buffer parameter.\r
\r
+  @param options:\r
+    The options parameter is used to indicate if the I2C bus should be released\r
+    on completion of the write-read transaction. Using the I2C_RELEASE_BUS\r
+    constant for the options parameter causes a STOP bit to be generated at the\r
+    end of the write-read transaction causing the bus to be released for other\r
+    I2C devices to use. Using the I2C_HOLD_BUS constant as options parameter\r
+    prevents a STOP bit from being generated at the end of the write-read\r
+    transaction, preventing other I2C devices from initiating a bus transaction.\r
+        \r
+  @return none.  \r
+  \r
+  Example:\r
+  @code\r
+    #define COREI2C_BASE_ADDR    0xC0000000u\r
+    #define COREI2C_DUMMY_ADDR   0x10u\r
+    #define TX_LENGTH            16u\r
+    #define RX_LENGTH            8u\r
+\r
+    i2c_instance_t g_i2c_inst;\r
+    uint8_t  rx_buffer[RX_LENGTH];\r
+    uint8_t  read_length = RX_LENGTH;     \r
+    uint8_t  tx_buffer[TX_LENGTH];\r
+    uint8_t  write_length = TX_LENGTH;  \r
+    \r
+    void main( void )\r
+    {\r
+        uint8_t  target_slave_addr = 0x12;\r
+        i2c_status_t status;\r
+        // Initialize base CoreI2C instance\r
+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, COREI2C_DUMMY_ADDR,\r
+                  I2C_PCLK_DIV_256 );\r
+                  \r
+        I2C_write_read( &g_i2c_inst, target_slave_addr, tx_buffer, write_length,\r
+                        rx_buffer, read_length, I2C_RELEASE_BUS );\r
+                        \r
+        status = I2C_wait_complete( &g_i2c_inst, I2C_NO_TIMEOUT );\r
+    }\r
+  @endcode\r
+ */\r
+void I2C_write_read\r
+(\r
+    i2c_instance_t * this_i2c,\r
+    uint8_t serial_addr,\r
+    const uint8_t * addr_offset,\r
+    uint16_t offset_size,\r
+    uint8_t * read_buffer,\r
+    uint16_t read_size,\r
+    uint8_t options\r
+);\r
+    \r
+/*-------------------------------------------------------------------------*//**\r
+  I2C status\r
+  ------------------------------------------------------------------------------\r
+  This function indicates the current state of a CoreI2C channel.\r
+  ------------------------------------------------------------------------------\r
+  @param this_i2c:\r
+    The this_i2c parameter is a pointer to the i2c_instance_t data structure\r
+    holding all data related to a specific CoreI2C channel. For example, if only\r
+    one channel is initialized, this data structure holds the information of \r
+    channel 0 of the instantiated CoreI2C hardware.\r
+  ------------------------------------------------------------------------------\r
+  @return\r
+    The return value indicates the current state of a CoreI2C channel or the\r
+    outcome of the previous transaction if no transaction is in progress. \r
+    Possible return values are:\r
+      I2C_SUCCESS\r
+        The last I2C transaction has completed successfully.  \r
+      I2C_IN_PROGRESS\r
+        There is an I2C transaction in progress.\r
+      I2C_FAILED\r
+        The last I2C transaction failed.\r
+      I2C_TIMED_OUT\r
+        The request has failed to complete in the allotted time.      \r
+  \r
+  Example:\r
+  @code\r
+    i2c_instance_t g_i2c_inst;\r
+    \r
+    while( I2C_IN_PROGRESS == I2C_get_status( &g_i2c_inst ) )\r
+    {\r
+        // Do something useful while waiting for I2C operation to complete\r
+        our_i2c_busy_task();\r
+    }\r
+    \r
+    if( I2C_SUCCESS != I2C_get_status( &g_i2c_inst ) )\r
+    {\r
+        // Something went wrong... \r
+        our_i2c_error_recovery( &g_i2c_inst );\r
+    }\r
+  @endcode\r
+ */\r
+i2c_status_t I2C_get_status\r
+(\r
+    i2c_instance_t * this_i2c\r
+);\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  Wait for I2C transaction completion.\r
+  ------------------------------------------------------------------------------\r
+  This function waits for the current I2C transaction to complete. The return\r
+  value indicates whether the last I2C transaction was successful or not.\r
+  ------------------------------------------------------------------------------\r
+  @param this_i2c:\r
+    The this_i2c parameter is a pointer to the i2c_instance_t data structure\r
+    holding all data related to a specific CoreI2C channel. For example, if only\r
+    one channel is initialized, this data structure holds the information of\r
+    channel 0 of the instantiated CoreI2C hardware.\r
+  @param timeout_ms:\r
+    The timeout_ms parameter specified the delay within which the current I2C \r
+    transaction is expected to complete. The time out delay is given in \r
+    milliseconds. I2C_wait_complete() will return I2C_TIMED_OUT if the current\r
+    transaction has not completed after the time out delay has expired. This\r
+    parameter can be set to I2C_NO_TIMEOUT to indicate that I2C_wait_complete()\r
+    must not time out.\r
+  ------------------------------------------------------------------------------\r
+  @return\r
+    The return value indicates the outcome of the last I2C transaction. It can\r
+    be one of the following: \r
+      I2C_SUCCESS\r
+        The last I2C transaction has completed successfully.\r
+      I2C_FAILED\r
+        The last I2C transaction failed.\r
+      I2C_TIMED_OUT\r
+        The last transaction failed to complete within the time out delay given\r
+        as second parameter.\r
+\r
+  Example:\r
+  @code\r
+    #define COREI2C_BASE_ADDR  0xC0000000u\r
+    #define COREI2C_DUMMY_ADDR   0x10u\r
+    #define DATA_LENGTH           16u\r
+\r
+    i2c_instance_t g_i2c_inst;\r
+\r
+    uint8_t  rx_buffer[DATA_LENGTH];\r
+    uint8_t  read_length = DATA_LENGTH;     \r
+\r
+    void main( void )\r
+    {\r
+        uint8_t  target_slave_addr = 0x12;\r
+        i2c_status_t status;\r
+        \r
+        // Initialize base CoreI2C instance\r
+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, COREI2C_DUMMY_ADDR,\r
+                  I2C_PCLK_DIV_256 );\r
+        \r
+        // Read data from Channel 0 of CoreI2C instance.\r
+        I2C_read( &g_i2c_inst, target_slave_addr, rx_buffer, read_length,\r
+                  I2C_RELEASE_BUS );\r
+        \r
+        // Wait for completion and record the outcome\r
+        status = I2C_wait_complete( &g_i2c_inst, I2C_NO_TIMEOUT );\r
+    }\r
+  @endcode\r
+ */\r
+i2c_status_t I2C_wait_complete\r
+(\r
+    i2c_instance_t * this_i2c,\r
+    uint32_t timeout_ms\r
+);\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  Time out delay expiration.\r
+  ------------------------------------------------------------------------------\r
+  This function is used to control the expiration of the time out delay\r
+  specified as a parameter to the I2C_wait_complete() function. It must be\r
+  called from the interrupt service routine of a periodic interrupt source such\r
+  as the Cortex-M3 SysTick timer interrupt. It takes the period of the interrupt\r
+  source as its ms_since_last_tick parameter and uses it as the time base for\r
+  the I2C_wait_complete() function\92s time out delay.\r
+  \r
+  Note: This function does not need to be called if the I2C_wait_complete()\r
+        function is called with a timeout_ms value of I2C_NO_TIMEOUT.\r
+  Note: If this function is not called then the I2C_wait_complete() function\r
+        will behave as if its timeout_ms was specified as I2C_NO_TIMEOUT and it\r
+        will not time out.\r
+  Note: If this function is being called from an interrupt handler (e.g SysTick)\r
+        it is important that the calling interrupt have a lower priority than\r
+        the CoreI2C interrupt(s) to ensure any updates to shared data are\r
+        protected.\r
+  \r
+  ------------------------------------------------------------------------------\r
+  @param this_i2c:\r
+    The this_i2c parameter is a pointer to the i2c_instance_t data structure\r
+    holding all data related to a specific CoreI2C channel. For example, if only\r
+    one channel is initialized, this data structure holds the information of \r
+    channel 0 of the instantiated CoreI2C hardware.\r
+  @param ms_since_last_tick:\r
+    The ms_since_last_tick parameter specifies the number of milliseconds that\r
+    elapsed since the last call to I2C_system_tick(). This parameter would\r
+    typically be a constant specifying the interrupt rate of a timer used to\r
+    generate system ticks.\r
+  ------------------------------------------------------------------------------\r
+  @return\r
+    none.\r
+\r
+  Example:\r
+    The example below shows an example of how the I2C_system_tick() function\r
+    would be called in a Cortex-M3 based system. I2C_system_tick() is called for\r
+    each I2C channel from the Cortex-M3 SysTick timer interrupt service routine.\r
+    The SysTick is configured to generate an interrupt every 10 milliseconds in\r
+    the example below.\r
+  @code\r
+    #define SYSTICK_INTERVAL_MS 10\r
+   \r
+    void SysTick_Handler(void)\r
+    {\r
+        I2C_system_tick(&g_core_i2c0, SYSTICK_INTERVAL_MS);\r
+        I2C_system_tick(&g_core_i2c2, SYSTICK_INTERVAL_MS);\r
+    }\r
+  @endcode\r
+ */\r
+void I2C_system_tick\r
+(\r
+    i2c_instance_t * this_i2c,\r
+    uint32_t ms_since_last_tick\r
+);\r
+\r
+/*******************************************************************************\r
+ *******************************************************************************\r
+ * \r
+ *                           Slave specific functions\r
+ * \r
+ * The following functions are only used within the implementation of an I2C\r
+ * slave device.\r
+ */\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  I2C slave transmit buffer configuration.\r
+  ------------------------------------------------------------------------------\r
+  This function specifies the memory buffer holding the data that will be sent\r
+  to the I2C master when this CoreI2C channel is the target of an I2C read or\r
+  write-read transaction.\r
+  ------------------------------------------------------------------------------\r
+  @param this_i2c:\r
+    The this_i2c parameter is a pointer to the i2c_instance_t data structure\r
+    holding all data related to a specific CoreI2C channel. For example, if only\r
+    one channel is initialized, this data structure holds the information of \r
+    channel 0 of the instantiated CoreI2C hardware.\r
+  \r
+  @param tx_buffer:\r
+    This parameter is a pointer to the memory buffer holding the data to be\r
+    returned to the I2C master when this CoreI2C channel is the target of an\r
+    I2C read or write-read transaction.\r
+  \r
+  @param tx_size:\r
+    Size of the transmit buffer pointed to by the tx_buffer parameter.\r
+\r
+  @return none.  \r
+      \r
+  Example:\r
+  @code\r
+    #define COREI2C_BASE_ADDR    0xC0000000u\r
+    #define SLAVE_SER_ADDR       0x10u\r
+    #define SLAVE_TX_BUFFER_SIZE 10u\r
+\r
+    i2c_instance_t g_i2c_inst;\r
+\r
+    uint8_t g_slave_tx_buffer[SLAVE_TX_BUFFER_SIZE] = { 1, 2, 3, 4, 5,\r
+                                                        6, 7, 8, 9, 10 };\r
+\r
+    void main( void )\r
+    {\r
+        // Initialize the CoreI2C driver with its base address, I2C serial\r
+        // address and serial clock divider.\r
+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, SLAVE_SER_ADDR,\r
+                  I2C_PCLK_DIV_256 );\r
+       \r
+        // Specify the transmit buffer containing the data that will be\r
+        // returned to the master during read and write-read transactions.\r
+        I2C_set_slave_tx_buffer( &g_i2c_inst, g_slave_tx_buffer, \r
+                                 sizeof(g_slave_tx_buffer) );\r
+    }\r
+  @endcode\r
+ */\r
+void I2C_set_slave_tx_buffer\r
+(\r
+    i2c_instance_t * this_i2c,\r
+    const uint8_t * tx_buffer,\r
+    uint16_t tx_size\r
+);\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  I2C slave receive buffer configuration.\r
+  ------------------------------------------------------------------------------\r
+  This function specifies the memory buffer that will be used by the CoreI2C\r
+  channel to receive data when it is a slave. This buffer is the memory where\r
+  data will be stored when the CoreI2C channel is the target of an I2C master\r
+  write transaction (i.e. when it is the slave).\r
+  ------------------------------------------------------------------------------\r
+  @param this_i2c:\r
+    The this_i2c parameter is a pointer to the i2c_instance_t data structure\r
+    holding all data related to a specific CoreI2C channel. For example, if only\r
+    one channel is initialized, this data structure holds the information of \r
+    channel 0 of the instantiated CoreI2C hardware.\r
+  \r
+  @param rx_buffer:\r
+    This parameter is a pointer to the memory buffer allocated by the caller\r
+    software to be used as a slave receive buffer.\r
+  \r
+  @param rx_size:\r
+    Size of the slave receive buffer. This is the amount of memory that is\r
+    allocated to the buffer pointed to by rx_buffer.\r
+    Note:   This buffer size indirectly specifies the maximum I2C write\r
+            transaction length this CoreI2C channel can be the target of. This\r
+            is because this CoreI2C channel responds to further received\r
+            bytes with a non-acknowledge bit (NACK) as soon as its receive\r
+            buffer is full. This causes the write transaction to fail.\r
+            \r
+  @return none.  \r
+      \r
+  Example:\r
+  @code\r
+    #define COREI2C_BASE_ADDR    0xC0000000u\r
+    #define SLAVE_SER_ADDR       0x10u\r
+    #define SLAVE_RX_BUFFER_SIZE 10u\r
+\r
+    i2c_instance_t g_i2c_inst;\r
+\r
+    uint8_t g_slave_rx_buffer[SLAVE_RX_BUFFER_SIZE];\r
+\r
+    void main( void )\r
+    {\r
+        // Initialize the CoreI2C driver with its base address, I2C serial\r
+        // address and serial clock divider.\r
+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, SLAVE_SER_ADDR,\r
+                  I2C_PCLK_DIV_256 );\r
+       \r
+        // Specify the buffer used to store the data written by the I2C master.\r
+        I2C_set_slave_rx_buffer( &g_i2c_inst, g_slave_rx_buffer, \r
+                                 sizeof(g_slave_rx_buffer) );\r
+    }\r
+  @endcode\r
+ */\r
+void I2C_set_slave_rx_buffer\r
+(\r
+    i2c_instance_t * this_i2c,\r
+    uint8_t * rx_buffer,\r
+    uint16_t rx_size\r
+);\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  I2C slave memory offset length configuration.\r
+  ------------------------------------------------------------------------------\r
+  This function is used as part of the configuration of a CoreI2C channel for\r
+  operation as a slave supporting write-read transactions. It specifies the\r
+  number of bytes expected as part of the write phase of a write-read\r
+  transaction. The bytes received during the write phase of a write-read\r
+  transaction will be interpreted as an offset into the slave's transmit buffer.\r
+  This allows random access into the I2C slave transmit buffer from a remote\r
+  I2C master.\r
+  ------------------------------------------------------------------------------\r
+  @param this_i2c:\r
+    The this_i2c parameter is a pointer to the i2c_instance_t data structure\r
+    holding all data related to a specific CoreI2C channel. For example, if only\r
+    one channel is initialized, this data structure holds the information of \r
+    channel 0 of the instantiated CoreI2C hardware.\r
+  \r
+  @param offset_length:\r
+    The offset_length parameter configures the number of bytes to be interpreted\r
+    by the CoreI2C slave as a memory offset value during the write phase of\r
+    write-read transactions. The maximum value for the offset_length parameter\r
+    is two. The value of offset_length has the following effect on the \r
+    interpretation of the received data.\r
+    \r
+      If offset_length is 0, the offset into the transmit buffer is fixed at 0.\r
+      \r
+      If offset_length is 1, a single byte of received data is interpreted as an\r
+      unsigned 8 bit offset value in the range 0 to 255.\r
+      \r
+      If offset_length is 2, 2 bytes of received data are interpreted as an\r
+      unsigned 16 bit offset value in the range 0 to 65535. The first byte\r
+      received in this case provides the high order bits of the offset and\r
+      the second byte provides the low order bits.\r
+      \r
+    If the number of bytes received does not match the non 0 value of\r
+    offset_length the transmit buffer offset is set to 0.\r
+            \r
+  @return none.  \r
+      \r
+  Example:\r
+  @code\r
+    #define COREI2C_BASE_ADDR    0xC0000000u\r
+    #define SLAVE_SER_ADDR       0x10u\r
+    #define SLAVE_TX_BUFFER_SIZE 10u\r
+\r
+    i2c_instance_t g_i2c_inst;\r
+\r
+    uint8_t g_slave_tx_buffer[SLAVE_TX_BUFFER_SIZE] = { 1, 2, 3, 4, 5,\r
+                                                        6, 7, 8, 9, 10 };\r
+\r
+    void main( void )\r
+    {\r
+        // Initialize the CoreI2C driver with its base address, I2C serial\r
+        // address and serial clock divider.\r
+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, SLAVE_SER_ADDR,\r
+                  I2C_PCLK_DIV_256 );\r
+        I2C_set_slave_tx_buffer( &g_i2c_inst, g_slave_tx_buffer, \r
+                                 sizeof(g_slave_tx_buffer) );\r
+        I2C_set_slave_mem_offset_length( &g_i2c_inst, 1 );\r
+    }\r
+  @endcode        \r
+ */\r
+void I2C_set_slave_mem_offset_length\r
+(\r
+    i2c_instance_t * this_i2c,\r
+    uint8_t offset_length\r
+);\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  I2C write handler registration. \r
+  ------------------------------------------------------------------------------\r
+  Register the function that is called to process the data written to this\r
+  CoreI2C channel when it is the slave in an I2C write transaction.\r
+  Note: If a write handler is registered, it is called on completion of the\r
+        write phase of a write-read transaction and responsible for processing\r
+        the received data in the slave receive buffer and populating the slave\r
+        transmit buffer with the data that will be transmitted to the I2C master\r
+        as part of the read phase of the write-read transaction. If a write\r
+        handler is not registered, the write data of a write read transaction is\r
+        interpreted as an offset into the slave\92s transmit buffer and handled by\r
+        the driver.\r
+  ------------------------------------------------------------------------------\r
+  @param this_i2c:\r
+    The this_i2c parameter is a pointer to the i2c_instance_t data structure\r
+    holding all data related to a specific CoreI2C channel. For example, if only\r
+    one channel is initialized, this data structure holds the information of \r
+    channel 0 of the instantiated CoreI2C hardware.\r
+  \r
+  @param handler:\r
+    Pointer to the function that will process the I2C write request.\r
+            \r
+  @return none.  \r
+      \r
+  Example:\r
+  @code\r
+    #define COREI2C_BASE_ADDR    0xC0000000u\r
+    #define SLAVE_SER_ADDR       0x10u\r
+    #define SLAVE_TX_BUFFER_SIZE 10u\r
+\r
+    i2c_instance_t g_i2c_inst;\r
+\r
+    uint8_t g_slave_tx_buffer[SLAVE_TX_BUFFER_SIZE] = { 1, 2, 3, 4, 5,\r
+                                                       6, 7, 8, 9, 10 };\r
+\r
+    // local function prototype\r
+    void slave_write_handler\r
+    (\r
+        i2c_instance_t * this_i2c,\r
+        uint8_t * p_rx_data,\r
+        uint16_t rx_size\r
+    );\r
+\r
+    void main( void )\r
+    {\r
+        // Initialize the CoreI2C driver with its base address, I2C serial\r
+        // address and serial clock divider.\r
+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, SLAVE_SER_ADDR, \r
+                  I2C_PCLK_DIV_256 );\r
+        I2C_set_slave_tx_buffer( &g_i2c_inst, g_slave_tx_buffer, \r
+                                 sizeof(g_slave_tx_buffer) );\r
+        I2C_set_slave_mem_offset_length( &g_i2c_inst, 1 );\r
+        I2C_register_write_handler( &g_i2c_inst, slave_write_handler );\r
+    }\r
+  @endcode    \r
+*/\r
+void I2C_register_write_handler\r
+(\r
+    i2c_instance_t * this_i2c,\r
+    i2c_slave_wr_handler_t handler\r
+);\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  I2C slave enable.\r
+  ------------------------------------------------------------------------------\r
+  This function enables slave mode operation for a CoreI2C channel. It enables \r
+  the CoreI2C slave to receive data when it is the target of an I2C read, write\r
+  or write-read transaction.\r
+  ------------------------------------------------------------------------------\r
+  @param this_i2c:\r
+    The this_i2c parameter is a pointer to the i2c_instance_t data structure\r
+    holding all data related to a specific CoreI2C channel. For example, if only\r
+    one channel is initialized, this data structure holds the information of \r
+    channel 0 of the instantiated CoreI2C hardware.\r
+\r
+  @return none.\r
+\r
+  Example:\r
+  @code\r
+    // Enable I2C slave\r
+    I2C_enable_slave( &g_i2c_inst );\r
+  @endcode\r
+ */\r
+void I2C_enable_slave\r
+(\r
+    i2c_instance_t * this_i2c\r
+);\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  I2C slave disable.\r
+  ------------------------------------------------------------------------------\r
+  This function disables slave mode operation for a CoreI2C channel. It stops\r
+  the CoreI2C slave acknowledging I2C read, write or write-read transactions\r
+  targeted at it.\r
+  ------------------------------------------------------------------------------\r
+  @param this_i2c:\r
+    The this_i2c parameter is a pointer to the i2c_instance_t data structure\r
+    holding all data related to a specific CoreI2C channel. For example, if only\r
+    one channel is initialized, this data structure holds the information of \r
+    channel 0 of the instantiated CoreI2C hardware.\r
+\r
+  @return none.\r
+\r
+  Example:\r
+  @code\r
+   // Disable I2C slave\r
+   I2C_disable_slave( &g_i2c_inst );\r
+  @endcode\r
+ */\r
+void I2C_disable_slave\r
+(\r
+    i2c_instance_t * this_i2c\r
+);\r
+/*-------------------------------------------------------------------------*//**\r
+  Set I2C slave second address.\r
+  ------------------------------------------------------------------------------\r
+  The function I2C_set_slave_second_addr() sets the secondary slave address for\r
+  a CoreI2C slave device. This is an additional slave address which might be\r
+  required in certain applications, for example to enable fail-safe operation in\r
+  a system. As the CoreI2C device supports 7-bit addressing, the highest value\r
+  which can be assigned to second slave address is 127 (0x7F).\r
+  Note: This function does not support CoreI2C hardware configured with a fixed \r
+      second slave address.  The current implementation of the ADDR1[0] register\r
+      bit makes it difficult for the driver to support both programmable and\r
+      fixed second slave address, so we choose to support programmable only.\r
+  ------------------------------------------------------------------------------\r
+  @param this_i2c:\r
+    The this_i2c parameter is a pointer to the i2c_instance_t data structure\r
+    holding all data related to a specific CoreI2C channel. For example, if only\r
+    one channel is initialized, this data structure holds the information of \r
+    channel 0 of the instantiated CoreI2C hardware.\r
+\r
+  @param second_slave_addr:\r
+    The second_slave_addr parameter is the secondary slave address of the I2C\r
+    device.\r
+\r
+  @return\r
+    none.\r
+\r
+  Example:\r
+  @code\r
+    #define COREI2C_BASE_ADDR  0xC0000000u\r
+    #define SLAVE_SER_ADDR     0x10u\r
+    #define SECOND_SLAVE_ADDR  0x20u\r
+\r
+    i2c_instance_t g_i2c_inst;\r
+    void main( void )\r
+    {\r
+        // Initialize the CoreI2C driver with its base address, primary I2C\r
+        // serial address and serial clock divider.\r
+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, SLAVE_SER_ADDR, \r
+                  I2C_PCLK_DIV_256 );\r
+        I2C_set_slave_second_addr( &g_i2c_inst, SECOND_SLAVE_ADDR );\r
+    }\r
+  @endcode\r
+ */\r
+void I2C_set_slave_second_addr\r
+(\r
+    i2c_instance_t * this_i2c,\r
+    uint8_t second_slave_addr\r
+);\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  Disable second slave address.\r
+  ------------------------------------------------------------------------------\r
+  The function I2C_disable_slave_second_addr() disables the secondary slave\r
+  address of the CoreI2C slave device. \r
+  Note: This version of the driver only supports CoreI2C hardware configured\r
+        with a programmable second slave address.\r
+  ------------------------------------------------------------------------------\r
+  @param this_i2c:\r
+    The this_i2c parameter is a pointer to the i2c_instance_t data structure\r
+    holding all data related to a specific CoreI2C channel. For example, if only\r
+    one channel is initialized, this data structure holds the information of \r
+    channel 0 of the instantiated CoreI2C hardware.\r
+\r
+  @return\r
+    none.\r
+\r
+  Example:\r
+  @code\r
+    i2c_instance_t g_i2c_inst;\r
+    I2C_disable_slave_second_addr( &g_i2c_inst);\r
+  @endcode\r
+ */\r
+void I2C_disable_slave_second_addr\r
+(\r
+    i2c_instance_t * this_i2c\r
+);\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  The I2C_set_gca() function is used to set the general call acknowledgement bit\r
+  of a CoreI2C slave device. This allows all channels of the CoreI2C slave\r
+  device respond to a general call or broadcast message from an I2C master.\r
+  ------------------------------------------------------------------------------\r
+  @param this_i2c:\r
+    The this_i2c parameter is a pointer to the i2c_instance_t data structure\r
+    holding all data related to a specific CoreI2C channel. For example, if only\r
+    one channel is initialized, this data structure holds the information of \r
+    channel 0 of the instantiated CoreI2C hardware.\r
+\r
+  @return\r
+    none.\r
+\r
+  Example:\r
+  @code\r
+    i2c_instance_t g_i2c_inst;\r
+\r
+    // Enable recognition of the General Call Address\r
+    I2C_set_gca( &g_i2c_inst ); \r
+  @endcode\r
+ */\r
+void I2C_set_gca\r
+(\r
+    i2c_instance_t * this_i2c\r
+);\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  The I2C_clear_gca() function is used to clear the general call acknowledgement\r
+  bit of a CoreI2C slave device. This will stop all channels of the I2C slave\r
+  device responding to any general call or broadcast message from the master.\r
+  ------------------------------------------------------------------------------\r
+  @param this_i2c:\r
+    The this_i2c parameter is a pointer to the i2c_instance_t data structure\r
+    holding all data related to a specific CoreI2C channel. For example, if only\r
+    one channel is initialized, this data structure holds the information of \r
+    channel 0 of the instantiated CoreI2C hardware.\r
+\r
+  @return\r
+    none.\r
+\r
+  Example:\r
+  @code\r
+    i2c_instance_t g_i2c_inst;\r
+\r
+    // Disable recognition of the General Call Address\r
+    I2C_clear_gca( &g_i2c_inst );\r
+  @endcode\r
+ */\r
+\r
+void I2C_clear_gca\r
+(\r
+    i2c_instance_t * this_i2c\r
+);\r
+\r
+/*------------------------------------------------------------------------------\r
+                      I2C SMBUS specific APIs\r
+ ----------------------------------------------------------------------------*/\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  The I2C_smbus_init() function enables SMBus timeouts and status logic for a\r
+  CoreI2C channel.\r
+  Note: This and any of the other SMBus related functionality will only have an\r
+        effect if the CoreI2C was instantiated with the Generate SMBus Logic\r
+        option checked.\r
+  Note: If the CoreI2C was instantiated with the Generate IPMI Logic option\r
+        checked this function will enable the IPMI 3mS SCL low timeout but none\r
+        of the other SMBus functions will have any effect.\r
+  ------------------------------------------------------------------------------\r
+  @param this_i2c:\r
+    The this_i2c parameter is a pointer to the i2c_instance_t data structure\r
+    holding all data related to a specific CoreI2C channel. For example, if only\r
+    one channel is initialized, this data structure holds the information of \r
+    channel 0 of the instantiated CoreI2C hardware.\r
+\r
+  @return\r
+    none.\r
+\r
+  Example:\r
+  @code\r
+   #define COREI2C_BASE_ADDR  0xC0000000u\r
+   #define SLAVE_SER_ADDR     0x10u\r
+\r
+   i2c_instance_t g_i2c_inst;\r
+\r
+   void system_init( void )\r
+   {\r
+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, SLAVE_SER_ADDR,\r
+                  I2C_PCLK_DIV_256 );\r
+        \r
+        // Initialize SMBus feature\r
+        I2C_smbus_init( &g_i2c_inst);\r
+   }\r
+  @endcode    \r
+ */\r
+void I2C_smbus_init\r
+(\r
+    i2c_instance_t * this_i2c\r
+);\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  The I2C_enable_smbus_irq() function is used to enable the CoreI2C channel\92\r
+  SMBSUS and SMBALERT SMBus interrupts.\r
+  ------------------------------------------------------------------------------\r
+  @param this_i2c:\r
+    The this_i2c parameter is a pointer to the i2c_instance_t data structure\r
+    holding all data related to a specific CoreI2C channel. For example, if only\r
+    one channel is initialized, this data structure holds the information of \r
+    channel 0 of the instantiated CoreI2C hardware.\r
+\r
+  @param irq_type\r
+    The irq_type specify the SMBUS interrupt(s) which will be enabled.\r
+    The two possible interrupts are:\r
+      I2C_SMBALERT_IRQ\r
+      I2C_SMBSUS_IRQ\r
+    To enable both ints in one call, use I2C_SMBALERT_IRQ | I2C_SMBSUS_IRQ.\r
+    \r
+  @return\r
+    none\r
+  \r
+  Example:\r
+  @code\r
+    #define COREI2C_BASE_ADDR  0xC0000000u\r
+    #define SLAVE_SER_ADDR     0x10u\r
+\r
+    i2c_instance_t g_i2c_inst;\r
+\r
+    void main( void )\r
+    {\r
+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, SLAVE_SER_ADDR,\r
+                  I2C_PCLK_DIV_256 );\r
+        \r
+        // Initialize SMBus feature\r
+        I2C_smbus_init( &g_i2c_inst );\r
+        \r
+        // Enable both I2C_SMBALERT_IRQ & I2C_SMBSUS_IRQ interrupts\r
+        I2C_enable_smbus_irq( &g_i2c_inst,\r
+                              (uint8_t)(I2C_SMBALERT_IRQ | I2C_SMBSUS_IRQ) );\r
+   }\r
+   @endcode\r
+ */\r
+void I2C_enable_smbus_irq\r
+(\r
+    i2c_instance_t * this_i2c,\r
+    uint8_t  irq_type\r
+);\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  The I2C_disable_smbus_irq() function is used to disable the CoreI2C channel\92s\r
+  SMBSUS and SMBALERT SMBus interrupts.\r
+  ------------------------------------------------------------------------------\r
+  @param this_i2c:\r
+    The this_i2c parameter is a pointer to the i2c_instance_t data structure\r
+    holding all data related to a specific CoreI2C channel. For example, if only\r
+    one channel is initialized, this data structure holds the information of \r
+    channel 0 of the instantiated CoreI2C hardware.\r
+\r
+  @param irq_type\r
+    The irq_type specifies the SMBUS interrupt(s) which will be disabled.\r
+    The two possible interrupts are:\r
+      I2C_SMBALERT_IRQ\r
+      I2C_SMBSUS_IRQ\r
+    To disable both ints in one call, use I2C_SMBALERT_IRQ | I2C_SMBSUS_IRQ.\r
+\r
+  @return\r
+    none.\r
+      \r
+  Example:\r
+  @code\r
+    #define COREI2C_BASE_ADDR  0xC0000000u\r
+    #define SLAVE_SER_ADDR     0x10u\r
+\r
+    i2c_instance_t g_i2c_inst;\r
+\r
+    void main( void )\r
+    {\r
+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, SLAVE_SER_ADDR,\r
+                  I2C_PCLK_DIV_256 );\r
+        \r
+        // Initialize SMBus feature\r
+        I2C_smbus_init( &g_i2c_inst );\r
+        \r
+        // Enable both SMBALERT & SMBSUS interrupts\r
+        I2C_enable_smbus_irq( &g_i2c_inst,\r
+                              (uint8_t)(I2C_SMBALERT_IRQ | I2C_SMBSUS_IRQ));\r
+        \r
+        ...        \r
+\r
+        // Disable the SMBALERT interrupt\r
+        I2C_disable_smbus_irq( &g_i2c_inst, I2C_SMBALERT_IRQ );\r
+    }\r
+  @endcode\r
+ */\r
+void I2C_disable_smbus_irq\r
+(\r
+    i2c_instance_t * this_i2c,\r
+    uint8_t  irq_type\r
+);\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  The function I2C_suspend_smbus_slave() forces any SMBUS slave devices\r
+  connected to a CoreI2C channel into power down or suspend mode by asserting\r
+  the channel's SMBSUS signal. The CoreI2C channel is the SMBus master in this\r
+  case.\r
+  ------------------------------------------------------------------------------\r
+  @param this_i2c:\r
+    The this_i2c parameter is a pointer to the i2c_instance_t data structure\r
+    holding all data related to a specific CoreI2C channel. For example, if only\r
+    one channel is initialized, this data structure holds the information of \r
+    channel 0 of the instantiated CoreI2C hardware.\r
+\r
+  @return\r
+    none.\r
+    \r
+  Example:\r
+  @code\r
+    #define COREI2C_BASE_ADDR  0xC0000000u\r
+    #define SLAVE_SER_ADDR     0x10u\r
+\r
+    i2c_instance_t g_i2c_inst;\r
+    \r
+    void main( void )\r
+    {\r
+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, SLAVE_SER_ADDR, \r
+                  I2C_PCLK_DIV_256 );\r
+\r
+        // Initialize SMBus feature\r
+        I2C_smbus_init( &g_i2c_inst );\r
+\r
+        // suspend SMBus slaves\r
+        I2C_suspend_smbus_slave( &g_i2c_inst );\r
+\r
+        ...\r
+\r
+        // Re-enable SMBus slaves\r
+        I2C_resume_smbus_slave( &g_i2c_inst );\r
+    }\r
+  @endcode\r
+ */\r
+void I2C_suspend_smbus_slave\r
+(\r
+    i2c_instance_t * this_i2c\r
+);\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  The function I2C_resume_smbus_slave() de-asserts the CoreI2C channel's SMBSUS\r
+  signal to take any connected slave devices out of suspend mode. The CoreI2C\r
+  channel is the SMBus master in this case.\r
+  ------------------------------------------------------------------------------\r
+  @param this_i2c:\r
+    The this_i2c parameter is a pointer to the i2c_instance_t data structure\r
+    holding all data related to a specific CoreI2C channel. For example, if only\r
+    one channel is initialized, this data structure holds the information of \r
+    channel 0 of the instantiated CoreI2C hardware.\r
+\r
+  @return\r
+    none.\r
+    \r
+  Example:\r
+  @code\r
+    #define COREI2C_BASE_ADDR  0xC0000000u\r
+    #define SLAVE_SER_ADDR     0x10u\r
+\r
+    i2c_instance_t g_i2c_inst;\r
+    \r
+    void main( void )\r
+    {\r
+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, SLAVE_SER_ADDR, \r
+                  I2C_PCLK_DIV_256 );\r
+\r
+        // Initialize SMBus feature\r
+        I2C_smbus_init( &g_i2c_inst );\r
+\r
+        // suspend SMBus slaves\r
+        I2C_suspend_smbus_slave( &g_i2c_inst );\r
+\r
+        ...\r
+\r
+        // Re-enable SMBus slaves\r
+        I2C_resume_smbus_slave( &g_i2c_inst );\r
+    }\r
+  @endcode\r
+ */\r
+void I2C_resume_smbus_slave\r
+(\r
+    i2c_instance_t * this_i2c\r
+);\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  The I2C_reset_smbus() function resets the CoreI2C channel's SMBus connection\r
+  by forcing SCLK low for 35mS. The reset is automatically cleared after 35ms\r
+  have elapsed. The CoreI2C channel is the SMBus master in this case.\r
+  ------------------------------------------------------------------------------\r
+  @param this_i2c:\r
+    The this_i2c parameter is a pointer to the i2c_instance_t data structure\r
+    holding all data related to a specific CoreI2C channel. For example, if only\r
+    one channel is initialized, this data structure holds the information of \r
+    channel 0 of the instantiated CoreI2C hardware.\r
+\r
+  @return\r
+    none.\r
+\r
+  Example:\r
+  @code\r
+    #define COREI2C_BASE_ADDR  0xC0000000u\r
+    #define SLAVE_SER_ADDR     0x10u\r
+\r
+    i2c_instance_t g_i2c_inst;\r
+    \r
+    void main( void )\r
+    {\r
+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, SLAVE_SER_ADDR, \r
+                  I2C_PCLK_DIV_256 );\r
+\r
+        // Initialize SMBus feature\r
+        I2C_smbus_init( &g_i2c_inst );\r
+\r
+        // Make sure the SMBus channel is in a known state by resetting it\r
+        I2C_reset_smbus( &g_i2c_inst ); \r
+    }\r
+  @endcode\r
+ */\r
+void I2C_reset_smbus\r
+(\r
+    i2c_instance_t * this_i2c\r
+);\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  The I2C_set_smbus_alert() function is used to force master communication with\r
+  an I2C slave device by asserting the CoreI2C channel\92s SMBALERT signal. The\r
+  CoreI2C channel is the SMBus slave in this case.\r
+  ------------------------------------------------------------------------------\r
+  @param this_i2c:\r
+    The this_i2c parameter is a pointer to the i2c_instance_t data structure\r
+    holding all data related to a specific CoreI2C channel. For example, if only\r
+    one channel is initialized, this data structure holds the information of \r
+    channel 0 of the instantiated CoreI2C hardware.\r
+\r
+  @return\r
+    none.\r
+\r
+  Example:\r
+  @code\r
+    #define COREI2C_BASE_ADDR  0xC0000000u\r
+    #define SLAVE_SER_ADDR     0x10u\r
+\r
+    i2c_instance_t g_i2c_inst;\r
+    \r
+    void main( void )\r
+    {\r
+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, SLAVE_SER_ADDR, \r
+                  I2C_PCLK_DIV_256 );\r
+\r
+        // Initialize SMBus feature\r
+        I2C_smbus_init( &g_i2c_inst );\r
+\r
+        // Get the SMBus masters attention\r
+        I2C_set_smbus_alert( &g_i2c_inst );\r
+\r
+        ...\r
+\r
+        // Once we are happy, drop the alert\r
+        I2C_clear_smbus_alert( &g_i2c_inst );\r
+    }\r
+  @endcode\r
+ */\r
+void I2C_set_smbus_alert\r
+(\r
+    i2c_instance_t * this_i2c\r
+);\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  The I2C_clear_smbus_alert() function is used de-assert the CoreI2C channel\92\r
+  SMBALERT signal once a slave device has had a response from the master. The\r
+  CoreI2C channel is the SMBus slave in this case.\r
+  ------------------------------------------------------------------------------\r
+  @param this_i2c:\r
+    The this_i2c parameter is a pointer to the i2c_instance_t data structure\r
+    holding all data related to a specific CoreI2C channel. For example, if only\r
+    one channel is initialized, this data structure holds the information of \r
+    channel 0 of the instantiated CoreI2C hardware.\r
+\r
+  @return\r
+    none.\r
+    \r
+  Example:\r
+  @code\r
+    #define COREI2C_BASE_ADDR  0xC0000000u\r
+    #define SLAVE_SER_ADDR     0x10u\r
+\r
+    i2c_instance_t g_i2c_inst;\r
+    \r
+    void main( void )\r
+    {\r
+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, SLAVE_SER_ADDR, \r
+                  I2C_PCLK_DIV_256 );\r
+\r
+        // Initialize SMBus feature\r
+        I2C_smbus_init( &g_i2c_inst );\r
+\r
+        // Get the SMBus masters attention\r
+        I2C_set_smbus_alert( &g_i2c_inst );\r
+\r
+        ...\r
+\r
+        // Once we are happy, drop the alert\r
+        I2C_clear_smbus_alert( &g_i2c_inst );\r
+    }\r
+  @endcode\r
+ */\r
+void I2C_clear_smbus_alert\r
+(\r
+    i2c_instance_t * this_i2c\r
+);\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  The I2C_get_irq_status function returns information on which interrupts are\r
+  currently pending in a CoreI2C channel.\r
+  The interrupts supported by CoreI2C are:\r
+    * SMBUSALERT\r
+    * SMBSUS\r
+    * INTR\r
+  The macros I2C_NO_IRQ, I2C_SMBALERT_IRQ, I2C_SMBSUS_IRQ and I2C_INTR_IRQ are\r
+  provided for use with this function.\r
+  ------------------------------------------------------------------------------\r
+  @param this_i2c:\r
+    The this_i2c parameter is a pointer to the i2c_instance_t data structure\r
+    holding all data related to a specific CoreI2C channel. For example, if only\r
+    one channel is initialized, this data structure holds the information of \r
+    channel 0 of the instantiated CoreI2C hardware.\r
+\r
+  @return\r
+    This function returns the status of the CoreI2C channel\92s interrupts as a \r
+    single byte bitmap where a bit is set to indicate a pending interrupt.\r
+    The following are the bit positions associated with each interrupt type:\r
+        Bit 0 - SMBUS_ALERT_IRQ\r
+        Bit 1 - SMBSUS_IRQ\r
+        Bit 2 - INTR_IRQ\r
+    It returns 0, if there are no pending interrupts.\r
+\r
+  Example\r
+  @code\r
+   #define COREI2C_BASE_ADDR  0xC0000000u\r
+   #define SLAVE_SER_ADDR     0x10u\r
+\r
+   i2c_instance_t g_i2c_inst;\r
+   \r
+   void main( void )\r
+   {\r
+        uint8_t irq_to_enable = I2C_SMBALERT_IRQ | I2C_SMBSUS_IRQ;\r
+        uint8_t pending_irq = 0u;\r
+        \r
+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, SLAVE_SER_ADDR,\r
+                  I2C_PCLK_DIV_256 );\r
+\r
+        // Initialize SMBus feature\r
+        I2C_smbus_init( &g_i2c_inst );\r
+\r
+        // Enable both I2C_SMBALERT_IRQ & I2C_SMBSUS_IRQ irq\r
+        I2C_enable_smbus_irq( &g_i2c_inst, irq_to_enable );\r
+\r
+        // Get I2C IRQ type\r
+        pending_irq = I2C_get_irq_status( &g_i2c_inst );\r
+\r
+        // Let's assume, in system, INTR and SMBALERT IRQ is pending.\r
+        // So pending_irq will return status of both the IRQs\r
+\r
+        if( pending_irq & I2C_SMBALERT_IRQ )\r
+        {\r
+           // if true, it means SMBALERT_IRQ is there in pending IRQ list\r
+        }\r
+        if( pending_irq & I2C_INTR_IRQ )\r
+        {\r
+           // if true, it means I2C_INTR_IRQ is there in pending IRQ list\r
+        }\r
+   }\r
+  @endcode\r
+ */\r
+uint8_t I2C_get_irq_status\r
+(\r
+    i2c_instance_t * this_i2c\r
+);\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  The I2C_set_user_data() function is used to allow the association of a block\r
+  of application specific data with a CoreI2C channel. The composition of the \r
+  data block is an application matter and the driver simply provides the means\r
+  for the application to set and retrieve the pointer. This may for example be\r
+  used to provide additional channel specific information to the slave write \r
+  handler.\r
+  ------------------------------------------------------------------------------\r
+  @param this_i2c:\r
+    The this_i2c parameter is a pointer to the i2c_instance_t data structure\r
+    holding all data related to a specific CoreI2C channel. For example, if only\r
+    one channel is initialized, this data structure holds the information of \r
+    channel 0 of the instantiated CoreI2C hardware.\r
+\r
+  @param p_user_data:\r
+    The p_user_data parameter is a pointer to the user specific data block for\r
+    this channel. It is defined as void * as the driver does not know the actual\r
+    type of data being pointed to and simply stores the pointer for later\r
+    retrieval by the application.\r
+\r
+  @return\r
+    none.\r
+    \r
+  Example\r
+  @code\r
+    #define COREI2C_BASE_ADDR  0xC0000000u\r
+    #define SLAVE_SER_ADDR     0x10u\r
+\r
+    i2c_instance_t g_i2c_inst;\r
+    app_data_t channel_xdata;\r
+  \r
+    void main( void )\r
+    {\r
+        app_data_t *p_xdata;\r
+\r
+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, SLAVE_SER_ADDR, \r
+                  I2C_PCLK_DIV_256 );\r
+\r
+        // Store location of user data in instance structure\r
+        I2C_set_user_data( &g_i2c_inst, (void *)&channel_xdata );\r
+\r
+        ...\r
+\r
+        // Retrieve location of user data and do some work on it\r
+        p_xdata = (app_data_t *)I2C_get_user_data( &g_i2c_inst );\r
+        if( NULL != p_xdata )\r
+        {\r
+            p_xdata->foo = 123;\r
+        }\r
+    }\r
+  @endcode\r
+ */\r
+void I2C_set_user_data\r
+(\r
+    i2c_instance_t * this_i2c,\r
+    void * p_user_data\r
+);\r
+\r
+/*-------------------------------------------------------------------------*//**\r
+  The I2C_get_user_data() function is used to allow the retrieval of the address\r
+  of a block of application specific data associated with a CoreI2C channel.\r
+  The composition of the data block is an application matter and the driver \r
+  simply provides the means for the application to set and retrieve the pointer.\r
+  This may for example be used to provide additional channel specific\r
+  information to the slave write handler.\r
+  ------------------------------------------------------------------------------\r
+  @param this_i2c:\r
+    The this_i2c parameter is a pointer to the i2c_instance_t data structure\r
+    holding all data related to a specific CoreI2C channel. For example, if only\r
+    one channel is initialized, this data structure holds the information of \r
+    channel 0 of the instantiated CoreI2C hardware.\r
+\r
+  @return\r
+    This function returns a pointer to the user specific data block for this \r
+    channel. It is defined as void * as the driver does not know the actual type\r
+    of data being pointed. If no user data has been registered for this channel\r
+    a NULL pointer is returned.\r
+    \r
+  Example\r
+  @code\r
+    #define COREI2C_BASE_ADDR  0xC0000000u\r
+    #define SLAVE_SER_ADDR     0x10u\r
+\r
+    i2c_instance_t g_i2c_inst;\r
+    app_data_t channel_xdata;\r
+  \r
+    void main( void )\r
+    {\r
+        app_data_t *p_xdata;\r
+\r
+        I2C_init( &g_i2c_inst, COREI2C_BASE_ADDR, SLAVE_SER_ADDR,\r
+                  I2C_PCLK_DIV_256 );\r
+\r
+        // Store location of user data in instance structure\r
+        I2C_set_user_data( &g_i2c_inst, (void *)&channel_xdata );\r
+\r
+        ...\r
+        \r
+        // Retrieve location of user data and do some work on it\r
+        p_xdata = (app_data_t *)I2C_get_user_data( &g_i2c_inst );\r
+        if( NULL != p_xdata )\r
+        {\r
+            p_xdata->foo = 123;\r
+        }\r
+    }\r
+  @endcode\r
+ */\r
+void * I2C_get_user_data\r
+(\r
+    i2c_instance_t * this_i2c\r
+);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
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 (file)
index 0000000..67da7a5
--- /dev/null
@@ -0,0 +1,190 @@
+/*******************************************************************************\r
+ * (c) Copyright 2009-2015 Microsemi SoC Products Group.  All rights reserved.\r
+ * \r
+ * SVN $Revision: 7984 $\r
+ * SVN $Date: 2015-10-12 12:07:40 +0530 (Mon, 12 Oct 2015) $\r
+ */\r
+\r
+#ifndef __CORE_SMBUS_REGISTERS\r
+#define __CORE_SMBUS_REGISTERS    1\r
+\r
+/*------------------------------------------------------------------------------\r
+ * CONTROL register details\r
+ */\r
+#define CONTROL_REG_OFFSET    0x00u\r
+\r
+/*\r
+ * CR0 bits.\r
+ */\r
+#define CR0_OFFSET   0x00u\r
+#define CR0_MASK     0x01u\r
+#define CR0_SHIFT    0u\r
+\r
+/*\r
+ * CR1 bits.\r
+ */\r
+#define CR1_OFFSET   0x00u\r
+#define CR1_MASK     0x02u\r
+#define CR1_SHIFT    1u\r
+\r
+/*\r
+ * AA bits.\r
+ */\r
+#define AA_OFFSET   0x00u\r
+#define AA_MASK     0x04u\r
+#define AA_SHIFT    2u\r
+\r
+/*\r
+ * SI bits.\r
+ */\r
+#define SI_OFFSET   0x00u\r
+#define SI_MASK     0x08u\r
+#define SI_SHIFT    3u\r
+\r
+/*\r
+ * STO bits.\r
+ */\r
+#define STO_OFFSET   0x00u\r
+#define STO_MASK     0x10u\r
+#define STO_SHIFT    4u\r
+\r
+/*\r
+ * STA bits.\r
+ */\r
+#define STA_OFFSET   0x00u\r
+#define STA_MASK     0x20u\r
+#define STA_SHIFT    5u\r
+\r
+/*\r
+ * ENS1 bits.\r
+ */\r
+#define ENS1_OFFSET   0x00u\r
+#define ENS1_MASK     0x40u\r
+#define ENS1_SHIFT    6u\r
+\r
+/*\r
+ * CR2 bits.\r
+ */\r
+#define CR2_OFFSET   0x00u\r
+#define CR2_MASK     0x80u\r
+#define CR2_SHIFT    7u\r
+\r
+/*------------------------------------------------------------------------------\r
+ * STATUS register details\r
+ */\r
+#define STATUS_REG_OFFSET    0x04u\r
+\r
+/*------------------------------------------------------------------------------\r
+ * DATA register details\r
+ */\r
+#define DATA_REG_OFFSET    0x08u\r
+\r
+/*\r
+ * TARGET_ADDR bits.\r
+ */\r
+#define TARGET_ADDR_OFFSET    0x08u\r
+#define TARGET_ADDR_MASK      0xFEu\r
+#define TARGET_ADDR_SHIFT     1u\r
\r
+/*\r
+ * DIR bit.\r
+ */\r
+#define DIR_OFFSET   0x08u\r
+#define DIR_MASK     0x01u\r
+#define DIR_SHIFT    0u\r
+\r
+\r
+/*------------------------------------------------------------------------------\r
+ * ADDRESS register details\r
+ */\r
+#define ADDRESS_REG_OFFSET    0x0Cu\r
+\r
+/*\r
+ * GC bits.\r
+ */\r
+#define GC_OFFSET   0x0Cu\r
+#define GC_MASK     0x01u\r
+#define GC_SHIFT    0u\r
+\r
+/*\r
+ * ADR bits.\r
+ */\r
+#define OWN_SLAVE_ADDR_OFFSET   0x0Cu\r
+#define OWN_SLAVE_ADDR_MASK     0xFEu\r
+#define OWN_SLAVE_ADDR_SHIFT    1u\r
+\r
+/*------------------------------------------------------------------------------\r
+ * SMBUS register details\r
+ */\r
+#define SMBUS_REG_OFFSET    0x10u\r
+\r
+/*\r
+ * SMBALERT_IE bits.\r
+ */\r
+#define SMBALERT_IE_OFFSET   0x10u\r
+#define SMBALERT_IE_MASK     0x01u\r
+#define SMBALERT_IE_SHIFT    0u\r
+\r
+/*\r
+ * SMBSUS_IE bits.\r
+ */\r
+#define SMBSUS_IE_OFFSET   0x10u\r
+#define SMBSUS_IE_MASK     0x02u\r
+#define SMBSUS_IE_SHIFT    1u\r
+\r
+/*\r
+ * SMB_IPMI_EN bits.\r
+ */\r
+#define SMB_IPMI_EN_OFFSET   0x10u\r
+#define SMB_IPMI_EN_MASK     0x04u\r
+#define SMB_IPMI_EN_SHIFT    2u\r
+\r
+/*\r
+ * SMBALERT_NI_STATUS bits.\r
+ */\r
+#define SMBALERT_NI_STATUS_OFFSET   0x10u\r
+#define SMBALERT_NI_STATUS_MASK     0x08u\r
+#define SMBALERT_NI_STATUS_SHIFT    3u\r
+\r
+/*\r
+ * SMBALERT_NO_CONTROL bits.\r
+ */\r
+#define SMBALERT_NO_CONTROL_OFFSET   0x10u\r
+#define SMBALERT_NO_CONTROL_MASK     0x10u\r
+#define SMBALERT_NO_CONTROL_SHIFT    4u\r
+\r
+/*\r
+ * SMBSUS_NI_STATUS bits.\r
+ */\r
+#define SMBSUS_NI_STATUS_OFFSET   0x10u\r
+#define SMBSUS_NI_STATUS_MASK     0x20u\r
+#define SMBSUS_NI_STATUS_SHIFT    5u\r
+\r
+/*\r
+ * SMBSUS_NO_CONTROL bits.\r
+ */\r
+#define SMBSUS_NO_CONTROL_OFFSET   0x10u\r
+#define SMBSUS_NO_CONTROL_MASK     0x40u\r
+#define SMBSUS_NO_CONTROL_SHIFT    6u\r
+\r
+/*\r
+ * SMBUS_MST_RESET bits.\r
+ */\r
+#define SMBUS_MST_RESET_OFFSET   0x10u\r
+#define SMBUS_MST_RESET_MASK     0x80u\r
+#define SMBUS_MST_RESET_SHIFT    7u\r
+\r
+/*------------------------------------------------------------------------------\r
+ * SLAVE ADDRESS 1 register details\r
+ */\r
+\r
+#define ADDRESS1_REG_OFFSET    0x1Cu\r
+\r
+/*\r
+ * SLAVE1_EN bit of Slave Address 1 .\r
+ */\r
+#define SLAVE1_EN_OFFSET      0x1Cu\r
+#define SLAVE1_EN_MASK        0x01u\r
+#define SLAVE1_EN_SHIFT          0u\r
+\r
+#endif    /* __CORE_SMBUS_REGISTERS */\r
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 (file)
index 0000000..f918b8c
--- /dev/null
@@ -0,0 +1,35 @@
+/*******************************************************************************\r
+ * (c) Copyright 2009-2015 Microsemi SoC Products Group.  All rights reserved.\r
+ * \r
+ * CoreI2C driver interrupt control.\r
+ * \r
+ * SVN $Revision: 7984 $\r
+ * SVN $Date: 2015-10-12 12:07:40 +0530 (Mon, 12 Oct 2015) $\r
+ */\r
+#include "hal.h"\r
+#include "hal_assert.h"\r
+#include "core_i2c.h"\r
+#include "riscv_hal.h"\r
+\r
+\r
+#define I2C_IRQn                                           External_29_IRQn\r
+\r
+/*------------------------------------------------------------------------------\r
+ * This function must be modified to enable interrupts generated from the\r
+ * CoreI2C instance identified as parameter.\r
+ */\r
+void I2C_enable_irq( i2c_instance_t * this_i2c )\r
+{\r
+       PLIC_EnableIRQ(I2C_IRQn);\r
+//    HAL_ASSERT(0)\r
+}\r
+\r
+/*------------------------------------------------------------------------------\r
+ * This function must be modified to disable interrupts generated from the\r
+ * CoreI2C instance identified as parameter.\r
+ */\r
+void I2C_disable_irq( i2c_instance_t * this_i2c )\r
+{\r
+       PLIC_DisableIRQ(I2C_IRQn);\r
+//    HAL_ASSERT(0)\r
+}\r
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 (file)
index 0000000..3f6720b
--- /dev/null
@@ -0,0 +1,158 @@
+/*******************************************************************************\r
+ * (c) Copyright 2007-2015 Microsemi SoC Products Group. All rights reserved.\r
+ * \r
+ * CoreTimer driver implementation.\r
+ * \r
+ * SVN $Revision: 7967 $\r
+ * SVN $Date: 2015-10-09 18:48:26 +0530 (Fri, 09 Oct 2015) $\r
+ */\r
+\r
+#include "core_timer.h"\r
+#include "coretimer_regs.h"\r
+#include "hal.h"\r
+#include "hal_assert.h"\r
+\r
+#ifndef NDEBUG\r
+static timer_instance_t* NULL_timer_instance;\r
+#endif\r
+\r
+/***************************************************************************//**\r
+ * TMR_init()\r
+ * See "core_timer.h" for details of how to use this function.\r
+ */\r
+void \r
+TMR_init\r
+(\r
+       timer_instance_t * this_timer,\r
+       addr_t address,\r
+       uint8_t mode,\r
+       uint32_t prescale,\r
+       uint32_t load_value\r
+)\r
+{\r
+       HAL_ASSERT( this_timer != NULL_timer_instance )\r
+       HAL_ASSERT( prescale <= PRESCALER_DIV_1024 )\r
+       HAL_ASSERT( load_value != 0 )\r
+    \r
+    this_timer->base_address = address;\r
+\r
+    /* Disable interrupts. */\r
+    HAL_set_32bit_reg_field( address, InterruptEnable,0 );\r
+\r
+    /* Disable timer. */\r
+    HAL_set_32bit_reg_field( address, TimerEnable, 0 );\r
+\r
+    /* Clear pending interrupt. */\r
+    HAL_set_32bit_reg( address, TimerIntClr, 1 );\r
+\r
+    /* Configure prescaler and load value. */  \r
+    HAL_set_32bit_reg( address, TimerPrescale, prescale );\r
+    HAL_set_32bit_reg( address, TimerLoad, load_value );\r
+\r
+    /* Set the interrupt mode. */\r
+    if ( mode == TMR_CONTINUOUS_MODE )\r
+    {\r
+        HAL_set_32bit_reg_field( address, TimerMode, 0 );\r
+    }\r
+    else\r
+    {\r
+        /* TMR_ONE_SHOT_MODE */\r
+        HAL_set_32bit_reg_field( address, TimerMode, 1 );\r
+    }\r
+}\r
+\r
+/***************************************************************************//**\r
+ * TMR_start()\r
+ * See "core_timer.h" for details of how to use this function.\r
+ */\r
+void\r
+TMR_start\r
+(\r
+    timer_instance_t * this_timer\r
+)\r
+{\r
+       HAL_ASSERT( this_timer != NULL_timer_instance )\r
+    \r
+    HAL_set_32bit_reg_field( this_timer->base_address, TimerEnable, 1 );\r
+}\r
+\r
+/***************************************************************************//**\r
+ * TMR_stop()\r
+ * See "core_timer.h" for details of how to use this function.\r
+ */\r
+void\r
+TMR_stop\r
+(\r
+    timer_instance_t * this_timer\r
+)\r
+{\r
+       HAL_ASSERT( this_timer != NULL_timer_instance )\r
+    \r
+    HAL_set_32bit_reg_field( this_timer->base_address, TimerEnable, 0 );\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * TMR_enable_int()\r
+ * See "core_timer.h" for details of how to use this function.\r
+ */\r
+void\r
+TMR_enable_int\r
+(\r
+    timer_instance_t * this_timer\r
+)\r
+{\r
+       HAL_ASSERT( this_timer != NULL_timer_instance )\r
+    \r
+    HAL_set_32bit_reg_field( this_timer->base_address, InterruptEnable, 1 );\r
+}\r
+\r
+/***************************************************************************//**\r
+ * TMR_clear_int()\r
+ * See "core_timer.h" for details of how to use this function.\r
+ */\r
+void\r
+TMR_clear_int\r
+(\r
+    timer_instance_t * this_timer\r
+)\r
+{\r
+       HAL_ASSERT( this_timer != NULL_timer_instance )\r
+    \r
+    HAL_set_32bit_reg( this_timer->base_address, TimerIntClr, 0x01 );\r
+}\r
+\r
+/***************************************************************************//**\r
+ * TMR_current_value()\r
+ * See "core_timer.h" for details of how to use this function.\r
+ */\r
+uint32_t\r
+TMR_current_value\r
+(\r
+    timer_instance_t * this_timer\r
+)\r
+{\r
+       uint32_t value = 0;\r
+       HAL_ASSERT( this_timer != NULL_timer_instance )\r
+    \r
+    value = HAL_get_32bit_reg( this_timer->base_address, TimerValue );\r
+    \r
+       return value;\r
+}\r
+\r
+/***************************************************************************//**\r
+ * TMR_reload()\r
+ * See "core_timer.h" for details of how to use this function.\r
+ */\r
+void TMR_reload\r
+(\r
+       timer_instance_t * this_timer,\r
+       uint32_t load_value\r
+)\r
+{\r
+       HAL_ASSERT( this_timer != NULL_timer_instance )\r
+       HAL_ASSERT( load_value != 0 )\r
+       \r
+       HAL_set_32bit_reg(this_timer->base_address, TimerLoad, load_value );\r
+}\r
+\r
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 (file)
index 0000000..04b7a6e
--- /dev/null
@@ -0,0 +1,206 @@
+/*******************************************************************************\r
+ * (c) Copyright 2007-2015 Microsemi SoC Products Group. All rights reserved.\r
+ * \r
+ * CoreTimer public API.\r
+ * \r
+ * SVN $Revision: 7967 $\r
+ * SVN $Date: 2015-10-09 18:48:26 +0530 (Fri, 09 Oct 2015) $\r
+ */\r
+#ifndef CORE_TIMER_H_\r
+#define CORE_TIMER_H_\r
+\r
+#include "cpu_types.h"\r
+\r
+/***************************************************************************//**\r
+ * The following definitions are used to select the CoreTimer driver operating\r
+ * mode. They allow selecting continuous or one-shot mode.\r
+ * 1. Continuous Mode\r
+ * In continuous mode the timer's counter is decremented from the load value \r
+ * until it reaches zero. The timer counter is automatically reloaded, with the\r
+ * load value, upon reaching zero. An interrupt is generated every time the\r
+ * counter reaches zero if interrupt is enabled.\r
+ * This mode is typically used to generate an interrupt at constant time\r
+ * intervals.\r
+ * 2. One-shot mode: \r
+ * In one-shot mode, the counter decrements from the load value and until it\r
+ * reaches zero. An interrupt can be generated, if enabled, when the counter\r
+ * reaches zero. The timer's counter must be reloaded to begin counting down\r
+ * again.\r
+ */\r
+#define TMR_CONTINUOUS_MODE            0\r
+#define TMR_ONE_SHOT_MODE              1\r
+\r
+/***************************************************************************//**\r
+ * The following definitions are used to configure the CoreTimer prescaler.\r
+ * The prescaler is used to divide down the clock used to decrement the\r
+ * CoreTimer counter. It can be configure to divide the clock by 2, 4, 8,\r
+ * 16, 32, 64, 128, 256, 512, or 1024.\r
+ */\r
+#define PRESCALER_DIV_2                        0\r
+#define PRESCALER_DIV_4                        1\r
+#define PRESCALER_DIV_8                        2\r
+#define PRESCALER_DIV_16               3\r
+#define PRESCALER_DIV_32               4\r
+#define PRESCALER_DIV_64               5\r
+#define PRESCALER_DIV_128              6\r
+#define PRESCALER_DIV_256              7\r
+#define PRESCALER_DIV_512              8\r
+#define PRESCALER_DIV_1024             9\r
+\r
+/***************************************************************************//**\r
+ * There should be one instance of this structure for each instance of CoreTimer\r
+ * in your system. The function TMR_init() initializes this structure. It is\r
+ * used to identify the various CoreTimer hardware instances in your system.\r
+ * An initialized timer instance structure should be passed as first parameter to\r
+ * CoreTimer driver functions to identify which CoreTimer instance should perform\r
+ * the requested operation.\r
+ * Software using this driver should only need to create one single instance of \r
+ * this data structure for each hardware timer instance in the system.\r
+ */\r
+typedef struct __timer_instance_t\r
+{\r
+       addr_t base_address;\r
+} timer_instance_t;\r
+\r
+/***************************************************************************//**\r
+ * The function TMR_init() initializes the data structures and sets relevant\r
+ * CoreTimer registers. This function will prepare the Timer for use in a given\r
+ * hardware/software configuration. It should be called before any other Timer\r
+ * API functions.\r
+ * The timer will not start counting down immediately after this function is\r
+ * called. It is necessary to call TMR_start() to start the timer decrementing.\r
+ * The CoreTimer interrupt is disabled as part of this function.\r
+ *\r
+ * @param this_timer    Pointer to a timer_instance_t structure holding all \r
+ *                      relevant data associated with the target timer hardware\r
+ *                                             instance. This pointer will be used to identify the\r
+ *                                             target CoreTimer hardware instance in subsequent calls\r
+ *                                             to the CoreTimer functions.\r
+ * @param address       Base address in the processor's memory map of the \r
+ *                      registers of the CoreTimer instance being initialized.\r
+ * @param mode          This parameter is used to select the operating mode of\r
+ *                                             the timer driver. This can be either TMR_CONTINUOUS_MODE\r
+ *                                             or TMR_ONE_SHOT_MODE.\r
+ * @param prescale     This parameter is used to select the prescaler divider\r
+ *                                             used to divide down the clock used to decrement the\r
+ *                                             timer\92s counter. This can be set using one of the \r
+ *                                             PRESCALER_DIV_<n> definitions, where <n> is the\r
+ *                                             divider\92s value.  \r
+ * @param load_value   This parameter is used to set the timer\92s load value\r
+ *                                             from which the CoreTimer counter will decrement.\r
+ *                                             In Continuous mode, this value will be used to reload \r
+ *                                             the timer\92s counter whenever it reaches zero.\r
+ */\r
+void\r
+TMR_init\r
+(\r
+       timer_instance_t * this_timer,\r
+       addr_t address,\r
+       uint8_t mode,\r
+       uint32_t prescale,\r
+       uint32_t load_value\r
+);\r
+\r
+/***************************************************************************//**\r
+ * The function TMR_start() enables the timer to start counting down.\r
+ * This function only needs to be called once after the timer has been\r
+ * initialized through a call to TMR_init(). It does not need to be called after\r
+ * each call to TMR_reload() when the timer is used in one-shot mode.\r
+ *\r
+ * @param this_timer    Pointer to a timer_instance_t structure holding all \r
+ *                      relevant data associated with the target timer hardware\r
+ *                                             instance. This pointer is used to identify the target\r
+ *                                             CoreTimer hardware instance.\r
+ */\r
+void\r
+TMR_start\r
+(\r
+    timer_instance_t * this_timer\r
+);\r
+\r
+/***************************************************************************//**\r
+ * The function TMR_stop() stops the timer counting down. It can be used to \r
+ * stop interrupts from being generated when continuous mode is used and\r
+ * interrupts must be paused from being generated.\r
+ *\r
+ * @param this_timer    Pointer to a timer_instance_t structure holding all \r
+ *                      relevant data associated with the target timer hardware\r
+ *                                             instance. This pointer is used to identify the target\r
+ *                                             CoreTimer hardware instance.\r
+ */\r
+void\r
+TMR_stop\r
+(\r
+    timer_instance_t * this_timer\r
+);\r
+\r
+/***************************************************************************//**\r
+ * The function TMR_enable_int() enables the timer interrupt. A call to this\r
+ * function will allow the interrupt signal coming out of CoreTimer to be\r
+ * asserted. \r
+ *\r
+ * @param this_timer    Pointer to a timer_instance_t structure holding all \r
+ *                      relevant data associated with the target timer hardware\r
+ *                                             instance. This pointer is used to identify the target\r
+ *                                             CoreTimer hardware instance.\r
+ */\r
+void\r
+TMR_enable_int\r
+(\r
+    timer_instance_t * this_timer\r
+);\r
+\r
+/***************************************************************************//**\r
+ * The function TMR_clear_int() clears the timer interrupt. This function should\r
+ * be called within the interrupt handler servicing interrupts from the timer.\r
+ * Failure to clear the timer interrupt will result in the interrupt signal\r
+ * generating from CoreTimer to remain asserted. This assertion may cause the\r
+ * interrupt service routine to be continuously called, causing the system to\r
+ * lock up.\r
+ *\r
+ * @param this_timer    Pointer to a timer_instance_t structure holding all \r
+ *                      relevant data associated with the target timer hardware\r
+ *                                             instance. This pointer is used to identify the target\r
+ *                                             CoreTimer hardware instance.\r
+ */\r
+void\r
+TMR_clear_int\r
+(\r
+    timer_instance_t * this_timer\r
+);\r
+\r
+/***************************************************************************//**\r
+ * The TMR_current_value() function returns the current value of the counter.\r
+ *\r
+ * @param this_timer    Pointer to a timer_instance_t structure holding all \r
+ *                      relevant data associated with the target timer hardware\r
+ *                                             instance. This pointer is used to identify the target\r
+ *                                             CoreTimer hardware instance.\r
+ *\r
+ * @return              Returns the current value of the timer counter value.\r
+ */\r
+uint32_t\r
+TMR_current_value\r
+(\r
+    timer_instance_t * this_timer\r
+);\r
+\r
+/***************************************************************************//**\r
+ * The TMR_reload() function is used in one-shot mode. It reloads the timer\r
+ * counter with the values passed as parameter. This will result in an interrupt\r
+ * being generated when the timer counter reaches 0 if interrupt is enabled.\r
+ * \r
+ * @param this_timer    Pointer to a timer_instance_t structure holding all \r
+ *                      relevant data associated with the target timer hardware\r
+ *                                             instance. This pointer is used to identify the target\r
+ *                                             CoreTimer hardware instance.\r
+ * @param load_value   This parameter sets the value from which the CoreTimer\r
+ *                                             counter will decrement. \r
+ */\r
+void TMR_reload\r
+(\r
+       timer_instance_t * this_timer,\r
+       uint32_t load_value\r
+);\r
+       \r
+#endif /* CORE_TIMER_H_ */\r
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 (file)
index 0000000..5d7c67d
--- /dev/null
@@ -0,0 +1,109 @@
+/*******************************************************************************\r
+ * (c) Copyright 2007-2015 Microsemi SoC Products Group. All rights reserved.\r
+ * \r
+ * SVN $Revision: 7967 $\r
+ * SVN $Date: 2015-10-09 18:48:26 +0530 (Fri, 09 Oct 2015) $\r
+ */\r
+\r
+#ifndef __CORE_TIMER_REGISTERS\r
+#define __CORE_TIMER_REGISTERS 1\r
+\r
+/*------------------------------------------------------------------------------\r
+ * TimerLoad register details\r
+ */\r
+#define TimerLoad_REG_OFFSET   0x00\r
+\r
+/*\r
+ * LoadValue bits.\r
+ */\r
+#define LoadValue_OFFSET   0x00\r
+#define LoadValue_MASK     0xFFFFFFFF\r
+#define LoadValue_SHIFT    0\r
+\r
+/*------------------------------------------------------------------------------\r
+ * TimerValue register details\r
+ */\r
+#define TimerValue_REG_OFFSET  0x04\r
+\r
+/*\r
+ * CurrentValue bits.\r
+ */\r
+#define CurrentValue_OFFSET   0x04\r
+#define CurrentValue_MASK     0xFFFFFFFF\r
+#define CurrentValue_SHIFT    0\r
+\r
+/*------------------------------------------------------------------------------\r
+ * TimerControl register details\r
+ */\r
+#define TimerControl_REG_OFFSET        0x08\r
+\r
+/*\r
+ * TimerEnable bits.\r
+ */\r
+#define TimerEnable_OFFSET   0x08\r
+#define TimerEnable_MASK     0x00000001\r
+#define TimerEnable_SHIFT    0\r
+\r
+/*\r
+ * InterruptEnable bits.\r
+ */\r
+#define InterruptEnable_OFFSET   0x08\r
+#define InterruptEnable_MASK     0x00000002\r
+#define InterruptEnable_SHIFT    1\r
+\r
+/*\r
+ * TimerMode bits.\r
+ */\r
+#define TimerMode_OFFSET   0x08\r
+#define TimerMode_MASK     0x00000004\r
+#define TimerMode_SHIFT    2\r
+\r
+/*------------------------------------------------------------------------------\r
+ * TimerPrescale register details\r
+ */\r
+#define TimerPrescale_REG_OFFSET       0x0C\r
+\r
+/*\r
+ * Prescale bits.\r
+ */\r
+#define Prescale_OFFSET   0x0C\r
+#define Prescale_MASK     0x0000000F\r
+#define Prescale_SHIFT    0\r
+\r
+/*------------------------------------------------------------------------------\r
+ * TimerIntClr register details\r
+ */\r
+#define TimerIntClr_REG_OFFSET 0x10\r
+\r
+/*\r
+ * TimerIntClr bits.\r
+ */\r
+#define TimerIntClr_OFFSET   0x10\r
+#define TimerIntClr_MASK     0xFFFFFFFF\r
+#define TimerIntClr_SHIFT    0\r
+\r
+/*------------------------------------------------------------------------------\r
+ * TimerRIS register details\r
+ */\r
+#define TimerRIS_REG_OFFSET    0x14\r
+\r
+/*\r
+ * RawTimerInterrupt bits.\r
+ */\r
+#define RawTimerInterrupt_OFFSET   0x14\r
+#define RawTimerInterrupt_MASK     0x00000001\r
+#define RawTimerInterrupt_SHIFT    0\r
+\r
+/*------------------------------------------------------------------------------\r
+ * TimerMIS register details\r
+ */\r
+#define TimerMIS_REG_OFFSET    0x18\r
+\r
+/*\r
+ * TimerInterrupt bits.\r
+ */\r
+#define TimerInterrupt_OFFSET   0x18\r
+#define TimerInterrupt_MASK     0x00000001\r
+#define TimerInterrupt_SHIFT    0\r
+\r
+#endif /* __CORE_TIMER_REGISTERS */\r
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 (file)
index 0000000..b4f40dc
--- /dev/null
@@ -0,0 +1,296 @@
+/*******************************************************************************\r
+ * (c) Copyright 2007-2017 Microsemi SoC Products Group. All rights reserved.\r
+ * \r
+ * CoreUARTapb driver implementation. See file "core_uart_apb.h" for a\r
+ * description of the functions implemented in this file.\r
+ * \r
+ * SVN $Revision: 9082 $\r
+ * SVN $Date: 2017-04-28 11:51:36 +0530 (Fri, 28 Apr 2017) $\r
+ */\r
+#include "hal.h"\r
+#include "coreuartapb_regs.h"\r
+#include "core_uart_apb.h"\r
+#include "hal_assert.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+#define NULL_INSTANCE ( ( UART_instance_t* ) 0 )\r
+#define NULL_BUFFER   ( ( uint8_t* ) 0 )\r
+\r
+#define MAX_LINE_CONFIG     ( ( uint8_t )( DATA_8_BITS | ODD_PARITY ) )\r
+#define MAX_BAUD_VALUE      ( ( uint16_t )( 0x1FFF ) )\r
+#define STATUS_ERROR_MASK   ( ( uint8_t )( STATUS_PARITYERR_MASK | \\r
+                                           STATUS_OVERFLOW_MASK  | \\r
+                                           STATUS_FRAMERR_MASK ) )\r
+#define BAUDVALUE_LSB ( (uint16_t) (0x00FF) )\r
+#define BAUDVALUE_MSB ( (uint16_t) (0xFF00) )\r
+#define BAUDVALUE_SHIFT ( (uint8_t) (5) )\r
+\r
+#define STATUS_ERROR_OFFSET STATUS_PARITYERR_SHIFT \r
+\r
+/***************************************************************************//**\r
+ * UART_init()\r
+ * See "core_uart_apb.h" for details of how to use this function.\r
+ */\r
+void\r
+UART_init\r
+(\r
+    UART_instance_t * this_uart,\r
+    addr_t base_addr,\r
+    uint16_t baud_value,\r
+    uint8_t line_config\r
+)\r
+{\r
+    uint8_t rx_full;\r
+    \r
+    HAL_ASSERT( this_uart != NULL_INSTANCE )\r
+    HAL_ASSERT( line_config <= MAX_LINE_CONFIG )\r
+    HAL_ASSERT( baud_value <= MAX_BAUD_VALUE )\r
+\r
+    if( ( this_uart != NULL_INSTANCE ) &&\r
+        ( line_config <= MAX_LINE_CONFIG ) &&\r
+        ( baud_value <= MAX_BAUD_VALUE ) )\r
+    {\r
+        /*\r
+         * Store lower 8-bits of baud value in CTRL1.\r
+         */\r
+        HAL_set_8bit_reg( base_addr, CTRL1, (uint_fast8_t)(baud_value &\r
+                                                       BAUDVALUE_LSB ) );\r
+    \r
+        /*\r
+         * Extract higher 5-bits of baud value and store in higher 5-bits \r
+         * of CTRL2, along with line configuration in lower 3 three bits.\r
+         */\r
+        HAL_set_8bit_reg( base_addr, CTRL2, (uint_fast8_t)line_config | \r
+                                           (uint_fast8_t)((baud_value &\r
+                                   BAUDVALUE_MSB) >> BAUDVALUE_SHIFT ) );\r
+    \r
+        this_uart->base_address = base_addr;\r
+#ifndef NDEBUG\r
+        {\r
+            uint8_t  config;\r
+            uint8_t  temp;\r
+            uint16_t baud_val;\r
+            baud_val = HAL_get_8bit_reg( this_uart->base_address, CTRL1 );\r
+            config =  HAL_get_8bit_reg( this_uart->base_address, CTRL2 );\r
+            /*\r
+             * To resolve operator precedence between & and <<\r
+             */\r
+            temp =  ( config  &  (uint8_t)(CTRL2_BAUDVALUE_MASK ) );\r
+            baud_val |= (uint16_t)( (uint16_t)(temp) << BAUDVALUE_SHIFT );\r
+            config &= (uint8_t)(~CTRL2_BAUDVALUE_MASK);\r
+            HAL_ASSERT( baud_val == baud_value );\r
+            HAL_ASSERT( config == line_config );\r
+        }        \r
+#endif\r
+        \r
+        /*\r
+         * Flush the receive FIFO of data that may have been received before the\r
+         * driver was initialized.\r
+         */\r
+        rx_full = HAL_get_8bit_reg( this_uart->base_address, STATUS ) &\r
+                                                    STATUS_RXFULL_MASK;\r
+        while ( rx_full )\r
+        {\r
+            HAL_get_8bit_reg( this_uart->base_address, RXDATA );\r
+            rx_full = HAL_get_8bit_reg( this_uart->base_address, STATUS ) &\r
+                                                        STATUS_RXFULL_MASK;\r
+        }\r
+\r
+        /*\r
+         * Clear status of the UART instance.\r
+         */\r
+        this_uart->status = (uint8_t)0;\r
+    }\r
+}\r
+\r
+/***************************************************************************//**\r
+ * UART_send()\r
+ * See "core_uart_apb.h" for details of how to use this function.\r
+ */\r
+void\r
+UART_send\r
+(\r
+    UART_instance_t * this_uart,\r
+    const uint8_t * tx_buffer,\r
+    size_t tx_size\r
+)\r
+{\r
+    size_t char_idx;\r
+    uint8_t tx_ready;\r
+\r
+    HAL_ASSERT( this_uart != NULL_INSTANCE )\r
+    HAL_ASSERT( tx_buffer != NULL_BUFFER )\r
+    HAL_ASSERT( tx_size > 0 )\r
+      \r
+    if( (this_uart != NULL_INSTANCE) &&\r
+        (tx_buffer != NULL_BUFFER)   &&\r
+        (tx_size > (size_t)0) )\r
+    {\r
+        for ( char_idx = (size_t)0; char_idx < tx_size; char_idx++ )\r
+        {\r
+            /* Wait for UART to become ready to transmit. */\r
+            do {\r
+                tx_ready = HAL_get_8bit_reg( this_uart->base_address, STATUS ) &\r
+                                                              STATUS_TXRDY_MASK;\r
+            } while ( !tx_ready );\r
+            /* Send next character in the buffer. */\r
+            HAL_set_8bit_reg( this_uart->base_address, TXDATA,\r
+                              (uint_fast8_t)tx_buffer[char_idx] );\r
+        }\r
+    }\r
+}\r
+\r
+/***************************************************************************//**\r
+ * UART_fill_tx_fifo()\r
+ * See "core_uart_apb.h" for details of how to use this function.\r
+ */\r
+size_t\r
+UART_fill_tx_fifo\r
+(\r
+    UART_instance_t * this_uart,\r
+    const uint8_t * tx_buffer,\r
+    size_t tx_size\r
+)\r
+{\r
+    uint8_t tx_ready;\r
+    size_t size_sent = 0u;\r
+    \r
+    HAL_ASSERT( this_uart != NULL_INSTANCE )\r
+    HAL_ASSERT( tx_buffer != NULL_BUFFER )\r
+    HAL_ASSERT( tx_size > 0 )\r
+      \r
+    /* Fill the UART's Tx FIFO until the FIFO is full or the complete input \r
+     * buffer has been written. */\r
+    if( (this_uart != NULL_INSTANCE) &&\r
+        (tx_buffer != NULL_BUFFER)   &&\r
+        (tx_size > 0u) )\r
+    {\r
+        tx_ready = HAL_get_8bit_reg( this_uart->base_address, STATUS ) &\r
+                                                      STATUS_TXRDY_MASK;\r
+        if ( tx_ready )\r
+        {\r
+            do {\r
+                HAL_set_8bit_reg( this_uart->base_address, TXDATA,\r
+                                  (uint_fast8_t)tx_buffer[size_sent] );\r
+                size_sent++;\r
+                tx_ready = HAL_get_8bit_reg( this_uart->base_address, STATUS ) &\r
+                                                              STATUS_TXRDY_MASK;\r
+            } while ( (tx_ready) && ( size_sent < tx_size ) );\r
+        }\r
+    }    \r
+    return size_sent;\r
+}\r
+\r
+/***************************************************************************//**\r
+ * UART_get_rx()\r
+ * See "core_uart_apb.h" for details of how to use this function.\r
+ */\r
+size_t\r
+UART_get_rx\r
+(\r
+    UART_instance_t * this_uart,\r
+    uint8_t * rx_buffer,\r
+    size_t buff_size\r
+)\r
+{\r
+    uint8_t new_status;\r
+    uint8_t rx_full;\r
+    size_t rx_idx = 0u;\r
+    \r
+    HAL_ASSERT( this_uart != NULL_INSTANCE )\r
+    HAL_ASSERT( rx_buffer != NULL_BUFFER )\r
+    HAL_ASSERT( buff_size > 0 )\r
+      \r
+    if( (this_uart != NULL_INSTANCE) &&\r
+        (rx_buffer != NULL_BUFFER)   &&\r
+        (buff_size > 0u) )\r
+    {\r
+        rx_idx = 0u;\r
+        new_status = HAL_get_8bit_reg( this_uart->base_address, STATUS );\r
+        this_uart->status |= new_status;\r
+        rx_full = new_status & STATUS_RXFULL_MASK;\r
+        while ( ( rx_full ) && ( rx_idx < buff_size ) )\r
+        {\r
+            rx_buffer[rx_idx] = HAL_get_8bit_reg( this_uart->base_address,\r
+                                                  RXDATA );\r
+            rx_idx++;\r
+            new_status = HAL_get_8bit_reg( this_uart->base_address, STATUS );\r
+            this_uart->status |= new_status;\r
+            rx_full = new_status & STATUS_RXFULL_MASK;\r
+        }\r
+    }\r
+    return rx_idx;\r
+}\r
+\r
+/***************************************************************************//**\r
+ * UART_polled_tx_string()\r
+ * See "core_uart_apb.h" for details of how to use this function.\r
+ */\r
+void \r
+UART_polled_tx_string\r
+( \r
+    UART_instance_t * this_uart, \r
+    const uint8_t * p_sz_string\r
+)\r
+{\r
+    uint32_t char_idx;\r
+    uint8_t tx_ready;\r
+\r
+    HAL_ASSERT( this_uart != NULL_INSTANCE )\r
+    HAL_ASSERT( p_sz_string != NULL_BUFFER )\r
+    \r
+    if( ( this_uart != NULL_INSTANCE ) && ( p_sz_string != NULL_BUFFER ) )\r
+    {\r
+        char_idx = 0U;\r
+        while( 0U != p_sz_string[char_idx] )\r
+        {\r
+            /* Wait for UART to become ready to transmit. */\r
+            do {\r
+                tx_ready = HAL_get_8bit_reg( this_uart->base_address, STATUS ) &\r
+                                                              STATUS_TXRDY_MASK;\r
+            } while ( !tx_ready );\r
+            /* Send next character in the buffer. */\r
+            HAL_set_8bit_reg( this_uart->base_address, TXDATA,\r
+                              (uint_fast8_t)p_sz_string[char_idx] );\r
+            char_idx++;\r
+        }\r
+    }\r
+}\r
+\r
+/***************************************************************************//**\r
+ * UART_get_rx_status()\r
+ * See "core_uart_apb.h" for details of how to use this function.\r
+ */\r
+uint8_t\r
+UART_get_rx_status\r
+(\r
+    UART_instance_t * this_uart\r
+)\r
+{\r
+    uint8_t status = UART_APB_INVALID_PARAM;\r
+\r
+    HAL_ASSERT( this_uart != NULL_INSTANCE )\r
+    /*\r
+     * Extract UART error status and place in lower bits of "status".\r
+     * Bit 0 - Parity error status\r
+     * Bit 1 - Overflow error status\r
+     * Bit 2 - Frame error status\r
+     */\r
+    if( this_uart != NULL_INSTANCE )\r
+    {\r
+        status = ( ( this_uart->status & STATUS_ERROR_MASK ) >> \r
+                                          STATUS_ERROR_OFFSET );\r
+        /*\r
+         * Clear the sticky status for this instance.\r
+         */\r
+        this_uart->status = (uint8_t)0;\r
+    }\r
+    return status;\r
+}\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
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 (file)
index 0000000..680b68d
--- /dev/null
@@ -0,0 +1,407 @@
+/*******************************************************************************\r
+ * (c) Copyright 2007-2017 Microsemi SoC Products Group. All rights reserved.\r
+ * \r
+ * This file contains the application programming interface for the CoreUARTapb\r
+ * bare metal driver.\r
+ * \r
+ * SVN $Revision: 9082 $\r
+ * SVN $Date: 2017-04-28 11:51:36 +0530 (Fri, 28 Apr 2017) $\r
+ */\r
+/*=========================================================================*//**\r
+  @mainpage CoreUARTapb Bare Metal Driver.\r
+\r
+  @section intro_sec Introduction\r
+  CoreUARTapb is an implementation of the Universal Asynchronous \r
+  Receiver/Transmitter aimed at a minimal FPGA tile usage within an Microsemi\r
+  FPGA. The CoreUARTapb bare metal software driver is designed for use in \r
+  systems with no operating system.\r
+\r
+  The CoreUARTapb driver provides functions for basic polled transmitting and \r
+  receiving operations. It also provides functions allowing use of the \r
+  CoreUARTapb in interrupt-driven mode, but leaves the management of interrupts \r
+  to the calling application, as interrupt enabling and disabling cannot be \r
+  controlled through the CoreUARTapb registers. The CoreUARTapb driver is \r
+  provided as C source code.\r
+\r
+  @section driver_configuration Driver Configuration\r
+  Your application software should configure the CoreUARTapb driver, through \r
+  calls to the UART_init() function for each CoreUARTapb instance in the \r
+  hardware design. The configuration parameters include the CoreUARTapb \r
+  hardware instance base address and other runtime parameters, such as baud \r
+  rate, bit width, and parity. No CoreUARTapb hardware configuration parameters \r
+  are needed by the driver, apart from the CoreUARTapb hardware instance base \r
+  address. Hence, no additional configuration files are required to use the driver.\r
+\r
+  A CoreUARTapb hardware instance can be generated with fixed baud value, \r
+  character size and parity configuration settings as part of the hardware flow. \r
+  The baud_value and line_config parameter values passed to the UART_init() \r
+  function will not have any effect if fixed values were selected for the \r
+  baud value, character size and parity in the hardware configuration of \r
+  CoreUARTapb. When fixed values are selected for these hardware configuration \r
+  parameters, the driver cannot overwrite the fixed values in the CoreUARTapb \r
+  control registers, CTRL1 and CTRL2.\r
+\r
+  @section theory_op Theory of Operation\r
+  The CoreUARTapb software driver is designed to allow the control of multiple \r
+  instances of CoreUARTapb. Each instance of CoreUARTapb in the hardware design \r
+  is associated with a single instance of the UART_instance_t structure in the \r
+  software. You need to allocate memory for one unique UART_instance_t  \r
+  structure instance for each CoreUARTapb hardware instance. The contents of \r
+  these data structures are initialized during calls to function UART_init(). \r
+  A pointer to the structure is passed to subsequent driver functions in order\r
+  to identify the CoreUARTapb hardware instance you wish to perform the \r
+  requested operation on.\r
+  \r
+  Note: Do not attempt to directly manipulate the content of UART_instance_t \r
+  structures. This structure is only intended to be modified by the driver \r
+  function.\r
+\r
+  The driver can be used to transmit and receive data once initialized. \r
+  Transmit can be performed using the UART_send() function. This function\r
+  is blocking, meaning that it will only return once the data passed to \r
+  the function has been sent to the CoreUARTapb hardware. Data received \r
+  by the CoreUARTapb hardware can be read by the user application using \r
+  the UART_get_rx() function.\r
+\r
+  The function UART_fill_tx_fifo() is also provided to be used as part of \r
+  interrupt-driven transmit. This function fills the CoreUARTapb hardware \r
+  transmit FIFO with the content of a data buffer passed as a parameter before \r
+  returning. The control of the interrupts must be implemented outside the \r
+  driver as the CoreUARTapb hardware does not provide the ability to enable \r
+  or disable its interrupt sources.\r
+\r
+  The function UART_polled_tx_string() is provided to transmit a NULL \r
+  terminated string in polled mode. This function is blocking, meaning that it \r
+  will only return once the data passed to the function has been sent to the \r
+  CoreUARTapb hardware.\r
+\r
+  The function UART_get_rx_status() returns the error status of the CoreUARTapb\r
+  receiver. This can be used by applications to take appropriate action in case\r
+  of receiver errors.\r
+*//*=========================================================================*/\r
+#ifndef __CORE_UART_APB_H\r
+#define __CORE_UART_APB_H 1\r
+\r
+#include "cpu_types.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+/***************************************************************************//**\r
+ * Data bits length defines:\r
+ */\r
+#define DATA_7_BITS     0x00u\r
+#define DATA_8_BITS     0x01u\r
+\r
+/***************************************************************************//**\r
+ * Parity defines:\r
+ */\r
+#define NO_PARITY       0x00u\r
+#define EVEN_PARITY     0x02u\r
+#define ODD_PARITY      0x06u\r
+\r
+/***************************************************************************//**\r
+ * Error Status definitions:\r
+ */\r
+#define UART_APB_PARITY_ERROR    0x01u\r
+#define UART_APB_OVERFLOW_ERROR  0x02u\r
+#define UART_APB_FRAMING_ERROR   0x04u\r
+#define UART_APB_NO_ERROR        0x00u\r
+#define UART_APB_INVALID_PARAM   0xFFu\r
+\r
+/***************************************************************************//**\r
+ * UART_instance_t\r
+ * \r
+ * There should be one instance of this structure for each instance of CoreUARTapb\r
+ * in your system. This structure instance is used to identify the various UARTs\r
+ * in a system and should be passed as first parameter to UART functions to \r
+ * identify which UART should perform the requested operation. The 'status' \r
+ * element in the structure is used to provide sticky status information. \r
+ */\r
+typedef struct\r
+{\r
+    addr_t      base_address;\r
+    uint8_t     status;\r
+} UART_instance_t;\r
+\r
+/***************************************************************************//**\r
+ * The function UART_init() initializes the UART with the configuration passed \r
+ * as parameters. The configuration parameters are the baud_value used to \r
+ * generate the baud rate and the line configuration (bit length and parity).\r
+ *\r
+ * @param this_uart   The this_uart parameter is a pointer to a UART_instance_t\r
+ *                    structure which holds all data regarding this instance of\r
+ *                    the CoreUARTapb. This pointer will be used to identify \r
+ *                    the target CoreUARTapb hardware instance in subsequent \r
+ *                    calls to the CoreUARTapb functions.\r
+ * @param base_addr   The base_address parameter is the base address in the \r
+ *                    processor's memory map for the registers of the \r
+ *                    CoreUARTapb instance being initialized.\r
+ * @param baud_value  The baud_value parameter is used to select the baud rate \r
+ *                    for the UART. The baud value is calculated from the \r
+ *                    frequency of the system clock in hertz and the desired \r
+ *                    baud rate using the following equation: \r
+ *                    \r
+ *                    baud_value = (clock /(baud_rate * 16)) - 1.\r
+ * \r
+ *                    The baud_value parameter must be a value in the range 0 \r
+ *                    to 8191 (or 0x0000 to 0x1FFF).\r
+ * @param line_config This parameter is the line configuration specifying the \r
+ *                    bit length and parity settings. This is a logical OR of:\r
+ *                      - DATA_7_BITS\r
+ *                    - DATA_8_BITS\r
+ *                    - NO_PARITY\r
+ *                    - EVEN_PARITY\r
+ *                    - ODD_PARITY\r
+ *                    For example, 8 bits even parity would be specified as \r
+ *                    (DATA_8_BITS | EVEN_PARITY). \r
+ * @return            This function does not return a value.\r
+ * Example:\r
+ * @code\r
+ *   #define BAUD_VALUE_57600    25\r
+ *   \r
+ *   #define COREUARTAPB0_BASE_ADDR      0xC3000000UL\r
+ *   \r
+ *   UART_instance_t g_uart;\r
+ *   int main()\r
+ *   {\r
+ *      UART_init(&g_uart, COREUARTAPB0_BASE_ADDR, \r
+                  BAUD_VALUE_57600, (DATA_8_BITS | EVEN_PARITY));\r
+ *   }\r
+ * @endcode\r
+ */\r
+void\r
+UART_init\r
+(\r
+    UART_instance_t * this_uart,\r
+    addr_t base_addr,\r
+    uint16_t baud_value,\r
+    uint8_t line_config\r
+);\r
+\r
+/***************************************************************************//**\r
+ * The function UART_send() is used to transmit data. It transfers the contents\r
+ * of the transmitter data buffer, passed as a function parameter, into the \r
+ * UART's hardware transmitter FIFO. It returns when the full content of the \r
+ * transmitter data buffer has been transferred to the UART's transmitter FIFO. \r
+ *\r
+ * Note: you cannot assume that the data you are sending using this function has\r
+ * been received at the other end by the time this function returns. The actual\r
+ * transmit over the serial connection will still be taking place at the time of\r
+ * the function return. It is safe to release or reuse the memory used as the\r
+ * transmit buffer once this function returns.\r
+ *\r
+ * @param this_uart     The this_uart parameter is a pointer to a \r
+ *                      UART_instance_t structure which holds all data regarding \r
+ *                      this instance of the CoreUARTapbUART.\r
+ * @param tx_buffer     The tx_buffer parameter is a pointer to a buffer \r
+ *                      containing the data to be transmitted.\r
+ * @param tx_size       The tx_size parameter is the size, in bytes, of \r
+ *                      the data to be transmitted.\r
+ *\r
+ * @return              This function does not return a value.\r
+ *\r
+ * Example:\r
+ * @code\r
+ *   uint8_t testmsg1[] = {"\n\r\n\r\n\rUART_send() test message 1"};\r
+ *   UART_send(&g_uart,(const uint8_t *)&testmsg1,sizeof(testmsg1));\r
+ * @endcode\r
+ */\r
+void\r
+UART_send\r
+(\r
+    UART_instance_t * this_uart,\r
+    const uint8_t * tx_buffer,\r
+    size_t tx_size\r
+);\r
+\r
+/***************************************************************************//**\r
+ * The function UART_fill_tx_fifo() fills the UART's transmitter hardware FIFO \r
+ * with the data found in the transmitter buffer that is passed in as a \r
+ * function parameter. The function returns either when the FIFO is full or \r
+ * when the complete contents of the transmitter buffer have been copied into \r
+ * the FIFO. It returns the number of bytes copied into the UART's transmitter\r
+ * hardware FIFO. This function is intended to be used as part of \r
+ * interrupt-driven transmission.\r
+ *\r
+ * Note:    You cannot assume that the data you transmit using this function has \r
+ *          been received at the other end by the time this function returns. \r
+ *          The actual transmission over the serial connection will still be \r
+ *          taking place at the time of the function return. \r
+ *\r
+ * @param this_uart     The this_uart parameter is a pointer to a UART_instance_t\r
+ *                      structure which holds all data regarding this instance of\r
+ *                      the UART.\r
+ * @param tx_buffer     The tx_buffer parameter is a pointer to a buffer \r
+ *                      containing the data to be transmitted.\r
+ * @param tx_size       The tx_size parameter is the size in bytes, of the data \r
+ *                      to be transmitted.\r
+ * @return              This function returns the number of bytes copied \r
+ *                      into the UART's transmitter hardware FIFO. \r
+ *\r
+ * Example:\r
+ * @code\r
+ *   void send_using_interrupt\r
+ *   (\r
+ *       uint8_t * pbuff,\r
+ *       size_t tx_size\r
+ *   )\r
+ *   {\r
+ *       size_t size_in_fifo;\r
+ *       size_in_fifo = UART_fill_tx_fifo( &g_uart, pbuff, tx_size );\r
+ *   }\r
+ * @endcode\r
+ */\r
+size_t\r
+UART_fill_tx_fifo\r
+(\r
+    UART_instance_t * this_uart,\r
+    const uint8_t * tx_buffer,\r
+    size_t tx_size\r
+);\r
+\r
+/***************************************************************************//**\r
+ * The function UART_get_rx() reads the content of the UART's receiver hardware \r
+ * FIFO and stores it in the receiver buffer that is passed in as a function \r
+ * parameter. It copies either the full contents of the FIFO into the receiver \r
+ * buffer, or just enough data from the FIFO to fill the receiver buffer, \r
+ * dependent upon the size of the receiver buffer.  The size of the receiver \r
+ * buffer is passed in as a function parameter. UART_get_rx() returns the number\r
+ * of bytes copied into the receiver buffer. If no data was received at the time\r
+ * the function is called, the function returns 0.\r
+ *\r
+ * Note:    This function reads and accumulates the receiver status of the \r
+ *          CoreUARTapb instance before reading each byte from the receiver's \r
+ *          data register/FIFO. This allows the driver to maintain a sticky \r
+ *          record of any receiver errors that occur as the UART receives each \r
+ *          data byte; receiver errors would otherwise be lost after each read \r
+ *          from the receiver's data register. A call to the UART_get_rx_status()\r
+ *          function returns any receiver errors accumulated during the execution\r
+ *          of the UART_get_rx() function.\r
+ * Note:    When FIFO mode is disabled in the CoreUARTapb hardware configuration,\r
+ *          the driver accumulates a sticky record of any parity errors, framing \r
+ *          errors or overflow errors. When FIFO mode is enabled, the driver \r
+ *          accumulates a sticky record of overflow errors only; in this case \r
+ *          interrupts must be used to handle parity errors or framing errors.\r
+ *\r
+ * @param this_uart     The this_uart parameter is a pointer to a UART_instance_t \r
+ *                      structure which holds all data regarding this instance of \r
+ *                      the UART.\r
+ * @param rx_buffer     The rx_buffer parameter is a pointer to a buffer where the \r
+ *                      received data will be copied.\r
+ * @param buff_size     The buff_size parameter is the size of the receive buffer \r
+ *                      in bytes.\r
+ * @return              This function returns the number of bytes copied into the \r
+ *                      receive buffer.\r
+ *\r
+ * Example:\r
+ * @code\r
+ *   #define MAX_RX_DATA_SIZE    256\r
+ *   \r
+ *   uint8_t rx_data[MAX_RX_DATA_SIZE];\r
+ *   uint8_t rx_size = 0;\r
+ *           \r
+ *   rx_size = UART_get_rx( &g_uart, rx_data, sizeof(rx_data) );\r
+ * @endcode\r
+ */\r
+size_t\r
+UART_get_rx\r
+(\r
+    UART_instance_t * this_uart,\r
+    uint8_t * rx_buffer,\r
+    size_t buff_size\r
+);\r
+\r
+/***************************************************************************//**\r
+ * The function UART_polled_tx_string() is used to transmit a NULL ('\0') \r
+ * terminated string. Internally, it polls for the transmit ready status and\r
+ * transfers the text starting at the address pointed to by p_sz_string into\r
+ * the UART's hardware transmitter FIFO. It is a blocking function and returns\r
+ * only when the complete string has been transferred to the UART's transmit \r
+ * FIFO.\r
+ *\r
+ * Note:    You cannot assume that the data you transmit using this function \r
+ *          has been received at the other end by the time this function \r
+ *          returns. The actual transmission over the serial connection will\r
+ *          still be taking place at the time of the function return.\r
+ *\r
+ * @param this_uart     The this_uart parameter is a pointer to a \r
+ *                      UART_instance_t structure which holds\r
+ *                      all data regarding this instance of the UART.\r
+ * @param p_sz_string   The p_sz_string parameter is a pointer to a buffer\r
+ *                      containing the NULL ('\0') terminated string to be \r
+ *                      transmitted.\r
+ * @return              This function does not return a value.\r
+ *\r
+ * Example:\r
+ * @code\r
+ *   uint8_t testmsg1[] = {"\r\n\r\nUART_polled_tx_string() test message 1\0"};\r
+ *   UART_polled_tx_string(&g_uart,(const uint8_t *)&testmsg1);\r
+ * @endcode\r
+ */\r
+void \r
+UART_polled_tx_string\r
+( \r
+    UART_instance_t * this_uart, \r
+    const uint8_t * p_sz_string\r
+);\r
+\r
+/***************************************************************************//**\r
+ * The UART_get_rx_status() function returns the receiver error status of the \r
+ * CoreUARTapb instance. It reads both the current error status of the receiver\r
+ * and the accumulated error status from preceding calls to the UART_get_rx() \r
+ * function and combines them using a bitwise OR. It returns the cumulative \r
+ * parity, framing and overflow error status of the receiver, since the \r
+ * previous call to UART_get_rx_status(), as an 8-bit encoded value.\r
+ *\r
+ * Note:    The UART_get_rx() function reads and accumulates the receiver status \r
+ *          of the CoreUARTapb instance before reading each byte from the \r
+ *          receiver's data register/FIFO. The driver maintains a sticky record \r
+ *          of the cumulative error status, which persists after the \r
+ *          UART_get_rx() function returns. The UART_get_rx_status() function \r
+ *          clears this accumulated record of receiver errors before returning.\r
+ * \r
+ * @param this_uart     The this_uart parameter is a pointer to a UART_instance_t\r
+ *                      structure which holds all data regarding this instance \r
+ *                      of the UART.\r
+ * @return              This function returns the UART receiver error status as \r
+ *                      an 8-bit encoded value. The returned value is 0 if no \r
+ *                      receiver errors occurred. The driver provides a set of \r
+ *                      bit mask constants which should be compared with and/or\r
+ *                      used to mask the returned value to determine the \r
+ *                      receiver error status. \r
+ *                      When the return value is compared to the following bit \r
+ *                      masks, a non-zero result indicates that the \r
+ *                      corresponding error occurred:\r
+ *                      UART_APB_PARITY_ERROR    (bit mask = 0x01)\r
+ *                      UART_APB_OVERFLOW_ERROR  (bit mask = 0x02)\r
+ *                      UART_APB_FRAMING_ERROR   (bit mask = 0x04)\r
+ *                      When the return value is compared to the following bit \r
+ *                      mask, a non-zero result indicates that no error occurred:\r
+ *                      UART_APB_NO_ERROR        (0x00)\r
+ *\r
+ * Example:\r
+ * @code\r
+ *   UART_instance_t g_uart;\r
+ *   uint8_t rx_data[MAX_RX_DATA_SIZE];\r
+ *   uint8_t err_status;\r
+ *   err_status = UART_get_err_status(&g_uart);\r
+ *   \r
+ *   if(UART_APB_NO_ERROR == err_status )\r
+ *   {\r
+ *        rx_size = UART_get_rx( &g_uart, rx_data, MAX_RX_DATA_SIZE );\r
+ *   }\r
+ * @endcode\r
+ */\r
+uint8_t\r
+UART_get_rx_status\r
+(\r
+    UART_instance_t * this_uart\r
+);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* __CORE_UART_APB_H */\r
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 (file)
index 0000000..e6cc8c1
--- /dev/null
@@ -0,0 +1,130 @@
+/*******************************************************************************\r
+ * (c) Copyright 2007-2017 Microsemi SoC Products Group. All rights reserved.\r
+ * \r
+ * SVN $Revision: 9082 $\r
+ * SVN $Date: 2017-04-28 11:51:36 +0530 (Fri, 28 Apr 2017) $\r
+ */\r
+\r
+#ifndef __CORE_UART_APB_REGISTERS\r
+#define __CORE_UART_APB_REGISTERS   1\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+/*------------------------------------------------------------------------------\r
+ * TxData register details\r
+ */\r
+#define TXDATA_REG_OFFSET   0x0u\r
+\r
+/*\r
+ * TxData bits.\r
+ */\r
+#define TXDATA_OFFSET   0x0u\r
+#define TXDATA_MASK     0xFFu\r
+#define TXDATA_SHIFT    0u\r
+\r
+/*------------------------------------------------------------------------------\r
+ * RxData register details\r
+ */\r
+#define RXDATA_REG_OFFSET   0x4u\r
+\r
+/*\r
+ * RxData bits.\r
+ */\r
+#define RXDATA_OFFSET   0x4u\r
+#define RXDATA_MASK     0xFFu\r
+#define RXDATA_SHIFT    0u\r
+\r
+/*------------------------------------------------------------------------------\r
+ * ControReg1 register details\r
+ */\r
+#define CTRL1_REG_OFFSET        0x8u\r
+\r
+/*\r
+ * Baud value (Lower 8-bits)\r
+ */\r
+#define CTRL1_BAUDVALUE_OFFSET   0x8u\r
+#define CTRL1_BAUDVALUE_MASK     0xFFu\r
+#define CTRL1_BAUDVALUE_SHIFT    0u\r
+\r
+/*------------------------------------------------------------------------------\r
+ * ControReg2 register details\r
+ */\r
+#define CTRL2_REG_OFFSET          0xCu\r
+\r
+/*\r
+ * Bit length\r
+ */\r
+#define CTRL2_BIT_LENGTH_OFFSET   0xCu\r
+#define CTRL2_BIT_LENGTH_MASK     0x01u\r
+#define CTRL2_BIT_LENGTH_SHIFT    0u\r
+\r
+/*\r
+ * Parity enable.\r
+ */\r
+#define CTRL2_PARITY_EN_OFFSET    0xCu\r
+#define CTRL2_PARITY_EN_MASK      0x02u\r
+#define CTRL2_PARITY_EN_SHIFT     1u\r
+\r
+/*\r
+ * Odd/even parity selection.\r
+ */\r
+#define CTRL2_ODD_EVEN_OFFSET     0xCu\r
+#define CTRL2_ODD_EVEN_MASK       0x04u\r
+#define CTRL2_ODD_EVEN_SHIFT      2u\r
+\r
+/*\r
+ *  Baud value (Higher 5-bits)\r
+ */\r
+#define CTRL2_BAUDVALUE_OFFSET    0xCu\r
+#define CTRL2_BAUDVALUE_MASK      0xF8u\r
+#define CTRL2_BAUDVALUE_SHIFT     3u\r
+\r
+/*------------------------------------------------------------------------------\r
+ * StatusReg register details\r
+ */\r
+#define StatusReg_REG_OFFSET    0x10u\r
+\r
+#define STATUS_REG_OFFSET       0x10u\r
+\r
+/*\r
+ * Transmit ready.\r
+ */\r
+#define STATUS_TXRDY_OFFSET   0x10u\r
+#define STATUS_TXRDY_MASK     0x01u\r
+#define STATUS_TXRDY_SHIFT    0u\r
+\r
+/*\r
+ * Receive full.\r
+ */\r
+#define STATUS_RXFULL_OFFSET   0x10u\r
+#define STATUS_RXFULL_MASK     0x02u\r
+#define STATUS_RXFULL_SHIFT    1u\r
+\r
+/*\r
+ * Parity error.\r
+ */\r
+#define STATUS_PARITYERR_OFFSET   0x10u\r
+#define STATUS_PARITYERR_MASK     0x04u\r
+#define STATUS_PARITYERR_SHIFT    2u\r
+\r
+/*\r
+ * Overflow.\r
+ */\r
+#define STATUS_OVERFLOW_OFFSET   0x10u\r
+#define STATUS_OVERFLOW_MASK     0x08u\r
+#define STATUS_OVERFLOW_SHIFT    3u\r
+\r
+/*\r
+ * Frame Error.\r
+ */\r
+#define STATUS_FRAMERR_OFFSET   0x10u\r
+#define STATUS_FRAMERR_MASK     0x10u\r
+#define STATUS_FRAMERR_SHIFT    4u\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* __CORE_UART_APB_REGISTERS */\r
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 (file)
index 0000000..1beae8c
--- /dev/null
@@ -0,0 +1,31 @@
+/*******************************************************************************\r
+ * (c) Copyright 2007-2018 Microsemi SoC Products Group. All rights reserved.\r
+ * \r
+ * SVN $Revision: 9661 $\r
+ * SVN $Date: 2018-01-15 16:13:33 +0530 (Mon, 15 Jan 2018) $\r
+ */\r
+#ifndef __CPU_TYPES_H\r
+#define __CPU_TYPES_H   1\r
+\r
+#include <stdint.h>\r
+\r
+/*------------------------------------------------------------------------------\r
+ */\r
+typedef unsigned int size_t;\r
+\r
+/*------------------------------------------------------------------------------\r
+ * addr_t: address type.\r
+ * Used to specify the address of peripherals present in the processor's memory\r
+ * map.\r
+ */\r
+typedef unsigned int addr_t;\r
+\r
+/*------------------------------------------------------------------------------\r
+ * psr_t: processor state register.\r
+ * Used by HAL_disable_interrupts() and HAL_restore_interrupts() to store the\r
+ * processor's state between disabling and restoring interrupts.\r
+ */\r
+typedef unsigned int psr_t;\r
+\r
+#endif  /* __CPU_TYPES_H */\r
+\r
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 (file)
index 0000000..5b82ed0
--- /dev/null
@@ -0,0 +1,207 @@
+/***************************************************************************//**\r
+ * (c) Copyright 2007-2018 Microsemi SoC Products Group. All rights reserved.\r
+ * \r
+ * Hardware abstraction layer functions.\r
+ * \r
+ * SVN $Revision: 9661 $\r
+ * SVN $Date: 2018-01-15 16:13:33 +0530 (Mon, 15 Jan 2018) $\r
+ */\r
+#ifndef HAL_H_\r
+#define HAL_H_\r
+\r
+#include "cpu_types.h"\r
+#include "hw_reg_access.h"\r
+\r
+/***************************************************************************//**\r
+ * Enable all interrupts at the processor level.\r
+ */\r
+void HAL_enable_interrupts( void );\r
+\r
+/***************************************************************************//**\r
+ * Disable all interrupts at the processor core level.\r
+ * Return the interrupts enable state before disabling occured so that it can \r
+ * later be restored. \r
+ */\r
+psr_t HAL_disable_interrupts( void );\r
+\r
+/***************************************************************************//**\r
+ * Restore the interrupts enable state at the processor core level.\r
+ * This function is normally passed the value returned from a previous call to\r
+ * HAL_disable_interrupts(). \r
+ */\r
+void HAL_restore_interrupts( psr_t saved_psr );\r
+\r
+/***************************************************************************//**\r
+ */\r
+#define FIELD_OFFSET(FIELD_NAME)  (FIELD_NAME##_OFFSET)\r
+#define FIELD_SHIFT(FIELD_NAME)   (FIELD_NAME##_SHIFT)\r
+#define FIELD_MASK(FIELD_NAME)    (FIELD_NAME##_MASK)\r
+\r
+/***************************************************************************//**\r
+ * The macro HAL_set_32bit_reg() allows writing a 32 bits wide register.\r
+ *\r
+ * BASE_ADDR:   A variable of type addr_t specifying the base address of the\r
+ *              peripheral containing the register.\r
+ * REG_NAME:    A string identifying the register to write. These strings are\r
+ *              specified in a header file associated with the peripheral.\r
+ * VALUE:       A variable of type uint32_t containing the value to write.\r
+ */\r
+#define HAL_set_32bit_reg(BASE_ADDR, REG_NAME, VALUE) \\r
+          (HW_set_32bit_reg( ((BASE_ADDR) + (REG_NAME##_REG_OFFSET)), (VALUE) ))\r
+\r
+/***************************************************************************//**\r
+ * The macro HAL_get_32bit_reg() is used to read the value  of a 32 bits wide\r
+ * register.\r
+ * \r
+ * BASE_ADDR:   A variable of type addr_t specifying the base address of the\r
+ *              peripheral containing the register.\r
+ * REG_NAME:    A string identifying the register to read. These strings are\r
+ *              specified in a header file associated with the peripheral.\r
+ * RETURN:      This function-like macro returns a uint32_t value.\r
+ */\r
+#define HAL_get_32bit_reg(BASE_ADDR, REG_NAME) \\r
+          (HW_get_32bit_reg( ((BASE_ADDR) + (REG_NAME##_REG_OFFSET)) ))\r
+\r
+/***************************************************************************//**\r
+ * The macro HAL_set_32bit_reg_field() is used to write a field within a\r
+ * 32 bits wide register. The field written can be one or more bits.\r
+ * \r
+ * BASE_ADDR:   A variable of type addr_t specifying the base address of the\r
+ *              peripheral containing the register.\r
+ * FIELD_NAME:  A string identifying the register field to write. These strings\r
+ *              are specified in a header file associated with the peripheral.\r
+ * VALUE:       A variable of type uint32_t containing the field value to write.\r
+ */\r
+#define HAL_set_32bit_reg_field(BASE_ADDR, FIELD_NAME, VALUE) \\r
+            (HW_set_32bit_reg_field(\\r
+                (BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\\r
+                FIELD_SHIFT(FIELD_NAME),\\r
+                FIELD_MASK(FIELD_NAME),\\r
+                (VALUE)))\r
+  \r
+/***************************************************************************//**\r
+ * The macro HAL_get_32bit_reg_field() is used to read a register field from\r
+ * within a 32 bit wide peripheral register. The field can be one or more bits.\r
+ * \r
+ * BASE_ADDR:   A variable of type addr_t specifying the base address of the\r
+ *              peripheral containing the register.\r
+ * FIELD_NAME:  A string identifying the register field to write. These strings\r
+ *              are specified in a header file associated with the peripheral.\r
+ * RETURN:      This function-like macro returns a uint32_t value.\r
+ */\r
+#define HAL_get_32bit_reg_field(BASE_ADDR, FIELD_NAME) \\r
+            (HW_get_32bit_reg_field(\\r
+                (BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\\r
+                FIELD_SHIFT(FIELD_NAME),\\r
+                FIELD_MASK(FIELD_NAME)))\r
+  \r
+/***************************************************************************//**\r
+ * The macro HAL_set_16bit_reg() allows writing a 16 bits wide register.\r
+ *\r
+ * BASE_ADDR:   A variable of type addr_t specifying the base address of the\r
+ *              peripheral containing the register.\r
+ * REG_NAME:    A string identifying the register to write. These strings are\r
+ *              specified in a header file associated with the peripheral.\r
+ * VALUE:       A variable of type uint_fast16_t containing the value to write.\r
+ */\r
+#define HAL_set_16bit_reg(BASE_ADDR, REG_NAME, VALUE) \\r
+            (HW_set_16bit_reg( ((BASE_ADDR) + (REG_NAME##_REG_OFFSET)), (VALUE) ))\r
+\r
+/***************************************************************************//**\r
+ * The macro HAL_get_16bit_reg() is used to read the value  of a 16 bits wide\r
+ * register.\r
+ * \r
+ * BASE_ADDR:   A variable of type addr_t specifying the base address of the\r
+ *              peripheral containing the register.\r
+ * REG_NAME:    A string identifying the register to read. These strings are\r
+ *              specified in a header file associated with the peripheral.\r
+ * RETURN:      This function-like macro returns a uint16_t value.\r
+ */\r
+#define HAL_get_16bit_reg(BASE_ADDR, REG_NAME) \\r
+            (HW_get_16bit_reg( (BASE_ADDR) + (REG_NAME##_REG_OFFSET) ))\r
+\r
+/***************************************************************************//**\r
+ * The macro HAL_set_16bit_reg_field() is used to write a field within a\r
+ * 16 bits wide register. The field written can be one or more bits.\r
+ * \r
+ * BASE_ADDR:   A variable of type addr_t specifying the base address of the\r
+ *              peripheral containing the register.\r
+ * FIELD_NAME:  A string identifying the register field to write. These strings\r
+ *              are specified in a header file associated with the peripheral.\r
+ * VALUE:       A variable of type uint16_t containing the field value to write.\r
+ */\r
+#define HAL_set_16bit_reg_field(BASE_ADDR, FIELD_NAME, VALUE) \\r
+            (HW_set_16bit_reg_field(\\r
+                (BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\\r
+                FIELD_SHIFT(FIELD_NAME),\\r
+                FIELD_MASK(FIELD_NAME),\\r
+                (VALUE)))  \r
+\r
+/***************************************************************************//**\r
+ * The macro HAL_get_16bit_reg_field() is used to read a register field from\r
+ * within a 8 bit wide peripheral register. The field can be one or more bits.\r
+ * \r
+ * BASE_ADDR:   A variable of type addr_t specifying the base address of the\r
+ *              peripheral containing the register.\r
+ * FIELD_NAME:  A string identifying the register field to write. These strings\r
+ *              are specified in a header file associated with the peripheral.\r
+ * RETURN:      This function-like macro returns a uint16_t value.\r
+ */\r
+#define HAL_get_16bit_reg_field(BASE_ADDR, FIELD_NAME) \\r
+            (HW_get_16bit_reg_field(\\r
+                (BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\\r
+                FIELD_SHIFT(FIELD_NAME),\\r
+                FIELD_MASK(FIELD_NAME)))\r
+\r
+/***************************************************************************//**\r
+ * The macro HAL_set_8bit_reg() allows writing a 8 bits wide register.\r
+ *\r
+ * BASE_ADDR:   A variable of type addr_t specifying the base address of the\r
+ *              peripheral containing the register.\r
+ * REG_NAME:    A string identifying the register to write. These strings are\r
+ *              specified in a header file associated with the peripheral.\r
+ * VALUE:       A variable of type uint_fast8_t containing the value to write.\r
+ */\r
+#define HAL_set_8bit_reg(BASE_ADDR, REG_NAME, VALUE) \\r
+          (HW_set_8bit_reg( ((BASE_ADDR) + (REG_NAME##_REG_OFFSET)), (VALUE) ))\r
+\r
+/***************************************************************************//**\r
+ * The macro HAL_get_8bit_reg() is used to read the value of a 8 bits wide\r
+ * register.\r
+ * \r
+ * BASE_ADDR:   A variable of type addr_t specifying the base address of the\r
+ *              peripheral containing the register.\r
+ * REG_NAME:    A string identifying the register to read. These strings are\r
+ *              specified in a header file associated with the peripheral.\r
+ * RETURN:      This function-like macro returns a uint8_t value.\r
+ */\r
+#define HAL_get_8bit_reg(BASE_ADDR, REG_NAME) \\r
+          (HW_get_8bit_reg( (BASE_ADDR) + (REG_NAME##_REG_OFFSET) ))\r
+\r
+/***************************************************************************//**\r
+ */\r
+#define HAL_set_8bit_reg_field(BASE_ADDR, FIELD_NAME, VALUE) \\r
+            (HW_set_8bit_reg_field(\\r
+                (BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\\r
+                FIELD_SHIFT(FIELD_NAME),\\r
+                FIELD_MASK(FIELD_NAME),\\r
+                (VALUE)))\r
+\r
+/***************************************************************************//**\r
+ * The macro HAL_get_8bit_reg_field() is used to read a register field from\r
+ * within a 8 bit wide peripheral register. The field can be one or more bits.\r
+ * \r
+ * BASE_ADDR:   A variable of type addr_t specifying the base address of the\r
+ *              peripheral containing the register.\r
+ * FIELD_NAME:  A string identifying the register field to write. These strings\r
+ *              are specified in a header file associated with the peripheral.\r
+ * RETURN:      This function-like macro returns a uint8_t value.\r
+ */\r
+#define HAL_get_8bit_reg_field(BASE_ADDR, FIELD_NAME) \\r
+            (HW_get_8bit_reg_field(\\r
+                (BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\\r
+                FIELD_SHIFT(FIELD_NAME),\\r
+                FIELD_MASK(FIELD_NAME)))\r
+  \r
+#endif /*HAL_H_*/\r
+\r
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 (file)
index 0000000..db8ab77
--- /dev/null
@@ -0,0 +1,29 @@
+/*******************************************************************************\r
+ * (c) Copyright 2008-2018 Microsemi SoC Products Group. All rights reserved.\r
+ * \r
+ * SVN $Revision: 9661 $\r
+ * SVN $Date: 2018-01-15 16:13:33 +0530 (Mon, 15 Jan 2018) $\r
+ */\r
+#ifndef HAL_ASSERT_HEADER\r
+#define HAL_ASSERT_HEADER\r
+\r
+#define NDEBUG 1\r
+\r
+#if defined(NDEBUG)\r
+/***************************************************************************//**\r
+ * HAL_ASSERT() is defined out when the NDEBUG symbol is used.\r
+ ******************************************************************************/\r
+#define HAL_ASSERT(CHECK)\r
+\r
+#else\r
+/***************************************************************************//**\r
+ * Default behaviour for HAL_ASSERT() macro:\r
+ *------------------------------------------------------------------------------\r
+  The behaviour is toolchain specific and project setting specific.\r
+ ******************************************************************************/\r
+#define HAL_ASSERT(CHECK)     ASSERT(CHECK);\r
+\r
+#endif  /* NDEBUG */\r
+\r
+#endif  /* HAL_ASSERT_HEADER */\r
+\r
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 (file)
index 0000000..52f6301
--- /dev/null
@@ -0,0 +1,36 @@
+/***************************************************************************//**\r
+ * (c) Copyright 2007-2018 Microsemi SoC Products Group. All rights reserved.\r
+ * \r
+ * Legacy interrupt control functions for the Microsemi driver library hardware\r
+ * abstraction layer.\r
+ *\r
+ * SVN $Revision: 9661 $\r
+ * SVN $Date: 2018-01-15 16:13:33 +0530 (Mon, 15 Jan 2018) $\r
+ */\r
+#include "hal.h"\r
+#include "riscv_hal.h"\r
+\r
+/*------------------------------------------------------------------------------\r
+ * \r
+ */\r
+void HAL_enable_interrupts(void) {\r
+    __enable_irq();\r
+}\r
+\r
+/*------------------------------------------------------------------------------\r
+ * \r
+ */\r
+psr_t HAL_disable_interrupts(void) {\r
+    psr_t psr;\r
+    psr = read_csr(mstatus);\r
+    __disable_irq();\r
+    return(psr);\r
+}\r
+\r
+/*------------------------------------------------------------------------------\r
+ * \r
+ */\r
+void HAL_restore_interrupts(psr_t saved_psr) {\r
+    write_csr(mstatus, saved_psr);\r
+}\r
+\r
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 (file)
index 0000000..2149544
--- /dev/null
@@ -0,0 +1,97 @@
+/*******************************************************************************\r
+ * (c) Copyright 2007-2018 Microsemi SoC Products Group. All rights reserved.\r
+ * \r
+ *  Hardware registers access macros.\r
+ * \r
+ *  THE MACROS DEFINED IN THIS FILE ARE DEPRECATED. DO NOT USED FOR NEW \r
+ *  DEVELOPMENT.\r
+ *\r
+ * These macros are used to access peripheral's registers. They allow access to\r
+ * 8, 16 and 32 bit wide registers. All accesses to peripheral registers should\r
+ * be done through these macros in order to ease porting across different \r
+ * processors/bus architectures.\r
+ * \r
+ * Some of these macros also allow to access a specific register field.\r
+ * \r
+ * SVN $Revision: 9661 $\r
+ * SVN $Date: 2018-01-15 16:13:33 +0530 (Mon, 15 Jan 2018) $\r
+ */\r
+#ifndef __HW_REGISTER_MACROS_H\r
+#define __HW_REGISTER_MACROS_H 1\r
+\r
+/*------------------------------------------------------------------------------\r
+ * 32 bits registers access:\r
+ */\r
+#define HW_get_uint32_reg(BASE_ADDR, REG_OFFSET) (*((uint32_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)))\r
+\r
+#define HW_set_uint32_reg(BASE_ADDR, REG_OFFSET, VALUE) (*((uint32_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)) = (VALUE))\r
+\r
+#define HW_set_uint32_reg_field(BASE_ADDR, FIELD, VALUE) \\r
+            (*((uint32_t volatile *)(BASE_ADDR + FIELD##_OFFSET)) =  \\r
+                ( \\r
+                    (uint32_t) \\r
+                    ( \\r
+                    (*((uint32_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & ~FIELD##_MASK) | \\r
+                    (uint32_t)(((VALUE) << FIELD##_SHIFT) & FIELD##_MASK) \\r
+                ) \\r
+            )\r
+\r
+#define HW_get_uint32_reg_field( BASE_ADDR, FIELD ) \\r
+            (( (*((uint32_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & FIELD##_MASK) >> FIELD##_SHIFT)\r
+\r
+/*------------------------------------------------------------------------------\r
+ * 32 bits memory access:\r
+ */\r
+#define HW_get_uint32(BASE_ADDR) (*((uint32_t volatile *)(BASE_ADDR)))\r
+\r
+#define HW_set_uint32(BASE_ADDR, VALUE) (*((uint32_t volatile *)(BASE_ADDR)) = (VALUE))\r
+\r
+/*------------------------------------------------------------------------------\r
+ * 16 bits registers access:\r
+ */\r
+#define HW_get_uint16_reg(BASE_ADDR, REG_OFFSET) (*((uint16_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)))\r
+\r
+#define HW_set_uint16_reg(BASE_ADDR, REG_OFFSET, VALUE) (*((uint16_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)) = (VALUE))\r
+\r
+#define HW_set_uint16_reg_field(BASE_ADDR, FIELD, VALUE) \\r
+            (*((uint16_t volatile *)(BASE_ADDR + FIELD##_OFFSET)) =  \\r
+                ( \\r
+                    (uint16_t) \\r
+                    ( \\r
+                    (*((uint16_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & ~FIELD##_MASK) | \\r
+                    (uint16_t)(((VALUE) << FIELD##_SHIFT) & FIELD##_MASK) \\r
+                ) \\r
+            )\r
+\r
+#define HW_get_uint16_reg_field( BASE_ADDR, FIELD ) \\r
+            (( (*((uint16_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & FIELD##_MASK) >> FIELD##_SHIFT)\r
+\r
+/*------------------------------------------------------------------------------\r
+ * 8 bits registers access:\r
+ */\r
+#define HW_get_uint8_reg(BASE_ADDR, REG_OFFSET) (*((uint8_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)))\r
+\r
+#define HW_set_uint8_reg(BASE_ADDR, REG_OFFSET, VALUE) (*((uint8_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)) = (VALUE))\r
\r
+#define HW_set_uint8_reg_field(BASE_ADDR, FIELD, VALUE) \\r
+            (*((uint8_t volatile *)(BASE_ADDR + FIELD##_OFFSET)) =  \\r
+                ( \\r
+                    (uint8_t) \\r
+                    ( \\r
+                    (*((uint8_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & ~FIELD##_MASK) | \\r
+                    (uint8_t)(((VALUE) << FIELD##_SHIFT) & FIELD##_MASK) \\r
+                ) \\r
+            )\r
+\r
+#define HW_get_uint8_reg_field( BASE_ADDR, FIELD ) \\r
+            (( (*((uint8_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & FIELD##_MASK) >> FIELD##_SHIFT)\r
+\r
+/*------------------------------------------------------------------------------\r
+ * 8 bits memory access:\r
+ */\r
+#define HW_get_uint8(BASE_ADDR) (*((uint8_t volatile *)(BASE_ADDR)))\r
+\r
+#define HW_set_uint8(BASE_ADDR, VALUE) (*((uint8_t volatile *)(BASE_ADDR)) = (VALUE))\r
\r
+#endif  /* __HW_REGISTER_MACROS_H */\r
+\r
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 (file)
index 0000000..68d93dd
--- /dev/null
@@ -0,0 +1,209 @@
+/***************************************************************************//**\r
+ * (c) Copyright 2007-2018 Microsemi SoC Products Group. All rights reserved.\r
+ *\r
+ * Hardware registers access functions.\r
+ * The implementation of these function is platform and toolchain specific.\r
+ * The functions declared here are implemented using assembler as part of the\r
+ * processor/toolchain specific HAL.\r
+ *\r
+ * SVN $Revision: 9661 $\r
+ * SVN $Date: 2018-01-15 16:13:33 +0530 (Mon, 15 Jan 2018) $\r
+ */\r
+\r
+.section .text\r
+    .globl HW_set_32bit_reg\r
+    .globl HW_get_32bit_reg\r
+    .globl HW_set_32bit_reg_field\r
+    .globl HW_get_32bit_reg_field\r
+    .globl HW_set_16bit_reg\r
+    .globl HW_get_16bit_reg\r
+    .globl HW_set_16bit_reg_field\r
+    .globl HW_get_16bit_reg_field\r
+    .globl HW_set_8bit_reg\r
+    .globl HW_get_8bit_reg\r
+    .globl HW_set_8bit_reg_field\r
+    .globl HW_get_8bit_reg_field\r
+\r
+\r
+/***************************************************************************//**\r
+ * HW_set_32bit_reg is used to write the content of a 32 bits wide peripheral\r
+ * register.\r
+ *\r
+ * a0:   addr_t reg_addr\r
+ * a1:   uint32_t value\r
+ */\r
+HW_set_32bit_reg:\r
+    sw a1, 0(a0)\r
+    ret\r
+\r
+/***************************************************************************//**\r
+ * HW_get_32bit_reg is used to read the content of a 32 bits wide peripheral\r
+ * register.\r
+ *\r
+ * R0:   addr_t reg_addr\r
+ * @return          32 bits value read from the peripheral register.\r
+ */\r
+HW_get_32bit_reg:\r
+    lw a0, 0(a0)\r
+    ret\r
+\r
+/***************************************************************************//**\r
+ * HW_set_32bit_reg_field is used to set the content of a field in a 32 bits\r
+ * wide peripheral register.\r
+ *\r
+ * a0:   addr_t reg_addr\r
+ * a1:   int_fast8_t shift\r
+ * a2:   uint32_t mask\r
+ * a3:   uint32_t value\r
+ */\r
+HW_set_32bit_reg_field:\r
+    mv t3, a3\r
+    sll t3, t3, a1\r
+    and  t3, t3, a2\r
+    lw t1, 0(a0)\r
+    mv t2, a2\r
+    not t2, t2\r
+    and t1, t1, t2\r
+    or t1, t1, t3\r
+    sw t1, 0(a0)\r
+    ret\r
+\r
+/***************************************************************************//**\r
+ * HW_get_32bit_reg_field is used to read the content of a field out of a\r
+ * 32 bits wide peripheral register.\r
+ *\r
+ * a0:   addr_t reg_addr\r
+ * a1:   int_fast8_t shift\r
+ * a2:   uint32_t mask\r
+ *\r
+ * @return          32 bits value containing the register field value specified\r
+ *                  as parameter.\r
+ */\r
+HW_get_32bit_reg_field:\r
+    lw a0, 0(a0)\r
+    and a0, a0, a2\r
+    srl a0, a0, a1\r
+    ret\r
+\r
+/***************************************************************************//**\r
+ * HW_set_16bit_reg is used to write the content of a 16 bits wide peripheral\r
+ * register.\r
+ *\r
+ * a0:   addr_t reg_addr\r
+ * a1:   uint_fast16_t value\r
+ */\r
+HW_set_16bit_reg:\r
+    sh a1, 0(a0)\r
+    ret\r
+\r
+/***************************************************************************//**\r
+ * HW_get_16bit_reg is used to read the content of a 16 bits wide peripheral\r
+ * register.\r
+ *\r
+ * a0:   addr_t reg_addr\r
+ * @return          16 bits value read from the peripheral register.\r
+ */\r
+HW_get_16bit_reg:\r
+    lh a0, (a0)\r
+    ret\r
+\r
+/***************************************************************************//**\r
+ * HW_set_16bit_reg_field is used to set the content of a field in a 16 bits\r
+ * wide peripheral register.\r
+ *\r
+ * a0:   addr_t reg_addr\r
+ * a1:   int_fast8_t shift\r
+ * a2:   uint_fast16_t mask\r
+ * a3:   uint_fast16_t value\r
+ * @param value     Value to be written in the specified field.\r
+ */\r
+HW_set_16bit_reg_field:\r
+    mv t3, a3\r
+    sll t3, t3, a1\r
+    and  t3, t3, a2\r
+    lh t1, 0(a0)\r
+    mv t2, a2\r
+    not t2, t2\r
+    and t1, t1, t2\r
+    or t1, t1, t3\r
+    sh t1, 0(a0)\r
+    ret\r
+\r
+/***************************************************************************//**\r
+ * HW_get_16bit_reg_field is used to read the content of a field from a\r
+ * 16 bits wide peripheral register.\r
+ *\r
+ * a0:   addr_t reg_addr\r
+ * a1:   int_fast8_t shift\r
+ * a2:   uint_fast16_t mask\r
+ *\r
+ * @return          16 bits value containing the register field value specified\r
+ *                  as parameter.\r
+ */\r
+HW_get_16bit_reg_field:\r
+    lh a0, 0(a0)\r
+    and a0, a0, a2\r
+    srl a0, a0, a1\r
+    ret\r
+\r
+/***************************************************************************//**\r
+ * HW_set_8bit_reg is used to write the content of a 8 bits wide peripheral\r
+ * register.\r
+ *\r
+ * a0:   addr_t reg_addr\r
+ * a1:   uint_fast8_t value\r
+ */\r
+HW_set_8bit_reg:\r
+    sb a1, 0(a0)\r
+    ret\r
+\r
+/***************************************************************************//**\r
+ * HW_get_8bit_reg is used to read the content of a 8 bits wide peripheral\r
+ * register.\r
+ *\r
+ * a0:   addr_t reg_addr\r
+ * @return          8 bits value read from the peripheral register.\r
+ */\r
+HW_get_8bit_reg:\r
+    lb a0, 0(a0)\r
+    ret\r
+\r
+/***************************************************************************//**\r
+ * HW_set_8bit_reg_field is used to set the content of a field in a 8 bits\r
+ * wide peripheral register.\r
+ *\r
+ * a0:   addr_t reg_addr,\r
+ * a1:   int_fast8_t shift\r
+ * a2:   uint_fast8_t mask\r
+ * a3:   uint_fast8_t value\r
+ */\r
+HW_set_8bit_reg_field:\r
+    mv t3, a3\r
+    sll t3, t3, a1\r
+    and  t3, t3, a2\r
+    lb t1, 0(a0)\r
+    mv t2, a2\r
+    not t2, t2\r
+    and t1, t1, t2\r
+    or t1, t1, t3\r
+    sb t1, 0(a0)\r
+    ret\r
+\r
+/***************************************************************************//**\r
+ * HW_get_8bit_reg_field is used to read the content of a field from a\r
+ * 8 bits wide peripheral register.\r
+ *\r
+ * a0:   addr_t reg_addr\r
+ * a1:   int_fast8_t shift\r
+ * a2:   uint_fast8_t mask\r
+ *\r
+ * @return          8 bits value containing the register field value specified\r
+ *                  as parameter.\r
+ */\r
+HW_get_8bit_reg_field:\r
+    lb a0, 0(a0)\r
+    and a0, a0, a2\r
+    srl a0, a0, a1\r
+    ret\r
+\r
+.end\r
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 (file)
index 0000000..bc3dd65
--- /dev/null
@@ -0,0 +1,229 @@
+/***************************************************************************//**\r
+ * (c) Copyright 2007-2018 Microsemi SoC Products Group. All rights reserved.\r
+ * \r
+ * Hardware registers access functions.\r
+ * The implementation of these function is platform and toolchain specific.\r
+ * The functions declared here are implemented using assembler as part of the \r
+ * processor/toolchain specific HAL.\r
+ * \r
+ * SVN $Revision: 9661 $\r
+ * SVN $Date: 2018-01-15 16:13:33 +0530 (Mon, 15 Jan 2018) $\r
+ */\r
+#ifndef HW_REG_ACCESS\r
+#define HW_REG_ACCESS\r
+\r
+#include "cpu_types.h"\r
+/***************************************************************************//**\r
+ * HW_set_32bit_reg is used to write the content of a 32 bits wide peripheral\r
+ * register.\r
+ * \r
+ * @param reg_addr  Address in the processor's memory map of the register to\r
+ *                  write.\r
+ * @param value     Value to be written into the peripheral register.\r
+ */\r
+void\r
+HW_set_32bit_reg\r
+(\r
+    addr_t reg_addr,\r
+    uint32_t value\r
+);\r
+\r
+/***************************************************************************//**\r
+ * HW_get_32bit_reg is used to read the content of a 32 bits wide peripheral\r
+ * register.\r
+ * \r
+ * @param reg_addr  Address in the processor's memory map of the register to\r
+ *                  read.\r
+ * @return          32 bits value read from the peripheral register.\r
+ */\r
+uint32_t\r
+HW_get_32bit_reg\r
+(\r
+    addr_t reg_addr\r
+);\r
+\r
+/***************************************************************************//**\r
+ * HW_set_32bit_reg_field is used to set the content of a field in a 32 bits \r
+ * wide peripheral register.\r
+ * \r
+ * @param reg_addr  Address in the processor's memory map of the register to\r
+ *                  be written.\r
+ * @param shift     Bit offset of the register field to be read within the \r
+ *                  register.\r
+ * @param mask      Bit mask to be applied to the raw register value to filter\r
+ *                  out the other register fields values.\r
+ * @param value     Value to be written in the specified field.\r
+ */\r
+void\r
+HW_set_32bit_reg_field\r
+(\r
+    addr_t reg_addr,\r
+    int_fast8_t shift,\r
+    uint32_t mask,\r
+    uint32_t value\r
+);\r
+\r
+/***************************************************************************//**\r
+ * HW_get_32bit_reg_field is used to read the content of a field out of a \r
+ * 32 bits wide peripheral register.\r
+ * \r
+ * @param reg_addr  Address in the processor's memory map of the register to\r
+ *                  read.\r
+ * @param shift     Bit offset of the register field to be written within the \r
+ *                  register.\r
+ * @param mask      Bit mask to be applied to the raw register value to filter\r
+ *                  out the other register fields values.\r
+ *\r
+ * @return          32 bits value containing the register field value specified\r
+ *                  as parameter.\r
+ */\r
+uint32_t \r
+HW_get_32bit_reg_field\r
+(\r
+    addr_t reg_addr,\r
+    int_fast8_t shift,\r
+    uint32_t mask\r
+);\r
+\r
+/***************************************************************************//**\r
+ * HW_set_16bit_reg is used to write the content of a 16 bits wide peripheral\r
+ * register.\r
+ * \r
+ * @param reg_addr  Address in the processor's memory map of the register to\r
+ *                  write.\r
+ * @param value     Value to be written into the peripheral register.\r
+ */\r
+void\r
+HW_set_16bit_reg\r
+(\r
+    addr_t reg_addr,\r
+    uint_fast16_t value\r
+);\r
+\r
+/***************************************************************************//**\r
+ * HW_get_16bit_reg is used to read the content of a 16 bits wide peripheral\r
+ * register.\r
+ * \r
+ * @param reg_addr  Address in the processor's memory map of the register to\r
+ *                  read.\r
+ * @return          16 bits value read from the peripheral register.\r
+ */\r
+uint16_t\r
+HW_get_16bit_reg\r
+(\r
+    addr_t reg_addr\r
+);\r
+\r
+/***************************************************************************//**\r
+ * HW_set_16bit_reg_field is used to set the content of a field in a 16 bits \r
+ * wide peripheral register.\r
+ * \r
+ * @param reg_addr  Address in the processor's memory map of the register to\r
+ *                  be written.\r
+ * @param shift     Bit offset of the register field to be read within the \r
+ *                  register.\r
+ * @param mask      Bit mask to be applied to the raw register value to filter\r
+ *                  out the other register fields values.\r
+ * @param value     Value to be written in the specified field.\r
+ */\r
+void HW_set_16bit_reg_field\r
+(\r
+    addr_t reg_addr,\r
+    int_fast8_t shift,\r
+    uint_fast16_t mask,\r
+    uint_fast16_t value\r
+);\r
+\r
+/***************************************************************************//**\r
+ * HW_get_16bit_reg_field is used to read the content of a field from a \r
+ * 16 bits wide peripheral register.\r
+ * \r
+ * @param reg_addr  Address in the processor's memory map of the register to\r
+ *                  read.\r
+ * @param shift     Bit offset of the register field to be written within the \r
+ *                  register.\r
+ * @param mask      Bit mask to be applied to the raw register value to filter\r
+ *                  out the other register fields values.\r
+ *\r
+ * @return          16 bits value containing the register field value specified\r
+ *                  as parameter.\r
+ */\r
+uint16_t HW_get_16bit_reg_field\r
+(\r
+    addr_t reg_addr,\r
+    int_fast8_t shift,\r
+    uint_fast16_t mask\r
+);\r
+\r
+/***************************************************************************//**\r
+ * HW_set_8bit_reg is used to write the content of a 8 bits wide peripheral\r
+ * register.\r
+ * \r
+ * @param reg_addr  Address in the processor's memory map of the register to\r
+ *                  write.\r
+ * @param value     Value to be written into the peripheral register.\r
+ */\r
+void\r
+HW_set_8bit_reg\r
+(\r
+    addr_t reg_addr,\r
+    uint_fast8_t value\r
+);\r
+\r
+/***************************************************************************//**\r
+ * HW_get_8bit_reg is used to read the content of a 8 bits wide peripheral\r
+ * register.\r
+ * \r
+ * @param reg_addr  Address in the processor's memory map of the register to\r
+ *                  read.\r
+ * @return          8 bits value read from the peripheral register.\r
+ */\r
+uint8_t\r
+HW_get_8bit_reg\r
+(\r
+    addr_t reg_addr\r
+);\r
+\r
+/***************************************************************************//**\r
+ * HW_set_8bit_reg_field is used to set the content of a field in a 8 bits \r
+ * wide peripheral register.\r
+ * \r
+ * @param reg_addr  Address in the processor's memory map of the register to\r
+ *                  be written.\r
+ * @param shift     Bit offset of the register field to be read within the \r
+ *                  register.\r
+ * @param mask      Bit mask to be applied to the raw register value to filter\r
+ *                  out the other register fields values.\r
+ * @param value     Value to be written in the specified field.\r
+ */\r
+void HW_set_8bit_reg_field\r
+(\r
+    addr_t reg_addr,\r
+    int_fast8_t shift,\r
+    uint_fast8_t mask,\r
+    uint_fast8_t value\r
+);\r
+\r
+/***************************************************************************//**\r
+ * HW_get_8bit_reg_field is used to read the content of a field from a \r
+ * 8 bits wide peripheral register.\r
+ * \r
+ * @param reg_addr  Address in the processor's memory map of the register to\r
+ *                  read.\r
+ * @param shift     Bit offset of the register field to be written within the \r
+ *                  register.\r
+ * @param mask      Bit mask to be applied to the raw register value to filter\r
+ *                  out the other register fields values.\r
+ *\r
+ * @return          8 bits value containing the register field value specified\r
+ *                  as parameter.\r
+ */\r
+uint8_t HW_get_8bit_reg_field\r
+(\r
+    addr_t reg_addr,\r
+    int_fast8_t shift,\r
+    uint_fast8_t mask\r
+);\r
+\r
+#endif /* HW_REG_ACCESS */\r
+\r
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 (file)
index 0000000..268eba6
--- /dev/null
@@ -0,0 +1,119 @@
+/*******************************************************************************\r
+ * (c) Copyright 2016-2017 Microsemi Corporation.  All rights reserved.\r
+ *\r
+ * Platform definitions\r
+ * Version based on requirements of RISCV-HAL\r
+ *\r
+ * SVN $Revision: 9587 $\r
+ * SVN $Date: 2017-11-16 12:53:31 +0530 (Thu, 16 Nov 2017) $\r
+ */\r
+ /*=========================================================================*//**\r
+  @mainpage Sample file detailing how hw_platform.h should be constructed for \r
+    the Mi-V processors.\r
+\r
+    @section intro_sec Introduction\r
+    The hw_platform.h is to be located in the project root directory.\r
+    Currently this file must be hand crafted when using the Mi-V Soft Processor.\r
+    \r
+    You can use this file as sample.\r
+    Rename this file from sample_hw_platform.h to hw_platform.h and store it in\r
+    the root folder of your project. Then customize it per your HW design.\r
+\r
+    @section driver_configuration Project configuration Instructions\r
+    1. Change SYS_CLK_FREQ define to frequency of Mi-V Soft processor clock\r
+    2  Add all other core BASE addresses\r
+    3. Add peripheral Core Interrupt to Mi-V Soft processor interrupt mappings\r
+    4. Define MSCC_STDIO_UART_BASE_ADDR if you want a CoreUARTapb mapped to STDIO\r
+*//*=========================================================================*/\r
+\r
+#ifndef HW_PLATFORM_H\r
+#define HW_PLATFORM_H\r
+\r
+/***************************************************************************//**\r
+ * Soft-processor clock definition\r
+ * This is the only clock brought over from the Mi-V Soft processor Libero design.\r
+ */\r
+#ifndef SYS_CLK_FREQ\r
+#define SYS_CLK_FREQ                    83000000UL\r
+#endif\r
+\r
+/***************************************************************************//**\r
+ * Non-memory Peripheral base addresses\r
+ * Format of define is:\r
+ * <corename>_<instance>_BASE_ADDR\r
+ */\r
+#define COREUARTAPB0_BASE_ADDR          0x70001000UL\r
+#define COREGPIO_IN_BASE_ADDR           0x70002000UL\r
+#define CORETIMER0_BASE_ADDR            0x70003000UL\r
+#define CORETIMER1_BASE_ADDR            0x70004000UL\r
+#define COREGPIO_OUT_BASE_ADDR          0x70005000UL\r
+#define FLASH_CORE_SPI_BASE             0x70006000UL\r
+#define CORE16550_BASE_ADDR             0x70007000UL\r
+\r
+/***************************************************************************//**\r
+ * Peripheral Interrupts are mapped to the corresponding Mi-V Soft processor\r
+ * interrupt from the Libero design.\r
+ * There can be up to 31 external interrupts (IRQ[30:0] pins) on the Mi-V Soft\r
+ * processor.The Mi-V Soft processor external interrupts are defined in the\r
+ * riscv_plic.h\r
+ * These are of the form\r
+ * typedef enum\r
+{\r
+    NoInterrupt_IRQn = 0,\r
+    External_1_IRQn  = 1,\r
+    External_2_IRQn  = 2,\r
+    .\r
+    .\r
+    .\r
+    External_31_IRQn = 31\r
+} IRQn_Type;\r
\r
+ The interrupt 0 on RISC-V processor is not used. The pin IRQ[0] should map to\r
+ External_1_IRQn likewise IRQ[30] should map to External_31_IRQn\r
+ * Format of define is:\r
+ * <corename>_<instance>_<core interrupt name>\r
+ */\r
+\r
+#define TIMER0_IRQn                     External_30_IRQn\r
+#define TIMER1_IRQn                     External_31_IRQn\r
+\r
+/****************************************************************************\r
+ * Baud value to achieve a 115200 baud rate with a 83MHz system clock.\r
+ * This value is calculated using the following equation:\r
+ *      BAUD_VALUE = (CLOCK / (16 * BAUD_RATE)) - 1\r
+ *****************************************************************************/\r
+#define BAUD_VALUE_115200               (SYS_CLK_FREQ / (16 * 115200)) - 1\r
+\r
+/***************************************************************************//**\r
+ * User edit section- Edit sections below if required\r
+ */\r
+#ifdef MSCC_STDIO_THRU_CORE_UART_APB\r
+/*\r
+ * A base address mapping for the STDIO printf/scanf mapping to CortUARTapb\r
+ * must be provided if it is being used\r
+ *\r
+ * e.g. #define MSCC_STDIO_UART_BASE_ADDR COREUARTAPB1_BASE_ADDR\r
+ */\r
+#define MSCC_STDIO_UART_BASE_ADDR COREUARTAPB0_BASE_ADDR\r
+\r
+#ifndef MSCC_STDIO_UART_BASE_ADDR\r
+#error MSCC_STDIO_UART_BASE_ADDR not defined- e.g. #define MSCC_STDIO_UART_BASE_ADDR COREUARTAPB1_BASE_ADDR\r
+#endif\r
+\r
+#ifndef MSCC_STDIO_BAUD_VALUE\r
+/*\r
+ * The MSCC_STDIO_BAUD_VALUE define should be set in your project's settings to\r
+ * specify the baud value used by the standard output CoreUARTapb instance for\r
+ * generating the UART's baud rate if you want a different baud rate from the\r
+ * default of 115200 baud\r
+ */\r
+#define MSCC_STDIO_BAUD_VALUE           115200\r
+#endif  /*MSCC_STDIO_BAUD_VALUE*/\r
+\r
+#endif  /* end of MSCC_STDIO_THRU_CORE_UART_APB */\r
+/*******************************************************************************\r
+ * End of user edit section\r
+ */\r
+#endif /* HW_PLATFORM_H */\r
+\r
+\r
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 (file)
index 0000000..4ec3a71
--- /dev/null
@@ -0,0 +1,136 @@
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+#include "queue.h"\r
+#include "timers.h"\r
+\r
+#include "hw_platform.h"\r
+#include "core_uart_apb.h"\r
+#include "task.h"\r
+\r
+const char * g_hello_msg = "\r\nFreeRTOS Example\r\n";\r
+\r
+\r
+/* A block time of zero simply means "don't block". */\r
+#define mainDONT_BLOCK                                         ( 0UL )\r
+\r
+/******************************************************************************\r
+ * CoreUARTapb instance data.\r
+ *****************************************************************************/\r
+UART_instance_t g_uart;\r
+/*-----------------------------------------------------------*/\r
+\r
+static void vUartTestTask1( void *pvParameters );\r
+static void vUartTestTask2( void *pvParameters );\r
+\r
+/*\r
+ * FreeRTOS hook for when malloc fails, enable in FreeRTOSConfig.\r
+ */\r
+void vApplicationMallocFailedHook( void );\r
+\r
+/*\r
+ * FreeRTOS hook for when FreeRtos is idling, enable in FreeRTOSConfig.\r
+ */\r
+void vApplicationIdleHook( void );\r
+\r
+/*\r
+ * FreeRTOS hook for when a stack overflow occurs, enable in FreeRTOSConfig.\r
+ */\r
+void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+int main( void )\r
+{\r
+    PLIC_init();\r
+\r
+    /**************************************************************************\r
+    * Initialize CoreUART with its base address, baud value, and line\r
+    * configuration.\r
+    *************************************************************************/\r
+    UART_init(&g_uart, COREUARTAPB0_BASE_ADDR, BAUD_VALUE_115200,\r
+             (DATA_8_BITS | NO_PARITY) );\r
+\r
+    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" );\r
+    UART_polled_tx_string( &g_uart, (const uint8_t *)"         This project creates  two tasks and runs them at regular intervals.\r\n" );\r
+\r
+    /* Create the two test tasks. */\r
+       xTaskCreate( vUartTestTask1, "UArt1", 1000, NULL, uartPRIMARY_PRIORITY, NULL );\r
+       xTaskCreate( vUartTestTask2, "UArt2", 1000, NULL, uartPRIMARY_PRIORITY, NULL );\r
+\r
+       /* Start the kernel.  From here on, only tasks and interrupts will run. */\r
+       vTaskStartScheduler();\r
+\r
+       /* Exit FreeRTOS */\r
+       return 0;\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void vApplicationMallocFailedHook( void )\r
+{\r
+       /* vApplicationMallocFailedHook() will only be called if\r
+       configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h.  It is a hook\r
+       function that will get called if a call to pvPortMalloc() fails.\r
+       pvPortMalloc() is called internally by the kernel whenever a task, queue,\r
+       timer or semaphore is created.  It is also called by various parts of the\r
+       demo application.  If heap_1.c or heap_2.c are used, then the size of the\r
+       heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in\r
+       FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used\r
+       to query the size of free heap space that remains (although it does not\r
+       provide information on how the remaining heap might be fragmented). */\r
+       taskDISABLE_INTERRUPTS();\r
+       for( ;; );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vApplicationIdleHook( void )\r
+{\r
+       /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set\r
+       to 1 in FreeRTOSConfig.h.  It will be called on each iteration of the idle\r
+       task.  It is essential that code added to this hook function never attempts\r
+       to block in any way (for example, call xQueueReceive() with a block time\r
+       specified, or call vTaskDelay()).  If the application makes use of the\r
+       vTaskDelete() API function (as this demo application does) then it is also\r
+       important that vApplicationIdleHook() is permitted to return to its calling\r
+       function, because it is the responsibility of the idle task to clean up\r
+       memory allocated by the kernel to any task that has since been deleted. */\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )\r
+{\r
+       ( void ) pcTaskName;\r
+       ( void ) pxTask;\r
+\r
+       /* Run time stack overflow checking is performed if\r
+       configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2.  This hook\r
+       function is called if a stack overflow is detected. */\r
+       taskDISABLE_INTERRUPTS();\r
+       for( ;; );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void vUartTestTask1( void *pvParameters )\r
+{\r
+       ( void ) pvParameters;\r
+\r
+       for( ;; )\r
+       {\r
+               UART_polled_tx_string( &g_uart, (const uint8_t *)"Task - 1\r\n" );\r
+           vTaskDelay(10);\r
+       }\r
+}\r
+\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+static void vUartTestTask2( void *pvParameters )\r
+{\r
+       ( void ) pvParameters;\r
+\r
+       for( ;; )\r
+       {\r
+               UART_polled_tx_string( &g_uart, (const uint8_t *)"Task - 2\r\n" );\r
+           vTaskDelay(5);\r
+       }\r
+}\r
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 (file)
index 0000000..aa379ee
--- /dev/null
@@ -0,0 +1,596 @@
+/*******************************************************************************\r
+ * (c) Copyright 2016-2018 Microsemi SoC Products Group.  All rights reserved.\r
+ *\r
+ * @file encodings.h\r
+ * @author Microsemi SoC Products Group\r
+ * @brief Mi-V soft processor register bit mask and shift constants encodings.\r
+ *\r
+ * SVN $Revision: 9825 $\r
+ * SVN $Date: 2018-03-19 10:31:41 +0530 (Mon, 19 Mar 2018) $\r
+ */\r
+#ifndef RISCV_CSR_ENCODING_H\r
+#define RISCV_CSR_ENCODING_H\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+#define MSTATUS_UIE         0x00000001\r
+#define MSTATUS_SIE         0x00000002\r
+#define MSTATUS_HIE         0x00000004\r
+#define MSTATUS_MIE         0x00000008\r
+#define MSTATUS_UPIE        0x00000010\r
+#define MSTATUS_SPIE        0x00000020\r
+#define MSTATUS_HPIE        0x00000040\r
+#define MSTATUS_MPIE        0x00000080\r
+#define MSTATUS_SPP         0x00000100\r
+#define MSTATUS_HPP         0x00000600\r
+#define MSTATUS_MPP         0x00001800\r
+#define MSTATUS_FS          0x00006000\r
+#define MSTATUS_XS          0x00018000\r
+#define MSTATUS_MPRV        0x00020000\r
+#define MSTATUS_SUM         0x00040000      /*changed in v1.10*/\r
+#define MSTATUS_MXR         0x00080000      /*changed in v1.10*/\r
+#define MSTATUS_TVM         0x00100000      /*changed in v1.10*/\r
+#define MSTATUS_TW          0x00200000      /*changed in v1.10*/\r
+#define MSTATUS_TSR         0x00400000      /*changed in v1.10*/\r
+#define MSTATUS_RES         0x7F800000      /*changed in v1.10*/\r
+#define MSTATUS32_SD        0x80000000\r
+#define MSTATUS64_SD        0x8000000000000000\r
+\r
+#define MCAUSE32_CAUSE       0x7FFFFFFF\r
+#define MCAUSE64_CAUSE       0x7FFFFFFFFFFFFFFF\r
+#define MCAUSE32_INT         0x80000000\r
+#define MCAUSE64_INT         0x8000000000000000\r
+\r
+#define SSTATUS_UIE         0x00000001\r
+#define SSTATUS_SIE         0x00000002\r
+#define SSTATUS_UPIE        0x00000010\r
+#define SSTATUS_SPIE        0x00000020\r
+#define SSTATUS_SPP         0x00000100\r
+#define SSTATUS_FS          0x00006000\r
+#define SSTATUS_XS          0x00018000\r
+#define SSTATUS_PUM         0x00040000\r
+#define SSTATUS32_SD        0x80000000\r
+#define SSTATUS64_SD        0x8000000000000000\r
+\r
+#define MIP_SSIP            (1u << IRQ_S_SOFT)\r
+#define MIP_HSIP            (1u << IRQ_H_SOFT)\r
+#define MIP_MSIP            (1u << IRQ_M_SOFT)\r
+#define MIP_STIP            (1u << IRQ_S_TIMER)\r
+#define MIP_HTIP            (1u << IRQ_H_TIMER)\r
+#define MIP_MTIP            (1u << IRQ_M_TIMER)\r
+#define MIP_SEIP            (1u << IRQ_S_EXT)\r
+#define MIP_HEIP            (1u << IRQ_H_EXT)\r
+#define MIP_MEIP            (1u << IRQ_M_EXT)\r
+\r
+#define SIP_SSIP            MIP_SSIP\r
+#define SIP_STIP            MIP_STIP\r
+\r
+#define PRV_U               0\r
+#define PRV_S               1\r
+#define PRV_H               2\r
+#define PRV_M               3\r
+\r
+#define VM_MBARE            0\r
+#define VM_MBB              1\r
+#define VM_MBBID            2\r
+#define VM_SV32             8\r
+#define VM_SV39             9\r
+#define VM_SV48             10\r
+\r
+#define IRQ_S_SOFT          1\r
+#define IRQ_H_SOFT          2\r
+#define IRQ_M_SOFT          3\r
+#define IRQ_S_TIMER         5\r
+#define IRQ_H_TIMER         6\r
+#define IRQ_M_TIMER         7\r
+#define IRQ_S_EXT           9\r
+#define IRQ_H_EXT           10\r
+#define IRQ_M_EXT           11\r
+\r
+#define DEFAULT_RSTVEC      0x00001000\r
+#define DEFAULT_NMIVEC      0x00001004\r
+#define DEFAULT_MTVEC       0x00001010\r
+#define CONFIG_STRING_ADDR  0x0000100C\r
+#define EXT_IO_BASE         0x40000000\r
+#define DRAM_BASE           0x80000000\r
+\r
+/* page table entry (PTE) fields */\r
+#define PTE_V               0x001       /* Valid */\r
+#define PTE_TYPE            0x01E       /* Type  */\r
+#define PTE_R               0x020       /* Referenced */\r
+#define PTE_D               0x040       /* Dirty */\r
+#define PTE_SOFT            0x380       /* Reserved for Software */\r
+\r
+#define PTE_TYPE_TABLE        0x00\r
+#define PTE_TYPE_TABLE_GLOBAL 0x02\r
+#define PTE_TYPE_URX_SR       0x04\r
+#define PTE_TYPE_URWX_SRW     0x06\r
+#define PTE_TYPE_UR_SR        0x08\r
+#define PTE_TYPE_URW_SRW      0x0A\r
+#define PTE_TYPE_URX_SRX      0x0C\r
+#define PTE_TYPE_URWX_SRWX    0x0E\r
+#define PTE_TYPE_SR           0x10\r
+#define PTE_TYPE_SRW          0x12\r
+#define PTE_TYPE_SRX          0x14\r
+#define PTE_TYPE_SRWX         0x16\r
+#define PTE_TYPE_SR_GLOBAL    0x18\r
+#define PTE_TYPE_SRW_GLOBAL   0x1A\r
+#define PTE_TYPE_SRX_GLOBAL   0x1C\r
+#define PTE_TYPE_SRWX_GLOBAL  0x1E\r
+\r
+#define PTE_PPN_SHIFT 10\r
+\r
+#define PTE_TABLE(PTE) ((0x0000000AU >> ((PTE) & 0x1F)) & 1)\r
+#define PTE_UR(PTE)    ((0x0000AAA0U >> ((PTE) & 0x1F)) & 1)\r
+#define PTE_UW(PTE)    ((0x00008880U >> ((PTE) & 0x1F)) & 1)\r
+#define PTE_UX(PTE)    ((0x0000A0A0U >> ((PTE) & 0x1F)) & 1)\r
+#define PTE_SR(PTE)    ((0xAAAAAAA0U >> ((PTE) & 0x1F)) & 1)\r
+#define PTE_SW(PTE)    ((0x88888880U >> ((PTE) & 0x1F)) & 1)\r
+#define PTE_SX(PTE)    ((0xA0A0A000U >> ((PTE) & 0x1F)) & 1)\r
+\r
+#define PTE_CHECK_PERM(PTE, SUPERVISOR, STORE, FETCH) \\r
+  ((STORE) ? ((SUPERVISOR) ? PTE_SW(PTE) : PTE_UW(PTE)) : \\r
+   (FETCH) ? ((SUPERVISOR) ? PTE_SX(PTE) : PTE_UX(PTE)) : \\r
+             ((SUPERVISOR) ? PTE_SR(PTE) : PTE_UR(PTE)))\r
+\r
+#ifdef __riscv\r
+\r
+#if __riscv_xlen == 64\r
+# define MSTATUS_SD             MSTATUS64_SD\r
+# define SSTATUS_SD             SSTATUS64_SD\r
+# define MCAUSE_INT             MCAUSE64_INT\r
+# define MCAUSE_CAUSE           MCAUSE64_CAUSE\r
+# define RISCV_PGLEVEL_BITS     9\r
+#else\r
+# define MSTATUS_SD             MSTATUS32_SD\r
+# define SSTATUS_SD             SSTATUS32_SD\r
+# define RISCV_PGLEVEL_BITS     10\r
+# define MCAUSE_INT             MCAUSE32_INT\r
+# define MCAUSE_CAUSE           MCAUSE32_CAUSE\r
+#endif\r
+\r
+#define RISCV_PGSHIFT           12\r
+#define RISCV_PGSIZE            (1 << RISCV_PGSHIFT)\r
+\r
+#ifndef __ASSEMBLER__\r
+\r
+#ifdef __GNUC__\r
+\r
+#define read_csr(reg) ({ unsigned long __tmp; \\r
+  asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \\r
+  __tmp; })\r
+\r
+#define write_csr(reg, val) ({ \\r
+  if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \\r
+    asm volatile ("csrw " #reg ", %0" :: "i"(val)); \\r
+  else \\r
+    asm volatile ("csrw " #reg ", %0" :: "r"(val)); })\r
+\r
+#define swap_csr(reg, val) ({ unsigned long __tmp; \\r
+  if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \\r
+    asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "i"(val)); \\r
+  else \\r
+    asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "r"(val)); \\r
+  __tmp; })\r
+\r
+#define set_csr(reg, bit) ({ unsigned long __tmp; \\r
+  if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \\r
+    asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \\r
+  else \\r
+    asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \\r
+  __tmp; })\r
+\r
+#define clear_csr(reg, bit) ({ unsigned long __tmp; \\r
+  if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \\r
+    asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \\r
+  else \\r
+    asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \\r
+  __tmp; })\r
+\r
+#define rdtime() read_csr(time)\r
+#define rdcycle() read_csr(cycle)\r
+#define rdinstret() read_csr(instret)\r
+\r
+#ifdef __riscv_atomic\r
+\r
+#define MASK(nr)                    (1UL << nr)\r
+#define MASK_NOT(nr)                (~(1UL << nr))\r
+\r
+/**\r
+ * atomic_read - read atomic variable\r
+ * @v: pointer of type int\r
+ *\r
+ * Atomically reads the value of @v.\r
+ */\r
+static inline int atomic_read(const int *v)\r
+{\r
+    return *((volatile int *)(v));\r
+}\r
+\r
+/**\r
+ * atomic_set - set atomic variable\r
+ * @v: pointer of type int\r
+ * @i: required value\r
+ *\r
+ * Atomically sets the value of @v to @i.\r
+ */\r
+static inline void atomic_set(int *v, int i)\r
+{\r
+    *v = i;\r
+}\r
+\r
+/**\r
+ * atomic_add - add integer to atomic variable\r
+ * @i: integer value to add\r
+ * @v: pointer of type int\r
+ *\r
+ * Atomically adds @i to @v.\r
+ */\r
+static inline void atomic_add(int i, int *v)\r
+{\r
+    __asm__ __volatile__ (\r
+        "amoadd.w zero, %1, %0"\r
+        : "+A" (*v)\r
+        : "r" (i));\r
+}\r
+\r
+static inline int atomic_fetch_add(unsigned int mask, int *v)\r
+{\r
+    int out;\r
+\r
+    __asm__ __volatile__ (\r
+        "amoadd.w %2, %1, %0"\r
+        : "+A" (*v), "=r" (out)\r
+        : "r" (mask));\r
+    return out;\r
+}\r
+\r
+/**\r
+ * atomic_sub - subtract integer from atomic variable\r
+ * @i: integer value to subtract\r
+ * @v: pointer of type int\r
+ *\r
+ * Atomically subtracts @i from @v.\r
+ */\r
+static inline void atomic_sub(int i, int *v)\r
+{\r
+    atomic_add(-i, v);\r
+}\r
+\r
+static inline int atomic_fetch_sub(unsigned int mask, int *v)\r
+{\r
+    int out;\r
+\r
+    __asm__ __volatile__ (\r
+        "amosub.w %2, %1, %0"\r
+        : "+A" (*v), "=r" (out)\r
+        : "r" (mask));\r
+    return out;\r
+}\r
+\r
+/**\r
+ * atomic_add_return - add integer to atomic variable\r
+ * @i: integer value to add\r
+ * @v: pointer of type int\r
+ *\r
+ * Atomically adds @i to @v and returns the result\r
+ */\r
+static inline int atomic_add_return(int i, int *v)\r
+{\r
+    register int c;\r
+    __asm__ __volatile__ (\r
+        "amoadd.w %0, %2, %1"\r
+        : "=r" (c), "+A" (*v)\r
+        : "r" (i));\r
+    return (c + i);\r
+}\r
+\r
+/**\r
+ * atomic_sub_return - subtract integer from atomic variable\r
+ * @i: integer value to subtract\r
+ * @v: pointer of type int\r
+ *\r
+ * Atomically subtracts @i from @v and returns the result\r
+ */\r
+static inline int atomic_sub_return(int i, int *v)\r
+{\r
+    return atomic_add_return(-i, v);\r
+}\r
+\r
+/**\r
+ * atomic_inc - increment atomic variable\r
+ * @v: pointer of type int\r
+ *\r
+ * Atomically increments @v by 1.\r
+ */\r
+static inline void atomic_inc(int *v)\r
+{\r
+    atomic_add(1, v);\r
+}\r
+\r
+/**\r
+ * atomic_dec - decrement atomic variable\r
+ * @v: pointer of type int\r
+ *\r
+ * Atomically decrements @v by 1.\r
+ */\r
+static inline void atomic_dec(int *v)\r
+{\r
+    atomic_add(-1, v);\r
+}\r
+\r
+static inline int atomic_inc_return(int *v)\r
+{\r
+    return atomic_add_return(1, v);\r
+}\r
+\r
+static inline int atomic_dec_return(int *v)\r
+{\r
+    return atomic_sub_return(1, v);\r
+}\r
+\r
+/**\r
+ * atomic_sub_and_test - subtract value from variable and test result\r
+ * @i: integer value to subtract\r
+ * @v: pointer of type int\r
+ *\r
+ * Atomically subtracts @i from @v and returns\r
+ * true if the result is zero, or false for all\r
+ * other cases.\r
+ */\r
+static inline int atomic_sub_and_test(int i, int *v)\r
+{\r
+    return (atomic_sub_return(i, v) == 0);\r
+}\r
+\r
+/**\r
+ * atomic_inc_and_test - increment and test\r
+ * @v: pointer of type int\r
+ *\r
+ * Atomically increments @v by 1\r
+ * and returns true if the result is zero, or false for all\r
+ * other cases.\r
+ */\r
+static inline int atomic_inc_and_test(int *v)\r
+{\r
+    return (atomic_inc_return(v) == 0);\r
+}\r
+\r
+/**\r
+ * atomic_dec_and_test - decrement and test\r
+ * @v: pointer of type int\r
+ *\r
+ * Atomically decrements @v by 1 and\r
+ * returns true if the result is 0, or false for all other\r
+ * cases.\r
+ */\r
+static inline int atomic_dec_and_test(int *v)\r
+{\r
+    return (atomic_dec_return(v) == 0);\r
+}\r
+\r
+/**\r
+ * atomic_add_negative - add and test if negative\r
+ * @i: integer value to add\r
+ * @v: pointer of type int\r
+ *\r
+ * Atomically adds @i to @v and returns true\r
+ * if the result is negative, or false when\r
+ * result is greater than or equal to zero.\r
+ */\r
+static inline int atomic_add_negative(int i, int *v)\r
+{\r
+    return (atomic_add_return(i, v) < 0);\r
+}\r
+\r
+static inline int atomic_xchg(int *v, int n)\r
+{\r
+    register int c;\r
+    __asm__ __volatile__ (\r
+        "amoswap.w %0, %2, %1"\r
+        : "=r" (c), "+A" (*v)\r
+        : "r" (n));\r
+    return c;\r
+}\r
+\r
+/**\r
+ * atomic_and - Atomically clear bits in atomic variable\r
+ * @mask: Mask of the bits to be retained\r
+ * @v: pointer of type int\r
+ *\r
+ * Atomically retains the bits set in @mask from @v\r
+ */\r
+static inline void atomic_and(unsigned int mask, int *v)\r
+{\r
+    __asm__ __volatile__ (\r
+        "amoand.w zero, %1, %0"\r
+        : "+A" (*v)\r
+        : "r" (mask));\r
+}\r
+\r
+static inline int atomic_fetch_and(unsigned int mask, int *v)\r
+{\r
+    int out;\r
+    __asm__ __volatile__ (\r
+        "amoand.w %2, %1, %0"\r
+        : "+A" (*v), "=r" (out)\r
+        : "r" (mask));\r
+    return out;\r
+}\r
+\r
+/**\r
+ * atomic_or - Atomically set bits in atomic variable\r
+ * @mask: Mask of the bits to be set\r
+ * @v: pointer of type int\r
+ *\r
+ * Atomically sets the bits set in @mask in @v\r
+ */\r
+static inline void atomic_or(unsigned int mask, int *v)\r
+{\r
+    __asm__ __volatile__ (\r
+        "amoor.w zero, %1, %0"\r
+        : "+A" (*v)\r
+        : "r" (mask));\r
+}\r
+\r
+static inline int atomic_fetch_or(unsigned int mask, int *v)\r
+{\r
+    int out;\r
+    __asm__ __volatile__ (\r
+        "amoor.w %2, %1, %0"\r
+        : "+A" (*v), "=r" (out)\r
+        : "r" (mask));\r
+    return out;\r
+}\r
+\r
+/**\r
+ * atomic_xor - Atomically flips bits in atomic variable\r
+ * @mask: Mask of the bits to be flipped\r
+ * @v: pointer of type int\r
+ *\r
+ * Atomically flips the bits set in @mask in @v\r
+ */\r
+static inline void atomic_xor(unsigned int mask, int *v)\r
+{\r
+    __asm__ __volatile__ (\r
+        "amoxor.w zero, %1, %0"\r
+        : "+A" (*v)\r
+        : "r" (mask));\r
+}\r
+\r
+static inline int atomic_fetch_xor(unsigned int mask, int *v)\r
+{\r
+    int out;\r
+    __asm__ __volatile__ (\r
+        "amoxor.w %2, %1, %0"\r
+        : "+A" (*v), "=r" (out)\r
+        : "r" (mask));\r
+    return out;\r
+}\r
+\r
+/*----------------------------------------------------*/\r
+\r
+/**\r
+ * test_and_set_bit - Set a bit and return its old value\r
+ * @nr: Bit to set\r
+ * @addr: Address to count from\r
+ *\r
+ * This operation is atomic and cannot be reordered.\r
+ * It also implies a memory barrier.\r
+ */\r
+static inline int test_and_set_bit(int nr, volatile unsigned long *addr)\r
+{\r
+    unsigned long __res, __mask;\r
+    __mask = MASK(nr);\r
+    __asm__ __volatile__ (                \\r
+        "amoor.w %0, %2, %1"            \\r
+        : "=r" (__res), "+A" (*addr)    \\r
+        : "r" (__mask));                \\r
+\r
+        return ((__res & __mask) != 0);\r
+}\r
+\r
+\r
+/**\r
+ * test_and_clear_bit - Clear a bit and return its old value\r
+ * @nr: Bit to clear\r
+ * @addr: Address to count from\r
+ *\r
+ * This operation is atomic and cannot be reordered.\r
+ * It also implies a memory barrier.\r
+ */\r
+static inline int test_and_clear_bit(int nr, volatile unsigned long *addr)\r
+{\r
+    unsigned long __res, __mask;\r
+    __mask = MASK_NOT(nr);\r
+    __asm__ __volatile__ (                \\r
+        "amoand.w %0, %2, %1"            \\r
+        : "=r" (__res), "+A" (*addr)    \\r
+        : "r" (__mask));                \\r
+\r
+        return ((__res & __mask) != 0);\r
+}\r
+\r
+/**\r
+ * test_and_change_bit - Change a bit and return its old value\r
+ * @nr: Bit to change\r
+ * @addr: Address to count from\r
+ *\r
+ * This operation is atomic and cannot be reordered.\r
+ * It also implies a memory barrier.\r
+ */\r
+static inline int test_and_change_bit(int nr, volatile unsigned long *addr)\r
+{\r
+\r
+    unsigned long __res, __mask;\r
+    __mask = MASK(nr);\r
+    __asm__ __volatile__ (                \\r
+        "amoxor.w %0, %2, %1"            \\r
+        : "=r" (__res), "+A" (*addr)    \\r
+        : "r" (__mask));                \\r
+\r
+        return ((__res & __mask) != 0);\r
+}\r
+\r
+/**\r
+ * set_bit - Atomically set a bit in memory\r
+ * @nr: the bit to set\r
+ * @addr: the address to start counting from\r
+ *\r
+ * This function is atomic and may not be reordered. \r
+ */\r
+\r
+static inline void set_bit(int nr, volatile unsigned long *addr)\r
+{\r
+    __asm__ __volatile__ (                    \\r
+        "AMOOR.w zero, %1, %0"            \\r
+        : "+A" (*addr)            \\r
+        : "r" (MASK(nr)));\r
+}\r
+\r
+/**\r
+ * clear_bit - Clears a bit in memory\r
+ * @nr: Bit to clear\r
+ * @addr: Address to start counting from\r
+ *\r
+ * clear_bit() is atomic and may not be reordered.  \r
+ */\r
+static inline void clear_bit(int nr, volatile unsigned long *addr)\r
+{\r
+    __asm__ __volatile__ (                    \\r
+        "AMOAND.w zero, %1, %0"            \\r
+        : "+A" (*addr)            \\r
+        : "r" (MASK_NOT(nr)));\r
+}\r
+\r
+/**\r
+ * change_bit - Toggle a bit in memory\r
+ * @nr: Bit to change\r
+ * @addr: Address to start counting from\r
+ *\r
+ * change_bit() is atomic and may not be reordered.\r
+ */\r
+static inline void change_bit(int nr, volatile unsigned long *addr)\r
+{\r
+    __asm__ __volatile__ (                    \\r
+            "AMOXOR.w zero, %1, %0"            \\r
+            : "+A" (*addr)            \\r
+            : "r" (MASK(nr)));\r
+}\r
+\r
+#endif /* __riscv_atomic */\r
+\r
+#endif  /*__GNUC__*/\r
+\r
+#endif  /*__ASSEMBLER__*/\r
+\r
+#endif  /*__riscv*/\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif    /*RISCV_CSR_ENCODING_H*/\r
+\r
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 (file)
index 0000000..6e3ef92
--- /dev/null
@@ -0,0 +1,160 @@
+/*******************************************************************************\r
+ * (c) Copyright 2016-2018 Microsemi SoC Products Group.  All rights reserved.\r
+ *\r
+ * @file entry.S\r
+ * @author Microsemi SoC Products Group\r
+ * @brief Mi-V soft processor vectors, trap handling and startup code.\r
+ *\r
+ * SVN $Revision: 9947 $\r
+ * SVN $Date: 2018-04-30 20:28:49 +0530 (Mon, 30 Apr 2018) $\r
+ */\r
+#ifndef ENTRY_S\r
+#define ENTRY_S\r
+\r
+#include "encoding.h"\r
+\r
+#if __riscv_xlen == 64\r
+# define LREG ld\r
+# define SREG sd\r
+# define REGBYTES 8\r
+#else\r
+# define LREG lw\r
+# define SREG sw\r
+# define REGBYTES 4\r
+#endif\r
+\r
+  .section      .text.entry\r
+  .globl _start\r
+\r
+_start:\r
+  j handle_reset\r
+\r
+nmi_vector:\r
+  j nmi_vector\r
+\r
+trap_vector:\r
+  j trap_entry\r
+\r
+handle_reset:\r
+  la t0, trap_entry\r
+  csrw mtvec, t0\r
+  csrwi mstatus, 0\r
+  csrwi mie, 0\r
+\r
+/*Floating point support configuration*/\r
+\r
+#ifdef __riscv_flen\r
+  csrr t0, mstatus\r
+  lui t1, 0xffffa\r
+  addi t1, t1, -1\r
+  and t0, t0, t1\r
+  lui t1, 0x4\r
+  or t1, t0, t1\r
+  csrw mstatus, t1\r
+\r
+  lui t0, 0x0\r
+  fscsr t0\r
+#endif\r
+.option push\r
+\r
+# Ensure the instruction is not optimized, since gp is not yet set\r
+\r
+.option norelax\r
+  # initialize global pointer\r
+  la gp, __global_pointer$\r
+\r
+.option pop\r
+\r
+  # initialize stack pointer\r
+  la sp, __stack_top\r
+\r
+  # perform the rest of initialization in C\r
+  j _init\r
+\r
+\r
+trap_entry:\r
+  addi sp, sp, -32*REGBYTES\r
+\r
+  SREG x1, 0 * REGBYTES(sp)\r
+  SREG x2, 1 * REGBYTES(sp)\r
+  SREG x3, 2 * REGBYTES(sp)\r
+  SREG x4, 3 * REGBYTES(sp)\r
+  SREG x5, 4 * REGBYTES(sp)\r
+  SREG x6, 5 * REGBYTES(sp)\r
+  SREG x7, 6 * REGBYTES(sp)\r
+  SREG x8, 7 * REGBYTES(sp)\r
+  SREG x9, 8 * REGBYTES(sp)\r
+  SREG x10, 9 * REGBYTES(sp)\r
+  SREG x11, 10 * REGBYTES(sp)\r
+  SREG x12, 11 * REGBYTES(sp)\r
+  SREG x13, 12 * REGBYTES(sp)\r
+  SREG x14, 13 * REGBYTES(sp)\r
+  SREG x15, 14 * REGBYTES(sp)\r
+  SREG x16, 15 * REGBYTES(sp)\r
+  SREG x17, 16 * REGBYTES(sp)\r
+  SREG x18, 17 * REGBYTES(sp)\r
+  SREG x19, 18 * REGBYTES(sp)\r
+  SREG x20, 19 * REGBYTES(sp)\r
+  SREG x21, 20 * REGBYTES(sp)\r
+  SREG x22, 21 * REGBYTES(sp)\r
+  SREG x23, 22 * REGBYTES(sp)\r
+  SREG x24, 23 * REGBYTES(sp)\r
+  SREG x25, 24 * REGBYTES(sp)\r
+  SREG x26, 25 * REGBYTES(sp)\r
+  SREG x27, 26 * REGBYTES(sp)\r
+  SREG x28, 27 * REGBYTES(sp)\r
+  SREG x29, 28 * REGBYTES(sp)\r
+  SREG x30, 29 * REGBYTES(sp)\r
+  SREG x31, 30 * REGBYTES(sp)\r
+\r
+\r
+  csrr t0, mepc\r
+  SREG t0, 31 * REGBYTES(sp)\r
+\r
+  csrr a0, mcause\r
+  csrr a1, mepc\r
+  mv a2, sp\r
+  jal handle_trap\r
+  csrw mepc, a0\r
+\r
+  # Remain in M-mode after mret\r
+  li t0, MSTATUS_MPP\r
+  csrs mstatus, t0\r
+\r
+  LREG x1, 0 * REGBYTES(sp)\r
+  LREG x2, 1 * REGBYTES(sp)\r
+  LREG x3, 2 * REGBYTES(sp)\r
+  LREG x4, 3 * REGBYTES(sp)\r
+  LREG x5, 4 * REGBYTES(sp)\r
+  LREG x6, 5 * REGBYTES(sp)\r
+  LREG x7, 6 * REGBYTES(sp)\r
+  LREG x8, 7 * REGBYTES(sp)\r
+  LREG x9, 8 * REGBYTES(sp)\r
+  LREG x10, 9 * REGBYTES(sp)\r
+  LREG x11, 10 * REGBYTES(sp)\r
+  LREG x12, 11 * REGBYTES(sp)\r
+  LREG x13, 12 * REGBYTES(sp)\r
+  LREG x14, 13 * REGBYTES(sp)\r
+  LREG x15, 14 * REGBYTES(sp)\r
+  LREG x16, 15 * REGBYTES(sp)\r
+  LREG x17, 16 * REGBYTES(sp)\r
+  LREG x18, 17 * REGBYTES(sp)\r
+  LREG x19, 18 * REGBYTES(sp)\r
+  LREG x20, 19 * REGBYTES(sp)\r
+  LREG x21, 20 * REGBYTES(sp)\r
+  LREG x22, 21 * REGBYTES(sp)\r
+  LREG x23, 22 * REGBYTES(sp)\r
+  LREG x24, 23 * REGBYTES(sp)\r
+  LREG x25, 24 * REGBYTES(sp)\r
+  LREG x26, 25 * REGBYTES(sp)\r
+  LREG x27, 26 * REGBYTES(sp)\r
+  LREG x28, 27 * REGBYTES(sp)\r
+  LREG x29, 28 * REGBYTES(sp)\r
+  LREG x30, 29 * REGBYTES(sp)\r
+  LREG x31, 30 * REGBYTES(sp)\r
+\r
+  addi sp, sp, 32*REGBYTES\r
+  mret\r
+\r
+#endif\r
+\r
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 (file)
index 0000000..8c5998f
--- /dev/null
@@ -0,0 +1,80 @@
+/*******************************************************************************\r
+ * (c) Copyright 2016-2018 Microsemi SoC Products Group.  All rights reserved.\r
+ *\r
+ * @file init.c\r
+ * @author Microsemi SoC Products Group\r
+ * @brief Mi-V soft processor memory section initializations and start-up code.\r
+ *\r
+ * SVN $Revision: 9661 $\r
+ * SVN $Date: 2018-01-15 16:13:33 +0530 (Mon, 15 Jan 2018) $\r
+ */\r
+\r
+#include <stdlib.h>\r
+#include <stdint.h>\r
+#include <unistd.h>\r
+\r
+#include "encoding.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+extern uint32_t     __sdata_load;\r
+extern uint32_t     __sdata_start;\r
+extern uint32_t     __sdata_end;\r
+\r
+extern uint32_t     __data_load;\r
+extern uint32_t     __data_start;\r
+extern uint32_t     __data_end;\r
+\r
+extern uint32_t     __sbss_start;\r
+extern uint32_t     __sbss_end;\r
+extern uint32_t     __bss_start;\r
+extern uint32_t     __bss_end;\r
+\r
+\r
+static void copy_section(uint32_t * p_load, uint32_t * p_vma, uint32_t * p_vma_end)\r
+{\r
+    while(p_vma <= p_vma_end)\r
+    {\r
+        *p_vma = *p_load;\r
+        ++p_load;\r
+        ++p_vma;\r
+    }\r
+}\r
+\r
+static void zero_section(uint32_t * start, uint32_t * end)\r
+{\r
+    uint32_t * p_zero = start;\r
+    \r
+    while(p_zero <= end)\r
+    {\r
+        *p_zero = 0;\r
+        ++p_zero;\r
+    }\r
+}\r
+\r
+void _init(void)\r
+{\r
+    extern int main(int, char**);\r
+    const char *argv0 = "hello";\r
+    char *argv[] = {(char *)argv0, NULL, NULL};\r
+\r
+    copy_section(&__sdata_load, &__sdata_start, &__sdata_end);\r
+    copy_section(&__data_load, &__data_start, &__data_end);\r
+    zero_section(&__sbss_start, &__sbss_end);\r
+    zero_section(&__bss_start, &__bss_end);\r
+    \r
+    main(1, argv);\r
+}\r
+\r
+/* Function called after main() finishes */\r
+void\r
+_fini()\r
+{\r
+}\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
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 (file)
index 0000000..11d0697
--- /dev/null
@@ -0,0 +1,137 @@
+/*******************************************************************************\r
+ * (c) Copyright 2016-2018 Microsemi SoC Products Group.  All rights reserved.\r
+ * \r
+ * file name : microsemi-riscv-igloo2.ld\r
+ * Mi-V soft processor linker script for creating a SoftConsole downloadable\r
+ * image executing in eNVM.\r
+ * \r
+ * This linker script assumes that the eNVM is connected at on the Mi-V soft\r
+ * processor memory space. \r
+ *\r
+ * SVN $Revision: 9661 $\r
+ * SVN $Date: 2018-01-15 16:13:33 +0530 (Mon, 15 Jan 2018) $\r
+ */\r
\r
+OUTPUT_ARCH( "riscv" )\r
+ENTRY(_start)\r
+\r
+\r
+MEMORY\r
+{\r
+    envm (rx) : ORIGIN = 0x60000000, LENGTH = 240k\r
+    ram (rwx) : ORIGIN = 0x80000000, LENGTH = 64k\r
+}\r
+\r
+RAM_START_ADDRESS   = 0x80000000;       /* Must be the same value MEMORY region ram ORIGIN above. */\r
+RAM_SIZE            = 64k;              /* Must be the same value MEMORY region ram LENGTH above. */\r
+STACK_SIZE          = 2k;               /* needs to be calculated for your application */             \r
+HEAP_SIZE           = 2k;               /* needs to be calculated for your application */\r
+\r
+SECTIONS\r
+{\r
+  .text : ALIGN(0x10)\r
+  {\r
+    KEEP (*(SORT_NONE(.text.entry)))   \r
+    . = ALIGN(0x10);\r
+    *(.text .text.* .gnu.linkonce.t.*)\r
+    *(.plt)\r
+    . = ALIGN(0x10);\r
+    \r
+    KEEP (*crtbegin.o(.ctors))\r
+    KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))\r
+    KEEP (*(SORT(.ctors.*)))\r
+    KEEP (*crtend.o(.ctors))\r
+    KEEP (*crtbegin.o(.dtors))\r
+    KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))\r
+    KEEP (*(SORT(.dtors.*)))\r
+    KEEP (*crtend.o(.dtors))\r
+    \r
+    *(.rodata .rodata.* .gnu.linkonce.r.*)\r
+    *(.gcc_except_table) \r
+    *(.eh_frame_hdr)\r
+    *(.eh_frame)\r
+    \r
+    KEEP (*(.init))\r
+    KEEP (*(.fini))\r
+\r
+    PROVIDE_HIDDEN (__preinit_array_start = .);\r
+    KEEP (*(.preinit_array))\r
+    PROVIDE_HIDDEN (__preinit_array_end = .);\r
+    PROVIDE_HIDDEN (__init_array_start = .);\r
+    KEEP (*(SORT(.init_array.*)))\r
+    KEEP (*(.init_array))\r
+    PROVIDE_HIDDEN (__init_array_end = .);\r
+    PROVIDE_HIDDEN (__fini_array_start = .);\r
+    KEEP (*(.fini_array))\r
+    KEEP (*(SORT(.fini_array.*)))\r
+    PROVIDE_HIDDEN (__fini_array_end = .);\r
+    . = ALIGN(0x10);\r
+    \r
+  } >envm\r
+\r
+  /* short/global data section */\r
+  .sdata : ALIGN(0x10)\r
+  {\r
+    __sdata_load = LOADADDR(.sdata);\r
+    __sdata_start = .; \r
+    PROVIDE( __global_pointer$ = . + 0x800);\r
+    *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2)\r
+    *(.srodata*)\r
+    *(.sdata .sdata.* .gnu.linkonce.s.*)\r
+    . = ALIGN(0x10);\r
+    __sdata_end = .;\r
+  } >ram AT>envm\r
+\r
+  /* data section */\r
+  .data : ALIGN(0x10)\r
+  { \r
+    __data_load = LOADADDR(.data);\r
+    __data_start = .; \r
+    *(.got.plt) *(.got)\r
+    *(.shdata)\r
+    *(.data .data.* .gnu.linkonce.d.*)\r
+    . = ALIGN(0x10);\r
+    __data_end = .;\r
+  } >ram AT>envm\r
+\r
+  /* sbss section */\r
+  .sbss : ALIGN(0x10)\r
+  {\r
+    __sbss_start = .;\r
+    *(.sbss .sbss.* .gnu.linkonce.sb.*)\r
+    *(.scommon)\r
+    . = ALIGN(0x10);\r
+    __sbss_end = .;\r
+  } > ram\r
+  \r
+  /* sbss section */\r
+  .bss : ALIGN(0x10)\r
+  { \r
+    __bss_start = .;\r
+    *(.shbss)\r
+    *(.bss .bss.* .gnu.linkonce.b.*)\r
+    *(COMMON)\r
+    . = ALIGN(0x10);\r
+    __bss_end = .;\r
+  } > ram\r
+\r
+  /* End of uninitialized data segment */\r
+  _end = .;\r
+  \r
+  .heap : ALIGN(0x10)\r
+  {\r
+    __heap_start = .;\r
+    . += HEAP_SIZE;\r
+    __heap_end = .;\r
+    . = ALIGN(0x10);\r
+    _heap_end = __heap_end;\r
+  } > ram\r
+  \r
+  .stack : ALIGN(0x10)\r
+  {\r
+    __stack_bottom = .;\r
+    . += STACK_SIZE;\r
+    __stack_top = .;\r
+  } > ram\r
+}\r
+\r
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 (file)
index 0000000..d63709e
--- /dev/null
@@ -0,0 +1,137 @@
+/*******************************************************************************\r
+ * (c) Copyright 2016-2018 Microsemi SoC Products Group.  All rights reserved.\r
+ * \r
+ * file name : microsemi-riscv-ram.ld\r
+ * Mi-V soft processor linker script for creating a SoftConsole downloadable\r
+ * debug image executing in SRAM.\r
+ * \r
+ * This linker script assumes that the SRAM is connected at on the Mi-V soft\r
+ * processor memory space. The start address and size of the memory space must\r
+ * be correct as per the Libero design.\r
+ *\r
+ * SVN $Revision: 9661 $\r
+ * SVN $Date: 2018-01-15 16:13:33 +0530 (Mon, 15 Jan 2018) $\r
+ */\r
\r
+OUTPUT_ARCH( "riscv" )\r
+ENTRY(_start)\r
+\r
+\r
+MEMORY\r
+{\r
+    ram (rwx) : ORIGIN = 0x80000000, LENGTH = 512k\r
+}\r
+\r
+RAM_START_ADDRESS   = 0x80000000;       /* Must be the same value MEMORY region ram ORIGIN above. */\r
+RAM_SIZE            = 512k;              /* Must be the same value MEMORY region ram LENGTH above. */\r
+STACK_SIZE          = 64k;               /* needs to be calculated for your application */             \r
+HEAP_SIZE           = 64k;               /* needs to be calculated for your application */\r
+\r
+SECTIONS\r
+{\r
+  .text : ALIGN(0x10)\r
+  {\r
+    KEEP (*(SORT_NONE(.text.entry)))   \r
+    . = ALIGN(0x10);\r
+    *(.text .text.* .gnu.linkonce.t.*)\r
+    *(.plt)\r
+    . = ALIGN(0x10);\r
+    \r
+    KEEP (*crtbegin.o(.ctors))\r
+    KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))\r
+    KEEP (*(SORT(.ctors.*)))\r
+    KEEP (*crtend.o(.ctors))\r
+    KEEP (*crtbegin.o(.dtors))\r
+    KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))\r
+    KEEP (*(SORT(.dtors.*)))\r
+    KEEP (*crtend.o(.dtors))\r
+    \r
+    *(.rodata .rodata.* .gnu.linkonce.r.*)\r
+    *(.gcc_except_table) \r
+    *(.eh_frame_hdr)\r
+    *(.eh_frame)\r
+    \r
+    KEEP (*(.init))\r
+    KEEP (*(.fini))\r
+\r
+    PROVIDE_HIDDEN (__preinit_array_start = .);\r
+    KEEP (*(.preinit_array))\r
+    PROVIDE_HIDDEN (__preinit_array_end = .);\r
+    PROVIDE_HIDDEN (__init_array_start = .);\r
+    KEEP (*(SORT(.init_array.*)))\r
+    KEEP (*(.init_array))\r
+    PROVIDE_HIDDEN (__init_array_end = .);\r
+    PROVIDE_HIDDEN (__fini_array_start = .);\r
+    KEEP (*(.fini_array))\r
+    KEEP (*(SORT(.fini_array.*)))\r
+    PROVIDE_HIDDEN (__fini_array_end = .);\r
+    . = ALIGN(0x10);\r
+    \r
+  } > ram\r
+\r
+  /* short/global data section */\r
+  .sdata : ALIGN(0x10)\r
+  {\r
+    __sdata_load = LOADADDR(.sdata);\r
+    __sdata_start = .; \r
+    PROVIDE( __global_pointer$ = . + 0x800);\r
+    *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2)\r
+    *(.srodata*)\r
+    *(.sdata .sdata.* .gnu.linkonce.s.*)\r
+    . = ALIGN(0x10);\r
+    __sdata_end = .;\r
+  } > ram\r
+\r
+  /* data section */\r
+  .data : ALIGN(0x10)\r
+  { \r
+    __data_load = LOADADDR(.data);\r
+    __data_start = .; \r
+    *(.got.plt) *(.got)\r
+    *(.shdata)\r
+    *(.data .data.* .gnu.linkonce.d.*)\r
+    . = ALIGN(0x10);\r
+    __data_end = .;\r
+  } > ram\r
+\r
+  /* sbss section */\r
+  .sbss : ALIGN(0x10)\r
+  {\r
+    __sbss_start = .;\r
+    *(.sbss .sbss.* .gnu.linkonce.sb.*)\r
+    *(.scommon)\r
+    . = ALIGN(0x10);\r
+    __sbss_end = .;\r
+  } > ram\r
+  \r
+  /* sbss section */\r
+  .bss : ALIGN(0x10)\r
+  { \r
+    __bss_start = .;\r
+    *(.shbss)\r
+    *(.bss .bss.* .gnu.linkonce.b.*)\r
+    *(COMMON)\r
+    . = ALIGN(0x10);\r
+    __bss_end = .;\r
+  } > ram\r
+\r
+  /* End of uninitialized data segment */\r
+  _end = .;\r
+  \r
+  .heap : ALIGN(0x10)\r
+  {\r
+    __heap_start = .;\r
+    . += HEAP_SIZE;\r
+    __heap_end = .;\r
+    . = ALIGN(0x10);\r
+    _heap_end = __heap_end;\r
+  } > ram\r
+  \r
+  .stack : ALIGN(0x10)\r
+  {\r
+    __stack_bottom = .;\r
+    . += STACK_SIZE;\r
+    __stack_top = .;\r
+  } > ram\r
+}\r
+\r
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 (file)
index 0000000..f7be82c
--- /dev/null
@@ -0,0 +1,251 @@
+/*******************************************************************************\r
+ * (c) Copyright 2016-2018 Microsemi SoC Products Group. All rights reserved.\r
+ *\r
+ * @file riscv_hal.c\r
+ * @author Microsemi SoC Products Group\r
+ * @brief Implementation of Hardware Abstraction Layer for Mi-V soft processors\r
+ *\r
+ * SVN $Revision: 9835 $\r
+ * SVN $Date: 2018-03-19 19:11:35 +0530 (Mon, 19 Mar 2018) $\r
+ */\r
+#include <stdlib.h>\r
+#include <stdint.h>\r
+#include <unistd.h>\r
+\r
+#include "riscv_hal.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+#define RTC_PRESCALER 100UL\r
+\r
+#define SUCCESS 0U\r
+#define ERROR   1U\r
+\r
+/*------------------------------------------------------------------------------\r
+ *\r
+ */\r
+uint8_t Invalid_IRQHandler(void);\r
+uint8_t External_1_IRQHandler(void);\r
+uint8_t External_2_IRQHandler(void);\r
+uint8_t External_3_IRQHandler(void);\r
+uint8_t External_4_IRQHandler(void);\r
+uint8_t External_5_IRQHandler(void);\r
+uint8_t External_6_IRQHandler(void);\r
+uint8_t External_7_IRQHandler(void);\r
+uint8_t External_8_IRQHandler(void);\r
+uint8_t External_9_IRQHandler(void);\r
+uint8_t External_10_IRQHandler(void);\r
+uint8_t External_11_IRQHandler(void);\r
+uint8_t External_12_IRQHandler(void);\r
+uint8_t External_13_IRQHandler(void);\r
+uint8_t External_14_IRQHandler(void);\r
+uint8_t External_15_IRQHandler(void);\r
+uint8_t External_16_IRQHandler(void);\r
+uint8_t External_17_IRQHandler(void);\r
+uint8_t External_18_IRQHandler(void);\r
+uint8_t External_19_IRQHandler(void);\r
+uint8_t External_20_IRQHandler(void);\r
+uint8_t External_21_IRQHandler(void);\r
+uint8_t External_22_IRQHandler(void);\r
+uint8_t External_23_IRQHandler(void);\r
+uint8_t External_24_IRQHandler(void);\r
+uint8_t External_25_IRQHandler(void);\r
+uint8_t External_26_IRQHandler(void);\r
+uint8_t External_27_IRQHandler(void);\r
+uint8_t External_28_IRQHandler(void);\r
+uint8_t External_29_IRQHandler(void);\r
+uint8_t External_30_IRQHandler(void);\r
+uint8_t External_31_IRQHandler(void);\r
+\r
+/*------------------------------------------------------------------------------\r
+ *\r
+ */\r
+extern void Software_IRQHandler(void);\r
+\r
+/*------------------------------------------------------------------------------\r
+ * Increment value for the mtimecmp register in order to achieve a system tick\r
+ * interrupt as specified through the SysTick_Config() function.\r
+ */\r
+static uint64_t g_systick_increment = 0U;\r
+\r
+/*------------------------------------------------------------------------------\r
+ * Disable all interrupts.\r
+ */\r
+void __disable_irq(void)\r
+{\r
+    clear_csr(mstatus, MSTATUS_MPIE);\r
+    clear_csr(mstatus, MSTATUS_MIE);\r
+}\r
+\r
+/*------------------------------------------------------------------------------\r
+ * Enabler all interrupts.\r
+ */\r
+void __enable_irq(void)\r
+{\r
+    set_csr(mstatus, MSTATUS_MIE);\r
+}\r
+\r
+/*------------------------------------------------------------------------------\r
+ * Configure the machine timer to generate an interrupt.\r
+ */\r
+uint32_t SysTick_Config(uint32_t ticks)\r
+{\r
+    uint32_t ret_val = ERROR;\r
+\r
+    g_systick_increment = (uint64_t)(ticks) / RTC_PRESCALER;\r
+\r
+    if (g_systick_increment > 0U)\r
+    {\r
+        uint32_t mhart_id = read_csr(mhartid);\r
+\r
+        PRCI->MTIMECMP[mhart_id] = PRCI->MTIME + g_systick_increment;\r
+\r
+        set_csr(mie, MIP_MTIP);\r
+\r
+        __enable_irq();\r
+\r
+        ret_val = SUCCESS;\r
+    }\r
+\r
+    return ret_val;\r
+}\r
+\r
+/*------------------------------------------------------------------------------\r
+ * RISC-V interrupt handler for machine timer interrupts.\r
+ */\r
+static void handle_m_timer_interrupt(void)\r
+{\r
+    clear_csr(mie, MIP_MTIP);\r
+\r
+    SysTick_Handler();\r
+\r
+    PRCI->MTIMECMP[read_csr(mhartid)] = PRCI->MTIME + g_systick_increment;\r
+\r
+    set_csr(mie, MIP_MTIP);\r
+}\r
+\r
+/*------------------------------------------------------------------------------\r
+ * RISC-V interrupt handler for external interrupts.\r
+ */\r
+uint8_t (*ext_irq_handler_table[32])(void) =\r
+{\r
+    Invalid_IRQHandler,\r
+    External_1_IRQHandler,\r
+    External_2_IRQHandler,\r
+    External_3_IRQHandler,\r
+    External_4_IRQHandler,\r
+    External_5_IRQHandler,\r
+    External_6_IRQHandler,\r
+    External_7_IRQHandler,\r
+    External_8_IRQHandler,\r
+    External_9_IRQHandler,\r
+    External_10_IRQHandler,\r
+    External_11_IRQHandler,\r
+    External_12_IRQHandler,\r
+    External_13_IRQHandler,\r
+    External_14_IRQHandler,\r
+    External_15_IRQHandler,\r
+    External_16_IRQHandler,\r
+    External_17_IRQHandler,\r
+    External_18_IRQHandler,\r
+    External_19_IRQHandler,\r
+    External_20_IRQHandler,\r
+    External_21_IRQHandler,\r
+    External_22_IRQHandler,\r
+    External_23_IRQHandler,\r
+    External_24_IRQHandler,\r
+    External_25_IRQHandler,\r
+    External_26_IRQHandler,\r
+    External_27_IRQHandler,\r
+    External_28_IRQHandler,\r
+    External_29_IRQHandler,\r
+    External_30_IRQHandler,\r
+    External_31_IRQHandler\r
+};\r
+\r
+/*------------------------------------------------------------------------------\r
+ *\r
+ */\r
+static void handle_m_ext_interrupt(void)\r
+{\r
+    uint32_t int_num  = PLIC_ClaimIRQ();\r
+    uint8_t disable = EXT_IRQ_KEEP_ENABLED;\r
+\r
+    disable = ext_irq_handler_table[int_num]();\r
+\r
+    PLIC_CompleteIRQ(int_num);\r
+\r
+    if(EXT_IRQ_DISABLE == disable)\r
+    {\r
+        PLIC_DisableIRQ((IRQn_Type)int_num);\r
+    }\r
+}\r
+\r
+static void handle_m_soft_interrupt(void)\r
+{\r
+    Software_IRQHandler();\r
+\r
+    /*Clear software interrupt*/\r
+    PRCI->MSIP[0] = 0x00U;\r
+}\r
+\r
+/*------------------------------------------------------------------------------\r
+ * Trap/Interrupt handler\r
+ */\r
+uintptr_t handle_trap(uintptr_t mcause, uintptr_t mepc)\r
+{\r
+    if ((mcause & MCAUSE_INT) && ((mcause & MCAUSE_CAUSE)  == IRQ_M_EXT))\r
+    {\r
+        handle_m_ext_interrupt();\r
+    }\r
+    else if ((mcause & MCAUSE_INT) && ((mcause & MCAUSE_CAUSE)  == IRQ_M_TIMER))\r
+    {\r
+        handle_m_timer_interrupt();\r
+    }\r
+    else if ( (mcause & MCAUSE_INT) && ((mcause & MCAUSE_CAUSE)  == IRQ_M_SOFT))\r
+    {\r
+        handle_m_soft_interrupt();\r
+    }\r
+    else\r
+    {\r
+#ifndef NDEBUG\r
+        /*\r
+         Arguments supplied to this function are mcause, mepc (exception PC) and stack pointer\r
+         based onprivileged-isa specification\r
+         mcause values and meanings are:\r
+         0 Instruction address misaligned (mtval/mbadaddr is the address)\r
+         1 Instruction access fault       (mtval/mbadaddr is the address)\r
+         2 Illegal instruction            (mtval/mbadaddr contains the offending instruction opcode)\r
+         3 Breakpoint\r
+         4 Load address misaligned        (mtval/mbadaddr is the address)\r
+         5 Load address fault             (mtval/mbadaddr is the address)\r
+         6 Store/AMO address fault        (mtval/mbadaddr is the address)\r
+         7 Store/AMO access fault         (mtval/mbadaddr is the address)\r
+         8 Environment call from U-mode\r
+         9 Environment call from S-mode\r
+         A Environment call from M-mode\r
+         B Instruction page fault\r
+         C Load page fault                (mtval/mbadaddr is the address)\r
+         E Store page fault               (mtval/mbadaddr is the address)\r
+        */\r
+\r
+         uintptr_t mip      = read_csr(mip);      /* interrupt pending */\r
+         uintptr_t mbadaddr = read_csr(mbadaddr); /* additional info and meaning depends on mcause */\r
+         uintptr_t mtvec    = read_csr(mtvec);    /* trap vector */\r
+         uintptr_t mscratch = read_csr(mscratch); /* temporary, sometimes might hold temporary value of a0 */\r
+         uintptr_t mstatus  = read_csr(mstatus);  /* status contains many smaller fields: */\r
+\r
+               /* breakpoint*/\r
+        __asm("ebreak");\r
+#else\r
+        _exit(1 + mcause);\r
+#endif\r
+    }\r
+    return mepc;\r
+}\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
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 (file)
index 0000000..7c3835f
--- /dev/null
@@ -0,0 +1,55 @@
+/*******************************************************************************\r
+ * (c) Copyright 2016-2018 Microsemi SoC Products Group. All rights reserved.\r
+ *\r
+ * @file riscv_hal.h\r
+ * @author Microsemi SoC Products Group\r
+ * @brief Hardware Abstraction Layer functions for Mi-V soft processors\r
+ *\r
+ * SVN $Revision: 9835 $\r
+ * SVN $Date: 2018-03-19 19:11:35 +0530 (Mon, 19 Mar 2018) $\r
+ */\r
+\r
+#ifndef RISCV_HAL_H\r
+#define RISCV_HAL_H\r
+\r
+#include "riscv_plic.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+/*\r
+ *Return value from External IRQ handler. This will be used to disable the External\r
+ *interrupt.\r
+ */\r
+#define EXT_IRQ_KEEP_ENABLED                0U\r
+#define EXT_IRQ_DISABLE                     1U\r
+\r
+/*------------------------------------------------------------------------------\r
+ * Interrupt enable/disable.\r
+ */\r
+void __disable_irq(void);\r
+void __enable_irq(void);\r
+\r
+/*------------------------------------------------------------------------------\r
+ *  System tick handler. This is generated from the RISC-V machine timer.\r
+ */\r
+void SysTick_Handler(void);\r
+\r
+/*------------------------------------------------------------------------------\r
+ * System tick configuration.\r
+ * Configures the machine timer to generate a system tick interrupt at regular\r
+ * intervals.\r
+ * Takes the number of system clock ticks between interrupts.\r
+ *\r
+ * Returns 0 if successful.\r
+ * Returns 1 if the interrupt interval cannot be achieved.\r
+ */\r
+uint32_t SysTick_Config(uint32_t ticks);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif  /* RISCV_HAL_H */\r
+\r
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 (file)
index 0000000..29a4f40
--- /dev/null
@@ -0,0 +1,227 @@
+/*******************************************************************************\r
+ * (c) Copyright 2016-2018 Microsemi SoC Products Group. All rights reserved.\r
+ *\r
+ * @file riscv_hal_stubs.c\r
+ * @author Microsemi SoC Products Group\r
+ * @brief Mi-V soft processor Interrupt Function stubs.\r
+ * The functions below will only be linked with the application code if the user\r
+ * does not provide an implementation for these functions. These functions are\r
+ * defined with weak linking so that they can be overridden by a function with\r
+ * same prototype in the user's application code.\r
+ *\r
+ * SVN $Revision: 9835 $\r
+ * SVN $Date: 2018-03-19 19:11:35 +0530 (Mon, 19 Mar 2018) $\r
+ */\r
+#include <unistd.h>\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+/*Weakly linked handler. Will be replaced with user's definition if provided*/\r
+__attribute__((weak)) void Software_IRQHandler(void)\r
+{\r
+    _exit(10);\r
+}\r
+\r
+/*Weakly linked handler. Will be replaced with user's definition if provided*/\r
+__attribute__((weak)) void SysTick_Handler(void)\r
+{\r
+       /*Default handler*/\r
+}\r
+\r
+/*Weakly linked handler. Will be replaced with user's definition if provided*/\r
+__attribute__((weak)) uint8_t Invalid_IRQHandler(void)\r
+{\r
+    return(0U); /*Default handler*/\r
+}\r
+\r
+/*Weakly linked handler. Will be replaced with user's definition if provided*/\r
+__attribute__((weak)) uint8_t External_1_IRQHandler(void)\r
+{\r
+    return(0U); /*Default handler*/\r
+}\r
+\r
+/*Weakly linked handler. Will be replaced with user's definition if provided*/\r
+__attribute__((weak)) uint8_t External_2_IRQHandler(void)\r
+{\r
+    return(0U); /*Default handler*/\r
+}\r
+\r
+/*Weakly linked handler. Will be replaced with user's definition if provided*/\r
+__attribute__((weak)) uint8_t External_3_IRQHandler(void)\r
+{\r
+    return(0U); /*Default handler*/\r
+}\r
+\r
+/*Weakly linked handler. Will be replaced with user's definition if provided*/\r
+__attribute__((weak)) uint8_t External_4_IRQHandler(void)\r
+{\r
+       return(0U); /*Default handler*/\r
+}\r
+\r
+/*Weakly linked handler. Will be replaced with user's definition if provided*/\r
+__attribute__((weak)) uint8_t External_5_IRQHandler(void)\r
+{\r
+    return(0U); /*Default handler*/\r
+}\r
+\r
+/*Weakly linked handler. Will be replaced with user's definition if provided*/\r
+__attribute__((weak)) uint8_t External_6_IRQHandler(void)\r
+{\r
+    return(0U); /*Default handler*/\r
+}\r
+\r
+/*Weakly linked handler. Will be replaced with user's definition if provided*/\r
+__attribute__((weak)) uint8_t External_7_IRQHandler(void)\r
+{\r
+    return(0U); /*Default handler*/\r
+}\r
+\r
+/*Weakly linked handler. Will be replaced with user's definition if provided*/\r
+__attribute__((weak)) uint8_t External_8_IRQHandler(void)\r
+{\r
+    return(0U); /*Default handler*/\r
+}\r
+\r
+/*Weakly linked handler. Will be replaced with user's definition if provided*/\r
+__attribute__((weak)) uint8_t External_9_IRQHandler(void)\r
+{\r
+    return(0U); /*Default handler*/\r
+}\r
+\r
+/*Weakly linked handler. Will be replaced with user's definition if provided*/\r
+__attribute__((weak)) uint8_t External_10_IRQHandler(void)\r
+{\r
+    return(0U); /*Default handler*/\r
+}\r
+\r
+/*Weakly linked handler. Will be replaced with user's definition if provided*/\r
+__attribute__((weak)) uint8_t External_11_IRQHandler(void)\r
+{\r
+    return(0U); /*Default handler*/\r
+}\r
+\r
+/*Weakly linked handler. Will be replaced with user's definition if provided*/\r
+__attribute__((weak)) uint8_t External_12_IRQHandler(void)\r
+{\r
+       return(0U); /*Default handler*/\r
+}\r
+\r
+/*Weakly linked handler. Will be replaced with user's definition if provided*/\r
+__attribute__((weak)) uint8_t External_13_IRQHandler(void)\r
+{\r
+       return(0U); /*Default handler*/\r
+}\r
+\r
+/*Weakly linked handler. Will be replaced with user's definition if provided*/\r
+__attribute__((weak)) uint8_t External_14_IRQHandler(void)\r
+{\r
+       return(0U); /*Default handler*/\r
+}\r
+\r
+/*Weakly linked handler. Will be replaced with user's definition if provided*/\r
+__attribute__((weak)) uint8_t External_15_IRQHandler(void)\r
+{\r
+       return(0U); /*Default handler*/\r
+}\r
+\r
+/*Weakly linked handler. Will be replaced with user's definition if provided*/\r
+__attribute__((weak)) uint8_t External_16_IRQHandler(void)\r
+{\r
+       return(0U); /*Default handler*/\r
+}\r
+\r
+/*Weakly linked handler. Will be replaced with user's definition if provided*/\r
+__attribute__((weak)) uint8_t External_17_IRQHandler(void)\r
+{\r
+       return(0U); /*Default handler*/\r
+}\r
+\r
+/*Weakly linked handler. Will be replaced with user's definition if provided*/\r
+__attribute__((weak)) uint8_t External_18_IRQHandler(void)\r
+{\r
+       return(0U); /*Default handler*/\r
+}\r
+\r
+/*Weakly linked handler. Will be replaced with user's definition if provided*/\r
+__attribute__((weak)) uint8_t External_19_IRQHandler(void)\r
+{\r
+       return(0U); /*Default handler*/\r
+}\r
+\r
+/*Weakly linked handler. Will be replaced with user's definition if provided*/\r
+__attribute__((weak)) uint8_t External_20_IRQHandler(void)\r
+{\r
+       return(0U); /*Default handler*/\r
+}\r
+\r
+/*Weakly linked handler. Will be replaced with user's definition if provided*/\r
+__attribute__((weak)) uint8_t External_21_IRQHandler(void)\r
+{\r
+       return(0U); /*Default handler*/\r
+}\r
+\r
+/*Weakly linked handler. Will be replaced with user's definition if provided*/\r
+__attribute__((weak)) uint8_t External_22_IRQHandler(void)\r
+{\r
+       return(0U); /*Default handler*/\r
+}\r
+\r
+/*Weakly linked handler. Will be replaced with user's definition if provided*/\r
+__attribute__((weak)) uint8_t External_23_IRQHandler(void)\r
+{\r
+       return(0U); /*Default handler*/\r
+}\r
+\r
+/*Weakly linked handler. Will be replaced with user's definition if provided*/\r
+__attribute__((weak)) uint8_t External_24_IRQHandler(void)\r
+{\r
+       return(0U); /*Default handler*/\r
+}\r
+\r
+/*Weakly linked handler. Will be replaced with user's definition if provided*/\r
+__attribute__((weak)) uint8_t External_25_IRQHandler(void)\r
+{\r
+       return(0U); /*Default handler*/\r
+}\r
+\r
+/*Weakly linked handler. Will be replaced with user's definition if provided*/\r
+__attribute__((weak)) uint8_t External_26_IRQHandler(void)\r
+{\r
+       return(0U); /*Default handler*/\r
+}\r
+\r
+/*Weakly linked handler. Will be replaced with user's definition if provided*/\r
+__attribute__((weak)) uint8_t External_27_IRQHandler(void)\r
+{\r
+       return(0U); /*Default handler*/\r
+}\r
+\r
+/*Weakly linked handler. Will be replaced with user's definition if provided*/\r
+__attribute__((weak)) uint8_t External_28_IRQHandler(void)\r
+{\r
+       return(0U); /*Default handler*/\r
+}\r
+\r
+/*Weakly linked handler. Will be replaced with user's definition if provided*/\r
+__attribute__((weak)) uint8_t External_29_IRQHandler(void)\r
+{\r
+       return(0U); /*Default handler*/\r
+}\r
+\r
+/*Weakly linked handler. Will be replaced with user's definition if provided*/\r
+__attribute__((weak)) uint8_t External_30_IRQHandler(void)\r
+{\r
+       return(0U); /*Default handler*/\r
+}\r
+\r
+/*Weakly linked handler. Will be replaced with user's definition if provide*/\r
+__attribute__((weak)) uint8_t External_31_IRQHandler(void)\r
+{\r
+       return(0U); /*Default handler*/\r
+}\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
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 (file)
index 0000000..2d09518
--- /dev/null
@@ -0,0 +1,249 @@
+/*******************************************************************************\r
+ * (c) Copyright 2016-2018 Microsemi SoC Products Group.  All rights reserved.\r
+ *\r
+ * @file riscv_plic.h\r
+ * @author Microsemi SoC Products Group\r
+ * @brief Mi-V soft processor PLIC and PRCI access data structures and functions.\r
+ *\r
+ * SVN $Revision: 9838 $\r
+ * SVN $Date: 2018-03-19 19:22:54 +0530 (Mon, 19 Mar 2018) $\r
+ */\r
+#ifndef RISCV_PLIC_H\r
+#define RISCV_PLIC_H\r
+\r
+#include <stdint.h>\r
+\r
+#include "encoding.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+#define PLIC_NUM_SOURCES 31\r
+#define PLIC_NUM_PRIORITIES 0\r
+\r
+/*==============================================================================\r
+ * Interrupt numbers:\r
+ */\r
+typedef enum\r
+{\r
+    NoInterrupt_IRQn = 0,\r
+    External_1_IRQn  = 1,\r
+    External_2_IRQn  = 2,\r
+    External_3_IRQn  = 3, \r
+    External_4_IRQn  = 4,\r
+    External_5_IRQn  = 5,\r
+    External_6_IRQn  = 6,\r
+    External_7_IRQn  = 7,\r
+    External_8_IRQn  = 8,\r
+    External_9_IRQn  = 9,\r
+    External_10_IRQn = 10,\r
+    External_11_IRQn = 11,\r
+    External_12_IRQn = 12,\r
+    External_13_IRQn = 13,\r
+    External_14_IRQn = 14,\r
+    External_15_IRQn = 15,\r
+    External_16_IRQn = 16,\r
+    External_17_IRQn = 17,\r
+    External_18_IRQn = 18,\r
+    External_19_IRQn = 19,\r
+    External_20_IRQn = 20,\r
+    External_21_IRQn = 21,\r
+    External_22_IRQn = 22,\r
+    External_23_IRQn = 23,\r
+    External_24_IRQn = 24,\r
+    External_25_IRQn = 25,\r
+    External_26_IRQn = 26,\r
+    External_27_IRQn = 27,\r
+    External_28_IRQn = 28,\r
+    External_29_IRQn = 29,\r
+    External_30_IRQn = 30,\r
+    External_31_IRQn = 31\r
+} IRQn_Type;\r
+\r
+\r
+/*==============================================================================\r
+ * PLIC: Platform Level Interrupt Controller\r
+ */\r
+#define PLIC_BASE_ADDR 0x40000000UL\r
+\r
+typedef struct\r
+{\r
+    volatile uint32_t PRIORITY_THRESHOLD;\r
+    volatile uint32_t CLAIM_COMPLETE;\r
+    volatile uint32_t reserved[1022];\r
+} IRQ_Target_Type;\r
+\r
+typedef struct\r
+{\r
+    volatile uint32_t ENABLES[32];\r
+} Target_Enables_Type;\r
+\r
+typedef struct\r
+{\r
+    /*-------------------- Source Priority --------------------*/\r
+    volatile uint32_t SOURCE_PRIORITY[1024];\r
+    \r
+    /*-------------------- Pending array --------------------*/\r
+    volatile const uint32_t PENDING_ARRAY[32];\r
+    volatile uint32_t RESERVED1[992];\r
+    \r
+    /*-------------------- Target enables --------------------*/\r
+    volatile Target_Enables_Type TARGET_ENABLES[15808];\r
+\r
+    volatile uint32_t RESERVED2[16384];\r
+    \r
+    /*--- Target Priority threshold and claim/complete---------*/\r
+    IRQ_Target_Type TARGET[15872];\r
+    \r
+} PLIC_Type;\r
+\r
+\r
+#define PLIC    ((PLIC_Type *)PLIC_BASE_ADDR)\r
+\r
+/*==============================================================================\r
+ * PRCI: Power, Reset, Clock, Interrupt\r
+ */\r
+#define PRCI_BASE   0x44000000UL\r
+\r
+typedef struct\r
+{\r
+    volatile uint32_t MSIP[4095];\r
+    volatile uint32_t reserved;\r
+    volatile uint64_t MTIMECMP[4095];\r
+    volatile const uint64_t MTIME;\r
+} PRCI_Type;\r
+\r
+#define PRCI    ((PRCI_Type *)PRCI_BASE) \r
+\r
+/*==============================================================================\r
+ * The function PLIC_init() initializes the PLIC controller and enables the \r
+ * global external interrupt bit.\r
+ */\r
+static inline void PLIC_init(void)\r
+{\r
+    uint32_t inc;\r
+    unsigned long hart_id = read_csr(mhartid);\r
+\r
+    /* Disable all interrupts for the current hart. */\r
+    for(inc = 0; inc < ((PLIC_NUM_SOURCES + 32u) / 32u); ++inc)\r
+    {\r
+        PLIC->TARGET_ENABLES[hart_id].ENABLES[inc] = 0;\r
+    }\r
+\r
+    /* Set priorities to zero. */\r
+    /* Should this really be done??? Calling PLIC_init() on one hart will cause\r
+    * the priorities previously set by other harts to be messed up. */\r
+    for(inc = 0; inc < PLIC_NUM_SOURCES; ++inc)\r
+    {\r
+        PLIC->SOURCE_PRIORITY[inc] = 0;\r
+    }\r
+\r
+    /* Set the threshold to zero. */\r
+    PLIC->TARGET[hart_id].PRIORITY_THRESHOLD = 0;\r
+\r
+    /* Enable machine external interrupts. */\r
+    set_csr(mie, MIP_MEIP);\r
+}\r
+\r
+/*==============================================================================\r
+ * The function PLIC_EnableIRQ() enables the external interrupt for the interrupt\r
+ * number indicated by the parameter IRQn.\r
+ */\r
+static inline void PLIC_EnableIRQ(IRQn_Type IRQn)\r
+{\r
+    unsigned long hart_id = read_csr(mhartid);\r
+    uint32_t current = PLIC->TARGET_ENABLES[hart_id].ENABLES[IRQn / 32];\r
+    current |= (uint32_t)1 << (IRQn % 32);\r
+    PLIC->TARGET_ENABLES[hart_id].ENABLES[IRQn / 32] = current;\r
+}\r
+\r
+/*==============================================================================\r
+ * The function PLIC_DisableIRQ() disables the external interrupt for the interrupt\r
+ * number indicated by the parameter IRQn.\r
+\r
+ * NOTE:\r
+ *     This function can be used to disable the external interrupt from outside\r
+ *     external interrupt handler function.\r
+ *     This function MUST NOT be used from within the External Interrupt handler.\r
+ *     If you wish to disable the external interrupt while the interrupt handler\r
+ *     for that external interrupt is executing then you must use the return value\r
+ *     EXT_IRQ_DISABLE to return from the extern interrupt handler.\r
+ */\r
+static inline void PLIC_DisableIRQ(IRQn_Type IRQn)\r
+{\r
+    unsigned long hart_id = read_csr(mhartid);\r
+    uint32_t current = PLIC->TARGET_ENABLES[hart_id].ENABLES[IRQn / 32];\r
+\r
+    current &= ~((uint32_t)1 << (IRQn % 32));\r
+\r
+    PLIC->TARGET_ENABLES[hart_id].ENABLES[IRQn / 32] = current;\r
+}\r
+\r
+/*==============================================================================\r
+ * The function PLIC_SetPriority() sets the priority for the external interrupt \r
+ * for the interrupt number indicated by the parameter IRQn.\r
+ */\r
+static inline void PLIC_SetPriority(IRQn_Type IRQn, uint32_t priority) \r
+{\r
+    PLIC->SOURCE_PRIORITY[IRQn] = priority;\r
+}\r
+\r
+/*==============================================================================\r
+ * The function PLIC_GetPriority() returns the priority for the external interrupt \r
+ * for the interrupt number indicated by the parameter IRQn.\r
+ */\r
+static inline uint32_t PLIC_GetPriority(IRQn_Type IRQn)\r
+{\r
+    return PLIC->SOURCE_PRIORITY[IRQn];\r
+}\r
+\r
+/*==============================================================================\r
+ * The function PLIC_ClaimIRQ() claims the interrupt from the PLIC controller.\r
+ */\r
+static inline uint32_t PLIC_ClaimIRQ(void)\r
+{\r
+    unsigned long hart_id = read_csr(mhartid);\r
+\r
+    return PLIC->TARGET[hart_id].CLAIM_COMPLETE;\r
+}\r
+\r
+/*==============================================================================\r
+ * The function PLIC_CompleteIRQ() indicates to the PLIC controller the interrupt\r
+ * is processed and claim is complete.\r
+ */\r
+static inline void PLIC_CompleteIRQ(uint32_t source)\r
+{\r
+    unsigned long hart_id = read_csr(mhartid);\r
+\r
+    PLIC->TARGET[hart_id].CLAIM_COMPLETE = source;\r
+}\r
+\r
+/*==============================================================================\r
+ * The function raise_soft_interrupt() raises a synchronous software interrupt by\r
+ * writing into the MSIP register.\r
+ */\r
+static inline void raise_soft_interrupt()\r
+{\r
+    unsigned long hart_id = read_csr(mhartid);\r
+\r
+    /*You need to make sure that the global interrupt is enabled*/\r
+    set_csr(mie, MIP_MSIP);       /*Enable software interrupt bit */\r
+    PRCI->MSIP[hart_id] = 0x01;   /*raise soft interrupt for hart0*/\r
+}\r
+\r
+/*==============================================================================\r
+ * The function clear_soft_interrupt() clears a synchronous software interrupt by\r
+ * clearing the MSIP register.\r
+ */\r
+static inline void clear_soft_interrupt()\r
+{\r
+    unsigned long hart_id = read_csr(mhartid);\r
+    PRCI->MSIP[hart_id] = 0x00;   /*clear soft interrupt for hart0*/\r
+}\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif  /* RISCV_PLIC_H */\r
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 (file)
index 0000000..2990bd0
--- /dev/null
@@ -0,0 +1,120 @@
+/*******************************************************************************\r
+ * (c) Copyright 2016-2018 Microsemi Corporation.  All rights reserved.\r
+ *\r
+ * Platform definitions\r
+ * Version based on requirements of RISCV-HAL\r
+ *\r
+ * SVN $Revision: 9946 $\r
+ * SVN $Date: 2018-04-30 20:26:55 +0530 (Mon, 30 Apr 2018) $\r
+ */\r
+ /*=========================================================================*//**\r
+  @mainpage Sample file detailing how hw_platform.h should be constructed for \r
+    the Mi-V processors.\r
+\r
+    @section intro_sec Introduction\r
+    The hw_platform.h is to be located in the project root directory.\r
+    Currently this file must be hand crafted when using the Mi-V Soft Processor.\r
+    \r
+    You can use this file as sample.\r
+    Rename this file from sample_hw_platform.h to hw_platform.h and store it in\r
+    the root folder of your project. Then customize it per your HW design.\r
+\r
+    @section driver_configuration Project configuration Instructions\r
+    1. Change SYS_CLK_FREQ define to frequency of Mi-V Soft processor clock\r
+    2  Add all other core BASE addresses\r
+    3. Add peripheral Core Interrupt to Mi-V Soft processor interrupt mappings\r
+    4. Define MSCC_STDIO_UART_BASE_ADDR if you want a CoreUARTapb mapped to STDIO\r
+*//*=========================================================================*/\r
+\r
+#ifndef HW_PLATFORM_H\r
+#define HW_PLATFORM_H\r
+\r
+/***************************************************************************//**\r
+ * Soft-processor clock definition\r
+ * This is the only clock brought over from the Mi-V Soft processor Libero design.\r
+ */\r
+#ifndef SYS_CLK_FREQ\r
+#define SYS_CLK_FREQ                    83000000UL\r
+#endif\r
+\r
+\r
+/***************************************************************************//**\r
+ * Non-memory Peripheral base addresses\r
+ * Format of define is:\r
+ * <corename>_<instance>_BASE_ADDR\r
+ */\r
+#define COREUARTAPB0_BASE_ADDR          0x70001000UL\r
+#define COREGPIO_IN_BASE_ADDR           0x70002000UL\r
+#define CORETIMER0_BASE_ADDR            0x70003000UL\r
+#define CORETIMER1_BASE_ADDR            0x70004000UL\r
+#define COREGPIO_OUT_BASE_ADDR          0x70005000UL\r
+#define FLASH_CORE_SPI_BASE             0x70006000UL\r
+#define CORE16550_BASE_ADDR             0x70007000UL\r
+\r
+/***************************************************************************//**\r
+ * Peripheral Interrupts are mapped to the corresponding Mi-V Soft processor\r
+ * interrupt from the Libero design.\r
+ * There can be up to 31 external interrupts (IRQ[30:0] pins) on the Mi-V Soft\r
+ * processor.The Mi-V Soft processor external interrupts are defined in the\r
+ * riscv_plic.h\r
+ * These are of the form\r
+ * typedef enum\r
+{\r
+    NoInterrupt_IRQn = 0,\r
+    External_1_IRQn  = 1,\r
+    External_2_IRQn  = 2,\r
+    .\r
+    .\r
+    .\r
+    External_31_IRQn = 31\r
+} IRQn_Type;\r
\r
+ The interrupt 0 on RISC-V processor is not used. The pin IRQ[0] should map to\r
+ External_1_IRQn likewise IRQ[30] should map to External_31_IRQn\r
+ * Format of define is:\r
+ * <corename>_<instance>_<core interrupt name>\r
+ */\r
+\r
+#define TIMER0_IRQn                     External_30_IRQn\r
+#define TIMER1_IRQn                     External_31_IRQn\r
+\r
+/****************************************************************************\r
+ * Baud value to achieve a 115200 baud rate with a 83MHz system clock.\r
+ * This value is calculated using the following equation:\r
+ *      BAUD_VALUE = (CLOCK / (16 * BAUD_RATE)) - 1\r
+ *****************************************************************************/\r
+#define BAUD_VALUE_115200               (SYS_CLK_FREQ / (16 * 115200)) - 1\r
+\r
+/***************************************************************************//**\r
+ * User edit section- Edit sections below if required\r
+ */\r
+#ifdef MSCC_STDIO_THRU_CORE_UART_APB\r
+/*\r
+ * A base address mapping for the STDIO printf/scanf mapping to CortUARTapb\r
+ * must be provided if it is being used\r
+ *\r
+ * e.g. #define MSCC_STDIO_UART_BASE_ADDR COREUARTAPB1_BASE_ADDR\r
+ */\r
+#define MSCC_STDIO_UART_BASE_ADDR COREUARTAPB0_BASE_ADDR\r
+\r
+#ifndef MSCC_STDIO_UART_BASE_ADDR\r
+#error MSCC_STDIO_UART_BASE_ADDR not defined- e.g. #define MSCC_STDIO_UART_BASE_ADDR COREUARTAPB1_BASE_ADDR\r
+#endif\r
+\r
+#ifndef MSCC_STDIO_BAUD_VALUE\r
+/*\r
+ * The MSCC_STDIO_BAUD_VALUE define should be set in your project's settings to\r
+ * specify the baud value used by the standard output CoreUARTapb instance for\r
+ * generating the UART's baud rate if you want a different baud rate from the\r
+ * default of 115200 baud\r
+ */\r
+#define MSCC_STDIO_BAUD_VALUE           115200\r
+#endif  /*MSCC_STDIO_BAUD_VALUE*/\r
+\r
+#endif  /* end of MSCC_STDIO_THRU_CORE_UART_APB */\r
+/*******************************************************************************\r
+ * End of user edit section\r
+ */\r
+#endif /* HW_PLATFORM_H */\r
+\r
+\r
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 (file)
index 0000000..4c99f80
--- /dev/null
@@ -0,0 +1,266 @@
+/*******************************************************************************\r
+ * (c) Copyright 2016-2018 Microsemi SoC Products Group.  All rights reserved.\r
+ *\r
+ * @file syscall.c\r
+ * @author Microsemi SoC Products Group\r
+ * @brief Stubs for system calls.\r
+ *\r
+ * SVN $Revision: 9661 $\r
+ * SVN $Date: 2018-01-15 16:13:33 +0530 (Mon, 15 Jan 2018) $\r
+ */\r
+#include <stdint.h>\r
+#include <stdlib.h>\r
+#include <stddef.h>\r
+#include <unistd.h>\r
+#include <errno.h>\r
+#include <sys/stat.h>\r
+#include <sys/times.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+\r
+#include "encoding.h"\r
+\r
+#ifdef MSCC_STDIO_THRU_CORE_UART_APB\r
+\r
+#include "core_uart_apb.h"\r
+#include "hw_platform.h"\r
+\r
+#endif  /*MSCC_STDIO_THRU_CORE_UART_APB*/\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+#ifdef MSCC_STDIO_THRU_CORE_UART_APB\r
+\r
+/*------------------------------------------------------------------------------\r
+ * CoreUARTapb instance data for the CoreUARTapb instance used for standard\r
+ * output.\r
+ */\r
+static UART_instance_t g_stdio_uart;\r
+\r
+/*==============================================================================\r
+ * Flag used to indicate if the UART driver needs to be initialized.\r
+ */\r
+static int g_stdio_uart_init_done = 0;\r
+#endif /*MSCC_STDIO_THRU_CORE_UART_APB*/\r
+\r
+#undef errno\r
+int errno;\r
+\r
+char *__env[1] = { 0 };\r
+char **environ = __env;\r
+\r
+void write_hex(int fd, uint32_t hex)\r
+{\r
+    uint8_t ii;\r
+    uint8_t jj;\r
+    char towrite;\r
+    uint8_t digit;\r
+\r
+    write( fd , "0x", 2 );\r
+\r
+    for (ii = 8 ; ii > 0; ii--)\r
+    {\r
+        jj = ii-1;\r
+        digit = ((hex & (0xF << (jj*4))) >> (jj*4));\r
+        towrite = digit < 0xA ? ('0' + digit) : ('A' +  (digit - 0xA));\r
+        write( fd, &towrite, 1);\r
+    }\r
+}\r
+\r
+               \r
+void _exit(int code)\r
+{\r
+#ifdef MSCC_STDIO_THRU_CORE_UART_APB\r
+    const char * message = "\nProgam has exited with code:";\r
+\r
+    write(STDERR_FILENO, message, strlen(message));\r
+    write_hex(STDERR_FILENO, code);\r
+#endif\r
+\r
+    while (1);\r
+}\r
+\r
+void *_sbrk(ptrdiff_t incr)\r
+{\r
+    extern char _end[];\r
+    extern char _heap_end[];\r
+    static char *curbrk = _end;\r
+\r
+    if ((curbrk + incr < _end) || (curbrk + incr > _heap_end))\r
+    {\r
+        return ((char *) - 1);\r
+    }\r
+\r
+    curbrk += incr;\r
+    return curbrk - incr;\r
+}\r
+\r
+int _isatty(int fd)\r
+{\r
+    if (fd == STDOUT_FILENO || fd == STDERR_FILENO)\r
+    {\r
+        return 1;\r
+    }\r
+\r
+    errno = EBADF;\r
+    return 0;\r
+}\r
+\r
+static int stub(int err)\r
+{\r
+    errno = err;\r
+    return -1;\r
+}\r
+\r
+int _open(const char* name, int flags, int mode)\r
+{\r
+    return stub(ENOENT);\r
+}\r
+\r
+int _openat(int dirfd, const char* name, int flags, int mode)\r
+{\r
+    return stub(ENOENT);\r
+}\r
+\r
+int _close(int fd)\r
+{\r
+    return stub(EBADF);\r
+}\r
+\r
+int _execve(const char* name, char* const argv[], char* const env[])\r
+{\r
+    return stub(ENOMEM);\r
+}\r
+\r
+int _fork()\r
+{\r
+    return stub(EAGAIN);\r
+}\r
+\r
+int _fstat(int fd, struct stat *st)\r
+{\r
+    if (isatty(fd))\r
+    {\r
+        st->st_mode = S_IFCHR;\r
+        return 0;\r
+    }\r
+\r
+    return stub(EBADF);\r
+}\r
+\r
+int _getpid()\r
+{\r
+    return 1;\r
+}\r
+\r
+int _kill(int pid, int sig)\r
+{\r
+    return stub(EINVAL);\r
+}\r
+\r
+int _link(const char *old_name, const char *new_name)\r
+{\r
+    return stub(EMLINK);\r
+}\r
+\r
+off_t _lseek(int fd, off_t ptr, int dir)\r
+{\r
+    if (_isatty(fd))\r
+    {\r
+        return 0;\r
+    }\r
+\r
+    return stub(EBADF);\r
+}\r
+\r
+ssize_t _read(int fd, void* ptr, size_t len)\r
+{\r
+#ifdef MSCC_STDIO_THRU_CORE_UART_APB\r
+    if (_isatty(fd))\r
+    {\r
+        /*--------------------------------------------------------------------------\r
+        * Initialize the UART driver if it is the first time this function is\r
+        * called.\r
+        */\r
+        if ( !g_stdio_uart_init_done )\r
+        {\r
+            /******************************************************************************\r
+            * Baud value:\r
+            * This value is calculated using the following equation:\r
+            *      BAUD_VALUE = (CLOCK / (16 * BAUD_RATE)) - 1\r
+            *****************************************************************************/\r
+            UART_init( &g_stdio_uart, MSCC_STDIO_UART_BASE_ADDR, ((SYS_CLK_FREQ/(16 * MSCC_STDIO_BAUD_VALUE))-1), (DATA_8_BITS | NO_PARITY));\r
+            g_stdio_uart_init_done = 1;\r
+        }\r
+\r
+        return UART_get_rx(&g_stdio_uart, (uint8_t*) ptr, len);\r
+    }\r
+#endif\r
+\r
+    return stub(EBADF);\r
+}\r
+\r
+int _stat(const char* file, struct stat* st)\r
+{\r
+    return stub(EACCES);\r
+}\r
+\r
+clock_t _times(struct tms* buf)\r
+{\r
+    return stub(EACCES);\r
+}\r
+\r
+int _unlink(const char* name)\r
+{\r
+    return stub(ENOENT);\r
+}\r
+\r
+int _wait(int* status)\r
+{\r
+    return stub(ECHILD);\r
+}\r
+\r
+ssize_t _write(int fd, const void* ptr, size_t len)\r
+{\r
+\r
+#ifdef MSCC_STDIO_THRU_CORE_UART_APB\r
+  const uint8_t * current = (const uint8_t *) ptr;\r
+  size_t jj;\r
+\r
+  if (_isatty(fd))\r
+  {\r
+        /*--------------------------------------------------------------------------\r
+        * Initialize the UART driver if it is the first time this function is\r
+        * called.\r
+        */\r
+        if ( !g_stdio_uart_init_done )\r
+        {\r
+            /******************************************************************************\r
+            * Baud value:\r
+            * This value is calculated using the following equation:\r
+            *      BAUD_VALUE = (CLOCK / (16 * BAUD_RATE)) - 1\r
+            *****************************************************************************/\r
+            UART_init( &g_stdio_uart, MSCC_STDIO_UART_BASE_ADDR, ((SYS_CLK_FREQ/(16 * MSCC_STDIO_BAUD_VALUE))-1), (DATA_8_BITS | NO_PARITY));\r
+            g_stdio_uart_init_done = 1;\r
+        }\r
+\r
+    for (jj = 0; jj < len; jj++)\r
+    {\r
+        UART_send(&g_stdio_uart, current + jj, 1);\r
+        if (current[jj] == '\n')\r
+        {\r
+            UART_send(&g_stdio_uart, (const uint8_t *)"\r", 1);\r
+        }\r
+    }\r
+    return len;\r
+  }\r
+#endif\r
+\r
+  return stub(EBADF);\r
+}\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r