Add starting point for IGLOO2 RISV-V demo project.

This commit is contained in:
Richard Barry 2018-06-20 21:18:14 +00:00
parent 483f4a8c4b
commit 9119e1e0e3
42 changed files with 13068 additions and 0 deletions

View File

@ -0,0 +1,125 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.debug.2049051127">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.debug.2049051127" moduleId="org.eclipse.cdt.core.settings" name="Debug">
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="${cross_rm} -rf" description="" errorParsers="org.eclipse.cdt.core.GASErrorParser;org.eclipse.cdt.core.GmakeErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.CWDLocator;org.eclipse.cdt.core.GCCErrorParser" id="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.debug.2049051127" name="Debug" parent="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.debug" postannouncebuildStep="" postbuildStep="" preannouncebuildStep="" prebuildStep="">
<folderInfo id="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.debug.2049051127." name="/" resourcePath="">
<toolChain errorParsers="" id="ilg.gnumcueclipse.managedbuild.cross.riscv.toolchain.elf.debug.1135421195" name="RISC-V Cross GCC" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.toolchain.elf.debug">
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createflash.1236561658" name="Create flash image" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createflash" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createlisting.197330232" name="Create extended listing" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createlisting" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.printsize.306588546" name="Print size" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.printsize" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.level.1940053873" name="Optimization Level" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.level" useByScannerDiscovery="true" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.level.none" valueType="enumerated"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.messagelength.565243439" name="Message length (-fmessage-length=0)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.messagelength" useByScannerDiscovery="true" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.signedchar.321222073" name="'char' is signed (-fsigned-char)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.signedchar" useByScannerDiscovery="true" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.functionsections.1177210712" name="Function sections (-ffunction-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.functionsections" useByScannerDiscovery="true" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.datasections.1159308156" name="Data sections (-fdata-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.datasections" useByScannerDiscovery="true" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.level.400131419" name="Debug level" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.level" useByScannerDiscovery="true" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.level.max" valueType="enumerated"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.format.227460743" name="Debug format" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.format" useByScannerDiscovery="true"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.name.39106845" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.name" useByScannerDiscovery="false" value="RISC-V GCC/Newlib" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.prefix.975904647" name="Prefix" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.prefix" useByScannerDiscovery="false" value="riscv64-unknown-elf-" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.c.629106139" name="C compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.c" useByScannerDiscovery="false" value="gcc" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.cpp.700052137" name="C++ compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.cpp" useByScannerDiscovery="false" value="g++" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.ar.1315168450" name="Archiver" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.ar" useByScannerDiscovery="false" value="ar" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objcopy.729800518" name="Hex/Bin converter" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objcopy" useByScannerDiscovery="false" value="objcopy" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objdump.1799678707" name="Listing generator" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objdump" useByScannerDiscovery="false" value="objdump" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.size.2116391716" name="Size command" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.size" useByScannerDiscovery="false" value="size" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.make.323254382" name="Build command" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.make" useByScannerDiscovery="false" value="make" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.rm.1360582657" name="Remove command" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.rm" useByScannerDiscovery="false" value="rm" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.base.1725087349" name="Architecture" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.base" useByScannerDiscovery="false" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.arch.rv32i" valueType="enumerated"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.multiply.1573871360" name="Multiply extension (RVM)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.multiply" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.abi.integer.957415439" name="Integer ABI" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.abi.integer" useByScannerDiscovery="false" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.abi.integer.ilp32" valueType="enumerated"/>
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="ilg.gnumcueclipse.managedbuild.cross.riscv.targetPlatform.1851994667" isAbstract="false" osList="all" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.targetPlatform"/>
<builder buildPath="${workspace_loc:/miv-rv32im-freertos-port-test}/Debug" errorParsers="org.eclipse.cdt.core.GmakeErrorParser;org.eclipse.cdt.core.CWDLocator" id="ilg.gnumcueclipse.managedbuild.cross.riscv.builder.1748717066" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.builder"/>
<tool command="${cross_prefix}${cross_c}${cross_suffix}" commandLinePattern="${COMMAND} ${cross_toolchain_flags} ${FLAGS} -c ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}" errorParsers="org.eclipse.cdt.core.GASErrorParser;org.eclipse.cdt.core.GCCErrorParser" id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.1205277158" name="GNU RISC-V Cross Assembler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler">
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.assembler.usepreprocessor.1853992692" name="Use preprocessor" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.assembler.usepreprocessor" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<inputType id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.input.1786331150" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.input"/>
</tool>
<tool command="${cross_prefix}${cross_c}${cross_suffix}" commandLinePattern="${COMMAND} ${cross_toolchain_flags} ${FLAGS} -c ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}" errorParsers="org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.GCCErrorParser" id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.894708922" name="GNU RISC-V Cross C Compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler">
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.include.paths.1818715770" name="Include paths (-I)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.include.paths" useByScannerDiscovery="true" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/FreeRTOS_Source/include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/FreeRTOS_Source/portable/ThirdParty/GCC/RISC-V}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/drivers/CoreGPIO}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/drivers/Core16550}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/drivers/CoreUARTapb}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/drivers/CoreTimer}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/drivers/CoreSPI}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/hal}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/riscv_hal}&quot;"/>
</option>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.defs.43291576" name="Defined symbols (-D)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.defs" useByScannerDiscovery="true" valueType="definedSymbols">
<listOptionValue builtIn="false" value="MSCC_STDIO_THRU_CORE_UART_APB"/>
</option>
<inputType id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input.1901773760" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input"/>
</tool>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.compiler.1713474071" name="GNU RISC-V Cross C++ Compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.compiler"/>
<tool command="${cross_prefix}${cross_c}${cross_suffix}" commandLinePattern="${COMMAND} ${cross_toolchain_flags} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}" errorParsers="" id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.linker.209069143" name="GNU RISC-V Cross C Linker" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.linker">
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.gcsections.991946343" name="Remove unused sections (-Xlinker --gc-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.gcsections" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.scriptfile.746597241" name="Script files (-T)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.scriptfile" useByScannerDiscovery="false" valueType="stringList">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/riscv_hal/microsemi-riscv-ram.ld}&quot;"/>
</option>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.nostart.1750314954" name="Do not use standard start files (-nostartfiles)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.nostart" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.usenewlibnano.991677097" name="Use newlib-nano (--specs=nano.specs)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.usenewlibnano" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<inputType id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.linker.input.314001493" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.linker.1999185643" name="GNU RISC-V Cross C++ Linker" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.linker">
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.gcsections.1490980679" name="Remove unused sections (-Xlinker --gc-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.gcsections" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.scriptfile.1026577013" name="Script files (-T)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.scriptfile" valueType="stringList">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/riscv_hal/microsemi-riscv-ram.ld}&quot;"/>
</option>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.nostart.1240127315" name="Do not use standard start files (-nostartfiles)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.nostart" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.usenewlibnano.89628615" name="Use newlib-nano (--specs=nano.specs)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.usenewlibnano" value="true" valueType="boolean"/>
</tool>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.archiver.690189418" name="GNU RISC-V Cross Archiver" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.archiver"/>
<tool command="${cross_prefix}${cross_objcopy}${cross_suffix}" commandLinePattern="${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT}" errorParsers="" id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createflash.1183225084" name="GNU RISC-V Cross Create Flash Image" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createflash"/>
<tool command="${cross_prefix}${cross_objdump}${cross_suffix}" commandLinePattern="${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT}" errorParsers="" id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createlisting.876462403" name="GNU RISC-V Cross Create Listing" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createlisting">
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.source.1650627599" name="Display source (--source|-S)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.source" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.allheaders.1290189840" name="Display all headers (--all-headers|-x)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.allheaders" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.demangle.1153388295" name="Demangle names (--demangle|-C)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.demangle" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.linenumbers.59828896" name="Display line numbers (--line-numbers|-l)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.linenumbers" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.wide.2003727408" name="Wide lines (--wide|-w)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.wide" useByScannerDiscovery="false" value="true" valueType="boolean"/>
</tool>
<tool command="${cross_prefix}${cross_size}${cross_suffix}" commandLinePattern="${COMMAND} ${FLAGS}" errorParsers="" id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.printsize.1868273119" name="GNU RISC-V Cross Print Size" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.printsize">
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.printsize.format.1198877735" name="Size format" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.printsize.format" useByScannerDiscovery="false"/>
</tool>
</toolChain>
</folderInfo>
<sourceEntries>
<entry excluding="FreeRTOS/portable/MemMang/heap_5.c|FreeRTOS/portable/MemMang/heap_4.c|FreeRTOS/portable/MemMang/heap_3.c|FreeRTOS/portable/MemMang/heap_1.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="miv-rv32im-freertos-port-test.ilg.gnumcueclipse.managedbuild.cross.riscv.target.elf.1563732131" name="Executable" projectType="ilg.gnumcueclipse.managedbuild.cross.riscv.target.elf"/>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release.1785100359;ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release.1785100359.;ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.1642196096;ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input.702511061">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.debug.2049051127;ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.debug.2049051127.;ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.894708922;ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input.1901773760">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
<storageModule moduleId="refreshScope"/>
</cproject>

View File

@ -0,0 +1,162 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>RTOSDemo</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
<linkedResources>
<link>
<name>FreeRTOS_Source</name>
<type>2</type>
<locationURI>FREERTOS_ROOT/FreeRTOS/Source</locationURI>
</link>
</linkedResources>
<filteredResources>
<filter>
<id>1529524430510</id>
<name>FreeRTOS_Source</name>
<type>9</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-include</arguments>
</matcher>
</filter>
<filter>
<id>1529524430514</id>
<name>FreeRTOS_Source</name>
<type>9</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-portable</arguments>
</matcher>
</filter>
<filter>
<id>1529524430518</id>
<name>FreeRTOS_Source</name>
<type>5</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-event_groups.c</arguments>
</matcher>
</filter>
<filter>
<id>1529524430521</id>
<name>FreeRTOS_Source</name>
<type>5</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-list.c</arguments>
</matcher>
</filter>
<filter>
<id>1529524430525</id>
<name>FreeRTOS_Source</name>
<type>5</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-queue.c</arguments>
</matcher>
</filter>
<filter>
<id>1529524430529</id>
<name>FreeRTOS_Source</name>
<type>5</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-stream_buffer.c</arguments>
</matcher>
</filter>
<filter>
<id>1529524430533</id>
<name>FreeRTOS_Source</name>
<type>5</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-tasks.c</arguments>
</matcher>
</filter>
<filter>
<id>1529524430538</id>
<name>FreeRTOS_Source</name>
<type>5</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-timers.c</arguments>
</matcher>
</filter>
<filter>
<id>1529524475525</id>
<name>FreeRTOS_Source/portable</name>
<type>9</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-ThirdParty</arguments>
</matcher>
</filter>
<filter>
<id>1529524475530</id>
<name>FreeRTOS_Source/portable</name>
<type>9</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-MemMang</arguments>
</matcher>
</filter>
<filter>
<id>1529524494421</id>
<name>FreeRTOS_Source/portable/MemMang</name>
<type>5</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-heap_4.c</arguments>
</matcher>
</filter>
<filter>
<id>1529524515837</id>
<name>FreeRTOS_Source/portable/ThirdParty</name>
<type>9</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-GCC</arguments>
</matcher>
</filter>
<filter>
<id>1529524627661</id>
<name>FreeRTOS_Source/portable/ThirdParty/GCC</name>
<type>9</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-RISC-V</arguments>
</matcher>
</filter>
</filteredResources>
<variableList>
<variable>
<name>FREERTOS_ROOT</name>
<value>$%7BPARENT-3-PROJECT_LOC%7D</value>
</variable>
<variable>
<name>copy_PARENT</name>
<value>$%7BPARENT-4-PROJECT_LOC%7D/FreeRTOS/WorkingCopy/FreeRTOS</value>
</variable>
</variableList>
</projectDescription>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
<configuration id="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.debug.2049051127" name="Debug">
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="886405286544253612" id="ilg.gnumcueclipse.managedbuild.cross.riscv.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT RISC-V Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
</extension>
</configuration>
</project>

View File

@ -0,0 +1,151 @@
/*
FreeRTOS V8.2.3 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
***************************************************************************
>>! NOTE: The modification to the GPL is included to allow you to !<<
>>! distribute a combined work that includes FreeRTOS without being !<<
>>! obliged to provide the source code for proprietary components !<<
>>! outside of the FreeRTOS kernel. !<<
***************************************************************************
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. Full license text is available on the following
link: http://www.freertos.org/a00114.html
***************************************************************************
* *
* FreeRTOS provides completely free yet professionally developed, *
* robust, strictly quality controlled, supported, and cross *
* platform software that is more than just the market leader, it *
* is the industry's de facto standard. *
* *
* Help yourself get started quickly while simultaneously helping *
* to support the FreeRTOS project by purchasing a FreeRTOS *
* tutorial book, reference manual, or both: *
* http://www.FreeRTOS.org/Documentation *
* *
***************************************************************************
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
the FAQ page "My application does not run, what could be wrong?". Have you
defined configASSERT()?
http://www.FreeRTOS.org/support - In return for receiving this top quality
embedded software for free we request you assist our global community by
participating in the support forum.
http://www.FreeRTOS.org/training - Investing in training allows your team to
be as productive as possible as early as possible. Now you can receive
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
Ltd, and the world's leading authority on the world's leading RTOS.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
licenses offer ticketed support, indemnification and commercial middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
/*-----------------------------------------------------------
* Application specific definitions.
*
* These definitions should be adjusted for your particular hardware and
* application requirements.
*
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
*
* See http://www.freertos.org/a00110.html.
*----------------------------------------------------------*/
#include <stdint.h>
#include <string.h>
#include "riscv_plic.h"
extern uint32_t SystemCoreClock;
#define configUSE_PREEMPTION 1
#define configUSE_IDLE_HOOK 1
#define configUSE_TICK_HOOK 0
#define configCPU_CLOCK_HZ ( ( unsigned long ) 83000000 )
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
#define configMAX_PRIORITIES ( 5 )
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 1024 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 100 * 1024 ) )
#define configMAX_TASK_NAME_LEN ( 16 )
#define configUSE_TRACE_FACILITY 1
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
#define configUSE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 8
#define configCHECK_FOR_STACK_OVERFLOW 0 //2
#define configUSE_RECURSIVE_MUTEXES 1
#define configUSE_MALLOC_FAILED_HOOK 1
#define configUSE_APPLICATION_TASK_TAG 0
#define configUSE_COUNTING_SEMAPHORES 1
#define configGENERATE_RUN_TIME_STATS 0
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/* Software timer definitions. */
#define configUSE_TIMERS 0
#define configTIMER_TASK_PRIORITY ( 2 )
#define configTIMER_QUEUE_LENGTH 2
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE )
/* Task priorities. Allow these to be overridden. */
#ifndef uartPRIMARY_PRIORITY
#define uartPRIMARY_PRIORITY ( configMAX_PRIORITIES - 3 )
#endif
/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources 1
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_eTaskGetState 1
/* Normal assert() semantics without relying on the provision of an assert.h
header file. */
#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }
/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
standard names - or at least those used in the unmodified vector table. */
#define vPortSVCHandler SVCall_Handler
#define xPortPendSVHandler PendSV_Handler
#define vPortSysTickHandler SysTick_Handler
extern void vApplicationMallocFailedHook();
#endif /* FREERTOS_CONFIG_H */

View File

@ -0,0 +1,48 @@
## FreeRTOS port for Mi-V Soft Processor
### HW Platform and FPGA design:
This project is tested on following hardware platforms:
RISCV-Creative-Board
- [RISC-V Creative board Mi-V Sample Design](https://github.com/RISCV-on-Microsemi-FPGA/RISC-V-Creative-Board/tree/master/Programming_The_Target_Device/PROC_SUBSYSTEM_MIV_RV32IMA_BaseDesign)
PolarFire-Eval-Kit
- [PolarFire Eval Kit RISC-V Sample Design](https://github.com/RISCV-on-Microsemi-FPGA/PolarFire-Eval-Kit/tree/master/Programming_The_Target_Device/MIV_RV32IMA_L1_AHB_BaseDesign)
SmartFusion2-Advanced-Dev-Kit
- [SmartFusion2 Advanced Development Kit RISC-V Sample Design](https://github.com/RISCV-on-Microsemi-FPGA/SmartFusion2-Advanced-Dev-Kit/tree/master/Programming_The_Target_Device/PROC_SUBSYSTEM_BaseDesign)
### How to run the FreeRTOS RISC-V port:
To know how to use the SoftConsole workspace, please refer the [Readme.md](https://github.com/RISCV-on-Microsemi-FPGA/SoftConsole/blob/master/README.md)
The miv-rv32im-freertos-port-test is a self contained project. This project demonstrates
the FreeRTOS running with Microsemi RISC-V processor. This project creates two
tasks and runs them at regular intervals.
This example project requires USB-UART interface to be connected to a host PC.
The host PC must connect to the serial port using a terminal emulator such as
TeraTerm or PuTTY configured as follows:
- 115200 baud
- 8 data bits
- 1 stop bit
- no parity
- no flow control
The ./hw_platform.h file contains the design related information that is required
for this project. If you update the design, the hw_platform.h must be updated
accordingly.
### FreeRTOS Configurations
You must configure the FreeRTOS as per your applications need. Please read and modify FreeRTOSConfig.h.
E.g. You must set configCPU_CLOCK_HZ parameter in FreeRTOSConfig.h according to the hardware platform
design that you are using.
The RISC-V creative board design uses 66Mhz processor clock. The PolarFire Eval Kit design uses 50Mhz processor clock. The SmartFusion2 Adv. Development kit design uses 83Mhz processor clock.
### Microsemi SoftConsole Toolchain
To know more please refer: [SoftConsole](https://github.com/RISCV-on-Microsemi-FPGA/SoftConsole)
### Documentation for Microsemi RISC-V processor, SoftConsole toochain, Debug Tools, FPGA design etc.
To know more please refer: [Documentation](https://github.com/RISCV-on-Microsemi-FPGA/Documentation)

View File

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="ilg.gnumcueclipse.debug.gdbjtag.openocd.launchConfigurationType">
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doContinue" value="true"/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doDebugInRam" value="false"/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doFirstReset" value="true"/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doGdbServerAllocateConsole" value="true"/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doGdbServerAllocateTelnetConsole" value="false"/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doSecondReset" value="false"/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doStartGdbServer" value="true"/>
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.enableSemihosting" value="false"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.firstResetType" value="init"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbClientOtherCommands" value="set mem inaccessible-by-default off&#13;&#10;set arch riscv:rv32"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbClientOtherOptions" value=""/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerConnectionAddress" value=""/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerExecutable" value="${openocd_path}/${openocd_executable}"/>
<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerGdbPortNumber" value="3333"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerLog" value=""/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerOther" value="--file board/microsemi-riscv.cfg"/>
<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerTelnetPortNumber" value="4444"/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.otherInitCommands" value=""/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.otherRunCommands" value=""/>
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.secondResetType" value="halt"/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageFileName" value=""/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageOffset" value=""/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.ipAddress" value="localhost"/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.jtagDevice" value="GNU MCU OpenOCD"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadImage" value="true"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadSymbols" value="true"/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.pcRegister" value=""/>
<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.portNumber" value="3333"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setPcRegister" value="false"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setResume" value="false"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setStopAt" value="true"/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.stopAt" value="main"/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsFileName" value=""/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsOffset" value=""/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForImage" value="false"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForSymbols" value="false"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForImage" value="true"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForSymbols" value="true"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useRemoteTarget" value="true"/>
<stringAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_NAME" value="${cross_prefix}gdb${cross_suffix}"/>
<booleanAttribute key="org.eclipse.cdt.dsf.gdb.UPDATE_THREADLIST_ON_SUSPEND" value="false"/>
<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="2"/>
<stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/>
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_REGISTER_GROUPS" value=""/>
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="Debug\RTOSDemo.elf"/>
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="RTOSDemo"/>
<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="true"/>
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.debug.2049051127"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/RTOSDemo"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="4"/>
</listAttribute>
<stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;memoryBlockExpressionList context=&quot;Context string&quot;/&gt;&#13;&#10;"/>
<stringAttribute key="process_factory_id" value="org.eclipse.cdt.dsf.gdb.GdbProcessFactory"/>
</launchConfiguration>

View File

@ -0,0 +1,582 @@
/*******************************************************************************
* (c) Copyright 2007-2015 Microsemi SoC Products Group. All rights reserved.
*
* IP core registers definitions. This file contains the definitions required
* for accessing the IP core through the hardware abstraction layer (HAL).
* This file was automatically generated, using "get_header.exe" version 0.4.0,
* from the IP-XACT description for:
*
* Core16550 version: 2.0.0
*
* SVN $Revision: 7963 $
* SVN $Date: 2015-10-09 17:58:21 +0530 (Fri, 09 Oct 2015) $
*
*******************************************************************************/
#ifndef CORE_16550_REGISTERS_H_
#define CORE_16550_REGISTERS_H_ 1
#ifdef __cplusplus
extern "C" {
#endif
/*******************************************************************************
* RBR register:
*------------------------------------------------------------------------------
* Receive Buffer Register
*/
#define RBR_REG_OFFSET 0x00U
/*******************************************************************************
* THR register:
*------------------------------------------------------------------------------
* Transmit Holding Register
*/
#define THR_REG_OFFSET 0x00U
/*******************************************************************************
* DLR register:
*------------------------------------------------------------------------------
* Divisor Latch(LSB) Register
*/
#define DLR_REG_OFFSET 0x00U
/*******************************************************************************
* DMR register:
*------------------------------------------------------------------------------
* Divisor Latch(MSB) Register
*/
#define DMR_REG_OFFSET 0x04U
/*******************************************************************************
* IER register:
*------------------------------------------------------------------------------
* Interrupt Enable Register
*/
#define IER_REG_OFFSET 0x04U
/*------------------------------------------------------------------------------
* IER_ERBFI:
* ERBFI field of register IER.
*------------------------------------------------------------------------------
* Enables Received Data Available Interrupt. 0 - Disabled; 1 - Enabled
*/
#define IER_ERBFI_OFFSET 0x04U
#define IER_ERBFI_MASK 0x01U
#define IER_ERBFI_SHIFT 0U
/*------------------------------------------------------------------------------
* IER_ETBEI:
* ETBEI field of register IER.
*------------------------------------------------------------------------------
* Enables the Transmitter Holding Register Empty Interrupt. 0 - Disabled; 1 -
* Enabled
*/
#define IER_ETBEI_OFFSET 0x04U
#define IER_ETBEI_MASK 0x02U
#define IER_ETBEI_SHIFT 1U
/*------------------------------------------------------------------------------
* IER_ELSI:
* ELSI field of register IER.
*------------------------------------------------------------------------------
* Enables the Receiver Line Status Interrupt. 0 - Disabled; 1 - Enabled
*/
#define IER_ELSI_OFFSET 0x04U
#define IER_ELSI_MASK 0x04U
#define IER_ELSI_SHIFT 2U
/*------------------------------------------------------------------------------
* IER_EDSSI:
* EDSSI field of register IER.
*------------------------------------------------------------------------------
* Enables the Modem Status Interrupt 0 - Disabled; 1 - Enabled
*/
#define IER_EDSSI_OFFSET 0x04U
#define IER_EDSSI_MASK 0x08U
#define IER_EDSSI_SHIFT 3U
/*******************************************************************************
* IIR register:
*------------------------------------------------------------------------------
* Interrupt Identification
*/
#define IIR_REG_OFFSET 0x08U
/*------------------------------------------------------------------------------
* IIR_IIR:
* IIR field of register IIR.
*------------------------------------------------------------------------------
* Interrupt Identification bits.
*/
#define IIR_IIR_OFFSET 0x08U
#define IIR_IIR_MASK 0x0FU
#define IIR_IIR_SHIFT 0U
/*------------------------------------------------------------------------------
* IIR_IIR:
* IIR field of register IIR.
*------------------------------------------------------------------------------
* Interrupt Identification bits.
*/
/*------------------------------------------------------------------------------
* IIR_Mode:
* Mode field of register IIR.
*------------------------------------------------------------------------------
* 11 - FIFO mode
*/
#define IIR_MODE_OFFSET 0x08U
#define IIR_MODE_MASK 0xC0U
#define IIR_MODE_SHIFT 6U
/*******************************************************************************
* FCR register:
*------------------------------------------------------------------------------
* FIFO Control Register
*/
#define FCR_REG_OFFSET 0x08
/*------------------------------------------------------------------------------
* FCR_Bit0:
* Bit0 field of register FCR.
*------------------------------------------------------------------------------
* This bit enables both the TX and RX FIFOs.
*/
#define FCR_BIT0_OFFSET 0x08U
#define FCR_BIT0_MASK 0x01U
#define FCR_BIT0_SHIFT 0U
#define FCR_ENABLE_OFFSET 0x08U
#define FCR_ENABLE_MASK 0x01U
#define FCR_ENABLE_SHIFT 0U
/*------------------------------------------------------------------------------
* FCR_Bit1:
* Bit1 field of register FCR.
*------------------------------------------------------------------------------
* Clears all bytes in the RX FIFO and resets its counter logic. The shift
* register is not cleared. 0 - Disabled; 1 - Enabled
*/
#define FCR_BIT1_OFFSET 0x08U
#define FCR_BIT1_MASK 0x02U
#define FCR_BIT1_SHIFT 1U
#define FCR_CLEAR_RX_OFFSET 0x08U
#define FCR_CLEAR_RX_MASK 0x02U
#define FCR_CLEAR_RX_SHIFT 1U
/*------------------------------------------------------------------------------
* FCR_Bit2:
* Bit2 field of register FCR.
*------------------------------------------------------------------------------
* Clears all bytes in the TX FIFO and resets its counter logic. The shift
* register is not cleared. 0 - Disabled; 1 - Enabled
*/
#define FCR_BIT2_OFFSET 0x08U
#define FCR_BIT2_MASK 0x04U
#define FCR_BIT2_SHIFT 2U
#define FCR_CLEAR_TX_OFFSET 0x08U
#define FCR_CLEAR_TX_MASK 0x04U
#define FCR_CLEAR_TX_SHIFT 2U
/*------------------------------------------------------------------------------
* FCR_Bit3:
* Bit3 field of register FCR.
*------------------------------------------------------------------------------
* Enables RXRDYN and TXRDYN pins when set to 1. Otherwise, they are disabled.
*/
#define FCR_BIT3_OFFSET 0x08U
#define FCR_BIT3_MASK 0x08U
#define FCR_BIT3_SHIFT 3U
#define FCR_RDYN_EN_OFFSET 0x08U
#define FCR_RDYN_EN_MASK 0x08U
#define FCR_RDYN_EN_SHIFT 3U
/*------------------------------------------------------------------------------
* FCR_Bit6:
* Bit6 field of register FCR.
*------------------------------------------------------------------------------
* These bits are used to set the trigger level for the RX FIFO interrupt. RX
* FIFO Trigger Level: 0 - 1; 1 - 4; 2 - 8; 3 - 14
*/
#define FCR_BIT6_OFFSET 0x08U
#define FCR_BIT6_MASK 0xC0U
#define FCR_BIT6_SHIFT 6U
#define FCR_TRIG_LEVEL_OFFSET 0x08U
#define FCR_TRIG_LEVEL_MASK 0xC0U
#define FCR_TRIG_LEVEL_SHIFT 6U
/*******************************************************************************
* LCR register:
*------------------------------------------------------------------------------
* Line Control Register
*/
#define LCR_REG_OFFSET 0x0CU
/*------------------------------------------------------------------------------
* LCR_WLS:
* WLS field of register LCR.
*------------------------------------------------------------------------------
* Word Length Select: 00 - 5 bits; 01 - 6 bits; 10 - 7 bits; 11 - 8 bits
*/
#define LCR_WLS_OFFSET 0x0CU
#define LCR_WLS_MASK 0x03U
#define LCR_WLS_SHIFT 0U
/*------------------------------------------------------------------------------
* LCR_STB:
* STB field of register LCR.
*------------------------------------------------------------------------------
* Number of Stop Bits: 0 - 1 stop bit; 1 - 1½ stop bits when WLS = 00, 2 stop
* bits in other cases
*/
#define LCR_STB_OFFSET 0x0CU
#define LCR_STB_MASK 0x04U
#define LCR_STB_SHIFT 2U
/*------------------------------------------------------------------------------
* LCR_PEN:
* PEN field of register LCR.
*------------------------------------------------------------------------------
* Parity Enable 0 - Disabled; 1 - Enabled. Parity is added in transmission and
* checked in receiving.
*/
#define LCR_PEN_OFFSET 0x0CU
#define LCR_PEN_MASK 0x08U
#define LCR_PEN_SHIFT 3U
/*------------------------------------------------------------------------------
* LCR_EPS:
* EPS field of register LCR.
*------------------------------------------------------------------------------
* Even Parity Select 0 - Odd parity; 1 - Even parity
*/
#define LCR_EPS_OFFSET 0x0CU
#define LCR_EPS_MASK 0x10U
#define LCR_EPS_SHIFT 4U
/*------------------------------------------------------------------------------
* LCR_SP:
* SP field of register LCR.
*------------------------------------------------------------------------------
* Stick Parity 0 - Disabled; 1 - Enabled When stick parity is enabled, it
* works as follows: Bits 4..3, 11 - 0 will be sent as a parity bit, and
* checked in receiving. 01 - 1 will be sent as a parity bit, and checked in
* receiving.
*/
#define LCR_SP_OFFSET 0x0CU
#define LCR_SP_MASK 0x20U
#define LCR_SP_SHIFT 5U
/*------------------------------------------------------------------------------
* LCR_SB:
* SB field of register LCR.
*------------------------------------------------------------------------------
* Set Break 0 - Disabled 1 - Set break. SOUT is forced to 0. This does not
* have any effect on transmitter logic. The break is disabled by setting the
* bit to 0.
*/
#define LCR_SB_OFFSET 0x0CU
#define LCR_SB_MASK 0x40U
#define LCR_SB_SHIFT 6U
/*------------------------------------------------------------------------------
* LCR_DLAB:
* DLAB field of register LCR.
*------------------------------------------------------------------------------
* Divisor Latch Access Bit 0 - Disabled. Normal addressing mode in use 1 -
* Enabled. Enables access to the Divisor Latch registers during read or write
* operation to addresses 0 and 1.
*/
#define LCR_DLAB_OFFSET 0x0CU
#define LCR_DLAB_MASK 0x80U
#define LCR_DLAB_SHIFT 7U
/*******************************************************************************
* MCR register:
*------------------------------------------------------------------------------
* Modem Control Register
*/
#define MCR_REG_OFFSET 0x10U
/*------------------------------------------------------------------------------
* MCR_DTR:
* DTR field of register MCR.
*------------------------------------------------------------------------------
* Controls the Data Terminal Ready (DTRn) output. 0 - DTRn <= 1; 1 - DTRn <= 0
*/
#define MCR_DTR_OFFSET 0x10U
#define MCR_DTR_MASK 0x01U
#define MCR_DTR_SHIFT 0U
/*------------------------------------------------------------------------------
* MCR_RTS:
* RTS field of register MCR.
*------------------------------------------------------------------------------
* Controls the Request to Send (RTSn) output. 0 - RTSn <= 1; 1 - RTSn <= 0
*/
#define MCR_RTS_OFFSET 0x10U
#define MCR_RTS_MASK 0x02U
#define MCR_RTS_SHIFT 1U
/*------------------------------------------------------------------------------
* MCR_Out1:
* Out1 field of register MCR.
*------------------------------------------------------------------------------
* Controls the Output1 (OUT1n) signal. 0 - OUT1n <= 1; 1 - OUT1n <= 0
*/
#define MCR_OUT1_OFFSET 0x10U
#define MCR_OUT1_MASK 0x04U
#define MCR_OUT1_SHIFT 2U
/*------------------------------------------------------------------------------
* MCR_Out2:
* Out2 field of register MCR.
*------------------------------------------------------------------------------
* Controls the Output2 (OUT2n) signal. 0 - OUT2n <=1; 1 - OUT2n <=0
*/
#define MCR_OUT2_OFFSET 0x10U
#define MCR_OUT2_MASK 0x08U
#define MCR_OUT2_SHIFT 3U
/*------------------------------------------------------------------------------
* MCR_Loop:
* Loop field of register MCR.
*------------------------------------------------------------------------------
* Loop enable bit 0 - Disabled; 1 - Enabled. The following happens in loop
* mode: SOUT is set to 1. The SIN, DSRn, CTSn, RIn, and DCDn inputs are
* disconnected. The output of the Transmitter Shift Register is looped back
* into the Receiver Shift Register. The modem control outputs (DTRn, RTSn,
* OUT1n, and OUT2n) are connected internally to the modem control inputs, and
* the modem control output pins are set at 1. In loopback mode, the
* transmitted data is immediately received, allowing the CPU to check the
* operation of the UART. The interrupts are operating in loop mode.
*/
#define MCR_LOOP_OFFSET 0x10U
#define MCR_LOOP_MASK 0x10U
#define MCR_LOOP_SHIFT 4U
/*******************************************************************************
* LSR register:
*------------------------------------------------------------------------------
* Line Status Register
*/
#define LSR_REG_OFFSET 0x14U
/*------------------------------------------------------------------------------
* LSR_DR:
* DR field of register LSR.
*------------------------------------------------------------------------------
* Data Ready indicator 1 when a data byte has been received and stored in the
* FIFO. DR is cleared to 0 when the CPU reads the data from the FIFO.
*/
#define LSR_DR_OFFSET 0x14U
#define LSR_DR_MASK 0x01U
#define LSR_DR_SHIFT 0U
/*------------------------------------------------------------------------------
* LSR_OE:
* OE field of register LSR.
*------------------------------------------------------------------------------
* Overrun Error indicator Indicates that the new byte was received before the
* CPU read the byte from the receive buffer, and that the earlier data byte
* was destroyed. OE is cleared when the CPU reads the Line Status Register. If
* the data continues to fill the FIFO beyond the trigger level, an overrun
* error will occur once the FIFO is full and the next character has been
* completely received in the shift register. The character in the shift
* register is overwritten, but it is not transferred to the FIFO.
*/
#define LSR_OE_OFFSET 0x14U
#define LSR_OE_MASK 0x02U
#define LSR_OE_SHIFT 1U
/*------------------------------------------------------------------------------
* LSR_PE:
* PE field of register LSR.
*------------------------------------------------------------------------------
* Parity Error indicator Indicates that the received byte had a parity error.
* PE is cleared when the CPU reads the Line Status Register. This error is
* revealed to the CPU when its associated character is at the top of the FIFO.
*/
#define LSR_PE_OFFSET 0x14U
#define LSR_PE_MASK 0x04U
#define LSR_PE_SHIFT 2U
/*------------------------------------------------------------------------------
* LSR_FE:
* FE field of register LSR.
*------------------------------------------------------------------------------
* Framing Error indicator Indicates that the received byte did not have a
* valid Stop bit. FE is cleared when the CPU reads the Line Status Register.
* The UART will try to re-synchronize after a framing error. To do this, it
* assumes that the framing error was due to the next start bit, so it samples
* this start bit twice, and then starts receiving the data. This error is
* revealed to the CPU when its associated character is at the top of the FIFO.
*/
#define LSR_FE_OFFSET 0x14U
#define LSR_FE_MASK 0x08U
#define LSR_FE_SHIFT 3U
/*------------------------------------------------------------------------------
* LSR_BI:
* BI field of register LSR.
*------------------------------------------------------------------------------
* Break Interrupt indicator Indicates that the received data is at 0 longer
* than a full word transmission time (start bit + data bits + parity + stop
* bits). BI is cleared when the CPU reads the Line Status Register. This error
* is revealed to the CPU when its associated character is at the top of the
* FIFO. When break occurs, only one zero character is loaded into the FIFO.
*/
#define LSR_BI_OFFSET 0x14U
#define LSR_BI_MASK 0x10U
#define LSR_BI_SHIFT 4U
/*------------------------------------------------------------------------------
* LSR_THRE:
* THRE field of register LSR.
*------------------------------------------------------------------------------
* Transmitter Holding Register Empty indicator Indicates that the UART is
* ready to transmit a new data byte. THRE causes an interrupt to the CPU when
* bit 1 (ETBEI) in the Interrupt Enable Register is 1. This bit is set when
* the TX FIFO is empty. It is cleared when at least one byte is written to the
* TX FIFO.
*/
#define LSR_THRE_OFFSET 0x14U
#define LSR_THRE_MASK 0x20U
#define LSR_THRE_SHIFT 5U
/*------------------------------------------------------------------------------
* LSR_TEMT:
* TEMT field of register LSR.
*------------------------------------------------------------------------------
* Transmitter Empty indicator This bit is set to 1 when both the transmitter
* FIFO and shift registers are empty.
*/
#define LSR_TEMT_OFFSET 0x14U
#define LSR_TEMT_MASK 0x40U
#define LSR_TEMT_SHIFT 6U
/*------------------------------------------------------------------------------
* LSR_FIER:
* FIER field of register LSR.
*------------------------------------------------------------------------------
* This bit is set when there is at least one parity error, framing error, or
* break indication in the FIFO. FIER is cleared when the CPU reads the LSR if
* there are no subsequent errors in the FIFO.
*/
#define LSR_FIER_OFFSET 0x14U
#define LSR_FIER_MASK 0x80U
#define LSR_FIER_SHIFT 7U
/*******************************************************************************
* MSR register:
*------------------------------------------------------------------------------
* Modem Status Register
*/
#define MSR_REG_OFFSET 0x18U
/*------------------------------------------------------------------------------
* MSR_DCTS:
* DCTS field of register MSR.
*------------------------------------------------------------------------------
* Delta Clear to Send indicator. Indicates that the CTSn input has changed
* state since the last time it was read by the CPU.
*/
#define MSR_DCTS_OFFSET 0x18U
#define MSR_DCTS_MASK 0x01U
#define MSR_DCTS_SHIFT 0U
/*------------------------------------------------------------------------------
* MSR_DDSR:
* DDSR field of register MSR.
*------------------------------------------------------------------------------
* Delta Data Set Ready indicator Indicates that the DSRn input has changed
* state since the last time it was read by the CPU.
*/
#define MSR_DDSR_OFFSET 0x18U
#define MSR_DDSR_MASK 0x02U
#define MSR_DDSR_SHIFT 1U
/*------------------------------------------------------------------------------
* MSR_TERI:
* TERI field of register MSR.
*------------------------------------------------------------------------------
* Trailing Edge of Ring Indicator detector. Indicates that RI input has
* changed from 0 to 1.
*/
#define MSR_TERI_OFFSET 0x18U
#define MSR_TERI_MASK 0x04U
#define MSR_TERI_SHIFT 2U
/*------------------------------------------------------------------------------
* MSR_DDCD:
* DDCD field of register MSR.
*------------------------------------------------------------------------------
* Delta Data Carrier Detect indicator Indicates that DCD input has changed
* state. NOTE: Whenever bit 0, 1, 2, or 3 is set to 1, a Modem Status
* Interrupt is generated.
*/
#define MSR_DDCD_OFFSET 0x18U
#define MSR_DDCD_MASK 0x08U
#define MSR_DDCD_SHIFT 3U
/*------------------------------------------------------------------------------
* MSR_CTS:
* CTS field of register MSR.
*------------------------------------------------------------------------------
* Clear to Send The complement of the CTSn input. When bit 4 of the Modem
* Control Register (MCR) is set to 1 (loop), this bit is equivalent to DTR in
* the MCR.
*/
#define MSR_CTS_OFFSET 0x18U
#define MSR_CTS_MASK 0x10U
#define MSR_CTS_SHIFT 4U
/*------------------------------------------------------------------------------
* MSR_DSR:
* DSR field of register MSR.
*------------------------------------------------------------------------------
* Data Set Ready The complement of the DSR input. When bit 4 of the MCR is set
* to 1 (loop), this bit is equivalent to RTSn in the MCR.
*/
#define MSR_DSR_OFFSET 0x18U
#define MSR_DSR_MASK 0x20U
#define MSR_DSR_SHIFT 5U
/*------------------------------------------------------------------------------
* MSR_RI:
* RI field of register MSR.
*------------------------------------------------------------------------------
* Ring Indicator The complement of the RIn input. When bit 4 of the MCR is set
* to 1 (loop), this bit is equivalent to OUT1 in the MCR.
*/
#define MSR_RI_OFFSET 0x18U
#define MSR_RI_MASK 0x40U
#define MSR_RI_SHIFT 6U
/*------------------------------------------------------------------------------
* MSR_DCD:
* DCD field of register MSR.
*------------------------------------------------------------------------------
* Data Carrier Detect The complement of DCDn input. When bit 4 of the MCR is
* set to 1 (loop), this bit is equivalent to OUT2 in the MCR.
*/
#define MSR_DCD_OFFSET 0x18U
#define MSR_DCD_MASK 0x80U
#define MSR_DCD_SHIFT 7U
/*******************************************************************************
* SR register:
*------------------------------------------------------------------------------
* Scratch Register
*/
#define SR_REG_OFFSET 0x1CU
#ifdef __cplusplus
}
#endif
#endif /* CORE_16550_REGISTERS_H_*/

View File

@ -0,0 +1,865 @@
/*******************************************************************************
* (c) Copyright 2007-2015 Microsemi SoC Products Group. All rights reserved.
*
* Core16550 driver implementation. See file "core_16550.h" for a
* description of the functions implemented in this file.
*
* SVN $Revision: 7963 $
* SVN $Date: 2015-10-09 17:58:21 +0530 (Fri, 09 Oct 2015) $
*/
#include "hal.h"
#include "core_16550.h"
#include "core16550_regs.h"
#include "hal_assert.h"
#ifdef __cplusplus
extern "C" {
#endif
/*******************************************************************************
* Definitions for transmitter states
*/
#define TX_COMPLETE 0x00U
/*******************************************************************************
* Definition for transmitter FIFO size
*/
#define TX_FIFO_SIZE 16U
/*******************************************************************************
* Default receive interrupt trigger level
*/
#define DEFAULT_RX_TRIG_LEVEL ((uint8_t)UART_16550_FIFO_SINGLE_BYTE)
/*******************************************************************************
* Receiver error status mask and shift offset
*/
#define STATUS_ERROR_MASK ( LSR_OE_MASK | LSR_PE_MASK | \
LSR_FE_MASK | LSR_BI_MASK | LSR_FIER_MASK)
/*******************************************************************************
* Definitions for invalid parameters with proper type
*/
#define INVALID_INTERRUPT 0U
#define INVALID_IRQ_HANDLER ( (uart_16550_irq_handler_t) 0 )
/*******************************************************************************
* Possible values for Interrupt Identification Register Field.
*/
#define IIRF_MODEM_STATUS 0x00U
#define IIRF_THRE 0x02U
#define IIRF_RX_DATA 0x04U
#define IIRF_RX_LINE_STATUS 0x06U
#define IIRF_DATA_TIMEOUT 0x0CU
/*******************************************************************************
* Null parameters with appropriate type definitions
*/
#define NULL_ADDR ( ( addr_t ) 0 )
#define NULL_INSTANCE ( ( uart_16550_instance_t * ) 0 )
#define NULL_BUFF ( ( uint8_t * ) 0 )
/*******************************************************************************
* Possible states for different register bit fields
*/
enum {
DISABLE = 0U,
ENABLE = 1U
};
/*******************************************************************************
* Static function declarations
*/
static void default_tx_handler(uart_16550_instance_t * this_uart);
/*******************************************************************************
* Public function definitions
*/
/***************************************************************************//**
* UART_16550_init.
* See core_16550.h for details of how to use this function.
*/
void
UART_16550_init
(
uart_16550_instance_t* this_uart,
addr_t base_addr,
uint16_t baud_value,
uint8_t line_config
)
{
#ifndef NDEBUG
uint8_t dbg1;
uint8_t dbg2;
#endif
uint8_t fifo_config;
uint8_t temp;
HAL_ASSERT( base_addr != NULL_ADDR );
HAL_ASSERT( this_uart != NULL_INSTANCE );
if( ( base_addr != NULL_ADDR ) && ( this_uart != NULL_INSTANCE ) )
{
/* disable interrupts */
HAL_set_8bit_reg(base_addr, IER, DISABLE);
/* reset divisor latch */
HAL_set_8bit_reg_field(base_addr, LCR_DLAB, ENABLE);
#ifndef NDEBUG
dbg1 = HAL_get_8bit_reg_field(base_addr, LCR_DLAB );
HAL_ASSERT( dbg1 == ENABLE );
#endif
/* MSB of baud value */
temp = (uint8_t)(baud_value >> 8);
HAL_set_8bit_reg(base_addr, DMR, temp );
/* LSB of baud value */
HAL_set_8bit_reg(base_addr, DLR, ( (uint8_t)baud_value ) );
#ifndef NDEBUG
dbg1 = HAL_get_8bit_reg(base_addr, DMR );
dbg2 = HAL_get_8bit_reg(base_addr, DLR );
HAL_ASSERT( ( ( ( (uint16_t) dbg1 ) << 8 ) | dbg2 ) == baud_value );
#endif
/* reset divisor latch */
HAL_set_8bit_reg_field(base_addr, LCR_DLAB, DISABLE);
#ifndef NDEBUG
dbg1 = HAL_get_8bit_reg_field(base_addr, LCR_DLAB );
HAL_ASSERT( dbg1 == DISABLE );
#endif
/* set the line control register (bit length, stop bits, parity) */
HAL_set_8bit_reg( base_addr, LCR, line_config );
#ifndef NDEBUG
dbg1 = HAL_get_8bit_reg(base_addr, LCR );
HAL_ASSERT( dbg1 == line_config)
#endif
/* Enable and configure the RX and TX FIFOs. */
fifo_config = ((uint8_t)(DEFAULT_RX_TRIG_LEVEL << FCR_TRIG_LEVEL_SHIFT) |
FCR_RDYN_EN_MASK | FCR_CLEAR_RX_MASK |
FCR_CLEAR_TX_MASK | FCR_ENABLE_MASK );
HAL_set_8bit_reg( base_addr, FCR, fifo_config );
/* disable loopback */
HAL_set_8bit_reg_field( base_addr, MCR_LOOP, DISABLE );
#ifndef NDEBUG
dbg1 = HAL_get_8bit_reg_field(base_addr, MCR_LOOP);
HAL_ASSERT( dbg1 == DISABLE );
#endif
/* Instance setup */
this_uart->base_address = base_addr;
this_uart->tx_buffer = NULL_BUFF;
this_uart->tx_buff_size = TX_COMPLETE;
this_uart->tx_idx = 0U;
this_uart->tx_handler = default_tx_handler;
this_uart->rx_handler = ( (uart_16550_irq_handler_t) 0 );
this_uart->linests_handler = ( (uart_16550_irq_handler_t) 0 );
this_uart->modemsts_handler = ( (uart_16550_irq_handler_t) 0 );
this_uart->status = 0U;
}
}
/***************************************************************************//**
* UART_16550_polled_tx.
* See core_16550.h for details of how to use this function.
*/
void
UART_16550_polled_tx
(
uart_16550_instance_t * this_uart,
const uint8_t * pbuff,
uint32_t tx_size
)
{
uint32_t char_idx = 0U;
uint32_t size_sent;
uint8_t status;
HAL_ASSERT( this_uart != NULL_INSTANCE );
HAL_ASSERT( pbuff != NULL_BUFF );
HAL_ASSERT( tx_size > 0U );
if( ( this_uart != NULL_INSTANCE ) &&
( pbuff != NULL_BUFF ) &&
( tx_size > 0U ) )
{
/* Remain in this loop until the entire input buffer
* has been transferred to the UART.
*/
do {
/* Read the Line Status Register and update the sticky record */
status = HAL_get_8bit_reg( this_uart->base_address, LSR );
this_uart->status |= status;
/* Check if TX FIFO is empty. */
if( status & LSR_THRE_MASK )
{
uint32_t fill_size = TX_FIFO_SIZE;
/* Calculate the number of bytes to transmit. */
if ( tx_size < TX_FIFO_SIZE )
{
fill_size = tx_size;
}
/* Fill the TX FIFO with the calculated the number of bytes. */
for ( size_sent = 0U; size_sent < fill_size; ++size_sent )
{
/* Send next character in the buffer. */
HAL_set_8bit_reg( this_uart->base_address, THR,
(uint_fast8_t)pbuff[char_idx++]);
}
/* Calculate the number of untransmitted bytes remaining. */
tx_size -= size_sent;
}
} while ( tx_size );
}
}
/***************************************************************************//**
* UART_16550_polled_tx_string.
* See core_16550.h for details of how to use this function.
*/
void
UART_16550_polled_tx_string
(
uart_16550_instance_t * this_uart,
const uint8_t * p_sz_string
)
{
uint32_t char_idx = 0U;
uint32_t fill_size;
uint_fast8_t data_byte;
uint8_t status;
HAL_ASSERT( this_uart != NULL_INSTANCE );
HAL_ASSERT( p_sz_string != NULL_BUFF );
if( ( this_uart != NULL_INSTANCE ) && ( p_sz_string != NULL_BUFF ) )
{
char_idx = 0U;
/* Get the first data byte from the input buffer */
data_byte = (uint_fast8_t)p_sz_string[char_idx];
/* First check for the NULL terminator byte.
* Then remain in this loop until the entire string in the input buffer
* has been transferred to the UART.
*/
while ( 0U != data_byte )
{
/* Wait until TX FIFO is empty. */
do {
status = HAL_get_8bit_reg( this_uart->base_address,LSR);
this_uart->status |= status;
} while ( !( status & LSR_THRE_MASK ) );
/* Send bytes from the input buffer until the TX FIFO is full
* or we reach the NULL terminator byte.
*/
fill_size = 0U;
while ( (0U != data_byte) && (fill_size < TX_FIFO_SIZE) )
{
/* Send the data byte */
HAL_set_8bit_reg( this_uart->base_address, THR, data_byte );
++fill_size;
char_idx++;
/* Get the next data byte from the input buffer */
data_byte = (uint_fast8_t)p_sz_string[char_idx];
}
}
}
}
/***************************************************************************//**
* UART_16550_irq_tx.
* See core_16550.h for details of how to use this function.
*/
void
UART_16550_irq_tx
(
uart_16550_instance_t * this_uart,
const uint8_t * pbuff,
uint32_t tx_size
)
{
HAL_ASSERT( this_uart != NULL_INSTANCE )
HAL_ASSERT( pbuff != NULL_BUFF )
HAL_ASSERT( tx_size > 0U )
if( ( this_uart != NULL_INSTANCE ) &&
( pbuff != NULL_BUFF ) &&
( tx_size > 0U ) )
{
/*Initialize the UART instance with
parameters required for transmission.*/
this_uart->tx_buffer = pbuff;
this_uart->tx_buff_size = tx_size;
/* char_idx; */
this_uart->tx_idx = 0U;
/* assign handler for default data transmission */
this_uart->tx_handler = default_tx_handler;
/* enables TX interrupt */
HAL_set_8bit_reg_field(this_uart->base_address, IER_ETBEI, ENABLE);
}
}
/***************************************************************************//**
* UART_16550_tx_complete.
* See core_16550.h for details of how to use this function.
*/
int8_t
UART_16550_tx_complete
(
uart_16550_instance_t * this_uart
)
{
int8_t returnvalue = 0;
uint8_t status = 0U;
HAL_ASSERT( this_uart != NULL_INSTANCE )
if( this_uart != NULL_INSTANCE )
{
status = HAL_get_8bit_reg(this_uart->base_address,LSR);
this_uart->status |= status;
if( ( this_uart->tx_buff_size == TX_COMPLETE ) &&
( status & LSR_TEMT_MASK ) )
{
returnvalue = (int8_t)1;
}
}
return returnvalue;
}
/***************************************************************************//**
* UART_16550_get_rx.
* See core_16550.h for details of how to use this function.
*/
size_t
UART_16550_get_rx
(
uart_16550_instance_t * this_uart,
uint8_t * rx_buff,
size_t buff_size
)
{
uint8_t status;
size_t rx_size = 0U;
HAL_ASSERT( this_uart != NULL_INSTANCE )
HAL_ASSERT( rx_buff != (uint8_t *)0 )
HAL_ASSERT( buff_size > 0U )
if( ( this_uart != NULL_INSTANCE ) &&
( rx_buff != (uint8_t *)0 ) &&
( buff_size > 0U ) )
{
status = HAL_get_8bit_reg( this_uart->base_address, LSR );
this_uart->status |= status;
while ( ((status & LSR_DR_MASK) != 0U) && ( rx_size < buff_size ) )
{
rx_buff[rx_size] = HAL_get_8bit_reg( this_uart->base_address, RBR );
rx_size++;
status = HAL_get_8bit_reg( this_uart->base_address, LSR );
this_uart->status |= status;
}
}
return rx_size;
}
/***************************************************************************//**
* UART_16550_isr.
* See core_16550.h for details of how to use this function.
*/
void
UART_16550_isr
(
uart_16550_instance_t * this_uart
)
{
uint8_t iirf;
HAL_ASSERT( this_uart != NULL_INSTANCE )
if(this_uart != NULL_INSTANCE )
{
iirf = HAL_get_8bit_reg_field( this_uart->base_address, IIR_IIR );
switch ( iirf )
{
/* Modem status interrupt */
case IIRF_MODEM_STATUS:
{
if( INVALID_IRQ_HANDLER != this_uart->modemsts_handler )
{
HAL_ASSERT( INVALID_IRQ_HANDLER != this_uart->modemsts_handler );
if( INVALID_IRQ_HANDLER != this_uart->modemsts_handler )
{
(*(this_uart->modemsts_handler))(this_uart);
}
}
}
break;
/* Transmitter Holding Register Empty interrupt */
case IIRF_THRE:
{
HAL_ASSERT( INVALID_IRQ_HANDLER != this_uart->tx_handler );
if ( INVALID_IRQ_HANDLER != this_uart->tx_handler )
{
(*(this_uart->tx_handler))(this_uart);
}
}
break;
/* Received Data Available interrupt */
case IIRF_RX_DATA:
case IIRF_DATA_TIMEOUT:
{
HAL_ASSERT( INVALID_IRQ_HANDLER != this_uart->rx_handler );
if ( INVALID_IRQ_HANDLER != this_uart->rx_handler )
{
(*(this_uart->rx_handler))(this_uart);
}
}
break;
/* Line status interrupt */
case IIRF_RX_LINE_STATUS:
{
HAL_ASSERT( INVALID_IRQ_HANDLER != this_uart->linests_handler );
if ( INVALID_IRQ_HANDLER != this_uart->linests_handler )
{
(*(this_uart->linests_handler))(this_uart);
}
}
break;
/* Unidentified interrupt */
default:
{
HAL_ASSERT( INVALID_INTERRUPT )
}
}
}
}
/***************************************************************************//**
* UART_16550_set_rx_handler.
* See core_16550.h for details of how to use this function.
*/
void
UART_16550_set_rx_handler
(
uart_16550_instance_t * this_uart,
uart_16550_irq_handler_t handler,
uart_16550_rx_trig_level_t trigger_level
)
{
HAL_ASSERT( this_uart != NULL_INSTANCE )
HAL_ASSERT( handler != INVALID_IRQ_HANDLER)
HAL_ASSERT( trigger_level < UART_16550_FIFO_INVALID_TRIG_LEVEL)
if( ( this_uart != NULL_INSTANCE ) &&
( handler != INVALID_IRQ_HANDLER) &&
( trigger_level < UART_16550_FIFO_INVALID_TRIG_LEVEL) )
{
this_uart->rx_handler = handler;
/* Set the receive interrupt trigger level. */
HAL_set_8bit_reg_field( this_uart->base_address,
FCR_TRIG_LEVEL, trigger_level );
/* Enable receive interrupt. */
HAL_set_8bit_reg_field( this_uart->base_address, IER_ERBFI, ENABLE );
}
}
/***************************************************************************//**
* UART_16550_set_loopback.
* See core_16550.h for details of how to use this function.
*/
void
UART_16550_set_loopback
(
uart_16550_instance_t * this_uart,
uart_16550_loopback_t loopback
)
{
HAL_ASSERT( this_uart != NULL_INSTANCE );
HAL_ASSERT( loopback < UART_16550_INVALID_LOOPBACK );
if( ( this_uart != NULL_INSTANCE ) &&
( loopback < UART_16550_INVALID_LOOPBACK ) )
{
if ( loopback == UART_16550_LOOPBACK_OFF )
{
HAL_set_8bit_reg_field( this_uart->base_address,
MCR_LOOP,
DISABLE );
}
else
{
HAL_set_8bit_reg_field( this_uart->base_address,
MCR_LOOP,
ENABLE );
}
}
}
/***************************************************************************//**
* UART_16550_get_rx_status.
* See core_16550.h for details of how to use this function.
*/
uint8_t
UART_16550_get_rx_status
(
uart_16550_instance_t * this_uart
)
{
uint8_t status = UART_16550_INVALID_PARAM;
HAL_ASSERT( this_uart != NULL_INSTANCE );
if( ( this_uart != NULL_INSTANCE ) )
{
/*
* Bit 1 - Overflow error status
* Bit 2 - Parity error status
* Bit 3 - Frame error status
* Bit 4 - Break interrupt indicator
* Bit 7 - FIFO data error status
*/
this_uart->status |= HAL_get_8bit_reg( this_uart->base_address, LSR );
status = ( this_uart->status & STATUS_ERROR_MASK );
/*
* Clear the sticky status for this instance.
*/
this_uart->status = (uint8_t)0;
}
return status;
}
/***************************************************************************//**
* UART_16550_get_modem_status.
* See core_16550.h for details of how to use this function.
*/
uint8_t
UART_16550_get_modem_status
(
uart_16550_instance_t * this_uart
)
{
uint8_t status = UART_16550_NO_ERROR;
HAL_ASSERT( this_uart != NULL_INSTANCE )
if( ( this_uart != NULL_INSTANCE ) )
{
/*
* Extract UART error status and place in lower bits of "status".
* Bit 0 - Delta Clear to Send Indicator
* Bit 1 - Delta Clear to Receive Indicator
* Bit 2 - Trailing edge of Ring Indicator detector
* Bit 3 - Delta Data Carrier Detect indicator
* Bit 4 - Clear To Send
* Bit 5 - Data Set Ready
* Bit 6 - Ring Indicator
* Bit 7 - Data Carrier Detect
*/
status = HAL_get_8bit_reg( this_uart->base_address, MSR );
}
return status;
}
/***************************************************************************//**
* Default TX interrupt handler to automatically transmit data from
* user assgined TX buffer.
*/
static void
default_tx_handler
(
uart_16550_instance_t * this_uart
)
{
uint8_t status;
HAL_ASSERT( NULL_INSTANCE != this_uart )
if ( this_uart != NULL_INSTANCE )
{
HAL_ASSERT( NULL_BUFF != this_uart->tx_buffer )
HAL_ASSERT( 0U != this_uart->tx_buff_size )
if ( ( this_uart->tx_buffer != NULL_BUFF ) &&
( 0U != this_uart->tx_buff_size ) )
{
/* Read the Line Status Register and update the sticky record. */
status = HAL_get_8bit_reg( this_uart->base_address,LSR);
this_uart->status |= status;
/*
* This function should only be called as a result of a THRE interrupt.
* Verify that this is true before proceeding to transmit data.
*/
if ( status & LSR_THRE_MASK )
{
uint32_t size_sent = 0U;
uint32_t fill_size = TX_FIFO_SIZE;
uint32_t tx_remain = this_uart->tx_buff_size - this_uart->tx_idx;
/* Calculate the number of bytes to transmit. */
if ( tx_remain < TX_FIFO_SIZE )
{
fill_size = tx_remain;
}
/* Fill the TX FIFO with the calculated the number of bytes. */
for ( size_sent = 0U; size_sent < fill_size; ++size_sent )
{
/* Send next character in the buffer. */
HAL_set_8bit_reg( this_uart->base_address, THR,
(uint_fast8_t)this_uart->tx_buffer[this_uart->tx_idx]);
++this_uart->tx_idx;
}
}
/* Flag Tx as complete if all data has been pushed into the Tx FIFO. */
if ( this_uart->tx_idx == this_uart->tx_buff_size )
{
this_uart->tx_buff_size = TX_COMPLETE;
/* disables TX interrupt */
HAL_set_8bit_reg_field( this_uart->base_address,
IER_ETBEI, DISABLE);
}
}
}
}
/***************************************************************************//**
* UART_16550_enable_irq.
* See core_16550.h for details of how to use this function.
*/
void
UART_16550_enable_irq
(
uart_16550_instance_t * this_uart,
uint8_t irq_mask
)
{
HAL_ASSERT( this_uart != NULL_INSTANCE )
if( this_uart != NULL_INSTANCE )
{
/* irq_mask encoding: 1- enable
* bit 0 - Receive Data Available Interrupt
* bit 1 - Transmitter Holding Register Empty Interrupt
* bit 2 - Receiver Line Status Interrupt
* bit 3 - Modem Status Interrupt
*/
/* read present interrupts for enabled ones*/
irq_mask |= HAL_get_8bit_reg( this_uart->base_address, IER );
/* Enable interrupts */
HAL_set_8bit_reg( this_uart->base_address, IER, irq_mask );
}
}
/***************************************************************************//**
* UART_16550_disable_irq.
* See core_16550.h for details of how to use this function.
*/
void
UART_16550_disable_irq
(
uart_16550_instance_t * this_uart,
uint8_t irq_mask
)
{
HAL_ASSERT( this_uart != NULL_INSTANCE )
if( this_uart != NULL_INSTANCE )
{
/* irq_mask encoding: 1 - disable
* bit 0 - Receive Data Available Interrupt
* bit 1 - Transmitter Holding Register Empty Interrupt
* bit 2 - Receiver Line Status Interrupt
* bit 3 - Modem Status Interrupt
*/
/* read present interrupts for enabled ones */
irq_mask = (( (uint8_t)~irq_mask ) &
HAL_get_8bit_reg( this_uart->base_address, IER ));
/* Disable interrupts */
HAL_set_8bit_reg( this_uart->base_address, IER, irq_mask );
}
}
/***************************************************************************//**
* UART_16550_set_rxstatus_handler.
* See core_16550.h for details of how to use this function.
*/
void
UART_16550_set_rxstatus_handler
(
uart_16550_instance_t * this_uart,
uart_16550_irq_handler_t handler
)
{
HAL_ASSERT( this_uart != NULL_INSTANCE )
HAL_ASSERT( handler != INVALID_IRQ_HANDLER)
if( ( this_uart != NULL_INSTANCE ) &&
( handler != INVALID_IRQ_HANDLER) )
{
this_uart->linests_handler = handler;
/* Enable receiver line status interrupt. */
HAL_set_8bit_reg_field( this_uart->base_address, IER_ELSI, ENABLE );
}
}
/***************************************************************************//**
* UART_16550_set_tx_handler.
* See core_16550.h for details of how to use this function.
*/
void
UART_16550_set_tx_handler
(
uart_16550_instance_t * this_uart,
uart_16550_irq_handler_t handler
)
{
HAL_ASSERT( this_uart != NULL_INSTANCE )
HAL_ASSERT( handler != INVALID_IRQ_HANDLER)
if( ( this_uart != NULL_INSTANCE ) &&
( handler != INVALID_IRQ_HANDLER) )
{
this_uart->tx_handler = handler;
/* Make TX buffer info invalid */
this_uart->tx_buffer = NULL_BUFF;
this_uart->tx_buff_size = 0U;
/* Enable transmitter holding register Empty interrupt. */
HAL_set_8bit_reg_field( this_uart->base_address, IER_ETBEI, ENABLE );
}
}
/***************************************************************************//**
* UART_16550_set_modemstatus_handler.
* See core_16550.h for details of how to use this function.
*/
void
UART_16550_set_modemstatus_handler
(
uart_16550_instance_t * this_uart,
uart_16550_irq_handler_t handler
)
{
HAL_ASSERT( this_uart != NULL_INSTANCE )
HAL_ASSERT( handler != INVALID_IRQ_HANDLER)
if( ( this_uart != NULL_INSTANCE ) &&
( handler != INVALID_IRQ_HANDLER) )
{
this_uart->modemsts_handler = handler;
/* Enable modem status interrupt. */
HAL_set_8bit_reg_field( this_uart->base_address, IER_EDSSI, ENABLE );
}
}
/***************************************************************************//**
* UART_16550_fill_tx_fifo.
* See core_16550.h for details of how to use this function.
*/
size_t
UART_16550_fill_tx_fifo
(
uart_16550_instance_t * this_uart,
const uint8_t * tx_buffer,
size_t tx_size
)
{
uint8_t status;
size_t size_sent = 0U;
HAL_ASSERT( this_uart != NULL_INSTANCE )
HAL_ASSERT( tx_buffer != NULL_BUFF )
HAL_ASSERT( tx_size > 0U )
/* Fill the UART's Tx FIFO until the FIFO is full or the complete input
* buffer has been written. */
if( (this_uart != NULL_INSTANCE) &&
(tx_buffer != NULL_BUFF) &&
(tx_size > 0U) )
{
/* Read the Line Status Register and update the sticky record. */
status = HAL_get_8bit_reg( this_uart->base_address, LSR );
this_uart->status |= status;
/* Check if TX FIFO is empty. */
if( status & LSR_THRE_MASK )
{
uint32_t fill_size = TX_FIFO_SIZE;
/* Calculate the number of bytes to transmit. */
if ( tx_size < TX_FIFO_SIZE )
{
fill_size = tx_size;
}
/* Fill the TX FIFO with the calculated the number of bytes. */
for ( size_sent = 0U; size_sent < fill_size; ++size_sent )
{
/* Send next character in the buffer. */
HAL_set_8bit_reg( this_uart->base_address, THR,
(uint_fast8_t)tx_buffer[size_sent]);
}
}
}
return size_sent;
}
/***************************************************************************//**
* UART_16550_get_tx_status.
* See core_16550.h for details of how to use this function.
*/
uint8_t
UART_16550_get_tx_status
(
uart_16550_instance_t * this_uart
)
{
uint8_t status = UART_16550_TX_BUSY;
HAL_ASSERT( this_uart != NULL_INSTANCE );
if( ( this_uart != NULL_INSTANCE ) )
{
/* Read the Line Status Register and update the sticky record. */
status = HAL_get_8bit_reg( this_uart->base_address, LSR );
this_uart->status |= status;
/*
* Extract the transmit status bits from the UART's Line Status Register.
* Bit 5 - Transmitter Holding Register/FIFO Empty (THRE) status. (If = 1, TX FIFO is empty)
* Bit 6 - Transmitter Empty (TEMT) status. (If = 1, both TX FIFO and shift register are empty)
*/
status &= ( LSR_THRE_MASK | LSR_TEMT_MASK );
}
return status;
}
#ifdef __cplusplus
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,461 @@
/*******************************************************************************
* (c) Copyright 2008-2015 Microsemi SoC Products Group. All rights reserved.
*
* CoreGPIO bare metal driver implementation.
*
* SVN $Revision: 7964 $
* SVN $Date: 2015-10-09 18:26:53 +0530 (Fri, 09 Oct 2015) $
*/
#include "core_gpio.h"
#include "hal.h"
#include "hal_assert.h"
#include "coregpio_regs.h"
/*-------------------------------------------------------------------------*//**
*
*/
#define GPIO_INT_ENABLE_MASK (uint32_t)0x00000008UL
#define OUTPUT_BUFFER_ENABLE_MASK 0x00000004UL
#define NB_OF_GPIO 32
#define CLEAR_ALL_IRQ32 (uint32_t)0xFFFFFFFF
#define CLEAR_ALL_IRQ16 (uint16_t)0xFFFF
#define CLEAR_ALL_IRQ8 (uint8_t)0xFF
/*-------------------------------------------------------------------------*//**
* GPIO_init()
* See "core_gpio.h" for details of how to use this function.
*/
void GPIO_init
(
gpio_instance_t * this_gpio,
addr_t base_addr,
gpio_apb_width_t bus_width
)
{
uint8_t i = 0;
addr_t cfg_reg_addr = base_addr;
this_gpio->base_addr = base_addr;
this_gpio->apb_bus_width = bus_width;
/* Clear configuration. */
for( i = 0, cfg_reg_addr = base_addr; i < NB_OF_GPIO; ++i )
{
HW_set_8bit_reg( cfg_reg_addr, 0 );
cfg_reg_addr += 4;
}
/* Clear any pending interrupts */
switch( this_gpio->apb_bus_width )
{
case GPIO_APB_32_BITS_BUS:
HAL_set_32bit_reg( this_gpio->base_addr, IRQ, CLEAR_ALL_IRQ32 );
break;
case GPIO_APB_16_BITS_BUS:
HAL_set_16bit_reg( this_gpio->base_addr, IRQ0, (uint16_t)CLEAR_ALL_IRQ16 );
HAL_set_16bit_reg( this_gpio->base_addr, IRQ1, (uint16_t)CLEAR_ALL_IRQ16 );
break;
case GPIO_APB_8_BITS_BUS:
HAL_set_8bit_reg( this_gpio->base_addr, IRQ0, (uint8_t)CLEAR_ALL_IRQ8 );
HAL_set_8bit_reg( this_gpio->base_addr, IRQ1, (uint8_t)CLEAR_ALL_IRQ8 );
HAL_set_8bit_reg( this_gpio->base_addr, IRQ2, (uint8_t)CLEAR_ALL_IRQ8 );
HAL_set_8bit_reg( this_gpio->base_addr, IRQ3, (uint8_t)CLEAR_ALL_IRQ8 );
break;
default:
HAL_ASSERT(0);
break;
}
}
/*-------------------------------------------------------------------------*//**
* GPIO_config
* See "core_gpio.h" for details of how to use this function.
*/
void GPIO_config
(
gpio_instance_t * this_gpio,
gpio_id_t port_id,
uint32_t config
)
{
HAL_ASSERT( port_id < NB_OF_GPIO );
if ( port_id < NB_OF_GPIO )
{
uint32_t cfg_reg_addr = this_gpio->base_addr;
cfg_reg_addr += (port_id * 4);
HW_set_32bit_reg( cfg_reg_addr, config );
/*
* Verify that the configuration was correctly written. Failure to read
* back the expected value may indicate that the GPIO port was configured
* as part of the hardware flow and cannot be modified through software.
* It may also indicate that the base address passed as parameter to
* GPIO_init() was incorrect.
*/
HAL_ASSERT( HW_get_32bit_reg( cfg_reg_addr ) == config );
}
}
/*-------------------------------------------------------------------------*//**
* GPIO_set_outputs
* See "core_gpio.h" for details of how to use this function.
*/
void GPIO_set_outputs
(
gpio_instance_t * this_gpio,
uint32_t value
)
{
switch( this_gpio->apb_bus_width )
{
case GPIO_APB_32_BITS_BUS:
HAL_set_32bit_reg( this_gpio->base_addr, GPIO_OUT, value );
break;
case GPIO_APB_16_BITS_BUS:
HAL_set_16bit_reg( this_gpio->base_addr, GPIO_OUT0, (uint16_t)value );
HAL_set_16bit_reg( this_gpio->base_addr, GPIO_OUT1, (uint16_t)(value >> 16) );
break;
case GPIO_APB_8_BITS_BUS:
HAL_set_8bit_reg( this_gpio->base_addr, GPIO_OUT0, (uint8_t)value );
HAL_set_8bit_reg( this_gpio->base_addr, GPIO_OUT1, (uint8_t)(value >> 8) );
HAL_set_8bit_reg( this_gpio->base_addr, GPIO_OUT2, (uint8_t)(value >> 16) );
HAL_set_8bit_reg( this_gpio->base_addr, GPIO_OUT3, (uint8_t)(value >> 24) );
break;
default:
HAL_ASSERT(0);
break;
}
/*
* Verify that the output register was correctly written. Failure to read back
* the expected value may indicate that some of the GPIOs may not exist due to
* the number of GPIOs selected in the CoreGPIO hardware flow configuration.
* It may also indicate that the base address or APB bus width passed as
* parameter to the GPIO_init() function do not match the hardware design.
*/
HAL_ASSERT( GPIO_get_outputs( this_gpio ) == value );
}
/*-------------------------------------------------------------------------*//**
* GPIO_get_inputs
* See "core_gpio.h" for details of how to use this function.
*/
uint32_t GPIO_get_inputs
(
gpio_instance_t * this_gpio
)
{
uint32_t gpio_in = 0;
switch( this_gpio->apb_bus_width )
{
case GPIO_APB_32_BITS_BUS:
gpio_in = HAL_get_32bit_reg( this_gpio->base_addr, GPIO_IN );
break;
case GPIO_APB_16_BITS_BUS:
gpio_in |= HAL_get_16bit_reg( this_gpio->base_addr, GPIO_IN0 );
gpio_in |= (HAL_get_16bit_reg( this_gpio->base_addr, GPIO_IN1 ) << 16);
break;
case GPIO_APB_8_BITS_BUS:
gpio_in |= HAL_get_8bit_reg( this_gpio->base_addr, GPIO_IN0 );
gpio_in |= (HAL_get_8bit_reg( this_gpio->base_addr, GPIO_IN1 ) << 8);
gpio_in |= (HAL_get_8bit_reg( this_gpio->base_addr, GPIO_IN2 ) << 16);
gpio_in |= (HAL_get_8bit_reg( this_gpio->base_addr, GPIO_IN3 ) << 24);
break;
default:
HAL_ASSERT(0);
break;
}
return gpio_in;
}
/*-------------------------------------------------------------------------*//**
* GPIO_get_outputs
* See "core_gpio.h" for details of how to use this function.
*/
uint32_t GPIO_get_outputs
(
gpio_instance_t * this_gpio
)
{
uint32_t gpio_out = 0;
switch( this_gpio->apb_bus_width )
{
case GPIO_APB_32_BITS_BUS:
gpio_out = HAL_get_32bit_reg( this_gpio->base_addr, GPIO_OUT );
break;
case GPIO_APB_16_BITS_BUS:
gpio_out |= HAL_get_16bit_reg( this_gpio->base_addr, GPIO_OUT0 );
gpio_out |= (HAL_get_16bit_reg( this_gpio->base_addr, GPIO_OUT1 ) << 16);
break;
case GPIO_APB_8_BITS_BUS:
gpio_out |= HAL_get_16bit_reg( this_gpio->base_addr, GPIO_OUT0 );
gpio_out |= (HAL_get_16bit_reg( this_gpio->base_addr, GPIO_OUT1 ) << 8);
gpio_out |= (HAL_get_16bit_reg( this_gpio->base_addr, GPIO_OUT2 ) << 16);
gpio_out |= (HAL_get_16bit_reg( this_gpio->base_addr, GPIO_OUT3 ) << 24);
break;
default:
HAL_ASSERT(0);
break;
}
return gpio_out;
}
/*-------------------------------------------------------------------------*//**
* GPIO_set_output
* See "core_gpio.h" for details of how to use this function.
*/
void GPIO_set_output
(
gpio_instance_t * this_gpio,
gpio_id_t port_id,
uint8_t value
)
{
HAL_ASSERT( port_id < NB_OF_GPIO );
switch( this_gpio->apb_bus_width )
{
case GPIO_APB_32_BITS_BUS:
{
uint32_t outputs_state;
outputs_state = HAL_get_32bit_reg( this_gpio->base_addr, GPIO_OUT );
if ( 0 == value )
{
outputs_state &= ~(1 << port_id);
}
else
{
outputs_state |= 1 << port_id;
}
HAL_set_32bit_reg( this_gpio->base_addr, GPIO_OUT, outputs_state );
/*
* Verify that the output register was correctly written. Failure to read back
* the expected value may indicate that some of the GPIOs may not exist due to
* the number of GPIOs selected in the CoreGPIO hardware flow configuration.
* It may also indicate that the base address or APB bus width passed as
* parameter to the GPIO_init() function do not match the hardware design.
*/
HAL_ASSERT( HAL_get_32bit_reg( this_gpio->base_addr, GPIO_OUT ) == outputs_state );
}
break;
case GPIO_APB_16_BITS_BUS:
{
uint16_t outputs_state;
uint32_t gpio_out_reg_addr = this_gpio->base_addr + GPIO_OUT_REG_OFFSET + ((port_id >> 4) * 4);
outputs_state = HW_get_16bit_reg( gpio_out_reg_addr );
if ( 0 == value )
{
outputs_state &= ~(1 << (port_id & 0x0F));
}
else
{
outputs_state |= 1 << (port_id & 0x0F);
}
HW_set_16bit_reg( gpio_out_reg_addr, outputs_state );
/*
* Verify that the output register was correctly written. Failure to read back
* the expected value may indicate that some of the GPIOs may not exist due to
* the number of GPIOs selected in the CoreGPIO hardware flow configuration.
* It may also indicate that the base address or APB bus width passed as
* parameter to the GPIO_init() function do not match the hardware design.
*/
HAL_ASSERT( HW_get_16bit_reg( gpio_out_reg_addr ) == outputs_state );
}
break;
case GPIO_APB_8_BITS_BUS:
{
uint8_t outputs_state;
uint32_t gpio_out_reg_addr = this_gpio->base_addr + GPIO_OUT_REG_OFFSET + ((port_id >> 3) * 4);
outputs_state = HW_get_8bit_reg( gpio_out_reg_addr );
if ( 0 == value )
{
outputs_state &= ~(1 << (port_id & 0x07));
}
else
{
outputs_state |= 1 << (port_id & 0x07);
}
HW_set_8bit_reg( gpio_out_reg_addr, outputs_state );
/*
* Verify that the output register was correctly written. Failure to read back
* the expected value may indicate that some of the GPIOs may not exist due to
* the number of GPIOs selected in the CoreGPIO hardware flow configuration.
* It may also indicate that the base address or APB bus width passed as
* parameter to the GPIO_init() function do not match the hardware design.
*/
HAL_ASSERT( HW_get_8bit_reg( gpio_out_reg_addr ) == outputs_state );
}
break;
default:
HAL_ASSERT(0);
break;
}
}
/*-------------------------------------------------------------------------*//**
* GPIO_drive_inout
* See "core_gpio.h" for details of how to use this function.
*/
void GPIO_drive_inout
(
gpio_instance_t * this_gpio,
gpio_id_t port_id,
gpio_inout_state_t inout_state
)
{
uint32_t config;
uint32_t cfg_reg_addr = this_gpio->base_addr;
HAL_ASSERT( port_id < NB_OF_GPIO );
switch( inout_state )
{
case GPIO_DRIVE_HIGH:
/* Set output high */
GPIO_set_output( this_gpio, port_id, 1 );
/* Enable output buffer */
cfg_reg_addr = this_gpio->base_addr + (port_id * 4);
config = HW_get_8bit_reg( cfg_reg_addr );
config |= OUTPUT_BUFFER_ENABLE_MASK;
HW_set_8bit_reg( cfg_reg_addr, config );
break;
case GPIO_DRIVE_LOW:
/* Set output low */
GPIO_set_output( this_gpio, port_id, 0 );
/* Enable output buffer */
cfg_reg_addr = this_gpio->base_addr + (port_id * 4);
config = HW_get_8bit_reg( cfg_reg_addr );
config |= OUTPUT_BUFFER_ENABLE_MASK;
HW_set_8bit_reg( cfg_reg_addr, config );
break;
case GPIO_HIGH_Z:
/* Disable output buffer */
cfg_reg_addr = this_gpio->base_addr + (port_id * 4);
config = HW_get_8bit_reg( cfg_reg_addr );
config &= ~OUTPUT_BUFFER_ENABLE_MASK;
HW_set_8bit_reg( cfg_reg_addr, config );
break;
default:
HAL_ASSERT(0);
break;
}
}
/*-------------------------------------------------------------------------*//**
* GPIO_enable_irq
* See "core_gpio.h" for details of how to use this function.
*/
void GPIO_enable_irq
(
gpio_instance_t * this_gpio,
gpio_id_t port_id
)
{
uint32_t cfg_value;
uint32_t cfg_reg_addr = this_gpio->base_addr;
HAL_ASSERT( port_id < NB_OF_GPIO );
if ( port_id < NB_OF_GPIO )
{
cfg_reg_addr += (port_id * 4);
cfg_value = HW_get_8bit_reg( cfg_reg_addr );
cfg_value |= GPIO_INT_ENABLE_MASK;
HW_set_8bit_reg( cfg_reg_addr, cfg_value );
}
}
/*-------------------------------------------------------------------------*//**
* GPIO_disable_irq
* See "core_gpio.h" for details of how to use this function.
*/
void GPIO_disable_irq
(
gpio_instance_t * this_gpio,
gpio_id_t port_id
)
{
uint32_t cfg_value;
uint32_t cfg_reg_addr = this_gpio->base_addr;
HAL_ASSERT( port_id < NB_OF_GPIO );
if ( port_id < NB_OF_GPIO )
{
cfg_reg_addr += (port_id * 4);
cfg_value = HW_get_8bit_reg( cfg_reg_addr );
cfg_value &= ~GPIO_INT_ENABLE_MASK;
HW_set_8bit_reg( cfg_reg_addr, cfg_value );
}
}
/*-------------------------------------------------------------------------*//**
* GPIO_clear_irq
* See "core_gpio.h" for details of how to use this function.
*/
void GPIO_clear_irq
(
gpio_instance_t * this_gpio,
gpio_id_t port_id
)
{
uint32_t irq_clr_value = ((uint32_t)1) << ((uint32_t)port_id);
switch( this_gpio->apb_bus_width )
{
case GPIO_APB_32_BITS_BUS:
HAL_set_32bit_reg( this_gpio->base_addr, IRQ, irq_clr_value );
break;
case GPIO_APB_16_BITS_BUS:
HAL_set_16bit_reg( this_gpio->base_addr, IRQ0, irq_clr_value );
HAL_set_16bit_reg( this_gpio->base_addr, IRQ1, irq_clr_value >> 16 );
break;
case GPIO_APB_8_BITS_BUS:
HAL_set_8bit_reg( this_gpio->base_addr, IRQ0, irq_clr_value );
HAL_set_8bit_reg( this_gpio->base_addr, IRQ1, irq_clr_value >> 8 );
HAL_set_8bit_reg( this_gpio->base_addr, IRQ2, irq_clr_value >> 16 );
HAL_set_8bit_reg( this_gpio->base_addr, IRQ3, irq_clr_value >> 24 );
break;
default:
HAL_ASSERT(0);
break;
}
}

View File

@ -0,0 +1,552 @@
/*******************************************************************************
* (c) Copyright 2008-2015 Microsemi SoC Products Group. All rights reserved.
*
* CoreGPIO bare metal driver public API.
*
* SVN $Revision: 7964 $
* SVN $Date: 2015-10-09 18:26:53 +0530 (Fri, 09 Oct 2015) $
*/
/*=========================================================================*//**
@mainpage CoreGPIO Bare Metal Driver.
@section intro_sec Introduction
The CoreGPIO hardware IP includes up to 32 general purpose input output GPIOs.
This driver provides a set of functions for controlling the GPIOs as part of a
bare metal system where no operating system is available. These drivers
can be adapted for use as part of an operating system but the implementation
of the adaptation layer between this driver and the operating system's driver
model is outside the scope of this driver.
@section driver_configuration Driver Configuration
The CoreGPIO individual IOs can be configured either in the hardware flow or
as part of the software application through calls to the GPIO_config() function.
GPIOs configured as as part of the hardware is fixed and cannot be modified
using a call to the GPI_config() function.
@section theory_op Theory of Operation
The CoreGPIO driver uses the Actel Hardware Abstraction Layer (HAL) to access
hardware registers. You must ensure that the Actel HAL is included as part of
your software project. The Actel HAL is available through the Actel Firmware
Catalog.
The CoreGPIO driver functions are logically grouped into the following groups:
- Initiliazation
- Configuration
- Reading and writing GPIO state
- Interrupt control
The CoreGPIO driver is initialized through a call to the GPIO_init() function.
The GPIO_init() function must be called before any other GPIO driver functions
can be called.
Each GPIO port is individually configured through a call to the
GPIO_config() function. Configuration includes deciding if a GPIO port
will be used as input, output or both. GPIO ports configured as inputs can be
further configured to generate interrupts based on the input's state.
Interrupts can be level or edge sensitive.
Please note that a CoreGPIO hardware instance can be generated, as part of the
hardware flow, with a fixed configuration for some or all of its IOs. Attempting
to modify the configuration of such a hardware configured IO using the
GPIO_config() function has no effect.
The state of the GPIO ports can be read and written using the following
functions:
- GPIO_get_inputs()
- GPIO_get_outputs()
- GPIO_set_outputs()
- GPIO_drive_inout()
Interrupts generated by GPIO ports configured as inputs are controlled using
the following functions:
- GPIO_enable_irq()
- GPIO_disable_irq()
- GPIO_clear_irq()
*//*=========================================================================*/
#ifndef CORE_GPIO_H_
#define CORE_GPIO_H_
#include <stdint.h>
#include "cpu_types.h"
/*-------------------------------------------------------------------------*//**
The gpio_id_t enumeration is used to identify GPIOs as part of the
parameter to functions:
- GPIO_config(),
- GPIO_drive_inout(),
- GPIO_enable_int(),
- GPIO_disable_int(),
- GPIO_clear_int()
*/
typedef enum __gpio_id_t
{
GPIO_0 = 0,
GPIO_1 = 1,
GPIO_2 = 2,
GPIO_3 = 3,
GPIO_4 = 4,
GPIO_5 = 5,
GPIO_6 = 6,
GPIO_7 = 7,
GPIO_8 = 8,
GPIO_9 = 9,
GPIO_10 = 10,
GPIO_11 = 11,
GPIO_12 = 12,
GPIO_13 = 13,
GPIO_14 = 14,
GPIO_15 = 15,
GPIO_16 = 16,
GPIO_17 = 17,
GPIO_18 = 18,
GPIO_19 = 19,
GPIO_20 = 20,
GPIO_21 = 21,
GPIO_22 = 22,
GPIO_23 = 23,
GPIO_24 = 24,
GPIO_25 = 25,
GPIO_26 = 26,
GPIO_27 = 27,
GPIO_28 = 28,
GPIO_29 = 29,
GPIO_30 = 30,
GPIO_31 = 31
} gpio_id_t;
typedef enum __gpio_apb_width_t
{
GPIO_APB_8_BITS_BUS = 0,
GPIO_APB_16_BITS_BUS = 1,
GPIO_APB_32_BITS_BUS = 2,
GPIO_APB_UNKNOWN_BUS_WIDTH = 3
} gpio_apb_width_t;
/*-------------------------------------------------------------------------*//**
*/
typedef struct __gpio_instance_t
{
addr_t base_addr;
gpio_apb_width_t apb_bus_width;
} gpio_instance_t;
/*-------------------------------------------------------------------------*//**
GPIO ports definitions used to identify GPIOs as part of the parameter to
function GPIO_set_outputs().
These definitions can also be used to identity GPIO through logical
operations on the return value of function GPIO_get_inputs().
*/
#define GPIO_0_MASK 0x00000001UL
#define GPIO_1_MASK 0x00000002UL
#define GPIO_2_MASK 0x00000004UL
#define GPIO_3_MASK 0x00000008UL
#define GPIO_4_MASK 0x00000010UL
#define GPIO_5_MASK 0x00000020UL
#define GPIO_6_MASK 0x00000040UL
#define GPIO_7_MASK 0x00000080UL
#define GPIO_8_MASK 0x00000100UL
#define GPIO_9_MASK 0x00000200UL
#define GPIO_10_MASK 0x00000400UL
#define GPIO_11_MASK 0x00000800UL
#define GPIO_12_MASK 0x00001000UL
#define GPIO_13_MASK 0x00002000UL
#define GPIO_14_MASK 0x00004000UL
#define GPIO_15_MASK 0x00008000UL
#define GPIO_16_MASK 0x00010000UL
#define GPIO_17_MASK 0x00020000UL
#define GPIO_18_MASK 0x00040000UL
#define GPIO_19_MASK 0x00080000UL
#define GPIO_20_MASK 0x00100000UL
#define GPIO_21_MASK 0x00200000UL
#define GPIO_22_MASK 0x00400000UL
#define GPIO_23_MASK 0x00800000UL
#define GPIO_24_MASK 0x01000000UL
#define GPIO_25_MASK 0x02000000UL
#define GPIO_26_MASK 0x04000000UL
#define GPIO_27_MASK 0x08000000UL
#define GPIO_28_MASK 0x10000000UL
#define GPIO_29_MASK 0x20000000UL
#define GPIO_30_MASK 0x40000000UL
#define GPIO_31_MASK 0x80000000UL
/*-------------------------------------------------------------------------*//**
* GPIO modes
*/
#define GPIO_INPUT_MODE 0x0000000002UL
#define GPIO_OUTPUT_MODE 0x0000000005UL
#define GPIO_INOUT_MODE 0x0000000003UL
/*-------------------------------------------------------------------------*//**
* Possible GPIO inputs interrupt configurations.
*/
#define GPIO_IRQ_LEVEL_HIGH 0x0000000000UL
#define GPIO_IRQ_LEVEL_LOW 0x0000000020UL
#define GPIO_IRQ_EDGE_POSITIVE 0x0000000040UL
#define GPIO_IRQ_EDGE_NEGATIVE 0x0000000060UL
#define GPIO_IRQ_EDGE_BOTH 0x0000000080UL
/*-------------------------------------------------------------------------*//**
* Possible states for GPIO configured as INOUT.
*/
typedef enum gpio_inout_state
{
GPIO_DRIVE_LOW = 0,
GPIO_DRIVE_HIGH,
GPIO_HIGH_Z
} gpio_inout_state_t;
/*-------------------------------------------------------------------------*//**
The GPIO_init() function initialises a CoreGPIO hardware instance and the data
structure associated with the CoreGPIO hardware instance.
Please note that a CoreGPIO hardware instance can be generated with a fixed
configuration for some or all of its IOs as part of the hardware flow. Attempting
to modify the configuration of such a hardware configured IO using the
GPIO_config() function has no effect.
@param this_gpio
Pointer to the gpio_instance_t data structure instance holding all data
regarding the CoreGPIO hardware instance being initialized. A pointer to the
same data structure will be used in subsequent calls to the CoreGPIO driver
functions in order to identify the CoreGPIO instance that should perform the
operation implemented by the called driver function.
@param base_addr
The base_addr parameter is the base address in the processor's memory map for
the registers of the GPIO instance being initialized.
@param bus_width
The bus_width parameter informs the driver of the APB bus width selected during
the hardware flow configuration of the CoreGPIO hardware instance. It indicates
to the driver whether the CoreGPIO hardware registers will be visible as 8, 16
or 32 bits registers. Allowed value are:
- GPIO_APB_8_BITS_BUS
- GPIO_APB_16_BITS_BUS
- GPIO_APB_32_BITS_BUS
@return
none.
Example:
@code
#define COREGPIO_BASE_ADDR 0xC2000000
gpio_instance_t g_gpio;
void system_init( void )
{
GPIO_init( &g_gpio, COREGPIO_BASE_ADDR, GPIO_APB_32_BITS_BUS );
}
@endcode
*/
void GPIO_init
(
gpio_instance_t * this_gpio,
addr_t base_addr,
gpio_apb_width_t bus_width
);
/*-------------------------------------------------------------------------*//**
The GPIO_config() function is used to configure an individual GPIO port.
@param this_gpio
The this_gpio parameter is a pointer to the gpio_instance_t structure holding
all data regarding the CoreGPIO instance controlled through this function call.
@param port_id
The port_id parameter identifies the GPIO port to be configured.
An enumeration item of the form GPIO_n where n is the number of the GPIO
port is used to identify the GPIO port. For example GPIO_0 identifies the
first GPIO port and GPIO_31 the last one.
@param config
The config parameter specifies the configuration to be applied to the GPIO
port identified by the first parameter. It is a logical OR of GPIO mode and
the interrupt mode. The interrupt mode is only relevant if the GPIO is
configured as input.
Possible modes are:
- GPIO_INPUT_MODE,
- GPIO_OUTPUT_MODE,
- GPIO_INOUT_MODE.
Possible interrupt modes are:
- GPIO_IRQ_LEVEL_HIGH,
- GPIO_IRQ_LEVEL_LOW,
- GPIO_IRQ_EDGE_POSITIVE,
- GPIO_IRQ_EDGE_NEGATIVE,
- GPIO_IRQ_EDGE_BOTH
@return
none.
For example the following call will configure GPIO 4 as an input generating
interrupts on a low to high transition of the input:
@code
GPIO_config( &g_gpio, GPIO_4, GPIO_INPUT_MODE | GPIO_IRQ_EDGE_POSITIVE );
@endcode
*/
void GPIO_config
(
gpio_instance_t * this_gpio,
gpio_id_t port_id,
uint32_t config
);
/*-------------------------------------------------------------------------*//**
The GPIO_set_outputs() function is used to set the state of the GPIO ports
configured as outputs.
@param this_gpio
The this_gpio parameter is a pointer to the gpio_instance_t structure holding
all data regarding the CoreGPIO instance controlled through this function call.
@param value
The value parameter specifies the state of the GPIO ports configured as
outputs. It is a bit mask of the form (GPIO_n_MASK | GPIO_m_MASK) where n
and m are numbers identifying GPIOs.
For example (GPIO_0_MASK | GPIO_1_MASK | GPIO_2_MASK ) specifies that the
first, second and third GPIOs' must be set high and all other outputs set
low.
@return
none.
Example 1:
Set GPIOs outputs 0 and 8 high and all other GPIO outputs low.
@code
GPIO_set_outputs( &g_gpio, GPIO_0_MASK | GPIO_8_MASK );
@endcode
Example 2:
Set GPIOs outputs 2 and 4 low without affecting other GPIO outputs.
@code
uint32_t gpio_outputs;
gpio_outputs = GPIO_get_outputs( &g_gpio );
gpio_outputs &= ~( GPIO_2_MASK | GPIO_4_MASK );
GPIO_set_outputs( &g_gpio, gpio_outputs );
@endcode
@see GPIO_get_outputs()
*/
void GPIO_set_outputs
(
gpio_instance_t * this_gpio,
uint32_t value
);
/*-------------------------------------------------------------------------*//**
The GPIO_set_output() function is used to set the state of a single GPIO
port configured as output.
@param this_gpio
The this_gpio parameter is a pointer to the gpio_instance_t structure holding
all data regarding the CoreGPIO instance controlled through this function call.
@param port_id
The port_id parameter specifies the GPIO port that will have its output set
by a call to this function.
@param value
The value parameter specifies the desired state for the GPIO output. A value
of 0 will set the output low and a value of 1 will set the port high.
@return
none.
*/
void GPIO_set_output
(
gpio_instance_t * this_gpio,
gpio_id_t port_id,
uint8_t value
);
/*-------------------------------------------------------------------------*//**
The GPIO_get_inputs() function is used to read the state of all GPIOs
confgured as inputs.
@param this_gpio
The this_gpio parameter is a pointer to the gpio_instance_t structure holding
all data regarding the CoreGPIO instance controlled through this function call.
@return
This function returns a 32 bit unsigned integer where each bit represents
the state of an input. The least significant bit representing the state of
GPIO 0 and the most significant bit the state of GPIO 31.
*/
uint32_t GPIO_get_inputs
(
gpio_instance_t * this_gpio
);
/*-------------------------------------------------------------------------*//**
The GPIO_get_outputs() function is used to read the current state of all
GPIO outputs.
@param this_gpio
The this_gpio parameter is a pointer to the gpio_instance_t structure holding
all data regarding the CoreGPIO instance controlled through this function call.
@return
This function returns a 32 bit unsigned integer where each bit represents
the state of an output. The least significant bit representing the state
of GPIO 0 and the most significant bit the state of GPIO 31.
*/
uint32_t GPIO_get_outputs
(
gpio_instance_t * this_gpio
);
/*-------------------------------------------------------------------------*//**
The GPIO_drive_inout() function is used to set the output state of a
GPIO configured as INOUT. An INOUT GPIO can be in one of three states:
- high
- low
- high impedance
An INOUT output would typically be used where several devices can drive the
state of a signal. The high and low states are equivalent to the high and low
states of a GPIO configured as output. The high impedance state is used to
prevent the GPIO from driving the state of the output and therefore allow
reading the state of the GPIO as an input.
Please note that the GPIO port you wish to use as INOUT through this function
must be configurable through software. Therefore the GPIO ports used as INOUT
must not have a fixed configuration selected as part of the hardware flow.
@param this_gpio
The this_gpio parameter is a pointer to the gpio_instance_t structure holding
all data regarding the CoreGPIO instance controlled through this function call.
@param port_id
The port_id parameter identifies the GPIO for whcih this function will
change the output state.
An enumeration item of the form GPIO_n where n is the number of the GPIO
port is used to identify the GPIO port. For example GPIO_0 identifies the
first GPIO port and GPIO_31 the last one.
@param inout_state
The inout_state parameter specifies the state of the I/O identified by the
first parameter. Possible states are:
- GPIO_DRIVE_HIGH,
- GPIO_DRIVE_LOW,
- GPIO_HIGH_Z (high impedance)
@return
none.
Example:
The call to GPIO_drive_inout() below will set the GPIO 7 output to
high impedance state.
@code
GPIO_drive_inout( &g_gpio, GPIO_7, GPIO_HIGH_Z );
@endcode
*/
void GPIO_drive_inout
(
gpio_instance_t * this_gpio,
gpio_id_t port_id,
gpio_inout_state_t inout_state
);
/*-------------------------------------------------------------------------*//**
The GPIO_enable_irq() function is used to enable an interrupt to be
generated based on the state of the input identified as parameter.
@param this_gpio
The this_gpio parameter is a pointer to the gpio_instance_t structure holding
all data regarding the CoreGPIO instance controlled through this function call.
@param port_id
The port_id parameter identifies the GPIO input the call to
GPIO_enable_irq() will enable to generate interrupts.
An enumeration item of the form GPIO_n where n is the number of the GPIO
port is used to identify the GPIO port. For example GPIO_0 identifies the
first GPIO port and GPIO_31 the last one.
@return
none.
Example:
The call to GPIO_enable_irq() below will allow GPIO 8 to generate
interrupts.
@code
GPIO_enable_irq( &g_gpio, GPIO_8 );
@endcode
*/
void GPIO_enable_irq
(
gpio_instance_t * this_gpio,
gpio_id_t port_id
);
/*-------------------------------------------------------------------------*//**
The GPIO_disable_irq() function is used to disable interrupt from being
generated based on the state of the input specified as parameter.
@param this_gpio
The this_gpio parameter is a pointer to the gpio_instance_t structure holding
all data regarding the CoreGPIO instance controlled through this function call.
@param port_id
The port_id parameter identifies the GPIO input the call to
GPIO_disable_irq() will disable from generating interrupts.
An enumeration item of the form GPIO_n where n is the number of the GPIO
port is used to identify the GPIO port. For example GPIO_0 identifies the
first GPIO port and GPIO_31 the last one.
@return
none.
Example:
The call to GPIO_disable_irq() below will prevent GPIO 8 from generating
interrupts.
@code
GPIO_disable_irq( &g_gpio, GPIO_8 );
@endcode
*/
void GPIO_disable_irq
(
gpio_instance_t * this_gpio,
gpio_id_t port_id
);
/*-------------------------------------------------------------------------*//**
The GPIO_clear_irq() function is used to clear the interrupt generated by
the GPIO specified as parameter. The GPIO_clear_irq() function must be
called as part of a GPIO interrupt service routine (ISR) in order to prevent
the same interrupt event retriggering a call to the GPIO ISR.
Please note that interrupts may also need to be cleared in the processor's
interrupt controller.
@param this_gpio
The this_gpio parameter is a pointer to the gpio_instance_t structure holding
all data regarding the CoreGPIO instance controlled through this function call.
@param port_id
The port_id parameter identifies the GPIO input for which to clear the
interrupt.
An enumeration item of the form GPIO_n where n is the number of the GPIO
port is used to identify the GPIO port. For example GPIO_0 identifies the
first GPIO port and GPIO_31 the last one.
@return
none.
Example:
The example below demonstrates the use of the GPIO_clear_irq() function as
part of the GPIO 9 interrupt service routine on a Cortex-M processor.
@code
void GPIO9_IRQHandler( void )
{
do_interrupt_processing();
GPIO_clear_irq( &g_gpio, GPIO_9 );
NVIC_ClearPendingIRQ( GPIO9_IRQn );
}
@endcode
*/
void GPIO_clear_irq
(
gpio_instance_t * this_gpio,
gpio_id_t port_id
);
#endif /* CORE_GPIO_H_ */

View File

@ -0,0 +1,40 @@
/*******************************************************************************
* (c) Copyright 2009-2015 Microsemi SoC Products Group. All rights reserved.
*
* SVN $Revision: 7964 $
* SVN $Date: 2015-10-09 18:26:53 +0530 (Fri, 09 Oct 2015) $
*/
#ifndef __CORE_GPIO_REGISTERS_H
#define __CORE_GPIO_REGISTERS_H 1
/*------------------------------------------------------------------------------
*
*/
#define IRQ_REG_OFFSET 0x80
#define IRQ0_REG_OFFSET 0x80
#define IRQ1_REG_OFFSET 0x84
#define IRQ2_REG_OFFSET 0x88
#define IRQ3_REG_OFFSET 0x8C
/*------------------------------------------------------------------------------
*
*/
#define GPIO_IN_REG_OFFSET 0x90
#define GPIO_IN0_REG_OFFSET 0x90
#define GPIO_IN1_REG_OFFSET 0x94
#define GPIO_IN2_REG_OFFSET 0x98
#define GPIO_IN3_REG_OFFSET 0x9C
/*------------------------------------------------------------------------------
*
*/
#define GPIO_OUT_REG_OFFSET 0xA0
#define GPIO_OUT0_REG_OFFSET 0xA0
#define GPIO_OUT1_REG_OFFSET 0xA4
#define GPIO_OUT2_REG_OFFSET 0xA8
#define GPIO_OUT3_REG_OFFSET 0xAC
#endif /* __CORE_GPIO_REGISTERS_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,190 @@
/*******************************************************************************
* (c) Copyright 2009-2015 Microsemi SoC Products Group. All rights reserved.
*
* SVN $Revision: 7984 $
* SVN $Date: 2015-10-12 12:07:40 +0530 (Mon, 12 Oct 2015) $
*/
#ifndef __CORE_SMBUS_REGISTERS
#define __CORE_SMBUS_REGISTERS 1
/*------------------------------------------------------------------------------
* CONTROL register details
*/
#define CONTROL_REG_OFFSET 0x00u
/*
* CR0 bits.
*/
#define CR0_OFFSET 0x00u
#define CR0_MASK 0x01u
#define CR0_SHIFT 0u
/*
* CR1 bits.
*/
#define CR1_OFFSET 0x00u
#define CR1_MASK 0x02u
#define CR1_SHIFT 1u
/*
* AA bits.
*/
#define AA_OFFSET 0x00u
#define AA_MASK 0x04u
#define AA_SHIFT 2u
/*
* SI bits.
*/
#define SI_OFFSET 0x00u
#define SI_MASK 0x08u
#define SI_SHIFT 3u
/*
* STO bits.
*/
#define STO_OFFSET 0x00u
#define STO_MASK 0x10u
#define STO_SHIFT 4u
/*
* STA bits.
*/
#define STA_OFFSET 0x00u
#define STA_MASK 0x20u
#define STA_SHIFT 5u
/*
* ENS1 bits.
*/
#define ENS1_OFFSET 0x00u
#define ENS1_MASK 0x40u
#define ENS1_SHIFT 6u
/*
* CR2 bits.
*/
#define CR2_OFFSET 0x00u
#define CR2_MASK 0x80u
#define CR2_SHIFT 7u
/*------------------------------------------------------------------------------
* STATUS register details
*/
#define STATUS_REG_OFFSET 0x04u
/*------------------------------------------------------------------------------
* DATA register details
*/
#define DATA_REG_OFFSET 0x08u
/*
* TARGET_ADDR bits.
*/
#define TARGET_ADDR_OFFSET 0x08u
#define TARGET_ADDR_MASK 0xFEu
#define TARGET_ADDR_SHIFT 1u
/*
* DIR bit.
*/
#define DIR_OFFSET 0x08u
#define DIR_MASK 0x01u
#define DIR_SHIFT 0u
/*------------------------------------------------------------------------------
* ADDRESS register details
*/
#define ADDRESS_REG_OFFSET 0x0Cu
/*
* GC bits.
*/
#define GC_OFFSET 0x0Cu
#define GC_MASK 0x01u
#define GC_SHIFT 0u
/*
* ADR bits.
*/
#define OWN_SLAVE_ADDR_OFFSET 0x0Cu
#define OWN_SLAVE_ADDR_MASK 0xFEu
#define OWN_SLAVE_ADDR_SHIFT 1u
/*------------------------------------------------------------------------------
* SMBUS register details
*/
#define SMBUS_REG_OFFSET 0x10u
/*
* SMBALERT_IE bits.
*/
#define SMBALERT_IE_OFFSET 0x10u
#define SMBALERT_IE_MASK 0x01u
#define SMBALERT_IE_SHIFT 0u
/*
* SMBSUS_IE bits.
*/
#define SMBSUS_IE_OFFSET 0x10u
#define SMBSUS_IE_MASK 0x02u
#define SMBSUS_IE_SHIFT 1u
/*
* SMB_IPMI_EN bits.
*/
#define SMB_IPMI_EN_OFFSET 0x10u
#define SMB_IPMI_EN_MASK 0x04u
#define SMB_IPMI_EN_SHIFT 2u
/*
* SMBALERT_NI_STATUS bits.
*/
#define SMBALERT_NI_STATUS_OFFSET 0x10u
#define SMBALERT_NI_STATUS_MASK 0x08u
#define SMBALERT_NI_STATUS_SHIFT 3u
/*
* SMBALERT_NO_CONTROL bits.
*/
#define SMBALERT_NO_CONTROL_OFFSET 0x10u
#define SMBALERT_NO_CONTROL_MASK 0x10u
#define SMBALERT_NO_CONTROL_SHIFT 4u
/*
* SMBSUS_NI_STATUS bits.
*/
#define SMBSUS_NI_STATUS_OFFSET 0x10u
#define SMBSUS_NI_STATUS_MASK 0x20u
#define SMBSUS_NI_STATUS_SHIFT 5u
/*
* SMBSUS_NO_CONTROL bits.
*/
#define SMBSUS_NO_CONTROL_OFFSET 0x10u
#define SMBSUS_NO_CONTROL_MASK 0x40u
#define SMBSUS_NO_CONTROL_SHIFT 6u
/*
* SMBUS_MST_RESET bits.
*/
#define SMBUS_MST_RESET_OFFSET 0x10u
#define SMBUS_MST_RESET_MASK 0x80u
#define SMBUS_MST_RESET_SHIFT 7u
/*------------------------------------------------------------------------------
* SLAVE ADDRESS 1 register details
*/
#define ADDRESS1_REG_OFFSET 0x1Cu
/*
* SLAVE1_EN bit of Slave Address 1 .
*/
#define SLAVE1_EN_OFFSET 0x1Cu
#define SLAVE1_EN_MASK 0x01u
#define SLAVE1_EN_SHIFT 0u
#endif /* __CORE_SMBUS_REGISTERS */

View File

@ -0,0 +1,35 @@
/*******************************************************************************
* (c) Copyright 2009-2015 Microsemi SoC Products Group. All rights reserved.
*
* CoreI2C driver interrupt control.
*
* SVN $Revision: 7984 $
* SVN $Date: 2015-10-12 12:07:40 +0530 (Mon, 12 Oct 2015) $
*/
#include "hal.h"
#include "hal_assert.h"
#include "core_i2c.h"
#include "riscv_hal.h"
#define I2C_IRQn External_29_IRQn
/*------------------------------------------------------------------------------
* This function must be modified to enable interrupts generated from the
* CoreI2C instance identified as parameter.
*/
void I2C_enable_irq( i2c_instance_t * this_i2c )
{
PLIC_EnableIRQ(I2C_IRQn);
// HAL_ASSERT(0)
}
/*------------------------------------------------------------------------------
* This function must be modified to disable interrupts generated from the
* CoreI2C instance identified as parameter.
*/
void I2C_disable_irq( i2c_instance_t * this_i2c )
{
PLIC_DisableIRQ(I2C_IRQn);
// HAL_ASSERT(0)
}

View File

@ -0,0 +1,158 @@
/*******************************************************************************
* (c) Copyright 2007-2015 Microsemi SoC Products Group. All rights reserved.
*
* CoreTimer driver implementation.
*
* SVN $Revision: 7967 $
* SVN $Date: 2015-10-09 18:48:26 +0530 (Fri, 09 Oct 2015) $
*/
#include "core_timer.h"
#include "coretimer_regs.h"
#include "hal.h"
#include "hal_assert.h"
#ifndef NDEBUG
static timer_instance_t* NULL_timer_instance;
#endif
/***************************************************************************//**
* TMR_init()
* See "core_timer.h" for details of how to use this function.
*/
void
TMR_init
(
timer_instance_t * this_timer,
addr_t address,
uint8_t mode,
uint32_t prescale,
uint32_t load_value
)
{
HAL_ASSERT( this_timer != NULL_timer_instance )
HAL_ASSERT( prescale <= PRESCALER_DIV_1024 )
HAL_ASSERT( load_value != 0 )
this_timer->base_address = address;
/* Disable interrupts. */
HAL_set_32bit_reg_field( address, InterruptEnable,0 );
/* Disable timer. */
HAL_set_32bit_reg_field( address, TimerEnable, 0 );
/* Clear pending interrupt. */
HAL_set_32bit_reg( address, TimerIntClr, 1 );
/* Configure prescaler and load value. */
HAL_set_32bit_reg( address, TimerPrescale, prescale );
HAL_set_32bit_reg( address, TimerLoad, load_value );
/* Set the interrupt mode. */
if ( mode == TMR_CONTINUOUS_MODE )
{
HAL_set_32bit_reg_field( address, TimerMode, 0 );
}
else
{
/* TMR_ONE_SHOT_MODE */
HAL_set_32bit_reg_field( address, TimerMode, 1 );
}
}
/***************************************************************************//**
* TMR_start()
* See "core_timer.h" for details of how to use this function.
*/
void
TMR_start
(
timer_instance_t * this_timer
)
{
HAL_ASSERT( this_timer != NULL_timer_instance )
HAL_set_32bit_reg_field( this_timer->base_address, TimerEnable, 1 );
}
/***************************************************************************//**
* TMR_stop()
* See "core_timer.h" for details of how to use this function.
*/
void
TMR_stop
(
timer_instance_t * this_timer
)
{
HAL_ASSERT( this_timer != NULL_timer_instance )
HAL_set_32bit_reg_field( this_timer->base_address, TimerEnable, 0 );
}
/***************************************************************************//**
* TMR_enable_int()
* See "core_timer.h" for details of how to use this function.
*/
void
TMR_enable_int
(
timer_instance_t * this_timer
)
{
HAL_ASSERT( this_timer != NULL_timer_instance )
HAL_set_32bit_reg_field( this_timer->base_address, InterruptEnable, 1 );
}
/***************************************************************************//**
* TMR_clear_int()
* See "core_timer.h" for details of how to use this function.
*/
void
TMR_clear_int
(
timer_instance_t * this_timer
)
{
HAL_ASSERT( this_timer != NULL_timer_instance )
HAL_set_32bit_reg( this_timer->base_address, TimerIntClr, 0x01 );
}
/***************************************************************************//**
* TMR_current_value()
* See "core_timer.h" for details of how to use this function.
*/
uint32_t
TMR_current_value
(
timer_instance_t * this_timer
)
{
uint32_t value = 0;
HAL_ASSERT( this_timer != NULL_timer_instance )
value = HAL_get_32bit_reg( this_timer->base_address, TimerValue );
return value;
}
/***************************************************************************//**
* TMR_reload()
* See "core_timer.h" for details of how to use this function.
*/
void TMR_reload
(
timer_instance_t * this_timer,
uint32_t load_value
)
{
HAL_ASSERT( this_timer != NULL_timer_instance )
HAL_ASSERT( load_value != 0 )
HAL_set_32bit_reg(this_timer->base_address, TimerLoad, load_value );
}

View File

@ -0,0 +1,206 @@
/*******************************************************************************
* (c) Copyright 2007-2015 Microsemi SoC Products Group. All rights reserved.
*
* CoreTimer public API.
*
* SVN $Revision: 7967 $
* SVN $Date: 2015-10-09 18:48:26 +0530 (Fri, 09 Oct 2015) $
*/
#ifndef CORE_TIMER_H_
#define CORE_TIMER_H_
#include "cpu_types.h"
/***************************************************************************//**
* The following definitions are used to select the CoreTimer driver operating
* mode. They allow selecting continuous or one-shot mode.
* 1. Continuous Mode
* In continuous mode the timer's counter is decremented from the load value
* until it reaches zero. The timer counter is automatically reloaded, with the
* load value, upon reaching zero. An interrupt is generated every time the
* counter reaches zero if interrupt is enabled.
* This mode is typically used to generate an interrupt at constant time
* intervals.
* 2. One-shot mode:
* In one-shot mode, the counter decrements from the load value and until it
* reaches zero. An interrupt can be generated, if enabled, when the counter
* reaches zero. The timer's counter must be reloaded to begin counting down
* again.
*/
#define TMR_CONTINUOUS_MODE 0
#define TMR_ONE_SHOT_MODE 1
/***************************************************************************//**
* The following definitions are used to configure the CoreTimer prescaler.
* The prescaler is used to divide down the clock used to decrement the
* CoreTimer counter. It can be configure to divide the clock by 2, 4, 8,
* 16, 32, 64, 128, 256, 512, or 1024.
*/
#define PRESCALER_DIV_2 0
#define PRESCALER_DIV_4 1
#define PRESCALER_DIV_8 2
#define PRESCALER_DIV_16 3
#define PRESCALER_DIV_32 4
#define PRESCALER_DIV_64 5
#define PRESCALER_DIV_128 6
#define PRESCALER_DIV_256 7
#define PRESCALER_DIV_512 8
#define PRESCALER_DIV_1024 9
/***************************************************************************//**
* There should be one instance of this structure for each instance of CoreTimer
* in your system. The function TMR_init() initializes this structure. It is
* used to identify the various CoreTimer hardware instances in your system.
* An initialized timer instance structure should be passed as first parameter to
* CoreTimer driver functions to identify which CoreTimer instance should perform
* the requested operation.
* Software using this driver should only need to create one single instance of
* this data structure for each hardware timer instance in the system.
*/
typedef struct __timer_instance_t
{
addr_t base_address;
} timer_instance_t;
/***************************************************************************//**
* The function TMR_init() initializes the data structures and sets relevant
* CoreTimer registers. This function will prepare the Timer for use in a given
* hardware/software configuration. It should be called before any other Timer
* API functions.
* The timer will not start counting down immediately after this function is
* called. It is necessary to call TMR_start() to start the timer decrementing.
* The CoreTimer interrupt is disabled as part of this function.
*
* @param this_timer Pointer to a timer_instance_t structure holding all
* relevant data associated with the target timer hardware
* instance. This pointer will be used to identify the
* target CoreTimer hardware instance in subsequent calls
* to the CoreTimer functions.
* @param address Base address in the processor's memory map of the
* registers of the CoreTimer instance being initialized.
* @param mode This parameter is used to select the operating mode of
* the timer driver. This can be either TMR_CONTINUOUS_MODE
* or TMR_ONE_SHOT_MODE.
* @param prescale This parameter is used to select the prescaler divider
* used to divide down the clock used to decrement the
* timers counter. This can be set using one of the
* PRESCALER_DIV_<n> definitions, where <n> is the
* dividers value.
* @param load_value This parameter is used to set the timers load value
* from which the CoreTimer counter will decrement.
* In Continuous mode, this value will be used to reload
* the timers counter whenever it reaches zero.
*/
void
TMR_init
(
timer_instance_t * this_timer,
addr_t address,
uint8_t mode,
uint32_t prescale,
uint32_t load_value
);
/***************************************************************************//**
* The function TMR_start() enables the timer to start counting down.
* This function only needs to be called once after the timer has been
* initialized through a call to TMR_init(). It does not need to be called after
* each call to TMR_reload() when the timer is used in one-shot mode.
*
* @param this_timer Pointer to a timer_instance_t structure holding all
* relevant data associated with the target timer hardware
* instance. This pointer is used to identify the target
* CoreTimer hardware instance.
*/
void
TMR_start
(
timer_instance_t * this_timer
);
/***************************************************************************//**
* The function TMR_stop() stops the timer counting down. It can be used to
* stop interrupts from being generated when continuous mode is used and
* interrupts must be paused from being generated.
*
* @param this_timer Pointer to a timer_instance_t structure holding all
* relevant data associated with the target timer hardware
* instance. This pointer is used to identify the target
* CoreTimer hardware instance.
*/
void
TMR_stop
(
timer_instance_t * this_timer
);
/***************************************************************************//**
* The function TMR_enable_int() enables the timer interrupt. A call to this
* function will allow the interrupt signal coming out of CoreTimer to be
* asserted.
*
* @param this_timer Pointer to a timer_instance_t structure holding all
* relevant data associated with the target timer hardware
* instance. This pointer is used to identify the target
* CoreTimer hardware instance.
*/
void
TMR_enable_int
(
timer_instance_t * this_timer
);
/***************************************************************************//**
* The function TMR_clear_int() clears the timer interrupt. This function should
* be called within the interrupt handler servicing interrupts from the timer.
* Failure to clear the timer interrupt will result in the interrupt signal
* generating from CoreTimer to remain asserted. This assertion may cause the
* interrupt service routine to be continuously called, causing the system to
* lock up.
*
* @param this_timer Pointer to a timer_instance_t structure holding all
* relevant data associated with the target timer hardware
* instance. This pointer is used to identify the target
* CoreTimer hardware instance.
*/
void
TMR_clear_int
(
timer_instance_t * this_timer
);
/***************************************************************************//**
* The TMR_current_value() function returns the current value of the counter.
*
* @param this_timer Pointer to a timer_instance_t structure holding all
* relevant data associated with the target timer hardware
* instance. This pointer is used to identify the target
* CoreTimer hardware instance.
*
* @return Returns the current value of the timer counter value.
*/
uint32_t
TMR_current_value
(
timer_instance_t * this_timer
);
/***************************************************************************//**
* The TMR_reload() function is used in one-shot mode. It reloads the timer
* counter with the values passed as parameter. This will result in an interrupt
* being generated when the timer counter reaches 0 if interrupt is enabled.
*
* @param this_timer Pointer to a timer_instance_t structure holding all
* relevant data associated with the target timer hardware
* instance. This pointer is used to identify the target
* CoreTimer hardware instance.
* @param load_value This parameter sets the value from which the CoreTimer
* counter will decrement.
*/
void TMR_reload
(
timer_instance_t * this_timer,
uint32_t load_value
);
#endif /* CORE_TIMER_H_ */

View File

@ -0,0 +1,109 @@
/*******************************************************************************
* (c) Copyright 2007-2015 Microsemi SoC Products Group. All rights reserved.
*
* SVN $Revision: 7967 $
* SVN $Date: 2015-10-09 18:48:26 +0530 (Fri, 09 Oct 2015) $
*/
#ifndef __CORE_TIMER_REGISTERS
#define __CORE_TIMER_REGISTERS 1
/*------------------------------------------------------------------------------
* TimerLoad register details
*/
#define TimerLoad_REG_OFFSET 0x00
/*
* LoadValue bits.
*/
#define LoadValue_OFFSET 0x00
#define LoadValue_MASK 0xFFFFFFFF
#define LoadValue_SHIFT 0
/*------------------------------------------------------------------------------
* TimerValue register details
*/
#define TimerValue_REG_OFFSET 0x04
/*
* CurrentValue bits.
*/
#define CurrentValue_OFFSET 0x04
#define CurrentValue_MASK 0xFFFFFFFF
#define CurrentValue_SHIFT 0
/*------------------------------------------------------------------------------
* TimerControl register details
*/
#define TimerControl_REG_OFFSET 0x08
/*
* TimerEnable bits.
*/
#define TimerEnable_OFFSET 0x08
#define TimerEnable_MASK 0x00000001
#define TimerEnable_SHIFT 0
/*
* InterruptEnable bits.
*/
#define InterruptEnable_OFFSET 0x08
#define InterruptEnable_MASK 0x00000002
#define InterruptEnable_SHIFT 1
/*
* TimerMode bits.
*/
#define TimerMode_OFFSET 0x08
#define TimerMode_MASK 0x00000004
#define TimerMode_SHIFT 2
/*------------------------------------------------------------------------------
* TimerPrescale register details
*/
#define TimerPrescale_REG_OFFSET 0x0C
/*
* Prescale bits.
*/
#define Prescale_OFFSET 0x0C
#define Prescale_MASK 0x0000000F
#define Prescale_SHIFT 0
/*------------------------------------------------------------------------------
* TimerIntClr register details
*/
#define TimerIntClr_REG_OFFSET 0x10
/*
* TimerIntClr bits.
*/
#define TimerIntClr_OFFSET 0x10
#define TimerIntClr_MASK 0xFFFFFFFF
#define TimerIntClr_SHIFT 0
/*------------------------------------------------------------------------------
* TimerRIS register details
*/
#define TimerRIS_REG_OFFSET 0x14
/*
* RawTimerInterrupt bits.
*/
#define RawTimerInterrupt_OFFSET 0x14
#define RawTimerInterrupt_MASK 0x00000001
#define RawTimerInterrupt_SHIFT 0
/*------------------------------------------------------------------------------
* TimerMIS register details
*/
#define TimerMIS_REG_OFFSET 0x18
/*
* TimerInterrupt bits.
*/
#define TimerInterrupt_OFFSET 0x18
#define TimerInterrupt_MASK 0x00000001
#define TimerInterrupt_SHIFT 0
#endif /* __CORE_TIMER_REGISTERS */

View File

@ -0,0 +1,296 @@
/*******************************************************************************
* (c) Copyright 2007-2017 Microsemi SoC Products Group. All rights reserved.
*
* CoreUARTapb driver implementation. See file "core_uart_apb.h" for a
* description of the functions implemented in this file.
*
* SVN $Revision: 9082 $
* SVN $Date: 2017-04-28 11:51:36 +0530 (Fri, 28 Apr 2017) $
*/
#include "hal.h"
#include "coreuartapb_regs.h"
#include "core_uart_apb.h"
#include "hal_assert.h"
#ifdef __cplusplus
extern "C" {
#endif
#define NULL_INSTANCE ( ( UART_instance_t* ) 0 )
#define NULL_BUFFER ( ( uint8_t* ) 0 )
#define MAX_LINE_CONFIG ( ( uint8_t )( DATA_8_BITS | ODD_PARITY ) )
#define MAX_BAUD_VALUE ( ( uint16_t )( 0x1FFF ) )
#define STATUS_ERROR_MASK ( ( uint8_t )( STATUS_PARITYERR_MASK | \
STATUS_OVERFLOW_MASK | \
STATUS_FRAMERR_MASK ) )
#define BAUDVALUE_LSB ( (uint16_t) (0x00FF) )
#define BAUDVALUE_MSB ( (uint16_t) (0xFF00) )
#define BAUDVALUE_SHIFT ( (uint8_t) (5) )
#define STATUS_ERROR_OFFSET STATUS_PARITYERR_SHIFT
/***************************************************************************//**
* UART_init()
* See "core_uart_apb.h" for details of how to use this function.
*/
void
UART_init
(
UART_instance_t * this_uart,
addr_t base_addr,
uint16_t baud_value,
uint8_t line_config
)
{
uint8_t rx_full;
HAL_ASSERT( this_uart != NULL_INSTANCE )
HAL_ASSERT( line_config <= MAX_LINE_CONFIG )
HAL_ASSERT( baud_value <= MAX_BAUD_VALUE )
if( ( this_uart != NULL_INSTANCE ) &&
( line_config <= MAX_LINE_CONFIG ) &&
( baud_value <= MAX_BAUD_VALUE ) )
{
/*
* Store lower 8-bits of baud value in CTRL1.
*/
HAL_set_8bit_reg( base_addr, CTRL1, (uint_fast8_t)(baud_value &
BAUDVALUE_LSB ) );
/*
* Extract higher 5-bits of baud value and store in higher 5-bits
* of CTRL2, along with line configuration in lower 3 three bits.
*/
HAL_set_8bit_reg( base_addr, CTRL2, (uint_fast8_t)line_config |
(uint_fast8_t)((baud_value &
BAUDVALUE_MSB) >> BAUDVALUE_SHIFT ) );
this_uart->base_address = base_addr;
#ifndef NDEBUG
{
uint8_t config;
uint8_t temp;
uint16_t baud_val;
baud_val = HAL_get_8bit_reg( this_uart->base_address, CTRL1 );
config = HAL_get_8bit_reg( this_uart->base_address, CTRL2 );
/*
* To resolve operator precedence between & and <<
*/
temp = ( config & (uint8_t)(CTRL2_BAUDVALUE_MASK ) );
baud_val |= (uint16_t)( (uint16_t)(temp) << BAUDVALUE_SHIFT );
config &= (uint8_t)(~CTRL2_BAUDVALUE_MASK);
HAL_ASSERT( baud_val == baud_value );
HAL_ASSERT( config == line_config );
}
#endif
/*
* Flush the receive FIFO of data that may have been received before the
* driver was initialized.
*/
rx_full = HAL_get_8bit_reg( this_uart->base_address, STATUS ) &
STATUS_RXFULL_MASK;
while ( rx_full )
{
HAL_get_8bit_reg( this_uart->base_address, RXDATA );
rx_full = HAL_get_8bit_reg( this_uart->base_address, STATUS ) &
STATUS_RXFULL_MASK;
}
/*
* Clear status of the UART instance.
*/
this_uart->status = (uint8_t)0;
}
}
/***************************************************************************//**
* UART_send()
* See "core_uart_apb.h" for details of how to use this function.
*/
void
UART_send
(
UART_instance_t * this_uart,
const uint8_t * tx_buffer,
size_t tx_size
)
{
size_t char_idx;
uint8_t tx_ready;
HAL_ASSERT( this_uart != NULL_INSTANCE )
HAL_ASSERT( tx_buffer != NULL_BUFFER )
HAL_ASSERT( tx_size > 0 )
if( (this_uart != NULL_INSTANCE) &&
(tx_buffer != NULL_BUFFER) &&
(tx_size > (size_t)0) )
{
for ( char_idx = (size_t)0; char_idx < tx_size; char_idx++ )
{
/* Wait for UART to become ready to transmit. */
do {
tx_ready = HAL_get_8bit_reg( this_uart->base_address, STATUS ) &
STATUS_TXRDY_MASK;
} while ( !tx_ready );
/* Send next character in the buffer. */
HAL_set_8bit_reg( this_uart->base_address, TXDATA,
(uint_fast8_t)tx_buffer[char_idx] );
}
}
}
/***************************************************************************//**
* UART_fill_tx_fifo()
* See "core_uart_apb.h" for details of how to use this function.
*/
size_t
UART_fill_tx_fifo
(
UART_instance_t * this_uart,
const uint8_t * tx_buffer,
size_t tx_size
)
{
uint8_t tx_ready;
size_t size_sent = 0u;
HAL_ASSERT( this_uart != NULL_INSTANCE )
HAL_ASSERT( tx_buffer != NULL_BUFFER )
HAL_ASSERT( tx_size > 0 )
/* Fill the UART's Tx FIFO until the FIFO is full or the complete input
* buffer has been written. */
if( (this_uart != NULL_INSTANCE) &&
(tx_buffer != NULL_BUFFER) &&
(tx_size > 0u) )
{
tx_ready = HAL_get_8bit_reg( this_uart->base_address, STATUS ) &
STATUS_TXRDY_MASK;
if ( tx_ready )
{
do {
HAL_set_8bit_reg( this_uart->base_address, TXDATA,
(uint_fast8_t)tx_buffer[size_sent] );
size_sent++;
tx_ready = HAL_get_8bit_reg( this_uart->base_address, STATUS ) &
STATUS_TXRDY_MASK;
} while ( (tx_ready) && ( size_sent < tx_size ) );
}
}
return size_sent;
}
/***************************************************************************//**
* UART_get_rx()
* See "core_uart_apb.h" for details of how to use this function.
*/
size_t
UART_get_rx
(
UART_instance_t * this_uart,
uint8_t * rx_buffer,
size_t buff_size
)
{
uint8_t new_status;
uint8_t rx_full;
size_t rx_idx = 0u;
HAL_ASSERT( this_uart != NULL_INSTANCE )
HAL_ASSERT( rx_buffer != NULL_BUFFER )
HAL_ASSERT( buff_size > 0 )
if( (this_uart != NULL_INSTANCE) &&
(rx_buffer != NULL_BUFFER) &&
(buff_size > 0u) )
{
rx_idx = 0u;
new_status = HAL_get_8bit_reg( this_uart->base_address, STATUS );
this_uart->status |= new_status;
rx_full = new_status & STATUS_RXFULL_MASK;
while ( ( rx_full ) && ( rx_idx < buff_size ) )
{
rx_buffer[rx_idx] = HAL_get_8bit_reg( this_uart->base_address,
RXDATA );
rx_idx++;
new_status = HAL_get_8bit_reg( this_uart->base_address, STATUS );
this_uart->status |= new_status;
rx_full = new_status & STATUS_RXFULL_MASK;
}
}
return rx_idx;
}
/***************************************************************************//**
* UART_polled_tx_string()
* See "core_uart_apb.h" for details of how to use this function.
*/
void
UART_polled_tx_string
(
UART_instance_t * this_uart,
const uint8_t * p_sz_string
)
{
uint32_t char_idx;
uint8_t tx_ready;
HAL_ASSERT( this_uart != NULL_INSTANCE )
HAL_ASSERT( p_sz_string != NULL_BUFFER )
if( ( this_uart != NULL_INSTANCE ) && ( p_sz_string != NULL_BUFFER ) )
{
char_idx = 0U;
while( 0U != p_sz_string[char_idx] )
{
/* Wait for UART to become ready to transmit. */
do {
tx_ready = HAL_get_8bit_reg( this_uart->base_address, STATUS ) &
STATUS_TXRDY_MASK;
} while ( !tx_ready );
/* Send next character in the buffer. */
HAL_set_8bit_reg( this_uart->base_address, TXDATA,
(uint_fast8_t)p_sz_string[char_idx] );
char_idx++;
}
}
}
/***************************************************************************//**
* UART_get_rx_status()
* See "core_uart_apb.h" for details of how to use this function.
*/
uint8_t
UART_get_rx_status
(
UART_instance_t * this_uart
)
{
uint8_t status = UART_APB_INVALID_PARAM;
HAL_ASSERT( this_uart != NULL_INSTANCE )
/*
* Extract UART error status and place in lower bits of "status".
* Bit 0 - Parity error status
* Bit 1 - Overflow error status
* Bit 2 - Frame error status
*/
if( this_uart != NULL_INSTANCE )
{
status = ( ( this_uart->status & STATUS_ERROR_MASK ) >>
STATUS_ERROR_OFFSET );
/*
* Clear the sticky status for this instance.
*/
this_uart->status = (uint8_t)0;
}
return status;
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,407 @@
/*******************************************************************************
* (c) Copyright 2007-2017 Microsemi SoC Products Group. All rights reserved.
*
* This file contains the application programming interface for the CoreUARTapb
* bare metal driver.
*
* SVN $Revision: 9082 $
* SVN $Date: 2017-04-28 11:51:36 +0530 (Fri, 28 Apr 2017) $
*/
/*=========================================================================*//**
@mainpage CoreUARTapb Bare Metal Driver.
@section intro_sec Introduction
CoreUARTapb is an implementation of the Universal Asynchronous
Receiver/Transmitter aimed at a minimal FPGA tile usage within an Microsemi
FPGA. The CoreUARTapb bare metal software driver is designed for use in
systems with no operating system.
The CoreUARTapb driver provides functions for basic polled transmitting and
receiving operations. It also provides functions allowing use of the
CoreUARTapb in interrupt-driven mode, but leaves the management of interrupts
to the calling application, as interrupt enabling and disabling cannot be
controlled through the CoreUARTapb registers. The CoreUARTapb driver is
provided as C source code.
@section driver_configuration Driver Configuration
Your application software should configure the CoreUARTapb driver, through
calls to the UART_init() function for each CoreUARTapb instance in the
hardware design. The configuration parameters include the CoreUARTapb
hardware instance base address and other runtime parameters, such as baud
rate, bit width, and parity. No CoreUARTapb hardware configuration parameters
are needed by the driver, apart from the CoreUARTapb hardware instance base
address. Hence, no additional configuration files are required to use the driver.
A CoreUARTapb hardware instance can be generated with fixed baud value,
character size and parity configuration settings as part of the hardware flow.
The baud_value and line_config parameter values passed to the UART_init()
function will not have any effect if fixed values were selected for the
baud value, character size and parity in the hardware configuration of
CoreUARTapb. When fixed values are selected for these hardware configuration
parameters, the driver cannot overwrite the fixed values in the CoreUARTapb
control registers, CTRL1 and CTRL2.
@section theory_op Theory of Operation
The CoreUARTapb software driver is designed to allow the control of multiple
instances of CoreUARTapb. Each instance of CoreUARTapb in the hardware design
is associated with a single instance of the UART_instance_t structure in the
software. You need to allocate memory for one unique UART_instance_t
structure instance for each CoreUARTapb hardware instance. The contents of
these data structures are initialized during calls to function UART_init().
A pointer to the structure is passed to subsequent driver functions in order
to identify the CoreUARTapb hardware instance you wish to perform the
requested operation on.
Note: Do not attempt to directly manipulate the content of UART_instance_t
structures. This structure is only intended to be modified by the driver
function.
The driver can be used to transmit and receive data once initialized.
Transmit can be performed using the UART_send() function. This function
is blocking, meaning that it will only return once the data passed to
the function has been sent to the CoreUARTapb hardware. Data received
by the CoreUARTapb hardware can be read by the user application using
the UART_get_rx() function.
The function UART_fill_tx_fifo() is also provided to be used as part of
interrupt-driven transmit. This function fills the CoreUARTapb hardware
transmit FIFO with the content of a data buffer passed as a parameter before
returning. The control of the interrupts must be implemented outside the
driver as the CoreUARTapb hardware does not provide the ability to enable
or disable its interrupt sources.
The function UART_polled_tx_string() is provided to transmit a NULL
terminated string in polled mode. This function is blocking, meaning that it
will only return once the data passed to the function has been sent to the
CoreUARTapb hardware.
The function UART_get_rx_status() returns the error status of the CoreUARTapb
receiver. This can be used by applications to take appropriate action in case
of receiver errors.
*//*=========================================================================*/
#ifndef __CORE_UART_APB_H
#define __CORE_UART_APB_H 1
#include "cpu_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* Data bits length defines:
*/
#define DATA_7_BITS 0x00u
#define DATA_8_BITS 0x01u
/***************************************************************************//**
* Parity defines:
*/
#define NO_PARITY 0x00u
#define EVEN_PARITY 0x02u
#define ODD_PARITY 0x06u
/***************************************************************************//**
* Error Status definitions:
*/
#define UART_APB_PARITY_ERROR 0x01u
#define UART_APB_OVERFLOW_ERROR 0x02u
#define UART_APB_FRAMING_ERROR 0x04u
#define UART_APB_NO_ERROR 0x00u
#define UART_APB_INVALID_PARAM 0xFFu
/***************************************************************************//**
* UART_instance_t
*
* There should be one instance of this structure for each instance of CoreUARTapb
* in your system. This structure instance is used to identify the various UARTs
* in a system and should be passed as first parameter to UART functions to
* identify which UART should perform the requested operation. The 'status'
* element in the structure is used to provide sticky status information.
*/
typedef struct
{
addr_t base_address;
uint8_t status;
} UART_instance_t;
/***************************************************************************//**
* The function UART_init() initializes the UART with the configuration passed
* as parameters. The configuration parameters are the baud_value used to
* generate the baud rate and the line configuration (bit length and parity).
*
* @param this_uart The this_uart parameter is a pointer to a UART_instance_t
* structure which holds all data regarding this instance of
* the CoreUARTapb. This pointer will be used to identify
* the target CoreUARTapb hardware instance in subsequent
* calls to the CoreUARTapb functions.
* @param base_addr The base_address parameter is the base address in the
* processor's memory map for the registers of the
* CoreUARTapb instance being initialized.
* @param baud_value The baud_value parameter is used to select the baud rate
* for the UART. The baud value is calculated from the
* frequency of the system clock in hertz and the desired
* baud rate using the following equation:
*
* baud_value = (clock /(baud_rate * 16)) - 1.
*
* The baud_value parameter must be a value in the range 0
* to 8191 (or 0x0000 to 0x1FFF).
* @param line_config This parameter is the line configuration specifying the
* bit length and parity settings. This is a logical OR of:
* - DATA_7_BITS
* - DATA_8_BITS
* - NO_PARITY
* - EVEN_PARITY
* - ODD_PARITY
* For example, 8 bits even parity would be specified as
* (DATA_8_BITS | EVEN_PARITY).
* @return This function does not return a value.
* Example:
* @code
* #define BAUD_VALUE_57600 25
*
* #define COREUARTAPB0_BASE_ADDR 0xC3000000UL
*
* UART_instance_t g_uart;
* int main()
* {
* UART_init(&g_uart, COREUARTAPB0_BASE_ADDR,
BAUD_VALUE_57600, (DATA_8_BITS | EVEN_PARITY));
* }
* @endcode
*/
void
UART_init
(
UART_instance_t * this_uart,
addr_t base_addr,
uint16_t baud_value,
uint8_t line_config
);
/***************************************************************************//**
* The function UART_send() is used to transmit data. It transfers the contents
* of the transmitter data buffer, passed as a function parameter, into the
* UART's hardware transmitter FIFO. It returns when the full content of the
* transmitter data buffer has been transferred to the UART's transmitter FIFO.
*
* Note: you cannot assume that the data you are sending using this function has
* been received at the other end by the time this function returns. The actual
* transmit over the serial connection will still be taking place at the time of
* the function return. It is safe to release or reuse the memory used as the
* transmit buffer once this function returns.
*
* @param this_uart The this_uart parameter is a pointer to a
* UART_instance_t structure which holds all data regarding
* this instance of the CoreUARTapbUART.
* @param tx_buffer The tx_buffer parameter is a pointer to a buffer
* containing the data to be transmitted.
* @param tx_size The tx_size parameter is the size, in bytes, of
* the data to be transmitted.
*
* @return This function does not return a value.
*
* Example:
* @code
* uint8_t testmsg1[] = {"\n\r\n\r\n\rUART_send() test message 1"};
* UART_send(&g_uart,(const uint8_t *)&testmsg1,sizeof(testmsg1));
* @endcode
*/
void
UART_send
(
UART_instance_t * this_uart,
const uint8_t * tx_buffer,
size_t tx_size
);
/***************************************************************************//**
* The function UART_fill_tx_fifo() fills the UART's transmitter hardware FIFO
* with the data found in the transmitter buffer that is passed in as a
* function parameter. The function returns either when the FIFO is full or
* when the complete contents of the transmitter buffer have been copied into
* the FIFO. It returns the number of bytes copied into the UART's transmitter
* hardware FIFO. This function is intended to be used as part of
* interrupt-driven transmission.
*
* Note: You cannot assume that the data you transmit using this function has
* been received at the other end by the time this function returns.
* The actual transmission over the serial connection will still be
* taking place at the time of the function return.
*
* @param this_uart The this_uart parameter is a pointer to a UART_instance_t
* structure which holds all data regarding this instance of
* the UART.
* @param tx_buffer The tx_buffer parameter is a pointer to a buffer
* containing the data to be transmitted.
* @param tx_size The tx_size parameter is the size in bytes, of the data
* to be transmitted.
* @return This function returns the number of bytes copied
* into the UART's transmitter hardware FIFO.
*
* Example:
* @code
* void send_using_interrupt
* (
* uint8_t * pbuff,
* size_t tx_size
* )
* {
* size_t size_in_fifo;
* size_in_fifo = UART_fill_tx_fifo( &g_uart, pbuff, tx_size );
* }
* @endcode
*/
size_t
UART_fill_tx_fifo
(
UART_instance_t * this_uart,
const uint8_t * tx_buffer,
size_t tx_size
);
/***************************************************************************//**
* The function UART_get_rx() reads the content of the UART's receiver hardware
* FIFO and stores it in the receiver buffer that is passed in as a function
* parameter. It copies either the full contents of the FIFO into the receiver
* buffer, or just enough data from the FIFO to fill the receiver buffer,
* dependent upon the size of the receiver buffer. The size of the receiver
* buffer is passed in as a function parameter. UART_get_rx() returns the number
* of bytes copied into the receiver buffer. If no data was received at the time
* the function is called, the function returns 0.
*
* Note: This function reads and accumulates the receiver status of the
* CoreUARTapb instance before reading each byte from the receiver's
* data register/FIFO. This allows the driver to maintain a sticky
* record of any receiver errors that occur as the UART receives each
* data byte; receiver errors would otherwise be lost after each read
* from the receiver's data register. A call to the UART_get_rx_status()
* function returns any receiver errors accumulated during the execution
* of the UART_get_rx() function.
* Note: When FIFO mode is disabled in the CoreUARTapb hardware configuration,
* the driver accumulates a sticky record of any parity errors, framing
* errors or overflow errors. When FIFO mode is enabled, the driver
* accumulates a sticky record of overflow errors only; in this case
* interrupts must be used to handle parity errors or framing errors.
*
* @param this_uart The this_uart parameter is a pointer to a UART_instance_t
* structure which holds all data regarding this instance of
* the UART.
* @param rx_buffer The rx_buffer parameter is a pointer to a buffer where the
* received data will be copied.
* @param buff_size The buff_size parameter is the size of the receive buffer
* in bytes.
* @return This function returns the number of bytes copied into the
* receive buffer.
*
* Example:
* @code
* #define MAX_RX_DATA_SIZE 256
*
* uint8_t rx_data[MAX_RX_DATA_SIZE];
* uint8_t rx_size = 0;
*
* rx_size = UART_get_rx( &g_uart, rx_data, sizeof(rx_data) );
* @endcode
*/
size_t
UART_get_rx
(
UART_instance_t * this_uart,
uint8_t * rx_buffer,
size_t buff_size
);
/***************************************************************************//**
* The function UART_polled_tx_string() is used to transmit a NULL ('\0')
* terminated string. Internally, it polls for the transmit ready status and
* transfers the text starting at the address pointed to by p_sz_string into
* the UART's hardware transmitter FIFO. It is a blocking function and returns
* only when the complete string has been transferred to the UART's transmit
* FIFO.
*
* Note: You cannot assume that the data you transmit using this function
* has been received at the other end by the time this function
* returns. The actual transmission over the serial connection will
* still be taking place at the time of the function return.
*
* @param this_uart The this_uart parameter is a pointer to a
* UART_instance_t structure which holds
* all data regarding this instance of the UART.
* @param p_sz_string The p_sz_string parameter is a pointer to a buffer
* containing the NULL ('\0') terminated string to be
* transmitted.
* @return This function does not return a value.
*
* Example:
* @code
* uint8_t testmsg1[] = {"\r\n\r\nUART_polled_tx_string() test message 1\0"};
* UART_polled_tx_string(&g_uart,(const uint8_t *)&testmsg1);
* @endcode
*/
void
UART_polled_tx_string
(
UART_instance_t * this_uart,
const uint8_t * p_sz_string
);
/***************************************************************************//**
* The UART_get_rx_status() function returns the receiver error status of the
* CoreUARTapb instance. It reads both the current error status of the receiver
* and the accumulated error status from preceding calls to the UART_get_rx()
* function and combines them using a bitwise OR. It returns the cumulative
* parity, framing and overflow error status of the receiver, since the
* previous call to UART_get_rx_status(), as an 8-bit encoded value.
*
* Note: The UART_get_rx() function reads and accumulates the receiver status
* of the CoreUARTapb instance before reading each byte from the
* receiver's data register/FIFO. The driver maintains a sticky record
* of the cumulative error status, which persists after the
* UART_get_rx() function returns. The UART_get_rx_status() function
* clears this accumulated record of receiver errors before returning.
*
* @param this_uart The this_uart parameter is a pointer to a UART_instance_t
* structure which holds all data regarding this instance
* of the UART.
* @return This function returns the UART receiver error status as
* an 8-bit encoded value. The returned value is 0 if no
* receiver errors occurred. The driver provides a set of
* bit mask constants which should be compared with and/or
* used to mask the returned value to determine the
* receiver error status.
* When the return value is compared to the following bit
* masks, a non-zero result indicates that the
* corresponding error occurred:
* UART_APB_PARITY_ERROR (bit mask = 0x01)
* UART_APB_OVERFLOW_ERROR (bit mask = 0x02)
* UART_APB_FRAMING_ERROR (bit mask = 0x04)
* When the return value is compared to the following bit
* mask, a non-zero result indicates that no error occurred:
* UART_APB_NO_ERROR (0x00)
*
* Example:
* @code
* UART_instance_t g_uart;
* uint8_t rx_data[MAX_RX_DATA_SIZE];
* uint8_t err_status;
* err_status = UART_get_err_status(&g_uart);
*
* if(UART_APB_NO_ERROR == err_status )
* {
* rx_size = UART_get_rx( &g_uart, rx_data, MAX_RX_DATA_SIZE );
* }
* @endcode
*/
uint8_t
UART_get_rx_status
(
UART_instance_t * this_uart
);
#ifdef __cplusplus
}
#endif
#endif /* __CORE_UART_APB_H */

View File

@ -0,0 +1,130 @@
/*******************************************************************************
* (c) Copyright 2007-2017 Microsemi SoC Products Group. All rights reserved.
*
* SVN $Revision: 9082 $
* SVN $Date: 2017-04-28 11:51:36 +0530 (Fri, 28 Apr 2017) $
*/
#ifndef __CORE_UART_APB_REGISTERS
#define __CORE_UART_APB_REGISTERS 1
#ifdef __cplusplus
extern "C" {
#endif
/*------------------------------------------------------------------------------
* TxData register details
*/
#define TXDATA_REG_OFFSET 0x0u
/*
* TxData bits.
*/
#define TXDATA_OFFSET 0x0u
#define TXDATA_MASK 0xFFu
#define TXDATA_SHIFT 0u
/*------------------------------------------------------------------------------
* RxData register details
*/
#define RXDATA_REG_OFFSET 0x4u
/*
* RxData bits.
*/
#define RXDATA_OFFSET 0x4u
#define RXDATA_MASK 0xFFu
#define RXDATA_SHIFT 0u
/*------------------------------------------------------------------------------
* ControReg1 register details
*/
#define CTRL1_REG_OFFSET 0x8u
/*
* Baud value (Lower 8-bits)
*/
#define CTRL1_BAUDVALUE_OFFSET 0x8u
#define CTRL1_BAUDVALUE_MASK 0xFFu
#define CTRL1_BAUDVALUE_SHIFT 0u
/*------------------------------------------------------------------------------
* ControReg2 register details
*/
#define CTRL2_REG_OFFSET 0xCu
/*
* Bit length
*/
#define CTRL2_BIT_LENGTH_OFFSET 0xCu
#define CTRL2_BIT_LENGTH_MASK 0x01u
#define CTRL2_BIT_LENGTH_SHIFT 0u
/*
* Parity enable.
*/
#define CTRL2_PARITY_EN_OFFSET 0xCu
#define CTRL2_PARITY_EN_MASK 0x02u
#define CTRL2_PARITY_EN_SHIFT 1u
/*
* Odd/even parity selection.
*/
#define CTRL2_ODD_EVEN_OFFSET 0xCu
#define CTRL2_ODD_EVEN_MASK 0x04u
#define CTRL2_ODD_EVEN_SHIFT 2u
/*
* Baud value (Higher 5-bits)
*/
#define CTRL2_BAUDVALUE_OFFSET 0xCu
#define CTRL2_BAUDVALUE_MASK 0xF8u
#define CTRL2_BAUDVALUE_SHIFT 3u
/*------------------------------------------------------------------------------
* StatusReg register details
*/
#define StatusReg_REG_OFFSET 0x10u
#define STATUS_REG_OFFSET 0x10u
/*
* Transmit ready.
*/
#define STATUS_TXRDY_OFFSET 0x10u
#define STATUS_TXRDY_MASK 0x01u
#define STATUS_TXRDY_SHIFT 0u
/*
* Receive full.
*/
#define STATUS_RXFULL_OFFSET 0x10u
#define STATUS_RXFULL_MASK 0x02u
#define STATUS_RXFULL_SHIFT 1u
/*
* Parity error.
*/
#define STATUS_PARITYERR_OFFSET 0x10u
#define STATUS_PARITYERR_MASK 0x04u
#define STATUS_PARITYERR_SHIFT 2u
/*
* Overflow.
*/
#define STATUS_OVERFLOW_OFFSET 0x10u
#define STATUS_OVERFLOW_MASK 0x08u
#define STATUS_OVERFLOW_SHIFT 3u
/*
* Frame Error.
*/
#define STATUS_FRAMERR_OFFSET 0x10u
#define STATUS_FRAMERR_MASK 0x10u
#define STATUS_FRAMERR_SHIFT 4u
#ifdef __cplusplus
}
#endif
#endif /* __CORE_UART_APB_REGISTERS */

View File

@ -0,0 +1,31 @@
/*******************************************************************************
* (c) Copyright 2007-2018 Microsemi SoC Products Group. All rights reserved.
*
* SVN $Revision: 9661 $
* SVN $Date: 2018-01-15 16:13:33 +0530 (Mon, 15 Jan 2018) $
*/
#ifndef __CPU_TYPES_H
#define __CPU_TYPES_H 1
#include <stdint.h>
/*------------------------------------------------------------------------------
*/
typedef unsigned int size_t;
/*------------------------------------------------------------------------------
* addr_t: address type.
* Used to specify the address of peripherals present in the processor's memory
* map.
*/
typedef unsigned int addr_t;
/*------------------------------------------------------------------------------
* psr_t: processor state register.
* Used by HAL_disable_interrupts() and HAL_restore_interrupts() to store the
* processor's state between disabling and restoring interrupts.
*/
typedef unsigned int psr_t;
#endif /* __CPU_TYPES_H */

View File

@ -0,0 +1,207 @@
/***************************************************************************//**
* (c) Copyright 2007-2018 Microsemi SoC Products Group. All rights reserved.
*
* Hardware abstraction layer functions.
*
* SVN $Revision: 9661 $
* SVN $Date: 2018-01-15 16:13:33 +0530 (Mon, 15 Jan 2018) $
*/
#ifndef HAL_H_
#define HAL_H_
#include "cpu_types.h"
#include "hw_reg_access.h"
/***************************************************************************//**
* Enable all interrupts at the processor level.
*/
void HAL_enable_interrupts( void );
/***************************************************************************//**
* Disable all interrupts at the processor core level.
* Return the interrupts enable state before disabling occured so that it can
* later be restored.
*/
psr_t HAL_disable_interrupts( void );
/***************************************************************************//**
* Restore the interrupts enable state at the processor core level.
* This function is normally passed the value returned from a previous call to
* HAL_disable_interrupts().
*/
void HAL_restore_interrupts( psr_t saved_psr );
/***************************************************************************//**
*/
#define FIELD_OFFSET(FIELD_NAME) (FIELD_NAME##_OFFSET)
#define FIELD_SHIFT(FIELD_NAME) (FIELD_NAME##_SHIFT)
#define FIELD_MASK(FIELD_NAME) (FIELD_NAME##_MASK)
/***************************************************************************//**
* The macro HAL_set_32bit_reg() allows writing a 32 bits wide register.
*
* BASE_ADDR: A variable of type addr_t specifying the base address of the
* peripheral containing the register.
* REG_NAME: A string identifying the register to write. These strings are
* specified in a header file associated with the peripheral.
* VALUE: A variable of type uint32_t containing the value to write.
*/
#define HAL_set_32bit_reg(BASE_ADDR, REG_NAME, VALUE) \
(HW_set_32bit_reg( ((BASE_ADDR) + (REG_NAME##_REG_OFFSET)), (VALUE) ))
/***************************************************************************//**
* The macro HAL_get_32bit_reg() is used to read the value of a 32 bits wide
* register.
*
* BASE_ADDR: A variable of type addr_t specifying the base address of the
* peripheral containing the register.
* REG_NAME: A string identifying the register to read. These strings are
* specified in a header file associated with the peripheral.
* RETURN: This function-like macro returns a uint32_t value.
*/
#define HAL_get_32bit_reg(BASE_ADDR, REG_NAME) \
(HW_get_32bit_reg( ((BASE_ADDR) + (REG_NAME##_REG_OFFSET)) ))
/***************************************************************************//**
* The macro HAL_set_32bit_reg_field() is used to write a field within a
* 32 bits wide register. The field written can be one or more bits.
*
* BASE_ADDR: A variable of type addr_t specifying the base address of the
* peripheral containing the register.
* FIELD_NAME: A string identifying the register field to write. These strings
* are specified in a header file associated with the peripheral.
* VALUE: A variable of type uint32_t containing the field value to write.
*/
#define HAL_set_32bit_reg_field(BASE_ADDR, FIELD_NAME, VALUE) \
(HW_set_32bit_reg_field(\
(BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\
FIELD_SHIFT(FIELD_NAME),\
FIELD_MASK(FIELD_NAME),\
(VALUE)))
/***************************************************************************//**
* The macro HAL_get_32bit_reg_field() is used to read a register field from
* within a 32 bit wide peripheral register. The field can be one or more bits.
*
* BASE_ADDR: A variable of type addr_t specifying the base address of the
* peripheral containing the register.
* FIELD_NAME: A string identifying the register field to write. These strings
* are specified in a header file associated with the peripheral.
* RETURN: This function-like macro returns a uint32_t value.
*/
#define HAL_get_32bit_reg_field(BASE_ADDR, FIELD_NAME) \
(HW_get_32bit_reg_field(\
(BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\
FIELD_SHIFT(FIELD_NAME),\
FIELD_MASK(FIELD_NAME)))
/***************************************************************************//**
* The macro HAL_set_16bit_reg() allows writing a 16 bits wide register.
*
* BASE_ADDR: A variable of type addr_t specifying the base address of the
* peripheral containing the register.
* REG_NAME: A string identifying the register to write. These strings are
* specified in a header file associated with the peripheral.
* VALUE: A variable of type uint_fast16_t containing the value to write.
*/
#define HAL_set_16bit_reg(BASE_ADDR, REG_NAME, VALUE) \
(HW_set_16bit_reg( ((BASE_ADDR) + (REG_NAME##_REG_OFFSET)), (VALUE) ))
/***************************************************************************//**
* The macro HAL_get_16bit_reg() is used to read the value of a 16 bits wide
* register.
*
* BASE_ADDR: A variable of type addr_t specifying the base address of the
* peripheral containing the register.
* REG_NAME: A string identifying the register to read. These strings are
* specified in a header file associated with the peripheral.
* RETURN: This function-like macro returns a uint16_t value.
*/
#define HAL_get_16bit_reg(BASE_ADDR, REG_NAME) \
(HW_get_16bit_reg( (BASE_ADDR) + (REG_NAME##_REG_OFFSET) ))
/***************************************************************************//**
* The macro HAL_set_16bit_reg_field() is used to write a field within a
* 16 bits wide register. The field written can be one or more bits.
*
* BASE_ADDR: A variable of type addr_t specifying the base address of the
* peripheral containing the register.
* FIELD_NAME: A string identifying the register field to write. These strings
* are specified in a header file associated with the peripheral.
* VALUE: A variable of type uint16_t containing the field value to write.
*/
#define HAL_set_16bit_reg_field(BASE_ADDR, FIELD_NAME, VALUE) \
(HW_set_16bit_reg_field(\
(BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\
FIELD_SHIFT(FIELD_NAME),\
FIELD_MASK(FIELD_NAME),\
(VALUE)))
/***************************************************************************//**
* The macro HAL_get_16bit_reg_field() is used to read a register field from
* within a 8 bit wide peripheral register. The field can be one or more bits.
*
* BASE_ADDR: A variable of type addr_t specifying the base address of the
* peripheral containing the register.
* FIELD_NAME: A string identifying the register field to write. These strings
* are specified in a header file associated with the peripheral.
* RETURN: This function-like macro returns a uint16_t value.
*/
#define HAL_get_16bit_reg_field(BASE_ADDR, FIELD_NAME) \
(HW_get_16bit_reg_field(\
(BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\
FIELD_SHIFT(FIELD_NAME),\
FIELD_MASK(FIELD_NAME)))
/***************************************************************************//**
* The macro HAL_set_8bit_reg() allows writing a 8 bits wide register.
*
* BASE_ADDR: A variable of type addr_t specifying the base address of the
* peripheral containing the register.
* REG_NAME: A string identifying the register to write. These strings are
* specified in a header file associated with the peripheral.
* VALUE: A variable of type uint_fast8_t containing the value to write.
*/
#define HAL_set_8bit_reg(BASE_ADDR, REG_NAME, VALUE) \
(HW_set_8bit_reg( ((BASE_ADDR) + (REG_NAME##_REG_OFFSET)), (VALUE) ))
/***************************************************************************//**
* The macro HAL_get_8bit_reg() is used to read the value of a 8 bits wide
* register.
*
* BASE_ADDR: A variable of type addr_t specifying the base address of the
* peripheral containing the register.
* REG_NAME: A string identifying the register to read. These strings are
* specified in a header file associated with the peripheral.
* RETURN: This function-like macro returns a uint8_t value.
*/
#define HAL_get_8bit_reg(BASE_ADDR, REG_NAME) \
(HW_get_8bit_reg( (BASE_ADDR) + (REG_NAME##_REG_OFFSET) ))
/***************************************************************************//**
*/
#define HAL_set_8bit_reg_field(BASE_ADDR, FIELD_NAME, VALUE) \
(HW_set_8bit_reg_field(\
(BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\
FIELD_SHIFT(FIELD_NAME),\
FIELD_MASK(FIELD_NAME),\
(VALUE)))
/***************************************************************************//**
* The macro HAL_get_8bit_reg_field() is used to read a register field from
* within a 8 bit wide peripheral register. The field can be one or more bits.
*
* BASE_ADDR: A variable of type addr_t specifying the base address of the
* peripheral containing the register.
* FIELD_NAME: A string identifying the register field to write. These strings
* are specified in a header file associated with the peripheral.
* RETURN: This function-like macro returns a uint8_t value.
*/
#define HAL_get_8bit_reg_field(BASE_ADDR, FIELD_NAME) \
(HW_get_8bit_reg_field(\
(BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\
FIELD_SHIFT(FIELD_NAME),\
FIELD_MASK(FIELD_NAME)))
#endif /*HAL_H_*/

View File

@ -0,0 +1,29 @@
/*******************************************************************************
* (c) Copyright 2008-2018 Microsemi SoC Products Group. All rights reserved.
*
* SVN $Revision: 9661 $
* SVN $Date: 2018-01-15 16:13:33 +0530 (Mon, 15 Jan 2018) $
*/
#ifndef HAL_ASSERT_HEADER
#define HAL_ASSERT_HEADER
#define NDEBUG 1
#if defined(NDEBUG)
/***************************************************************************//**
* HAL_ASSERT() is defined out when the NDEBUG symbol is used.
******************************************************************************/
#define HAL_ASSERT(CHECK)
#else
/***************************************************************************//**
* Default behaviour for HAL_ASSERT() macro:
*------------------------------------------------------------------------------
The behaviour is toolchain specific and project setting specific.
******************************************************************************/
#define HAL_ASSERT(CHECK) ASSERT(CHECK);
#endif /* NDEBUG */
#endif /* HAL_ASSERT_HEADER */

View File

@ -0,0 +1,36 @@
/***************************************************************************//**
* (c) Copyright 2007-2018 Microsemi SoC Products Group. All rights reserved.
*
* Legacy interrupt control functions for the Microsemi driver library hardware
* abstraction layer.
*
* SVN $Revision: 9661 $
* SVN $Date: 2018-01-15 16:13:33 +0530 (Mon, 15 Jan 2018) $
*/
#include "hal.h"
#include "riscv_hal.h"
/*------------------------------------------------------------------------------
*
*/
void HAL_enable_interrupts(void) {
__enable_irq();
}
/*------------------------------------------------------------------------------
*
*/
psr_t HAL_disable_interrupts(void) {
psr_t psr;
psr = read_csr(mstatus);
__disable_irq();
return(psr);
}
/*------------------------------------------------------------------------------
*
*/
void HAL_restore_interrupts(psr_t saved_psr) {
write_csr(mstatus, saved_psr);
}

View File

@ -0,0 +1,97 @@
/*******************************************************************************
* (c) Copyright 2007-2018 Microsemi SoC Products Group. All rights reserved.
*
* Hardware registers access macros.
*
* THE MACROS DEFINED IN THIS FILE ARE DEPRECATED. DO NOT USED FOR NEW
* DEVELOPMENT.
*
* These macros are used to access peripheral's registers. They allow access to
* 8, 16 and 32 bit wide registers. All accesses to peripheral registers should
* be done through these macros in order to ease porting across different
* processors/bus architectures.
*
* Some of these macros also allow to access a specific register field.
*
* SVN $Revision: 9661 $
* SVN $Date: 2018-01-15 16:13:33 +0530 (Mon, 15 Jan 2018) $
*/
#ifndef __HW_REGISTER_MACROS_H
#define __HW_REGISTER_MACROS_H 1
/*------------------------------------------------------------------------------
* 32 bits registers access:
*/
#define HW_get_uint32_reg(BASE_ADDR, REG_OFFSET) (*((uint32_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)))
#define HW_set_uint32_reg(BASE_ADDR, REG_OFFSET, VALUE) (*((uint32_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)) = (VALUE))
#define HW_set_uint32_reg_field(BASE_ADDR, FIELD, VALUE) \
(*((uint32_t volatile *)(BASE_ADDR + FIELD##_OFFSET)) = \
( \
(uint32_t) \
( \
(*((uint32_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & ~FIELD##_MASK) | \
(uint32_t)(((VALUE) << FIELD##_SHIFT) & FIELD##_MASK) \
) \
)
#define HW_get_uint32_reg_field( BASE_ADDR, FIELD ) \
(( (*((uint32_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & FIELD##_MASK) >> FIELD##_SHIFT)
/*------------------------------------------------------------------------------
* 32 bits memory access:
*/
#define HW_get_uint32(BASE_ADDR) (*((uint32_t volatile *)(BASE_ADDR)))
#define HW_set_uint32(BASE_ADDR, VALUE) (*((uint32_t volatile *)(BASE_ADDR)) = (VALUE))
/*------------------------------------------------------------------------------
* 16 bits registers access:
*/
#define HW_get_uint16_reg(BASE_ADDR, REG_OFFSET) (*((uint16_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)))
#define HW_set_uint16_reg(BASE_ADDR, REG_OFFSET, VALUE) (*((uint16_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)) = (VALUE))
#define HW_set_uint16_reg_field(BASE_ADDR, FIELD, VALUE) \
(*((uint16_t volatile *)(BASE_ADDR + FIELD##_OFFSET)) = \
( \
(uint16_t) \
( \
(*((uint16_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & ~FIELD##_MASK) | \
(uint16_t)(((VALUE) << FIELD##_SHIFT) & FIELD##_MASK) \
) \
)
#define HW_get_uint16_reg_field( BASE_ADDR, FIELD ) \
(( (*((uint16_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & FIELD##_MASK) >> FIELD##_SHIFT)
/*------------------------------------------------------------------------------
* 8 bits registers access:
*/
#define HW_get_uint8_reg(BASE_ADDR, REG_OFFSET) (*((uint8_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)))
#define HW_set_uint8_reg(BASE_ADDR, REG_OFFSET, VALUE) (*((uint8_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)) = (VALUE))
#define HW_set_uint8_reg_field(BASE_ADDR, FIELD, VALUE) \
(*((uint8_t volatile *)(BASE_ADDR + FIELD##_OFFSET)) = \
( \
(uint8_t) \
( \
(*((uint8_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & ~FIELD##_MASK) | \
(uint8_t)(((VALUE) << FIELD##_SHIFT) & FIELD##_MASK) \
) \
)
#define HW_get_uint8_reg_field( BASE_ADDR, FIELD ) \
(( (*((uint8_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & FIELD##_MASK) >> FIELD##_SHIFT)
/*------------------------------------------------------------------------------
* 8 bits memory access:
*/
#define HW_get_uint8(BASE_ADDR) (*((uint8_t volatile *)(BASE_ADDR)))
#define HW_set_uint8(BASE_ADDR, VALUE) (*((uint8_t volatile *)(BASE_ADDR)) = (VALUE))
#endif /* __HW_REGISTER_MACROS_H */

View File

@ -0,0 +1,209 @@
/***************************************************************************//**
* (c) Copyright 2007-2018 Microsemi SoC Products Group. All rights reserved.
*
* Hardware registers access functions.
* The implementation of these function is platform and toolchain specific.
* The functions declared here are implemented using assembler as part of the
* processor/toolchain specific HAL.
*
* SVN $Revision: 9661 $
* SVN $Date: 2018-01-15 16:13:33 +0530 (Mon, 15 Jan 2018) $
*/
.section .text
.globl HW_set_32bit_reg
.globl HW_get_32bit_reg
.globl HW_set_32bit_reg_field
.globl HW_get_32bit_reg_field
.globl HW_set_16bit_reg
.globl HW_get_16bit_reg
.globl HW_set_16bit_reg_field
.globl HW_get_16bit_reg_field
.globl HW_set_8bit_reg
.globl HW_get_8bit_reg
.globl HW_set_8bit_reg_field
.globl HW_get_8bit_reg_field
/***************************************************************************//**
* HW_set_32bit_reg is used to write the content of a 32 bits wide peripheral
* register.
*
* a0: addr_t reg_addr
* a1: uint32_t value
*/
HW_set_32bit_reg:
sw a1, 0(a0)
ret
/***************************************************************************//**
* HW_get_32bit_reg is used to read the content of a 32 bits wide peripheral
* register.
*
* R0: addr_t reg_addr
* @return 32 bits value read from the peripheral register.
*/
HW_get_32bit_reg:
lw a0, 0(a0)
ret
/***************************************************************************//**
* HW_set_32bit_reg_field is used to set the content of a field in a 32 bits
* wide peripheral register.
*
* a0: addr_t reg_addr
* a1: int_fast8_t shift
* a2: uint32_t mask
* a3: uint32_t value
*/
HW_set_32bit_reg_field:
mv t3, a3
sll t3, t3, a1
and t3, t3, a2
lw t1, 0(a0)
mv t2, a2
not t2, t2
and t1, t1, t2
or t1, t1, t3
sw t1, 0(a0)
ret
/***************************************************************************//**
* HW_get_32bit_reg_field is used to read the content of a field out of a
* 32 bits wide peripheral register.
*
* a0: addr_t reg_addr
* a1: int_fast8_t shift
* a2: uint32_t mask
*
* @return 32 bits value containing the register field value specified
* as parameter.
*/
HW_get_32bit_reg_field:
lw a0, 0(a0)
and a0, a0, a2
srl a0, a0, a1
ret
/***************************************************************************//**
* HW_set_16bit_reg is used to write the content of a 16 bits wide peripheral
* register.
*
* a0: addr_t reg_addr
* a1: uint_fast16_t value
*/
HW_set_16bit_reg:
sh a1, 0(a0)
ret
/***************************************************************************//**
* HW_get_16bit_reg is used to read the content of a 16 bits wide peripheral
* register.
*
* a0: addr_t reg_addr
* @return 16 bits value read from the peripheral register.
*/
HW_get_16bit_reg:
lh a0, (a0)
ret
/***************************************************************************//**
* HW_set_16bit_reg_field is used to set the content of a field in a 16 bits
* wide peripheral register.
*
* a0: addr_t reg_addr
* a1: int_fast8_t shift
* a2: uint_fast16_t mask
* a3: uint_fast16_t value
* @param value Value to be written in the specified field.
*/
HW_set_16bit_reg_field:
mv t3, a3
sll t3, t3, a1
and t3, t3, a2
lh t1, 0(a0)
mv t2, a2
not t2, t2
and t1, t1, t2
or t1, t1, t3
sh t1, 0(a0)
ret
/***************************************************************************//**
* HW_get_16bit_reg_field is used to read the content of a field from a
* 16 bits wide peripheral register.
*
* a0: addr_t reg_addr
* a1: int_fast8_t shift
* a2: uint_fast16_t mask
*
* @return 16 bits value containing the register field value specified
* as parameter.
*/
HW_get_16bit_reg_field:
lh a0, 0(a0)
and a0, a0, a2
srl a0, a0, a1
ret
/***************************************************************************//**
* HW_set_8bit_reg is used to write the content of a 8 bits wide peripheral
* register.
*
* a0: addr_t reg_addr
* a1: uint_fast8_t value
*/
HW_set_8bit_reg:
sb a1, 0(a0)
ret
/***************************************************************************//**
* HW_get_8bit_reg is used to read the content of a 8 bits wide peripheral
* register.
*
* a0: addr_t reg_addr
* @return 8 bits value read from the peripheral register.
*/
HW_get_8bit_reg:
lb a0, 0(a0)
ret
/***************************************************************************//**
* HW_set_8bit_reg_field is used to set the content of a field in a 8 bits
* wide peripheral register.
*
* a0: addr_t reg_addr,
* a1: int_fast8_t shift
* a2: uint_fast8_t mask
* a3: uint_fast8_t value
*/
HW_set_8bit_reg_field:
mv t3, a3
sll t3, t3, a1
and t3, t3, a2
lb t1, 0(a0)
mv t2, a2
not t2, t2
and t1, t1, t2
or t1, t1, t3
sb t1, 0(a0)
ret
/***************************************************************************//**
* HW_get_8bit_reg_field is used to read the content of a field from a
* 8 bits wide peripheral register.
*
* a0: addr_t reg_addr
* a1: int_fast8_t shift
* a2: uint_fast8_t mask
*
* @return 8 bits value containing the register field value specified
* as parameter.
*/
HW_get_8bit_reg_field:
lb a0, 0(a0)
and a0, a0, a2
srl a0, a0, a1
ret
.end

View File

@ -0,0 +1,229 @@
/***************************************************************************//**
* (c) Copyright 2007-2018 Microsemi SoC Products Group. All rights reserved.
*
* Hardware registers access functions.
* The implementation of these function is platform and toolchain specific.
* The functions declared here are implemented using assembler as part of the
* processor/toolchain specific HAL.
*
* SVN $Revision: 9661 $
* SVN $Date: 2018-01-15 16:13:33 +0530 (Mon, 15 Jan 2018) $
*/
#ifndef HW_REG_ACCESS
#define HW_REG_ACCESS
#include "cpu_types.h"
/***************************************************************************//**
* HW_set_32bit_reg is used to write the content of a 32 bits wide peripheral
* register.
*
* @param reg_addr Address in the processor's memory map of the register to
* write.
* @param value Value to be written into the peripheral register.
*/
void
HW_set_32bit_reg
(
addr_t reg_addr,
uint32_t value
);
/***************************************************************************//**
* HW_get_32bit_reg is used to read the content of a 32 bits wide peripheral
* register.
*
* @param reg_addr Address in the processor's memory map of the register to
* read.
* @return 32 bits value read from the peripheral register.
*/
uint32_t
HW_get_32bit_reg
(
addr_t reg_addr
);
/***************************************************************************//**
* HW_set_32bit_reg_field is used to set the content of a field in a 32 bits
* wide peripheral register.
*
* @param reg_addr Address in the processor's memory map of the register to
* be written.
* @param shift Bit offset of the register field to be read within the
* register.
* @param mask Bit mask to be applied to the raw register value to filter
* out the other register fields values.
* @param value Value to be written in the specified field.
*/
void
HW_set_32bit_reg_field
(
addr_t reg_addr,
int_fast8_t shift,
uint32_t mask,
uint32_t value
);
/***************************************************************************//**
* HW_get_32bit_reg_field is used to read the content of a field out of a
* 32 bits wide peripheral register.
*
* @param reg_addr Address in the processor's memory map of the register to
* read.
* @param shift Bit offset of the register field to be written within the
* register.
* @param mask Bit mask to be applied to the raw register value to filter
* out the other register fields values.
*
* @return 32 bits value containing the register field value specified
* as parameter.
*/
uint32_t
HW_get_32bit_reg_field
(
addr_t reg_addr,
int_fast8_t shift,
uint32_t mask
);
/***************************************************************************//**
* HW_set_16bit_reg is used to write the content of a 16 bits wide peripheral
* register.
*
* @param reg_addr Address in the processor's memory map of the register to
* write.
* @param value Value to be written into the peripheral register.
*/
void
HW_set_16bit_reg
(
addr_t reg_addr,
uint_fast16_t value
);
/***************************************************************************//**
* HW_get_16bit_reg is used to read the content of a 16 bits wide peripheral
* register.
*
* @param reg_addr Address in the processor's memory map of the register to
* read.
* @return 16 bits value read from the peripheral register.
*/
uint16_t
HW_get_16bit_reg
(
addr_t reg_addr
);
/***************************************************************************//**
* HW_set_16bit_reg_field is used to set the content of a field in a 16 bits
* wide peripheral register.
*
* @param reg_addr Address in the processor's memory map of the register to
* be written.
* @param shift Bit offset of the register field to be read within the
* register.
* @param mask Bit mask to be applied to the raw register value to filter
* out the other register fields values.
* @param value Value to be written in the specified field.
*/
void HW_set_16bit_reg_field
(
addr_t reg_addr,
int_fast8_t shift,
uint_fast16_t mask,
uint_fast16_t value
);
/***************************************************************************//**
* HW_get_16bit_reg_field is used to read the content of a field from a
* 16 bits wide peripheral register.
*
* @param reg_addr Address in the processor's memory map of the register to
* read.
* @param shift Bit offset of the register field to be written within the
* register.
* @param mask Bit mask to be applied to the raw register value to filter
* out the other register fields values.
*
* @return 16 bits value containing the register field value specified
* as parameter.
*/
uint16_t HW_get_16bit_reg_field
(
addr_t reg_addr,
int_fast8_t shift,
uint_fast16_t mask
);
/***************************************************************************//**
* HW_set_8bit_reg is used to write the content of a 8 bits wide peripheral
* register.
*
* @param reg_addr Address in the processor's memory map of the register to
* write.
* @param value Value to be written into the peripheral register.
*/
void
HW_set_8bit_reg
(
addr_t reg_addr,
uint_fast8_t value
);
/***************************************************************************//**
* HW_get_8bit_reg is used to read the content of a 8 bits wide peripheral
* register.
*
* @param reg_addr Address in the processor's memory map of the register to
* read.
* @return 8 bits value read from the peripheral register.
*/
uint8_t
HW_get_8bit_reg
(
addr_t reg_addr
);
/***************************************************************************//**
* HW_set_8bit_reg_field is used to set the content of a field in a 8 bits
* wide peripheral register.
*
* @param reg_addr Address in the processor's memory map of the register to
* be written.
* @param shift Bit offset of the register field to be read within the
* register.
* @param mask Bit mask to be applied to the raw register value to filter
* out the other register fields values.
* @param value Value to be written in the specified field.
*/
void HW_set_8bit_reg_field
(
addr_t reg_addr,
int_fast8_t shift,
uint_fast8_t mask,
uint_fast8_t value
);
/***************************************************************************//**
* HW_get_8bit_reg_field is used to read the content of a field from a
* 8 bits wide peripheral register.
*
* @param reg_addr Address in the processor's memory map of the register to
* read.
* @param shift Bit offset of the register field to be written within the
* register.
* @param mask Bit mask to be applied to the raw register value to filter
* out the other register fields values.
*
* @return 8 bits value containing the register field value specified
* as parameter.
*/
uint8_t HW_get_8bit_reg_field
(
addr_t reg_addr,
int_fast8_t shift,
uint_fast8_t mask
);
#endif /* HW_REG_ACCESS */

View File

@ -0,0 +1,119 @@
/*******************************************************************************
* (c) Copyright 2016-2017 Microsemi Corporation. All rights reserved.
*
* Platform definitions
* Version based on requirements of RISCV-HAL
*
* SVN $Revision: 9587 $
* SVN $Date: 2017-11-16 12:53:31 +0530 (Thu, 16 Nov 2017) $
*/
/*=========================================================================*//**
@mainpage Sample file detailing how hw_platform.h should be constructed for
the Mi-V processors.
@section intro_sec Introduction
The hw_platform.h is to be located in the project root directory.
Currently this file must be hand crafted when using the Mi-V Soft Processor.
You can use this file as sample.
Rename this file from sample_hw_platform.h to hw_platform.h and store it in
the root folder of your project. Then customize it per your HW design.
@section driver_configuration Project configuration Instructions
1. Change SYS_CLK_FREQ define to frequency of Mi-V Soft processor clock
2 Add all other core BASE addresses
3. Add peripheral Core Interrupt to Mi-V Soft processor interrupt mappings
4. Define MSCC_STDIO_UART_BASE_ADDR if you want a CoreUARTapb mapped to STDIO
*//*=========================================================================*/
#ifndef HW_PLATFORM_H
#define HW_PLATFORM_H
/***************************************************************************//**
* Soft-processor clock definition
* This is the only clock brought over from the Mi-V Soft processor Libero design.
*/
#ifndef SYS_CLK_FREQ
#define SYS_CLK_FREQ 83000000UL
#endif
/***************************************************************************//**
* Non-memory Peripheral base addresses
* Format of define is:
* <corename>_<instance>_BASE_ADDR
*/
#define COREUARTAPB0_BASE_ADDR 0x70001000UL
#define COREGPIO_IN_BASE_ADDR 0x70002000UL
#define CORETIMER0_BASE_ADDR 0x70003000UL
#define CORETIMER1_BASE_ADDR 0x70004000UL
#define COREGPIO_OUT_BASE_ADDR 0x70005000UL
#define FLASH_CORE_SPI_BASE 0x70006000UL
#define CORE16550_BASE_ADDR 0x70007000UL
/***************************************************************************//**
* Peripheral Interrupts are mapped to the corresponding Mi-V Soft processor
* interrupt from the Libero design.
* There can be up to 31 external interrupts (IRQ[30:0] pins) on the Mi-V Soft
* processor.The Mi-V Soft processor external interrupts are defined in the
* riscv_plic.h
* These are of the form
* typedef enum
{
NoInterrupt_IRQn = 0,
External_1_IRQn = 1,
External_2_IRQn = 2,
.
.
.
External_31_IRQn = 31
} IRQn_Type;
The interrupt 0 on RISC-V processor is not used. The pin IRQ[0] should map to
External_1_IRQn likewise IRQ[30] should map to External_31_IRQn
* Format of define is:
* <corename>_<instance>_<core interrupt name>
*/
#define TIMER0_IRQn External_30_IRQn
#define TIMER1_IRQn External_31_IRQn
/****************************************************************************
* Baud value to achieve a 115200 baud rate with a 83MHz system clock.
* This value is calculated using the following equation:
* BAUD_VALUE = (CLOCK / (16 * BAUD_RATE)) - 1
*****************************************************************************/
#define BAUD_VALUE_115200 (SYS_CLK_FREQ / (16 * 115200)) - 1
/***************************************************************************//**
* User edit section- Edit sections below if required
*/
#ifdef MSCC_STDIO_THRU_CORE_UART_APB
/*
* A base address mapping for the STDIO printf/scanf mapping to CortUARTapb
* must be provided if it is being used
*
* e.g. #define MSCC_STDIO_UART_BASE_ADDR COREUARTAPB1_BASE_ADDR
*/
#define MSCC_STDIO_UART_BASE_ADDR COREUARTAPB0_BASE_ADDR
#ifndef MSCC_STDIO_UART_BASE_ADDR
#error MSCC_STDIO_UART_BASE_ADDR not defined- e.g. #define MSCC_STDIO_UART_BASE_ADDR COREUARTAPB1_BASE_ADDR
#endif
#ifndef MSCC_STDIO_BAUD_VALUE
/*
* The MSCC_STDIO_BAUD_VALUE define should be set in your project's settings to
* specify the baud value used by the standard output CoreUARTapb instance for
* generating the UART's baud rate if you want a different baud rate from the
* default of 115200 baud
*/
#define MSCC_STDIO_BAUD_VALUE 115200
#endif /*MSCC_STDIO_BAUD_VALUE*/
#endif /* end of MSCC_STDIO_THRU_CORE_UART_APB */
/*******************************************************************************
* End of user edit section
*/
#endif /* HW_PLATFORM_H */

View File

@ -0,0 +1,136 @@
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "timers.h"
#include "hw_platform.h"
#include "core_uart_apb.h"
#include "task.h"
const char * g_hello_msg = "\r\nFreeRTOS Example\r\n";
/* A block time of zero simply means "don't block". */
#define mainDONT_BLOCK ( 0UL )
/******************************************************************************
* CoreUARTapb instance data.
*****************************************************************************/
UART_instance_t g_uart;
/*-----------------------------------------------------------*/
static void vUartTestTask1( void *pvParameters );
static void vUartTestTask2( void *pvParameters );
/*
* FreeRTOS hook for when malloc fails, enable in FreeRTOSConfig.
*/
void vApplicationMallocFailedHook( void );
/*
* FreeRTOS hook for when FreeRtos is idling, enable in FreeRTOSConfig.
*/
void vApplicationIdleHook( void );
/*
* FreeRTOS hook for when a stack overflow occurs, enable in FreeRTOSConfig.
*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName );
/*-----------------------------------------------------------*/
int main( void )
{
PLIC_init();
/**************************************************************************
* Initialize CoreUART with its base address, baud value, and line
* configuration.
*************************************************************************/
UART_init(&g_uart, COREUARTAPB0_BASE_ADDR, BAUD_VALUE_115200,
(DATA_8_BITS | NO_PARITY) );
UART_polled_tx_string( &g_uart, (const uint8_t *)"\r\n\r\n Sample Demonstration of FreeRTOS port for Mi-V processor.\r\n\r\n" );
UART_polled_tx_string( &g_uart, (const uint8_t *)" This project creates two tasks and runs them at regular intervals.\r\n" );
/* Create the two test tasks. */
xTaskCreate( vUartTestTask1, "UArt1", 1000, NULL, uartPRIMARY_PRIORITY, NULL );
xTaskCreate( vUartTestTask2, "UArt2", 1000, NULL, uartPRIMARY_PRIORITY, NULL );
/* Start the kernel. From here on, only tasks and interrupts will run. */
vTaskStartScheduler();
/* Exit FreeRTOS */
return 0;
}
/*-----------------------------------------------------------*/
void vApplicationMallocFailedHook( void )
{
/* vApplicationMallocFailedHook() will only be called if
configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
function that will get called if a call to pvPortMalloc() fails.
pvPortMalloc() is called internally by the kernel whenever a task, queue,
timer or semaphore is created. It is also called by various parts of the
demo application. If heap_1.c or heap_2.c are used, then the size of the
heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
to query the size of free heap space that remains (although it does not
provide information on how the remaining heap might be fragmented). */
taskDISABLE_INTERRUPTS();
for( ;; );
}
/*-----------------------------------------------------------*/
void vApplicationIdleHook( void )
{
/* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
task. It is essential that code added to this hook function never attempts
to block in any way (for example, call xQueueReceive() with a block time
specified, or call vTaskDelay()). If the application makes use of the
vTaskDelete() API function (as this demo application does) then it is also
important that vApplicationIdleHook() is permitted to return to its calling
function, because it is the responsibility of the idle task to clean up
memory allocated by the kernel to any task that has since been deleted. */
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS();
for( ;; );
}
/*-----------------------------------------------------------*/
static void vUartTestTask1( void *pvParameters )
{
( void ) pvParameters;
for( ;; )
{
UART_polled_tx_string( &g_uart, (const uint8_t *)"Task - 1\r\n" );
vTaskDelay(10);
}
}
/*-----------------------------------------------------------*/
static void vUartTestTask2( void *pvParameters )
{
( void ) pvParameters;
for( ;; )
{
UART_polled_tx_string( &g_uart, (const uint8_t *)"Task - 2\r\n" );
vTaskDelay(5);
}
}

View File

@ -0,0 +1,596 @@
/*******************************************************************************
* (c) Copyright 2016-2018 Microsemi SoC Products Group. All rights reserved.
*
* @file encodings.h
* @author Microsemi SoC Products Group
* @brief Mi-V soft processor register bit mask and shift constants encodings.
*
* SVN $Revision: 9825 $
* SVN $Date: 2018-03-19 10:31:41 +0530 (Mon, 19 Mar 2018) $
*/
#ifndef RISCV_CSR_ENCODING_H
#define RISCV_CSR_ENCODING_H
#ifdef __cplusplus
extern "C" {
#endif
#define MSTATUS_UIE 0x00000001
#define MSTATUS_SIE 0x00000002
#define MSTATUS_HIE 0x00000004
#define MSTATUS_MIE 0x00000008
#define MSTATUS_UPIE 0x00000010
#define MSTATUS_SPIE 0x00000020
#define MSTATUS_HPIE 0x00000040
#define MSTATUS_MPIE 0x00000080
#define MSTATUS_SPP 0x00000100
#define MSTATUS_HPP 0x00000600
#define MSTATUS_MPP 0x00001800
#define MSTATUS_FS 0x00006000
#define MSTATUS_XS 0x00018000
#define MSTATUS_MPRV 0x00020000
#define MSTATUS_SUM 0x00040000 /*changed in v1.10*/
#define MSTATUS_MXR 0x00080000 /*changed in v1.10*/
#define MSTATUS_TVM 0x00100000 /*changed in v1.10*/
#define MSTATUS_TW 0x00200000 /*changed in v1.10*/
#define MSTATUS_TSR 0x00400000 /*changed in v1.10*/
#define MSTATUS_RES 0x7F800000 /*changed in v1.10*/
#define MSTATUS32_SD 0x80000000
#define MSTATUS64_SD 0x8000000000000000
#define MCAUSE32_CAUSE 0x7FFFFFFF
#define MCAUSE64_CAUSE 0x7FFFFFFFFFFFFFFF
#define MCAUSE32_INT 0x80000000
#define MCAUSE64_INT 0x8000000000000000
#define SSTATUS_UIE 0x00000001
#define SSTATUS_SIE 0x00000002
#define SSTATUS_UPIE 0x00000010
#define SSTATUS_SPIE 0x00000020
#define SSTATUS_SPP 0x00000100
#define SSTATUS_FS 0x00006000
#define SSTATUS_XS 0x00018000
#define SSTATUS_PUM 0x00040000
#define SSTATUS32_SD 0x80000000
#define SSTATUS64_SD 0x8000000000000000
#define MIP_SSIP (1u << IRQ_S_SOFT)
#define MIP_HSIP (1u << IRQ_H_SOFT)
#define MIP_MSIP (1u << IRQ_M_SOFT)
#define MIP_STIP (1u << IRQ_S_TIMER)
#define MIP_HTIP (1u << IRQ_H_TIMER)
#define MIP_MTIP (1u << IRQ_M_TIMER)
#define MIP_SEIP (1u << IRQ_S_EXT)
#define MIP_HEIP (1u << IRQ_H_EXT)
#define MIP_MEIP (1u << IRQ_M_EXT)
#define SIP_SSIP MIP_SSIP
#define SIP_STIP MIP_STIP
#define PRV_U 0
#define PRV_S 1
#define PRV_H 2
#define PRV_M 3
#define VM_MBARE 0
#define VM_MBB 1
#define VM_MBBID 2
#define VM_SV32 8
#define VM_SV39 9
#define VM_SV48 10
#define IRQ_S_SOFT 1
#define IRQ_H_SOFT 2
#define IRQ_M_SOFT 3
#define IRQ_S_TIMER 5
#define IRQ_H_TIMER 6
#define IRQ_M_TIMER 7
#define IRQ_S_EXT 9
#define IRQ_H_EXT 10
#define IRQ_M_EXT 11
#define DEFAULT_RSTVEC 0x00001000
#define DEFAULT_NMIVEC 0x00001004
#define DEFAULT_MTVEC 0x00001010
#define CONFIG_STRING_ADDR 0x0000100C
#define EXT_IO_BASE 0x40000000
#define DRAM_BASE 0x80000000
/* page table entry (PTE) fields */
#define PTE_V 0x001 /* Valid */
#define PTE_TYPE 0x01E /* Type */
#define PTE_R 0x020 /* Referenced */
#define PTE_D 0x040 /* Dirty */
#define PTE_SOFT 0x380 /* Reserved for Software */
#define PTE_TYPE_TABLE 0x00
#define PTE_TYPE_TABLE_GLOBAL 0x02
#define PTE_TYPE_URX_SR 0x04
#define PTE_TYPE_URWX_SRW 0x06
#define PTE_TYPE_UR_SR 0x08
#define PTE_TYPE_URW_SRW 0x0A
#define PTE_TYPE_URX_SRX 0x0C
#define PTE_TYPE_URWX_SRWX 0x0E
#define PTE_TYPE_SR 0x10
#define PTE_TYPE_SRW 0x12
#define PTE_TYPE_SRX 0x14
#define PTE_TYPE_SRWX 0x16
#define PTE_TYPE_SR_GLOBAL 0x18
#define PTE_TYPE_SRW_GLOBAL 0x1A
#define PTE_TYPE_SRX_GLOBAL 0x1C
#define PTE_TYPE_SRWX_GLOBAL 0x1E
#define PTE_PPN_SHIFT 10
#define PTE_TABLE(PTE) ((0x0000000AU >> ((PTE) & 0x1F)) & 1)
#define PTE_UR(PTE) ((0x0000AAA0U >> ((PTE) & 0x1F)) & 1)
#define PTE_UW(PTE) ((0x00008880U >> ((PTE) & 0x1F)) & 1)
#define PTE_UX(PTE) ((0x0000A0A0U >> ((PTE) & 0x1F)) & 1)
#define PTE_SR(PTE) ((0xAAAAAAA0U >> ((PTE) & 0x1F)) & 1)
#define PTE_SW(PTE) ((0x88888880U >> ((PTE) & 0x1F)) & 1)
#define PTE_SX(PTE) ((0xA0A0A000U >> ((PTE) & 0x1F)) & 1)
#define PTE_CHECK_PERM(PTE, SUPERVISOR, STORE, FETCH) \
((STORE) ? ((SUPERVISOR) ? PTE_SW(PTE) : PTE_UW(PTE)) : \
(FETCH) ? ((SUPERVISOR) ? PTE_SX(PTE) : PTE_UX(PTE)) : \
((SUPERVISOR) ? PTE_SR(PTE) : PTE_UR(PTE)))
#ifdef __riscv
#if __riscv_xlen == 64
# define MSTATUS_SD MSTATUS64_SD
# define SSTATUS_SD SSTATUS64_SD
# define MCAUSE_INT MCAUSE64_INT
# define MCAUSE_CAUSE MCAUSE64_CAUSE
# define RISCV_PGLEVEL_BITS 9
#else
# define MSTATUS_SD MSTATUS32_SD
# define SSTATUS_SD SSTATUS32_SD
# define RISCV_PGLEVEL_BITS 10
# define MCAUSE_INT MCAUSE32_INT
# define MCAUSE_CAUSE MCAUSE32_CAUSE
#endif
#define RISCV_PGSHIFT 12
#define RISCV_PGSIZE (1 << RISCV_PGSHIFT)
#ifndef __ASSEMBLER__
#ifdef __GNUC__
#define read_csr(reg) ({ unsigned long __tmp; \
asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \
__tmp; })
#define write_csr(reg, val) ({ \
if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \
asm volatile ("csrw " #reg ", %0" :: "i"(val)); \
else \
asm volatile ("csrw " #reg ", %0" :: "r"(val)); })
#define swap_csr(reg, val) ({ unsigned long __tmp; \
if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \
asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "i"(val)); \
else \
asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "r"(val)); \
__tmp; })
#define set_csr(reg, bit) ({ unsigned long __tmp; \
if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \
asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \
else \
asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \
__tmp; })
#define clear_csr(reg, bit) ({ unsigned long __tmp; \
if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \
asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \
else \
asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \
__tmp; })
#define rdtime() read_csr(time)
#define rdcycle() read_csr(cycle)
#define rdinstret() read_csr(instret)
#ifdef __riscv_atomic
#define MASK(nr) (1UL << nr)
#define MASK_NOT(nr) (~(1UL << nr))
/**
* atomic_read - read atomic variable
* @v: pointer of type int
*
* Atomically reads the value of @v.
*/
static inline int atomic_read(const int *v)
{
return *((volatile int *)(v));
}
/**
* atomic_set - set atomic variable
* @v: pointer of type int
* @i: required value
*
* Atomically sets the value of @v to @i.
*/
static inline void atomic_set(int *v, int i)
{
*v = i;
}
/**
* atomic_add - add integer to atomic variable
* @i: integer value to add
* @v: pointer of type int
*
* Atomically adds @i to @v.
*/
static inline void atomic_add(int i, int *v)
{
__asm__ __volatile__ (
"amoadd.w zero, %1, %0"
: "+A" (*v)
: "r" (i));
}
static inline int atomic_fetch_add(unsigned int mask, int *v)
{
int out;
__asm__ __volatile__ (
"amoadd.w %2, %1, %0"
: "+A" (*v), "=r" (out)
: "r" (mask));
return out;
}
/**
* atomic_sub - subtract integer from atomic variable
* @i: integer value to subtract
* @v: pointer of type int
*
* Atomically subtracts @i from @v.
*/
static inline void atomic_sub(int i, int *v)
{
atomic_add(-i, v);
}
static inline int atomic_fetch_sub(unsigned int mask, int *v)
{
int out;
__asm__ __volatile__ (
"amosub.w %2, %1, %0"
: "+A" (*v), "=r" (out)
: "r" (mask));
return out;
}
/**
* atomic_add_return - add integer to atomic variable
* @i: integer value to add
* @v: pointer of type int
*
* Atomically adds @i to @v and returns the result
*/
static inline int atomic_add_return(int i, int *v)
{
register int c;
__asm__ __volatile__ (
"amoadd.w %0, %2, %1"
: "=r" (c), "+A" (*v)
: "r" (i));
return (c + i);
}
/**
* atomic_sub_return - subtract integer from atomic variable
* @i: integer value to subtract
* @v: pointer of type int
*
* Atomically subtracts @i from @v and returns the result
*/
static inline int atomic_sub_return(int i, int *v)
{
return atomic_add_return(-i, v);
}
/**
* atomic_inc - increment atomic variable
* @v: pointer of type int
*
* Atomically increments @v by 1.
*/
static inline void atomic_inc(int *v)
{
atomic_add(1, v);
}
/**
* atomic_dec - decrement atomic variable
* @v: pointer of type int
*
* Atomically decrements @v by 1.
*/
static inline void atomic_dec(int *v)
{
atomic_add(-1, v);
}
static inline int atomic_inc_return(int *v)
{
return atomic_add_return(1, v);
}
static inline int atomic_dec_return(int *v)
{
return atomic_sub_return(1, v);
}
/**
* atomic_sub_and_test - subtract value from variable and test result
* @i: integer value to subtract
* @v: pointer of type int
*
* Atomically subtracts @i from @v and returns
* true if the result is zero, or false for all
* other cases.
*/
static inline int atomic_sub_and_test(int i, int *v)
{
return (atomic_sub_return(i, v) == 0);
}
/**
* atomic_inc_and_test - increment and test
* @v: pointer of type int
*
* Atomically increments @v by 1
* and returns true if the result is zero, or false for all
* other cases.
*/
static inline int atomic_inc_and_test(int *v)
{
return (atomic_inc_return(v) == 0);
}
/**
* atomic_dec_and_test - decrement and test
* @v: pointer of type int
*
* Atomically decrements @v by 1 and
* returns true if the result is 0, or false for all other
* cases.
*/
static inline int atomic_dec_and_test(int *v)
{
return (atomic_dec_return(v) == 0);
}
/**
* atomic_add_negative - add and test if negative
* @i: integer value to add
* @v: pointer of type int
*
* Atomically adds @i to @v and returns true
* if the result is negative, or false when
* result is greater than or equal to zero.
*/
static inline int atomic_add_negative(int i, int *v)
{
return (atomic_add_return(i, v) < 0);
}
static inline int atomic_xchg(int *v, int n)
{
register int c;
__asm__ __volatile__ (
"amoswap.w %0, %2, %1"
: "=r" (c), "+A" (*v)
: "r" (n));
return c;
}
/**
* atomic_and - Atomically clear bits in atomic variable
* @mask: Mask of the bits to be retained
* @v: pointer of type int
*
* Atomically retains the bits set in @mask from @v
*/
static inline void atomic_and(unsigned int mask, int *v)
{
__asm__ __volatile__ (
"amoand.w zero, %1, %0"
: "+A" (*v)
: "r" (mask));
}
static inline int atomic_fetch_and(unsigned int mask, int *v)
{
int out;
__asm__ __volatile__ (
"amoand.w %2, %1, %0"
: "+A" (*v), "=r" (out)
: "r" (mask));
return out;
}
/**
* atomic_or - Atomically set bits in atomic variable
* @mask: Mask of the bits to be set
* @v: pointer of type int
*
* Atomically sets the bits set in @mask in @v
*/
static inline void atomic_or(unsigned int mask, int *v)
{
__asm__ __volatile__ (
"amoor.w zero, %1, %0"
: "+A" (*v)
: "r" (mask));
}
static inline int atomic_fetch_or(unsigned int mask, int *v)
{
int out;
__asm__ __volatile__ (
"amoor.w %2, %1, %0"
: "+A" (*v), "=r" (out)
: "r" (mask));
return out;
}
/**
* atomic_xor - Atomically flips bits in atomic variable
* @mask: Mask of the bits to be flipped
* @v: pointer of type int
*
* Atomically flips the bits set in @mask in @v
*/
static inline void atomic_xor(unsigned int mask, int *v)
{
__asm__ __volatile__ (
"amoxor.w zero, %1, %0"
: "+A" (*v)
: "r" (mask));
}
static inline int atomic_fetch_xor(unsigned int mask, int *v)
{
int out;
__asm__ __volatile__ (
"amoxor.w %2, %1, %0"
: "+A" (*v), "=r" (out)
: "r" (mask));
return out;
}
/*----------------------------------------------------*/
/**
* test_and_set_bit - Set a bit and return its old value
* @nr: Bit to set
* @addr: Address to count from
*
* This operation is atomic and cannot be reordered.
* It also implies a memory barrier.
*/
static inline int test_and_set_bit(int nr, volatile unsigned long *addr)
{
unsigned long __res, __mask;
__mask = MASK(nr);
__asm__ __volatile__ ( \
"amoor.w %0, %2, %1" \
: "=r" (__res), "+A" (*addr) \
: "r" (__mask)); \
return ((__res & __mask) != 0);
}
/**
* test_and_clear_bit - Clear a bit and return its old value
* @nr: Bit to clear
* @addr: Address to count from
*
* This operation is atomic and cannot be reordered.
* It also implies a memory barrier.
*/
static inline int test_and_clear_bit(int nr, volatile unsigned long *addr)
{
unsigned long __res, __mask;
__mask = MASK_NOT(nr);
__asm__ __volatile__ ( \
"amoand.w %0, %2, %1" \
: "=r" (__res), "+A" (*addr) \
: "r" (__mask)); \
return ((__res & __mask) != 0);
}
/**
* test_and_change_bit - Change a bit and return its old value
* @nr: Bit to change
* @addr: Address to count from
*
* This operation is atomic and cannot be reordered.
* It also implies a memory barrier.
*/
static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
{
unsigned long __res, __mask;
__mask = MASK(nr);
__asm__ __volatile__ ( \
"amoxor.w %0, %2, %1" \
: "=r" (__res), "+A" (*addr) \
: "r" (__mask)); \
return ((__res & __mask) != 0);
}
/**
* set_bit - Atomically set a bit in memory
* @nr: the bit to set
* @addr: the address to start counting from
*
* This function is atomic and may not be reordered.
*/
static inline void set_bit(int nr, volatile unsigned long *addr)
{
__asm__ __volatile__ ( \
"AMOOR.w zero, %1, %0" \
: "+A" (*addr) \
: "r" (MASK(nr)));
}
/**
* clear_bit - Clears a bit in memory
* @nr: Bit to clear
* @addr: Address to start counting from
*
* clear_bit() is atomic and may not be reordered.
*/
static inline void clear_bit(int nr, volatile unsigned long *addr)
{
__asm__ __volatile__ ( \
"AMOAND.w zero, %1, %0" \
: "+A" (*addr) \
: "r" (MASK_NOT(nr)));
}
/**
* change_bit - Toggle a bit in memory
* @nr: Bit to change
* @addr: Address to start counting from
*
* change_bit() is atomic and may not be reordered.
*/
static inline void change_bit(int nr, volatile unsigned long *addr)
{
__asm__ __volatile__ ( \
"AMOXOR.w zero, %1, %0" \
: "+A" (*addr) \
: "r" (MASK(nr)));
}
#endif /* __riscv_atomic */
#endif /*__GNUC__*/
#endif /*__ASSEMBLER__*/
#endif /*__riscv*/
#ifdef __cplusplus
}
#endif
#endif /*RISCV_CSR_ENCODING_H*/

View File

@ -0,0 +1,160 @@
/*******************************************************************************
* (c) Copyright 2016-2018 Microsemi SoC Products Group. All rights reserved.
*
* @file entry.S
* @author Microsemi SoC Products Group
* @brief Mi-V soft processor vectors, trap handling and startup code.
*
* SVN $Revision: 9947 $
* SVN $Date: 2018-04-30 20:28:49 +0530 (Mon, 30 Apr 2018) $
*/
#ifndef ENTRY_S
#define ENTRY_S
#include "encoding.h"
#if __riscv_xlen == 64
# define LREG ld
# define SREG sd
# define REGBYTES 8
#else
# define LREG lw
# define SREG sw
# define REGBYTES 4
#endif
.section .text.entry
.globl _start
_start:
j handle_reset
nmi_vector:
j nmi_vector
trap_vector:
j trap_entry
handle_reset:
la t0, trap_entry
csrw mtvec, t0
csrwi mstatus, 0
csrwi mie, 0
/*Floating point support configuration*/
#ifdef __riscv_flen
csrr t0, mstatus
lui t1, 0xffffa
addi t1, t1, -1
and t0, t0, t1
lui t1, 0x4
or t1, t0, t1
csrw mstatus, t1
lui t0, 0x0
fscsr t0
#endif
.option push
# Ensure the instruction is not optimized, since gp is not yet set
.option norelax
# initialize global pointer
la gp, __global_pointer$
.option pop
# initialize stack pointer
la sp, __stack_top
# perform the rest of initialization in C
j _init
trap_entry:
addi sp, sp, -32*REGBYTES
SREG x1, 0 * REGBYTES(sp)
SREG x2, 1 * REGBYTES(sp)
SREG x3, 2 * REGBYTES(sp)
SREG x4, 3 * REGBYTES(sp)
SREG x5, 4 * REGBYTES(sp)
SREG x6, 5 * REGBYTES(sp)
SREG x7, 6 * REGBYTES(sp)
SREG x8, 7 * REGBYTES(sp)
SREG x9, 8 * REGBYTES(sp)
SREG x10, 9 * REGBYTES(sp)
SREG x11, 10 * REGBYTES(sp)
SREG x12, 11 * REGBYTES(sp)
SREG x13, 12 * REGBYTES(sp)
SREG x14, 13 * REGBYTES(sp)
SREG x15, 14 * REGBYTES(sp)
SREG x16, 15 * REGBYTES(sp)
SREG x17, 16 * REGBYTES(sp)
SREG x18, 17 * REGBYTES(sp)
SREG x19, 18 * REGBYTES(sp)
SREG x20, 19 * REGBYTES(sp)
SREG x21, 20 * REGBYTES(sp)
SREG x22, 21 * REGBYTES(sp)
SREG x23, 22 * REGBYTES(sp)
SREG x24, 23 * REGBYTES(sp)
SREG x25, 24 * REGBYTES(sp)
SREG x26, 25 * REGBYTES(sp)
SREG x27, 26 * REGBYTES(sp)
SREG x28, 27 * REGBYTES(sp)
SREG x29, 28 * REGBYTES(sp)
SREG x30, 29 * REGBYTES(sp)
SREG x31, 30 * REGBYTES(sp)
csrr t0, mepc
SREG t0, 31 * REGBYTES(sp)
csrr a0, mcause
csrr a1, mepc
mv a2, sp
jal handle_trap
csrw mepc, a0
# Remain in M-mode after mret
li t0, MSTATUS_MPP
csrs mstatus, t0
LREG x1, 0 * REGBYTES(sp)
LREG x2, 1 * REGBYTES(sp)
LREG x3, 2 * REGBYTES(sp)
LREG x4, 3 * REGBYTES(sp)
LREG x5, 4 * REGBYTES(sp)
LREG x6, 5 * REGBYTES(sp)
LREG x7, 6 * REGBYTES(sp)
LREG x8, 7 * REGBYTES(sp)
LREG x9, 8 * REGBYTES(sp)
LREG x10, 9 * REGBYTES(sp)
LREG x11, 10 * REGBYTES(sp)
LREG x12, 11 * REGBYTES(sp)
LREG x13, 12 * REGBYTES(sp)
LREG x14, 13 * REGBYTES(sp)
LREG x15, 14 * REGBYTES(sp)
LREG x16, 15 * REGBYTES(sp)
LREG x17, 16 * REGBYTES(sp)
LREG x18, 17 * REGBYTES(sp)
LREG x19, 18 * REGBYTES(sp)
LREG x20, 19 * REGBYTES(sp)
LREG x21, 20 * REGBYTES(sp)
LREG x22, 21 * REGBYTES(sp)
LREG x23, 22 * REGBYTES(sp)
LREG x24, 23 * REGBYTES(sp)
LREG x25, 24 * REGBYTES(sp)
LREG x26, 25 * REGBYTES(sp)
LREG x27, 26 * REGBYTES(sp)
LREG x28, 27 * REGBYTES(sp)
LREG x29, 28 * REGBYTES(sp)
LREG x30, 29 * REGBYTES(sp)
LREG x31, 30 * REGBYTES(sp)
addi sp, sp, 32*REGBYTES
mret
#endif

View File

@ -0,0 +1,80 @@
/*******************************************************************************
* (c) Copyright 2016-2018 Microsemi SoC Products Group. All rights reserved.
*
* @file init.c
* @author Microsemi SoC Products Group
* @brief Mi-V soft processor memory section initializations and start-up code.
*
* SVN $Revision: 9661 $
* SVN $Date: 2018-01-15 16:13:33 +0530 (Mon, 15 Jan 2018) $
*/
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include "encoding.h"
#ifdef __cplusplus
extern "C" {
#endif
extern uint32_t __sdata_load;
extern uint32_t __sdata_start;
extern uint32_t __sdata_end;
extern uint32_t __data_load;
extern uint32_t __data_start;
extern uint32_t __data_end;
extern uint32_t __sbss_start;
extern uint32_t __sbss_end;
extern uint32_t __bss_start;
extern uint32_t __bss_end;
static void copy_section(uint32_t * p_load, uint32_t * p_vma, uint32_t * p_vma_end)
{
while(p_vma <= p_vma_end)
{
*p_vma = *p_load;
++p_load;
++p_vma;
}
}
static void zero_section(uint32_t * start, uint32_t * end)
{
uint32_t * p_zero = start;
while(p_zero <= end)
{
*p_zero = 0;
++p_zero;
}
}
void _init(void)
{
extern int main(int, char**);
const char *argv0 = "hello";
char *argv[] = {(char *)argv0, NULL, NULL};
copy_section(&__sdata_load, &__sdata_start, &__sdata_end);
copy_section(&__data_load, &__data_start, &__data_end);
zero_section(&__sbss_start, &__sbss_end);
zero_section(&__bss_start, &__bss_end);
main(1, argv);
}
/* Function called after main() finishes */
void
_fini()
{
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,137 @@
/*******************************************************************************
* (c) Copyright 2016-2018 Microsemi SoC Products Group. All rights reserved.
*
* file name : microsemi-riscv-igloo2.ld
* Mi-V soft processor linker script for creating a SoftConsole downloadable
* image executing in eNVM.
*
* This linker script assumes that the eNVM is connected at on the Mi-V soft
* processor memory space.
*
* SVN $Revision: 9661 $
* SVN $Date: 2018-01-15 16:13:33 +0530 (Mon, 15 Jan 2018) $
*/
OUTPUT_ARCH( "riscv" )
ENTRY(_start)
MEMORY
{
envm (rx) : ORIGIN = 0x60000000, LENGTH = 240k
ram (rwx) : ORIGIN = 0x80000000, LENGTH = 64k
}
RAM_START_ADDRESS = 0x80000000; /* Must be the same value MEMORY region ram ORIGIN above. */
RAM_SIZE = 64k; /* Must be the same value MEMORY region ram LENGTH above. */
STACK_SIZE = 2k; /* needs to be calculated for your application */
HEAP_SIZE = 2k; /* needs to be calculated for your application */
SECTIONS
{
.text : ALIGN(0x10)
{
KEEP (*(SORT_NONE(.text.entry)))
. = ALIGN(0x10);
*(.text .text.* .gnu.linkonce.t.*)
*(.plt)
. = ALIGN(0x10);
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*crtend.o(.ctors))
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*crtend.o(.dtors))
*(.rodata .rodata.* .gnu.linkonce.r.*)
*(.gcc_except_table)
*(.eh_frame_hdr)
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
PROVIDE_HIDDEN (__fini_array_end = .);
. = ALIGN(0x10);
} >envm
/* short/global data section */
.sdata : ALIGN(0x10)
{
__sdata_load = LOADADDR(.sdata);
__sdata_start = .;
PROVIDE( __global_pointer$ = . + 0x800);
*(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2)
*(.srodata*)
*(.sdata .sdata.* .gnu.linkonce.s.*)
. = ALIGN(0x10);
__sdata_end = .;
} >ram AT>envm
/* data section */
.data : ALIGN(0x10)
{
__data_load = LOADADDR(.data);
__data_start = .;
*(.got.plt) *(.got)
*(.shdata)
*(.data .data.* .gnu.linkonce.d.*)
. = ALIGN(0x10);
__data_end = .;
} >ram AT>envm
/* sbss section */
.sbss : ALIGN(0x10)
{
__sbss_start = .;
*(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.scommon)
. = ALIGN(0x10);
__sbss_end = .;
} > ram
/* sbss section */
.bss : ALIGN(0x10)
{
__bss_start = .;
*(.shbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(0x10);
__bss_end = .;
} > ram
/* End of uninitialized data segment */
_end = .;
.heap : ALIGN(0x10)
{
__heap_start = .;
. += HEAP_SIZE;
__heap_end = .;
. = ALIGN(0x10);
_heap_end = __heap_end;
} > ram
.stack : ALIGN(0x10)
{
__stack_bottom = .;
. += STACK_SIZE;
__stack_top = .;
} > ram
}

View File

@ -0,0 +1,137 @@
/*******************************************************************************
* (c) Copyright 2016-2018 Microsemi SoC Products Group. All rights reserved.
*
* file name : microsemi-riscv-ram.ld
* Mi-V soft processor linker script for creating a SoftConsole downloadable
* debug image executing in SRAM.
*
* This linker script assumes that the SRAM is connected at on the Mi-V soft
* processor memory space. The start address and size of the memory space must
* be correct as per the Libero design.
*
* SVN $Revision: 9661 $
* SVN $Date: 2018-01-15 16:13:33 +0530 (Mon, 15 Jan 2018) $
*/
OUTPUT_ARCH( "riscv" )
ENTRY(_start)
MEMORY
{
ram (rwx) : ORIGIN = 0x80000000, LENGTH = 512k
}
RAM_START_ADDRESS = 0x80000000; /* Must be the same value MEMORY region ram ORIGIN above. */
RAM_SIZE = 512k; /* Must be the same value MEMORY region ram LENGTH above. */
STACK_SIZE = 64k; /* needs to be calculated for your application */
HEAP_SIZE = 64k; /* needs to be calculated for your application */
SECTIONS
{
.text : ALIGN(0x10)
{
KEEP (*(SORT_NONE(.text.entry)))
. = ALIGN(0x10);
*(.text .text.* .gnu.linkonce.t.*)
*(.plt)
. = ALIGN(0x10);
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*crtend.o(.ctors))
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*crtend.o(.dtors))
*(.rodata .rodata.* .gnu.linkonce.r.*)
*(.gcc_except_table)
*(.eh_frame_hdr)
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
PROVIDE_HIDDEN (__fini_array_end = .);
. = ALIGN(0x10);
} > ram
/* short/global data section */
.sdata : ALIGN(0x10)
{
__sdata_load = LOADADDR(.sdata);
__sdata_start = .;
PROVIDE( __global_pointer$ = . + 0x800);
*(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2)
*(.srodata*)
*(.sdata .sdata.* .gnu.linkonce.s.*)
. = ALIGN(0x10);
__sdata_end = .;
} > ram
/* data section */
.data : ALIGN(0x10)
{
__data_load = LOADADDR(.data);
__data_start = .;
*(.got.plt) *(.got)
*(.shdata)
*(.data .data.* .gnu.linkonce.d.*)
. = ALIGN(0x10);
__data_end = .;
} > ram
/* sbss section */
.sbss : ALIGN(0x10)
{
__sbss_start = .;
*(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.scommon)
. = ALIGN(0x10);
__sbss_end = .;
} > ram
/* sbss section */
.bss : ALIGN(0x10)
{
__bss_start = .;
*(.shbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(0x10);
__bss_end = .;
} > ram
/* End of uninitialized data segment */
_end = .;
.heap : ALIGN(0x10)
{
__heap_start = .;
. += HEAP_SIZE;
__heap_end = .;
. = ALIGN(0x10);
_heap_end = __heap_end;
} > ram
.stack : ALIGN(0x10)
{
__stack_bottom = .;
. += STACK_SIZE;
__stack_top = .;
} > ram
}

View File

@ -0,0 +1,251 @@
/*******************************************************************************
* (c) Copyright 2016-2018 Microsemi SoC Products Group. All rights reserved.
*
* @file riscv_hal.c
* @author Microsemi SoC Products Group
* @brief Implementation of Hardware Abstraction Layer for Mi-V soft processors
*
* SVN $Revision: 9835 $
* SVN $Date: 2018-03-19 19:11:35 +0530 (Mon, 19 Mar 2018) $
*/
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include "riscv_hal.h"
#ifdef __cplusplus
extern "C" {
#endif
#define RTC_PRESCALER 100UL
#define SUCCESS 0U
#define ERROR 1U
/*------------------------------------------------------------------------------
*
*/
uint8_t Invalid_IRQHandler(void);
uint8_t External_1_IRQHandler(void);
uint8_t External_2_IRQHandler(void);
uint8_t External_3_IRQHandler(void);
uint8_t External_4_IRQHandler(void);
uint8_t External_5_IRQHandler(void);
uint8_t External_6_IRQHandler(void);
uint8_t External_7_IRQHandler(void);
uint8_t External_8_IRQHandler(void);
uint8_t External_9_IRQHandler(void);
uint8_t External_10_IRQHandler(void);
uint8_t External_11_IRQHandler(void);
uint8_t External_12_IRQHandler(void);
uint8_t External_13_IRQHandler(void);
uint8_t External_14_IRQHandler(void);
uint8_t External_15_IRQHandler(void);
uint8_t External_16_IRQHandler(void);
uint8_t External_17_IRQHandler(void);
uint8_t External_18_IRQHandler(void);
uint8_t External_19_IRQHandler(void);
uint8_t External_20_IRQHandler(void);
uint8_t External_21_IRQHandler(void);
uint8_t External_22_IRQHandler(void);
uint8_t External_23_IRQHandler(void);
uint8_t External_24_IRQHandler(void);
uint8_t External_25_IRQHandler(void);
uint8_t External_26_IRQHandler(void);
uint8_t External_27_IRQHandler(void);
uint8_t External_28_IRQHandler(void);
uint8_t External_29_IRQHandler(void);
uint8_t External_30_IRQHandler(void);
uint8_t External_31_IRQHandler(void);
/*------------------------------------------------------------------------------
*
*/
extern void Software_IRQHandler(void);
/*------------------------------------------------------------------------------
* Increment value for the mtimecmp register in order to achieve a system tick
* interrupt as specified through the SysTick_Config() function.
*/
static uint64_t g_systick_increment = 0U;
/*------------------------------------------------------------------------------
* Disable all interrupts.
*/
void __disable_irq(void)
{
clear_csr(mstatus, MSTATUS_MPIE);
clear_csr(mstatus, MSTATUS_MIE);
}
/*------------------------------------------------------------------------------
* Enabler all interrupts.
*/
void __enable_irq(void)
{
set_csr(mstatus, MSTATUS_MIE);
}
/*------------------------------------------------------------------------------
* Configure the machine timer to generate an interrupt.
*/
uint32_t SysTick_Config(uint32_t ticks)
{
uint32_t ret_val = ERROR;
g_systick_increment = (uint64_t)(ticks) / RTC_PRESCALER;
if (g_systick_increment > 0U)
{
uint32_t mhart_id = read_csr(mhartid);
PRCI->MTIMECMP[mhart_id] = PRCI->MTIME + g_systick_increment;
set_csr(mie, MIP_MTIP);
__enable_irq();
ret_val = SUCCESS;
}
return ret_val;
}
/*------------------------------------------------------------------------------
* RISC-V interrupt handler for machine timer interrupts.
*/
static void handle_m_timer_interrupt(void)
{
clear_csr(mie, MIP_MTIP);
SysTick_Handler();
PRCI->MTIMECMP[read_csr(mhartid)] = PRCI->MTIME + g_systick_increment;
set_csr(mie, MIP_MTIP);
}
/*------------------------------------------------------------------------------
* RISC-V interrupt handler for external interrupts.
*/
uint8_t (*ext_irq_handler_table[32])(void) =
{
Invalid_IRQHandler,
External_1_IRQHandler,
External_2_IRQHandler,
External_3_IRQHandler,
External_4_IRQHandler,
External_5_IRQHandler,
External_6_IRQHandler,
External_7_IRQHandler,
External_8_IRQHandler,
External_9_IRQHandler,
External_10_IRQHandler,
External_11_IRQHandler,
External_12_IRQHandler,
External_13_IRQHandler,
External_14_IRQHandler,
External_15_IRQHandler,
External_16_IRQHandler,
External_17_IRQHandler,
External_18_IRQHandler,
External_19_IRQHandler,
External_20_IRQHandler,
External_21_IRQHandler,
External_22_IRQHandler,
External_23_IRQHandler,
External_24_IRQHandler,
External_25_IRQHandler,
External_26_IRQHandler,
External_27_IRQHandler,
External_28_IRQHandler,
External_29_IRQHandler,
External_30_IRQHandler,
External_31_IRQHandler
};
/*------------------------------------------------------------------------------
*
*/
static void handle_m_ext_interrupt(void)
{
uint32_t int_num = PLIC_ClaimIRQ();
uint8_t disable = EXT_IRQ_KEEP_ENABLED;
disable = ext_irq_handler_table[int_num]();
PLIC_CompleteIRQ(int_num);
if(EXT_IRQ_DISABLE == disable)
{
PLIC_DisableIRQ((IRQn_Type)int_num);
}
}
static void handle_m_soft_interrupt(void)
{
Software_IRQHandler();
/*Clear software interrupt*/
PRCI->MSIP[0] = 0x00U;
}
/*------------------------------------------------------------------------------
* Trap/Interrupt handler
*/
uintptr_t handle_trap(uintptr_t mcause, uintptr_t mepc)
{
if ((mcause & MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) == IRQ_M_EXT))
{
handle_m_ext_interrupt();
}
else if ((mcause & MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) == IRQ_M_TIMER))
{
handle_m_timer_interrupt();
}
else if ( (mcause & MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) == IRQ_M_SOFT))
{
handle_m_soft_interrupt();
}
else
{
#ifndef NDEBUG
/*
Arguments supplied to this function are mcause, mepc (exception PC) and stack pointer
based onprivileged-isa specification
mcause values and meanings are:
0 Instruction address misaligned (mtval/mbadaddr is the address)
1 Instruction access fault (mtval/mbadaddr is the address)
2 Illegal instruction (mtval/mbadaddr contains the offending instruction opcode)
3 Breakpoint
4 Load address misaligned (mtval/mbadaddr is the address)
5 Load address fault (mtval/mbadaddr is the address)
6 Store/AMO address fault (mtval/mbadaddr is the address)
7 Store/AMO access fault (mtval/mbadaddr is the address)
8 Environment call from U-mode
9 Environment call from S-mode
A Environment call from M-mode
B Instruction page fault
C Load page fault (mtval/mbadaddr is the address)
E Store page fault (mtval/mbadaddr is the address)
*/
uintptr_t mip = read_csr(mip); /* interrupt pending */
uintptr_t mbadaddr = read_csr(mbadaddr); /* additional info and meaning depends on mcause */
uintptr_t mtvec = read_csr(mtvec); /* trap vector */
uintptr_t mscratch = read_csr(mscratch); /* temporary, sometimes might hold temporary value of a0 */
uintptr_t mstatus = read_csr(mstatus); /* status contains many smaller fields: */
/* breakpoint*/
__asm("ebreak");
#else
_exit(1 + mcause);
#endif
}
return mepc;
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,55 @@
/*******************************************************************************
* (c) Copyright 2016-2018 Microsemi SoC Products Group. All rights reserved.
*
* @file riscv_hal.h
* @author Microsemi SoC Products Group
* @brief Hardware Abstraction Layer functions for Mi-V soft processors
*
* SVN $Revision: 9835 $
* SVN $Date: 2018-03-19 19:11:35 +0530 (Mon, 19 Mar 2018) $
*/
#ifndef RISCV_HAL_H
#define RISCV_HAL_H
#include "riscv_plic.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
*Return value from External IRQ handler. This will be used to disable the External
*interrupt.
*/
#define EXT_IRQ_KEEP_ENABLED 0U
#define EXT_IRQ_DISABLE 1U
/*------------------------------------------------------------------------------
* Interrupt enable/disable.
*/
void __disable_irq(void);
void __enable_irq(void);
/*------------------------------------------------------------------------------
* System tick handler. This is generated from the RISC-V machine timer.
*/
void SysTick_Handler(void);
/*------------------------------------------------------------------------------
* System tick configuration.
* Configures the machine timer to generate a system tick interrupt at regular
* intervals.
* Takes the number of system clock ticks between interrupts.
*
* Returns 0 if successful.
* Returns 1 if the interrupt interval cannot be achieved.
*/
uint32_t SysTick_Config(uint32_t ticks);
#ifdef __cplusplus
}
#endif
#endif /* RISCV_HAL_H */

View File

@ -0,0 +1,227 @@
/*******************************************************************************
* (c) Copyright 2016-2018 Microsemi SoC Products Group. All rights reserved.
*
* @file riscv_hal_stubs.c
* @author Microsemi SoC Products Group
* @brief Mi-V soft processor Interrupt Function stubs.
* The functions below will only be linked with the application code if the user
* does not provide an implementation for these functions. These functions are
* defined with weak linking so that they can be overridden by a function with
* same prototype in the user's application code.
*
* SVN $Revision: 9835 $
* SVN $Date: 2018-03-19 19:11:35 +0530 (Mon, 19 Mar 2018) $
*/
#include <unistd.h>
#ifdef __cplusplus
extern "C" {
#endif
/*Weakly linked handler. Will be replaced with user's definition if provided*/
__attribute__((weak)) void Software_IRQHandler(void)
{
_exit(10);
}
/*Weakly linked handler. Will be replaced with user's definition if provided*/
__attribute__((weak)) void SysTick_Handler(void)
{
/*Default handler*/
}
/*Weakly linked handler. Will be replaced with user's definition if provided*/
__attribute__((weak)) uint8_t Invalid_IRQHandler(void)
{
return(0U); /*Default handler*/
}
/*Weakly linked handler. Will be replaced with user's definition if provided*/
__attribute__((weak)) uint8_t External_1_IRQHandler(void)
{
return(0U); /*Default handler*/
}
/*Weakly linked handler. Will be replaced with user's definition if provided*/
__attribute__((weak)) uint8_t External_2_IRQHandler(void)
{
return(0U); /*Default handler*/
}
/*Weakly linked handler. Will be replaced with user's definition if provided*/
__attribute__((weak)) uint8_t External_3_IRQHandler(void)
{
return(0U); /*Default handler*/
}
/*Weakly linked handler. Will be replaced with user's definition if provided*/
__attribute__((weak)) uint8_t External_4_IRQHandler(void)
{
return(0U); /*Default handler*/
}
/*Weakly linked handler. Will be replaced with user's definition if provided*/
__attribute__((weak)) uint8_t External_5_IRQHandler(void)
{
return(0U); /*Default handler*/
}
/*Weakly linked handler. Will be replaced with user's definition if provided*/
__attribute__((weak)) uint8_t External_6_IRQHandler(void)
{
return(0U); /*Default handler*/
}
/*Weakly linked handler. Will be replaced with user's definition if provided*/
__attribute__((weak)) uint8_t External_7_IRQHandler(void)
{
return(0U); /*Default handler*/
}
/*Weakly linked handler. Will be replaced with user's definition if provided*/
__attribute__((weak)) uint8_t External_8_IRQHandler(void)
{
return(0U); /*Default handler*/
}
/*Weakly linked handler. Will be replaced with user's definition if provided*/
__attribute__((weak)) uint8_t External_9_IRQHandler(void)
{
return(0U); /*Default handler*/
}
/*Weakly linked handler. Will be replaced with user's definition if provided*/
__attribute__((weak)) uint8_t External_10_IRQHandler(void)
{
return(0U); /*Default handler*/
}
/*Weakly linked handler. Will be replaced with user's definition if provided*/
__attribute__((weak)) uint8_t External_11_IRQHandler(void)
{
return(0U); /*Default handler*/
}
/*Weakly linked handler. Will be replaced with user's definition if provided*/
__attribute__((weak)) uint8_t External_12_IRQHandler(void)
{
return(0U); /*Default handler*/
}
/*Weakly linked handler. Will be replaced with user's definition if provided*/
__attribute__((weak)) uint8_t External_13_IRQHandler(void)
{
return(0U); /*Default handler*/
}
/*Weakly linked handler. Will be replaced with user's definition if provided*/
__attribute__((weak)) uint8_t External_14_IRQHandler(void)
{
return(0U); /*Default handler*/
}
/*Weakly linked handler. Will be replaced with user's definition if provided*/
__attribute__((weak)) uint8_t External_15_IRQHandler(void)
{
return(0U); /*Default handler*/
}
/*Weakly linked handler. Will be replaced with user's definition if provided*/
__attribute__((weak)) uint8_t External_16_IRQHandler(void)
{
return(0U); /*Default handler*/
}
/*Weakly linked handler. Will be replaced with user's definition if provided*/
__attribute__((weak)) uint8_t External_17_IRQHandler(void)
{
return(0U); /*Default handler*/
}
/*Weakly linked handler. Will be replaced with user's definition if provided*/
__attribute__((weak)) uint8_t External_18_IRQHandler(void)
{
return(0U); /*Default handler*/
}
/*Weakly linked handler. Will be replaced with user's definition if provided*/
__attribute__((weak)) uint8_t External_19_IRQHandler(void)
{
return(0U); /*Default handler*/
}
/*Weakly linked handler. Will be replaced with user's definition if provided*/
__attribute__((weak)) uint8_t External_20_IRQHandler(void)
{
return(0U); /*Default handler*/
}
/*Weakly linked handler. Will be replaced with user's definition if provided*/
__attribute__((weak)) uint8_t External_21_IRQHandler(void)
{
return(0U); /*Default handler*/
}
/*Weakly linked handler. Will be replaced with user's definition if provided*/
__attribute__((weak)) uint8_t External_22_IRQHandler(void)
{
return(0U); /*Default handler*/
}
/*Weakly linked handler. Will be replaced with user's definition if provided*/
__attribute__((weak)) uint8_t External_23_IRQHandler(void)
{
return(0U); /*Default handler*/
}
/*Weakly linked handler. Will be replaced with user's definition if provided*/
__attribute__((weak)) uint8_t External_24_IRQHandler(void)
{
return(0U); /*Default handler*/
}
/*Weakly linked handler. Will be replaced with user's definition if provided*/
__attribute__((weak)) uint8_t External_25_IRQHandler(void)
{
return(0U); /*Default handler*/
}
/*Weakly linked handler. Will be replaced with user's definition if provided*/
__attribute__((weak)) uint8_t External_26_IRQHandler(void)
{
return(0U); /*Default handler*/
}
/*Weakly linked handler. Will be replaced with user's definition if provided*/
__attribute__((weak)) uint8_t External_27_IRQHandler(void)
{
return(0U); /*Default handler*/
}
/*Weakly linked handler. Will be replaced with user's definition if provided*/
__attribute__((weak)) uint8_t External_28_IRQHandler(void)
{
return(0U); /*Default handler*/
}
/*Weakly linked handler. Will be replaced with user's definition if provided*/
__attribute__((weak)) uint8_t External_29_IRQHandler(void)
{
return(0U); /*Default handler*/
}
/*Weakly linked handler. Will be replaced with user's definition if provided*/
__attribute__((weak)) uint8_t External_30_IRQHandler(void)
{
return(0U); /*Default handler*/
}
/*Weakly linked handler. Will be replaced with user's definition if provide*/
__attribute__((weak)) uint8_t External_31_IRQHandler(void)
{
return(0U); /*Default handler*/
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,249 @@
/*******************************************************************************
* (c) Copyright 2016-2018 Microsemi SoC Products Group. All rights reserved.
*
* @file riscv_plic.h
* @author Microsemi SoC Products Group
* @brief Mi-V soft processor PLIC and PRCI access data structures and functions.
*
* SVN $Revision: 9838 $
* SVN $Date: 2018-03-19 19:22:54 +0530 (Mon, 19 Mar 2018) $
*/
#ifndef RISCV_PLIC_H
#define RISCV_PLIC_H
#include <stdint.h>
#include "encoding.h"
#ifdef __cplusplus
extern "C" {
#endif
#define PLIC_NUM_SOURCES 31
#define PLIC_NUM_PRIORITIES 0
/*==============================================================================
* Interrupt numbers:
*/
typedef enum
{
NoInterrupt_IRQn = 0,
External_1_IRQn = 1,
External_2_IRQn = 2,
External_3_IRQn = 3,
External_4_IRQn = 4,
External_5_IRQn = 5,
External_6_IRQn = 6,
External_7_IRQn = 7,
External_8_IRQn = 8,
External_9_IRQn = 9,
External_10_IRQn = 10,
External_11_IRQn = 11,
External_12_IRQn = 12,
External_13_IRQn = 13,
External_14_IRQn = 14,
External_15_IRQn = 15,
External_16_IRQn = 16,
External_17_IRQn = 17,
External_18_IRQn = 18,
External_19_IRQn = 19,
External_20_IRQn = 20,
External_21_IRQn = 21,
External_22_IRQn = 22,
External_23_IRQn = 23,
External_24_IRQn = 24,
External_25_IRQn = 25,
External_26_IRQn = 26,
External_27_IRQn = 27,
External_28_IRQn = 28,
External_29_IRQn = 29,
External_30_IRQn = 30,
External_31_IRQn = 31
} IRQn_Type;
/*==============================================================================
* PLIC: Platform Level Interrupt Controller
*/
#define PLIC_BASE_ADDR 0x40000000UL
typedef struct
{
volatile uint32_t PRIORITY_THRESHOLD;
volatile uint32_t CLAIM_COMPLETE;
volatile uint32_t reserved[1022];
} IRQ_Target_Type;
typedef struct
{
volatile uint32_t ENABLES[32];
} Target_Enables_Type;
typedef struct
{
/*-------------------- Source Priority --------------------*/
volatile uint32_t SOURCE_PRIORITY[1024];
/*-------------------- Pending array --------------------*/
volatile const uint32_t PENDING_ARRAY[32];
volatile uint32_t RESERVED1[992];
/*-------------------- Target enables --------------------*/
volatile Target_Enables_Type TARGET_ENABLES[15808];
volatile uint32_t RESERVED2[16384];
/*--- Target Priority threshold and claim/complete---------*/
IRQ_Target_Type TARGET[15872];
} PLIC_Type;
#define PLIC ((PLIC_Type *)PLIC_BASE_ADDR)
/*==============================================================================
* PRCI: Power, Reset, Clock, Interrupt
*/
#define PRCI_BASE 0x44000000UL
typedef struct
{
volatile uint32_t MSIP[4095];
volatile uint32_t reserved;
volatile uint64_t MTIMECMP[4095];
volatile const uint64_t MTIME;
} PRCI_Type;
#define PRCI ((PRCI_Type *)PRCI_BASE)
/*==============================================================================
* The function PLIC_init() initializes the PLIC controller and enables the
* global external interrupt bit.
*/
static inline void PLIC_init(void)
{
uint32_t inc;
unsigned long hart_id = read_csr(mhartid);
/* Disable all interrupts for the current hart. */
for(inc = 0; inc < ((PLIC_NUM_SOURCES + 32u) / 32u); ++inc)
{
PLIC->TARGET_ENABLES[hart_id].ENABLES[inc] = 0;
}
/* Set priorities to zero. */
/* Should this really be done??? Calling PLIC_init() on one hart will cause
* the priorities previously set by other harts to be messed up. */
for(inc = 0; inc < PLIC_NUM_SOURCES; ++inc)
{
PLIC->SOURCE_PRIORITY[inc] = 0;
}
/* Set the threshold to zero. */
PLIC->TARGET[hart_id].PRIORITY_THRESHOLD = 0;
/* Enable machine external interrupts. */
set_csr(mie, MIP_MEIP);
}
/*==============================================================================
* The function PLIC_EnableIRQ() enables the external interrupt for the interrupt
* number indicated by the parameter IRQn.
*/
static inline void PLIC_EnableIRQ(IRQn_Type IRQn)
{
unsigned long hart_id = read_csr(mhartid);
uint32_t current = PLIC->TARGET_ENABLES[hart_id].ENABLES[IRQn / 32];
current |= (uint32_t)1 << (IRQn % 32);
PLIC->TARGET_ENABLES[hart_id].ENABLES[IRQn / 32] = current;
}
/*==============================================================================
* The function PLIC_DisableIRQ() disables the external interrupt for the interrupt
* number indicated by the parameter IRQn.
* NOTE:
* This function can be used to disable the external interrupt from outside
* external interrupt handler function.
* This function MUST NOT be used from within the External Interrupt handler.
* If you wish to disable the external interrupt while the interrupt handler
* for that external interrupt is executing then you must use the return value
* EXT_IRQ_DISABLE to return from the extern interrupt handler.
*/
static inline void PLIC_DisableIRQ(IRQn_Type IRQn)
{
unsigned long hart_id = read_csr(mhartid);
uint32_t current = PLIC->TARGET_ENABLES[hart_id].ENABLES[IRQn / 32];
current &= ~((uint32_t)1 << (IRQn % 32));
PLIC->TARGET_ENABLES[hart_id].ENABLES[IRQn / 32] = current;
}
/*==============================================================================
* The function PLIC_SetPriority() sets the priority for the external interrupt
* for the interrupt number indicated by the parameter IRQn.
*/
static inline void PLIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
PLIC->SOURCE_PRIORITY[IRQn] = priority;
}
/*==============================================================================
* The function PLIC_GetPriority() returns the priority for the external interrupt
* for the interrupt number indicated by the parameter IRQn.
*/
static inline uint32_t PLIC_GetPriority(IRQn_Type IRQn)
{
return PLIC->SOURCE_PRIORITY[IRQn];
}
/*==============================================================================
* The function PLIC_ClaimIRQ() claims the interrupt from the PLIC controller.
*/
static inline uint32_t PLIC_ClaimIRQ(void)
{
unsigned long hart_id = read_csr(mhartid);
return PLIC->TARGET[hart_id].CLAIM_COMPLETE;
}
/*==============================================================================
* The function PLIC_CompleteIRQ() indicates to the PLIC controller the interrupt
* is processed and claim is complete.
*/
static inline void PLIC_CompleteIRQ(uint32_t source)
{
unsigned long hart_id = read_csr(mhartid);
PLIC->TARGET[hart_id].CLAIM_COMPLETE = source;
}
/*==============================================================================
* The function raise_soft_interrupt() raises a synchronous software interrupt by
* writing into the MSIP register.
*/
static inline void raise_soft_interrupt()
{
unsigned long hart_id = read_csr(mhartid);
/*You need to make sure that the global interrupt is enabled*/
set_csr(mie, MIP_MSIP); /*Enable software interrupt bit */
PRCI->MSIP[hart_id] = 0x01; /*raise soft interrupt for hart0*/
}
/*==============================================================================
* The function clear_soft_interrupt() clears a synchronous software interrupt by
* clearing the MSIP register.
*/
static inline void clear_soft_interrupt()
{
unsigned long hart_id = read_csr(mhartid);
PRCI->MSIP[hart_id] = 0x00; /*clear soft interrupt for hart0*/
}
#ifdef __cplusplus
}
#endif
#endif /* RISCV_PLIC_H */

View File

@ -0,0 +1,120 @@
/*******************************************************************************
* (c) Copyright 2016-2018 Microsemi Corporation. All rights reserved.
*
* Platform definitions
* Version based on requirements of RISCV-HAL
*
* SVN $Revision: 9946 $
* SVN $Date: 2018-04-30 20:26:55 +0530 (Mon, 30 Apr 2018) $
*/
/*=========================================================================*//**
@mainpage Sample file detailing how hw_platform.h should be constructed for
the Mi-V processors.
@section intro_sec Introduction
The hw_platform.h is to be located in the project root directory.
Currently this file must be hand crafted when using the Mi-V Soft Processor.
You can use this file as sample.
Rename this file from sample_hw_platform.h to hw_platform.h and store it in
the root folder of your project. Then customize it per your HW design.
@section driver_configuration Project configuration Instructions
1. Change SYS_CLK_FREQ define to frequency of Mi-V Soft processor clock
2 Add all other core BASE addresses
3. Add peripheral Core Interrupt to Mi-V Soft processor interrupt mappings
4. Define MSCC_STDIO_UART_BASE_ADDR if you want a CoreUARTapb mapped to STDIO
*//*=========================================================================*/
#ifndef HW_PLATFORM_H
#define HW_PLATFORM_H
/***************************************************************************//**
* Soft-processor clock definition
* This is the only clock brought over from the Mi-V Soft processor Libero design.
*/
#ifndef SYS_CLK_FREQ
#define SYS_CLK_FREQ 83000000UL
#endif
/***************************************************************************//**
* Non-memory Peripheral base addresses
* Format of define is:
* <corename>_<instance>_BASE_ADDR
*/
#define COREUARTAPB0_BASE_ADDR 0x70001000UL
#define COREGPIO_IN_BASE_ADDR 0x70002000UL
#define CORETIMER0_BASE_ADDR 0x70003000UL
#define CORETIMER1_BASE_ADDR 0x70004000UL
#define COREGPIO_OUT_BASE_ADDR 0x70005000UL
#define FLASH_CORE_SPI_BASE 0x70006000UL
#define CORE16550_BASE_ADDR 0x70007000UL
/***************************************************************************//**
* Peripheral Interrupts are mapped to the corresponding Mi-V Soft processor
* interrupt from the Libero design.
* There can be up to 31 external interrupts (IRQ[30:0] pins) on the Mi-V Soft
* processor.The Mi-V Soft processor external interrupts are defined in the
* riscv_plic.h
* These are of the form
* typedef enum
{
NoInterrupt_IRQn = 0,
External_1_IRQn = 1,
External_2_IRQn = 2,
.
.
.
External_31_IRQn = 31
} IRQn_Type;
The interrupt 0 on RISC-V processor is not used. The pin IRQ[0] should map to
External_1_IRQn likewise IRQ[30] should map to External_31_IRQn
* Format of define is:
* <corename>_<instance>_<core interrupt name>
*/
#define TIMER0_IRQn External_30_IRQn
#define TIMER1_IRQn External_31_IRQn
/****************************************************************************
* Baud value to achieve a 115200 baud rate with a 83MHz system clock.
* This value is calculated using the following equation:
* BAUD_VALUE = (CLOCK / (16 * BAUD_RATE)) - 1
*****************************************************************************/
#define BAUD_VALUE_115200 (SYS_CLK_FREQ / (16 * 115200)) - 1
/***************************************************************************//**
* User edit section- Edit sections below if required
*/
#ifdef MSCC_STDIO_THRU_CORE_UART_APB
/*
* A base address mapping for the STDIO printf/scanf mapping to CortUARTapb
* must be provided if it is being used
*
* e.g. #define MSCC_STDIO_UART_BASE_ADDR COREUARTAPB1_BASE_ADDR
*/
#define MSCC_STDIO_UART_BASE_ADDR COREUARTAPB0_BASE_ADDR
#ifndef MSCC_STDIO_UART_BASE_ADDR
#error MSCC_STDIO_UART_BASE_ADDR not defined- e.g. #define MSCC_STDIO_UART_BASE_ADDR COREUARTAPB1_BASE_ADDR
#endif
#ifndef MSCC_STDIO_BAUD_VALUE
/*
* The MSCC_STDIO_BAUD_VALUE define should be set in your project's settings to
* specify the baud value used by the standard output CoreUARTapb instance for
* generating the UART's baud rate if you want a different baud rate from the
* default of 115200 baud
*/
#define MSCC_STDIO_BAUD_VALUE 115200
#endif /*MSCC_STDIO_BAUD_VALUE*/
#endif /* end of MSCC_STDIO_THRU_CORE_UART_APB */
/*******************************************************************************
* End of user edit section
*/
#endif /* HW_PLATFORM_H */

View File

@ -0,0 +1,266 @@
/*******************************************************************************
* (c) Copyright 2016-2018 Microsemi SoC Products Group. All rights reserved.
*
* @file syscall.c
* @author Microsemi SoC Products Group
* @brief Stubs for system calls.
*
* SVN $Revision: 9661 $
* SVN $Date: 2018-01-15 16:13:33 +0530 (Mon, 15 Jan 2018) $
*/
#include <stdint.h>
#include <stdlib.h>
#include <stddef.h>
#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/times.h>
#include <stdio.h>
#include <string.h>
#include "encoding.h"
#ifdef MSCC_STDIO_THRU_CORE_UART_APB
#include "core_uart_apb.h"
#include "hw_platform.h"
#endif /*MSCC_STDIO_THRU_CORE_UART_APB*/
#ifdef __cplusplus
extern "C" {
#endif
#ifdef MSCC_STDIO_THRU_CORE_UART_APB
/*------------------------------------------------------------------------------
* CoreUARTapb instance data for the CoreUARTapb instance used for standard
* output.
*/
static UART_instance_t g_stdio_uart;
/*==============================================================================
* Flag used to indicate if the UART driver needs to be initialized.
*/
static int g_stdio_uart_init_done = 0;
#endif /*MSCC_STDIO_THRU_CORE_UART_APB*/
#undef errno
int errno;
char *__env[1] = { 0 };
char **environ = __env;
void write_hex(int fd, uint32_t hex)
{
uint8_t ii;
uint8_t jj;
char towrite;
uint8_t digit;
write( fd , "0x", 2 );
for (ii = 8 ; ii > 0; ii--)
{
jj = ii-1;
digit = ((hex & (0xF << (jj*4))) >> (jj*4));
towrite = digit < 0xA ? ('0' + digit) : ('A' + (digit - 0xA));
write( fd, &towrite, 1);
}
}
void _exit(int code)
{
#ifdef MSCC_STDIO_THRU_CORE_UART_APB
const char * message = "\nProgam has exited with code:";
write(STDERR_FILENO, message, strlen(message));
write_hex(STDERR_FILENO, code);
#endif
while (1);
}
void *_sbrk(ptrdiff_t incr)
{
extern char _end[];
extern char _heap_end[];
static char *curbrk = _end;
if ((curbrk + incr < _end) || (curbrk + incr > _heap_end))
{
return ((char *) - 1);
}
curbrk += incr;
return curbrk - incr;
}
int _isatty(int fd)
{
if (fd == STDOUT_FILENO || fd == STDERR_FILENO)
{
return 1;
}
errno = EBADF;
return 0;
}
static int stub(int err)
{
errno = err;
return -1;
}
int _open(const char* name, int flags, int mode)
{
return stub(ENOENT);
}
int _openat(int dirfd, const char* name, int flags, int mode)
{
return stub(ENOENT);
}
int _close(int fd)
{
return stub(EBADF);
}
int _execve(const char* name, char* const argv[], char* const env[])
{
return stub(ENOMEM);
}
int _fork()
{
return stub(EAGAIN);
}
int _fstat(int fd, struct stat *st)
{
if (isatty(fd))
{
st->st_mode = S_IFCHR;
return 0;
}
return stub(EBADF);
}
int _getpid()
{
return 1;
}
int _kill(int pid, int sig)
{
return stub(EINVAL);
}
int _link(const char *old_name, const char *new_name)
{
return stub(EMLINK);
}
off_t _lseek(int fd, off_t ptr, int dir)
{
if (_isatty(fd))
{
return 0;
}
return stub(EBADF);
}
ssize_t _read(int fd, void* ptr, size_t len)
{
#ifdef MSCC_STDIO_THRU_CORE_UART_APB
if (_isatty(fd))
{
/*--------------------------------------------------------------------------
* Initialize the UART driver if it is the first time this function is
* called.
*/
if ( !g_stdio_uart_init_done )
{
/******************************************************************************
* Baud value:
* This value is calculated using the following equation:
* BAUD_VALUE = (CLOCK / (16 * BAUD_RATE)) - 1
*****************************************************************************/
UART_init( &g_stdio_uart, MSCC_STDIO_UART_BASE_ADDR, ((SYS_CLK_FREQ/(16 * MSCC_STDIO_BAUD_VALUE))-1), (DATA_8_BITS | NO_PARITY));
g_stdio_uart_init_done = 1;
}
return UART_get_rx(&g_stdio_uart, (uint8_t*) ptr, len);
}
#endif
return stub(EBADF);
}
int _stat(const char* file, struct stat* st)
{
return stub(EACCES);
}
clock_t _times(struct tms* buf)
{
return stub(EACCES);
}
int _unlink(const char* name)
{
return stub(ENOENT);
}
int _wait(int* status)
{
return stub(ECHILD);
}
ssize_t _write(int fd, const void* ptr, size_t len)
{
#ifdef MSCC_STDIO_THRU_CORE_UART_APB
const uint8_t * current = (const uint8_t *) ptr;
size_t jj;
if (_isatty(fd))
{
/*--------------------------------------------------------------------------
* Initialize the UART driver if it is the first time this function is
* called.
*/
if ( !g_stdio_uart_init_done )
{
/******************************************************************************
* Baud value:
* This value is calculated using the following equation:
* BAUD_VALUE = (CLOCK / (16 * BAUD_RATE)) - 1
*****************************************************************************/
UART_init( &g_stdio_uart, MSCC_STDIO_UART_BASE_ADDR, ((SYS_CLK_FREQ/(16 * MSCC_STDIO_BAUD_VALUE))-1), (DATA_8_BITS | NO_PARITY));
g_stdio_uart_init_done = 1;
}
for (jj = 0; jj < len; jj++)
{
UART_send(&g_stdio_uart, current + jj, 1);
if (current[jj] == '\n')
{
UART_send(&g_stdio_uart, (const uint8_t *)"\r", 1);
}
}
return len;
}
#endif
return stub(EBADF);
}
#ifdef __cplusplus
}
#endif