mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-22 14:31:59 -04:00
Add starting point for IGLOO2 RISV-V demo project.
This commit is contained in:
parent
483f4a8c4b
commit
9119e1e0e3
125
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/.cproject
Normal file
125
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/.cproject
Normal 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=""${workspace_loc:/${ProjName}/FreeRTOS_Source/include}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/FreeRTOS_Source/portable/ThirdParty/GCC/RISC-V}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/drivers/CoreGPIO}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/drivers/Core16550}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/drivers/CoreUARTapb}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/drivers/CoreTimer}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/drivers/CoreSPI}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/hal}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/riscv_hal}""/>
|
||||||
|
</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=""${workspace_loc:/${ProjName}/riscv_hal/microsemi-riscv-ram.ld}""/>
|
||||||
|
</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=""${workspace_loc:/${ProjName}/riscv_hal/microsemi-riscv-ram.ld}""/>
|
||||||
|
</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>
|
162
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/.project
Normal file
162
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/.project
Normal 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>
|
|
@ -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 "${INPUTS}"" prefer-non-shared="true">
|
||||||
|
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
||||||
|
<language-scope id="org.eclipse.cdt.core.g++"/>
|
||||||
|
</provider>
|
||||||
|
</extension>
|
||||||
|
</configuration>
|
||||||
|
</project>
|
|
@ -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 */
|
48
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/README.md
Normal file
48
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/README.md
Normal 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)
|
||||||
|
|
|
@ -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 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="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <memoryBlockExpressionList context="Context string"/> "/>
|
||||||
|
<stringAttribute key="process_factory_id" value="org.eclipse.cdt.dsf.gdb.GdbProcessFactory"/>
|
||||||
|
</launchConfiguration>
|
|
@ -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_*/
|
|
@ -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
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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_ */
|
|
@ -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
|
@ -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 */
|
|
@ -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)
|
||||||
|
}
|
|
@ -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 );
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,206 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* (c) Copyright 2007-2015 Microsemi SoC Products Group. All rights reserved.
|
||||||
|
*
|
||||||
|
* CoreTimer public API.
|
||||||
|
*
|
||||||
|
* SVN $Revision: 7967 $
|
||||||
|
* SVN $Date: 2015-10-09 18:48:26 +0530 (Fri, 09 Oct 2015) $
|
||||||
|
*/
|
||||||
|
#ifndef CORE_TIMER_H_
|
||||||
|
#define CORE_TIMER_H_
|
||||||
|
|
||||||
|
#include "cpu_types.h"
|
||||||
|
|
||||||
|
/***************************************************************************//**
|
||||||
|
* The following definitions are used to select the CoreTimer driver operating
|
||||||
|
* mode. They allow selecting continuous or one-shot mode.
|
||||||
|
* 1. Continuous Mode
|
||||||
|
* In continuous mode the timer's counter is decremented from the load value
|
||||||
|
* until it reaches zero. The timer counter is automatically reloaded, with the
|
||||||
|
* load value, upon reaching zero. An interrupt is generated every time the
|
||||||
|
* counter reaches zero if interrupt is enabled.
|
||||||
|
* This mode is typically used to generate an interrupt at constant time
|
||||||
|
* intervals.
|
||||||
|
* 2. One-shot mode:
|
||||||
|
* In one-shot mode, the counter decrements from the load value and until it
|
||||||
|
* reaches zero. An interrupt can be generated, if enabled, when the counter
|
||||||
|
* reaches zero. The timer's counter must be reloaded to begin counting down
|
||||||
|
* again.
|
||||||
|
*/
|
||||||
|
#define TMR_CONTINUOUS_MODE 0
|
||||||
|
#define TMR_ONE_SHOT_MODE 1
|
||||||
|
|
||||||
|
/***************************************************************************//**
|
||||||
|
* The following definitions are used to configure the CoreTimer prescaler.
|
||||||
|
* The prescaler is used to divide down the clock used to decrement the
|
||||||
|
* CoreTimer counter. It can be configure to divide the clock by 2, 4, 8,
|
||||||
|
* 16, 32, 64, 128, 256, 512, or 1024.
|
||||||
|
*/
|
||||||
|
#define PRESCALER_DIV_2 0
|
||||||
|
#define PRESCALER_DIV_4 1
|
||||||
|
#define PRESCALER_DIV_8 2
|
||||||
|
#define PRESCALER_DIV_16 3
|
||||||
|
#define PRESCALER_DIV_32 4
|
||||||
|
#define PRESCALER_DIV_64 5
|
||||||
|
#define PRESCALER_DIV_128 6
|
||||||
|
#define PRESCALER_DIV_256 7
|
||||||
|
#define PRESCALER_DIV_512 8
|
||||||
|
#define PRESCALER_DIV_1024 9
|
||||||
|
|
||||||
|
/***************************************************************************//**
|
||||||
|
* There should be one instance of this structure for each instance of CoreTimer
|
||||||
|
* in your system. The function TMR_init() initializes this structure. It is
|
||||||
|
* used to identify the various CoreTimer hardware instances in your system.
|
||||||
|
* An initialized timer instance structure should be passed as first parameter to
|
||||||
|
* CoreTimer driver functions to identify which CoreTimer instance should perform
|
||||||
|
* the requested operation.
|
||||||
|
* Software using this driver should only need to create one single instance of
|
||||||
|
* this data structure for each hardware timer instance in the system.
|
||||||
|
*/
|
||||||
|
typedef struct __timer_instance_t
|
||||||
|
{
|
||||||
|
addr_t base_address;
|
||||||
|
} timer_instance_t;
|
||||||
|
|
||||||
|
/***************************************************************************//**
|
||||||
|
* The function TMR_init() initializes the data structures and sets relevant
|
||||||
|
* CoreTimer registers. This function will prepare the Timer for use in a given
|
||||||
|
* hardware/software configuration. It should be called before any other Timer
|
||||||
|
* API functions.
|
||||||
|
* The timer will not start counting down immediately after this function is
|
||||||
|
* called. It is necessary to call TMR_start() to start the timer decrementing.
|
||||||
|
* The CoreTimer interrupt is disabled as part of this function.
|
||||||
|
*
|
||||||
|
* @param this_timer Pointer to a timer_instance_t structure holding all
|
||||||
|
* relevant data associated with the target timer hardware
|
||||||
|
* instance. This pointer will be used to identify the
|
||||||
|
* target CoreTimer hardware instance in subsequent calls
|
||||||
|
* to the CoreTimer functions.
|
||||||
|
* @param address Base address in the processor's memory map of the
|
||||||
|
* registers of the CoreTimer instance being initialized.
|
||||||
|
* @param mode This parameter is used to select the operating mode of
|
||||||
|
* the timer driver. This can be either TMR_CONTINUOUS_MODE
|
||||||
|
* or TMR_ONE_SHOT_MODE.
|
||||||
|
* @param prescale This parameter is used to select the prescaler divider
|
||||||
|
* used to divide down the clock used to decrement the
|
||||||
|
* timer’s counter. This can be set using one of the
|
||||||
|
* PRESCALER_DIV_<n> definitions, where <n> is the
|
||||||
|
* divider’s value.
|
||||||
|
* @param load_value This parameter is used to set the timer’s load value
|
||||||
|
* from which the CoreTimer counter will decrement.
|
||||||
|
* In Continuous mode, this value will be used to reload
|
||||||
|
* the timer’s counter whenever it reaches zero.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
TMR_init
|
||||||
|
(
|
||||||
|
timer_instance_t * this_timer,
|
||||||
|
addr_t address,
|
||||||
|
uint8_t mode,
|
||||||
|
uint32_t prescale,
|
||||||
|
uint32_t load_value
|
||||||
|
);
|
||||||
|
|
||||||
|
/***************************************************************************//**
|
||||||
|
* The function TMR_start() enables the timer to start counting down.
|
||||||
|
* This function only needs to be called once after the timer has been
|
||||||
|
* initialized through a call to TMR_init(). It does not need to be called after
|
||||||
|
* each call to TMR_reload() when the timer is used in one-shot mode.
|
||||||
|
*
|
||||||
|
* @param this_timer Pointer to a timer_instance_t structure holding all
|
||||||
|
* relevant data associated with the target timer hardware
|
||||||
|
* instance. This pointer is used to identify the target
|
||||||
|
* CoreTimer hardware instance.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
TMR_start
|
||||||
|
(
|
||||||
|
timer_instance_t * this_timer
|
||||||
|
);
|
||||||
|
|
||||||
|
/***************************************************************************//**
|
||||||
|
* The function TMR_stop() stops the timer counting down. It can be used to
|
||||||
|
* stop interrupts from being generated when continuous mode is used and
|
||||||
|
* interrupts must be paused from being generated.
|
||||||
|
*
|
||||||
|
* @param this_timer Pointer to a timer_instance_t structure holding all
|
||||||
|
* relevant data associated with the target timer hardware
|
||||||
|
* instance. This pointer is used to identify the target
|
||||||
|
* CoreTimer hardware instance.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
TMR_stop
|
||||||
|
(
|
||||||
|
timer_instance_t * this_timer
|
||||||
|
);
|
||||||
|
|
||||||
|
/***************************************************************************//**
|
||||||
|
* The function TMR_enable_int() enables the timer interrupt. A call to this
|
||||||
|
* function will allow the interrupt signal coming out of CoreTimer to be
|
||||||
|
* asserted.
|
||||||
|
*
|
||||||
|
* @param this_timer Pointer to a timer_instance_t structure holding all
|
||||||
|
* relevant data associated with the target timer hardware
|
||||||
|
* instance. This pointer is used to identify the target
|
||||||
|
* CoreTimer hardware instance.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
TMR_enable_int
|
||||||
|
(
|
||||||
|
timer_instance_t * this_timer
|
||||||
|
);
|
||||||
|
|
||||||
|
/***************************************************************************//**
|
||||||
|
* The function TMR_clear_int() clears the timer interrupt. This function should
|
||||||
|
* be called within the interrupt handler servicing interrupts from the timer.
|
||||||
|
* Failure to clear the timer interrupt will result in the interrupt signal
|
||||||
|
* generating from CoreTimer to remain asserted. This assertion may cause the
|
||||||
|
* interrupt service routine to be continuously called, causing the system to
|
||||||
|
* lock up.
|
||||||
|
*
|
||||||
|
* @param this_timer Pointer to a timer_instance_t structure holding all
|
||||||
|
* relevant data associated with the target timer hardware
|
||||||
|
* instance. This pointer is used to identify the target
|
||||||
|
* CoreTimer hardware instance.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
TMR_clear_int
|
||||||
|
(
|
||||||
|
timer_instance_t * this_timer
|
||||||
|
);
|
||||||
|
|
||||||
|
/***************************************************************************//**
|
||||||
|
* The TMR_current_value() function returns the current value of the counter.
|
||||||
|
*
|
||||||
|
* @param this_timer Pointer to a timer_instance_t structure holding all
|
||||||
|
* relevant data associated with the target timer hardware
|
||||||
|
* instance. This pointer is used to identify the target
|
||||||
|
* CoreTimer hardware instance.
|
||||||
|
*
|
||||||
|
* @return Returns the current value of the timer counter value.
|
||||||
|
*/
|
||||||
|
uint32_t
|
||||||
|
TMR_current_value
|
||||||
|
(
|
||||||
|
timer_instance_t * this_timer
|
||||||
|
);
|
||||||
|
|
||||||
|
/***************************************************************************//**
|
||||||
|
* The TMR_reload() function is used in one-shot mode. It reloads the timer
|
||||||
|
* counter with the values passed as parameter. This will result in an interrupt
|
||||||
|
* being generated when the timer counter reaches 0 if interrupt is enabled.
|
||||||
|
*
|
||||||
|
* @param this_timer Pointer to a timer_instance_t structure holding all
|
||||||
|
* relevant data associated with the target timer hardware
|
||||||
|
* instance. This pointer is used to identify the target
|
||||||
|
* CoreTimer hardware instance.
|
||||||
|
* @param load_value This parameter sets the value from which the CoreTimer
|
||||||
|
* counter will decrement.
|
||||||
|
*/
|
||||||
|
void TMR_reload
|
||||||
|
(
|
||||||
|
timer_instance_t * this_timer,
|
||||||
|
uint32_t load_value
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif /* CORE_TIMER_H_ */
|
|
@ -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 */
|
|
@ -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
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
||||||
|
|
207
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/hal/hal.h
Normal file
207
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/hal/hal.h
Normal 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_*/
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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
|
|
@ -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 */
|
||||||
|
|
119
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/hw_platform.h
Normal file
119
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/hw_platform.h
Normal 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 */
|
||||||
|
|
||||||
|
|
136
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/main.c
Normal file
136
FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/main.c
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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*/
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
|
@ -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 */
|
||||||
|
|
|
@ -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
|
|
@ -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 */
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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
|
Loading…
Reference in a new issue