add dj_47dr_ibert vitis classic project
This commit is contained in:
@@ -0,0 +1,360 @@
|
||||
<?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="xilinx.gnu.arm.a53.exe.debug.30815160">
|
||||
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="xilinx.gnu.arm.a53.exe.debug.30815160" moduleId="org.eclipse.cdt.core.settings" name="Debug">
|
||||
|
||||
<externalSettings/>
|
||||
|
||||
<extensions>
|
||||
|
||||
<extension id="com.xilinx.sdk.managedbuilder.XELF.arm.a53" 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 artifactExtension="elf" 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="rm -rf" description="" id="xilinx.gnu.arm.a53.exe.debug.30815160" name="Debug" parent="xilinx.gnu.arm.a53.exe.debug">
|
||||
|
||||
<folderInfo id="xilinx.gnu.arm.a53.exe.debug.30815160." name="/" resourcePath="">
|
||||
|
||||
<toolChain id="xilinx.gnu.arm.a53.exe.debug.toolchain.563836801" name="Vitis ARM v8 GNU Toolchain" superClass="xilinx.gnu.arm.a53.exe.debug.toolchain">
|
||||
|
||||
<targetPlatform binaryParser="com.xilinx.sdk.managedbuilder.XELF.arm.a53" id="xilinx.arm.a53.target.gnu.base.debug.1938839932" isAbstract="false" name="Debug Platform" superClass="xilinx.arm.a53.target.gnu.base.debug"/>
|
||||
|
||||
<builder buildPath="${workspace_loc:/dj_47dr_basic}/Debug" enableAutoBuild="true" id="xilinx.gnu.arm.a53.toolchain.builder.debug.307915567" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="GNU make" parallelBuildOn="true" parallelizationNumber="optimal" superClass="xilinx.gnu.arm.a53.toolchain.builder.debug"/>
|
||||
|
||||
<tool id="xilinx.gnu.arm.a53.c.toolchain.assembler.debug.1605175182" name="ARM v8 gcc assembler" superClass="xilinx.gnu.arm.a53.c.toolchain.assembler.debug">
|
||||
|
||||
<inputType id="xilinx.gnu.assembler.input.1634623127" superClass="xilinx.gnu.assembler.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="xilinx.gnu.arm.a53.c.toolchain.compiler.debug.1960294133" name="ARM v8 gcc compiler" superClass="xilinx.gnu.arm.a53.c.toolchain.compiler.debug">
|
||||
|
||||
<option defaultValue="gnu.c.optimization.level.none" id="xilinx.gnu.compiler.option.optimization.level.959620718" name="Optimization Level" superClass="xilinx.gnu.compiler.option.optimization.level" valueType="enumerated"/>
|
||||
|
||||
<option id="xilinx.gnu.compiler.option.debugging.level.1257250070" name="Debug Level" superClass="xilinx.gnu.compiler.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.max" valueType="enumerated"/>
|
||||
|
||||
<option id="xilinx.gnu.compiler.inferred.swplatform.includes.809340997" name="Software Platform Include Path" superClass="xilinx.gnu.compiler.inferred.swplatform.includes" valueType="includePath">
|
||||
|
||||
<listOptionValue builtIn="false" value="${resolvePlatformFile:project=dj_47dr_basic,fileType=bspInclude}"/>
|
||||
|
||||
</option>
|
||||
|
||||
<option id="xilinx.gnu.compiler.inferred.swplatform.flags.460991024" name="Software Platform Inferred Flags" superClass="xilinx.gnu.compiler.inferred.swplatform.flags" value=" -D __BAREMETAL__" valueType="string"/>
|
||||
|
||||
<inputType id="xilinx.gnu.arm.a53.c.compiler.input.415482173" name="C source files" superClass="xilinx.gnu.arm.a53.c.compiler.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="xilinx.gnu.arm.a53.cxx.toolchain.compiler.debug.1173546074" name="ARM v8 g++ compiler" superClass="xilinx.gnu.arm.a53.cxx.toolchain.compiler.debug">
|
||||
|
||||
<option defaultValue="gnu.c.optimization.level.none" id="xilinx.gnu.compiler.option.optimization.level.284792166" name="Optimization Level" superClass="xilinx.gnu.compiler.option.optimization.level" valueType="enumerated"/>
|
||||
|
||||
<option id="xilinx.gnu.compiler.option.debugging.level.1867998394" name="Debug Level" superClass="xilinx.gnu.compiler.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.max" valueType="enumerated"/>
|
||||
|
||||
<option id="xilinx.gnu.compiler.inferred.swplatform.includes.727980830" name="Software Platform Include Path" superClass="xilinx.gnu.compiler.inferred.swplatform.includes" valueType="includePath">
|
||||
|
||||
<listOptionValue builtIn="false" value="${resolvePlatformFile:project=dj_47dr_basic,fileType=bspInclude}"/>
|
||||
|
||||
</option>
|
||||
|
||||
<option id="xilinx.gnu.compiler.inferred.swplatform.flags.1107022335" name="Software Platform Inferred Flags" superClass="xilinx.gnu.compiler.inferred.swplatform.flags" value=" -D __BAREMETAL__" valueType="string"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="xilinx.gnu.arm.a53.toolchain.archiver.1621273676" name="ARM v8 archiver" superClass="xilinx.gnu.arm.a53.toolchain.archiver"/>
|
||||
|
||||
<tool id="xilinx.gnu.arm.a53.c.toolchain.linker.debug.364528795" name="ARM v8 gcc linker" superClass="xilinx.gnu.arm.a53.c.toolchain.linker.debug">
|
||||
|
||||
<option id="xilinx.gnu.linker.inferred.swplatform.lpath.774358828" name="Software Platform Library Path" superClass="xilinx.gnu.linker.inferred.swplatform.lpath" valueType="libPaths">
|
||||
|
||||
<listOptionValue builtIn="false" value="${resolvePlatformFile:project=dj_47dr_basic,fileType=bspLib}"/>
|
||||
|
||||
</option>
|
||||
|
||||
<option id="xilinx.gnu.linker.inferred.swplatform.flags.1949777563" name="Software Platform Inferred Flags" superClass="xilinx.gnu.linker.inferred.swplatform.flags" valueType="libs">
|
||||
|
||||
<listOptionValue builtIn="false" value="-Wl,--start-group,-lxil,-lgcc,-lc,--end-group"/>
|
||||
|
||||
<listOptionValue builtIn="false" value="-Wl,--start-group,-lxil,-lgcc,-lc,-lmetal,--end-group"/>
|
||||
|
||||
</option>
|
||||
|
||||
<option id="xilinx.gnu.c.linker.option.lscript.1744301785" name="Linker Script" superClass="xilinx.gnu.c.linker.option.lscript" value="../src/lscript.ld" valueType="string"/>
|
||||
|
||||
<inputType id="xilinx.gnu.linker.input.229899632" superClass="xilinx.gnu.linker.input">
|
||||
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
|
||||
</inputType>
|
||||
|
||||
<inputType id="xilinx.gnu.linker.input.lscript.890081956" name="Linker Script" superClass="xilinx.gnu.linker.input.lscript"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="xilinx.gnu.arm.a53.cxx.toolchain.linker.debug.388448978" name="ARM v8 g++ linker" superClass="xilinx.gnu.arm.a53.cxx.toolchain.linker.debug">
|
||||
|
||||
<option id="xilinx.gnu.linker.inferred.swplatform.lpath.768616403" name="Software Platform Library Path" superClass="xilinx.gnu.linker.inferred.swplatform.lpath" valueType="libPaths">
|
||||
|
||||
<listOptionValue builtIn="false" value="${resolvePlatformFile:project=dj_47dr_basic,fileType=bspLib}"/>
|
||||
|
||||
</option>
|
||||
|
||||
<option id="xilinx.gnu.linker.inferred.swplatform.flags.1358855740" name="Software Platform Inferred Flags" superClass="xilinx.gnu.linker.inferred.swplatform.flags" valueType="libs">
|
||||
|
||||
<listOptionValue builtIn="false" value="-Wl,--start-group,-lxil,-lgcc,-lc,--end-group"/>
|
||||
|
||||
<listOptionValue builtIn="false" value="-Wl,--start-group,-lxil,-lgcc,-lc,-lmetal,--end-group"/>
|
||||
|
||||
</option>
|
||||
|
||||
<option id="xilinx.gnu.c.linker.option.lscript.1655760376" name="Linker Script" superClass="xilinx.gnu.c.linker.option.lscript" value="../src/lscript.ld" valueType="string"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="xilinx.gnu.arm.a53.size.debug.160170669" name="ARM v8 Print Size" superClass="xilinx.gnu.arm.a53.size.debug"/>
|
||||
|
||||
</toolChain>
|
||||
|
||||
</folderInfo>
|
||||
|
||||
<sourceEntries>
|
||||
|
||||
<entry excluding="_ide" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
|
||||
|
||||
</sourceEntries>
|
||||
|
||||
</configuration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
|
||||
<storageModule moduleId="ilg.gnuarmeclipse.managedbuild.packs"/>
|
||||
|
||||
</cconfiguration>
|
||||
|
||||
<cconfiguration id="xilinx.gnu.arm.a53.exe.release.844833279">
|
||||
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="xilinx.gnu.arm.a53.exe.release.844833279" moduleId="org.eclipse.cdt.core.settings" name="Release">
|
||||
|
||||
<externalSettings/>
|
||||
|
||||
<extensions>
|
||||
|
||||
<extension id="com.xilinx.sdk.managedbuilder.XELF.arm.a53" 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 artifactExtension="elf" 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.release" cleanCommand="rm -rf" description="" id="xilinx.gnu.arm.a53.exe.release.844833279" name="Release" parent="xilinx.gnu.arm.a53.exe.release">
|
||||
|
||||
<folderInfo id="xilinx.gnu.arm.a53.exe.release.844833279." name="/" resourcePath="">
|
||||
|
||||
<toolChain id="xilinx.gnu.arm.a53.exe.release.toolchain.2081233340" name="Vitis ARM v8 GNU Toolchain" superClass="xilinx.gnu.arm.a53.exe.release.toolchain">
|
||||
|
||||
<targetPlatform binaryParser="com.xilinx.sdk.managedbuilder.XELF.arm.a53" id="xilinx.arm.a53.target.gnu.base.release.1547035263" isAbstract="false" name="Release Platform" superClass="xilinx.arm.a53.target.gnu.base.release"/>
|
||||
|
||||
<builder buildPath="${workspace_loc:/dj_47dr_basic}/Release" enableAutoBuild="true" id="xilinx.gnu.arm.a53.toolchain.builder.release.1392236777" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="GNU make" superClass="xilinx.gnu.arm.a53.toolchain.builder.release"/>
|
||||
|
||||
<tool id="xilinx.gnu.arm.a53.c.toolchain.assembler.release.1615613593" name="ARM v8 gcc assembler" superClass="xilinx.gnu.arm.a53.c.toolchain.assembler.release">
|
||||
|
||||
<inputType id="xilinx.gnu.assembler.input.1937761839" superClass="xilinx.gnu.assembler.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="xilinx.gnu.arm.a53.c.toolchain.compiler.release.626075908" name="ARM v8 gcc compiler" superClass="xilinx.gnu.arm.a53.c.toolchain.compiler.release">
|
||||
|
||||
<option defaultValue="gnu.c.optimization.level.more" id="xilinx.gnu.compiler.option.optimization.level.1273964387" name="Optimization Level" superClass="xilinx.gnu.compiler.option.optimization.level" valueType="enumerated"/>
|
||||
|
||||
<option id="xilinx.gnu.compiler.option.debugging.level.349342249" name="Debug Level" superClass="xilinx.gnu.compiler.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.none" valueType="enumerated"/>
|
||||
|
||||
<option id="xilinx.gnu.compiler.inferred.swplatform.includes.1333542346" name="Software Platform Include Path" superClass="xilinx.gnu.compiler.inferred.swplatform.includes" valueType="includePath">
|
||||
|
||||
<listOptionValue builtIn="false" value="${resolvePlatformFile:project=dj_47dr_basic,fileType=bspInclude}"/>
|
||||
|
||||
</option>
|
||||
|
||||
<option id="xilinx.gnu.compiler.inferred.swplatform.flags.1119374604" name="Software Platform Inferred Flags" superClass="xilinx.gnu.compiler.inferred.swplatform.flags" value=" -D __BAREMETAL__" valueType="string"/>
|
||||
|
||||
<inputType id="xilinx.gnu.arm.a53.c.compiler.input.868554563" name="C source files" superClass="xilinx.gnu.arm.a53.c.compiler.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="xilinx.gnu.arm.a53.cxx.toolchain.compiler.release.1611227502" name="ARM v8 g++ compiler" superClass="xilinx.gnu.arm.a53.cxx.toolchain.compiler.release">
|
||||
|
||||
<option defaultValue="gnu.c.optimization.level.more" id="xilinx.gnu.compiler.option.optimization.level.1515899148" name="Optimization Level" superClass="xilinx.gnu.compiler.option.optimization.level" valueType="enumerated"/>
|
||||
|
||||
<option id="xilinx.gnu.compiler.option.debugging.level.1467101324" name="Debug Level" superClass="xilinx.gnu.compiler.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.none" valueType="enumerated"/>
|
||||
|
||||
<option id="xilinx.gnu.compiler.inferred.swplatform.includes.2032498034" name="Software Platform Include Path" superClass="xilinx.gnu.compiler.inferred.swplatform.includes" valueType="includePath">
|
||||
|
||||
<listOptionValue builtIn="false" value="${resolvePlatformFile:project=dj_47dr_basic,fileType=bspInclude}"/>
|
||||
|
||||
</option>
|
||||
|
||||
<option id="xilinx.gnu.compiler.inferred.swplatform.flags.843562482" name="Software Platform Inferred Flags" superClass="xilinx.gnu.compiler.inferred.swplatform.flags" value=" -D __BAREMETAL__" valueType="string"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="xilinx.gnu.arm.a53.toolchain.archiver.1594059272" name="ARM v8 archiver" superClass="xilinx.gnu.arm.a53.toolchain.archiver"/>
|
||||
|
||||
<tool id="xilinx.gnu.arm.a53.c.toolchain.linker.release.230507852" name="ARM v8 gcc linker" superClass="xilinx.gnu.arm.a53.c.toolchain.linker.release">
|
||||
|
||||
<option id="xilinx.gnu.linker.inferred.swplatform.lpath.1275652700" name="Software Platform Library Path" superClass="xilinx.gnu.linker.inferred.swplatform.lpath" valueType="libPaths">
|
||||
|
||||
<listOptionValue builtIn="false" value="${resolvePlatformFile:project=dj_47dr_basic,fileType=bspLib}"/>
|
||||
|
||||
</option>
|
||||
|
||||
<option id="xilinx.gnu.linker.inferred.swplatform.flags.494286477" name="Software Platform Inferred Flags" superClass="xilinx.gnu.linker.inferred.swplatform.flags" valueType="libs">
|
||||
|
||||
<listOptionValue builtIn="false" value="-Wl,--start-group,-lxil,-lgcc,-lc,--end-group"/>
|
||||
|
||||
<listOptionValue builtIn="false" value="-Wl,--start-group,-lxil,-lgcc,-lc,-lmetal,--end-group"/>
|
||||
|
||||
</option>
|
||||
|
||||
<option id="xilinx.gnu.c.linker.option.lscript.1226953901" name="Linker Script" superClass="xilinx.gnu.c.linker.option.lscript" value="../src/lscript.ld" valueType="string"/>
|
||||
|
||||
<inputType id="xilinx.gnu.linker.input.1333011753" superClass="xilinx.gnu.linker.input">
|
||||
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
|
||||
</inputType>
|
||||
|
||||
<inputType id="xilinx.gnu.linker.input.lscript.1901771258" name="Linker Script" superClass="xilinx.gnu.linker.input.lscript"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="xilinx.gnu.arm.a53.cxx.toolchain.linker.release.1526189423" name="ARM v8 g++ linker" superClass="xilinx.gnu.arm.a53.cxx.toolchain.linker.release">
|
||||
|
||||
<option id="xilinx.gnu.linker.inferred.swplatform.lpath.1315972755" name="Software Platform Library Path" superClass="xilinx.gnu.linker.inferred.swplatform.lpath" valueType="libPaths">
|
||||
|
||||
<listOptionValue builtIn="false" value="${resolvePlatformFile:project=dj_47dr_basic,fileType=bspLib}"/>
|
||||
|
||||
</option>
|
||||
|
||||
<option id="xilinx.gnu.linker.inferred.swplatform.flags.1978371562" name="Software Platform Inferred Flags" superClass="xilinx.gnu.linker.inferred.swplatform.flags" valueType="libs">
|
||||
|
||||
<listOptionValue builtIn="false" value="-Wl,--start-group,-lxil,-lgcc,-lc,--end-group"/>
|
||||
|
||||
<listOptionValue builtIn="false" value="-Wl,--start-group,-lxil,-lgcc,-lc,-lmetal,--end-group"/>
|
||||
|
||||
</option>
|
||||
|
||||
<option id="xilinx.gnu.c.linker.option.lscript.710141727" name="Linker Script" superClass="xilinx.gnu.c.linker.option.lscript" value="../src/lscript.ld" valueType="string"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="xilinx.gnu.arm.a53.size.release.1546736284" name="ARM v8 Print Size" superClass="xilinx.gnu.arm.a53.size.release"/>
|
||||
|
||||
</toolChain>
|
||||
|
||||
</folderInfo>
|
||||
|
||||
<sourceEntries>
|
||||
|
||||
<entry excluding="_ide" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
|
||||
|
||||
</sourceEntries>
|
||||
|
||||
</configuration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
|
||||
</cconfiguration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
|
||||
<project id="dj_47dr_basic.xilinx.gnu.arm.a53.exe.82547830" name="Vitis ARM v8 Executable" projectType="xilinx.gnu.arm.a53.exe"/>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
|
||||
<scannerConfigBuildInfo instanceId="xilinx.gnu.arm.a53.exe.release.844833279;xilinx.gnu.arm.a53.exe.release.844833279.">
|
||||
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.xilinx.managedbuilder.ui.ARMA53GCCManagedMakePerProjectProfileC"/>
|
||||
|
||||
</scannerConfigBuildInfo>
|
||||
|
||||
<scannerConfigBuildInfo instanceId="xilinx.gnu.arm.a53.exe.debug.30815160;xilinx.gnu.arm.a53.exe.debug.30815160.">
|
||||
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.xilinx.managedbuilder.ui.ARMA53GCCManagedMakePerProjectProfileC"/>
|
||||
|
||||
</scannerConfigBuildInfo>
|
||||
|
||||
<scannerConfigBuildInfo instanceId="xilinx.gnu.arm.a53.exe.release.844833279;xilinx.gnu.arm.a53.exe.release.844833279.;xilinx.gnu.arm.a53.c.toolchain.compiler.release.626075908;xilinx.gnu.arm.a53.c.compiler.input.868554563">
|
||||
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.xilinx.managedbuilder.ui.ARMA53GCCManagedMakePerProjectProfileC"/>
|
||||
|
||||
</scannerConfigBuildInfo>
|
||||
|
||||
<scannerConfigBuildInfo instanceId="xilinx.gnu.arm.a53.exe.debug.30815160;xilinx.gnu.arm.a53.exe.debug.30815160.;xilinx.gnu.arm.a53.c.toolchain.compiler.debug.1960294133;xilinx.gnu.arm.a53.c.compiler.input.415482173">
|
||||
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.xilinx.managedbuilder.ui.ARMA53GCCManagedMakePerProjectProfileC"/>
|
||||
|
||||
</scannerConfigBuildInfo>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="refreshScope" versionNumber="2">
|
||||
|
||||
<configuration configurationName="Debug">
|
||||
|
||||
<resource resourceType="PROJECT" workspacePath="/dj_47dr_basic"/>
|
||||
|
||||
</configuration>
|
||||
|
||||
<configuration configurationName="Release">
|
||||
|
||||
<resource resourceType="PROJECT" workspacePath="/dj_47dr_basic"/>
|
||||
|
||||
</configuration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
</cproject>
|
||||
@@ -0,0 +1,2 @@
|
||||
/Debug/
|
||||
/Release/
|
||||
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>dj_47dr_basic</name>
|
||||
<comment>Created by Vitis v2024.1</comment>
|
||||
<projects>
|
||||
<project>system_top</project>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>com.xilinx.sdx.sdk.core.SdkProjectNature</nature>
|
||||
<nature>org.eclipse.cdt.core.cnature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
3249361437
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="ASCII"?>
|
||||
<sdkproject:SdkProject xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sdkproject="http://www.xilinx.com/sdkproject" name="dj_47dr_basic" location="/home/josh/dj_47dr_ibert/vitis_classic/dj_47dr_basic" platform="/home/josh/Workspace/vivado/vivado_pub/projects/dj_47dr/dj_47dr_ibert/vitis_classic/system_top/export/system_top/system_top.xpfm" platformUID="xilinx:::0.0(custom)" systemProject="dj_47dr_basic_system" sysConfig="system_top" runtime="C/C++" cpu="standalone_psu_cortexa53_0" cpuInstance="psu_cortexa53_0" os="standalone" mssSignature="c6670d350bc5ad3b0c7e7d49c8d56f6d">
|
||||
<configuration name="Debug" id="xilinx.gnu.arm.a53.exe.debug.30815160">
|
||||
<configBuildOptions xsi:type="sdkproject:SdkOptions"/>
|
||||
<lastBuildOptions xsi:type="sdkproject:SdkOptions"/>
|
||||
</configuration>
|
||||
<configuration name="Release" id="xilinx.gnu.arm.a53.exe.release.844833279">
|
||||
<configBuildOptions xsi:type="sdkproject:SdkOptions"/>
|
||||
<lastBuildOptions xsi:type="sdkproject:SdkOptions"/>
|
||||
</configuration>
|
||||
<template appTemplateName="empty_application"/>
|
||||
</sdkproject:SdkProject>
|
||||
@@ -0,0 +1 @@
|
||||
Empty application. Add your own sources.
|
||||
@@ -0,0 +1,128 @@
|
||||
/***************************************************************************//**
|
||||
* @file ad9694.c
|
||||
* @brief Implementation of AD9680 Driver.
|
||||
* @author DBogdan ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2014-2016(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "ad9694.h"
|
||||
#include "../../../include/error.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief ad9694_read
|
||||
*******************************************************************************/
|
||||
int32_t ad9694_read(struct ad9694_dev *dev,
|
||||
uint16_t reg_addr,
|
||||
uint8_t *reg_data)
|
||||
{
|
||||
uint8_t tx_buf[2];
|
||||
uint8_t rx_buf[1];
|
||||
int32_t ret;
|
||||
|
||||
tx_buf[0] = 0x80 | (reg_addr >> 8);
|
||||
tx_buf[1] = reg_addr & 0xFF;
|
||||
|
||||
|
||||
ret = spi_write_and_read_3wire(dev->spi_desc,
|
||||
tx_buf, rx_buf, 2, 1);
|
||||
|
||||
*reg_data = rx_buf[0];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief ad9694_write
|
||||
*******************************************************************************/
|
||||
int32_t ad9694_write(struct ad9694_dev *dev,
|
||||
uint16_t reg_addr,
|
||||
uint8_t reg_data)
|
||||
{
|
||||
uint8_t buf[3];
|
||||
|
||||
int32_t ret;
|
||||
|
||||
buf[0] = reg_addr >> 8;
|
||||
buf[1] = reg_addr & 0xFF;
|
||||
buf[2] = reg_data;
|
||||
|
||||
ret = spi_write_and_read_3wire(dev->spi_desc,
|
||||
buf, NULL, 3, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief ad9694_init
|
||||
*******************************************************************************/
|
||||
int32_t ad9694_init(struct ad9694_dev **device,
|
||||
const struct ad9694_init_param *init_param)
|
||||
{
|
||||
int ret = SUCCESS;
|
||||
struct ad9694_dev *dev;
|
||||
|
||||
dev = (struct ad9694_dev *)malloc(sizeof(*dev));
|
||||
if (!dev)
|
||||
return FAILURE;
|
||||
|
||||
/* SPI */
|
||||
ret = spi_init(&dev->spi_desc, init_param->spi_init);
|
||||
|
||||
*device = dev;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Free the resources allocated by ad9694_setup().
|
||||
*
|
||||
* @param dev - The device structure.
|
||||
*
|
||||
* @return SUCCESS in case of success, negative error code otherwise.
|
||||
*******************************************************************************/
|
||||
int32_t ad9694_remove(struct ad9694_dev *dev)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
ret = spi_remove(dev->spi_desc);
|
||||
|
||||
free(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,231 @@
|
||||
/***************************************************************************//**
|
||||
* @file ad9694.h
|
||||
* @brief Header file of AD9694 Driver.
|
||||
* @author DBogdan ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2014-2016(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
#ifndef AD9694_H_
|
||||
#define AD9694_H_
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
#include <stdint.h>
|
||||
#include "../../../include/delay.h"
|
||||
#include "../../../include/spi.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** Macros and Constants Definitions **********************/
|
||||
/******************************************************************************/
|
||||
#define AD9694_REG_GLOBAL_MAP_SPI_CONF_A 0x0000
|
||||
#define AD9694_REG_GLOBAL_MAP_SPI_CONF_B 0x0001
|
||||
#define AD9694_REG_CH_MAP_CHIP_CONF 0x0002
|
||||
#define AD9694_REG_PAIR_MAP_CHIP_TYPE 0x0003
|
||||
#define AD9694_REG_PAIR_MAP_CHIP_ID_LSB 0x0004
|
||||
#define AD9694_REG_PAIR_MAP_CHIP_GRADE 0x0006
|
||||
#define AD9694_REG_PAIR_MAP_DEV_INDEX 0x0008
|
||||
#define AD9694_REG_GLOBAL_MAP_PAIR_INDEX 0x0009
|
||||
#define AD9694_REG_PAIR_MAP_SCRATCH_PAD 0x000A
|
||||
#define AD9694_REG_PAIR_MAP_SPI_REVISION 0x000B
|
||||
#define AD9694_REG_PAIR_MAP_VENDOR_ID_LSB 0x000C
|
||||
#define AD9694_REG_PAIR_MAP_VENDOR_ID_MSB 0x000D
|
||||
#define AD9694_REG_CH_MAP_CHIP_PD_PIN 0x003F
|
||||
#define AD9694_REG_PAIR_MAP_CHIP_PIN_CTRL_1 0x0040
|
||||
#define AD9694_REG_PAIR_MAP_CLK_DIV_CTRL 0x0108
|
||||
#define AD9694_REG_CH_MAP_CLK_DIV_PHASE 0x0109
|
||||
#define AD9694_REG_PAIR_MAP_CLK_DIV_SYSREF_CTRL 0x010A
|
||||
#define AD9694_REG_PAIR_MAP_CLK_DELAY_CTRL 0x0110
|
||||
#define AD9694_REG_CH_MAP_CLK_SUPER_FINE_DELAY 0x0111
|
||||
#define AD9694_REG_CH_MAP_CLK_FINE_DELAY 0x0112
|
||||
#define AD9694_REG_CLK_DETN_CTRL 0x011A
|
||||
#define AD9694_REG_PAIR_MAP_CLK_STAT 0x011B
|
||||
#define AD9694_REG_CLK_DCS_CTRL_1 0x011C
|
||||
#define AD9694_REG_CLK_DCS_CTRL_2 0x011E
|
||||
#define AD9694_REG_CLK_DCS_CTRL_3 0x011F
|
||||
#define AD9694_REG_PAIR_MAP_SYSREF_CTRL_1 0x0120
|
||||
#define AD9694_REG_PAIR_MAP_SYSREF_CTRL_2 0x0121
|
||||
#define AD9694_REG_PAIR_MAP_SYSREF_CTRL_4 0x0123
|
||||
#define AD9694_REG_PAIR_MAP_SYSREF_STAT_1 0x0128
|
||||
#define AD9694_REG_PAIR_MAP_SYSREF_STAT_2 0x0129
|
||||
#define AD9694_REG_PAIR_MAP_SYSREF_STAT_3 0x012A
|
||||
#define AD9694_REG_PAIR_MAP_CHIP_SYNC 0x01FF
|
||||
#define AD9694_REG_PAIR_MAP_CHIP_MODE 0x0200
|
||||
#define AD9694_REG_PAIR_MAP_CHIP_DEC_RATIO 0x0201
|
||||
#define AD9694_REG_CH_MAP_CUSTOM_OFFSET 0x0228
|
||||
#define AD9694_REG_CH_MAP_FD_CTRL 0x0245
|
||||
#define AD9694_REG_CH_MAP_FD_UT_LSB 0x0247
|
||||
#define AD9694_REG_CH_MAP_FD_UT_MSB 0x0248
|
||||
#define AD9694_REG_CH_MAP_FD_LT_LSB 0x0249
|
||||
#define AD9694_REG_CH_MAP_FD_LT_MSB 0x024A
|
||||
#define AD9694_REG_CH_MAP_FD_DWELL_TIME_LSB 0x024B
|
||||
#define AD9694_REG_CH_MAP_FD_DWELL_TIME_MSB 0x024C
|
||||
#define AD9694_REG_PAIR_MAP_SIG_MON_SYNC_CTRL 0x026F
|
||||
#define AD9694_REG_CH_MAP_SIG_MON_CTRL 0x0270
|
||||
#define AD9694_REG_CH_MAP_SIG_MON_PERIOD_0 0x0271
|
||||
#define AD9694_REG_CH_MAP_SIG_MON_PERIOD_1 0x0272
|
||||
#define AD9694_REG_CH_MAP_SIG_MON_PERIOD_2 0x0273
|
||||
#define AD9694_REG_CH_MAP_SIG_MON_STAT_CTRL 0x0274
|
||||
#define AD9694_REG_CH_MAP_SIG_MON_STAT_0 0x0275
|
||||
#define AD9694_REG_CH_MAP_SIG_MON_STAT_1 0x0276
|
||||
#define AD9694_REG_CH_MAP_SIG_MON_STAT_2 0x0277
|
||||
#define AD9694_REG_CH_MAP_SIG_MON_STAT_FRAME_CNT 0x0278
|
||||
#define AD9694_REG_CH_MAP_SIG_MON_SERIAL_FRAMER_CTRL 0x0279
|
||||
#define AD9694_REG_SPORT_OVER_JESD204B_INPUT_SEL 0x027A
|
||||
#define AD9694_REG_PAIR_MAP_DDC_SYNC_CTRL 0x0300
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_CTRL 0x0310
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_INPUT_SEL 0x0311
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_INC_0 0x0314
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_INC_1 0x0315
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_INC_2 0x0316
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_INC_3 0x0317
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_INC_4 0x0318
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_INC_5 0x031A
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_OFFSET_0 0x031D
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_OFFSET_1 0x031E
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_OFFSET_2 0x031F
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_OFFSET_3 0x0320
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_OFFSET_4 0x0321
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_OFFSET_5 0x0322
|
||||
#define AD9694_REG_PAIR_MAP_DDC_0_TEST_ENABLE 0x0327
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_CTRL 0x0330
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_INPUT_SEL 0x0331
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_INC_0 0x0334
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_INC_1 0x0335
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_INC_2 0x0336
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_INC_3 0x0337
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_INC_4 0x0338
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_INC_5 0x033A
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_OFFSET_0 0x033D
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_OFFSET_1 0x033E
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_OFFSET_2 0x033F
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_OFFSET_3 0x0340
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_OFFSET_4 0x0341
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_OFFSET_5 0x0342
|
||||
#define AD9694_REG_PAIR_MAP_DDC_1_TEST_ENABLE 0x0347
|
||||
#define AD9694_REG_CH_MAP_TEST_MODE_CTRL 0x0550
|
||||
#define AD9694_REG_PAIR_MAP_USER_PATTERN_1_LSB 0x0551
|
||||
#define AD9694_REG_PAIR_MAP_USER_PATTERN_1_MSB 0x0552
|
||||
#define AD9694_REG_PAIR_MAP_USER_PATTERN_2_LSB 0x0553
|
||||
#define AD9694_REG_PAIR_MAP_USER_PATTERN_2_MSB 0x0554
|
||||
#define AD9694_REG_PAIR_MAP_USER_PATTERN_3_LSB 0x0555
|
||||
#define AD9694_REG_PAIR_MAP_USER_PATTERN_3_MSB 0x0556
|
||||
#define AD9694_REG_PAIR_MAP_USER_PATTERN_4_LSB 0x0557
|
||||
#define AD9694_REG_PAIR_MAP_USER_PATTERN_4_MSB 0x0558
|
||||
#define AD9694_REG_PAIR_MAP_OUTPUT_CTRL_MODE_0 0x0559
|
||||
#define AD9694_REG_PAIR_MAP_OUTPUT_CTRL_MODE_1 0x055A
|
||||
#define AD9694_REG_PAIR_MAP_OUTPUT_SAMPLE_MODE 0x0561
|
||||
#define AD9694_REG_PAIR_MAP_OUTPUT_CH_SEL 0x0564
|
||||
#define AD9694_REG_JESD204B_MAP_PLL_CTRL 0x056E
|
||||
#define AD9694_REG_JESD204B_MAP_PLL_STAT 0x056F
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_QUICK_CONF 0x0570
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_LINK_CTRL_1 0x0571
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_LINK_CTRL_2 0x0572
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_LINK_CTRL_3 0x0573
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_LINK_CTRL_4 0x0574
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_LMFC_OFFSET 0x0578
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_DID_CONF 0x0580
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_BID_CONF 0x0581
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_LID_0_CONF 0x0583
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_LID_1_CONF 0x0585
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_SCR_L_CONF 0x058B
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_F_CONF 0x058C
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_K_CONF 0x058D
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_M_CONF 0x058E
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_CS_N_CONF 0x058F
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_SUBCLASS_CONF 0x0590
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_S_CONF 0x0591
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_HD_CF_CONF 0x0592
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_CHECKSUM_0_CONF 0x05A0
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_CHECKSUM_1_CONF 0x05A1
|
||||
#define AD9694_REG_SERDOUTX0_SERDOUTX1_LANE_PD 0x05B0
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_LANE_ASSIGN_1 0x05B2
|
||||
#define AD9694_REG_JESD204B_MAP_JTX_LANE_ASSIGN_2 0x05B3
|
||||
#define AD9694_REG_JESD204B_MAP_SERD_ADJUST_0 0x05C0
|
||||
#define AD9694_REG_JESD204B_MAP_SERD_ADJUST_1 0x05C1
|
||||
#define AD9694_REG_JESD204B_SER_PE_SEL_LANE_0 0x05C4
|
||||
#define AD9694_REG_JESD204B_SER_PE_SEL_LANE_1 0x05C6
|
||||
#define AD9694_REG_LARGE_DITHER_CTRL 0x0922
|
||||
#define AD9694_REG_PLL_CAL 0x1222
|
||||
#define AD9694_REG_JESD204B_STARTUP_CIRCUIT_RST 0x1228
|
||||
#define AD9694_REG_PLL_LOSS_OF_LOCK_CTRL 0x1262
|
||||
#define AD9694_REG_DC_OFFSET_CAL_CTRL 0x0701
|
||||
#define AD9694_REG_DC_OFFSET_CAL_CTRL_2 0x073B
|
||||
#define AD9694_REG_PAIR_MAP_VREF_CTRL 0x18A6
|
||||
#define AD9694_REG_EXT_VCM_BUF_CTRL_1 0x18E0
|
||||
#define AD9694_REG_EXT_VCM_BUF_CTRL_2 0x18E1
|
||||
#define AD9694_REG_EXT_VCM_BUF_CTRL_3 0x18E2
|
||||
#define AD9694_REG_EXT_VCM_BUF_CTRL 0x18E3
|
||||
#define AD9694_REG_TEMP_DIODE_EXPORT 0x18E6
|
||||
#define AD9694_REG_CH_MAP_ANALOG_INPUT_CTRL 0x1908
|
||||
#define AD9694_REG_CH_MAP_INPUT_FULLSCALE_RANGE 0x1910
|
||||
#define AD9694_REG_CH_MAP_BUF_CTRL_1 0x1A4C
|
||||
#define AD9694_REG_CH_MAP_BUF_CTRL_2 0x1A4D
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
struct ad9694_dev {
|
||||
/* SPI */
|
||||
spi_desc *spi_desc;
|
||||
};
|
||||
|
||||
struct ad9694_init_param {
|
||||
/* SPI */
|
||||
spi_init_param *spi_init;
|
||||
};
|
||||
|
||||
struct ad9694_config {
|
||||
uint16_t addr;
|
||||
uint8_t value;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Declarations ******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
int32_t ad9694_read(struct ad9694_dev *dev,
|
||||
uint16_t reg_addr,
|
||||
uint8_t *reg_data);
|
||||
|
||||
int32_t ad9694_write(struct ad9694_dev *dev,
|
||||
uint16_t reg_addr,
|
||||
uint8_t reg_data);
|
||||
|
||||
int32_t ad9694_init(struct ad9694_dev **device,
|
||||
const struct ad9694_init_param *init_param);
|
||||
|
||||
int32_t ad9694_remove(struct ad9694_dev *dev);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,184 @@
|
||||
/***************************************************************************//**
|
||||
* @file gpio.c
|
||||
* @brief Implementation of the GPIO Interface
|
||||
* @author Antoniu Miclaus ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2020(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
#include "../../include/gpio.h"
|
||||
#include "../../include/error.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Definitions *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Obtain the GPIO decriptor.
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @param param - GPIO Initialization parameters.
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t gpio_get(struct gpio_desc **desc,
|
||||
const struct gpio_init_param *param)
|
||||
{
|
||||
if (!param)
|
||||
return FAILURE;
|
||||
|
||||
if ((param->platform_ops->gpio_ops_get(desc, param)))
|
||||
return FAILURE;
|
||||
|
||||
(*desc)->platform_ops = param->platform_ops;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the value of an optional GPIO.
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @param param - GPIO Initialization parameters.
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t gpio_get_optional(struct gpio_desc **desc,
|
||||
const struct gpio_init_param *param)
|
||||
{
|
||||
if (!param || (param->number == -1)) {
|
||||
*desc = NULL;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
if ((param->platform_ops->gpio_ops_get_optional(desc, param)))
|
||||
return FAILURE;
|
||||
|
||||
(*desc)->platform_ops = param->platform_ops;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/**
|
||||
* @brief Free the resources allocated by gpio_get().
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t gpio_remove(struct gpio_desc *desc)
|
||||
{
|
||||
if (desc)
|
||||
return desc->platform_ops->gpio_ops_remove(desc);
|
||||
else
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the input direction of the specified GPIO.
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t gpio_direction_input(struct gpio_desc *desc)
|
||||
{
|
||||
if (desc)
|
||||
return desc->platform_ops->gpio_ops_direction_input(desc);
|
||||
else
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the output direction of the specified GPIO.
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @param value - The value.
|
||||
* Example: GPIO_HIGH
|
||||
* GPIO_LOW
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t gpio_direction_output(struct gpio_desc *desc,
|
||||
uint8_t value)
|
||||
{
|
||||
if (desc)
|
||||
return desc->platform_ops->
|
||||
gpio_ops_direction_output(desc, value);
|
||||
else
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the direction of the specified GPIO.
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @param direction - The direction.
|
||||
* Example: GPIO_OUT
|
||||
* GPIO_IN
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t gpio_get_direction(struct gpio_desc *desc,
|
||||
uint8_t *direction)
|
||||
{
|
||||
if (desc)
|
||||
return desc->platform_ops->
|
||||
gpio_ops_get_direction(desc, direction);
|
||||
else
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the value of the specified GPIO.
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @param value - The value.
|
||||
* Example: GPIO_HIGH
|
||||
* GPIO_LOW
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t gpio_set_value(struct gpio_desc *desc,
|
||||
uint8_t value)
|
||||
{
|
||||
if (desc)
|
||||
return desc->platform_ops->gpio_ops_set_value(desc, value);
|
||||
else
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the value of the specified GPIO.
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @param value - The value.
|
||||
* Example: GPIO_HIGH
|
||||
* GPIO_LOW
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t gpio_get_value(struct gpio_desc *desc,
|
||||
uint8_t *value)
|
||||
{
|
||||
if (desc)
|
||||
return desc->platform_ops->gpio_ops_get_value(desc, value);
|
||||
else
|
||||
return SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
/***************************************************************************//**
|
||||
* @file irq.c
|
||||
* @brief Implementation of the IRQ Interface
|
||||
* @author Andrei Porumb ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2021(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
#include "../../include/irq.h"
|
||||
#include "../../include/error.h"
|
||||
|
||||
/**
|
||||
* @brief Initialize the IRQ interrupts.
|
||||
* @param desc - The IRQ descriptor.
|
||||
* @param param - The structure that contains the IRQ parameters.
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t irq_ctrl_init(struct irq_ctrl_desc **desc,
|
||||
const struct irq_init_param *param)
|
||||
{
|
||||
if (!param)
|
||||
return FAILURE;
|
||||
|
||||
if ((param->platform_ops->init(desc, param)))
|
||||
return FAILURE;
|
||||
|
||||
(*desc)->platform_ops = param->platform_ops;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free the resources allocated by irq_ctrl_init().
|
||||
* @param desc - The SPI descriptor.
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t irq_ctrl_remove(struct irq_ctrl_desc *desc)
|
||||
{
|
||||
return desc->platform_ops->remove(desc);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Register a callback to handle the irq events.
|
||||
* @param desc - The IRQ controller descriptor.
|
||||
* @param irq_id - Interrupt identifier.
|
||||
* @param callback_desc - Callback descriptor
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t irq_register_callback(struct irq_ctrl_desc *desc, uint32_t irq_id,
|
||||
struct callback_desc *callback_desc)
|
||||
{
|
||||
return desc->platform_ops->register_callback(desc, irq_id, callback_desc);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unregisters a generic IRQ handling function.
|
||||
* @param desc - The IRQ controller descriptor.
|
||||
* @param irq_id - Interrupt identifier.
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t irq_unregister(struct irq_ctrl_desc *desc, uint32_t irq_id)
|
||||
{
|
||||
return desc->platform_ops->unregister(desc, irq_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable global interrupts.
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t irq_global_enable(struct irq_ctrl_desc *desc)
|
||||
{
|
||||
return desc->platform_ops->global_enable(desc);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable global interrupts.
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t irq_global_disable(struct irq_ctrl_desc *desc)
|
||||
{
|
||||
return desc->platform_ops->global_disable(desc);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set interrupt trigger level.
|
||||
* @param desc - The IRQ controller descriptor.
|
||||
* @param irq_id - Interrupt identifier.
|
||||
* @param trig - New trigger level for the interrupt.
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t irq_trigger_level_set(struct irq_ctrl_desc *desc, uint32_t irq_id,
|
||||
enum irq_trig_level trig)
|
||||
{
|
||||
if(desc->platform_ops->trigger_level_set)
|
||||
return desc->platform_ops->trigger_level_set(desc, irq_id, trig);
|
||||
else
|
||||
return ENOSYS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable specific interrupt.
|
||||
* @param desc - The IRQ controller descriptor.
|
||||
* @param irq_id - Interrupt identifier.
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t irq_enable(struct irq_ctrl_desc *desc, uint32_t irq_id)
|
||||
{
|
||||
return desc->platform_ops->enable(desc, irq_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable specific interrupt.
|
||||
* @param desc - The IRQ controller descriptor.
|
||||
* @param irq_id - Interrupt identifier.
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t irq_disable(struct irq_ctrl_desc *desc, uint32_t irq_id)
|
||||
{
|
||||
return desc->platform_ops->disable(desc, irq_id);
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
/***************************************************************************//**
|
||||
* @file spi.c
|
||||
* @brief Implementation of the SPI Interface
|
||||
* @author Antoniu Miclaus ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2020(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "../../include/spi.h"
|
||||
#include "../../include/error.h"
|
||||
|
||||
/**
|
||||
* @brief Initialize the SPI communication peripheral.
|
||||
* @param desc - The SPI descriptor.
|
||||
* @param param - The structure that contains the SPI parameters.
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t spi_init(struct spi_desc **desc,
|
||||
const struct spi_init_param *param)
|
||||
{
|
||||
if (!param)
|
||||
return FAILURE;
|
||||
|
||||
if ((param->platform_ops->init(desc, param)))
|
||||
return FAILURE;
|
||||
|
||||
(*desc)->platform_ops = param->platform_ops;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free the resources allocated by spi_init().
|
||||
* @param desc - The SPI descriptor.
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t spi_remove(struct spi_desc *desc)
|
||||
{
|
||||
return desc->platform_ops->remove(desc);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write and read data to/from SPI.
|
||||
* @param desc - The SPI descriptor.
|
||||
* @param data - The buffer with the transmitted/received data.
|
||||
* @param bytes_number - Number of bytes to write/read.
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t spi_write_and_read(struct spi_desc *desc,
|
||||
uint8_t *data,
|
||||
uint16_t bytes_number)
|
||||
{
|
||||
return desc->platform_ops->write_and_read(desc, data, bytes_number);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write and read data to/from SPI in 3 wire mode.
|
||||
* @param desc - The SPI descriptor.
|
||||
* @param write_data - The buffer with the transmitted data.
|
||||
* @param read_data - The buffer with the received data.
|
||||
* @param write_bytes_number - Number of bytes to write.
|
||||
* @param read_bytes_number - Number of bytes to read.
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t spi_write_and_read_3wire(struct spi_desc *desc,
|
||||
uint8_t *write_data,
|
||||
uint8_t *read_data,
|
||||
uint16_t write_bytes_number,
|
||||
uint16_t read_bytes_number)
|
||||
{
|
||||
int ret;
|
||||
if(desc->platform_ops->write_and_read_3wire != NULL){
|
||||
return desc->platform_ops->write_and_read_3wire(desc, write_data, read_data,
|
||||
write_bytes_number, read_bytes_number);
|
||||
}
|
||||
else{
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Iterate over head list and send all spi messages
|
||||
* @param desc - The SPI descriptor.
|
||||
* @param msgs - Array of messages.
|
||||
* @param len - Number of messages in the array.
|
||||
* @return SUCCESS in case of success, negativ error code otherwise.
|
||||
*/
|
||||
int32_t spi_transfer(struct spi_desc *desc, struct spi_msg *msgs, uint32_t len)
|
||||
{
|
||||
int32_t ret;
|
||||
uint32_t i;
|
||||
|
||||
if (!desc || !desc->platform_ops)
|
||||
return -EINVAL;
|
||||
|
||||
if (desc->platform_ops->transfer)
|
||||
return desc->platform_ops->transfer(desc, msgs, len);
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (msgs[i].rx_buff != msgs[i].tx_buff || !msgs[i].tx_buff)
|
||||
return -EINVAL;
|
||||
ret = spi_write_and_read(desc, msgs[i].rx_buff,
|
||||
msgs[i].bytes_number);
|
||||
if (IS_ERR_VALUE(ret))
|
||||
return ret;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
+328
@@ -0,0 +1,328 @@
|
||||
/***************************************************************************//**
|
||||
* @file axi_dmac.c
|
||||
* @brief Driver for the Analog Devices AXI-DMAC core.
|
||||
* @author DBogdan ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2018(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "../../../include/axi_io.h"
|
||||
#include "../../../include/error.h"
|
||||
#include "../axi_dmac/axi_dmac.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief dma_isr
|
||||
*******************************************************************************/
|
||||
void axi_dmac_default_isr(void *instance)
|
||||
{
|
||||
struct axi_dmac *dmac = (struct axi_dmac *)instance;
|
||||
uint32_t remaining_size, burst_size;
|
||||
uint32_t reg_val;
|
||||
|
||||
/* Get interrupt sources and clear interrupts. */
|
||||
axi_dmac_read(dmac, AXI_DMAC_REG_IRQ_PENDING, ®_val);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_IRQ_PENDING, reg_val);
|
||||
|
||||
if ((reg_val & AXI_DMAC_IRQ_SOT) && (dmac->big_transfer.size != 0)) {
|
||||
remaining_size = dmac->big_transfer.size -
|
||||
dmac->big_transfer.size_done;
|
||||
burst_size = (remaining_size <= dmac->transfer_max_size) ?
|
||||
remaining_size : dmac->transfer_max_size;
|
||||
|
||||
dmac->big_transfer.size_done += burst_size;
|
||||
dmac->big_transfer.address += burst_size;
|
||||
switch (dmac->direction) {
|
||||
case DMA_DEV_TO_MEM:
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_DEST_ADDRESS,
|
||||
dmac->big_transfer.address);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_DEST_STRIDE, 0x0);
|
||||
break;
|
||||
case DMA_MEM_TO_DEV:
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_SRC_ADDRESS,
|
||||
dmac->big_transfer.address);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_SRC_STRIDE, 0x0);
|
||||
break;
|
||||
default:
|
||||
return; // Other directions are not supported yet
|
||||
}
|
||||
/* The current transfer was started and a new one is queued. */
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_X_LENGTH,
|
||||
burst_size);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_Y_LENGTH, 0x0);
|
||||
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_START_TRANSFER, 0x1);
|
||||
}
|
||||
if (reg_val & AXI_DMAC_IRQ_EOT) {
|
||||
dmac->big_transfer.transfer_done = true;
|
||||
dmac->big_transfer.address = 0;
|
||||
dmac->big_transfer.size = 0;
|
||||
dmac->big_transfer.size_done = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief axi_dmac_read
|
||||
*******************************************************************************/
|
||||
int32_t axi_dmac_read(struct axi_dmac *dmac,
|
||||
uint32_t reg_addr,
|
||||
uint32_t *reg_data)
|
||||
{
|
||||
axi_io_read(dmac->base, reg_addr, reg_data);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief axi_dmac_write
|
||||
*******************************************************************************/
|
||||
int32_t axi_dmac_write(struct axi_dmac *dmac,
|
||||
uint32_t reg_addr,
|
||||
uint32_t reg_data)
|
||||
{
|
||||
axi_io_write(dmac->base, reg_addr, reg_data);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief axi_dmac_transfer_nonblock
|
||||
*******************************************************************************/
|
||||
int32_t axi_dmac_transfer_nonblocking(struct axi_dmac *dmac,
|
||||
uint32_t address, uint32_t size)
|
||||
{
|
||||
uint32_t reg_val;
|
||||
|
||||
if (size == 0)
|
||||
return SUCCESS; /* nothing to do */
|
||||
|
||||
axi_dmac_read(dmac, AXI_DMAC_REG_CTRL, ®_val);
|
||||
if (!(reg_val & AXI_DMAC_CTRL_ENABLE)) {
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_CTRL, 0x0);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_CTRL, AXI_DMAC_CTRL_ENABLE);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_IRQ_MASK, 0x0);
|
||||
}
|
||||
|
||||
axi_dmac_read(dmac, AXI_DMAC_REG_START_TRANSFER, ®_val);
|
||||
if (!(reg_val & 1)) {
|
||||
switch (dmac->direction) {
|
||||
case DMA_DEV_TO_MEM:
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_DEST_ADDRESS, address);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_DEST_STRIDE, 0x0);
|
||||
break;
|
||||
case DMA_MEM_TO_DEV:
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_SRC_ADDRESS, address);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_SRC_STRIDE, 0x0);
|
||||
break;
|
||||
default:
|
||||
return FAILURE; // Other directions are not supported yet
|
||||
}
|
||||
if ((size - 1) > dmac->transfer_max_size) {
|
||||
dmac->big_transfer.address = address;
|
||||
dmac->big_transfer.size = size - 1;
|
||||
dmac->big_transfer.size_done = dmac->transfer_max_size;
|
||||
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_X_LENGTH,
|
||||
dmac->transfer_max_size);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_Y_LENGTH, 0x0);
|
||||
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_FLAGS, dmac->flags);
|
||||
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_START_TRANSFER, 0x1);
|
||||
} else {
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_X_LENGTH,
|
||||
size - 1);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_Y_LENGTH, 0x0);
|
||||
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_FLAGS, dmac->flags);
|
||||
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_START_TRANSFER, 0x1);
|
||||
}
|
||||
} else {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief axi_dmac_is_transfer_ready
|
||||
*******************************************************************************/
|
||||
int32_t axi_dmac_is_transfer_ready(struct axi_dmac *dmac, bool *rdy)
|
||||
{
|
||||
*rdy = dmac->big_transfer.transfer_done;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief axi_dmac_transfer
|
||||
*******************************************************************************/
|
||||
int32_t axi_dmac_transfer(struct axi_dmac *dmac,
|
||||
uint32_t address, uint32_t size)
|
||||
{
|
||||
uint32_t transfer_id;
|
||||
uint32_t reg_val;
|
||||
uint32_t timeout = 0;
|
||||
|
||||
if (size == 0)
|
||||
return SUCCESS; /* nothing to do */
|
||||
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_CTRL, 0x0);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_CTRL, AXI_DMAC_CTRL_ENABLE);
|
||||
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_IRQ_MASK, 0x0);
|
||||
|
||||
axi_dmac_read(dmac, AXI_DMAC_REG_TRANSFER_ID, &transfer_id);
|
||||
axi_dmac_read(dmac, AXI_DMAC_REG_IRQ_PENDING, ®_val);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_IRQ_PENDING, reg_val);
|
||||
|
||||
switch (dmac->direction) {
|
||||
case DMA_DEV_TO_MEM:
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_DEST_ADDRESS, address);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_DEST_STRIDE, 0x0);
|
||||
break;
|
||||
case DMA_MEM_TO_DEV:
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_SRC_ADDRESS, address);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_SRC_STRIDE, 0x0);
|
||||
break;
|
||||
default:
|
||||
return FAILURE; // Other directions are not supported yet
|
||||
}
|
||||
|
||||
if ((size - 1) > dmac->transfer_max_size) {
|
||||
dmac->big_transfer.address = address;
|
||||
dmac->big_transfer.size = size - 1;
|
||||
dmac->big_transfer.size_done = dmac->transfer_max_size;
|
||||
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_X_LENGTH,
|
||||
dmac->transfer_max_size);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_Y_LENGTH, 0x0);
|
||||
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_FLAGS, dmac->flags);
|
||||
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_START_TRANSFER, 0x1);
|
||||
|
||||
while(!dmac->big_transfer.transfer_done) {
|
||||
timeout++;
|
||||
if (timeout == UINT32_MAX)
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
dmac->big_transfer.address = 0;
|
||||
dmac->big_transfer.size = 0;
|
||||
dmac->big_transfer.size_done = 0;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_X_LENGTH, size - 1);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_Y_LENGTH, 0x0);
|
||||
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_FLAGS, dmac->flags);
|
||||
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_START_TRANSFER, 0x1);
|
||||
|
||||
if (dmac->flags & DMA_CYCLIC)
|
||||
return SUCCESS;
|
||||
|
||||
/* Wait until the new transfer is queued. */
|
||||
do {
|
||||
axi_dmac_read(dmac, AXI_DMAC_REG_START_TRANSFER, ®_val);
|
||||
} while(reg_val == 1);
|
||||
|
||||
/* Wait until the current transfer is completed. */
|
||||
do {
|
||||
axi_dmac_read(dmac, AXI_DMAC_REG_IRQ_PENDING, ®_val);
|
||||
if (reg_val == (AXI_DMAC_IRQ_SOT | AXI_DMAC_IRQ_EOT))
|
||||
break;
|
||||
} while(!dmac->big_transfer.transfer_done);
|
||||
if (reg_val != (AXI_DMAC_IRQ_SOT | AXI_DMAC_IRQ_EOT))
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_IRQ_PENDING, reg_val);
|
||||
|
||||
/* Wait until the transfer with the ID transfer_id is completed. */
|
||||
do {
|
||||
axi_dmac_read(dmac, AXI_DMAC_REG_TRANSFER_DONE, ®_val);
|
||||
} while((reg_val & (1u << transfer_id)) != (1u << transfer_id));
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief axi_dmac_init
|
||||
*******************************************************************************/
|
||||
int32_t axi_dmac_init(struct axi_dmac **dmac_core,
|
||||
const struct axi_dmac_init *init)
|
||||
{
|
||||
struct axi_dmac *dmac;
|
||||
|
||||
dmac = (struct axi_dmac *)malloc(sizeof(*dmac));
|
||||
if (!dmac)
|
||||
return FAILURE;
|
||||
|
||||
dmac->name = init->name;
|
||||
dmac->base = init->base;
|
||||
dmac->direction = init->direction;
|
||||
dmac->flags = init->flags;
|
||||
dmac->transfer_max_size = -1;
|
||||
dmac->big_transfer.address = 0;
|
||||
dmac->big_transfer.size = 0;
|
||||
dmac->big_transfer.size_done = 0;
|
||||
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_X_LENGTH, dmac->transfer_max_size);
|
||||
axi_dmac_read(dmac, AXI_DMAC_REG_X_LENGTH, &dmac->transfer_max_size);
|
||||
|
||||
*dmac_core = dmac;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief axi_dmac_remove
|
||||
*******************************************************************************/
|
||||
int32_t axi_dmac_remove(struct axi_dmac *dmac)
|
||||
{
|
||||
if(!dmac)
|
||||
return FAILURE;
|
||||
|
||||
free(dmac);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
/***************************************************************************//**
|
||||
* @file axi_dmac.h
|
||||
* @brief Driver for the Analog Devices AXI-DMAC core.
|
||||
* @author DBogdan ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2018(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
#ifndef AXI_DMAC_H_
|
||||
#define AXI_DMAC_H_
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
#include <stdint.h>
|
||||
#include "../../../include/util.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** Macros and Constants Definitions **********************/
|
||||
/******************************************************************************/
|
||||
#define AXI_DMAC_REG_IRQ_MASK 0x80
|
||||
#define AXI_DMAC_REG_IRQ_PENDING 0x84
|
||||
#define AXI_DMAC_IRQ_SOT BIT(0)
|
||||
#define AXI_DMAC_IRQ_EOT BIT(1)
|
||||
|
||||
#define AXI_DMAC_REG_CTRL 0x400
|
||||
#define AXI_DMAC_CTRL_ENABLE BIT(0)
|
||||
#define AXI_DMAC_CTRL_PAUSE BIT(1)
|
||||
|
||||
#define AXI_DMAC_REG_TRANSFER_ID 0x404
|
||||
#define AXI_DMAC_REG_START_TRANSFER 0x408
|
||||
#define AXI_DMAC_REG_FLAGS 0x40c
|
||||
#define AXI_DMAC_REG_DEST_ADDRESS 0x410
|
||||
#define AXI_DMAC_REG_SRC_ADDRESS 0x414
|
||||
#define AXI_DMAC_REG_X_LENGTH 0x418
|
||||
#define AXI_DMAC_REG_Y_LENGTH 0x41c
|
||||
#define AXI_DMAC_REG_DEST_STRIDE 0x420
|
||||
#define AXI_DMAC_REG_SRC_STRIDE 0x424
|
||||
#define AXI_DMAC_REG_TRANSFER_DONE 0x428
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
enum dma_direction {
|
||||
DMA_DEV_TO_MEM,
|
||||
DMA_MEM_TO_DEV
|
||||
};
|
||||
|
||||
enum dma_flags {
|
||||
DMA_CYCLIC = 1,
|
||||
DMA_LAST = 2
|
||||
};
|
||||
|
||||
struct axi_dma_transfer {
|
||||
uint32_t size;
|
||||
uint32_t address;
|
||||
uint32_t size_done;
|
||||
volatile bool transfer_done;
|
||||
};
|
||||
|
||||
struct axi_dmac {
|
||||
const char *name;
|
||||
uint32_t base;
|
||||
enum dma_direction direction;
|
||||
uint32_t flags;
|
||||
uint32_t transfer_max_size;
|
||||
volatile struct axi_dma_transfer big_transfer;
|
||||
};
|
||||
|
||||
struct axi_dmac_init {
|
||||
const char *name;
|
||||
uint32_t base;
|
||||
enum dma_direction direction;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Declarations ******************************/
|
||||
/******************************************************************************/
|
||||
void axi_dmac_default_isr(void *instance);
|
||||
int32_t axi_dmac_read(struct axi_dmac *dmac, uint32_t reg_addr,
|
||||
uint32_t *reg_data);
|
||||
int32_t axi_dmac_write(struct axi_dmac *dmac, uint32_t reg_addr,
|
||||
uint32_t reg_data);
|
||||
int32_t axi_dmac_transfer_nonblocking(struct axi_dmac *dmac,
|
||||
uint32_t address, uint32_t size);
|
||||
int32_t axi_dmac_is_transfer_ready(struct axi_dmac *dmac, bool *rdy);
|
||||
int32_t axi_dmac_transfer(struct axi_dmac *dmac,
|
||||
uint32_t address, uint32_t size);
|
||||
int32_t axi_dmac_init(struct axi_dmac **adc_core,
|
||||
const struct axi_dmac_init *init);
|
||||
int32_t axi_dmac_remove(struct axi_dmac *dmac);
|
||||
|
||||
#endif
|
||||
+978
@@ -0,0 +1,978 @@
|
||||
/*******************************************************************************
|
||||
* @file spi_engine.c
|
||||
* @brief Core implementation of the SPI Engine Driver.
|
||||
* @author Sergiu Cuciurean ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2019(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/* In debug mode the printf function used in displaying the messages is causing
|
||||
significant delays */
|
||||
//#define DEBUG_LEVEL 2
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sleep.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "spi_engine.h"
|
||||
#include "../axi_dmac/axi_dmac.h"
|
||||
#include "../../../include/axi_io.h"
|
||||
#include "../../../include/error.h"
|
||||
|
||||
/**
|
||||
* @brief Spi engine platform specific SPI platform ops structure
|
||||
*/
|
||||
const struct spi_platform_ops spi_eng_platform_ops = {
|
||||
.init = &spi_engine_init,
|
||||
.write_and_read = &spi_engine_spi_write_and_read,
|
||||
.write_and_read_3wire = &spi_engine_spi_write_and_read_3wire,
|
||||
.remove = &spi_engine_remove
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Static variables *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Static variable used to sync transfers
|
||||
*
|
||||
*/
|
||||
static uint8_t _sync_id = 0x01;
|
||||
|
||||
/******************************************************************************/
|
||||
/************************** Functions Implementation **************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Write SPI Engine's axi registers
|
||||
*
|
||||
* @param desc Decriptor containing SPI Engine's parameters
|
||||
* @param reg_addr The address of the SPI Engine's axi register where the data
|
||||
* will be written
|
||||
* @param reg_data Data that will be written
|
||||
* @return int32_t This function allways returns SUCCESS
|
||||
*/
|
||||
int32_t spi_engine_write(struct spi_engine_desc *desc,
|
||||
uint32_t reg_addr,
|
||||
uint32_t reg_data)
|
||||
{
|
||||
axi_io_write(desc->spi_engine_baseaddr, reg_addr, reg_data);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read SPI Engine's axi registers
|
||||
*
|
||||
* @param desc Decriptor containing SPI Engine's parameters
|
||||
* @param reg_addr The address of the SPI Engine's axi register from where the
|
||||
* data where the data will be read
|
||||
* @param reg_data Pointer where the read that will be stored
|
||||
* @return int32_t This function allways returns SUCCESS
|
||||
*/
|
||||
int32_t spi_engine_read(struct spi_engine_desc *desc,
|
||||
uint32_t reg_addr,
|
||||
uint32_t *reg_data)
|
||||
{
|
||||
axi_io_read(desc->spi_engine_baseaddr, reg_addr, reg_data);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set width of the transferred word over SPI
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @param data_width The desired data width
|
||||
* The supported values are:
|
||||
* - 8
|
||||
* - 16
|
||||
* - 24
|
||||
* - 32
|
||||
*/
|
||||
int32_t spi_engine_set_transfer_width(struct spi_desc *desc,
|
||||
uint8_t data_width)
|
||||
{
|
||||
struct spi_engine_desc *desc_extra;
|
||||
|
||||
desc_extra = desc->extra;
|
||||
|
||||
if (data_width > desc_extra->max_data_width)
|
||||
desc_extra->data_width = desc_extra->max_data_width;
|
||||
else
|
||||
desc_extra->data_width = data_width;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set SPI engine clock frequency
|
||||
*
|
||||
* @param desc Decriptor containing SPI Engine's parameters
|
||||
* @param speed_hz SPI engine transfer speed
|
||||
*/
|
||||
void spi_engine_set_speed(struct spi_desc *desc,
|
||||
uint32_t speed_hz)
|
||||
{
|
||||
struct spi_engine_desc *desc_extra;
|
||||
|
||||
desc_extra = desc->extra;
|
||||
|
||||
desc_extra->clk_div = desc_extra->ref_clk_hz /
|
||||
(2 * speed_hz) - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the number of words transferred in a single transaction
|
||||
*
|
||||
* @param desc Decriptor containing SPI Engine's parameters
|
||||
* @param bytes_number The number of bytes to be converted
|
||||
* @return uint8_t A number of words in which bytes_number can be grouped
|
||||
*/
|
||||
static uint8_t spi_get_words_number(struct spi_engine_desc *desc,
|
||||
uint8_t bytes_number)
|
||||
{
|
||||
uint8_t xfer_word_len;
|
||||
uint8_t words_number;
|
||||
|
||||
xfer_word_len = desc->data_width / 8;
|
||||
words_number = bytes_number / xfer_word_len;
|
||||
|
||||
if ((bytes_number % xfer_word_len) != 0)
|
||||
words_number++;
|
||||
|
||||
return words_number;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the word length in bytes
|
||||
*
|
||||
* @param desc Decriptor containing SPI Engine's parameters
|
||||
* @return uint8_t Number of bytes that fit in one word
|
||||
*/
|
||||
static uint8_t spi_get_word_length(struct spi_engine_desc *desc)
|
||||
{
|
||||
uint8_t word_length;
|
||||
|
||||
word_length = desc->data_width / 8;
|
||||
|
||||
return word_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Compute the prescaler used to set the sleep period.
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @param sleep_time_ns The amount of time where the transfer hangs
|
||||
* @param sleep_div Clock prescaler
|
||||
* @return int32_t This function allways returns SUCCESS
|
||||
*/
|
||||
static int32_t spi_get_sleep_div(struct spi_desc *desc,
|
||||
uint32_t sleep_time_ns,
|
||||
uint32_t *sleep_div)
|
||||
{
|
||||
struct spi_engine_desc *eng_desc;
|
||||
|
||||
eng_desc = desc->extra;
|
||||
|
||||
/*
|
||||
* Engine Wiki:
|
||||
*
|
||||
* The frequency of the SCLK signal is derived from the
|
||||
* module clock frequency using the following formula:
|
||||
* f_sclk = f_clk / ((div + 1) * 2)
|
||||
*/
|
||||
|
||||
*sleep_div = (desc->max_speed_hz / 1000000 * sleep_time_ns / 1000) /
|
||||
((eng_desc->clk_div + 1) * 2) - 1;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create a new commands queue used in a spi transfer
|
||||
*
|
||||
* @param fifo Command buffer, usually used in fifo mode
|
||||
* @param cmd Command with witch the buffer will be initiated
|
||||
* @return int32_t Failure if the memory allocation failed
|
||||
*/
|
||||
static int32_t spi_engine_queue_new_cmd(struct spi_engine_cmd_queue **fifo,
|
||||
uint32_t cmd)
|
||||
{
|
||||
struct spi_engine_cmd_queue *local_fifo;
|
||||
|
||||
local_fifo = (spi_engine_cmd_queue*)malloc(sizeof(*local_fifo));
|
||||
|
||||
if(!local_fifo)
|
||||
return FAILURE;
|
||||
|
||||
local_fifo->cmd = cmd;
|
||||
local_fifo->next = NULL;
|
||||
*fifo = local_fifo;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Add a command at the end of an existing queue
|
||||
*
|
||||
* @param fifo Command buffer, usually used in fifo mode
|
||||
* @param cmd Command to be added
|
||||
*/
|
||||
static void spi_engine_queue_add_cmd(struct spi_engine_cmd_queue **fifo,
|
||||
uint32_t cmd)
|
||||
{
|
||||
struct spi_engine_cmd_queue *to_add = NULL;
|
||||
struct spi_engine_cmd_queue *local_fifo;
|
||||
|
||||
local_fifo = *fifo;
|
||||
while (local_fifo->next != NULL) {
|
||||
// Get the last element
|
||||
local_fifo = local_fifo->next;
|
||||
}
|
||||
|
||||
// Create a new element
|
||||
spi_engine_queue_new_cmd(&to_add, cmd);
|
||||
// Add as the next element
|
||||
local_fifo->next = to_add;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Add a command at the beginning of an existing queue
|
||||
*
|
||||
* @param fifo Command buffer, usually used in fifo mode
|
||||
* @param cmd Command to be added
|
||||
*/
|
||||
static void spi_engine_queue_append_cmd(struct spi_engine_cmd_queue **fifo,
|
||||
uint32_t cmd)
|
||||
{
|
||||
struct spi_engine_cmd_queue *to_add = NULL;
|
||||
|
||||
// Create a new element
|
||||
spi_engine_queue_new_cmd(&to_add, cmd);
|
||||
// Interchange the addresses
|
||||
to_add->next = *fifo;
|
||||
*fifo = to_add;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get the command from the beginning of the queue
|
||||
*
|
||||
* @param fifo Command buffer, usually used in fifo mode
|
||||
* @param cmd Value of the command that was extracted
|
||||
* @return int32_t Return FAILURE if the queue is empty
|
||||
*/
|
||||
static int32_t spi_engine_queue_get_cmd(struct spi_engine_cmd_queue **fifo,
|
||||
uint32_t *cmd)
|
||||
{
|
||||
struct spi_engine_cmd_queue *local_fifo;
|
||||
|
||||
if (!*fifo)
|
||||
return FAILURE;
|
||||
|
||||
local_fifo = *fifo;
|
||||
*cmd = local_fifo->cmd;
|
||||
if ((*fifo)->next) {
|
||||
*fifo = local_fifo->next;
|
||||
free(local_fifo);
|
||||
} else {
|
||||
free(*fifo);
|
||||
*fifo = NULL;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free the memory allocated by a queue
|
||||
*
|
||||
* @param fifo The queue that needs it's memory freed
|
||||
* @return int32_t This function allways return SUCCESS
|
||||
*/
|
||||
static int32_t spi_engine_queue_free(struct spi_engine_cmd_queue **fifo)
|
||||
{
|
||||
if(*fifo && (*fifo)->next)
|
||||
spi_engine_queue_free(&(*fifo)->next);
|
||||
if((*fifo) != NULL) {
|
||||
free(*fifo);
|
||||
*fifo = NULL;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write the SPI engine's command fifo
|
||||
*
|
||||
* @param desc Decriptor containing SPI Engine's parameters
|
||||
* @param cmd The command that will be written
|
||||
* @return int32_t Returns FAILURE if the the axi transfer failed
|
||||
*/
|
||||
static int32_t spi_engine_write_cmd_reg(struct spi_engine_desc *desc,
|
||||
uint32_t cmd)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
/* Check if offload is enabled */
|
||||
if(desc->offload_config & (OFFLOAD_TX_EN | OFFLOAD_RX_EN)) {
|
||||
ret = spi_engine_write(desc,
|
||||
SPI_ENGINE_REG_OFFLOAD_CMD_MEM(0),
|
||||
cmd);
|
||||
|
||||
} else {
|
||||
ret = spi_engine_write(desc,
|
||||
SPI_ENGINE_REG_CMD_FIFO,
|
||||
cmd);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write a transfer command to the SPI engine's command fifo
|
||||
*
|
||||
* @param desc Decriptor containing SPI Engine's parameters
|
||||
* @param read_write Read/Write operation flag
|
||||
* @param bytes_number Number of bytes to transfer
|
||||
* @return int32_t This function allways returns SUCCESS
|
||||
*/
|
||||
static int32_t spi_engine_transfer(struct spi_engine_desc *desc,
|
||||
uint8_t read_write,
|
||||
uint8_t bytes_number)
|
||||
{
|
||||
uint8_t words_number;
|
||||
|
||||
words_number = spi_get_words_number(desc, bytes_number);
|
||||
|
||||
desc->offload_tx_len += words_number;
|
||||
|
||||
/*
|
||||
* Engine Wiki:
|
||||
*
|
||||
* https://wiki.analog.com/resources/fpga/peripherals/spi_engine
|
||||
*
|
||||
* The words number is zero based
|
||||
*/
|
||||
|
||||
spi_engine_write_cmd_reg(desc,
|
||||
SPI_ENGINE_CMD_TRANSFER(read_write,
|
||||
words_number - 1));
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Change the state of the chip select port
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @param assert Chip select state.
|
||||
* The supported values are :
|
||||
* -true (HIGH)
|
||||
* -false (LOW)
|
||||
*/
|
||||
static void spi_engine_set_cs(struct spi_desc *desc,
|
||||
bool assert)
|
||||
{
|
||||
uint8_t mask;
|
||||
struct spi_engine_desc *eng_desc;
|
||||
|
||||
eng_desc = desc->extra;
|
||||
|
||||
mask = 0xFF;
|
||||
/* Switch the state only of the selected chip select */
|
||||
if (!assert)
|
||||
mask ^= BIT(desc->chip_select);
|
||||
|
||||
spi_engine_write_cmd_reg(eng_desc,
|
||||
SPI_ENGINE_CMD_ASSERT(eng_desc->cs_delay,
|
||||
mask));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Add a delay between the engine commands
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @param sleep_time_ns Number of nanoseconds to sleep between commands
|
||||
*/
|
||||
static void spi_gen_sleep_ns(struct spi_desc *desc,
|
||||
uint32_t sleep_time_ns)
|
||||
{
|
||||
uint32_t sleep_div;
|
||||
struct spi_engine_desc *eng_desc;
|
||||
|
||||
eng_desc = desc->extra;
|
||||
|
||||
spi_get_sleep_div(desc, sleep_time_ns, &sleep_div);
|
||||
|
||||
spi_engine_write_cmd_reg(eng_desc, SPI_ENGINE_CMD_SLEEP(sleep_div));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Spi engine command interpreter
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @param cmd Command to send to the engine
|
||||
* @return int32_t - SUCCESS if the command is transferred
|
||||
* - FAILURE if the command format is invalid
|
||||
*/
|
||||
static int32_t spi_engine_write_cmd(struct spi_desc *desc,
|
||||
uint32_t cmd)
|
||||
{
|
||||
uint8_t engine_command;
|
||||
uint8_t parameter;
|
||||
uint8_t modifier;
|
||||
struct spi_engine_desc *desc_extra;
|
||||
|
||||
desc_extra = desc->extra;
|
||||
|
||||
engine_command = (cmd >> 12) & 0x0F;
|
||||
modifier = (cmd >> 8) & 0x0F;
|
||||
parameter = cmd & 0xFF;
|
||||
|
||||
switch(engine_command) {
|
||||
case SPI_ENGINE_INST_TRANSFER:
|
||||
spi_engine_transfer(desc_extra, modifier, parameter);
|
||||
break;
|
||||
|
||||
case SPI_ENGINE_INST_ASSERT:
|
||||
if(parameter == 0xFF) {
|
||||
/* Set the CS HIGH */
|
||||
spi_engine_set_cs(desc, true);
|
||||
} else if(parameter == 0x00) {
|
||||
/* Set the CS LOW */
|
||||
spi_engine_set_cs(desc, false);
|
||||
}
|
||||
break;
|
||||
|
||||
/* The SYNC and SLEEP commands got the same value but different
|
||||
modifier */
|
||||
case SPI_ENGINE_INST_SYNC_SLEEP:
|
||||
/* SYNC instruction */
|
||||
if(modifier == 0x00) {
|
||||
spi_engine_write_cmd_reg(desc_extra, cmd);
|
||||
} else if(modifier == 0x01) {
|
||||
spi_gen_sleep_ns(desc, parameter);
|
||||
}
|
||||
break;
|
||||
case SPI_ENGINE_INST_CONFIG:
|
||||
spi_engine_write_cmd_reg(desc_extra, cmd);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepare the command queue before sending it to the engine
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @param msg Structure used to store the transfer messages
|
||||
* @return int32_t This function allways returns SUCCESS
|
||||
*/
|
||||
static int32_t spi_engine_compile_message(struct spi_desc *desc,
|
||||
struct spi_engine_msg *msg)
|
||||
{
|
||||
struct spi_engine_desc *desc_extra;
|
||||
|
||||
desc_extra = desc->extra;
|
||||
|
||||
/* Configure the prescaler */
|
||||
spi_engine_queue_append_cmd(&msg->cmds,
|
||||
SPI_ENGINE_CMD_CONFIG(
|
||||
SPI_ENGINE_CMD_REG_CLK_DIV,
|
||||
desc_extra->clk_div));
|
||||
|
||||
/* Set the data transfer length */
|
||||
spi_engine_queue_append_cmd(&msg->cmds,
|
||||
SPI_ENGINE_CMD_CONFIG(
|
||||
SPI_ENGINE_CMD_DATA_TRANSFER_LEN,
|
||||
desc_extra->data_width));
|
||||
/*
|
||||
* Configure the spi mode :
|
||||
* - 3 wire
|
||||
* - CPOL
|
||||
* - CPHA
|
||||
*/
|
||||
spi_engine_queue_append_cmd(&msg->cmds,
|
||||
SPI_ENGINE_CMD_CONFIG(
|
||||
SPI_ENGINE_CMD_REG_CONFIG,
|
||||
desc->mode));
|
||||
|
||||
/* Add a sync command to signal that the transfer has finished */
|
||||
spi_engine_queue_add_cmd(&msg->cmds, SPI_ENGINE_CMD_SYNC(_sync_id));
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initiate a spi transfer (Blocking)
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @param msg Structure used to store the transfer messages
|
||||
* @return int32_t - SUCCESS if the transfer finished
|
||||
* - FAILURE if the memory allocation failed
|
||||
*/
|
||||
static int32_t spi_engine_transfer_message(struct spi_desc *desc,
|
||||
struct spi_engine_msg *msg)
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t data;
|
||||
uint32_t sync_id;
|
||||
bool offload_en;
|
||||
struct spi_engine_desc *desc_extra;
|
||||
|
||||
desc_extra = desc->extra;
|
||||
|
||||
spi_engine_compile_message(desc, msg);
|
||||
|
||||
offload_en = (desc_extra->offload_config & OFFLOAD_TX_EN) |
|
||||
(desc_extra->offload_config & OFFLOAD_RX_EN);
|
||||
|
||||
/* Write the command fifo buffer */
|
||||
while(msg->cmds != NULL) {
|
||||
spi_engine_queue_get_cmd(&msg->cmds, &data);
|
||||
spi_engine_write_cmd(desc, data);
|
||||
}
|
||||
|
||||
/* Write a number of tx_length WORDS on the SDO line */
|
||||
if(offload_en) {
|
||||
for(i = 0; i < desc_extra->offload_tx_len; i++)
|
||||
spi_engine_write(desc_extra,
|
||||
SPI_ENGINE_REG_OFFLOAD_SDO_MEM(0),
|
||||
msg->tx_buf[i]);
|
||||
|
||||
} else {
|
||||
if(msg->tx_buf != NULL){
|
||||
for(i = 0; i < msg->tx_length; i++)
|
||||
spi_engine_write(desc_extra,
|
||||
SPI_ENGINE_REG_SDO_DATA_FIFO,
|
||||
msg->tx_buf[i]);
|
||||
}
|
||||
do {
|
||||
spi_engine_read(desc_extra,
|
||||
SPI_ENGINE_REG_SYNC_ID,
|
||||
&sync_id);
|
||||
}
|
||||
/* Wait for the end sync signal */
|
||||
while(sync_id != _sync_id);
|
||||
_sync_id++;
|
||||
|
||||
/* Read a number of rx_length WORDS from the SDI line and store
|
||||
them */
|
||||
for(i = 0; i < msg->rx_length; i++) {
|
||||
spi_engine_read(desc_extra,
|
||||
SPI_ENGINE_REG_SDI_DATA_FIFO,
|
||||
&data);
|
||||
/* Store the rx data if rx buffer valid, flush sdi_fifo if
|
||||
rx buffer is invalid.*/
|
||||
if(msg->rx_buf != NULL){
|
||||
msg->rx_buf[i] = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the spi engine
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @param param Structure containing the spi init parameters
|
||||
* @return int32_t - SUCCESS if the transfer finished
|
||||
* - FAILURE if the memory allocation failed
|
||||
*/
|
||||
int32_t spi_engine_init(struct spi_desc **desc,
|
||||
const struct spi_init_param *param)
|
||||
{
|
||||
uint32_t data_width = 0;
|
||||
uint32_t spi_engine_version = 0;
|
||||
struct spi_engine_desc *eng_desc;
|
||||
struct spi_engine_init_param *spi_engine_init;
|
||||
|
||||
if (!param) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
*desc = malloc(sizeof(**desc));
|
||||
if(! *desc) {
|
||||
free(*desc);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
eng_desc = (struct spi_engine_desc*)malloc(sizeof(*eng_desc));
|
||||
|
||||
if (!eng_desc)
|
||||
return FAILURE;
|
||||
|
||||
spi_engine_init = param->extra;
|
||||
|
||||
(*desc)->max_speed_hz = param->max_speed_hz;
|
||||
(*desc)->chip_select = param->chip_select;
|
||||
(*desc)->mode = param->mode;
|
||||
(*desc)->extra = eng_desc;
|
||||
|
||||
eng_desc->offload_config = OFFLOAD_DISABLED;
|
||||
eng_desc->spi_engine_baseaddr = spi_engine_init->spi_engine_baseaddr;
|
||||
eng_desc->type = spi_engine_init->type;
|
||||
eng_desc->cs_delay = spi_engine_init->cs_delay;
|
||||
eng_desc->ref_clk_hz = spi_engine_init->ref_clk_hz;
|
||||
eng_desc->clk_div = eng_desc->ref_clk_hz /
|
||||
(2 * param->max_speed_hz) - 1;
|
||||
|
||||
/* Perform a reset */
|
||||
spi_engine_write(eng_desc, SPI_ENGINE_REG_RESET, 0x01);
|
||||
usleep(1000);
|
||||
spi_engine_write(eng_desc, SPI_ENGINE_REG_RESET, 0x00);
|
||||
|
||||
/* Get current data width */
|
||||
spi_engine_read(eng_desc, SPI_ENGINE_REG_DATA_WIDTH, &data_width);
|
||||
eng_desc->max_data_width = data_width;
|
||||
|
||||
spi_engine_set_transfer_width(*desc, spi_engine_init->data_width);
|
||||
|
||||
/* Get spi engine version */
|
||||
spi_engine_read(eng_desc, SPI_ENGINE_REG_VERSION, &spi_engine_version);
|
||||
|
||||
printf("Spi engine v%"PRIu32".%"PRIu32".%"PRIu32" successfully initialized.\n",
|
||||
(spi_engine_version >> 16),
|
||||
((spi_engine_version >> 8) & 0xFF),
|
||||
(spi_engine_version & 0xFF));
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write and read on the spi interface in 4-wire mode (full-duplex)
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @param data Pointer to data buffer
|
||||
* @param bytes_number Number of bytes to transfer
|
||||
* @return int32_t - SUCCESS if the transfer finished
|
||||
* - FAILURE if the memory allocation or transfer failed
|
||||
*/
|
||||
int32_t spi_engine_spi_write_and_read(struct spi_desc *desc,
|
||||
uint8_t *data,
|
||||
uint16_t bytes_number)
|
||||
{
|
||||
uint8_t word_len;
|
||||
uint8_t words_number;
|
||||
int32_t ret;
|
||||
struct spi_engine_msg msg;
|
||||
struct spi_engine_desc *desc_extra;
|
||||
|
||||
desc_extra = desc->extra;
|
||||
|
||||
/* If we want to access SPI interface and SPI engine offload module was
|
||||
* activated, we need to disable it
|
||||
* This is set in spi_engine_offload_init() */
|
||||
desc_extra->offload_config = OFFLOAD_DISABLED;
|
||||
/* This is set in spi_engine_offload_transfer() */
|
||||
spi_engine_write(desc_extra, SPI_ENGINE_REG_OFFLOAD_CTRL(0), 0);
|
||||
|
||||
words_number = spi_get_words_number(desc_extra, bytes_number);
|
||||
|
||||
msg.cmds = (spi_engine_cmd_queue*)malloc(sizeof(*msg.cmds));
|
||||
if (!msg.cmds)
|
||||
return FAILURE;
|
||||
|
||||
msg.tx_buf =(uint32_t*)calloc(words_number, sizeof(msg.tx_buf[0]));
|
||||
msg.rx_buf =(uint32_t*)calloc(words_number, sizeof(msg.rx_buf[0]));
|
||||
msg.tx_length = words_number;
|
||||
msg.rx_length = words_number;
|
||||
|
||||
/* Get the length of transferred word */
|
||||
word_len = spi_get_word_length(desc_extra);
|
||||
|
||||
/* Make sure the CS is HIGH before starting a transaction */
|
||||
msg.cmds->next = NULL;
|
||||
msg.cmds->cmd = CS_HIGH;
|
||||
// Assert select.
|
||||
spi_engine_queue_add_cmd(&msg.cmds, CS_LOW);
|
||||
// add read/write command
|
||||
spi_engine_queue_add_cmd(&msg.cmds, WRITE_READ(bytes_number));
|
||||
// Disable select.
|
||||
spi_engine_queue_add_cmd(&msg.cmds, CS_HIGH);
|
||||
|
||||
/* Pack the bytes into engine WORDS */
|
||||
for (int i = 0; i < bytes_number; i++)
|
||||
msg.tx_buf[i / word_len] |= data[i] << (desc_extra->data_width-
|
||||
(i % word_len + 1) * 8);
|
||||
|
||||
ret = spi_engine_transfer_message(desc, &msg);
|
||||
|
||||
for (int i = 0; i < bytes_number; i++)
|
||||
data[i] = msg.rx_buf[(i) / word_len] >>
|
||||
(desc_extra->data_width -
|
||||
((i) % word_len + 1) * 8);
|
||||
|
||||
spi_engine_queue_free(&msg.cmds);
|
||||
free(msg.tx_buf);
|
||||
free(msg.rx_buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write and read on the spi interface in 3-wire mode (half-duplex)
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @param data Pointer to data buffer
|
||||
* @param bytes_number Number of bytes to transfer
|
||||
* @return int32_t - SUCCESS if the transfer finished
|
||||
* - FAILURE if the memory allocation or transfer failed
|
||||
*/
|
||||
int32_t spi_engine_spi_write_and_read_3wire(struct spi_desc *desc,
|
||||
uint8_t *write_data,
|
||||
uint8_t *read_data,
|
||||
uint16_t write_bytes_number,
|
||||
uint16_t read_bytes_number)
|
||||
{
|
||||
uint8_t word_len;
|
||||
uint8_t wr_words_number;
|
||||
uint8_t rd_words_number;
|
||||
int32_t ret;
|
||||
struct spi_engine_msg msg;
|
||||
struct spi_engine_desc *desc_extra;
|
||||
|
||||
desc_extra = desc->extra;
|
||||
|
||||
/* If we want to access SPI interface and SPI engine offload module was
|
||||
* activated, we need to disable it
|
||||
* This is set in spi_engine_offload_init() */
|
||||
desc_extra->offload_config = OFFLOAD_DISABLED;
|
||||
/* This is set in spi_engine_offload_transfer() */
|
||||
spi_engine_write(desc_extra, SPI_ENGINE_REG_OFFLOAD_CTRL(0), 0);
|
||||
|
||||
wr_words_number = spi_get_words_number(desc_extra, write_bytes_number);
|
||||
rd_words_number = spi_get_words_number(desc_extra, read_bytes_number);
|
||||
|
||||
msg.cmds = (spi_engine_cmd_queue*)malloc(sizeof(*msg.cmds));
|
||||
if (!msg.cmds)
|
||||
return FAILURE;
|
||||
|
||||
msg.tx_buf =(wr_words_number>0)?(uint32_t*)calloc(wr_words_number, sizeof(msg.tx_buf[0])):NULL;
|
||||
msg.rx_buf =(rd_words_number>0)?(uint32_t*)calloc(rd_words_number, sizeof(msg.rx_buf[0])):NULL;
|
||||
msg.tx_length = wr_words_number;
|
||||
msg.rx_length = rd_words_number;
|
||||
|
||||
/* Get the length of transferred word */
|
||||
word_len = spi_get_word_length(desc_extra);
|
||||
|
||||
/* Make sure the CS is HIGH before starting a transaction */
|
||||
msg.cmds->next = NULL;
|
||||
msg.cmds->cmd = CS_HIGH;
|
||||
|
||||
// Assert select.
|
||||
spi_engine_queue_add_cmd(&msg.cmds, CS_LOW);
|
||||
|
||||
// add read/write command
|
||||
if(write_bytes_number > 0)
|
||||
spi_engine_queue_add_cmd(&msg.cmds, WRITE(write_bytes_number));
|
||||
if(read_bytes_number > 0)
|
||||
spi_engine_queue_add_cmd(&msg.cmds, READ(read_bytes_number));
|
||||
|
||||
// Disable select.
|
||||
spi_engine_queue_add_cmd(&msg.cmds, CS_HIGH);
|
||||
|
||||
/* Pack the bytes into engine WORDS */
|
||||
for (int i = 0; i < write_bytes_number; i++)
|
||||
msg.tx_buf[i / word_len] |= write_data[i] << (desc_extra->data_width-
|
||||
(i % word_len + 1) * 8);
|
||||
|
||||
ret = spi_engine_transfer_message(desc, &msg);
|
||||
|
||||
for (int i = 0; i < read_bytes_number; i++)
|
||||
read_data[i] = msg.rx_buf[(i) / word_len] >>
|
||||
(desc_extra->data_width -
|
||||
((i) % word_len + 1) * 8);
|
||||
|
||||
spi_engine_queue_free(&msg.cmds);
|
||||
free(msg.tx_buf);
|
||||
free(msg.rx_buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the SPI engine's offload module
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @param param Structure containing the offload init parameters
|
||||
* @return int32_t This function allways returns SUCCESS
|
||||
*/
|
||||
int32_t spi_engine_offload_init(struct spi_desc *desc,
|
||||
const struct spi_engine_offload_init_param *param)
|
||||
{
|
||||
struct spi_engine_desc *eng_desc;
|
||||
struct axi_dmac_init dmac_init;
|
||||
uint32_t dma_flags;
|
||||
|
||||
eng_desc = desc->extra;
|
||||
|
||||
eng_desc->offload_config = param->offload_config;
|
||||
|
||||
if(!(param->dma_flags))
|
||||
dma_flags = DMA_CYCLIC;
|
||||
else
|
||||
dma_flags = *(param->dma_flags);
|
||||
|
||||
if(param->offload_config & OFFLOAD_TX_EN) {
|
||||
dmac_init.name = "DAC DMAC";
|
||||
dmac_init.base = param->tx_dma_baseaddr;
|
||||
dmac_init.direction = DMA_MEM_TO_DEV;
|
||||
dmac_init.flags = dma_flags;
|
||||
axi_dmac_init(&eng_desc->offload_tx_dma, &dmac_init);
|
||||
if(!eng_desc->offload_tx_dma)
|
||||
return FAILURE;
|
||||
}
|
||||
if(param->offload_config & OFFLOAD_RX_EN) {
|
||||
dmac_init.name = "ADC DMAC";
|
||||
dmac_init.base = param->rx_dma_baseaddr;
|
||||
dmac_init.direction = DMA_DEV_TO_MEM;
|
||||
dmac_init.flags = dma_flags;
|
||||
axi_dmac_init(&eng_desc->offload_rx_dma, &dmac_init);
|
||||
if(!eng_desc->offload_rx_dma)
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initiate a SPI transfer in offload mode
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @param msg Offload message that get's to be transferred
|
||||
* @param no_samples Number of time the messages will be transferred
|
||||
* @return int32_t This function allways returns SUCCESS
|
||||
*/
|
||||
int32_t spi_engine_offload_transfer(struct spi_desc *desc,
|
||||
struct spi_engine_offload_message msg,
|
||||
uint32_t no_samples)
|
||||
{
|
||||
struct spi_engine_msg transfer;
|
||||
struct spi_engine_desc *eng_desc;
|
||||
uint32_t i;
|
||||
uint8_t word_length;
|
||||
|
||||
eng_desc = desc->extra;
|
||||
|
||||
/* Check if offload is disabled */
|
||||
if(!((eng_desc->offload_config & OFFLOAD_TX_EN) |
|
||||
(eng_desc->offload_config & OFFLOAD_RX_EN)))
|
||||
return FAILURE;
|
||||
|
||||
spi_engine_write(eng_desc, SPI_ENGINE_REG_OFFLOAD_RESET(0), 1);
|
||||
spi_engine_write(eng_desc, SPI_ENGINE_REG_OFFLOAD_RESET(0), 0);
|
||||
|
||||
eng_desc->offload_tx_len = 0;
|
||||
eng_desc->offload_rx_len = 0;
|
||||
|
||||
transfer.cmds = (spi_engine_cmd_queue*)malloc(sizeof(*transfer.cmds));
|
||||
|
||||
if (!transfer.cmds)
|
||||
return FAILURE;
|
||||
|
||||
transfer.tx_buf = msg.commands_data;
|
||||
|
||||
/* Load the commands into the message */
|
||||
transfer.cmds->next = NULL;
|
||||
transfer.cmds->cmd = msg.commands[0];
|
||||
i = 1;
|
||||
while(i < msg.no_commands) {
|
||||
spi_engine_queue_add_cmd(&transfer.cmds, msg.commands[i++]);
|
||||
|
||||
}
|
||||
|
||||
spi_engine_transfer_message(desc, &transfer);
|
||||
|
||||
/* Start transfer */
|
||||
spi_engine_write(eng_desc, SPI_ENGINE_REG_OFFLOAD_CTRL(0), 0x0001);
|
||||
|
||||
word_length = spi_get_word_length(eng_desc);
|
||||
if(eng_desc->offload_config & OFFLOAD_TX_EN) {
|
||||
axi_dmac_transfer(eng_desc->offload_tx_dma,
|
||||
msg.tx_addr,
|
||||
word_length * eng_desc->offload_tx_len *
|
||||
no_samples);
|
||||
}
|
||||
|
||||
if(eng_desc->offload_config & OFFLOAD_RX_EN) {
|
||||
axi_dmac_transfer(eng_desc->offload_rx_dma,
|
||||
msg.rx_addr,
|
||||
word_length * eng_desc->offload_tx_len *
|
||||
no_samples);
|
||||
}
|
||||
|
||||
usleep(1000);
|
||||
|
||||
spi_engine_queue_free(&transfer.cmds);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free the resources allocated by spi_init().
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @return int32_t This function allways returns SUCCESS
|
||||
*/
|
||||
int32_t spi_engine_remove(struct spi_desc *desc)
|
||||
{
|
||||
struct spi_engine_desc *eng_desc;
|
||||
|
||||
eng_desc = desc->extra;
|
||||
|
||||
if(eng_desc->offload_config & OFFLOAD_TX_EN)
|
||||
axi_dmac_remove(eng_desc->offload_tx_dma);
|
||||
if(eng_desc->offload_config & OFFLOAD_RX_EN)
|
||||
axi_dmac_remove(eng_desc->offload_rx_dma);
|
||||
free(desc->extra);
|
||||
free(desc);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
+231
@@ -0,0 +1,231 @@
|
||||
/*******************************************************************************
|
||||
* @file spi_engine.h
|
||||
* @brief Header file of SPI Engine core features.
|
||||
* @author Sergiu Cuciurean ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2019(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef SPI_ENGINE_H
|
||||
#define SPI_ENGINE_H
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "spi_engine_private.h"
|
||||
#include "../../platform/spi_extra.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** Macros and Constants Definitions **********************/
|
||||
/******************************************************************************/
|
||||
|
||||
#define OFFLOAD_DISABLED 0x00
|
||||
#define OFFLOAD_TX_EN BIT(0)
|
||||
#define OFFLOAD_RX_EN BIT(1)
|
||||
#define OFFLOAD_TX_RX_EN OFFLOAD_TX_EN | OFFLOAD_RX_EN
|
||||
|
||||
#define SPI_ENGINE_MSG_QUEUE_END 0xFFFFFFFF
|
||||
|
||||
/* Spi engine commands */
|
||||
#define WRITE_OR_READ(mode, no_bytes) ((SPI_ENGINE_INST_TRANSFER << 12) |\
|
||||
((mode) << 8) | (no_bytes))
|
||||
|
||||
#define WRITE(no_bytes) ((SPI_ENGINE_INST_TRANSFER << 12) |\
|
||||
(SPI_ENGINE_INSTRUCTION_TRANSFER_W << 8) | (no_bytes))
|
||||
|
||||
#define READ(no_bytes) ((SPI_ENGINE_INST_TRANSFER << 12) |\
|
||||
(SPI_ENGINE_INSTRUCTION_TRANSFER_R << 8) | (no_bytes))
|
||||
|
||||
#define WRITE_READ(no_bytes) ((SPI_ENGINE_INST_TRANSFER << 12) |\
|
||||
(SPI_ENGINE_INSTRUCTION_TRANSFER_RW << 8) | (no_bytes))
|
||||
|
||||
|
||||
|
||||
#define SLEEP(time) SPI_ENGINE_CMD_SLEEP(time & 0xF)
|
||||
|
||||
/* The delay and chip select parmeters are passed over the engine descriptor
|
||||
and will be used inside the function call */
|
||||
#define CS_HIGH SPI_ENGINE_CMD_ASSERT(0x00, 0xFF)
|
||||
#define CS_LOW SPI_ENGINE_CMD_ASSERT(0x00, 0x00)
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @struct spi_engine_init_param
|
||||
* @brief Structure containing the init parameters needed by the SPI engine
|
||||
*/
|
||||
struct spi_engine_init_param {
|
||||
/** SPI engine reference clock */
|
||||
uint32_t ref_clk_hz;
|
||||
/** Type of implementation */
|
||||
enum xil_spi_type type;
|
||||
/** Base address where the HDL core is situated */
|
||||
uint32_t spi_engine_baseaddr;
|
||||
/** Delay between the CS toggle and the start of SCLK */
|
||||
uint32_t cs_delay;
|
||||
/** Data with of one SPI transfer ( in bits ) */
|
||||
uint8_t data_width;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @struct spi_engine_desc
|
||||
* @brief Structure representing an SPI engine device
|
||||
*/
|
||||
struct spi_engine_desc {
|
||||
/** SPI engine reference clock */
|
||||
uint32_t ref_clk_hz;
|
||||
/** Type of implementation */
|
||||
enum xil_spi_type type;
|
||||
/** Pointer to a DMAC used in transmission */
|
||||
struct axi_dmac *offload_tx_dma;
|
||||
/** Pointer to a DMAC used in reception */
|
||||
struct axi_dmac *offload_rx_dma;
|
||||
/** Offload's module transfer direction : TX, RX or both */
|
||||
uint8_t offload_config;
|
||||
/** Number of words that the module has to send */
|
||||
uint8_t offload_tx_len;
|
||||
/** Number of words that the module has to receive */
|
||||
uint8_t offload_rx_len;
|
||||
/** Base address where the HDL core is situated */
|
||||
uint32_t spi_engine_baseaddr;
|
||||
/** Base address where the RX DMAC core is situated */
|
||||
uint32_t rx_dma_baseaddr;
|
||||
/** Base address where the TX DMAC core is situated */
|
||||
uint32_t tx_dma_baseaddr;
|
||||
/** Delay between the CS toggle and the start of SCLK */
|
||||
uint8_t cs_delay;
|
||||
/** Clock divider used in transmission delays */
|
||||
uint32_t clk_div;
|
||||
/** Data with of one SPI transfer ( in bits ) */
|
||||
uint8_t data_width;
|
||||
/** The maximum data width supported by the engine */
|
||||
uint8_t max_data_width;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @struct spi_engine_offload_init_param
|
||||
* @brief Structure containing the init parameters needed by the offload module
|
||||
*/
|
||||
struct spi_engine_offload_init_param {
|
||||
/** Base address where the RX DMAC core is situated */
|
||||
uint32_t rx_dma_baseaddr;
|
||||
/** Base address where the TX DMAC core is situated */
|
||||
uint32_t tx_dma_baseaddr;
|
||||
/** DMAC flags - if not initialized, the default value is DMA_CYCLIC */
|
||||
uint32_t *dma_flags;
|
||||
/** Offload's module transfer direction : TX, RX or both */
|
||||
uint8_t offload_config;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct spi_engine_offload_message
|
||||
* @brief Structure representing an offload message
|
||||
*/
|
||||
struct spi_engine_offload_message {
|
||||
/** Pointer to the SPI engine commands buffer that will be sent.
|
||||
* The available commands can be found at:
|
||||
* https://wiki.analog.com/resources/fpga/peripherals/spi_engine/
|
||||
*/
|
||||
uint32_t *commands;
|
||||
/** Length of the SPI engine commands buffer */
|
||||
uint32_t no_commands;
|
||||
/** Pointer of the data that will be sent over spi */
|
||||
uint32_t *commands_data;
|
||||
/** The address where the data that will be transmitted is situated */
|
||||
uint32_t tx_addr;
|
||||
/** The address where the data that will be received is situated */
|
||||
uint32_t rx_addr;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Declarations ******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Spi engine platform specific SPI platform ops structure
|
||||
*/
|
||||
extern const struct spi_platform_ops xil_spi_ops;
|
||||
|
||||
/* Write SPI Engine's axi registers */
|
||||
int32_t spi_engine_write(struct spi_engine_desc *desc,
|
||||
uint32_t reg_addr,
|
||||
uint32_t reg_data);
|
||||
|
||||
/* Read SPI Engine's axi registers */
|
||||
int32_t spi_engine_read(struct spi_engine_desc *desc,
|
||||
uint32_t reg_addr,
|
||||
uint32_t *reg_data);
|
||||
/* Initialize the SPI engine device */
|
||||
int32_t spi_engine_init(struct spi_desc **desc,
|
||||
const struct spi_init_param *param);
|
||||
|
||||
/* Write and read data over SPI using the SPI engine */
|
||||
int32_t spi_engine_spi_write_and_read(struct spi_desc *desc,
|
||||
uint8_t *data,
|
||||
uint16_t bytes_number);
|
||||
|
||||
/* Write and read data over SPI using the SPI engine in 3-wire mode */
|
||||
int32_t spi_engine_spi_write_and_read_3wire(struct spi_desc *desc,
|
||||
uint8_t *write_data,
|
||||
uint8_t *read_data,
|
||||
uint16_t write_bytes_number,
|
||||
uint16_t read_bytes_number);
|
||||
/* Free the resources used by the SPI engine device */
|
||||
int32_t spi_engine_remove(struct spi_desc *desc);
|
||||
|
||||
/* Initialize the SPI engine offload module */
|
||||
int32_t spi_engine_offload_init(struct spi_desc *desc,
|
||||
const struct spi_engine_offload_init_param *param);
|
||||
|
||||
/* Write and read data over SPI using the offload module */
|
||||
int32_t spi_engine_offload_transfer(struct spi_desc *desc,
|
||||
struct spi_engine_offload_message msg,
|
||||
uint32_t no_samples);
|
||||
|
||||
/* Set SPI transfer width */
|
||||
int32_t spi_engine_set_transfer_width(struct spi_desc *desc,
|
||||
uint8_t data_wdith);
|
||||
|
||||
/* Set SPI transfer speed */
|
||||
void spi_engine_set_speed(struct spi_desc *desc,
|
||||
uint32_t speed_hz);
|
||||
|
||||
#endif // SPI_ENGINE_H
|
||||
+154
@@ -0,0 +1,154 @@
|
||||
/*******************************************************************************
|
||||
* @file spi_engine_private.h
|
||||
* @brief Private definitions of the SPI Engine
|
||||
* @author Sergiu Cuciurean ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2019(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef SPI_ENGINE_PRIVATE_H
|
||||
#define SPI_ENGINE_PRIVATE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "../../../include/spi.h"
|
||||
#include "../../../include/util.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Spi Engine registers *****************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#define SPI_ENGINE_REG_VERSION 0x00
|
||||
#define SPI_ENGINE_REG_DATA_WIDTH 0x0C
|
||||
#define SPI_ENGINE_REG_RESET 0x40
|
||||
#define SPI_ENGINE_REG_INT_ENABLE 0x80
|
||||
#define SPI_ENGINE_REG_INT_PENDING 0x84
|
||||
#define SPI_ENGINE_REG_INT_SOURCE 0x88
|
||||
#define SPI_ENGINE_REG_SYNC_ID 0xC0
|
||||
#define SPI_ENGINE_REG_CMD_FIFO_ROOM 0xD0
|
||||
#define SPI_ENGINE_REG_SDO_FIFO_ROOM 0xD4
|
||||
#define SPI_ENGINE_REG_SDI_FIFO_LEVEL 0xD8
|
||||
#define SPI_ENGINE_REG_CMD_FIFO 0xE0
|
||||
#define SPI_ENGINE_REG_SDO_DATA_FIFO 0xE4
|
||||
#define SPI_ENGINE_REG_SDI_DATA_FIFO 0xE8
|
||||
#define SPI_ENGINE_REG_SDI_DATA_FIFO_PEEK 0xEC
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Spi Engine register parameters **********************/
|
||||
/******************************************************************************/
|
||||
|
||||
#define SPI_ENGINE_INST_TRANSFER 0x00
|
||||
#define SPI_ENGINE_INST_ASSERT 0x01
|
||||
#define SPI_ENGINE_INST_CONFIG 0x02
|
||||
#define SPI_ENGINE_INST_SYNC_SLEEP 0x03
|
||||
#define SPI_ENGINE_INST_MISC 0x03
|
||||
#define SPI_ENGINE_CMD_REG_CLK_DIV 0x00
|
||||
#define SPI_ENGINE_CMD_REG_CONFIG 0x01
|
||||
#define SPI_ENGINE_CMD_DATA_TRANSFER_LEN 0x02
|
||||
#define SPI_ENGINE_MISC_SYNC 0x00
|
||||
#define SPI_ENGINE_MISC_SLEEP 0x01
|
||||
#define SPI_ENGINE_SYNC_TRANSFER_BEGIN BIT(1)
|
||||
#define SPI_ENGINE_SYNC_TRANSFER_END BIT(2)
|
||||
#define SPI_ENGINE_INT_CMD_ALMOST_EMPTY BIT(0)
|
||||
#define SPI_ENGINE_INT_SDO_ALMOST_EMPTY BIT(1)
|
||||
#define SPI_ENGINE_INT_SDI_ALMOST_FULL BIT(2)
|
||||
#define SPI_ENGINE_INT_SYNC BIT(3)
|
||||
#define SPI_ENGINE_OFFLOAD_CTRL_ENABLE BIT(0)
|
||||
#define SPI_ENGINE_OFFLOAD_STATUS_ENABLED BIT(0)
|
||||
#define SPI_ENGINE_CONFIG_CPHA BIT(0)
|
||||
#define SPI_ENGINE_CONFIG_CPOL BIT(1)
|
||||
#define SPI_ENGINE_CONFIG_3WIRE BIT(2)
|
||||
#define SPI_ENGINE_VERSION_MAJOR(x) ((x >> 16) & 0xff)
|
||||
#define SPI_ENGINE_VERSION_MINOR(x) ((x >> 8) & 0xff)
|
||||
#define SPI_ENGINE_VERSION_PATCH(x) (x & 0xff)
|
||||
|
||||
/******************************************************************************/
|
||||
/**************************** Spi Engine commands *****************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#define SPI_ENGINE_INSTRUCTION_TRANSFER_W 0x01
|
||||
#define SPI_ENGINE_INSTRUCTION_TRANSFER_R 0x02
|
||||
#define SPI_ENGINE_INSTRUCTION_TRANSFER_RW 0x03
|
||||
|
||||
#define SPI_ENGINE_REG_OFFLOAD_CTRL(x) (0x100 + (0x20 * x))
|
||||
#define SPI_ENGINE_REG_OFFLOAD_STATUS(x) (0x104 + (0x20 * x))
|
||||
#define SPI_ENGINE_REG_OFFLOAD_RESET(x) (0x108 + (0x20 * x))
|
||||
#define SPI_ENGINE_REG_OFFLOAD_CMD_MEM(x) (0x110 + (0x20 * x))
|
||||
#define SPI_ENGINE_REG_OFFLOAD_SDO_MEM(x) (0x114 + (0x20 * x))
|
||||
|
||||
#define SPI_ENGINE_CMD(inst, arg1, arg2) \
|
||||
(((inst & 0x03) << 12) | \
|
||||
((arg1 & 0x03) << 8) | arg2 )
|
||||
|
||||
#define SPI_ENGINE_CMD_TRANSFER(readwrite, n) \
|
||||
SPI_ENGINE_CMD(SPI_ENGINE_INST_TRANSFER, \
|
||||
(readwrite), (n))
|
||||
|
||||
#define SPI_ENGINE_CMD_ASSERT(delay, cs) \
|
||||
SPI_ENGINE_CMD(SPI_ENGINE_INST_ASSERT, \
|
||||
(delay), (cs))
|
||||
|
||||
#define SPI_ENGINE_CMD_CONFIG(reg, val) \
|
||||
SPI_ENGINE_CMD(SPI_ENGINE_INST_CONFIG, \
|
||||
(reg), (val))
|
||||
|
||||
#define SPI_ENGINE_CMD_SLEEP(delay) \
|
||||
SPI_ENGINE_CMD(SPI_ENGINE_INST_MISC, \
|
||||
SPI_ENGINE_MISC_SLEEP, \
|
||||
(delay))
|
||||
|
||||
#define SPI_ENGINE_CMD_SYNC(id) \
|
||||
SPI_ENGINE_CMD(SPI_ENGINE_INST_MISC, \
|
||||
SPI_ENGINE_MISC_SYNC, \
|
||||
(id))
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
typedef struct spi_engine_cmd_queue {
|
||||
uint32_t cmd;
|
||||
struct spi_engine_cmd_queue *next;
|
||||
} spi_engine_cmd_queue;
|
||||
|
||||
typedef struct spi_engine_msg {
|
||||
uint32_t *tx_buf;
|
||||
uint32_t *rx_buf;
|
||||
uint32_t tx_length;
|
||||
uint32_t rx_length;
|
||||
struct spi_engine_cmd_queue *cmds;
|
||||
} spi_engine_msg;
|
||||
|
||||
#endif // SPI_ENGINE_PRIVATE_H
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
/***************************************************************************//**
|
||||
* @file lmk04828.c
|
||||
* @brief Implementation of AD9680 Driver.
|
||||
* @author DBogdan ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2014-2016(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "lmk04828.h"
|
||||
#include "../../../include/error.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief lmk04828_read
|
||||
*******************************************************************************/
|
||||
int32_t lmk04828_read(struct lmk04828_dev *dev,
|
||||
uint16_t reg_addr,
|
||||
uint8_t *reg_data)
|
||||
{
|
||||
uint8_t tx_buf[2];
|
||||
uint8_t rx_buf[1];
|
||||
int32_t ret;
|
||||
|
||||
tx_buf[0] = 0x80 | (reg_addr >> 8);
|
||||
tx_buf[1] = reg_addr & 0xFF;
|
||||
|
||||
|
||||
ret = spi_write_and_read_3wire(dev->spi_desc,
|
||||
tx_buf, rx_buf, 2, 1);
|
||||
|
||||
*reg_data = rx_buf[0];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief lmk04828_write
|
||||
*******************************************************************************/
|
||||
int32_t lmk04828_write(struct lmk04828_dev *dev,
|
||||
uint16_t reg_addr,
|
||||
uint8_t reg_data)
|
||||
{
|
||||
uint8_t buf[3];
|
||||
|
||||
int32_t ret;
|
||||
|
||||
buf[0] = reg_addr >> 8;
|
||||
buf[1] = reg_addr & 0xFF;
|
||||
buf[2] = reg_data;
|
||||
|
||||
ret = spi_write_and_read_3wire(dev->spi_desc,
|
||||
buf, NULL, 3, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief lmk04828_init
|
||||
*******************************************************************************/
|
||||
int32_t lmk04828_init(struct lmk04828_dev **device,
|
||||
const struct lmk04828_init_param *init_param)
|
||||
{
|
||||
int ret = SUCCESS;
|
||||
struct lmk04828_dev *dev;
|
||||
|
||||
dev = (struct lmk04828_dev *)malloc(sizeof(*dev));
|
||||
if (!dev)
|
||||
return FAILURE;
|
||||
|
||||
/* SPI */
|
||||
ret = spi_init(&dev->spi_desc, init_param->spi_init);
|
||||
|
||||
*device = dev;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Free the resources allocated by lmk04828_setup().
|
||||
*
|
||||
* @param dev - The device structure.
|
||||
*
|
||||
* @return SUCCESS in case of success, negative error code otherwise.
|
||||
*******************************************************************************/
|
||||
int32_t lmk04828_remove(struct lmk04828_dev *dev)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
ret = spi_remove(dev->spi_desc);
|
||||
|
||||
free(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
/***************************************************************************//**
|
||||
* @file lmk04828.h
|
||||
* @brief Header file of lmk04828 Driver.
|
||||
* @author DBogdan ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2014-2016(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
#ifndef LMK04828_H_
|
||||
#define LMK04828_H_
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
#include <stdint.h>
|
||||
#include "../../../include/delay.h"
|
||||
#include "../../../include/spi.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** Macros and Constants Definitions **********************/
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
struct lmk04828_dev {
|
||||
/* SPI */
|
||||
spi_desc *spi_desc;
|
||||
};
|
||||
|
||||
struct lmk04828_init_param {
|
||||
/* SPI */
|
||||
spi_init_param *spi_init;
|
||||
};
|
||||
|
||||
struct lmk04828_config {
|
||||
uint16_t addr;
|
||||
uint8_t value;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Declarations ******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
int32_t lmk04828_read(struct lmk04828_dev *dev,
|
||||
uint16_t reg_addr,
|
||||
uint8_t *reg_data);
|
||||
|
||||
int32_t lmk04828_write(struct lmk04828_dev *dev,
|
||||
uint16_t reg_addr,
|
||||
uint8_t reg_data);
|
||||
|
||||
int32_t lmk04828_init(struct lmk04828_dev **device,
|
||||
const struct lmk04828_init_param *init_param);
|
||||
|
||||
int32_t lmk04828_remove(struct lmk04828_dev *dev);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,79 @@
|
||||
/***************************************************************************//**
|
||||
* @file xilinx/axi_io.c
|
||||
* @brief Implementation of Xilinx AXI IO.
|
||||
* @author Antoniu Miclaus ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2019(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#include <xil_io.h>
|
||||
#include "../../include/error.h"
|
||||
#include "../../include/axi_io.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Definitions *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief AXI IO Xilinx specific read function.
|
||||
* @param base - Base address
|
||||
* @param offset - Address offset
|
||||
* @param data - variable where returned data is stored
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t axi_io_read(uint32_t base, uint32_t offset, uint32_t *data)
|
||||
{
|
||||
*data = Xil_In32(base + offset);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief AXI IO Xilinx specific write function.
|
||||
* @param base - Base address
|
||||
* @param offset - Address offset
|
||||
* @param data - data to be written.
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t axi_io_write(uint32_t base, uint32_t offset, uint32_t data)
|
||||
{
|
||||
Xil_Out32(base + offset, data);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/***************************************************************************//**
|
||||
* @file xilinx/delay.c
|
||||
* @brief Implementation of Xilinx Delay Functions.
|
||||
* @author Antoniu Miclaus ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2019(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "../../include/delay.h"
|
||||
#include <sleep.h>
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Definitions *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Generate microseconds delay.
|
||||
* @param usecs - Delay in microseconds.
|
||||
* @return None.
|
||||
*/
|
||||
void udelay(uint32_t usecs)
|
||||
{
|
||||
#ifdef _XPARAMETERS_PS_H_
|
||||
usleep(usecs);
|
||||
#else
|
||||
usleep(usecs / 20); // FIXME
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Generate miliseconds delay.
|
||||
* @param msecs - Delay in miliseconds.
|
||||
* @return None.
|
||||
*/
|
||||
void mdelay(uint32_t msecs)
|
||||
{
|
||||
#ifdef _XPARAMETERS_PS_H_
|
||||
usleep(msecs * 1000);
|
||||
#else
|
||||
usleep(msecs * 50); // FIXME
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*******************************************************************************
|
||||
* @file xilinx/gpio_extra.h
|
||||
* @brief Header containing extra types used in the gpio driver
|
||||
* @author scuciurean ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2019(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef GPIO_EXTRA_H_
|
||||
#define GPIO_EXTRA_H_
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @enum xil_gpio_type
|
||||
* @brief Xilinx platform architecture sections
|
||||
*/
|
||||
typedef enum xil_gpio_type {
|
||||
/** Programmable Logic */
|
||||
GPIO_PL,
|
||||
/** Processing System */
|
||||
GPIO_PS
|
||||
} xil_gpio_type;
|
||||
|
||||
/**
|
||||
* @struct xil_gpio_init_param
|
||||
* @brief Structure holding the initialization parameters for Xilinx platform
|
||||
* specific GPIO parameters.
|
||||
*/
|
||||
typedef struct xil_gpio_init_param {
|
||||
/** Xilinx architecture */
|
||||
enum xil_gpio_type type;
|
||||
/** Device ID */
|
||||
uint32_t device_id;
|
||||
} xil_gpio_init_param;
|
||||
|
||||
/**
|
||||
* @struct xil_gpio_desc
|
||||
* @brief Xilinx platform specific GPIO descriptor
|
||||
*/
|
||||
typedef struct xil_gpio_desc {
|
||||
/** Xilinx architecture */
|
||||
enum xil_gpio_type type;
|
||||
/** Xilinx GPIO configuration */
|
||||
void *config;
|
||||
/** Xilinx GPIO Instance */
|
||||
void *instance;
|
||||
} xil_gpio_desc;
|
||||
|
||||
/**
|
||||
* @brief Xilinx platform specific gpio platform ops structure
|
||||
*/
|
||||
extern const struct gpio_platform_ops xil_gpio_ops;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,91 @@
|
||||
/*******************************************************************************
|
||||
* @file irq_extra.h
|
||||
* @brief Header containing types used in the irq driver.
|
||||
* @author Cristian Pop ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2019(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef IRQ_EXTRA_H_
|
||||
#define IRQ_EXTRA_H_
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "../../include/irq.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @enum xil_irq_type
|
||||
* @brief Xilinx platform architecture sections
|
||||
*/
|
||||
enum xil_irq_type {
|
||||
/** Programmable Logic */
|
||||
IRQ_PL,
|
||||
/** Processing System */
|
||||
IRQ_PS
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct xil_irq_init_param
|
||||
* @brief Structure holding the initialization parameters for Xilinx platform
|
||||
* specific IRQ parameters.
|
||||
*/
|
||||
struct xil_irq_init_param {
|
||||
/** Xilinx architecture */
|
||||
enum xil_irq_type type;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct xil_irq_desc
|
||||
* @brief Xilinx platform specific IRQ descriptor
|
||||
*/
|
||||
struct xil_irq_desc {
|
||||
/** Xilinx architecture */
|
||||
enum xil_irq_type type;
|
||||
/** Xilinx IRQ Instance */
|
||||
void *instance;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Xilinx specific IRQ platform ops structure
|
||||
*/
|
||||
extern const struct irq_platform_ops xil_irq_ops;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,115 @@
|
||||
/*******************************************************************************
|
||||
* @file xilinx/spi_extra.h
|
||||
* @brief Header containing extra types used in the spi driver.
|
||||
* @author scuciurean ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2019(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
#ifndef SPI_EXTRA_H_
|
||||
#define SPI_EXTRA_H_
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "../../include/spi.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** Macros and Constants Definitions **********************/
|
||||
/******************************************************************************/
|
||||
|
||||
#define SPI_CS_DECODE 0x01
|
||||
#define SPI_DEASSERT_CURRENT_SS 0x0F
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @enum xil_spi_type
|
||||
* @brief Xilinx platform architecture sections
|
||||
*/
|
||||
enum xil_spi_type {
|
||||
/** Programmable Logic */
|
||||
SPI_PL,
|
||||
/** Processing System */
|
||||
SPI_PS,
|
||||
/** SPI Engine */
|
||||
SPI_ENGINE
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct xil_spi_init_param
|
||||
* @brief Structure holding the initialization parameters for Xilinx platform
|
||||
* specific SPI parameters when using xil_spi_ops.
|
||||
*/
|
||||
typedef struct xil_spi_init_param {
|
||||
/** Xilinx architecture */
|
||||
enum xil_spi_type type;
|
||||
/** SPI flags */
|
||||
uint32_t flags;
|
||||
} xil_spi_init_param;
|
||||
|
||||
/**
|
||||
* @struct xil_spi_desc
|
||||
* @brief Xilinx platform specific SPI descriptor
|
||||
*/
|
||||
typedef struct xil_spi_desc {
|
||||
/** Xilinx architecture */
|
||||
enum xil_spi_type type;
|
||||
/** SPI flags */
|
||||
uint32_t flags;
|
||||
/** SPI configuration */
|
||||
void *config;
|
||||
/** SPI instance */
|
||||
void *instance;
|
||||
} xil_spi_desc;
|
||||
|
||||
/**
|
||||
* @brief SPI engine platform ops structure
|
||||
*/
|
||||
extern const struct spi_platform_ops spi_eng_platform_ops;
|
||||
|
||||
/**
|
||||
* @brief Xilinx specific SPI platform ops structure
|
||||
*/
|
||||
extern const struct spi_platform_ops xil_spi_ops;
|
||||
|
||||
/**
|
||||
* @brief Xilinx SPI PS register functions. No extra param needed
|
||||
*/
|
||||
extern const struct spi_platform_ops xil_spi_reg_ops_pl;
|
||||
|
||||
#endif // SPI_EXTRA_H_
|
||||
@@ -0,0 +1,107 @@
|
||||
/*******************************************************************************
|
||||
* @file xilinx/uart_extra.h
|
||||
* @brief Header containing types used in the uart driver.
|
||||
* @author Cristian Pop ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2019(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef UART_EXTRA_H_
|
||||
#define UART_EXTRA_H_
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** Macros and Constants Definitions **********************/
|
||||
/******************************************************************************/
|
||||
|
||||
#define UART_BUFF_LENGTH 256
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @enum xil_uart_type
|
||||
* @brief Xilinx platform architecture sections
|
||||
*/
|
||||
enum xil_uart_type {
|
||||
/** Programmable Logic */
|
||||
UART_PL,
|
||||
/** Processing System */
|
||||
UART_PS
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct xil_uart_init_param
|
||||
* @brief Structure holding the initialization parameters for Xilinx platform
|
||||
* specific UART parameters.
|
||||
*/
|
||||
struct xil_uart_init_param {
|
||||
/** Xilinx architecture */
|
||||
enum xil_uart_type type;
|
||||
/** Interrupt Request ID */
|
||||
uint32_t irq_id;
|
||||
/** Interrupt Request Descriptor */
|
||||
struct irq_ctrl_desc *irq_desc;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct xil_uart_desc
|
||||
* @brief Xilinx platform specific UART descriptor
|
||||
*/
|
||||
struct xil_uart_desc {
|
||||
/** Xilinx architecture */
|
||||
enum xil_uart_type type;
|
||||
/** Interrupt Request ID */
|
||||
uint32_t irq_id;
|
||||
/** Interrupt Request Descriptor */
|
||||
struct irq_ctrl_desc *irq_desc;
|
||||
/** FIFO */
|
||||
struct fifo_element *fifo;
|
||||
/** FIFO read offset */
|
||||
uint32_t fifo_read_offset;
|
||||
/** UART Buffer */
|
||||
char buff[UART_BUFF_LENGTH];
|
||||
/** Number of bytes received */
|
||||
uint32_t bytes_received;
|
||||
/** Total number of errors */
|
||||
uint32_t total_error_count;
|
||||
/** UART Instance */
|
||||
void *instance;
|
||||
};
|
||||
|
||||
#endif
|
||||
+464
@@ -0,0 +1,464 @@
|
||||
/***************************************************************************//**
|
||||
* @file xilinx/xilinx_gpio.c
|
||||
* @brief Implementation of Xilinx GPIO Generic Driver.
|
||||
* @author Antoniu Miclaus ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2019(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <xparameters.h>
|
||||
#ifdef XPAR_XGPIO_NUM_INSTANCES
|
||||
#include <xgpio.h>
|
||||
#endif
|
||||
#ifdef XPAR_XGPIOPS_NUM_INSTANCES
|
||||
#include <xgpiops.h>
|
||||
#endif
|
||||
|
||||
#include "gpio_extra.h"
|
||||
#include "../../include/error.h"
|
||||
#include "../../include/gpio.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Definitions *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Prepare the GPIO decriptor.
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @param param - The structure that contains the GPIO parameters.
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t _gpio_init(struct gpio_desc *desc,
|
||||
const struct gpio_init_param *param)
|
||||
{
|
||||
int32_t ret;
|
||||
struct xil_gpio_desc *xdesc;
|
||||
struct xil_gpio_init_param *xinit;
|
||||
|
||||
ret = FAILURE;
|
||||
|
||||
xdesc = desc->extra;
|
||||
xinit = param->extra;
|
||||
|
||||
xdesc->type = xinit->type;
|
||||
desc->number = param->number;
|
||||
|
||||
switch (xinit->type) {
|
||||
case GPIO_PL:
|
||||
#ifdef XGPIO_H
|
||||
xdesc->instance = (XGpio *)malloc(sizeof(XGpio));
|
||||
if(!xdesc->instance)
|
||||
goto pl_error;
|
||||
|
||||
xdesc->config = XGpio_LookupConfig(xinit->device_id);
|
||||
if(xdesc->config == NULL)
|
||||
goto pl_error;
|
||||
|
||||
ret = XGpio_CfgInitialize(xdesc->instance,
|
||||
xdesc->config,
|
||||
((XGpio_Config*)xdesc->config)
|
||||
->BaseAddress);
|
||||
if(ret < 0)
|
||||
goto pl_error;
|
||||
|
||||
break;
|
||||
pl_error:
|
||||
free(xdesc->instance);
|
||||
#endif
|
||||
goto error;
|
||||
case GPIO_PS:
|
||||
#ifdef XGPIOPS_H
|
||||
xdesc->instance = (XGpioPs *)malloc(sizeof(XGpioPs));
|
||||
if(!xdesc->instance)
|
||||
goto ps_error;
|
||||
|
||||
xdesc->config = XGpioPs_LookupConfig(xinit->device_id);
|
||||
if(xdesc->config == NULL)
|
||||
goto ps_error;
|
||||
|
||||
ret = XGpioPs_CfgInitialize(xdesc->instance,
|
||||
xdesc->config,
|
||||
((XGpioPs_Config*)xdesc->config)->BaseAddr);
|
||||
if(ret < 0)
|
||||
goto ps_error;
|
||||
break;
|
||||
ps_error:
|
||||
free(xdesc->instance);
|
||||
#endif
|
||||
goto error;
|
||||
error:
|
||||
default:
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Obtain the GPIO decriptor.
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @param param - GPIO initialization parameters
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t xil_gpio_get(struct gpio_desc **desc,
|
||||
const struct gpio_init_param *param)
|
||||
{
|
||||
struct gpio_desc *descriptor;
|
||||
struct xil_gpio_desc *extra;
|
||||
int32_t ret;
|
||||
|
||||
descriptor = (struct gpio_desc *)malloc(sizeof(*descriptor));
|
||||
extra = (struct xil_gpio_desc*)malloc(sizeof(*extra));
|
||||
|
||||
if (!descriptor || !extra)
|
||||
return FAILURE;
|
||||
|
||||
descriptor->extra = extra;
|
||||
ret = _gpio_init(descriptor, param);
|
||||
|
||||
if(ret != SUCCESS)
|
||||
goto error;
|
||||
|
||||
*desc = descriptor;
|
||||
|
||||
return SUCCESS;
|
||||
error:
|
||||
free(extra);
|
||||
free(descriptor);
|
||||
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the value of an optional GPIO.
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @param param - GPIO Initialization parameters.
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t xil_gpio_get_optional(struct gpio_desc **desc,
|
||||
const struct gpio_init_param *param)
|
||||
{
|
||||
if(param == NULL) {
|
||||
*desc = NULL;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
return xil_gpio_get(desc, param);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free the resources allocated by gpio_get().
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t xil_gpio_remove(struct gpio_desc *desc)
|
||||
{
|
||||
if (desc != NULL) {
|
||||
free(((xil_gpio_desc *)(desc->extra))->instance);
|
||||
free(desc->extra);
|
||||
free(desc);
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the input direction of the specified GPIO.
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t xil_gpio_direction_input(struct gpio_desc *desc)
|
||||
{
|
||||
struct xil_gpio_desc *extra;
|
||||
#ifdef XGPIO_H
|
||||
uint8_t pin = desc->number;
|
||||
uint32_t channel = 1;
|
||||
uint32_t config = 0;
|
||||
#endif
|
||||
extra = desc->extra;
|
||||
|
||||
switch (extra->type) {
|
||||
case GPIO_PL:
|
||||
#ifdef XGPIO_H
|
||||
/* We assume that pin 32 is the first pin from channel 2 */
|
||||
if (pin >= 32) {
|
||||
channel = 2;
|
||||
pin -= 32;
|
||||
}
|
||||
|
||||
config = XGpio_GetDataDirection((XGpio *)extra->instance,
|
||||
channel);
|
||||
config |= (1 << pin);
|
||||
XGpio_SetDataDirection((XGpio *)extra->instance,
|
||||
channel,
|
||||
config);
|
||||
#endif
|
||||
break;
|
||||
case GPIO_PS:
|
||||
#ifdef XGPIOPS_H
|
||||
XGpioPs_SetDirectionPin(extra->instance,
|
||||
desc->number,
|
||||
GPIO_IN);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the output direction of the specified GPIO.
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @param value - The value.
|
||||
* Example: GPIO_HIGH
|
||||
* GPIO_LOW
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t xil_gpio_direction_output(struct gpio_desc *desc,
|
||||
uint8_t value)
|
||||
{
|
||||
struct xil_gpio_desc *extra;
|
||||
#ifdef XGPIO_H
|
||||
uint8_t pin = desc->number;
|
||||
uint8_t channel;
|
||||
uint32_t reg_val;
|
||||
#endif
|
||||
extra = desc->extra;
|
||||
|
||||
switch (extra->type) {
|
||||
case GPIO_PL:
|
||||
#ifdef XGPIO_H
|
||||
if (pin >= 32) {
|
||||
channel = 2;
|
||||
pin -= 32;
|
||||
} else
|
||||
channel = 1;
|
||||
|
||||
reg_val = XGpio_GetDataDirection(extra->instance,
|
||||
channel);
|
||||
reg_val &= ~(1 << pin);
|
||||
XGpio_SetDataDirection(extra->instance,
|
||||
channel,
|
||||
reg_val);
|
||||
reg_val = XGpio_DiscreteRead(extra->instance,
|
||||
channel);
|
||||
if(value)
|
||||
reg_val |= (1 << pin);
|
||||
else
|
||||
reg_val &= ~(1 << pin);
|
||||
XGpio_DiscreteWrite(extra->instance,
|
||||
channel,
|
||||
reg_val);
|
||||
#endif
|
||||
break;
|
||||
case GPIO_PS:
|
||||
#ifdef XGPIOPS_H
|
||||
XGpioPs_SetDirectionPin(extra->instance,
|
||||
desc->number,
|
||||
GPIO_OUT);
|
||||
XGpioPs_SetOutputEnablePin(extra->instance,
|
||||
desc->number,
|
||||
GPIO_OUT);
|
||||
XGpioPs_WritePin(extra->instance,
|
||||
desc->number,
|
||||
value);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the direction of the specified GPIO.
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @param direction - The direction.
|
||||
* Example: GPIO_OUT
|
||||
* GPIO_IN
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t xil_gpio_get_direction(struct gpio_desc *desc,
|
||||
uint8_t *direction)
|
||||
{
|
||||
if (!desc)
|
||||
return FAILURE;
|
||||
|
||||
struct xil_gpio_desc *extra;
|
||||
uint8_t pin = desc->number;
|
||||
|
||||
#ifdef XGPIO_H
|
||||
uint8_t channel;
|
||||
#endif
|
||||
extra = desc->extra;
|
||||
|
||||
switch (extra->type) {
|
||||
case GPIO_PL:
|
||||
#ifdef XGPIO_H
|
||||
if (pin >= 32) {
|
||||
channel = 2;
|
||||
pin -= 32;
|
||||
} else
|
||||
channel = 1;
|
||||
*direction = ((XGpio_GetDataDirection(extra->instance,
|
||||
channel) >> pin) & 0x1) ^ 0x1;
|
||||
#endif
|
||||
break;
|
||||
case GPIO_PS:
|
||||
#ifdef XGPIOPS_H
|
||||
*direction = XGpioPs_GetDirectionPin(extra->instance, pin);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the value of the specified GPIO.
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @param value - The value.
|
||||
* Example: GPIO_HIGH
|
||||
* GPIO_LOW
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t xil_gpio_set_value(struct gpio_desc *desc,
|
||||
uint8_t value)
|
||||
{
|
||||
struct xil_gpio_desc *extra;
|
||||
#ifdef XGPIO_H
|
||||
uint8_t pin = desc->number;
|
||||
uint8_t channel;
|
||||
uint32_t reg_val;
|
||||
#endif
|
||||
extra = desc->extra;
|
||||
|
||||
switch (extra->type) {
|
||||
case GPIO_PL:
|
||||
#ifdef XGPIO_H
|
||||
if (pin >= 32) {
|
||||
channel = 2;
|
||||
pin -= 32;
|
||||
} else
|
||||
channel = 1;
|
||||
|
||||
reg_val = XGpio_DiscreteRead(extra->instance, channel);
|
||||
if(value)
|
||||
reg_val |= (1 << pin);
|
||||
else
|
||||
reg_val &= ~(1 << pin);
|
||||
XGpio_DiscreteWrite(extra->instance, channel, reg_val);
|
||||
#endif
|
||||
break;
|
||||
case GPIO_PS:
|
||||
#ifdef XGPIOPS_H
|
||||
XGpioPs_WritePin(extra->instance, desc->number, value);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the value of the specified GPIO.
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @param value - The value.
|
||||
* Example: GPIO_HIGH
|
||||
* GPIO_LOW
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t xil_gpio_get_value(struct gpio_desc *desc,
|
||||
uint8_t *value)
|
||||
{
|
||||
if (!desc)
|
||||
return FAILURE;
|
||||
|
||||
struct xil_gpio_desc *extra;
|
||||
uint8_t pin = desc->number;
|
||||
|
||||
#ifdef XGPIO_H
|
||||
uint8_t channel;
|
||||
#endif
|
||||
extra = desc->extra;
|
||||
|
||||
switch (extra->type) {
|
||||
case GPIO_PL:
|
||||
#ifdef XGPIO_H
|
||||
if (pin >= 32) {
|
||||
channel = 2;
|
||||
pin -= 32;
|
||||
} else
|
||||
channel = 1;
|
||||
*value = (XGpio_DiscreteRead(extra->instance, channel) >> pin) & 0x01;
|
||||
#endif
|
||||
break;
|
||||
case GPIO_PS:
|
||||
#ifdef XGPIOPS_H
|
||||
*value = XGpioPs_ReadPin(extra->instance, pin);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Xilinx platform specific GPIO platform ops structure
|
||||
*/
|
||||
const struct gpio_platform_ops xil_gpio_ops = {
|
||||
.gpio_ops_get = &xil_gpio_get,
|
||||
.gpio_ops_get_optional = &xil_gpio_get_optional,
|
||||
.gpio_ops_remove = &xil_gpio_remove,
|
||||
.gpio_ops_direction_input = &xil_gpio_direction_input,
|
||||
.gpio_ops_direction_output = &xil_gpio_direction_output,
|
||||
.gpio_ops_get_direction = &xil_gpio_get_direction,
|
||||
.gpio_ops_set_value = &xil_gpio_set_value,
|
||||
.gpio_ops_get_value = &xil_gpio_get_value,
|
||||
};
|
||||
@@ -0,0 +1,384 @@
|
||||
/***************************************************************************//**
|
||||
* @file xilinx/xilinx_irq.c
|
||||
* @brief Implementation of Xilinx IRQ Generic Driver.
|
||||
* @author Cristian Pop ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2019(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#include <xparameters.h>
|
||||
#include <stdlib.h>
|
||||
#include "irq_extra.h"
|
||||
#include "../../include/irq.h"
|
||||
#include "../../include/error.h"
|
||||
#ifdef XPAR_XSCUGIC_NUM_INSTANCES
|
||||
#include <xscugic.h>
|
||||
#endif
|
||||
#ifdef XPAR_XINTC_NUM_INSTANCES
|
||||
#include <xintc.h>
|
||||
#endif
|
||||
#ifdef XPAR_XTMRCTR_NUM_INSTANCES
|
||||
#include <xtmrctr.h>
|
||||
#endif
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Definitions *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Initialize the IRQ interrupts.
|
||||
* @param desc - The IRQ controller descriptor.
|
||||
* @param param - The structure that contains the IRQ parameters.
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t xil_irq_ctrl_init(struct irq_ctrl_desc **desc,
|
||||
const struct irq_init_param *param)
|
||||
{
|
||||
int32_t status;
|
||||
struct irq_ctrl_desc *descriptor;
|
||||
struct xil_irq_desc *xil_dev;
|
||||
#ifdef XSCUGIC_H
|
||||
void *config;
|
||||
#endif
|
||||
|
||||
descriptor = (struct irq_ctrl_desc *)calloc(1, sizeof *descriptor);
|
||||
if(!descriptor)
|
||||
return FAILURE;
|
||||
xil_dev = (struct xil_irq_desc *)calloc(1, sizeof *xil_dev);
|
||||
if(!xil_dev) {
|
||||
free(descriptor);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
Xil_ExceptionInit();
|
||||
|
||||
descriptor->irq_ctrl_id = param->irq_ctrl_id;
|
||||
descriptor->extra = xil_dev;
|
||||
xil_dev->type = ((struct xil_irq_init_param *)param->extra)->type;
|
||||
|
||||
switch(xil_dev->type) {
|
||||
case IRQ_PS:
|
||||
#ifdef XSCUGIC_H
|
||||
xil_dev->instance = calloc(1, sizeof(XScuGic));
|
||||
if(!xil_dev->instance)
|
||||
goto error;
|
||||
|
||||
config = XScuGic_LookupConfig(descriptor->irq_ctrl_id);
|
||||
if(!config)
|
||||
goto ps_error;
|
||||
|
||||
status = XScuGic_CfgInitialize(xil_dev->instance, config,
|
||||
((XScuGic_Config *)config)->CpuBaseAddress);
|
||||
if (status != SUCCESS)
|
||||
goto ps_error;
|
||||
|
||||
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
|
||||
(Xil_ExceptionHandler)XScuGic_InterruptHandler,
|
||||
xil_dev->instance);
|
||||
|
||||
break;
|
||||
ps_error:
|
||||
free(xil_dev->instance);
|
||||
#endif
|
||||
goto error;
|
||||
case IRQ_PL:
|
||||
#ifdef XINTC_H
|
||||
xil_dev->instance = calloc(1, sizeof(XIntc));
|
||||
if(!xil_dev->instance)
|
||||
goto error;
|
||||
|
||||
status = XIntc_Initialize(xil_dev->instance, descriptor->irq_ctrl_id);
|
||||
if(status != SUCCESS)
|
||||
goto pl_error;
|
||||
|
||||
status = XIntc_Start(xil_dev->instance, XIN_REAL_MODE);
|
||||
if(status != SUCCESS)
|
||||
goto pl_error;
|
||||
|
||||
break;
|
||||
pl_error:
|
||||
free(xil_dev->instance);
|
||||
#endif
|
||||
goto error;
|
||||
default:
|
||||
goto error;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
*desc = descriptor;
|
||||
|
||||
return SUCCESS;
|
||||
|
||||
error:
|
||||
free(xil_dev);
|
||||
free(descriptor);
|
||||
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable global interrupts.
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t xil_irq_global_enable(struct irq_ctrl_desc *desc)
|
||||
{
|
||||
/* Enable interrupts */
|
||||
Xil_ExceptionEnable();
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable global interrupts.
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t xil_irq_global_disable(struct irq_ctrl_desc *desc)
|
||||
{
|
||||
/* Disable interrupts */
|
||||
Xil_ExceptionDisable();
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable specific interrupt.
|
||||
* @param desc - The IRQ controller descriptor.
|
||||
* @param irq_id - Interrupt identifier.
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t xil_irq_enable(struct irq_ctrl_desc *desc, uint32_t irq_id)
|
||||
{
|
||||
struct xil_irq_desc *xil_dev = desc->extra;
|
||||
|
||||
switch(xil_dev->type) {
|
||||
case IRQ_PS:
|
||||
#ifdef XSCUGIC_H
|
||||
XScuGic_Enable(xil_dev->instance, irq_id);
|
||||
#endif
|
||||
break;
|
||||
case IRQ_PL:
|
||||
#ifdef XINTC_H
|
||||
XIntc_Enable(xil_dev->instance, irq_id);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable specific interrupt.
|
||||
* @param desc - The IRQ controller descriptor.
|
||||
* @param irq_id - Interrupt identifier.
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t xil_irq_disable(struct irq_ctrl_desc *desc, uint32_t irq_id)
|
||||
{
|
||||
struct xil_irq_desc *xil_dev = desc->extra;
|
||||
|
||||
switch(xil_dev->type) {
|
||||
case IRQ_PS:
|
||||
#ifdef XSCUGIC_H
|
||||
XScuGic_Disable(xil_dev->instance, irq_id);
|
||||
#endif
|
||||
break;
|
||||
case IRQ_PL:
|
||||
#ifdef XINTC_H
|
||||
XIntc_Disable(xil_dev->instance, irq_id);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Register a callback to handle the irq events.
|
||||
* @param desc - The IRQ controller descriptor.
|
||||
* @param irq_id - Interrupt identifier.
|
||||
* @param callback_desc - Callback descriptor
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t xil_irq_register_callback(struct irq_ctrl_desc *desc, uint32_t irq_id,
|
||||
struct callback_desc *callback_desc)
|
||||
{
|
||||
struct xil_irq_desc *xil_dev = desc->extra;
|
||||
|
||||
switch(xil_dev->type) {
|
||||
case IRQ_PS:
|
||||
#ifdef XSCUGIC_H
|
||||
return XScuGic_Connect(xil_dev->instance, irq_id,
|
||||
(Xil_InterruptHandler) callback_desc->callback,
|
||||
callback_desc->ctx);
|
||||
#endif
|
||||
break;
|
||||
case IRQ_PL:
|
||||
#ifdef XINTC_H
|
||||
if (irq_id == XPAR_AXI_INTC_AXI_TIMER_INTERRUPT_INTR) {
|
||||
int32_t ret;
|
||||
|
||||
ret = XIntc_Connect(xil_dev->instance, irq_id,
|
||||
XTmrCtr_InterruptHandler, callback_desc->config);
|
||||
if (IS_ERR_VALUE(ret))
|
||||
return FAILURE;
|
||||
XTmrCtr_SetHandler(callback_desc->config,
|
||||
(XTmrCtr_Handler)callback_desc->callback,
|
||||
callback_desc->ctx);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
return XIntc_Connect(xil_dev->instance, irq_id,
|
||||
(XInterruptHandler) callback_desc->callback,
|
||||
callback_desc->ctx);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set interrupt trigger level.
|
||||
* @param desc - The IRQ controller descriptor.
|
||||
* @param irq_id - Interrupt identifier.
|
||||
* @param trig - New trigger level for the interrupt.
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t xil_irq_trigger_level_set(struct irq_ctrl_desc *desc, uint32_t irq_id,
|
||||
enum irq_trig_level trig)
|
||||
{
|
||||
struct xil_irq_desc *xil_dev = desc->extra;
|
||||
|
||||
if(trig == IRQ_EDGE_BOTH)
|
||||
return -EINVAL;
|
||||
|
||||
switch(xil_dev->type) {
|
||||
case IRQ_PS:
|
||||
#ifdef XSCUGIC_H
|
||||
;
|
||||
uint8_t priority, trigger;
|
||||
|
||||
XScuGic_GetPriorityTriggerType(xil_dev->instance, irq_id, &priority,
|
||||
&trigger);
|
||||
trigger = trig;
|
||||
XScuGic_SetPriorityTriggerType(xil_dev->instance, irq_id, priority,
|
||||
trigger);
|
||||
|
||||
return SUCCESS;
|
||||
#endif
|
||||
break;
|
||||
case IRQ_PL:
|
||||
#ifdef XINTC_H
|
||||
/* Interrupt trigger determined in hardware. TODO: verify */
|
||||
return SUCCESS;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unregisters a generic IRQ handling function.
|
||||
* @param desc - The IRQ controller descriptor.
|
||||
* @param irq_id - Interrupt identifier.
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t xil_irq_unregister(struct irq_ctrl_desc *desc, uint32_t irq_id)
|
||||
{
|
||||
struct xil_irq_desc *xil_dev = desc->extra;
|
||||
|
||||
switch(xil_dev->type) {
|
||||
case IRQ_PS:
|
||||
#ifdef XSCUGIC_H
|
||||
XScuGic_Disconnect(xil_dev->instance, irq_id);
|
||||
#endif
|
||||
break;
|
||||
case IRQ_PL:
|
||||
#ifdef XINTC_H
|
||||
XIntc_Disconnect(xil_dev->instance, irq_id);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free the resources allocated by irq_ctrl_init().
|
||||
* @param desc - The IRQ control descriptor.
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t xil_irq_ctrl_remove(struct irq_ctrl_desc *desc)
|
||||
{
|
||||
struct xil_irq_desc *xil_dev = desc->extra;
|
||||
free(xil_dev->instance);
|
||||
free(desc->extra);
|
||||
free(desc);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Xilinx platform specific IRQ platform ops structure
|
||||
*/
|
||||
const struct irq_platform_ops xil_irq_ops = {
|
||||
.init = &xil_irq_ctrl_init,
|
||||
.register_callback = &xil_irq_register_callback,
|
||||
.unregister = &xil_irq_unregister,
|
||||
.global_enable = &xil_irq_global_enable,
|
||||
.global_disable = &xil_irq_global_disable,
|
||||
.trigger_level_set = &xil_irq_trigger_level_set,
|
||||
.enable = &xil_irq_enable,
|
||||
.disable = &xil_irq_disable,
|
||||
.remove = &xil_irq_ctrl_remove
|
||||
};
|
||||
@@ -0,0 +1,461 @@
|
||||
/***************************************************************************//**
|
||||
* @file xilinx/xilinx_spi.c
|
||||
* @brief Implementation of Xilinx SPI Generic Driver.
|
||||
* @author Antoniu Miclaus ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2019(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <xparameters.h>
|
||||
#ifdef XPAR_XSPI_NUM_INSTANCES
|
||||
#include <xspi.h>
|
||||
#endif
|
||||
#ifdef XPAR_XSPIPS_NUM_INSTANCES
|
||||
#include <xspips.h>
|
||||
#endif
|
||||
|
||||
#include "../../include/error.h"
|
||||
#include "../../include/spi.h"
|
||||
#include "spi_extra.h"
|
||||
|
||||
#if defined(PLATFORM_ZYNQ)
|
||||
#define SPI_CLK_FREQ_HZ(dev) (XPAR_PS7_SPI_ ## dev ## _SPI_CLK_FREQ_HZ)
|
||||
#define SPI_NUM_INSTANCES XPAR_XSPIPS_NUM_INSTANCES
|
||||
#elif defined(PLATFORM_ZYNQMP)
|
||||
#define SPI_CLK_FREQ_HZ(dev) (XPAR_PSU_SPI_ ## dev ## _SPI_CLK_FREQ_HZ)
|
||||
#define SPI_NUM_INSTANCES XPAR_XSPIPS_NUM_INSTANCES
|
||||
#else
|
||||
#define SPI_NUM_INSTANCES 0
|
||||
#endif
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Definitions *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Initialize the hardware SPI peripherial
|
||||
*
|
||||
* @param xdesc Platform specific SPI descriptor
|
||||
* @param xinit Platform specific SPI init param
|
||||
* @return int32_t FAILURE if the device couldn't be found or configured
|
||||
*/
|
||||
static int32_t spi_init_pl(struct spi_desc *desc,
|
||||
const struct spi_init_param *param)
|
||||
{
|
||||
#ifdef XSPI_H
|
||||
int32_t ret;
|
||||
struct xil_spi_desc *xdesc;
|
||||
struct xil_spi_init_param *xinit;
|
||||
|
||||
xdesc = (xil_spi_desc*)malloc(sizeof(xil_spi_desc));
|
||||
if(!xdesc) {
|
||||
free(xdesc);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
desc->extra = xdesc;
|
||||
xinit = param->extra;
|
||||
xdesc->type = xinit->type;
|
||||
xdesc->flags = xinit->flags;
|
||||
|
||||
xdesc->instance = (XSpi*)calloc(1, sizeof(XSpi));
|
||||
if(!xdesc->instance)
|
||||
goto pl_error;
|
||||
|
||||
xdesc->config = XSpi_LookupConfig(param->device_id);
|
||||
if(xdesc->config == NULL)
|
||||
goto pl_error;
|
||||
|
||||
ret = XSpi_CfgInitialize(xdesc->instance,
|
||||
xdesc->config,
|
||||
((XSpi_Config*)xdesc->config)
|
||||
->BaseAddress);
|
||||
if(ret != SUCCESS)
|
||||
goto pl_error;
|
||||
|
||||
ret = XSpi_Initialize(xdesc->instance, param->device_id);
|
||||
if (ret != SUCCESS)
|
||||
goto pl_error;
|
||||
|
||||
ret = XSpi_SetOptions(xdesc->instance,
|
||||
XSP_MASTER_OPTION |
|
||||
((desc->mode & SPI_CPOL) ?
|
||||
XSP_CLK_ACTIVE_LOW_OPTION : 0) |
|
||||
((desc->mode & SPI_CPHA) ?
|
||||
XSP_CLK_PHASE_1_OPTION : 0));
|
||||
if (ret != SUCCESS)
|
||||
goto pl_error;
|
||||
|
||||
ret = XSpi_Start(xdesc->instance);
|
||||
if (ret != SUCCESS)
|
||||
goto pl_error;
|
||||
|
||||
XSpi_IntrGlobalDisable((XSpi *)(xdesc->instance));
|
||||
|
||||
return SUCCESS;
|
||||
|
||||
pl_error:
|
||||
free(xdesc->instance);
|
||||
free(xdesc);
|
||||
#endif
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the hardware SPI peripherial
|
||||
*
|
||||
* @param xdesc Platform specific SPI descriptor
|
||||
* @param xinit Platform specific SPI init param
|
||||
* @return int32_t FAILURE if the device couldn't be found or configured
|
||||
*/
|
||||
static int32_t spi_init_ps(struct spi_desc *desc,
|
||||
const struct spi_init_param *param)
|
||||
{
|
||||
#ifdef XSPIPS_H
|
||||
int32_t ret;
|
||||
struct xil_spi_desc *xdesc;
|
||||
struct xil_spi_init_param *xinit;
|
||||
const uint32_t prescaler_default = XSPIPS_CLK_PRESCALE_64;
|
||||
const uint32_t prescaler_min = XSPIPS_CLK_PRESCALE_4;
|
||||
const uint32_t prescaler_max = XSPIPS_CLK_PRESCALE_256;
|
||||
uint32_t prescaler = 0u;
|
||||
uint32_t input_clock = 0u;
|
||||
|
||||
xdesc = (xil_spi_desc*)malloc(sizeof(xil_spi_desc));
|
||||
if(!xdesc) {
|
||||
free(xdesc);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
desc->extra = xdesc;
|
||||
xinit = param->extra;
|
||||
xdesc->type = xinit->type;
|
||||
xdesc->flags = xinit->flags;
|
||||
|
||||
xdesc->instance = (XSpiPs*)malloc(sizeof(XSpiPs));
|
||||
if(!xdesc->instance)
|
||||
goto ps_error;
|
||||
|
||||
xdesc->config = XSpiPs_LookupConfig(param->device_id);
|
||||
if(xdesc->config == NULL)
|
||||
goto ps_error;
|
||||
|
||||
ret = XSpiPs_CfgInitialize(xdesc->instance,
|
||||
xdesc->config,
|
||||
((XSpiPs_Config*)xdesc->config)
|
||||
->BaseAddress);
|
||||
if(ret != SUCCESS)
|
||||
goto ps_error;
|
||||
|
||||
switch (param->device_id) {
|
||||
#if (SPI_NUM_INSTANCES >= 1)
|
||||
case 0:
|
||||
input_clock = SPI_CLK_FREQ_HZ(0);
|
||||
break;
|
||||
#endif
|
||||
#if (SPI_NUM_INSTANCES >= 2)
|
||||
case 1:
|
||||
input_clock = SPI_CLK_FREQ_HZ(1);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
goto ps_error;
|
||||
};
|
||||
|
||||
if (desc->max_speed_hz != 0u) {
|
||||
uint32_t div = input_clock / desc->max_speed_hz;
|
||||
uint32_t rem = input_clock % desc->max_speed_hz;
|
||||
uint32_t po2 = !(div & (div - 1)) && !rem;
|
||||
|
||||
// find the power of two just higher than div and
|
||||
// store the exponent in prescaler
|
||||
while(div) {
|
||||
prescaler += 1;
|
||||
div >>= 1u;
|
||||
}
|
||||
|
||||
// this exponent - 1 is needed because of the way
|
||||
// xilinx stores it into registers
|
||||
if (prescaler)
|
||||
prescaler -= 1;
|
||||
|
||||
// this exponent - 1 is needed when initial div was
|
||||
// precisely a power of two
|
||||
if (prescaler && po2)
|
||||
prescaler -= 1;
|
||||
|
||||
if (prescaler < prescaler_min)
|
||||
prescaler = prescaler_min;
|
||||
|
||||
if (prescaler > prescaler_max)
|
||||
prescaler = prescaler_max;
|
||||
} else
|
||||
prescaler = prescaler_default;
|
||||
|
||||
ret = XSpiPs_SetClkPrescaler(xdesc->instance, prescaler);
|
||||
|
||||
if(ret != SUCCESS)
|
||||
goto ps_error;
|
||||
|
||||
return SUCCESS;
|
||||
|
||||
ps_error:
|
||||
free(xdesc->instance);
|
||||
free(xdesc);
|
||||
#endif
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the SPI communication peripheral.
|
||||
* @param desc - The SPI descriptor.
|
||||
* @param param - The structure that contains the SPI parameters.
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t xil_spi_init(struct spi_desc **desc,
|
||||
const struct spi_init_param *param)
|
||||
{
|
||||
int32_t ret;
|
||||
enum xil_spi_type *spi_type;
|
||||
|
||||
if (!param) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
*desc = malloc(sizeof(**desc));
|
||||
if(! *desc) {
|
||||
free(*desc);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
spi_type = param->extra;
|
||||
|
||||
if(!spi_type)
|
||||
goto init_error;
|
||||
|
||||
(*desc)->max_speed_hz = param->max_speed_hz;
|
||||
(*desc)->mode = param->mode;
|
||||
(*desc)->bit_order = param->bit_order;
|
||||
(*desc)->chip_select = param->chip_select;
|
||||
|
||||
switch (*spi_type) {
|
||||
case SPI_PL:
|
||||
ret = spi_init_pl(*desc, param);
|
||||
break;
|
||||
case SPI_PS:
|
||||
ret = spi_init_ps(*desc, param);
|
||||
break;
|
||||
|
||||
default:
|
||||
goto init_error;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret != SUCCESS) {
|
||||
init_error:
|
||||
free(*desc);
|
||||
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free the resources allocated by spi_init().
|
||||
* @param desc - The SPI descriptor.
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t xil_spi_remove(struct spi_desc *desc)
|
||||
{
|
||||
#ifdef XSPI_H
|
||||
int32_t ret;
|
||||
#endif
|
||||
struct xil_spi_desc *xdesc = NULL;
|
||||
enum xil_spi_type *spi_type;
|
||||
|
||||
spi_type = desc->extra;
|
||||
|
||||
if(!spi_type)
|
||||
return FAILURE;
|
||||
|
||||
switch (*spi_type ) {
|
||||
case SPI_PL:
|
||||
#ifdef XSPI_H
|
||||
xdesc = desc->extra;
|
||||
|
||||
if(!xdesc)
|
||||
return FAILURE;
|
||||
|
||||
ret = XSpi_Stop((XSpi *)(xdesc->instance));
|
||||
if(ret != SUCCESS)
|
||||
goto error;
|
||||
#endif
|
||||
break;
|
||||
case SPI_PS:
|
||||
#ifdef XSPIPS_H
|
||||
xdesc = desc->extra;
|
||||
|
||||
if(!xdesc)
|
||||
return FAILURE;
|
||||
#endif
|
||||
break;
|
||||
|
||||
/* Intended fallthrough */
|
||||
#ifdef XSPI_H
|
||||
error:
|
||||
#endif
|
||||
default:
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if(xdesc)
|
||||
free(xdesc->instance);
|
||||
free(desc->extra);
|
||||
free(desc);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write and read data to/from SPI.
|
||||
* @param desc - The SPI descriptor.
|
||||
* @param data - The buffer with the transmitted/received data.
|
||||
* @param bytes_number - Number of bytes to write/read.
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t xil_spi_write_and_read(struct spi_desc *desc,
|
||||
uint8_t *data,
|
||||
uint16_t bytes_number)
|
||||
{
|
||||
int32_t ret;
|
||||
#ifdef XSPI_H
|
||||
uint32_t ctrl_reg;
|
||||
#endif
|
||||
struct xil_spi_desc *xdesc;
|
||||
enum xil_spi_type *spi_type;
|
||||
|
||||
ret = FAILURE;
|
||||
|
||||
spi_type = desc->extra;
|
||||
|
||||
if(!spi_type)
|
||||
return FAILURE;
|
||||
|
||||
xdesc = desc->extra;
|
||||
|
||||
switch (*spi_type) {
|
||||
case SPI_PL:
|
||||
#ifdef XSPI_H
|
||||
ret = XSpi_SetOptions(xdesc->instance,
|
||||
XSP_MASTER_OPTION |
|
||||
((desc->mode & SPI_CPOL) ?
|
||||
XSP_CLK_ACTIVE_LOW_OPTION : 0) |
|
||||
((desc->mode & SPI_CPHA) ?
|
||||
XSP_CLK_PHASE_1_OPTION : 0));
|
||||
if (ret != SUCCESS)
|
||||
goto error;
|
||||
|
||||
ctrl_reg = XSpi_GetControlReg(((XSpi*)xdesc->instance));
|
||||
if (desc->bit_order == SPI_BIT_ORDER_LSB_FIRST)
|
||||
ctrl_reg |= XSP_CR_LSB_MSB_FIRST_MASK;
|
||||
else
|
||||
ctrl_reg &= ~ XSP_CR_LSB_MSB_FIRST_MASK;
|
||||
XSpi_SetControlReg(((XSpi*)xdesc->instance), ctrl_reg);
|
||||
|
||||
ret = XSpi_SetSlaveSelect(xdesc->instance,
|
||||
0x01 << desc->chip_select);
|
||||
if (ret != SUCCESS)
|
||||
goto error;
|
||||
|
||||
ret = XSpi_Transfer(xdesc->instance,
|
||||
data,
|
||||
data,
|
||||
bytes_number);
|
||||
if (ret != SUCCESS)
|
||||
goto error;
|
||||
#endif
|
||||
break;
|
||||
case SPI_PS:
|
||||
#ifdef XSPIPS_H
|
||||
ret = XSpiPs_SetOptions(xdesc->instance,
|
||||
XSPIPS_MASTER_OPTION |
|
||||
((xdesc->flags & SPI_CS_DECODE) ?
|
||||
XSPIPS_DECODE_SSELECT_OPTION : 0) |
|
||||
XSPIPS_FORCE_SSELECT_OPTION |
|
||||
((desc->mode & SPI_CPOL) ?
|
||||
XSPIPS_CLK_ACTIVE_LOW_OPTION : 0) |
|
||||
((desc->mode & SPI_CPHA) ?
|
||||
XSPIPS_CLK_PHASE_1_OPTION : 0));
|
||||
if (ret != SUCCESS)
|
||||
goto error;
|
||||
|
||||
ret = XSpiPs_SetSlaveSelect(xdesc->instance,
|
||||
desc->chip_select);
|
||||
if (ret != SUCCESS)
|
||||
goto error;
|
||||
ret = XSpiPs_PolledTransfer(xdesc->instance,
|
||||
data,
|
||||
data,
|
||||
bytes_number);
|
||||
if (ret != SUCCESS)
|
||||
goto error;
|
||||
ret = XSpiPs_SetSlaveSelect(xdesc->instance, SPI_DEASSERT_CURRENT_SS);
|
||||
if (ret != SUCCESS)
|
||||
goto error;
|
||||
#endif
|
||||
break;
|
||||
error:
|
||||
default:
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Xilinx platform specific SPI platform ops structure
|
||||
*/
|
||||
const struct spi_platform_ops xil_spi_ops = {
|
||||
.init = &xil_spi_init,
|
||||
.write_and_read = &xil_spi_write_and_read,
|
||||
.write_and_read_3wire = NULL, // Not support.
|
||||
.remove = &xil_spi_remove
|
||||
};
|
||||
+531
@@ -0,0 +1,531 @@
|
||||
/*******************************************************************************
|
||||
* @file xilinx/xilinx_spi_pl.c
|
||||
* @brief Driver for spi pl device using registers
|
||||
* @author Mihail Chindris ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2021(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
#include <xparameters.h>
|
||||
|
||||
#ifdef XPAR_XSPI_NUM_INSTANCES
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#include <xspi.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include "spi.h"
|
||||
#include "error.h"
|
||||
#include "delay.h"
|
||||
#include "util.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** Macros and Constants Definitions **********************/
|
||||
/******************************************************************************/
|
||||
|
||||
#define XPS_TYPE_WRITE 0x1
|
||||
#define XPS_TYPE_READ 0x2
|
||||
#define XSP_DEFAULT_SR_VALUE 0x25
|
||||
#define XSP_DUMMY_DATA 0xFF
|
||||
|
||||
/*
|
||||
* Used to store current spi device configuration in order to not update it for
|
||||
* each spi transaction if not needed.
|
||||
*/
|
||||
static struct spi_desc g_spi_desc[XPAR_XSPI_NUM_INSTANCES];
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/* Xilinx PL spi specific data */
|
||||
struct xspi_desc {
|
||||
uint32_t base_addr;
|
||||
uint32_t disable_slaves_mask;
|
||||
uint32_t fifo_depth;
|
||||
uint8_t cs_asserted;
|
||||
};
|
||||
|
||||
/* Structure used to iterate over SPI messages */
|
||||
struct msg_iter {
|
||||
struct spi_msg *msgs;
|
||||
uint32_t len;
|
||||
uint32_t i;
|
||||
uint32_t buff_i;
|
||||
uint8_t is_wr;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Definitions *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/* Read device register */
|
||||
static inline uint32_t _read(struct xspi_desc *xdesc, uint32_t reg)
|
||||
{
|
||||
return Xil_In32(xdesc->base_addr + reg);
|
||||
}
|
||||
|
||||
/* Write device register */
|
||||
static inline void _write(struct xspi_desc *xdesc, uint32_t reg, uint32_t val)
|
||||
{
|
||||
Xil_Out32(xdesc->base_addr + reg, val);
|
||||
}
|
||||
|
||||
/* Update device register. Only bits set to 1 in mask will be modified */
|
||||
static inline void _wr_mask(struct xspi_desc *xdesc, uint32_t reg,
|
||||
uint32_t val, uint32_t mask)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
tmp = _read(xdesc, reg);
|
||||
tmp &= ~mask;
|
||||
tmp |= val & mask;
|
||||
_write(xdesc, reg, tmp);
|
||||
}
|
||||
|
||||
/* Update spi device configuration if needed */
|
||||
static void _update_mode(struct spi_desc *desc)
|
||||
{
|
||||
uint32_t val;
|
||||
uint32_t mask;
|
||||
|
||||
if (desc->mode == g_spi_desc[desc->device_id].mode &&
|
||||
desc->bit_order == g_spi_desc[desc->device_id].bit_order)
|
||||
return ;
|
||||
|
||||
/* Update mode */
|
||||
val = desc->mode | SPI_CPOL ? XSP_CR_CLK_POLARITY_MASK : 0;
|
||||
val |= desc->mode | SPI_CPHA ? XSP_CR_CLK_PHASE_MASK : 0;
|
||||
mask = XSP_CR_CLK_POLARITY_MASK | XSP_CR_CLK_PHASE_MASK;
|
||||
|
||||
val |= desc->bit_order == SPI_BIT_ORDER_LSB_FIRST ?
|
||||
XSP_CR_LSB_MSB_FIRST_MASK : 0;
|
||||
mask |= XSP_CR_LSB_MSB_FIRST_MASK;
|
||||
|
||||
_wr_mask(desc->extra, XSP_CR_OFFSET, val, mask);
|
||||
g_spi_desc[desc->device_id] = *desc;
|
||||
}
|
||||
|
||||
/* Configure SPI PL device */
|
||||
static int32_t _xil_spi_init_dev(struct xspi_desc *xdesc)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
/* Software reset */
|
||||
_write(xdesc, XSP_SRR_OFFSET, XSP_SRR_RESET_MASK);
|
||||
mdelay(1);
|
||||
|
||||
/* Check if success reset */
|
||||
val = _read(xdesc, XSP_SR_OFFSET);
|
||||
if (val != XSP_DEFAULT_SR_VALUE)
|
||||
return -ENODEV;
|
||||
|
||||
/* Disable interrupts. Drivers only works with pooled mode */
|
||||
_write(xdesc, XSP_IIER_OFFSET, 0);
|
||||
|
||||
/* Deasert chip selects */
|
||||
_write(xdesc, XSP_SSR_OFFSET, 0xFFFFFFFF);
|
||||
|
||||
/* Get fifo depth */
|
||||
while (!(_read(xdesc, XSP_SR_OFFSET) & XSP_SR_TX_FULL_MASK))
|
||||
_write(xdesc, XSP_DTR_OFFSET, XSP_DUMMY_DATA);
|
||||
xdesc->fifo_depth = _read(xdesc, XSP_TFO_OFFSET) + 1;
|
||||
|
||||
/* Configure spi device */
|
||||
val = XSP_CR_ENABLE_MASK |
|
||||
XSP_CR_MANUAL_SS_MASK |
|
||||
XSP_CR_TXFIFO_RESET_MASK |
|
||||
XSP_CR_RXFIFO_RESET_MASK |
|
||||
XSP_CR_MASTER_MODE_MASK |
|
||||
XSP_CR_TRANS_INHIBIT_MASK;
|
||||
|
||||
_write(xdesc, XSP_CR_OFFSET, val);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/* Initialize spi_desc structure and device */
|
||||
static int32_t xil_spi_init_pl(struct spi_desc **desc,
|
||||
const struct spi_init_param *param)
|
||||
{
|
||||
struct spi_desc *ldesc;
|
||||
struct xspi_desc *xdesc;
|
||||
int32_t err;
|
||||
XSpi_Config *cfg;
|
||||
|
||||
if (!desc || !param || param->device_id >= XPAR_XSPI_NUM_INSTANCES)
|
||||
return -EINVAL;
|
||||
|
||||
cfg = XSpi_LookupConfig(param->device_id);
|
||||
if (!cfg)
|
||||
return -EINVAL;
|
||||
|
||||
if (param->chip_select > cfg->NumSlaveBits)
|
||||
return -EINVAL;
|
||||
|
||||
ldesc = (struct spi_desc *)calloc(1, sizeof(*ldesc));
|
||||
if (!ldesc)
|
||||
return -ENOMEM;
|
||||
|
||||
xdesc = (struct xspi_desc *)calloc(1, sizeof(*xdesc));
|
||||
if (!xdesc) {
|
||||
err = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
ldesc->bit_order = param->bit_order;
|
||||
ldesc->chip_select = param->chip_select;
|
||||
ldesc->mode = param->mode;
|
||||
xdesc->base_addr = cfg->BaseAddress;
|
||||
xdesc->disable_slaves_mask = (1 << cfg->NumSlaveBits) - 1;
|
||||
xdesc->cs_asserted = 0;
|
||||
|
||||
err = _xil_spi_init_dev(xdesc);
|
||||
if (IS_ERR_VALUE(err))
|
||||
goto error;
|
||||
|
||||
ldesc->extra = xdesc;
|
||||
*desc = ldesc;
|
||||
|
||||
return SUCCESS;
|
||||
|
||||
error:
|
||||
free(xdesc);
|
||||
free(ldesc);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Remove allocated resources */
|
||||
static int32_t xil_spi_remove_pl(struct spi_desc *desc)
|
||||
{
|
||||
if (!desc)
|
||||
return -EINVAL;
|
||||
|
||||
free(desc->extra);
|
||||
free(desc);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill fifo until fifo is full or no more data available.
|
||||
* Return the number of written bytes.
|
||||
*/
|
||||
static uint32_t _wr_fifo(struct xspi_desc *xdesc, uint8_t *data,
|
||||
uint32_t len)
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t to_write;
|
||||
uint32_t tx_available;
|
||||
|
||||
tx_available = xdesc->fifo_depth - _read(xdesc, XSP_TFO_OFFSET);
|
||||
to_write = min(tx_available, len);
|
||||
for (i = 0; i < to_write; ++i)
|
||||
if (data)
|
||||
_write(xdesc, XSP_DTR_OFFSET, data[i]);
|
||||
else
|
||||
_write(xdesc, XSP_DTR_OFFSET, XSP_DUMMY_DATA);
|
||||
|
||||
return to_write;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read fifo until fifo is empty or no more buffer available to read into
|
||||
* Returns the number of read bytes
|
||||
*/
|
||||
static uint32_t _rd_fifo(struct xspi_desc *xdesc, uint8_t *data,
|
||||
uint32_t len)
|
||||
{
|
||||
uint32_t rx_available;
|
||||
uint32_t to_read;
|
||||
uint32_t tmp;
|
||||
uint32_t i;
|
||||
|
||||
tmp = _read(xdesc, XSP_SR_OFFSET);
|
||||
if (tmp & XSP_SR_RX_EMPTY_MASK)
|
||||
return 0;
|
||||
|
||||
rx_available = _read(xdesc, XSP_RFO_OFFSET) + 1;
|
||||
to_read = min(rx_available, len);
|
||||
for (i = 0; i < to_read; ++i) {
|
||||
tmp = _read(xdesc, XSP_DRR_OFFSET);
|
||||
if (data)
|
||||
data[i] = tmp;
|
||||
}
|
||||
|
||||
return to_read;
|
||||
}
|
||||
|
||||
/* If start is 0 stop transfer, else start it.
|
||||
* CS will be asserted if needed. If different CS othere than the one needed
|
||||
* is asserted. Deassert it and assert correct one */
|
||||
static void _xil_spi_start_transfer(struct spi_desc *desc, uint8_t start)
|
||||
{
|
||||
struct xspi_desc *xdesc;
|
||||
|
||||
xdesc = desc->extra;
|
||||
if (start) {
|
||||
if (xdesc->cs_asserted) {
|
||||
if (desc->chip_select ==
|
||||
g_spi_desc[desc->device_id].chip_select)
|
||||
return ;
|
||||
else
|
||||
/* Stop transfer to start again with new CS */
|
||||
_xil_spi_start_transfer(desc, 0);
|
||||
}
|
||||
_write(xdesc, XSP_SSR_OFFSET, ~(1 << desc->chip_select));
|
||||
_wr_mask(xdesc, XSP_CR_OFFSET, 0, XSP_CR_TRANS_INHIBIT_MASK);
|
||||
} else {
|
||||
_wr_mask(xdesc, XSP_CR_OFFSET, XSP_CR_TRANS_INHIBIT_MASK,
|
||||
XSP_CR_TRANS_INHIBIT_MASK);
|
||||
_write(xdesc, XSP_SSR_OFFSET, xdesc->disable_slaves_mask);
|
||||
}
|
||||
xdesc->cs_asserted = start;
|
||||
}
|
||||
|
||||
|
||||
/* SPI polled transfer */
|
||||
static int32_t xil_spi_write_and_read_pl(struct spi_desc *desc, uint8_t *data,
|
||||
uint16_t bytes_number)
|
||||
{
|
||||
struct xspi_desc *xdesc;
|
||||
uint32_t rx;
|
||||
uint32_t tx;
|
||||
|
||||
if (!desc || !desc->extra)
|
||||
return -EINVAL;
|
||||
|
||||
xdesc = desc->extra;
|
||||
_update_mode(desc);
|
||||
|
||||
_xil_spi_start_transfer(desc, 1);
|
||||
rx = 0;
|
||||
tx = 0;
|
||||
while (rx < bytes_number) {
|
||||
if (tx < bytes_number)
|
||||
tx += _wr_fifo(xdesc, data + tx, bytes_number - tx);
|
||||
rx += _rd_fifo(xdesc, data + rx, bytes_number - rx);
|
||||
}
|
||||
_xil_spi_start_transfer(desc, 0);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/* Get type of message. It can be READ, WRITE or both */
|
||||
static uint32_t _get_msg_type(struct spi_msg *msg)
|
||||
{
|
||||
uint32_t type;
|
||||
|
||||
type = 0;
|
||||
if (msg->tx_buff)
|
||||
type |= XPS_TYPE_WRITE;
|
||||
if (msg->rx_buff)
|
||||
type |= XPS_TYPE_READ;
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
/* Get information based on current iterator position */
|
||||
static void _get_data(struct msg_iter *it, uint8_t **buff, uint32_t *len,
|
||||
uint32_t *type)
|
||||
{
|
||||
struct spi_msg *msg;
|
||||
|
||||
if (it->i == it->len) {
|
||||
*len = 0;
|
||||
return ;
|
||||
}
|
||||
|
||||
msg = it->msgs + it->i;
|
||||
if (it->is_wr)
|
||||
*buff = msg->tx_buff;
|
||||
else
|
||||
*buff = msg->rx_buff;
|
||||
|
||||
if (*buff)
|
||||
*buff += it->buff_i;
|
||||
|
||||
*len = msg->bytes_number - it->buff_i;
|
||||
if (type)
|
||||
*type = _get_msg_type(msg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Increment iterator position with desired length.
|
||||
* If the new position has a different message type, new_type will be set to 1
|
||||
* If a CS change is needed, cs_change is set
|
||||
*/
|
||||
static void _increment_iter(struct msg_iter *it, uint32_t len,
|
||||
uint8_t *cs_change, uint8_t *new_type)
|
||||
{
|
||||
struct spi_msg *msg;
|
||||
uint32_t type;
|
||||
uint32_t extra_len;
|
||||
|
||||
if (!len)
|
||||
return ;
|
||||
|
||||
*cs_change = 0;
|
||||
*new_type = 0;
|
||||
msg = it->msgs + it->i;
|
||||
if (it->buff_i + len > msg->bytes_number)
|
||||
extra_len = it->buff_i + len - msg->bytes_number;
|
||||
else
|
||||
extra_len = 0;
|
||||
len -= extra_len;
|
||||
it->buff_i += len;
|
||||
if (it->buff_i == msg->bytes_number) {
|
||||
type = _get_msg_type(msg);
|
||||
++it->i;
|
||||
it->buff_i = 0;
|
||||
if (cs_change && msg->cs_change)
|
||||
*cs_change = 1;
|
||||
if (new_type)
|
||||
if (it->i == it->len ||
|
||||
type != _get_msg_type(it->msgs + it->i))
|
||||
*new_type = 1;
|
||||
}
|
||||
if (extra_len)
|
||||
_increment_iter(it, extra_len, cs_change, new_type);
|
||||
}
|
||||
|
||||
/*
|
||||
* SPI polling transfer of multiple messages.
|
||||
*/
|
||||
static int32_t xil_spi_transfer_pl(struct spi_desc *desc, struct spi_msg *msgs,
|
||||
uint32_t len)
|
||||
|
||||
{
|
||||
struct xspi_desc *xdesc;
|
||||
uint8_t cs_change;
|
||||
uint8_t new_type;
|
||||
struct msg_iter rx = {.msgs = msgs, .len = len, .is_wr = 0};
|
||||
struct msg_iter tx = {.msgs = msgs, .len = len, .is_wr = 1};
|
||||
uint8_t *buff;
|
||||
uint32_t bytes;
|
||||
uint32_t type;
|
||||
/* Bytes to increment rx when only a write transaction is executed */
|
||||
uint32_t to_inc_rx;
|
||||
/* Difference between rx and tx iterators in bytes */
|
||||
uint32_t tx_advance;
|
||||
/* Save bytes sent during a write loop */
|
||||
uint32_t tx_sent;
|
||||
/* Used to loop if need to empty the RX FIFO */
|
||||
uint32_t loop;
|
||||
|
||||
if (!desc || !desc->extra)
|
||||
return -EINVAL;
|
||||
|
||||
xdesc = desc->extra;
|
||||
_update_mode(desc);
|
||||
|
||||
tx_advance = 0;
|
||||
to_inc_rx = 0;
|
||||
buff = NULL;
|
||||
type = 0;
|
||||
do {
|
||||
_xil_spi_start_transfer(desc, 1);
|
||||
|
||||
tx_sent = 0;
|
||||
/* Writing loop */
|
||||
do {
|
||||
_get_data(&tx, &buff, &bytes, &type);
|
||||
if (type & XPS_TYPE_READ)
|
||||
/*
|
||||
* Do not write more bytes than fifo_depth if
|
||||
* they haven't been read.
|
||||
*/
|
||||
bytes = min(bytes,
|
||||
xdesc->fifo_depth - tx_advance);
|
||||
bytes = _wr_fifo(xdesc, buff, bytes);
|
||||
tx_sent += bytes;
|
||||
_increment_iter(&tx, bytes, &cs_change, &new_type);
|
||||
tx_advance += bytes;
|
||||
} while (!cs_change && !new_type && bytes);
|
||||
|
||||
if (type & XPS_TYPE_READ) {
|
||||
loop = 1;
|
||||
/*
|
||||
* Loop only when no more data to write otherwise read
|
||||
* only available data.
|
||||
*/
|
||||
while (loop) {
|
||||
if (!new_type)
|
||||
loop = 0;
|
||||
_get_data(&rx, &buff, &bytes, NULL);
|
||||
bytes = _rd_fifo(xdesc, buff, bytes);
|
||||
_increment_iter(&rx, bytes, &cs_change, &new_type);
|
||||
tx_advance -= bytes;
|
||||
if (loop && new_type)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* Clean RX FIFO if it was only a WRITE message */
|
||||
to_inc_rx += tx_sent;
|
||||
if (new_type) {
|
||||
/* Wait for TX to be sent */
|
||||
while (!(_read(xdesc, XSP_SR_OFFSET) &
|
||||
XSP_SR_TX_EMPTY_MASK))
|
||||
;
|
||||
/* Reset fifo. Only write was performed */
|
||||
_wr_mask(xdesc, XSP_CR_OFFSET,
|
||||
XSP_CR_RXFIFO_RESET_MASK,
|
||||
XSP_CR_RXFIFO_RESET_MASK);
|
||||
|
||||
_increment_iter(&rx, to_inc_rx, NULL, NULL);
|
||||
tx_advance -= to_inc_rx;
|
||||
to_inc_rx = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ((cs_change && rx.i != len) || (!cs_change && rx.i == len))
|
||||
_xil_spi_start_transfer(desc, 0);
|
||||
} while (rx.i < len);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
const struct spi_platform_ops xil_spi_reg_ops_pl = {
|
||||
.init = xil_spi_init_pl,
|
||||
.remove = xil_spi_remove_pl,
|
||||
.write_and_read = xil_spi_write_and_read_pl,
|
||||
.write_and_read_3wire = NULL, // Not support.
|
||||
.transfer = xil_spi_transfer_pl
|
||||
};
|
||||
|
||||
#endif // XPAR_XSPI_NUM_INSTANCES
|
||||
@@ -0,0 +1,59 @@
|
||||
/***************************************************************************//**
|
||||
* @file axi_io.h
|
||||
* @brief Header file of AXI IO.
|
||||
* @author Antoniu Miclaus ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2019(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef AXI_IO_H_
|
||||
#define AXI_IO_H_
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Declarations ******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/* AXI IO Read data */
|
||||
int32_t axi_io_read(uint32_t base, uint32_t offset, uint32_t *data);
|
||||
|
||||
/* AXI IO Write data */
|
||||
int32_t axi_io_write(uint32_t base, uint32_t offset, uint32_t data);
|
||||
|
||||
#endif // AXI_IO_H_
|
||||
@@ -0,0 +1,59 @@
|
||||
/***************************************************************************//**
|
||||
* @file delay.h
|
||||
* @brief Header file of Delay functions
|
||||
* @author DBogdan ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2019(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef DELAY_H_
|
||||
#define DELAY_H_
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Declarations ******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/* Generate microseconds delay. */
|
||||
void udelay(uint32_t usecs);
|
||||
|
||||
/* Generate miliseconds delay. */
|
||||
void mdelay(uint32_t msecs);
|
||||
|
||||
#endif // DELAY_H_
|
||||
@@ -0,0 +1,67 @@
|
||||
/***************************************************************************//**
|
||||
* @file error.h
|
||||
* @brief Error codes definition
|
||||
* @author DBogdan ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2019(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef ERROR_H_
|
||||
#define ERROR_H_
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** Macros and Constants Definitions **********************/
|
||||
/******************************************************************************/
|
||||
|
||||
#ifdef SUCCESS
|
||||
#undef SUCCESS
|
||||
#endif
|
||||
#define SUCCESS 0
|
||||
#ifdef FAILURE
|
||||
#undef FAILURE
|
||||
#endif
|
||||
#define FAILURE -1
|
||||
|
||||
#ifndef __ELASTERROR
|
||||
#define __ELASTERROR 2000
|
||||
#endif
|
||||
|
||||
#define EOVERRUN (__ELASTERROR + 1) /* Circular buffer overrun */
|
||||
|
||||
|
||||
#define IS_ERR_VALUE(x) ((x) < 0)
|
||||
|
||||
#endif // ERROR_H_
|
||||
@@ -0,0 +1,165 @@
|
||||
/***************************************************************************//**
|
||||
* @file gpio.h
|
||||
* @brief Header file of GPIO Interface
|
||||
* @author DBogdan ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2019(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef GPIO_H_
|
||||
#define GPIO_H_
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** Macros and Constants Definitions **********************/
|
||||
/******************************************************************************/
|
||||
|
||||
#define GPIO_OUT 0x01
|
||||
#define GPIO_IN 0x00
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @struct gpio_platform_ops
|
||||
* @brief Structure holding gpio function pointers that point to the platform
|
||||
* specific function
|
||||
*/
|
||||
struct gpio_platform_ops ;
|
||||
|
||||
/**
|
||||
* @struct gpio_init_param
|
||||
* @brief Structure holding the parameters for GPIO initialization.
|
||||
*/
|
||||
typedef struct gpio_init_param {
|
||||
/** GPIO number */
|
||||
int32_t number;
|
||||
/** GPIO platform specific functions */
|
||||
const struct gpio_platform_ops *platform_ops;
|
||||
/** GPIO extra parameters (device specific) */
|
||||
void *extra;
|
||||
} gpio_init_param;
|
||||
|
||||
/**
|
||||
* @struct gpio_desc
|
||||
* @brief Structure holding the GPIO descriptor.
|
||||
*/
|
||||
typedef struct gpio_desc {
|
||||
/** GPIO number */
|
||||
int32_t number;
|
||||
/** GPIO platform specific functions */
|
||||
const struct gpio_platform_ops *platform_ops;
|
||||
/** GPIO extra parameters (device specific) */
|
||||
void *extra;
|
||||
} gpio_desc;
|
||||
|
||||
/**
|
||||
* @enum gpio_values
|
||||
* @brief Enum that holds the possible output states of a GPIO.
|
||||
*/
|
||||
enum gpio_values {
|
||||
/** GPIO logic low */
|
||||
GPIO_LOW,
|
||||
/** GPIO logic high */
|
||||
GPIO_HIGH,
|
||||
/** GPIO high impedance */
|
||||
GPIO_HIGH_Z
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct gpio_platform_ops
|
||||
* @brief Structure holding gpio function pointers that point to the platform
|
||||
* specific function
|
||||
*/
|
||||
struct gpio_platform_ops {
|
||||
/** gpio initialization function pointer */
|
||||
int32_t (*gpio_ops_get)(struct gpio_desc **, const struct gpio_init_param *);
|
||||
/** gpio optional descriptor function pointer */
|
||||
int32_t (*gpio_ops_get_optional)(struct gpio_desc **,
|
||||
const struct gpio_init_param *);
|
||||
/** gpio remove function pointer */
|
||||
int32_t (*gpio_ops_remove)(struct gpio_desc *);
|
||||
/** gpio direction input function pointer */
|
||||
int32_t (*gpio_ops_direction_input)(struct gpio_desc *);
|
||||
/** gpio direction output function pointer */
|
||||
int32_t (*gpio_ops_direction_output)(struct gpio_desc *, uint8_t);
|
||||
/** gpio get direction function pointer */
|
||||
int32_t (*gpio_ops_get_direction)(struct gpio_desc *, uint8_t *);
|
||||
/** gpio set value function pointer */
|
||||
int32_t (*gpio_ops_set_value)(struct gpio_desc *, uint8_t);
|
||||
/** gpio get value function pointer */
|
||||
int32_t (*gpio_ops_get_value)(struct gpio_desc *, uint8_t *);
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Declarations ******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/* Obtain the GPIO decriptor. */
|
||||
int32_t gpio_get(struct gpio_desc **desc,
|
||||
const struct gpio_init_param *param);
|
||||
|
||||
/* Obtain optional GPIO descriptor. */
|
||||
int32_t gpio_get_optional(struct gpio_desc **desc,
|
||||
const struct gpio_init_param *param);
|
||||
|
||||
/* Free the resources allocated by gpio_get() */
|
||||
int32_t gpio_remove(struct gpio_desc *desc);
|
||||
|
||||
/* Enable the input direction of the specified GPIO. */
|
||||
int32_t gpio_direction_input(struct gpio_desc *desc);
|
||||
|
||||
/* Enable the output direction of the specified GPIO. */
|
||||
int32_t gpio_direction_output(struct gpio_desc *desc,
|
||||
uint8_t value);
|
||||
|
||||
/* Get the direction of the specified GPIO. */
|
||||
int32_t gpio_get_direction(struct gpio_desc *desc,
|
||||
uint8_t *direction);
|
||||
|
||||
/* Set the value of the specified GPIO. */
|
||||
int32_t gpio_set_value(struct gpio_desc *desc,
|
||||
uint8_t value);
|
||||
|
||||
/* Get the value of the specified GPIO. */
|
||||
int32_t gpio_get_value(struct gpio_desc *desc,
|
||||
uint8_t *value);
|
||||
|
||||
#endif // GPIO_H_
|
||||
@@ -0,0 +1,188 @@
|
||||
/***************************************************************************//**
|
||||
* @file irq.h
|
||||
* @brief Header file of IRQ interface.
|
||||
* @author Cristian Pop ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2019(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef IRQ_H_
|
||||
#define IRQ_H_
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @enum irq_uart_event_e
|
||||
* @brief Possible events for uart interrupt
|
||||
*/
|
||||
enum irq_uart_event_e {
|
||||
/** Write operation finalized */
|
||||
IRQ_WRITE_DONE,
|
||||
/** Read operation finalized */
|
||||
IRQ_READ_DONE,
|
||||
/** An error occurred */
|
||||
IRQ_ERROR
|
||||
};
|
||||
|
||||
enum irq_trig_level {
|
||||
IRQ_LEVEL_LOW,
|
||||
IRQ_LEVEL_HIGH,
|
||||
IRQ_EDGE_FALLING,
|
||||
IRQ_EDGE_RISING,
|
||||
IRQ_EDGE_BOTH
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct irq_platform_ops
|
||||
* @brief Structure holding IRQ function pointers that point to the platform
|
||||
* specific function
|
||||
*/
|
||||
struct irq_platform_ops ;
|
||||
|
||||
/**
|
||||
* @struct irq_init_param
|
||||
* @brief Structure holding the initial parameters for Interrupt Request.
|
||||
*/
|
||||
struct irq_init_param {
|
||||
/** Interrupt request controller ID. */
|
||||
uint32_t irq_ctrl_id;
|
||||
/** Platform specific IRQ platform ops structure. */
|
||||
const struct irq_platform_ops *platform_ops;
|
||||
/** IRQ extra parameters (device specific) */
|
||||
void *extra;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct irq_desc
|
||||
* @brief Structure for Interrupt Request descriptor.
|
||||
*/
|
||||
struct irq_ctrl_desc {
|
||||
/** Interrupt request controller ID. */
|
||||
uint32_t irq_ctrl_id;
|
||||
/** Platform specific IRQ platform ops structure. */
|
||||
const struct irq_platform_ops *platform_ops;
|
||||
/** IRQ extra parameters (device specific) */
|
||||
void *extra;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct callback_desc
|
||||
* @brief Structure describing a callback to be registered
|
||||
*/
|
||||
struct callback_desc {
|
||||
/**
|
||||
* Callback to be called when the event an event occurs
|
||||
* @param ctx - Same as \ref callback_desc.ctx
|
||||
* @param event - Event that generated the callback
|
||||
* @param extra - Platform specific data
|
||||
*/
|
||||
void (*callback)(void *ctx, uint32_t event, void *extra);
|
||||
/** Parameter to be passed when the callback is called */
|
||||
void *ctx;
|
||||
/** Platform specific configuration for a callback */
|
||||
void *config;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct irq_platform_ops
|
||||
* @brief Structure holding IRQ function pointers that point to the platform
|
||||
* specific function
|
||||
*/
|
||||
struct irq_platform_ops {
|
||||
/** Initialize a interrupt controller peripheral. */
|
||||
int32_t (*init)(struct irq_ctrl_desc **desc,
|
||||
const struct irq_init_param *param);
|
||||
/** Register a callback to handle the irq events */
|
||||
int32_t (*register_callback)(struct irq_ctrl_desc *desc, uint32_t irq_id,
|
||||
struct callback_desc *callback_desc);
|
||||
/** Unregisters a generic IRQ handling function */
|
||||
int32_t (*unregister)(struct irq_ctrl_desc *desc, uint32_t irq_id);
|
||||
/** Global interrupt enable */
|
||||
int32_t (*global_enable)(struct irq_ctrl_desc *desc);
|
||||
/** Global interrupt disable */
|
||||
int32_t (*global_disable)(struct irq_ctrl_desc *desc);
|
||||
/** Set interrupt trigger level. */
|
||||
int32_t (*trigger_level_set)(struct irq_ctrl_desc *desc, uint32_t irq_id,
|
||||
enum irq_trig_level trig);
|
||||
/** Enable specific interrupt */
|
||||
int32_t (*enable)(struct irq_ctrl_desc *desc, uint32_t irq_id);
|
||||
/** Disable specific interrupt */
|
||||
int32_t (*disable)(struct irq_ctrl_desc *desc, uint32_t irq_id);
|
||||
/** IRQ remove function pointer */
|
||||
int32_t (*remove)(struct irq_ctrl_desc *desc);
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Declarations ******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/* Initialize a interrupt controller peripheral. */
|
||||
int32_t irq_ctrl_init(struct irq_ctrl_desc **desc,
|
||||
const struct irq_init_param *param);
|
||||
|
||||
/* Free the resources allocated by irq_ctrl_init(). */
|
||||
int32_t irq_ctrl_remove(struct irq_ctrl_desc *desc);
|
||||
|
||||
/* Register a callback to handle the irq events */
|
||||
int32_t irq_register_callback(struct irq_ctrl_desc *desc, uint32_t irq_id,
|
||||
struct callback_desc *callback_desc);
|
||||
|
||||
/* Unregisters a generic IRQ handling function */
|
||||
int32_t irq_unregister(struct irq_ctrl_desc *desc, uint32_t irq_id);
|
||||
|
||||
/* Global interrupt enable */
|
||||
int32_t irq_global_enable(struct irq_ctrl_desc *desc);
|
||||
|
||||
/* Global interrupt disable */
|
||||
int32_t irq_global_disable(struct irq_ctrl_desc *desc);
|
||||
|
||||
/* Set interrupt trigger level. */
|
||||
int32_t irq_trigger_level_set(struct irq_ctrl_desc *desc, uint32_t irq_id,
|
||||
enum irq_trig_level trig);
|
||||
|
||||
/* Enable specific interrupt */
|
||||
int32_t irq_enable(struct irq_ctrl_desc *desc, uint32_t irq_id);
|
||||
|
||||
/* Disable specific interrupt */
|
||||
int32_t irq_disable(struct irq_ctrl_desc *desc, uint32_t irq_id);
|
||||
|
||||
#endif // IRQ_H_
|
||||
@@ -0,0 +1,194 @@
|
||||
/***************************************************************************//**
|
||||
* @file spi.h
|
||||
* @brief Header file of SPI Interface
|
||||
* @author DBogdan ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2019(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef SPI_H_
|
||||
#define SPI_H_
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** Macros and Constants Definitions **********************/
|
||||
/******************************************************************************/
|
||||
|
||||
#define SPI_CPHA 0x01
|
||||
#define SPI_CPOL 0x02
|
||||
#define SPI_3WIRE 0x04
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @enum spi_mode
|
||||
* @brief SPI configuration for clock phase and polarity.
|
||||
*/
|
||||
typedef enum spi_mode {
|
||||
/** Data on rising, shift out on falling */
|
||||
SPI_MODE_0 = (0 | 0),
|
||||
/** Data on falling, shift out on rising */
|
||||
SPI_MODE_1 = (0 | SPI_CPHA),
|
||||
/** Data on falling, shift out on rising */
|
||||
SPI_MODE_2 = (SPI_CPOL | 0),
|
||||
/** Data on rising, shift out on falling */
|
||||
SPI_MODE_3 = (SPI_CPOL | SPI_CPHA),
|
||||
/** Data on rising, shift out on falling */
|
||||
SPI_MODE_4 = SPI_3WIRE
|
||||
} spi_mode;
|
||||
|
||||
/**
|
||||
* @enum spi_bit_order
|
||||
* @brief SPI configuration for bit order (MSB/LSB).
|
||||
*/
|
||||
typedef enum spi_bit_order {
|
||||
/** Most-significant bit (MSB) first */
|
||||
SPI_BIT_ORDER_MSB_FIRST = 0,
|
||||
/** Least-significant bit (LSB) first */
|
||||
SPI_BIT_ORDER_LSB_FIRST = 1,
|
||||
} spi_bit_order;
|
||||
|
||||
/**
|
||||
* @struct spi_msg_list
|
||||
* @brief List item describing a SPI transfer
|
||||
*/
|
||||
struct spi_msg {
|
||||
/** Buffer with data to send. If NULL, 0x00 will be sent */
|
||||
uint8_t *tx_buff;
|
||||
/** Buffer where to store data. If NULL, incoming data won't be saved */
|
||||
uint8_t *rx_buff;
|
||||
/** Length of buffers. Must have equal size. */
|
||||
uint32_t bytes_number;
|
||||
/** If set, CS will be deasserted after the transfer */
|
||||
uint8_t cs_change;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct spi_platform_ops
|
||||
* @brief Structure holding SPI function pointers that point to the platform
|
||||
* specific function
|
||||
*/
|
||||
struct spi_platform_ops ;
|
||||
|
||||
/**
|
||||
* @struct spi_init_param
|
||||
* @brief Structure holding the parameters for SPI initialization
|
||||
*/
|
||||
typedef struct spi_init_param {
|
||||
/** Device ID */
|
||||
uint32_t device_id;
|
||||
/** maximum transfer speed */
|
||||
uint32_t max_speed_hz;
|
||||
/** SPI chip select */
|
||||
uint8_t chip_select;
|
||||
/** SPI mode */
|
||||
enum spi_mode mode;
|
||||
/** SPI bit order */
|
||||
enum spi_bit_order bit_order;
|
||||
const struct spi_platform_ops *platform_ops;
|
||||
/** SPI extra parameters (device specific) */
|
||||
void *extra;
|
||||
} spi_init_param;
|
||||
|
||||
/**
|
||||
* @struct spi_desc
|
||||
* @brief Structure holding SPI descriptor.
|
||||
*/
|
||||
typedef struct spi_desc {
|
||||
/** Device ID */
|
||||
uint32_t device_id;
|
||||
/** maximum transfer speed */
|
||||
uint32_t max_speed_hz;
|
||||
/** SPI chip select */
|
||||
uint8_t chip_select;
|
||||
/** SPI mode */
|
||||
enum spi_mode mode;
|
||||
/** SPI bit order */
|
||||
enum spi_bit_order bit_order;
|
||||
const struct spi_platform_ops *platform_ops;
|
||||
/** SPI extra parameters (device specific) */
|
||||
void *extra;
|
||||
} spi_desc;
|
||||
|
||||
/**
|
||||
* @struct spi_platform_ops
|
||||
* @brief Structure holding SPI function pointers that point to the platform
|
||||
* specific function
|
||||
*/
|
||||
struct spi_platform_ops {
|
||||
/** SPI initialization function pointer */
|
||||
int32_t (*init)(struct spi_desc **, const struct spi_init_param *);
|
||||
/** SPI write/read function pointer */
|
||||
int32_t (*write_and_read)(struct spi_desc *, uint8_t *, uint16_t);
|
||||
/** SPI write function pointer */
|
||||
int32_t (*write_and_read_3wire)(struct spi_desc *, uint8_t *,uint8_t *,uint16_t, uint16_t);
|
||||
/** Iterate over the spi_msg array and send all messages at once */
|
||||
int32_t (*transfer)(struct spi_desc *, struct spi_msg *, uint32_t);
|
||||
/** SPI remove function pointer */
|
||||
int32_t (*remove)(struct spi_desc *);
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Declarations ******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/* Initialize the SPI communication peripheral. */
|
||||
int32_t spi_init(struct spi_desc **desc,
|
||||
const struct spi_init_param *param);
|
||||
|
||||
/* Free the resources allocated by spi_init(). */
|
||||
int32_t spi_remove(struct spi_desc *desc);
|
||||
|
||||
/* Write and read data to/from SPI. */
|
||||
int32_t spi_write_and_read(struct spi_desc *desc,
|
||||
uint8_t *data,
|
||||
uint16_t bytes_number);
|
||||
int32_t spi_write_and_read_3wire(struct spi_desc *desc,
|
||||
uint8_t *write_data,
|
||||
uint8_t *read_data,
|
||||
uint16_t write_bytes_number,
|
||||
uint16_t read_bytes_number);
|
||||
|
||||
/* Iterate over the spi_msg array and send all messages at once */
|
||||
int32_t spi_transfer(struct spi_desc *desc, struct spi_msg *msgs, uint32_t len);
|
||||
|
||||
|
||||
#endif // SPI_H_
|
||||
@@ -0,0 +1,165 @@
|
||||
/***************************************************************************//**
|
||||
* @file util.h
|
||||
* @brief Implementation of utility functions.
|
||||
* @author DBogdan ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2018(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
#ifndef UTIL_H_
|
||||
#define UTIL_H_
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
/******************************************************************************/
|
||||
/********************** Macros and Constants Definitions **********************/
|
||||
/******************************************************************************/
|
||||
#define BIT(x) (1 << (x))
|
||||
|
||||
#define ARRAY_SIZE(x) \
|
||||
(sizeof(x) / sizeof((x)[0]))
|
||||
|
||||
#define DIV_ROUND_UP(x,y) \
|
||||
(((x) + (y) - 1) / (y))
|
||||
#define DIV_ROUND_CLOSEST(x, y) \
|
||||
(((x) + (y) / 2) / (y))
|
||||
#define DIV_ROUND_CLOSEST_ULL(x, y) \
|
||||
DIV_ROUND_CLOSEST(x, y)
|
||||
|
||||
#define min(x, y) \
|
||||
(((x) < (y)) ? (x) : (y))
|
||||
#define min_t(type, x, y) \
|
||||
(type)min((type)(x), (type)(y))
|
||||
|
||||
#define max(x, y) \
|
||||
(((x) > (y)) ? (x) : (y))
|
||||
#define max_t(type, x, y) \
|
||||
(type)max((type)(x), (type)(y))
|
||||
|
||||
#define clamp(val, min_val, max_val) \
|
||||
(max(min((val), (max_val)), (min_val)))
|
||||
#define clamp_t(type, val, min_val, max_val) \
|
||||
(type)clamp((type)(val), (type)(min_val), (type)(max_val))
|
||||
|
||||
#define swap(x, y) \
|
||||
{typeof(x) _tmp_ = (x); (x) = (y); (y) = _tmp_;}
|
||||
|
||||
#define round_up(x,y) \
|
||||
(((x)+(y)-1)/(y))
|
||||
|
||||
#define BITS_PER_LONG 32
|
||||
|
||||
#define GENMASK(h, l) ({ \
|
||||
uint32_t t = (uint32_t)(~0UL); \
|
||||
t = t << (BITS_PER_LONG - (h - l + 1)); \
|
||||
t = t >> (BITS_PER_LONG - (h + 1)); \
|
||||
t; \
|
||||
})
|
||||
|
||||
#define bswap_constant_32(x) \
|
||||
((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
|
||||
(((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
|
||||
|
||||
#define bswap_constant_16(x) ((((x) & (uint16_t)0xff00) >> 8) | \
|
||||
(((x) & (uint16_t)0x00ff) << 8))
|
||||
|
||||
#define bit_swap_constant_8(x) \
|
||||
((((x) & 0x80) >> 7) | \
|
||||
(((x) & 0x40) >> 5) | \
|
||||
(((x) & 0x20) >> 3) | \
|
||||
(((x) & 0x10) >> 1) | \
|
||||
(((x) & 0x08) << 1) | \
|
||||
(((x) & 0x04) << 3) | \
|
||||
(((x) & 0x02) << 5) | \
|
||||
(((x) & 0x01) << 7))
|
||||
|
||||
#define U16_MAX ((uint16_t)~0U)
|
||||
#define S16_MAX ((int16_t)(U16_MAX>>1))
|
||||
|
||||
#define DIV_U64(x, y) (x / y)
|
||||
|
||||
#define UNUSED_PARAM(x) ((void)x)
|
||||
|
||||
#define shift_right(x, s) ((x) < 0 ? -(-(x) >> (s)) : (x) >> (s))
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Declarations ******************************/
|
||||
/******************************************************************************/
|
||||
/* Find first set bit in word. */
|
||||
uint32_t find_first_set_bit(uint32_t word);
|
||||
/* Find last set bit in word. */
|
||||
uint32_t find_last_set_bit(uint32_t word);
|
||||
/* Locate the closest element in an array. */
|
||||
uint32_t find_closest(int32_t val,
|
||||
const int32_t *array,
|
||||
uint32_t size);
|
||||
/* Shift the value and apply the specified mask. */
|
||||
uint32_t field_prep(uint32_t mask, uint32_t val);
|
||||
/* Get a field specified by a mask from a word. */
|
||||
uint32_t field_get(uint32_t mask, uint32_t word);
|
||||
/* Log base 2 of the given number. */
|
||||
int32_t log_base_2(uint32_t x);
|
||||
/* Find greatest common divisor of the given two numbers. */
|
||||
uint32_t greatest_common_divisor(uint32_t a,
|
||||
uint32_t b);
|
||||
/* Calculate best rational approximation for a given fraction. */
|
||||
void rational_best_approximation(uint32_t given_numerator,
|
||||
uint32_t given_denominator,
|
||||
uint32_t max_numerator,
|
||||
uint32_t max_denominator,
|
||||
uint32_t *best_numerator,
|
||||
uint32_t *best_denominator);
|
||||
/* Calculate the number of set bits. */
|
||||
uint32_t hweight8(uint32_t word);
|
||||
/* Calculate the quotient and the remainder of an integer division. */
|
||||
uint64_t do_div(uint64_t* n,
|
||||
uint64_t base);
|
||||
/* Unsigned 64bit divide with 64bit divisor and remainder */
|
||||
uint64_t div64_u64_rem(uint64_t dividend, uint64_t divisor,
|
||||
uint64_t *remainder);
|
||||
/* Unsigned 64bit divide with 32bit divisor with remainder */
|
||||
uint64_t div_u64_rem(uint64_t dividend, uint32_t divisor, uint32_t *remainder);
|
||||
int64_t div_s64_rem(int64_t dividend, int32_t divisor, int32_t *remainder);
|
||||
/* Unsigned 64bit divide with 32bit divisor */
|
||||
uint64_t div_u64(uint64_t dividend, uint32_t divisor);
|
||||
int64_t div_s64(int64_t dividend, int32_t divisor);
|
||||
/* Converts from string to int32_t */
|
||||
int32_t str_to_int32(const char *str);
|
||||
/* Converts from string to uint32_t */
|
||||
uint32_t srt_to_uint32(const char *str);
|
||||
#endif // UTIL_H_
|
||||
|
||||
@@ -0,0 +1,283 @@
|
||||
/***************************************************************************//**
|
||||
* @file util.c
|
||||
* @brief Implementation of utility functions.
|
||||
* @author DBogdan ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2018(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "errno.h"
|
||||
#include "../include/util.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/************************** Functions Implementation **************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* Find first set bit in word.
|
||||
*/
|
||||
uint32_t find_first_set_bit(uint32_t word)
|
||||
{
|
||||
uint32_t first_set_bit = 0;
|
||||
|
||||
while (word) {
|
||||
if (word & 0x1)
|
||||
return first_set_bit;
|
||||
word >>= 1;
|
||||
first_set_bit ++;
|
||||
}
|
||||
|
||||
return 32;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find last set bit in word.
|
||||
*/
|
||||
uint32_t find_last_set_bit(uint32_t word)
|
||||
{
|
||||
uint32_t bit = 0;
|
||||
uint32_t last_set_bit = 32;
|
||||
|
||||
while (word) {
|
||||
if (word & 0x1)
|
||||
last_set_bit = bit;
|
||||
word >>= 1;
|
||||
bit ++;
|
||||
}
|
||||
|
||||
return last_set_bit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Locate the closest element in an array.
|
||||
*/
|
||||
uint32_t find_closest(int32_t val,
|
||||
const int32_t *array,
|
||||
uint32_t size)
|
||||
{
|
||||
int32_t diff = abs(array[0] - val);
|
||||
uint32_t ret = 0;
|
||||
uint32_t i;
|
||||
|
||||
for (i = 1; i < size; i++) {
|
||||
if (abs(array[i] - val) < diff) {
|
||||
diff = abs(array[i] - val);
|
||||
ret = i;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shift the value and apply the specified mask.
|
||||
*/
|
||||
uint32_t field_prep(uint32_t mask, uint32_t val)
|
||||
{
|
||||
return (val << find_first_set_bit(mask)) & mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a field specified by a mask from a word.
|
||||
*/
|
||||
uint32_t field_get(uint32_t mask, uint32_t word)
|
||||
{
|
||||
return (word & mask) >> find_first_set_bit(mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log base 2 of the given number.
|
||||
*/
|
||||
int32_t log_base_2(uint32_t x)
|
||||
{
|
||||
return find_last_set_bit(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find greatest common divisor of the given two numbers.
|
||||
*/
|
||||
uint32_t greatest_common_divisor(uint32_t a,
|
||||
uint32_t b)
|
||||
{
|
||||
uint32_t div;
|
||||
uint32_t common_div = 1;
|
||||
|
||||
if ((a == 0) || (b == 0))
|
||||
return max(a, b);
|
||||
|
||||
for (div = 1; (div <= a) && (div <= b); div++)
|
||||
if (!(a % div) && !(b % div))
|
||||
common_div = div;
|
||||
|
||||
return common_div;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate best rational approximation for a given fraction.
|
||||
*/
|
||||
void rational_best_approximation(uint32_t given_numerator,
|
||||
uint32_t given_denominator,
|
||||
uint32_t max_numerator,
|
||||
uint32_t max_denominator,
|
||||
uint32_t *best_numerator,
|
||||
uint32_t *best_denominator)
|
||||
{
|
||||
uint32_t gcd;
|
||||
|
||||
gcd = greatest_common_divisor(given_numerator, given_denominator);
|
||||
|
||||
*best_numerator = given_numerator / gcd;
|
||||
*best_denominator = given_denominator / gcd;
|
||||
|
||||
if ((*best_numerator > max_numerator) ||
|
||||
(*best_denominator > max_denominator)) {
|
||||
*best_numerator = 0;
|
||||
*best_denominator = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the number of set bits.
|
||||
*/
|
||||
uint32_t hweight8(uint32_t word)
|
||||
{
|
||||
uint32_t count = 0;
|
||||
|
||||
while (word) {
|
||||
if (word & 0x1)
|
||||
count++;
|
||||
word >>= 1;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the quotient and the remainder of an integer division.
|
||||
*/
|
||||
uint64_t do_div(uint64_t* n,
|
||||
uint64_t base)
|
||||
{
|
||||
uint64_t mod = 0;
|
||||
|
||||
mod = *n % base;
|
||||
*n = *n / base;
|
||||
|
||||
return mod;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsigned 64bit divide with 64bit divisor and remainder
|
||||
*/
|
||||
uint64_t div64_u64_rem(uint64_t dividend, uint64_t divisor, uint64_t *remainder)
|
||||
{
|
||||
*remainder = dividend % divisor;
|
||||
|
||||
return dividend / divisor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsigned 64bit divide with 32bit divisor with remainder
|
||||
*/
|
||||
uint64_t div_u64_rem(uint64_t dividend, uint32_t divisor, uint32_t *remainder)
|
||||
{
|
||||
*remainder = do_div(÷nd, divisor);
|
||||
|
||||
return dividend;
|
||||
}
|
||||
|
||||
/**
|
||||
* Signed 64bit divide with 32bit divisor with remainder
|
||||
*/
|
||||
int64_t div_s64_rem(int64_t dividend, int32_t divisor, int32_t *remainder)
|
||||
{
|
||||
*remainder = dividend % divisor;
|
||||
return dividend / divisor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsigned 64bit divide with 32bit divisor
|
||||
*/
|
||||
uint64_t div_u64(uint64_t dividend, uint32_t divisor)
|
||||
{
|
||||
uint32_t remainder;
|
||||
|
||||
return div_u64_rem(dividend, divisor, &remainder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Signed 64bit divide with 32bit divisor
|
||||
*/
|
||||
int64_t div_s64(int64_t dividend, int32_t divisor)
|
||||
{
|
||||
int32_t remainder;
|
||||
return div_s64_rem(dividend, divisor, &remainder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts from string to int32_t
|
||||
* @param *str
|
||||
* @return int32_t
|
||||
*/
|
||||
int32_t str_to_int32(const char *str)
|
||||
{
|
||||
char *end;
|
||||
int32_t value = strtol(str, &end, 0);
|
||||
|
||||
if (end == str)
|
||||
return -EINVAL;
|
||||
else
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts from string to uint32_t
|
||||
* @param *str
|
||||
* @return uint32_t
|
||||
*/
|
||||
uint32_t srt_to_uint32(const char *str)
|
||||
{
|
||||
char *end;
|
||||
uint32_t value = strtoul(str, &end, 0);
|
||||
|
||||
if (end == str)
|
||||
return -EINVAL;
|
||||
else
|
||||
return value;
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/***************************************************************************//**
|
||||
* @file app_config.h
|
||||
* @brief Config file of AD9361/API Driver.
|
||||
* @author DBogdan ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2015(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
#ifndef CONFIG_H_
|
||||
#define CONFIG_H_
|
||||
|
||||
#define XILINX_PLATFORM
|
||||
#define SPI_INTERFACE_SPI_ENGINE
|
||||
|
||||
#define HAVE_SPLIT_GAIN_TABLE 1 /* only set to 0 in case split_gain_table_mode_enable = 0*/
|
||||
#define HAVE_TDD_SYNTH_TABLE 1 /* only set to 0 in case split_gain_table_mode_enable = 0*/
|
||||
|
||||
#define HAVE_VERBOSE_MESSAGES /* Recommended during development prints errors and warnings */
|
||||
//#define HAVE_DEBUG_MESSAGES /* For Debug purposes only */
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,35 @@
|
||||
#ifndef DEV_PROFILE_H_
|
||||
#define DEV_PROFILE_H_
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "../app_config.h"
|
||||
#include "../parameters.h"
|
||||
#include "../adi_noos/include/spi.h"
|
||||
#include "../adi_noos/include/gpio.h"
|
||||
#include "../adi_noos/include/delay.h"
|
||||
#include "../adi_noos/include/irq.h"
|
||||
#include "../adi_noos/include/error.h"
|
||||
#include "../adi_noos/drivers/frequency/lmk04828/lmk04828.h"
|
||||
|
||||
// Platform includes
|
||||
#include "../adi_noos/drivers/platform/spi_extra.h"
|
||||
#include "../adi_noos/drivers/platform/gpio_extra.h"
|
||||
#include "../adi_noos/drivers/platform/irq_extra.h"
|
||||
|
||||
// AXI-Cores includes
|
||||
#include "../adi_noos/drivers/axi_core/spi_engine/spi_engine.h"
|
||||
|
||||
// Declare in mian.c
|
||||
extern struct spi_engine_init_param spi_engine_param;
|
||||
extern struct xil_gpio_init_param xil_gpio_param;
|
||||
|
||||
#define GPIO_PARAM &xil_gpio_param
|
||||
#define SPI_PARAM &spi_engine_param
|
||||
#define GPIO_OPS &xil_gpio_ops
|
||||
#define SPI_OPS &spi_eng_platform_ops
|
||||
|
||||
extern struct lmk04828_init_param lmk04828_default_init_param;
|
||||
extern const struct lmk04828_config lmk04828_default_config[];
|
||||
extern const uint32_t lmk04828_default_config_len;
|
||||
|
||||
#endif /* SRC_DEV_PROFILE_H_ */
|
||||
@@ -0,0 +1,165 @@
|
||||
#include "dev_profile.h"
|
||||
#include "../app_config.h"
|
||||
#include "../adi_noos/drivers/frequency/lmk04828/lmk04828.h"
|
||||
|
||||
|
||||
static spi_init_param lmk04828_spi_init = {
|
||||
.device_id = SPI_DEVICE_ID,
|
||||
.max_speed_hz = SPI_ENGINE_MAX_SPEED,
|
||||
.mode = SPI_MODE_0,
|
||||
.chip_select = SPI_CS_LMK04828,
|
||||
.platform_ops = SPI_OPS,
|
||||
.extra = SPI_PARAM
|
||||
};
|
||||
|
||||
struct lmk04828_init_param lmk04828_default_init_param = {
|
||||
/* SPI */
|
||||
.spi_init = &lmk04828_spi_init
|
||||
};
|
||||
|
||||
const uint32_t lmk04828_default_config_len = 136;
|
||||
const struct lmk04828_config lmk04828_default_config[] = {
|
||||
{0x0000, 0x10}, // [7] normal operation; [4] 3-wire mode disabled
|
||||
{0x0002, 0x00}, // [0] normal operation
|
||||
{0x0003, 0x06}, // [7-0] product device type, read only, default: 6
|
||||
{0x0004, 0xD0}, // [7-0] msb of product identifier, read only, default: 208
|
||||
{0x0005, 0x5B}, // [7-0] lsb of product identifier, read only, default: 91
|
||||
{0x0006, 0x00}, // [7-0] ic version identifier, read only, default: 32
|
||||
{0x000C, 0x51}, // [7-0] msb of vendor identifier, read only, default: 81
|
||||
{0x000D, 0x04}, // [7-0] lsb of vendor identifier, read only, default: 4
|
||||
// device clock 0
|
||||
{0x0100, 0x0C}, // [6] output drive level (ODL); [5] input drive level (IDL); [4-0] device clock (DCLK) output divider
|
||||
{0x0101, 0x55}, // DCLK: [7-4] output digital delay (DDLY) high count; [3-0] DDLY low count
|
||||
{0x0102, 0x55},
|
||||
{0x0103, 0x01}, // DCLK: [7-3] analog delay (ADLY) value, 25 ps per lsb; [2] ADLY input mux; [1-0] DCLK input mux
|
||||
{0x0104, 0x22}, // [6] DCLK half step value; [5] SDCLK output MUX; [4-1] SDCLK DDLY; [0] SYSREF half step value
|
||||
{0x0105, 0x00}, // SYSREF: [4] ADLY enable; [3:0] ADLY value, 600 ps + 150 ps per lsb
|
||||
{0x0106, 0xF0}, // [7] DCLK DDLY enable; [6] DCLK glitchless half step enable; [5] DCLK glitchless ADLY enable; [4] DCLK ADLY enable; [3]: clock group enable; [2-1] SYSREF disable mode; [0]: SYSREF disable
|
||||
{0x0107, 0x11}, // [7] SDCLK output polarity; [6-4] SDCLK output format; [3] DCLK output polarity; [2:0] DCLK output format
|
||||
// device clock 2
|
||||
{0x0108, 0x0C}, // [6] output drive level (ODL); [5] input drive level (IDL); [4-0] device clock (DCLK) output divider
|
||||
{0x0109, 0x55}, // DCLK: [7-4] output digital delay (DDLY) high count; [3-0] DDLY low count
|
||||
{0x010A, 0x55},
|
||||
{0x010B, 0x00}, // DCLK: [7-3] analog delay (ADLY) value, 25 ps per lsb; [2] ADLY input mux; [1-0] DCLK input mux
|
||||
{0x010C, 0x22}, // [6] DCLK half step value; [5] SDCLK output MUX; [4-1] SDCLK DDLY; [0] SYSREF half step value
|
||||
{0x010D, 0x00}, // SYSREF: [4] ADLY enable; [3:0] ADLY value, 600 ps + 150 ps per lsb
|
||||
{0x010E, 0xF0}, // [7] DCLK DDLY enable; [6] DCLK glitchless half step enable; [5] DCLK glitchless ADLY enable; [4] DCLK ADLY enable; [3]: clock group enable; [2-1] SYSREF disable mode; [0]: SYSREF disable
|
||||
{0x010F, 0x10}, // [7] SDCLK output polarity; [6-4] SDCLK output format; [3] DCLK output polarity; [2:0] DCLK output format
|
||||
// device clock 4
|
||||
{0x0110, 0x0C}, // [6] output drive level (ODL); [5] input drive level (IDL); [4-0] device clock (DCLK) output divider
|
||||
{0x0111, 0x55}, // DCLK: [7-4] output digital delay (DDLY) high count; [3-0] DDLY low count
|
||||
{0x0112, 0x55},
|
||||
{0x0113, 0x00}, // DCLK: [7-3] analog delay (ADLY) value, 25 ps per lsb; [2] ADLY input mux; [1-0] DCLK input mux
|
||||
{0x0114, 0x22}, // [6] DCLK half step value; [5] SDCLK output MUX; [4-1] SDCLK DDLY; [0] SYSREF half step value
|
||||
{0x0115, 0x00}, // SYSREF: [4] ADLY enable; [3:0] ADLY value, 600 ps + 150 ps per lsb
|
||||
{0x0116, 0xF0}, // [7] DCLK DDLY enable; [6] DCLK glitchless half step enable; [5] DCLK glitchless ADLY enable; [4] DCLK ADLY enable; [3]: clock group enable; [2-1] SYSREF disable mode; [0]: SYSREF disable
|
||||
{0x0117, 0x11}, // [7] SDCLK output polarity; [6-4] SDCLK output format; [3] DCLK output polarity; [2:0] DCLK output format
|
||||
// device clock 6
|
||||
{0x0118, 0x0C}, // [6] output drive level (ODL); [5] input drive level (IDL); [4-0] device clock (DCLK) output divider
|
||||
{0x0119, 0x55}, // DCLK: [7-4] output digital delay (DDLY) high count; [3-0] DDLY low count
|
||||
{0x011A, 0x55},
|
||||
{0x011B, 0x00}, // DCLK: [7-3] analog delay (ADLY) value, 25 ps per lsb; [2] ADLY input mux; [1-0] DCLK input mux
|
||||
{0x011C, 0x02}, // [6] DCLK half step value; [5] SDCLK output MUX; [4-1] SDCLK DDLY; [0] SYSREF half step value
|
||||
{0x011D, 0x00}, // SYSREF: [4] ADLY enable; [3:0] ADLY value, 600 ps + 150 ps per lsb
|
||||
{0x011E, 0xF0}, // [7] DCLK DDLY enable; [6] DCLK glitchless half step enable; [5] DCLK glitchless ADLY enable; [4] DCLK ADLY enable; [3]: clock group enable; [2-1] SYSREF disable mode; [0]: SYSREF disable
|
||||
{0x011F, 0x55}, // [7] SDCLK output polarity; [6-4] SDCLK output format; [3] DCLK output polarity; [2:0] DCLK output format
|
||||
// device clock 8
|
||||
{0x0120, 0x0C}, // [6] output drive level (ODL); [5] input drive level (IDL); [4-0] device clock (DCLK) output divider
|
||||
{0x0121, 0x55}, // DCLK: [7-4] output digital delay (DDLY) high count; [3-0] DDLY low count
|
||||
{0x0122, 0x55},
|
||||
{0x0123, 0x00}, // DCLK: [7-3] analog delay (ADLY) value, 25 ps per lsb; [2] ADLY input mux; [1-0] DCLK input mux
|
||||
{0x0124, 0x22}, // [6] DCLK half step value; [5] SDCLK output MUX; [4-1] SDCLK DDLY; [0] SYSREF half step value
|
||||
{0x0125, 0x00}, // SYSREF: [4] ADLY enable; [3:0] ADLY value, 600 ps + 150 ps per lsb
|
||||
{0x0126, 0xF0}, // [7] DCLK DDLY enable; [6] DCLK glitchless half step enable; [5] DCLK glitchless ADLY enable; [4] DCLK ADLY enable; [3]: clock group enable; [2-1] SYSREF disable mode; [0]: SYSREF disable
|
||||
{0x0127, 0x55}, // [7] SDCLK output polarity; [6-4] SDCLK output format; [3] DCLK output polarity; [2:0] DCLK output format
|
||||
// device clock 10
|
||||
{0x0128, 0x0C}, // [6] output drive level (ODL); [5] input drive level (IDL); [4-0] device clock (DCLK) output divider
|
||||
{0x0129, 0x55}, // DCLK: [7-4] output digital delay (DDLY) high count; [3-0] DDLY low count
|
||||
{0x012A, 0x55},
|
||||
{0x012B, 0x00}, // DCLK: [7-3] analog delay (ADLY) value, 25 ps per lsb; [2] ADLY input mux; [1-0] DCLK input mux
|
||||
{0x012C, 0x22}, // [6] DCLK half step value; [5] SDCLK output MUX; [4-1] SDCLK DDLY; [0] SYSREF half step value
|
||||
{0x012D, 0x00}, // SYSREF: [4] ADLY enable; [3:0] ADLY value, 600 ps + 150 ps per lsb
|
||||
{0x012E, 0xF0}, // [7] DCLK DDLY enable; [6] DCLK glitchless half step enable; [5] DCLK glitchless ADLY enable; [4] DCLK ADLY enable; [3]: clock group enable; [2-1] SYSREF disable mode; [0]: SYSREF disable
|
||||
{0x012F, 0x51}, // [7] SDCLK output polarity; [6-4] SDCLK output format; [3] DCLK output polarity; [2:0] DCLK output format
|
||||
// device clock 12
|
||||
{0x0130, 0x0C}, // [6] output drive level (ODL); [5] input drive level (IDL); [4-0] device clock (DCLK) output divider
|
||||
{0x0131, 0x55}, // DCLK: [7-4] output digital delay (DDLY) high count; [3-0] DDLY low count
|
||||
{0x0132, 0x55},
|
||||
{0x0133, 0x00}, // DCLK: [7-3] analog delay (ADLY) value, 25 ps per lsb; [2] ADLY input mux; [1-0] DCLK input mux
|
||||
{0x0134, 0x22}, // [6] DCLK half step value; [5] SDCLK output MUX; [4-1] SDCLK DDLY; [0] SYSREF half step value
|
||||
{0x0135, 0x00}, // SYSREF: [4] ADLY enable; [3:0] ADLY value, 600 ps + 150 ps per lsb
|
||||
{0x0136, 0xF0}, // [7] DCLK DDLY enable; [6] DCLK glitchless half step enable; [5] DCLK glitchless ADLY enable; [4] DCLK ADLY enable; [3]: clock group enable; [2-1] SYSREF disable mode; [0]: SYSREF disable
|
||||
{0x0137, 0x55}, // [7] SDCLK output polarity; [6-4] SDCLK output format; [3] DCLK output polarity; [2:0] DCLK output format
|
||||
// clock distribution source
|
||||
{0x0138, 0x20}, // [6-5] VCO mux; [4] OSCout mux; [3:0] OSCout format
|
||||
{0x0139, 0x03}, // [2] SYSREF output mux; [1-0] SYSREF source
|
||||
{0x013A, 0x0C}, // [4-0] SYSREF divider [12:8]
|
||||
{0x013B, 0x00}, // [7-0] SYSREF divider [7:0]
|
||||
{0x013C, 0x00}, // [4-0] SYSREF DDLY [12:8]
|
||||
{0x013D, 0x08}, // [7-0] SYSREF DDLY [7:0]
|
||||
{0x013E, 0x03}, // [1-0] SYSREF pulse count
|
||||
{0x013F, 0x00}, // [4] pll2 mux; [3] pll1 mux; [2-1] feedback mux; [0] feedback mux enable
|
||||
{0x0140, 0x0B}, // power-down control: [7] pll1; [6] vco_ldo; [5] vco; [4] OSCin; [3] individual SYSREF; [2] SYSREF; [1] SYSREF DDLY; [0] SYSREF pluse generator
|
||||
{0x0141, 0x00}, // dynamic DDLY control
|
||||
{0x0142, 0x00}, // dynamic DDLY step control
|
||||
{0x0143, 0x10},
|
||||
{0x0144, 0xFF},
|
||||
{0x0145, 0x7F},
|
||||
{0x0146, 0x12},
|
||||
{0x0147, 0x1A},
|
||||
{0x0148, 0x03},
|
||||
{0x0149, 0x05},
|
||||
{0x014A, 0x1B},
|
||||
{0x014B, 0x16},
|
||||
{0x014C, 0x00},
|
||||
{0x014D, 0x00},
|
||||
{0x014E, 0xC0},
|
||||
{0x014F, 0x7F},
|
||||
{0x0150, 0x03},
|
||||
{0x0151, 0x02},
|
||||
{0x0152, 0x00},
|
||||
{0x0153, 0x00},
|
||||
{0x0154, 0x78},
|
||||
{0x0155, 0x00},
|
||||
{0x0156, 0x7D},
|
||||
{0x0157, 0x00},
|
||||
{0x0158, 0x96},
|
||||
{0x0159, 0x06},
|
||||
{0x015A, 0x00},
|
||||
{0x015B, 0xD4},
|
||||
{0x015C, 0x20},
|
||||
{0x015D, 0x00},
|
||||
{0x015E, 0x00},
|
||||
{0x015F, 0x3B},
|
||||
{0x0160, 0x00},
|
||||
{0x0161, 0x01},
|
||||
{0x0162, 0x44},
|
||||
{0x0163, 0x00},
|
||||
{0x0164, 0x00},
|
||||
{0x0165, 0x0C},
|
||||
{0x0171, 0xAA},
|
||||
{0x0172, 0x02},
|
||||
{0x017C, 0x15},
|
||||
{0x017D, 0x33},
|
||||
{0x0166, 0x00},
|
||||
{0x0167, 0x00},
|
||||
{0x0168, 0x0C},
|
||||
{0x0169, 0x59},
|
||||
{0x016A, 0x20},
|
||||
{0x016B, 0x00},
|
||||
{0x016C, 0x00},
|
||||
{0x016D, 0x00},
|
||||
{0x016E, 0x1B},
|
||||
{0x0173, 0x00},
|
||||
{0x0182, 0x00},
|
||||
{0x0183, 0x00},
|
||||
{0x0184, 0x00},
|
||||
{0x0185, 0x00},
|
||||
{0x0188, 0x00},
|
||||
{0x0189, 0x00},
|
||||
{0x018A, 0x00},
|
||||
{0x018B, 0x00},
|
||||
{0x1FFD, 0x00},
|
||||
{0x1FFE, 0x00},
|
||||
{0x1FFF, 0x53}
|
||||
};
|
||||
@@ -0,0 +1,325 @@
|
||||
/*******************************************************************/
|
||||
/* */
|
||||
/* This file is automatically generated by linker script generator.*/
|
||||
/* */
|
||||
/* Version: 2018.3 */
|
||||
/* */
|
||||
/* Copyright (c) 2010-2019 Xilinx, Inc. All rights reserved. */
|
||||
/* */
|
||||
/* Description : ARM v8 Linker Script */
|
||||
/* */
|
||||
/*******************************************************************/
|
||||
|
||||
_STACK_SIZE = DEFINED(_STACK_SIZE) ? _STACK_SIZE : 0x2000;
|
||||
_HEAP_SIZE = DEFINED(_HEAP_SIZE) ? _HEAP_SIZE : 0x2000;
|
||||
|
||||
_EL0_STACK_SIZE = DEFINED(_EL0_STACK_SIZE) ? _EL0_STACK_SIZE : 1024;
|
||||
_EL1_STACK_SIZE = DEFINED(_EL1_STACK_SIZE) ? _EL1_STACK_SIZE : 2048;
|
||||
_EL2_STACK_SIZE = DEFINED(_EL2_STACK_SIZE) ? _EL2_STACK_SIZE : 1024;
|
||||
|
||||
/* Define Memories in the system */
|
||||
|
||||
MEMORY
|
||||
{
|
||||
psu_ddr_0_MEM_0 : ORIGIN = 0x0, LENGTH = 0x7FF00000
|
||||
psu_ddr_1_MEM_0 : ORIGIN = 0x800000000, LENGTH = 0x80000000
|
||||
psu_ocm_ram_0_MEM_0 : ORIGIN = 0xFFFC0000, LENGTH = 0x40000
|
||||
psu_qspi_linear_0_MEM_0 : ORIGIN = 0xC0000000, LENGTH = 0x20000000
|
||||
}
|
||||
|
||||
/* Specify the default entry point to the program */
|
||||
|
||||
ENTRY(_vector_table)
|
||||
|
||||
/* Define the sections, and where they are mapped in memory */
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text : {
|
||||
. = ALIGN(2048);
|
||||
KEEP (*(.vectors))
|
||||
*(.boot)
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.gnu.linkonce.t.*)
|
||||
*(.plt)
|
||||
*(.gnu_warning)
|
||||
*(.gcc_execpt_table)
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
*(.ARM.extab)
|
||||
*(.gnu.linkonce.armextab.*)
|
||||
} > psu_ddr_0_MEM_0
|
||||
|
||||
.init (ALIGN(64)) : {
|
||||
KEEP (*(.init))
|
||||
} > psu_ddr_0_MEM_0
|
||||
|
||||
.fini (ALIGN(64)) : {
|
||||
KEEP (*(.fini))
|
||||
} > psu_ddr_0_MEM_0
|
||||
|
||||
.interp : {
|
||||
KEEP (*(.interp))
|
||||
} > psu_ddr_0_MEM_0
|
||||
|
||||
.note-ABI-tag : {
|
||||
KEEP (*(.note-ABI-tag))
|
||||
} > psu_ddr_0_MEM_0
|
||||
|
||||
.rodata : {
|
||||
. = ALIGN(64);
|
||||
__rodata_start = .;
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
*(.gnu.linkonce.r.*)
|
||||
__rodata_end = .;
|
||||
} > psu_ddr_0_MEM_0
|
||||
|
||||
.rodata1 : {
|
||||
. = ALIGN(64);
|
||||
__rodata1_start = .;
|
||||
*(.rodata1)
|
||||
*(.rodata1.*)
|
||||
__rodata1_end = .;
|
||||
} > psu_ddr_0_MEM_0
|
||||
|
||||
.sdata2 : {
|
||||
. = ALIGN(64);
|
||||
__sdata2_start = .;
|
||||
*(.sdata2)
|
||||
*(.sdata2.*)
|
||||
*(.gnu.linkonce.s2.*)
|
||||
__sdata2_end = .;
|
||||
} > psu_ddr_0_MEM_0
|
||||
|
||||
.sbss2 : {
|
||||
. = ALIGN(64);
|
||||
__sbss2_start = .;
|
||||
*(.sbss2)
|
||||
*(.sbss2.*)
|
||||
*(.gnu.linkonce.sb2.*)
|
||||
__sbss2_end = .;
|
||||
} > psu_ddr_0_MEM_0
|
||||
|
||||
.data : {
|
||||
. = ALIGN(64);
|
||||
__data_start = .;
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.gnu.linkonce.d.*)
|
||||
*(.jcr)
|
||||
*(.got)
|
||||
*(.got.plt)
|
||||
__data_end = .;
|
||||
} > psu_ddr_0_MEM_0
|
||||
|
||||
.data1 : {
|
||||
. = ALIGN(64);
|
||||
__data1_start = .;
|
||||
*(.data1)
|
||||
*(.data1.*)
|
||||
__data1_end = .;
|
||||
} > psu_ddr_0_MEM_0
|
||||
|
||||
.got : {
|
||||
*(.got)
|
||||
} > psu_ddr_0_MEM_0
|
||||
|
||||
.got1 : {
|
||||
*(.got1)
|
||||
} > psu_ddr_0_MEM_0
|
||||
|
||||
.got2 : {
|
||||
*(.got2)
|
||||
} > psu_ddr_0_MEM_0
|
||||
|
||||
.note.gnu.build-id : {
|
||||
KEEP (*(.note.gnu.build-id))
|
||||
} > psu_ddr_0_MEM_0
|
||||
|
||||
.ctors : {
|
||||
. = ALIGN(64);
|
||||
__CTOR_LIST__ = .;
|
||||
___CTORS_LIST___ = .;
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*(EXCLUDE_FILE(*crtend.o) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
__CTOR_END__ = .;
|
||||
___CTORS_END___ = .;
|
||||
} > psu_ddr_0_MEM_0
|
||||
|
||||
.dtors : {
|
||||
. = ALIGN(64);
|
||||
__DTOR_LIST__ = .;
|
||||
___DTORS_LIST___ = .;
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE(*crtend.o) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
__DTOR_END__ = .;
|
||||
___DTORS_END___ = .;
|
||||
} > psu_ddr_0_MEM_0
|
||||
|
||||
.fixup : {
|
||||
__fixup_start = .;
|
||||
*(.fixup)
|
||||
__fixup_end = .;
|
||||
} > psu_ddr_0_MEM_0
|
||||
|
||||
.eh_frame : {
|
||||
*(.eh_frame)
|
||||
} > psu_ddr_0_MEM_0
|
||||
|
||||
.eh_framehdr : {
|
||||
__eh_framehdr_start = .;
|
||||
*(.eh_framehdr)
|
||||
__eh_framehdr_end = .;
|
||||
} > psu_ddr_0_MEM_0
|
||||
|
||||
.gcc_except_table : {
|
||||
*(.gcc_except_table)
|
||||
} > psu_ddr_0_MEM_0
|
||||
|
||||
.mmu_tbl0 (ALIGN(4096)) : {
|
||||
__mmu_tbl0_start = .;
|
||||
*(.mmu_tbl0)
|
||||
__mmu_tbl0_end = .;
|
||||
} > psu_ddr_0_MEM_0
|
||||
|
||||
.mmu_tbl1 (ALIGN(4096)) : {
|
||||
__mmu_tbl1_start = .;
|
||||
*(.mmu_tbl1)
|
||||
__mmu_tbl1_end = .;
|
||||
} > psu_ddr_0_MEM_0
|
||||
|
||||
.mmu_tbl2 (ALIGN(4096)) : {
|
||||
__mmu_tbl2_start = .;
|
||||
*(.mmu_tbl2)
|
||||
__mmu_tbl2_end = .;
|
||||
} > psu_ddr_0_MEM_0
|
||||
|
||||
.ARM.exidx : {
|
||||
__exidx_start = .;
|
||||
*(.ARM.exidx*)
|
||||
*(.gnu.linkonce.armexidix.*.*)
|
||||
__exidx_end = .;
|
||||
} > psu_ddr_0_MEM_0
|
||||
|
||||
.preinit_array : {
|
||||
. = ALIGN(64);
|
||||
__preinit_array_start = .;
|
||||
KEEP (*(SORT(.preinit_array.*)))
|
||||
KEEP (*(.preinit_array))
|
||||
__preinit_array_end = .;
|
||||
} > psu_ddr_0_MEM_0
|
||||
|
||||
.init_array : {
|
||||
. = ALIGN(64);
|
||||
__init_array_start = .;
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array))
|
||||
__init_array_end = .;
|
||||
} > psu_ddr_0_MEM_0
|
||||
|
||||
.fini_array : {
|
||||
. = ALIGN(64);
|
||||
__fini_array_start = .;
|
||||
KEEP (*(SORT(.fini_array.*)))
|
||||
KEEP (*(.fini_array))
|
||||
__fini_array_end = .;
|
||||
} > psu_ddr_0_MEM_0
|
||||
|
||||
.ARM.attributes : {
|
||||
__ARM.attributes_start = .;
|
||||
*(.ARM.attributes)
|
||||
__ARM.attributes_end = .;
|
||||
} > psu_ddr_0_MEM_0
|
||||
|
||||
.sdata : {
|
||||
. = ALIGN(64);
|
||||
__sdata_start = .;
|
||||
*(.sdata)
|
||||
*(.sdata.*)
|
||||
*(.gnu.linkonce.s.*)
|
||||
__sdata_end = .;
|
||||
} > psu_ddr_0_MEM_0
|
||||
|
||||
.sbss (NOLOAD) : {
|
||||
. = ALIGN(64);
|
||||
__sbss_start = .;
|
||||
*(.sbss)
|
||||
*(.sbss.*)
|
||||
*(.gnu.linkonce.sb.*)
|
||||
. = ALIGN(64);
|
||||
__sbss_end = .;
|
||||
} > psu_ddr_0_MEM_0
|
||||
|
||||
.tdata : {
|
||||
. = ALIGN(64);
|
||||
__tdata_start = .;
|
||||
*(.tdata)
|
||||
*(.tdata.*)
|
||||
*(.gnu.linkonce.td.*)
|
||||
__tdata_end = .;
|
||||
} > psu_ddr_0_MEM_0
|
||||
|
||||
.tbss : {
|
||||
. = ALIGN(64);
|
||||
__tbss_start = .;
|
||||
*(.tbss)
|
||||
*(.tbss.*)
|
||||
*(.gnu.linkonce.tb.*)
|
||||
__tbss_end = .;
|
||||
} > psu_ddr_0_MEM_0
|
||||
|
||||
.bss (NOLOAD) : {
|
||||
. = ALIGN(64);
|
||||
__bss_start__ = .;
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(.gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
. = ALIGN(64);
|
||||
__bss_end__ = .;
|
||||
} > psu_ddr_0_MEM_0
|
||||
|
||||
_SDA_BASE_ = __sdata_start + ((__sbss_end - __sdata_start) / 2 );
|
||||
|
||||
_SDA2_BASE_ = __sdata2_start + ((__sbss2_end - __sdata2_start) / 2 );
|
||||
|
||||
/* Generate Stack and Heap definitions */
|
||||
|
||||
.heap (NOLOAD) : {
|
||||
. = ALIGN(64);
|
||||
_heap = .;
|
||||
HeapBase = .;
|
||||
_heap_start = .;
|
||||
. += _HEAP_SIZE;
|
||||
_heap_end = .;
|
||||
HeapLimit = .;
|
||||
} > psu_ddr_0_MEM_0
|
||||
|
||||
.stack (NOLOAD) : {
|
||||
. = ALIGN(64);
|
||||
_el3_stack_end = .;
|
||||
. += _STACK_SIZE;
|
||||
__el3_stack = .;
|
||||
_el2_stack_end = .;
|
||||
. += _EL2_STACK_SIZE;
|
||||
. = ALIGN(64);
|
||||
__el2_stack = .;
|
||||
_el1_stack_end = .;
|
||||
. += _EL1_STACK_SIZE;
|
||||
. = ALIGN(64);
|
||||
__el1_stack = .;
|
||||
_el0_stack_end = .;
|
||||
. += _EL0_STACK_SIZE;
|
||||
. = ALIGN(64);
|
||||
__el0_stack = .;
|
||||
} > psu_ddr_0_MEM_0
|
||||
|
||||
_end = .;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
/***************************************************************************//**
|
||||
* @file ad9361/src/main.c
|
||||
* @brief Implementation of Main Function.
|
||||
* @author DBogdan ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2013(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
// Platform includes
|
||||
#include <inttypes.h>
|
||||
#include <xparameters.h>
|
||||
#include <xil_mmu.h>
|
||||
#include "xgpiops.h"
|
||||
#include "xrfdc.h"
|
||||
// ADI Drivers
|
||||
#include "app_config.h"
|
||||
#include "dev_profile/dev_profile.h"
|
||||
#include "adi_noos/drivers/axi_core/spi_engine/spi_engine.h"
|
||||
// AXI-Cores includes
|
||||
#include "adi_noos/drivers/axi_core/spi_engine/spi_engine.h"
|
||||
#include "adi_noos/drivers/platform/gpio_extra.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Variables Definitions *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
struct spi_engine_init_param spi_engine_param = {
|
||||
.ref_clk_hz = SPI_ENGINE_REF_CLK,
|
||||
.type = SPI_ENGINE,
|
||||
.spi_engine_baseaddr = SPI_ENGINE_BASEADDR,
|
||||
.cs_delay = SPI_ENGINE_CS_DELAY,
|
||||
.data_width = SPI_ENGINE_DATA_WIDTH
|
||||
};
|
||||
|
||||
struct xil_gpio_init_param xil_gpio_param = {
|
||||
.type = GPIO_PS,
|
||||
.device_id = GPIO_DEVICE_ID
|
||||
};
|
||||
|
||||
struct lmk04828_dev *lmk04828_inst;
|
||||
|
||||
XRFdc RFdc;
|
||||
XGpioPs Gpio;
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief main
|
||||
*******************************************************************************/
|
||||
int main(void)
|
||||
{
|
||||
int32_t Status;
|
||||
|
||||
// gpio initialization
|
||||
XGpioPs_Config *ConfigPtr;
|
||||
ConfigPtr = XGpioPs_LookupConfig(GPIO_DEVICE_ID);
|
||||
Status = XGpioPs_CfgInitialize(&Gpio, ConfigPtr, ConfigPtr->BaseAddr);
|
||||
if (Status != XST_SUCCESS)
|
||||
{
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
// rf data converter initialization
|
||||
XRFdc_Config *RFdc_ConfigPtr;
|
||||
RFdc_ConfigPtr = XRFdc_LookupConfig(RFDC_DEVICE_ID);
|
||||
Status = XRFdc_CfgInitialize(&RFdc, RFdc_ConfigPtr);
|
||||
if (Status != XST_SUCCESS)
|
||||
{
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/**********************************************************/
|
||||
/***************** LMK04828 Configuration *****************/
|
||||
/**********************************************************/
|
||||
Status = lmk04828_init(&lmk04828_inst, &lmk04828_default_init_param);
|
||||
for(int i = 0; i < lmk04828_default_config_len; i++)
|
||||
{
|
||||
Status = lmk04828_write(lmk04828_inst, lmk04828_default_config[i].addr, lmk04828_default_config[i].value);
|
||||
if (lmk04828_default_config[i].addr == 0x0000)
|
||||
{
|
||||
mdelay(500);
|
||||
}
|
||||
}
|
||||
|
||||
// check pll2 lock status
|
||||
uint8_t reg183;
|
||||
Status = lmk04828_read(lmk04828_inst, 0x0183, ®183);
|
||||
if (reg183 & 0x02) {
|
||||
xil_printf("LMK04828 Config Done.\n");
|
||||
}
|
||||
else {
|
||||
xil_printf("LMK04828 not lock!\n");
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
print("Done.\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/***************************************************************************//**
|
||||
* @file ad9361/src/parameters.h
|
||||
* @brief Parameters Definitions.
|
||||
* @author DBogdan ([email protected])
|
||||
********************************************************************************
|
||||
* Copyright 2013(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
#ifndef __PARAMETERS_H__
|
||||
#define __PARAMETERS_H__
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
#include <xparameters.h>
|
||||
#include "app_config.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** Macros and Constants Definitions **********************/
|
||||
/******************************************************************************/
|
||||
#ifdef XILINX_PLATFORM
|
||||
|
||||
#define FCLK_CLK0_HZ 50000000
|
||||
|
||||
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
|
||||
|
||||
#define GPIO_DEVICE_ID XPAR_PSU_GPIO_0_DEVICE_ID
|
||||
#define RFDC_DEVICE_ID XPAR_USP_RF_DATA_CONVERTER_DEVICE_ID
|
||||
#define GPIO_OFFSET 78
|
||||
#define GPIO_INPUT 0
|
||||
#define GPIO_OUTPUT 1
|
||||
#define GPIO_DISABLE 0
|
||||
#define GPIO_ENABLE 1
|
||||
|
||||
#define SPI_DEVICE_ID 0
|
||||
#define SPI_ENGINE_REF_CLK FCLK_CLK0_HZ
|
||||
#define SPI_ENGINE_MAX_SPEED 2500000
|
||||
#define SPI_ENGINE_BASEADDR XPAR_AXI_SPI_ENGINE_AXI_SPI_ENGINE_BASEADDR
|
||||
#define SPI_ENGINE_DATA_WIDTH 8
|
||||
#define SPI_ENGINE_CS_DELAY 3
|
||||
|
||||
#define SPI_CS_LMK04828 0x00
|
||||
|
||||
#endif
|
||||
|
||||
#endif // __PARAMETERS_H__
|
||||
@@ -0,0 +1,108 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||
|
||||
<cconfiguration id="com.xilinx.sdx.system.managedbuilder.debugConfiguration.1530746339">
|
||||
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.xilinx.sdx.system.managedbuilder.debugConfiguration.1530746339" moduleId="org.eclipse.cdt.core.settings" name="Debug">
|
||||
|
||||
<externalSettings/>
|
||||
|
||||
<extensions>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
</extensions>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
|
||||
<configuration artifactName="${ProjName}" buildProperties="" description="" id="com.xilinx.sdx.system.managedbuilder.debugConfiguration.1530746339" name="Debug" parent="com.xilinx.sdx.system.managedbuilder.debugConfiguration">
|
||||
|
||||
<folderInfo id="com.xilinx.sdx.system.managedbuilder.debugConfiguration.1530746339." name="/" resourcePath="">
|
||||
|
||||
<toolChain id="com.xilinx.sdx.system.managedbuilder.debug.toolChain.1522907084" name="System Toolchain" superClass="com.xilinx.sdx.system.managedbuilder.debug.toolChain">
|
||||
|
||||
<targetPlatform id="com.xilinx.sdx.system.managedbuilder.debugConfiguration.1530746339..920443458" name=""/>
|
||||
|
||||
<builder buildPath="${workspace_loc:/dj_47dr_basic_system}/Debug" enableAutoBuild="true" id="com.xilinx.sdx.system.managedbuilder.systemBuilder.2071858494" managedBuildOn="true" name="System Project Builder.Debug" superClass="com.xilinx.sdx.system.managedbuilder.systemBuilder"/>
|
||||
|
||||
<tool id="com.xilinx.sdx.system.managedbuilder.toolchain.cfjoinTool.1353465847" name="System Builder" superClass="com.xilinx.sdx.system.managedbuilder.toolchain.cfjoinTool"/>
|
||||
|
||||
</toolChain>
|
||||
|
||||
</folderInfo>
|
||||
|
||||
</configuration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
|
||||
</cconfiguration>
|
||||
|
||||
<cconfiguration id="com.xilinx.sdx.system.managedbuilder.releaseConfiguration.1841717065">
|
||||
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.xilinx.sdx.system.managedbuilder.releaseConfiguration.1841717065" moduleId="org.eclipse.cdt.core.settings" name="Release">
|
||||
|
||||
<externalSettings/>
|
||||
|
||||
<extensions>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
</extensions>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
|
||||
<configuration artifactName="${ProjName}" buildProperties="" description="" id="com.xilinx.sdx.system.managedbuilder.releaseConfiguration.1841717065" name="Release" parent="com.xilinx.sdx.system.managedbuilder.releaseConfiguration">
|
||||
|
||||
<folderInfo id="com.xilinx.sdx.system.managedbuilder.releaseConfiguration.1841717065." name="/" resourcePath="">
|
||||
|
||||
<toolChain id="com.xilinx.sdx.system.managedbuilder.release.toolChain.763401419" name="System Toolchain" superClass="com.xilinx.sdx.system.managedbuilder.release.toolChain">
|
||||
|
||||
<targetPlatform id="com.xilinx.sdx.system.managedbuilder.releaseConfiguration.1841717065..366380419" name=""/>
|
||||
|
||||
<builder buildPath="${workspace_loc:/dj_47dr_basic_system}/Release" enableAutoBuild="true" id="com.xilinx.sdx.system.managedbuilder.systemBuilder.412763704" managedBuildOn="true" name="System Project Builder.Release" superClass="com.xilinx.sdx.system.managedbuilder.systemBuilder"/>
|
||||
|
||||
<tool id="com.xilinx.sdx.system.managedbuilder.toolchain.cfjoinTool.1321316502" name="System Builder" superClass="com.xilinx.sdx.system.managedbuilder.toolchain.cfjoinTool"/>
|
||||
|
||||
</toolChain>
|
||||
|
||||
</folderInfo>
|
||||
|
||||
</configuration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
|
||||
</cconfiguration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
|
||||
<project id="dj_47dr_basic_system.com.xilinx.sdx.system.managedbuilder.projectType.806574333" name="Vitis Embedded System Project" projectType="com.xilinx.sdx.system.managedbuilder.projectType"/>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="refreshScope"/>
|
||||
|
||||
</cproject>
|
||||
@@ -0,0 +1,2 @@
|
||||
/Debug/
|
||||
/Release/
|
||||
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>dj_47dr_basic_system</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
<project>dj_47dr_basic</project>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>com.xilinx.sdx.system.core.embedded</nature>
|
||||
<nature>com.xilinx.sdx.system.systemprojectnature</nature>
|
||||
<nature>org.eclipse.cdt.core.cnature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.core.ccnature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
Binary file not shown.
+12
@@ -0,0 +1,12 @@
|
||||
/* /tmp/bootgen_dj_47dr_basic_system14404165238617595020/sd_card_temp/boot.bif */
|
||||
/* Command to create bitstream .bin file: */
|
||||
/* bootgen -image <bif_file> -split bin -w */
|
||||
/* Command to create BOOT.BIN file: */
|
||||
/* bootgen -arch zynqmp -image <bif_file> -w -o i BOOT.BIN */
|
||||
/*system_top*/
|
||||
the_ROM_image:
|
||||
{
|
||||
[bootloader, destination_cpu=a53-0] /home/josh/dj_47dr_ibert/vitis_classic/system_top/export/system_top/sw/system_top/boot/fsbl.elf
|
||||
[destination_device=pl] /home/josh/dj_47dr_ibert/vitis_classic/dj_47dr_basic/_ide/bitstream/system_top.bit
|
||||
[destination_cpu=a53-0, exception_level=el-3] /home/josh/dj_47dr_ibert/vitis_classic/dj_47dr_basic/Release/dj_47dr_basic.elf
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
# Usage with Vitis IDE:
|
||||
# In Vitis IDE create a Single Application Debug launch configuration,
|
||||
# change the debug type to 'Attach to running target' and provide this
|
||||
# tcl script in 'Execute Script' option.
|
||||
# Path of this script: /home/josh/dj_47dr_ibert/vitis_classic/dj_47dr_basic_system/_ide/scripts/debugger_dj_47dr_basic-default.tcl
|
||||
#
|
||||
#
|
||||
# Usage with xsct:
|
||||
# To debug using xsct, launch xsct and run below command
|
||||
# source /home/josh/dj_47dr_ibert/vitis_classic/dj_47dr_basic_system/_ide/scripts/debugger_dj_47dr_basic-default.tcl
|
||||
#
|
||||
connect -url tcp:127.0.0.1:3121
|
||||
source /tools/Xilinx/Vitis/2024.1/scripts/vitis/util/zynqmp_utils.tcl
|
||||
targets -set -nocase -filter {name =~"APU*" && jtag_cable_name =~ "Digilent JTAG-HS1 210512180081" && jtag_device_ctx=="jsn-JTAG-HS1-210512180081-5ba00477-0"}
|
||||
rst -system
|
||||
after 3000
|
||||
targets -set -filter {jtag_cable_name =~ "Digilent JTAG-HS1 210512180081" && level==0 && jtag_device_ctx=="jsn-JTAG-HS1-210512180081-147ff093-0"}
|
||||
fpga -file /home/josh/dj_47dr_ibert/vitis_classic/dj_47dr_basic/_ide/bitstream/system_top.bit
|
||||
targets -set -nocase -filter {name =~"APU*" && jtag_cable_name =~ "Digilent JTAG-HS1 210512180081" && jtag_device_ctx=="jsn-JTAG-HS1-210512180081-5ba00477-0"}
|
||||
loadhw -hw /home/josh/dj_47dr_ibert/vitis_classic/system_top/export/system_top/hw/system_top.xsa -mem-ranges [list {0x80000000 0xbfffffff} {0x400000000 0x5ffffffff} {0x1000000000 0x7fffffffff}] -regs
|
||||
configparams force-mem-access 1
|
||||
targets -set -nocase -filter {name =~"APU*" && jtag_cable_name =~ "Digilent JTAG-HS1 210512180081" && jtag_device_ctx=="jsn-JTAG-HS1-210512180081-5ba00477-0"}
|
||||
set mode [expr [mrd -value 0xFF5E0200] & 0xf]
|
||||
targets -set -nocase -filter {name =~ "*A53*#0" && jtag_cable_name =~ "Digilent JTAG-HS1 210512180081" && jtag_device_ctx=="jsn-JTAG-HS1-210512180081-5ba00477-0"}
|
||||
rst -processor
|
||||
dow /home/josh/dj_47dr_ibert/vitis_classic/system_top/export/system_top/sw/system_top/boot/fsbl.elf
|
||||
set bp_49_27_fsbl_bp [bpadd -addr &XFsbl_Exit]
|
||||
con -block -timeout 60
|
||||
bpremove $bp_49_27_fsbl_bp
|
||||
targets -set -nocase -filter {name =~ "*A53*#0" && jtag_cable_name =~ "Digilent JTAG-HS1 210512180081" && jtag_device_ctx=="jsn-JTAG-HS1-210512180081-5ba00477-0"}
|
||||
rst -processor
|
||||
dow /home/josh/dj_47dr_ibert/vitis_classic/dj_47dr_basic/Release/dj_47dr_basic.elf
|
||||
configparams force-mem-access 0
|
||||
targets -set -nocase -filter {name =~ "*A53*#0" && jtag_cable_name =~ "Digilent JTAG-HS1 210512180081" && jtag_device_ctx=="jsn-JTAG-HS1-210512180081-5ba00477-0"}
|
||||
con
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="ASCII"?>
|
||||
<systemproject:SystemProject xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sdsproject="http://www.xilinx.com/sdsproject" xmlns:systemproject="http://www.xilinx.com/systemproject" name="dj_47dr_basic_system" platform="/home/josh/Workspace/vivado/vivado_pub/projects/dj_47dr/dj_47dr_ibert/vitis_classic/system_top/export/system_top/system_top.xpfm" platformUID="xilinx:::0.0(custom)" sysConfig="system_top" runtime="C/C++" rootFSLocation="" linuxImage="" sysroot="">
|
||||
<configuration name="Debug" id="com.xilinx.sdx.system.managedbuilder.debugConfiguration.1530746339">
|
||||
<configBuildOptions xsi:type="systemproject:SystemOptions">
|
||||
<applications name="dj_47dr_basic" domainName="standalone_psu_cortexa53_0" domainPrettyName="standalone_psu_cortexa53_0" appBuildConfig="Debug"/>
|
||||
<options xsi:type="sdsproject:Option" gensdcard="true" dmclkid="0"/>
|
||||
</configBuildOptions>
|
||||
<lastBuildOptions xsi:type="systemproject:SystemOptions">
|
||||
<applications name="dj_47dr_basic" domainName="standalone_psu_cortexa53_0" domainPrettyName="standalone_psu_cortexa53_0" appBuildConfig="Debug"/>
|
||||
<options xsi:type="sdsproject:Option" gensdcard="true" dmclkid="0"/>
|
||||
</lastBuildOptions>
|
||||
</configuration>
|
||||
<configuration name="Release" id="com.xilinx.sdx.system.managedbuilder.releaseConfiguration.1841717065">
|
||||
<configBuildOptions xsi:type="systemproject:SystemOptions">
|
||||
<applications name="dj_47dr_basic" domainName="standalone_psu_cortexa53_0" domainPrettyName="standalone_psu_cortexa53_0" appBuildConfig="Release"/>
|
||||
<options xsi:type="sdsproject:Option" gensdcard="true" dmclkid="0"/>
|
||||
</configBuildOptions>
|
||||
<lastBuildOptions xsi:type="systemproject:SystemOptions">
|
||||
<applications name="dj_47dr_basic" domainName="standalone_psu_cortexa53_0" domainPrettyName="standalone_psu_cortexa53_0" appBuildConfig="Release"/>
|
||||
<options xsi:type="sdsproject:Option" gensdcard="true" dmclkid="0"/>
|
||||
</lastBuildOptions>
|
||||
</configuration>
|
||||
</systemproject:SystemProject>
|
||||
@@ -0,0 +1,24 @@
|
||||
<?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="org.eclipse.cdt.core.default.config.1443200959">
|
||||
|
||||
<storageModule buildSystemId="org.eclipse.cdt.core.defaultConfigDataProvider" id="org.eclipse.cdt.core.default.config.1443200959" moduleId="org.eclipse.cdt.core.settings" name="Configuration">
|
||||
|
||||
<externalSettings/>
|
||||
|
||||
<extensions/>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
|
||||
</cconfiguration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||
|
||||
</cproject>
|
||||
@@ -0,0 +1,3 @@
|
||||
/export/
|
||||
*.o
|
||||
*.d
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>system_top</name>
|
||||
<comment>Created by Vitis v2024.1</comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>com.xilinx.sdx.scw.PlatformProjectBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>com.xilinx.sdx.scw.platformProject</nature>
|
||||
<nature>org.eclipse.cdt.core.cnature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
{"platformName":"system_top","sprVersion":"2.0","mode":"gui","dsaType":"Fixed","platformDesc":"system_top","platHandOff":"/home/josh/dj_47dr_ibert/system_top.xsa","platIntHandOff":"<platformDir>/hw/system_top.xsa","deviceType":"zynqMP","platIsPrebuiltAutogen":"false","platIsNoBootBsp":"false","platFsblTarget":"psu_cortexa53_0","hasFsblMakeHasChanges":"false","hasPmufwMakeHasChanges":"false","fsblExtraCompilerFlags":"-MMD -MP -Wall -fmessage-length=0 -DARMA53_64 -Os -flto -ffat-lto-objects ","pmufwExtraCompilerFlags":"-MMD -MP -mlittle-endian -mxl-barrel-shift -mxl-pattern-compare -mcpu=v9.2 -mxl-soft-mul -Os -flto -ffat-lto-objects ","platPreBuiltFlag":false,"platformSamplesDir":"","platActiveSys":"system_top","systems":[{"systemName":"system_top","systemDesc":"system_top","sysIsBootAutoGen":"true","systemDispName":"system_top","sysActiveDom":"standalone_psu_cortexa53_0","sysDefaultDom":"standalone_psu_cortexa53_0","domains":[{"domainName":"zynqmp_fsbl","domainDispName":"zynqmp_fsbl","domainDesc":"FSBL Application BSP - Auto Generated.","processors":"psu_cortexa53_0","os":"standalone","sdxOs":"standalone","debugEnable":"","domRuntimes":["cpp"],"swRepo":"","mssOsVer":"9.1","mssFile":"","md5Digest":"aa0403ecc96b493b46451bd1df82fc201","compatibleApp":"zynqmp_fsbl","domType":"bootDomain","arch":"64-bit","appSettings":{"appCompilerFlags":"","appLinkerFlags":""},"addedLibs":["xilffs:5.2","xilsecure:5.3","xilpm:5.2"],"libOptions":{"standalone":{"zynqmp_fsbl_bsp":"true","libOptionNames":["zynqmp_fsbl_bsp"]},"xilffs":{"read_only":"true","use_mkfs":"false","libOptionNames":["read_only","use_mkfs"]},"xilsecure":{"tpm_support":"true","libOptionNames":["tpm_support"]},"libsContainingOptions":["standalone","xilffs","xilsecure"]},"prebuiltLibs":{"prebuiltIncPath":[],"prebuiltLibPath":[]},"isolation":{}},{"domainName":"zynqmp_pmufw","domainDispName":"zynqmp_pmufw","domainDesc":"PMUFW Application BSP - Auto Generated.","processors":"psu_pmu_0","os":"standalone","sdxOs":"standalone","debugEnable":"","domRuntimes":["cpp"],"swRepo":"","mssOsVer":"9.1","mssFile":"","md5Digest":"73b6b202eb9eb62280586e95f9c5a9c61","compatibleApp":"zynqmp_pmufw","domType":"bootDomain","arch":"32-bit","appSettings":{"appCompilerFlags":"","appLinkerFlags":""},"addedLibs":["xilfpga:6.6","xilsecure:5.3","xilskey:7.6"],"libOptions":{"psu_pmu_0":{"extra_compiler_flags":"-g -ffunction-sections -fdata-sections -Wall -Wextra -fno-tree-loop-distribute-patterns -Os -flto -ffat-lto-objects","libOptionNames":["extra_compiler_flags"]},"libsContainingOptions":["psu_pmu_0"]},"prebuiltLibs":{"prebuiltIncPath":[],"prebuiltLibPath":[]},"isolation":{}},{"domainName":"standalone_psu_cortexa53_0","domainDispName":"standalone_psu_cortexa53_0","domainDesc":"standalone_psu_cortexa53_0","processors":"psu_cortexa53_0","os":"standalone","sdxOs":"standalone","qemuArgs":"<platformDir>/resources/system_top/standalone_psu_cortexa53_0/qemu_args.txt","qemuData":"<platformDir>/resources/system_top/standalone_psu_cortexa53_0/qemu","pmuQemuArgs":"<platformDir>/resources/system_top/standalone_psu_cortexa53_0/pmu_args.txt","debugEnable":"False","domRuntimes":["cpp"],"swRepo":"","mssOsVer":"9.1","mssFile":"","md5Digest":"95602ffcf523057eb4ed533b1a9f297a","compatibleApp":"","domType":"mssDomain","arch":"64-bit","appSettings":{"appCompilerFlags":"","appLinkerFlags":""},"addedLibs":[],"libOptions":{"standalone":{"stdin":"psu_coresight_0","stdout":"psu_coresight_0","libOptionNames":["stdin","stdout"]},"libsContainingOptions":["standalone"]},"prebuiltLibs":{"prebuiltIncPath":[],"prebuiltLibPath":[]},"isolation":{}}]}]}
|
||||
@@ -0,0 +1,42 @@
|
||||
#
|
||||
# Usage: To re-create this platform project launch xsct with below options.
|
||||
# xsct /home/josh/dj_47dr_ibert/vitis_classic/system_top/platform.tcl
|
||||
#
|
||||
# OR launch xsct and run below command.
|
||||
# source /home/josh/dj_47dr_ibert/vitis_classic/system_top/platform.tcl
|
||||
#
|
||||
# To create the platform in a different location, modify the -out option of "platform create" command.
|
||||
# -out option specifies the output directory of the platform project.
|
||||
|
||||
platform create -name {system_top}\
|
||||
-hw {/home/josh/dj_47dr_ibert/system_top.xsa}\
|
||||
-arch {64-bit} -fsbl-target {psu_cortexa53_0} -out {/home/josh/dj_47dr_ibert/vitis_classic}
|
||||
|
||||
platform write
|
||||
domain create -name {standalone_psu_cortexa53_0} -display-name {standalone_psu_cortexa53_0} -os {standalone} -proc {psu_cortexa53_0} -runtime {cpp} -arch {64-bit} -support-app {hello_world}
|
||||
platform generate -domains
|
||||
platform active {system_top}
|
||||
domain active {zynqmp_fsbl}
|
||||
domain active {zynqmp_pmufw}
|
||||
domain active {standalone_psu_cortexa53_0}
|
||||
platform generate -quick
|
||||
platform generate
|
||||
platform config -updatehw {/home/josh/dj_47dr_ibert/system_top.xsa}
|
||||
platform generate -domains
|
||||
bsp reload
|
||||
bsp config stdin "psu_coresight_0"
|
||||
bsp config stdout "psu_coresight_0"
|
||||
bsp write
|
||||
bsp reload
|
||||
catch {bsp regenerate}
|
||||
platform generate -domains standalone_psu_cortexa53_0
|
||||
platform active {system_top}
|
||||
platform config -updatehw {/home/josh/dj_47dr_ibert/system_top.xsa}
|
||||
platform generate -domains
|
||||
platform active {system_top}
|
||||
bsp reload
|
||||
bsp config stdin "psu_coresight_0"
|
||||
bsp reload
|
||||
platform generate -domains
|
||||
platform active {system_top}
|
||||
platform generate -domains
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
# Makefile generated by Xilinx.
|
||||
|
||||
DRIVER_LIB_VERSION = 1.0
|
||||
PROCESSOR = psu_cortexa53_0
|
||||
LIBRARIES = ${PROCESSOR}/lib/libxil.a
|
||||
BSP_MAKEFILES := $(wildcard $(PROCESSOR)/libsrc/*/src/Makefile)
|
||||
SUBDIRS := $(patsubst %/Makefile, %, $(BSP_MAKEFILES))
|
||||
BSP_SEQUENTIAL_MAKEFILES := psu_cortexa53_0/libsrc/libmetal_v2_7/src/Makefile
|
||||
BSP_PARALLEL_MAKEFILES := $(filter-out $(BSP_SEQUENTIAL_MAKEFILES),$(BSP_MAKEFILES))
|
||||
SEQ_SUBDIRS := $(patsubst %/Makefile, %, $(BSP_SEQUENTIAL_MAKEFILES))
|
||||
PAR_SUBDIRS := $(patsubst %/Makefile, %, $(BSP_PARALLEL_MAKEFILES))
|
||||
|
||||
ifneq (,$(findstring win,$(RDI_PLATFORM)))
|
||||
SHELL = CMD
|
||||
endif
|
||||
|
||||
all:
|
||||
$(MAKE) --no-print-directory seq_libs
|
||||
$(MAKE) -j 18 --no-print-directory par_libs
|
||||
$(MAKE) --no-print-directory archive
|
||||
@echo 'Finished building libraries'
|
||||
|
||||
include: $(addsuffix /make.include,$(SUBDIRS))
|
||||
|
||||
seq_libs: $(addsuffix /make.libs,$(SEQ_SUBDIRS))
|
||||
@echo 'Finished building libraries sequentially.'
|
||||
|
||||
par_libs: $(addsuffix /make.libs,$(PAR_SUBDIRS))
|
||||
@echo 'Finished building libraries parallelly.'
|
||||
|
||||
archive:
|
||||
aarch64-none-elf-ar -r $(LIBRARIES) $(sort $(wildcard $(PROCESSOR)/lib/*.o))
|
||||
|
||||
clean: $(addsuffix /make.clean,$(SUBDIRS))
|
||||
rm -f ${PROCESSOR}/lib/libxil.a
|
||||
|
||||
$(PROCESSOR)/lib/libxil.a: $(PROCESSOR)/lib/libxil_init.a
|
||||
cp -f $< $@
|
||||
|
||||
%/make.include: $(if $(wildcard $(PROCESSOR)/lib/libxil_init.a),$(PROCESSOR)/lib/libxil.a,)
|
||||
@echo "Running Make include in $(subst /make.include,,$@)"
|
||||
$(MAKE) -C $(subst /make.include,,$@) -s include "SHELL=$(SHELL)" "COMPILER=aarch64-none-elf-gcc" "ASSEMBLER=aarch64-none-elf-as" "ARCHIVER=aarch64-none-elf-ar" "COMPILER_FLAGS= -O2 -c" "EXTRA_COMPILER_FLAGS=-g -Wall -Wextra -fno-tree-loop-distribute-patterns"
|
||||
|
||||
%/make.libs: include
|
||||
@echo "Running Make libs in $(subst /make.libs,,$@)"
|
||||
$(MAKE) -C $(subst /make.libs,,$@) -s libs "SHELL=$(SHELL)" "COMPILER=aarch64-none-elf-gcc" "ASSEMBLER=aarch64-none-elf-as" "ARCHIVER=aarch64-none-elf-ar" "COMPILER_FLAGS= -O2 -c" "EXTRA_COMPILER_FLAGS=-g -Wall -Wextra -fno-tree-loop-distribute-patterns"
|
||||
|
||||
%/make.clean:
|
||||
$(MAKE) -C $(subst /make.clean,,$@) -s clean
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
# generated by Xilinx.
|
||||
|
||||
DEPENDENCY_FLAGS= -MMD -MP
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* CAUTION: This file is automatically generated by HSI.
|
||||
* Version: 2024.1
|
||||
* DO NOT EDIT.
|
||||
*
|
||||
* Copyright (C) 2010-2024 Xilinx, Inc. All Rights Reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
|
||||
*
|
||||
* Description: Configurations for Standalone BSP
|
||||
*
|
||||
*******************************************************************/
|
||||
|
||||
#ifndef BSPCONFIG_H /* prevent circular inclusions */
|
||||
#define BSPCONFIG_H /* by using protection macros */
|
||||
|
||||
#define MICROBLAZE_PVR_NONE
|
||||
#define EL3 1
|
||||
#define EL1_NONSECURE 0
|
||||
#define HYP_GUEST 0
|
||||
|
||||
#endif /*end of __BSPCONFIG_H_*/
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2022 Xilinx, Inc. and Contributors. All rights reserved.
|
||||
* Copyright (c) 2022-2023 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file alloc.h
|
||||
* @brief Memory allocation handling primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_ALLOC__H__
|
||||
#define __METAL_ALLOC__H__
|
||||
|
||||
#include <metal/system/generic/alloc.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup Memory Allocation Interfaces
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief allocate requested memory size
|
||||
* return a pointer to the allocated memory
|
||||
*
|
||||
* @param[in] size size in byte of requested memory
|
||||
* @return memory pointer, or 0 if it failed to allocate
|
||||
*/
|
||||
static inline void *metal_allocate_memory(unsigned int size)
|
||||
{
|
||||
return __metal_allocate_memory(size);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief free the memory previously allocated
|
||||
*
|
||||
* @param[in] ptr pointer to memory
|
||||
*/
|
||||
static inline void metal_free_memory(void *ptr)
|
||||
{
|
||||
__metal_free_memory(ptr);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_ALLOC__H__ */
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file assert.h
|
||||
* @brief Assertion support.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_ASSERT__H__
|
||||
#define __METAL_ASSERT__H__
|
||||
|
||||
#include <metal/system/generic/assert.h>
|
||||
|
||||
/**
|
||||
* @brief Assertion macro.
|
||||
* @param cond Condition to test.
|
||||
*/
|
||||
#define metal_assert(cond) metal_sys_assert(cond)
|
||||
|
||||
#endif /* __METAL_ASSERT_H__ */
|
||||
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2022, Xilinx Inc. and Contributors. All rights reserved.
|
||||
* Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file atomic.h
|
||||
* @brief Atomic primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_ATOMIC__H__
|
||||
#define __METAL_ATOMIC__H__
|
||||
|
||||
#include <metal/config.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
# include <cstdint>
|
||||
|
||||
/*
|
||||
* <atomic> has the same functionality as <stdatomic.h> but all members are only
|
||||
* accessible in the std namespace. As the rest of libmetal is pure C, it does
|
||||
* not know about namespaces, even when compiled as part of a C++ file. So we
|
||||
* just export the members of <atomic> into the global namespace.
|
||||
*/
|
||||
# include <atomic>
|
||||
using std::atomic_flag;
|
||||
using std::memory_order;
|
||||
using std::memory_order_relaxed;
|
||||
using std::memory_order_consume;
|
||||
using std::memory_order_acquire;
|
||||
using std::memory_order_release;
|
||||
using std::memory_order_acq_rel;
|
||||
using std::memory_order_seq_cst;
|
||||
|
||||
using std::atomic_bool;
|
||||
using std::atomic_char;
|
||||
using std::atomic_schar;
|
||||
using std::atomic_uchar;
|
||||
using std::atomic_short;
|
||||
using std::atomic_ushort;
|
||||
using std::atomic_int;
|
||||
using std::atomic_uint;
|
||||
using std::atomic_long;
|
||||
using std::atomic_ulong;
|
||||
using std::atomic_llong;
|
||||
using std::atomic_ullong;
|
||||
using std::atomic_char16_t;
|
||||
using std::atomic_char32_t;
|
||||
using std::atomic_wchar_t;
|
||||
using std::atomic_int_least8_t;
|
||||
using std::atomic_uint_least8_t;
|
||||
using std::atomic_int_least16_t;
|
||||
using std::atomic_uint_least16_t;
|
||||
using std::atomic_int_least32_t;
|
||||
using std::atomic_uint_least32_t;
|
||||
using std::atomic_int_least64_t;
|
||||
using std::atomic_uint_least64_t;
|
||||
using std::atomic_int_fast8_t;
|
||||
using std::atomic_uint_fast8_t;
|
||||
using std::atomic_int_fast16_t;
|
||||
using std::atomic_uint_fast16_t;
|
||||
using std::atomic_int_fast32_t;
|
||||
using std::atomic_uint_fast32_t;
|
||||
using std::atomic_int_fast64_t;
|
||||
using std::atomic_uint_fast64_t;
|
||||
using std::atomic_intptr_t;
|
||||
using std::atomic_uintptr_t;
|
||||
using std::atomic_size_t;
|
||||
using std::atomic_ptrdiff_t;
|
||||
using std::atomic_intmax_t;
|
||||
using std::atomic_uintmax_t;
|
||||
|
||||
using std::atomic_flag_test_and_set;
|
||||
using std::atomic_flag_test_and_set_explicit;
|
||||
using std::atomic_flag_clear;
|
||||
using std::atomic_flag_clear_explicit;
|
||||
using std::atomic_init;
|
||||
using std::atomic_is_lock_free;
|
||||
using std::atomic_store;
|
||||
using std::atomic_store_explicit;
|
||||
using std::atomic_load;
|
||||
using std::atomic_load_explicit;
|
||||
using std::atomic_exchange;
|
||||
using std::atomic_exchange_explicit;
|
||||
using std::atomic_compare_exchange_strong;
|
||||
using std::atomic_compare_exchange_strong_explicit;
|
||||
using std::atomic_compare_exchange_weak;
|
||||
using std::atomic_compare_exchange_weak_explicit;
|
||||
using std::atomic_fetch_add;
|
||||
using std::atomic_fetch_add_explicit;
|
||||
using std::atomic_fetch_sub;
|
||||
using std::atomic_fetch_sub_explicit;
|
||||
using std::atomic_fetch_or;
|
||||
using std::atomic_fetch_or_explicit;
|
||||
using std::atomic_fetch_xor;
|
||||
using std::atomic_fetch_xor_explicit;
|
||||
using std::atomic_fetch_and;
|
||||
using std::atomic_fetch_and_explicit;
|
||||
using std::atomic_thread_fence;
|
||||
using std::atomic_signal_fence;
|
||||
|
||||
#elif defined(HAVE_STDATOMIC_H) && !defined(__CC_ARM) && \
|
||||
!defined(__STDC_NO_ATOMICS__)
|
||||
# include <stdint.h>
|
||||
# include <stdatomic.h>
|
||||
#elif defined(__GNUC__)
|
||||
# include <metal/compiler/gcc/atomic.h>
|
||||
#else
|
||||
# include <metal/processor/arm/atomic.h>
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_ATOMIC__H__ */
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file cache.h
|
||||
* @brief CACHE operation primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_CACHE__H__
|
||||
#define __METAL_CACHE__H__
|
||||
|
||||
#include <metal/system/generic/cache.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup cache CACHE Interfaces
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief flush specified data cache
|
||||
*
|
||||
* @param[in] addr start memory logical address
|
||||
* @param[in] len length of memory
|
||||
* If addr is NULL, and len is 0,
|
||||
* It will flush the whole data cache.
|
||||
*/
|
||||
static inline void metal_cache_flush(void *addr, unsigned int len)
|
||||
{
|
||||
__metal_cache_flush(addr, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief invalidate specified data cache
|
||||
*
|
||||
* @param[in] addr start memory logical address
|
||||
* @param[in] len length of memory
|
||||
* If addr is NULL, and len is 0,
|
||||
* It will invalidate the whole data cache.
|
||||
*/
|
||||
static inline void metal_cache_invalidate(void *addr, unsigned int len)
|
||||
{
|
||||
__metal_cache_invalidate(addr, len);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_CACHE__H__ */
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2022 Xilinx, Inc. and Contributors. All rights reserved.
|
||||
* Copyright (c) 2022-2023 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file compiler.h
|
||||
* @brief Compiler specific primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_COMPILER__H__
|
||||
#define __METAL_COMPILER__H__
|
||||
|
||||
#if defined(__GNUC__)
|
||||
# include <metal/compiler/gcc/compiler.h>
|
||||
#elif defined(__ICCARM__)
|
||||
# include <metal/compiler/iar/compiler.h>
|
||||
#elif defined(__CC_ARM)
|
||||
# error "MDK-ARM ARMCC compiler requires the GNU extensions to work correctly"
|
||||
#else
|
||||
# error "Missing compiler support"
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_COMPILER__H__ */
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/*-
|
||||
* Copyright (c) 2020 STMicroelectronics. All rights reserved.
|
||||
*
|
||||
* Copyright (c) 1982, 1986, 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
* (c) UNIX System Laboratories, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef __METAL_ARMCC_ERRNO__H__
|
||||
#define __METAL_ARMCC_ERRNO__H__
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define LIBMETAL_ERR_BASE 100
|
||||
|
||||
#define EPERM (LIBMETAL_ERR_BASE + 1) /* Operation not permitted */
|
||||
#define ENOENT (LIBMETAL_ERR_BASE + 2) /* No such file or directory */
|
||||
#define ESRCH (LIBMETAL_ERR_BASE + 3) /* No such process */
|
||||
#define EINTR (LIBMETAL_ERR_BASE + 4) /* Interrupted system call */
|
||||
#define EIO (LIBMETAL_ERR_BASE + 5) /* Input/output error */
|
||||
#define ENXIO (LIBMETAL_ERR_BASE + 6) /* Device not configured */
|
||||
#define E2BIG (LIBMETAL_ERR_BASE + 7) /* Argument list too long */
|
||||
#define ENOEXEC (LIBMETAL_ERR_BASE + 8) /* Exec format error */
|
||||
#define EBADF (LIBMETAL_ERR_BASE + 9) /* Bad file descriptor */
|
||||
#define ECHILD (LIBMETAL_ERR_BASE + 10) /* No child processes */
|
||||
#define EDEADLK (LIBMETAL_ERR_BASE + 11) /* Resource deadlock avoided */
|
||||
#define EACCES (LIBMETAL_ERR_BASE + 13) /* Permission denied */
|
||||
#define EFAULT (LIBMETAL_ERR_BASE + 14) /* Bad address */
|
||||
#define ENOTBLK (LIBMETAL_ERR_BASE + 15) /* Block device required */
|
||||
#define EBUSY (LIBMETAL_ERR_BASE + 16) /* Device busy */
|
||||
#define EEXIST (LIBMETAL_ERR_BASE + 17) /* File exists */
|
||||
#define EXDEV (LIBMETAL_ERR_BASE + 18) /* Cross-device link */
|
||||
#define ENODEV (LIBMETAL_ERR_BASE + 19) /* Operation not supported by device */
|
||||
#define ENOTDIR (LIBMETAL_ERR_BASE + 20) /* Not a directory */
|
||||
#define EISDIR (LIBMETAL_ERR_BASE + 21) /* Is a directory */
|
||||
#define ENFILE (LIBMETAL_ERR_BASE + 23) /* Too many open files in system */
|
||||
#define EMFILE (LIBMETAL_ERR_BASE + 24) /* Too many open files */
|
||||
#define ENOTTY (LIBMETAL_ERR_BASE + 25) /* Inappropriate ioctl for device */
|
||||
#define ETXTBSY (LIBMETAL_ERR_BASE + 26) /* Text file busy */
|
||||
#define EFBIG (LIBMETAL_ERR_BASE + 27) /* File too large */
|
||||
#define ENOSPC (LIBMETAL_ERR_BASE + 28) /* No space left on device */
|
||||
#define ESPIPE (LIBMETAL_ERR_BASE + 29) /* Illegal seek */
|
||||
#define EROFS (LIBMETAL_ERR_BASE + 30) /* Read-only filesystem */
|
||||
#define EMLINK (LIBMETAL_ERR_BASE + 31) /* Too many links */
|
||||
#define EPIPE (LIBMETAL_ERR_BASE + 32) /* Broken pipe */
|
||||
#define EAGAIN (LIBMETAL_ERR_BASE + 35) /* Resource temporarily unavailable */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_ARMCC_ERRNO__H__ */
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file gcc/atomic.h
|
||||
* @brief GCC specific atomic primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_GCC_ATOMIC__H__
|
||||
#define __METAL_GCC_ATOMIC__H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef int atomic_flag;
|
||||
typedef char atomic_char;
|
||||
typedef unsigned char atomic_uchar;
|
||||
typedef short atomic_short;
|
||||
typedef unsigned short atomic_ushort;
|
||||
typedef int atomic_int;
|
||||
typedef unsigned int atomic_uint;
|
||||
typedef atomic_uint atomic_uintptr_t;
|
||||
typedef long atomic_long;
|
||||
typedef unsigned long atomic_ulong;
|
||||
typedef long long atomic_llong;
|
||||
typedef unsigned long long atomic_ullong;
|
||||
|
||||
#define ATOMIC_FLAG_INIT 0
|
||||
#define ATOMIC_VAR_INIT(VAL) (VAL)
|
||||
|
||||
typedef enum {
|
||||
memory_order_relaxed,
|
||||
memory_order_consume,
|
||||
memory_order_acquire,
|
||||
memory_order_release,
|
||||
memory_order_acq_rel,
|
||||
memory_order_seq_cst,
|
||||
} memory_order;
|
||||
|
||||
#define atomic_flag_test_and_set(FLAG) \
|
||||
__sync_lock_test_and_set((FLAG), 1)
|
||||
#define atomic_flag_test_and_set_explicit(FLAG, MO) \
|
||||
atomic_flag_test_and_set(FLAG)
|
||||
#define atomic_flag_clear(FLAG) \
|
||||
__sync_lock_release((FLAG))
|
||||
#define atomic_flag_clear_explicit(FLAG, MO) \
|
||||
atomic_flag_clear(FLAG)
|
||||
#define atomic_init(OBJ, VAL) \
|
||||
do { *(OBJ) = (VAL); } while (0)
|
||||
#define atomic_is_lock_free(OBJ) \
|
||||
(sizeof(*(OBJ)) <= sizeof(long))
|
||||
#define atomic_store(OBJ, VAL) \
|
||||
do { *(OBJ) = (VAL); __sync_synchronize(); } while (0)
|
||||
#define atomic_store_explicit(OBJ, VAL, MO) \
|
||||
atomic_store((OBJ), (VAL))
|
||||
#define atomic_load(OBJ) \
|
||||
({ __sync_synchronize(); *(OBJ); })
|
||||
#define atomic_load_explicit(OBJ, MO) \
|
||||
atomic_load(OBJ)
|
||||
#define atomic_exchange(OBJ, DES) \
|
||||
({ \
|
||||
__typeof__(OBJ) obj = (OBJ); \
|
||||
__typeof__(*obj) des = (DES); \
|
||||
__typeof__(*obj) expval; \
|
||||
__typeof__(*obj) oldval = atomic_load(obj); \
|
||||
do { \
|
||||
expval = oldval; \
|
||||
oldval = __sync_val_compare_and_swap( \
|
||||
obj, expval, des); \
|
||||
} while (oldval != expval); \
|
||||
oldval; \
|
||||
})
|
||||
#define atomic_exchange_explicit(OBJ, DES, MO) \
|
||||
atomic_exchange((OBJ), (DES))
|
||||
#define atomic_compare_exchange_strong(OBJ, EXP, DES) \
|
||||
({ \
|
||||
__typeof__(OBJ) obj = (OBJ); \
|
||||
__typeof__(EXP) exp = (EXP); \
|
||||
__typeof__(*obj) expval = *exp; \
|
||||
__typeof__(*obj) oldval = __sync_val_compare_and_swap( \
|
||||
obj, expval, (DES)); \
|
||||
*exp = oldval; \
|
||||
oldval == expval; \
|
||||
})
|
||||
#define atomic_compare_exchange_strong_explicit(OBJ, EXP, DES, MO) \
|
||||
atomic_compare_exchange_strong((OBJ), (EXP), (DES))
|
||||
#define atomic_compare_exchange_weak(OBJ, EXP, DES) \
|
||||
atomic_compare_exchange_strong((OBJ), (EXP), (DES))
|
||||
#define atomic_compare_exchange_weak_explicit(OBJ, EXP, DES, MO) \
|
||||
atomic_compare_exchange_weak((OBJ), (EXP), (DES))
|
||||
#define atomic_fetch_add(OBJ, VAL) \
|
||||
__sync_fetch_and_add((OBJ), (VAL))
|
||||
#define atomic_fetch_add_explicit(OBJ, VAL, MO) \
|
||||
atomic_fetch_add((OBJ), (VAL))
|
||||
#define atomic_fetch_sub(OBJ, VAL) \
|
||||
__sync_fetch_and_sub((OBJ), (VAL))
|
||||
#define atomic_fetch_sub_explicit(OBJ, VAL, MO) \
|
||||
atomic_fetch_sub((OBJ), (VAL))
|
||||
#define atomic_fetch_or(OBJ, VAL) \
|
||||
__sync_fetch_and_or((OBJ), (VAL))
|
||||
#define atomic_fetch_or_explicit(OBJ, VAL, MO) \
|
||||
atomic_fetch_or((OBJ), (VAL))
|
||||
#define atomic_fetch_xor(OBJ, VAL) \
|
||||
__sync_fetch_and_xor((OBJ), (VAL))
|
||||
#define atomic_fetch_xor_explicit(OBJ, VAL, MO) \
|
||||
atomic_fetch_xor((OBJ), (VAL))
|
||||
#define atomic_fetch_and(OBJ, VAL) \
|
||||
__sync_fetch_and_and((OBJ), (VAL))
|
||||
#define atomic_fetch_and_explicit(OBJ, VAL, MO) \
|
||||
atomic_fetch_and((OBJ), (VAL))
|
||||
#define atomic_thread_fence(MO) \
|
||||
__sync_synchronize()
|
||||
#define atomic_signal_fence(MO) \
|
||||
__sync_synchronize()
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_GCC_ATOMIC__H__ */
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file gcc/compiler.h
|
||||
* @brief GCC specific primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_GCC_COMPILER__H__
|
||||
#define __METAL_GCC_COMPILER__H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define restrict __restrict__
|
||||
#define metal_align(n) __attribute__((aligned(n)))
|
||||
#define metal_weak __attribute__((weak))
|
||||
|
||||
#if defined(__STRICT_ANSI__)
|
||||
#define metal_asm __asm__
|
||||
#else
|
||||
/*
|
||||
* Even though __asm__ is always available in mainline GCC, we use asm in
|
||||
* the non-strict modes for compatibility with other compilers that define
|
||||
* __GNUC__
|
||||
*/
|
||||
#define metal_asm asm
|
||||
#endif
|
||||
|
||||
#define METAL_PACKED_BEGIN
|
||||
#define METAL_PACKED_END __attribute__((__packed__))
|
||||
|
||||
#ifndef __deprecated
|
||||
#define __deprecated __attribute__((deprecated))
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_GCC_COMPILER__H__ */
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2018, ST Microelectronics. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file iar/compiler.h
|
||||
* @brief IAR specific primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_IAR_COMPILER__H__
|
||||
#define __METAL_IAR_COMPILER__H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define restrict __restrict__
|
||||
#define metal_align(n) __attribute__((aligned(n)))
|
||||
#define metal_weak __attribute__((weak))
|
||||
#define metal_asm asm
|
||||
|
||||
#define METAL_PACKED_BEGIN __packed
|
||||
#define METAL_PACKED_END
|
||||
|
||||
#ifndef __deprecated
|
||||
#define __deprecated __attribute__((deprecated))
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_IAR_COMPILER__H__ */
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
/*-
|
||||
* Copyright (c) 2020 STMicroelectronics. All rights reserved.
|
||||
*
|
||||
* Copyright (c) 1982, 1986, 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
* (c) UNIX System Laboratories, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef __METAL_IAR_ERRNO__H__
|
||||
#define __METAL_IAR_ERRNO__H__
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define LIBMETAL_ERR_BASE 100
|
||||
|
||||
#define EPERM (LIBMETAL_ERR_BASE + 1) /* Operation not permitted */
|
||||
#define ENOENT (LIBMETAL_ERR_BASE + 2) /* No such file or directory */
|
||||
#define ESRCH (LIBMETAL_ERR_BASE + 3) /* No such process */
|
||||
#define EINTR (LIBMETAL_ERR_BASE + 4) /* Interrupted system call */
|
||||
#define EIO (LIBMETAL_ERR_BASE + 5) /* Input/output error */
|
||||
#define ENXIO (LIBMETAL_ERR_BASE + 6) /* Device not configured */
|
||||
#define E2BIG (LIBMETAL_ERR_BASE + 7) /* Argument list too long */
|
||||
#define ENOEXEC (LIBMETAL_ERR_BASE + 8) /* Exec format error */
|
||||
#define EBADF (LIBMETAL_ERR_BASE + 9) /* Bad file descriptor */
|
||||
#define ECHILD (LIBMETAL_ERR_BASE + 10) /* No child processes */
|
||||
#define EDEADLK (LIBMETAL_ERR_BASE + 11) /* Resource deadlock avoided */
|
||||
#define ENOMEM (LIBMETAL_ERR_BASE + 12) /* Cannot allocate memory */
|
||||
#define EACCES (LIBMETAL_ERR_BASE + 13) /* Permission denied */
|
||||
#define EFAULT (LIBMETAL_ERR_BASE + 14) /* Bad address */
|
||||
#define ENOTBLK (LIBMETAL_ERR_BASE + 15) /* Block device required */
|
||||
#define EBUSY (LIBMETAL_ERR_BASE + 16) /* Device busy */
|
||||
#define EEXIST (LIBMETAL_ERR_BASE + 17) /* File exists */
|
||||
#define EXDEV (LIBMETAL_ERR_BASE + 18) /* Cross-device link */
|
||||
#define ENODEV (LIBMETAL_ERR_BASE + 19) /* Operation not supported by device */
|
||||
#define ENOTDIR (LIBMETAL_ERR_BASE + 20) /* Not a directory */
|
||||
#define EISDIR (LIBMETAL_ERR_BASE + 21) /* Is a directory */
|
||||
#define EINVAL (LIBMETAL_ERR_BASE + 22) /* Invalid argument */
|
||||
#define ENFILE (LIBMETAL_ERR_BASE + 23) /* Too many open files in system */
|
||||
#define EMFILE (LIBMETAL_ERR_BASE + 24) /* Too many open files */
|
||||
#define ENOTTY (LIBMETAL_ERR_BASE + 25) /* Inappropriate ioctl for device */
|
||||
#define ETXTBSY (LIBMETAL_ERR_BASE + 26) /* Text file busy */
|
||||
#define EFBIG (LIBMETAL_ERR_BASE + 27) /* File too large */
|
||||
#define ENOSPC (LIBMETAL_ERR_BASE + 28) /* No space left on device */
|
||||
#define ESPIPE (LIBMETAL_ERR_BASE + 29) /* Illegal seek */
|
||||
#define EROFS (LIBMETAL_ERR_BASE + 30) /* Read-only filesystem */
|
||||
#define EMLINK (LIBMETAL_ERR_BASE + 31) /* Too many links */
|
||||
#define EPIPE (LIBMETAL_ERR_BASE + 32) /* Broken pipe */
|
||||
#define EAGAIN (LIBMETAL_ERR_BASE + 35) /* Resource temporarily unavailable */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_IAR_ERRNO__H__ */
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2022 Xilinx, Inc. and Contributors. All rights reserved.
|
||||
* Copyright (c) 2022-2023 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file condition.h
|
||||
* @brief Condition variable for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_CONDITION__H__
|
||||
#define __METAL_CONDITION__H__
|
||||
|
||||
#include <metal/mutex.h>
|
||||
#include <metal/utilities.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup condition Condition Variable Interfaces
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Opaque libmetal condition variable data structure. */
|
||||
struct metal_condition;
|
||||
|
||||
/**
|
||||
* @brief Initialize a libmetal condition variable.
|
||||
* @param[in] cv condition variable to initialize.
|
||||
*/
|
||||
static inline void metal_condition_init(struct metal_condition *cv);
|
||||
|
||||
/**
|
||||
* @brief Notify one waiter.
|
||||
* Before calling this function, the caller
|
||||
* should have acquired the mutex.
|
||||
* @param[in] cv condition variable
|
||||
* @return zero on no errors, non-zero on errors
|
||||
* @see metal_condition_wait, metal_condition_broadcast
|
||||
*/
|
||||
static inline int metal_condition_signal(struct metal_condition *cv);
|
||||
|
||||
/**
|
||||
* @brief Notify all waiters.
|
||||
* Before calling this function, the caller
|
||||
* should have acquired the mutex.
|
||||
* @param[in] cv condition variable
|
||||
* @return zero on no errors, non-zero on errors
|
||||
* @see metal_condition_wait, metal_condition_signal
|
||||
*/
|
||||
static inline int metal_condition_broadcast(struct metal_condition *cv);
|
||||
|
||||
/**
|
||||
* @brief Block until the condition variable is notified.
|
||||
* Before calling this function, the caller should
|
||||
* have acquired the mutex.
|
||||
* @param[in] cv condition variable
|
||||
* @param[in] m mutex
|
||||
* @return 0 on success, non-zero on failure.
|
||||
* @see metal_condition_signal
|
||||
*/
|
||||
int metal_condition_wait(struct metal_condition *cv, metal_mutex_t *m);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <metal/system/generic/condition.h>
|
||||
|
||||
#endif /* __METAL_CONDITION__H__ */
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file config.h
|
||||
* @brief Generated configuration settings for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_CONFIG__H__
|
||||
#define __METAL_CONFIG__H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Library major version number. */
|
||||
#define METAL_VER_MAJOR 1
|
||||
|
||||
/** Library minor version number. */
|
||||
#define METAL_VER_MINOR 5
|
||||
|
||||
/** Library patch level. */
|
||||
#define METAL_VER_PATCH 0
|
||||
|
||||
/** Library version string. */
|
||||
#define METAL_VER "1.5.0"
|
||||
|
||||
/** System type (linux, generic, ...). */
|
||||
#define METAL_SYSTEM "generic"
|
||||
#define METAL_SYSTEM_GENERIC
|
||||
|
||||
/** Processor type (arm, x86_64, ...). */
|
||||
#define METAL_PROCESSOR "arm"
|
||||
#define METAL_PROCESSOR_ARM
|
||||
|
||||
/** Machine type (zynq, zynqmp, ...). */
|
||||
#define METAL_MACHINE "zynqmp_a53"
|
||||
#define METAL_MACHINE_ZYNQMP_A53
|
||||
|
||||
#define HAVE_STDATOMIC_H
|
||||
/* #undef HAVE_FUTEX_H */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_CONFIG__H__ */
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file cpu.h
|
||||
* @brief CPU primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_CPU__H__
|
||||
#define __METAL_CPU__H__
|
||||
|
||||
# include <metal/processor/arm/cpu.h>
|
||||
|
||||
#endif /* __METAL_CPU__H__ */
|
||||
+177
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file device.h
|
||||
* @brief Bus abstraction for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_BUS__H__
|
||||
#define __METAL_BUS__H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <metal/io.h>
|
||||
#include <metal/list.h>
|
||||
#include <metal/dma.h>
|
||||
#include <metal/sys.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup device Bus Abstraction
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef METAL_MAX_DEVICE_REGIONS
|
||||
#define METAL_MAX_DEVICE_REGIONS 32
|
||||
#endif
|
||||
|
||||
struct metal_bus;
|
||||
struct metal_device;
|
||||
|
||||
/** Bus operations. */
|
||||
struct metal_bus_ops {
|
||||
void (*bus_close)(struct metal_bus *bus);
|
||||
int (*dev_open)(struct metal_bus *bus,
|
||||
const char *dev_name,
|
||||
struct metal_device **device);
|
||||
void (*dev_close)(struct metal_bus *bus,
|
||||
struct metal_device *device);
|
||||
void (*dev_irq_ack)(struct metal_bus *bus,
|
||||
struct metal_device *device,
|
||||
int irq);
|
||||
int (*dev_dma_map)(struct metal_bus *bus,
|
||||
struct metal_device *device,
|
||||
uint32_t dir,
|
||||
struct metal_sg *sg_in,
|
||||
int nents_in,
|
||||
struct metal_sg *sg_out);
|
||||
void (*dev_dma_unmap)(struct metal_bus *bus,
|
||||
struct metal_device *device,
|
||||
uint32_t dir,
|
||||
struct metal_sg *sg,
|
||||
int nents);
|
||||
};
|
||||
|
||||
/** Libmetal bus structure. */
|
||||
struct metal_bus {
|
||||
const char *name;
|
||||
struct metal_bus_ops ops;
|
||||
struct metal_list devices;
|
||||
struct metal_list node;
|
||||
};
|
||||
|
||||
/** Libmetal generic bus. */
|
||||
extern struct metal_bus metal_generic_bus;
|
||||
|
||||
/** Libmetal device structure. */
|
||||
struct metal_device {
|
||||
const char *name; /**< Device name */
|
||||
struct metal_bus *bus; /**< Bus that contains device */
|
||||
unsigned int num_regions; /**< Number of I/O regions in
|
||||
device */
|
||||
struct metal_io_region regions[METAL_MAX_DEVICE_REGIONS]; /**< Array of
|
||||
I/O regions in device*/
|
||||
struct metal_list node; /**< Node on bus' list of devices */
|
||||
int irq_num; /**< Number of IRQs per device */
|
||||
void *irq_info; /**< IRQ ID */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Register a libmetal bus.
|
||||
* @param[in] bus Pre-initialized bus structure.
|
||||
* @return 0 on success, or -errno on failure.
|
||||
*/
|
||||
extern int metal_bus_register(struct metal_bus *bus);
|
||||
|
||||
/**
|
||||
* @brief Unregister a libmetal bus.
|
||||
* @param[in] bus Pre-registered bus structure.
|
||||
* @return 0 on success, or -errno on failure.
|
||||
*/
|
||||
extern int metal_bus_unregister(struct metal_bus *bus);
|
||||
|
||||
/**
|
||||
* @brief Find a libmetal bus by name.
|
||||
* @param[in] name Bus name.
|
||||
* @param[out] bus Returned bus handle.
|
||||
* @return 0 on success, or -errno on failure.
|
||||
*/
|
||||
extern int metal_bus_find(const char *name, struct metal_bus **bus);
|
||||
|
||||
/**
|
||||
* @brief Statically register a generic libmetal device.
|
||||
*
|
||||
* In non-Linux systems, devices are always required to be statically
|
||||
* registered at application initialization.
|
||||
* In Linux system, devices can be dynamically opened via sysfs or libfdt based
|
||||
* enumeration at runtime.
|
||||
* This interface is used for static registration of devices. Subsequent calls
|
||||
* to metal_device_open() look up in this list of pre-registered devices on the
|
||||
* "generic" bus.
|
||||
* "generic" bus is used on non-Linux system to group the memory mapped devices.
|
||||
*
|
||||
* @param[in] device Generic device.
|
||||
* @return 0 on success, or -errno on failure.
|
||||
*/
|
||||
extern int metal_register_generic_device(struct metal_device *device);
|
||||
|
||||
/**
|
||||
* @brief Open a libmetal device by name.
|
||||
* @param[in] bus_name Bus name.
|
||||
* @param[in] dev_name Device name.
|
||||
* @param[out] device Returned device handle.
|
||||
* @return 0 on success, or -errno on failure.
|
||||
*/
|
||||
extern int metal_device_open(const char *bus_name, const char *dev_name,
|
||||
struct metal_device **device);
|
||||
|
||||
/**
|
||||
* @brief Close a libmetal device.
|
||||
* @param[in] device Device handle.
|
||||
*/
|
||||
extern void metal_device_close(struct metal_device *device);
|
||||
|
||||
/**
|
||||
* @brief Get an I/O region accessor for a device region.
|
||||
*
|
||||
* @param[in] device Device handle.
|
||||
* @param[in] index Region index.
|
||||
* @return I/O accessor handle, or NULL on failure.
|
||||
*/
|
||||
static inline struct metal_io_region *
|
||||
metal_device_io_region(struct metal_device *device, unsigned int index)
|
||||
{
|
||||
return (index < device->num_regions
|
||||
? &device->regions[index]
|
||||
: NULL);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef METAL_INTERNAL
|
||||
extern int metal_generic_dev_sys_open(struct metal_device *dev);
|
||||
extern int metal_generic_dev_open(struct metal_bus *bus, const char *dev_name,
|
||||
struct metal_device **device);
|
||||
extern int metal_generic_dev_dma_map(struct metal_bus *bus,
|
||||
struct metal_device *device,
|
||||
uint32_t dir,
|
||||
struct metal_sg *sg_in,
|
||||
int nents_in,
|
||||
struct metal_sg *sg_out);
|
||||
extern void metal_generic_dev_dma_unmap(struct metal_bus *bus,
|
||||
struct metal_device *device,
|
||||
uint32_t dir,
|
||||
struct metal_sg *sg,
|
||||
int nents);
|
||||
#endif /* METAL_INTERNAL */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_BUS__H__ */
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2022 Xilinx, Inc. and Contributors. All rights reserved.
|
||||
* Copyright (c) 2022-2023 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file dma.h
|
||||
* @brief DMA primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_DMA__H__
|
||||
#define __METAL_DMA__H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <metal/sys.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup dma DMA Interfaces
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define METAL_DMA_DEV_R 1 /**< DMA direction, device read */
|
||||
#define METAL_DMA_DEV_W 2 /**< DMA direction, device write */
|
||||
#define METAL_DMA_DEV_WR 3 /**< DMA direction, device read/write */
|
||||
|
||||
/**
|
||||
* @brief scatter/gather list element structure
|
||||
*/
|
||||
struct metal_sg {
|
||||
void *virt; /**< CPU virtual address */
|
||||
struct metal_io_region *io; /**< IO region */
|
||||
int len; /**< length */
|
||||
};
|
||||
|
||||
struct metal_device;
|
||||
|
||||
/**
|
||||
* @brief Map memory for DMA transaction.
|
||||
* After the memory is DMA mapped, the memory should be
|
||||
* accessed by the DMA device but not the CPU.
|
||||
*
|
||||
* @param[in] dev DMA device
|
||||
* @param[in] dir DMA direction
|
||||
* @param[in] sg_in sg list of memory to map
|
||||
* @param[in] nents_in number of sg list entries of memory to map
|
||||
* @param[out] sg_out sg list of mapped memory
|
||||
* @return number of mapped sg entries, -error on failure.
|
||||
*/
|
||||
int metal_dma_map(struct metal_device *dev,
|
||||
uint32_t dir,
|
||||
struct metal_sg *sg_in,
|
||||
int nents_in,
|
||||
struct metal_sg *sg_out);
|
||||
|
||||
/**
|
||||
* @brief Unmap DMA memory
|
||||
* After the memory is DMA unmapped, the memory should
|
||||
* be accessed by the CPU but not the DMA device.
|
||||
*
|
||||
* @param[in] dev DMA device
|
||||
* @param[in] dir DMA direction
|
||||
* @param[in] sg sg list of mapped DMA memory
|
||||
* @param[in] nents number of sg list entries of DMA memory
|
||||
*/
|
||||
void metal_dma_unmap(struct metal_device *dev,
|
||||
uint32_t dir,
|
||||
struct metal_sg *sg,
|
||||
int nents);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_DMA__H__ */
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2020 STMicroelectronnics. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file metal/errno.h
|
||||
* @brief error specific primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_ERRNO__H__
|
||||
#define __METAL_ERRNO__H__
|
||||
|
||||
#if defined(__ICCARM__)
|
||||
# include <metal/compiler/iar/errno.h>
|
||||
#elif defined(__CC_ARM)
|
||||
# include <metal/compiler/armcc/errno.h>
|
||||
#else
|
||||
# include <errno.h>
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_ERRNO__H__ */
|
||||
+375
@@ -0,0 +1,375 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2022 Xilinx, Inc. and Contributors. All rights reserved.
|
||||
* Copyright (c) 2022-2023 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file io.h
|
||||
* @brief I/O access primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_IO__H__
|
||||
#define __METAL_IO__H__
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <metal/assert.h>
|
||||
#include <metal/compiler.h>
|
||||
#include <metal/atomic.h>
|
||||
#include <metal/sys.h>
|
||||
#include <metal/cpu.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup io IO Interfaces
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef __MICROBLAZE__
|
||||
#define NO_ATOMIC_64_SUPPORT
|
||||
#endif
|
||||
|
||||
struct metal_io_region;
|
||||
|
||||
/** Generic I/O operations. */
|
||||
struct metal_io_ops {
|
||||
uint64_t (*read)(struct metal_io_region *io,
|
||||
unsigned long offset,
|
||||
memory_order order,
|
||||
int width);
|
||||
void (*write)(struct metal_io_region *io,
|
||||
unsigned long offset,
|
||||
uint64_t value,
|
||||
memory_order order,
|
||||
int width);
|
||||
int (*block_read)(struct metal_io_region *io,
|
||||
unsigned long offset,
|
||||
void *restrict dst,
|
||||
memory_order order,
|
||||
int len);
|
||||
int (*block_write)(struct metal_io_region *io,
|
||||
unsigned long offset,
|
||||
const void *restrict src,
|
||||
memory_order order,
|
||||
int len);
|
||||
void (*block_set)(struct metal_io_region *io,
|
||||
unsigned long offset,
|
||||
unsigned char value,
|
||||
memory_order order,
|
||||
int len);
|
||||
void (*close)(struct metal_io_region *io);
|
||||
metal_phys_addr_t (*offset_to_phys)(struct metal_io_region *io,
|
||||
unsigned long offset);
|
||||
unsigned long (*phys_to_offset)(struct metal_io_region *io,
|
||||
metal_phys_addr_t phys);
|
||||
};
|
||||
|
||||
/** Libmetal I/O region structure. */
|
||||
struct metal_io_region {
|
||||
void *virt; /**< base virtual address */
|
||||
const metal_phys_addr_t *physmap; /**< table of base physical address
|
||||
of each of the pages in the I/O
|
||||
region */
|
||||
size_t size; /**< size of the I/O region */
|
||||
unsigned long page_shift; /**< page shift of I/O region */
|
||||
metal_phys_addr_t page_mask; /**< page mask of I/O region */
|
||||
unsigned int mem_flags; /**< memory attribute of the
|
||||
I/O region */
|
||||
struct metal_io_ops ops; /**< I/O region operations */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Open a libmetal I/O region.
|
||||
*
|
||||
* @param[in, out] io I/O region handle.
|
||||
* @param[in] virt Virtual address of region.
|
||||
* @param[in] physmap Array of physical addresses per page.
|
||||
* @param[in] size Size of region.
|
||||
* @param[in] page_shift Log2 of page size (-1 for single page).
|
||||
* @param[in] mem_flags Memory flags
|
||||
* @param[in] ops ops
|
||||
*/
|
||||
void
|
||||
metal_io_init(struct metal_io_region *io, void *virt,
|
||||
const metal_phys_addr_t *physmap, size_t size,
|
||||
unsigned int page_shift, unsigned int mem_flags,
|
||||
const struct metal_io_ops *ops);
|
||||
|
||||
/**
|
||||
* @brief Close a libmetal shared memory segment.
|
||||
* @param[in] io I/O region handle.
|
||||
*/
|
||||
static inline void metal_io_finish(struct metal_io_region *io)
|
||||
{
|
||||
if (io->ops.close)
|
||||
(*io->ops.close)(io);
|
||||
memset(io, 0, sizeof(*io));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get size of I/O region.
|
||||
*
|
||||
* @param[in] io I/O region handle.
|
||||
* @return Size of I/O region.
|
||||
*/
|
||||
static inline size_t metal_io_region_size(struct metal_io_region *io)
|
||||
{
|
||||
return io->size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get virtual address for a given offset into the I/O region.
|
||||
* @param[in] io I/O region handle.
|
||||
* @param[in] offset Offset into shared memory segment.
|
||||
* @return NULL if offset is out of range, or pointer to offset.
|
||||
*/
|
||||
static inline void *
|
||||
metal_io_virt(struct metal_io_region *io, unsigned long offset)
|
||||
{
|
||||
return (io->virt != METAL_BAD_VA && offset < io->size
|
||||
? (void *)((uintptr_t)io->virt + offset)
|
||||
: NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert a virtual address to offset within I/O region.
|
||||
* @param[in] io I/O region handle.
|
||||
* @param[in] virt Virtual address within segment.
|
||||
* @return METAL_BAD_OFFSET if out of range, or offset.
|
||||
*/
|
||||
static inline unsigned long
|
||||
metal_io_virt_to_offset(struct metal_io_region *io, void *virt)
|
||||
{
|
||||
size_t offset = (uintptr_t)virt - (uintptr_t)io->virt;
|
||||
|
||||
return (offset < io->size ? offset : METAL_BAD_OFFSET);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get physical address for a given offset into the I/O region.
|
||||
* @param[in] io I/O region handle.
|
||||
* @param[in] offset Offset into shared memory segment.
|
||||
* @return METAL_BAD_PHYS if offset is out of range, or physical address
|
||||
* of offset.
|
||||
*/
|
||||
static inline metal_phys_addr_t
|
||||
metal_io_phys(struct metal_io_region *io, unsigned long offset)
|
||||
{
|
||||
if (!io->ops.offset_to_phys) {
|
||||
unsigned long page = (io->page_shift >=
|
||||
sizeof(offset) * CHAR_BIT ?
|
||||
0 : offset >> io->page_shift);
|
||||
return (io->physmap && offset < io->size
|
||||
? io->physmap[page] + (offset & io->page_mask)
|
||||
: METAL_BAD_PHYS);
|
||||
}
|
||||
|
||||
return io->ops.offset_to_phys(io, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert a physical address to offset within I/O region.
|
||||
* @param[in] io I/O region handle.
|
||||
* @param[in] phys Physical address within segment.
|
||||
* @return METAL_BAD_OFFSET if out of range, or offset.
|
||||
*/
|
||||
static inline unsigned long
|
||||
metal_io_phys_to_offset(struct metal_io_region *io, metal_phys_addr_t phys)
|
||||
{
|
||||
if (!io->ops.phys_to_offset) {
|
||||
unsigned long offset =
|
||||
(io->page_mask == (metal_phys_addr_t)(-1) ?
|
||||
phys - io->physmap[0] : phys & io->page_mask);
|
||||
do {
|
||||
if (metal_io_phys(io, offset) == phys)
|
||||
return offset;
|
||||
offset += io->page_mask + 1;
|
||||
} while (offset < io->size);
|
||||
return METAL_BAD_OFFSET;
|
||||
}
|
||||
|
||||
return (*io->ops.phys_to_offset)(io, phys);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert a physical address to virtual address.
|
||||
* @param[in] io Shared memory segment handle.
|
||||
* @param[in] phys Physical address within segment.
|
||||
* @return NULL if out of range, or corresponding virtual address.
|
||||
*/
|
||||
static inline void *
|
||||
metal_io_phys_to_virt(struct metal_io_region *io, metal_phys_addr_t phys)
|
||||
{
|
||||
return metal_io_virt(io, metal_io_phys_to_offset(io, phys));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert a virtual address to physical address.
|
||||
* @param[in] io Shared memory segment handle.
|
||||
* @param[in] virt Virtual address within segment.
|
||||
* @return METAL_BAD_PHYS if out of range, or corresponding
|
||||
* physical address.
|
||||
*/
|
||||
static inline metal_phys_addr_t
|
||||
metal_io_virt_to_phys(struct metal_io_region *io, void *virt)
|
||||
{
|
||||
return metal_io_phys(io, metal_io_virt_to_offset(io, virt));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read a value from an I/O region.
|
||||
* @param[in] io I/O region handle.
|
||||
* @param[in] offset Offset into I/O region.
|
||||
* @param[in] order Memory ordering.
|
||||
* @param[in] width Width in bytes of datatype to read. This must be 1, 2,
|
||||
* 4, or 8, and a compile time constant for this function
|
||||
* to inline cleanly.
|
||||
* @return Value.
|
||||
*/
|
||||
static inline uint64_t
|
||||
metal_io_read(struct metal_io_region *io, unsigned long offset,
|
||||
memory_order order, int width)
|
||||
{
|
||||
void *ptr = metal_io_virt(io, offset);
|
||||
|
||||
if (io->ops.read)
|
||||
return (*io->ops.read)(io, offset, order, width);
|
||||
else if (ptr && sizeof(atomic_uchar) == width)
|
||||
return atomic_load_explicit((atomic_uchar *)ptr, order);
|
||||
else if (ptr && sizeof(atomic_ushort) == width)
|
||||
return atomic_load_explicit((atomic_ushort *)ptr, order);
|
||||
else if (ptr && sizeof(atomic_uint) == width)
|
||||
return atomic_load_explicit((atomic_uint *)ptr, order);
|
||||
else if (ptr && sizeof(atomic_ulong) == width)
|
||||
return atomic_load_explicit((atomic_ulong *)ptr, order);
|
||||
#ifndef NO_ATOMIC_64_SUPPORT
|
||||
else if (ptr && sizeof(atomic_ullong) == width)
|
||||
return atomic_load_explicit((atomic_ullong *)ptr, order);
|
||||
#endif
|
||||
metal_assert(0);
|
||||
return 0; /* quiet compiler */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write a value into an I/O region.
|
||||
* @param[in] io I/O region handle.
|
||||
* @param[in] offset Offset into I/O region.
|
||||
* @param[in] value Value to write.
|
||||
* @param[in] order Memory ordering.
|
||||
* @param[in] width Width in bytes of datatype to read. This must be 1, 2,
|
||||
* 4, or 8, and a compile time constant for this function
|
||||
* to inline cleanly.
|
||||
*/
|
||||
static inline void
|
||||
metal_io_write(struct metal_io_region *io, unsigned long offset,
|
||||
uint64_t value, memory_order order, int width)
|
||||
{
|
||||
void *ptr = metal_io_virt(io, offset);
|
||||
|
||||
if (io->ops.write)
|
||||
(*io->ops.write)(io, offset, value, order, width);
|
||||
else if (ptr && sizeof(atomic_uchar) == width)
|
||||
atomic_store_explicit((atomic_uchar *)ptr, (unsigned char)value,
|
||||
order);
|
||||
else if (ptr && sizeof(atomic_ushort) == width)
|
||||
atomic_store_explicit((atomic_ushort *)ptr,
|
||||
(unsigned short)value, order);
|
||||
else if (ptr && sizeof(atomic_uint) == width)
|
||||
atomic_store_explicit((atomic_uint *)ptr, (unsigned int)value,
|
||||
order);
|
||||
else if (ptr && sizeof(atomic_ulong) == width)
|
||||
atomic_store_explicit((atomic_ulong *)ptr, (unsigned long)value,
|
||||
order);
|
||||
#ifndef NO_ATOMIC_64_SUPPORT
|
||||
else if (ptr && sizeof(atomic_ullong) == width)
|
||||
atomic_store_explicit((atomic_ullong *)ptr,
|
||||
(unsigned long long)value, order);
|
||||
#endif
|
||||
else
|
||||
metal_assert(0);
|
||||
}
|
||||
|
||||
#define metal_io_read8_explicit(_io, _ofs, _order) \
|
||||
metal_io_read((_io), (_ofs), (_order), 1)
|
||||
#define metal_io_read8(_io, _ofs) \
|
||||
metal_io_read((_io), (_ofs), memory_order_seq_cst, 1)
|
||||
#define metal_io_write8_explicit(_io, _ofs, _val, _order) \
|
||||
metal_io_write((_io), (_ofs), (_val), (_order), 1)
|
||||
#define metal_io_write8(_io, _ofs, _val) \
|
||||
metal_io_write((_io), (_ofs), (_val), memory_order_seq_cst, 1)
|
||||
|
||||
#define metal_io_read16_explicit(_io, _ofs, _order) \
|
||||
metal_io_read((_io), (_ofs), (_order), 2)
|
||||
#define metal_io_read16(_io, _ofs) \
|
||||
metal_io_read((_io), (_ofs), memory_order_seq_cst, 2)
|
||||
#define metal_io_write16_explicit(_io, _ofs, _val, _order) \
|
||||
metal_io_write((_io), (_ofs), (_val), (_order), 2)
|
||||
#define metal_io_write16(_io, _ofs, _val) \
|
||||
metal_io_write((_io), (_ofs), (_val), memory_order_seq_cst, 2)
|
||||
|
||||
#define metal_io_read32_explicit(_io, _ofs, _order) \
|
||||
metal_io_read((_io), (_ofs), (_order), 4)
|
||||
#define metal_io_read32(_io, _ofs) \
|
||||
metal_io_read((_io), (_ofs), memory_order_seq_cst, 4)
|
||||
#define metal_io_write32_explicit(_io, _ofs, _val, _order) \
|
||||
metal_io_write((_io), (_ofs), (_val), (_order), 4)
|
||||
#define metal_io_write32(_io, _ofs, _val) \
|
||||
metal_io_write((_io), (_ofs), (_val), memory_order_seq_cst, 4)
|
||||
|
||||
#define metal_io_read64_explicit(_io, _ofs, _order) \
|
||||
metal_io_read((_io), (_ofs), (_order), 8)
|
||||
#define metal_io_read64(_io, _ofs) \
|
||||
metal_io_read((_io), (_ofs), memory_order_seq_cst, 8)
|
||||
#define metal_io_write64_explicit(_io, _ofs, _val, _order) \
|
||||
metal_io_write((_io), (_ofs), (_val), (_order), 8)
|
||||
#define metal_io_write64(_io, _ofs, _val) \
|
||||
metal_io_write((_io), (_ofs), (_val), memory_order_seq_cst, 8)
|
||||
|
||||
/**
|
||||
* @brief Read a block from an I/O region.
|
||||
* @param[in] io I/O region handle.
|
||||
* @param[in] offset Offset into I/O region.
|
||||
* @param[in] dst destination to store the read data.
|
||||
* @param[in] len length in bytes to read.
|
||||
* @return On success, number of bytes read. On failure, negative value
|
||||
*/
|
||||
int metal_io_block_read(struct metal_io_region *io, unsigned long offset,
|
||||
void *restrict dst, int len);
|
||||
|
||||
/**
|
||||
* @brief Write a block into an I/O region.
|
||||
* @param[in] io I/O region handle.
|
||||
* @param[in] offset Offset into I/O region.
|
||||
* @param[in] src source to write.
|
||||
* @param[in] len length in bytes to write.
|
||||
* @return On success, number of bytes written. On failure, negative value
|
||||
*/
|
||||
int metal_io_block_write(struct metal_io_region *io, unsigned long offset,
|
||||
const void *restrict src, int len);
|
||||
|
||||
/**
|
||||
* @brief fill a block of an I/O region.
|
||||
* @param[in] io I/O region handle.
|
||||
* @param[in] offset Offset into I/O region.
|
||||
* @param[in] value value to fill into the block
|
||||
* @param[in] len length in bytes to fill.
|
||||
* @return On success, number of bytes filled. On failure, negative value
|
||||
*/
|
||||
int metal_io_block_set(struct metal_io_region *io, unsigned long offset,
|
||||
unsigned char value, int len);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <metal/system/generic/io.h>
|
||||
|
||||
#endif /* __METAL_IO__H__ */
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2022 Xilinx, Inc. and Contributors. All rights reserved.
|
||||
* Copyright (c) 2022-2023 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file irq.h
|
||||
* @brief Interrupt handling primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_IRQ__H__
|
||||
#define __METAL_IRQ__H__
|
||||
|
||||
#include <metal/list.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup irq Interrupt Handling Interfaces
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** IRQ handled status */
|
||||
#define METAL_IRQ_NOT_HANDLED 0
|
||||
#define METAL_IRQ_HANDLED 1
|
||||
|
||||
/**
|
||||
* @brief type of interrupt handler
|
||||
* @param[in] irq interrupt id
|
||||
* @param[in] arg argument to pass to the handler
|
||||
* @return irq handled status
|
||||
*/
|
||||
typedef int (*metal_irq_handler) (int irq, void *arg);
|
||||
|
||||
/**
|
||||
* @brief Register interrupt handler for interrupt.
|
||||
* Only allow single interrupt handler for a interrupt.
|
||||
*
|
||||
* If irq_handler is NULL, it will unregister interrupt
|
||||
* handler from interrupt
|
||||
*
|
||||
* @param[in] irq interrupt id
|
||||
* @param[in] irq_handler interrupt handler
|
||||
* @param[in] arg arg is the argument pointing to the data which
|
||||
* will be passed to the interrupt handler.
|
||||
* @return 0 for success, non-zero on failure
|
||||
*/
|
||||
int metal_irq_register(int irq,
|
||||
metal_irq_handler irq_handler,
|
||||
void *arg);
|
||||
|
||||
/**
|
||||
* @brief Unregister interrupt handler for interrupt.
|
||||
*
|
||||
* @param[in] irq interrupt id
|
||||
*/
|
||||
static inline
|
||||
void metal_irq_unregister(int irq)
|
||||
{
|
||||
metal_irq_register(irq, 0, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief disable interrupts
|
||||
* @return interrupts state
|
||||
*/
|
||||
unsigned int metal_irq_save_disable(void);
|
||||
|
||||
/**
|
||||
* @brief restore interrupts to their previous state
|
||||
* @param[in] flags previous interrupts state
|
||||
*/
|
||||
void metal_irq_restore_enable(unsigned int flags);
|
||||
|
||||
/**
|
||||
* @brief metal_irq_enable
|
||||
*
|
||||
* Enables the given interrupt
|
||||
*
|
||||
* @param vector - interrupt vector number
|
||||
*/
|
||||
void metal_irq_enable(unsigned int vector);
|
||||
|
||||
/**
|
||||
* @brief metal_irq_disable
|
||||
*
|
||||
* Disables the given interrupt
|
||||
*
|
||||
* @param vector - interrupt vector number
|
||||
*/
|
||||
void metal_irq_disable(unsigned int vector);
|
||||
|
||||
#include <metal/system/generic/irq.h>
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_IRQ__H__ */
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2022 Xilinx, Inc. and Contributors. All rights reserved.
|
||||
* Copyright (c) 2022-2023 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file irq.h
|
||||
* @brief Interrupt handling primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_IRQ_CONTROLLER__H__
|
||||
#define __METAL_IRQ_CONTROLLER__H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup irq Interrupt Handling Interfaces
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <metal/irq.h>
|
||||
#include <metal/list.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/** IRQ ANY ID */
|
||||
#define METAL_IRQ_ANY (-1)
|
||||
|
||||
/** IRQ state macro which will be passed to metal irq set state function
|
||||
* to indicate which state the caller want the IRQ to change to.
|
||||
*/
|
||||
#define METAL_IRQ_DISABLE 0U
|
||||
#define METAL_IRQ_ENABLE 1U
|
||||
|
||||
struct metal_irq_controller;
|
||||
|
||||
/**
|
||||
* @brief type of interrupt controller to set irq enable
|
||||
* @param[in] irq_cntr pointer to interrupt controller
|
||||
* @param[in] irq interrupt id
|
||||
* @param[in] enable IRQ state
|
||||
*/
|
||||
typedef void (*metal_irq_set_enable) (struct metal_irq_controller *irq_cntr,
|
||||
int irq, unsigned int enable);
|
||||
|
||||
/**
|
||||
* @brief type of controller specific registering interrupt function
|
||||
* @param[in] irq_cntr pointer to interrupt controller
|
||||
* @param[in] irq interrupt id
|
||||
* @param[in] hd interrupt handler
|
||||
* @param[in] arg argument which will be passed to the interrupt handler
|
||||
* @return 0 for success, negative value for failure
|
||||
*/
|
||||
typedef int (*metal_cntr_irq_register) (struct metal_irq_controller *irq_cntr,
|
||||
int irq, metal_irq_handler hd,
|
||||
void *arg);
|
||||
|
||||
/** Libmetal interrupt structure */
|
||||
struct metal_irq {
|
||||
metal_irq_handler hd; /**< Interrupt handler */
|
||||
void *arg; /**< Argument to pass to the interrupt handler */
|
||||
};
|
||||
|
||||
/** Libmetal interrupt controller structure */
|
||||
struct metal_irq_controller {
|
||||
int irq_base; /**< Start of IRQ number of the range managed by
|
||||
* the IRQ controller
|
||||
*/
|
||||
int irq_num; /**< Number of IRQs managed by the IRQ controller */
|
||||
void *arg; /**< Argument to pass to interrupt controller function */
|
||||
metal_irq_set_enable irq_set_enable; /**< function to set IRQ enable */
|
||||
metal_cntr_irq_register irq_register; /**< function to register IRQ
|
||||
* handler
|
||||
*/
|
||||
struct metal_list node; /**< list node */
|
||||
struct metal_irq *irqs; /**< Array of IRQs managed by the controller */
|
||||
};
|
||||
|
||||
#define METAL_IRQ_CONTROLLER_DECLARE(_irq_controller, \
|
||||
_irq_base, _irq_num, \
|
||||
_arg, \
|
||||
_irq_set_enable, \
|
||||
_irq_register, \
|
||||
_irqs) \
|
||||
struct metal_irq_controller _irq_controller = { \
|
||||
.irq_base = _irq_base, \
|
||||
.irq_num = _irq_num, \
|
||||
.arg = _arg, \
|
||||
.irq_set_enable = _irq_set_enable, \
|
||||
.irq_register = _irq_register, \
|
||||
.irqs = _irqs,\
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief metal_irq_register_controller
|
||||
*
|
||||
* Register IRQ controller
|
||||
* This function will allocate IRQ ids if it was
|
||||
* not predefined in the irq controller. There is no
|
||||
* locking in the function, it is not supposed to be
|
||||
* called by multiple threads.
|
||||
*
|
||||
* @param[in] cntr Interrupt controller to register
|
||||
* @return 0 on success, or negative value for failure.
|
||||
*/
|
||||
int metal_irq_register_controller(struct metal_irq_controller *cntr);
|
||||
|
||||
/**
|
||||
* @brief metal_irq_handle
|
||||
*
|
||||
* Call registered IRQ handler
|
||||
*
|
||||
* @param[in] irq_data metal IRQ structure
|
||||
* @param[in] irq IRQ id which will be passed to handler
|
||||
* @return IRQ handler status
|
||||
*/
|
||||
static inline
|
||||
int metal_irq_handle(struct metal_irq *irq_data, int irq)
|
||||
{
|
||||
if (irq_data && irq_data->hd) {
|
||||
return irq_data->hd(irq, irq_data->arg);
|
||||
} else {
|
||||
return METAL_IRQ_NOT_HANDLED;
|
||||
}
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_IRQ__H__ */
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2022 Xilinx, Inc. and Contributors. All rights reserved.
|
||||
* Copyright (c) 2022-2023 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file list.h
|
||||
* @brief List primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_LIST__H__
|
||||
#define __METAL_LIST__H__
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup list List Primitives
|
||||
* @{
|
||||
*/
|
||||
|
||||
struct metal_list {
|
||||
struct metal_list *next, *prev;
|
||||
};
|
||||
|
||||
/*
|
||||
* METAL_INIT_LIST - used for initializing an list element in a static struct
|
||||
* or global
|
||||
*/
|
||||
#define METAL_INIT_LIST(name) { .next = &name, .prev = &name }
|
||||
/*
|
||||
* METAL_DECLARE_LIST - used for defining and initializing a global or
|
||||
* static singleton list
|
||||
*/
|
||||
#define METAL_DECLARE_LIST(name) \
|
||||
struct metal_list name = METAL_INIT_LIST(name)
|
||||
|
||||
static inline void metal_list_init(struct metal_list *list)
|
||||
{
|
||||
list->prev = list;
|
||||
list->next = list;
|
||||
}
|
||||
|
||||
static inline void metal_list_add_before(struct metal_list *node,
|
||||
struct metal_list *new_node)
|
||||
{
|
||||
new_node->prev = node->prev;
|
||||
new_node->next = node;
|
||||
new_node->next->prev = new_node;
|
||||
new_node->prev->next = new_node;
|
||||
}
|
||||
|
||||
static inline void metal_list_add_after(struct metal_list *node,
|
||||
struct metal_list *new_node)
|
||||
{
|
||||
new_node->prev = node;
|
||||
new_node->next = node->next;
|
||||
new_node->next->prev = new_node;
|
||||
new_node->prev->next = new_node;
|
||||
}
|
||||
|
||||
static inline void metal_list_add_head(struct metal_list *list,
|
||||
struct metal_list *node)
|
||||
{
|
||||
metal_list_add_after(list, node);
|
||||
}
|
||||
|
||||
static inline void metal_list_add_tail(struct metal_list *list,
|
||||
struct metal_list *node)
|
||||
{
|
||||
metal_list_add_before(list, node);
|
||||
}
|
||||
|
||||
static inline int metal_list_is_empty(struct metal_list *list)
|
||||
{
|
||||
return list->next == list;
|
||||
}
|
||||
|
||||
static inline void metal_list_del(struct metal_list *node)
|
||||
{
|
||||
node->next->prev = node->prev;
|
||||
node->prev->next = node->next;
|
||||
node->prev = node;
|
||||
node->next = node;
|
||||
}
|
||||
|
||||
static inline struct metal_list *metal_list_first(struct metal_list *list)
|
||||
{
|
||||
return metal_list_is_empty(list) ? NULL : list->next;
|
||||
}
|
||||
|
||||
#define metal_list_for_each(list, node) \
|
||||
for ((node) = (list)->next; \
|
||||
(node) != (list); \
|
||||
(node) = (node)->next)
|
||||
|
||||
static inline bool metal_list_find_node(struct metal_list *list,
|
||||
struct metal_list *node)
|
||||
{
|
||||
struct metal_list *n;
|
||||
|
||||
metal_list_for_each(list, n) {
|
||||
if (n == node)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_LIST__H__ */
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2022 Xilinx, Inc. and Contributors. All rights reserved.
|
||||
* Copyright (c) 2022-2023 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file log.h
|
||||
* @brief Logging support for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_METAL_LOG__H__
|
||||
#define __METAL_METAL_LOG__H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup logging Library Logging Interfaces
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Log message priority levels for libmetal. */
|
||||
enum metal_log_level {
|
||||
METAL_LOG_EMERGENCY, /**< system is unusable. */
|
||||
METAL_LOG_ALERT, /**< action must be taken immediately. */
|
||||
METAL_LOG_CRITICAL, /**< critical conditions. */
|
||||
METAL_LOG_ERROR, /**< error conditions. */
|
||||
METAL_LOG_WARNING, /**< warning conditions. */
|
||||
METAL_LOG_NOTICE, /**< normal but significant condition. */
|
||||
METAL_LOG_INFO, /**< informational messages. */
|
||||
METAL_LOG_DEBUG, /**< debug-level messages. */
|
||||
};
|
||||
|
||||
/** Log message handler type. */
|
||||
typedef void (*metal_log_handler)(enum metal_log_level level,
|
||||
const char *format, ...);
|
||||
|
||||
/**
|
||||
* @brief Set libmetal log handler.
|
||||
* @param[in] handler log message handler.
|
||||
* @return 0 on success, or -errno on failure.
|
||||
*/
|
||||
extern void metal_set_log_handler(metal_log_handler handler);
|
||||
|
||||
/**
|
||||
* @brief Get the current libmetal log handler.
|
||||
* @return Current log handler.
|
||||
*/
|
||||
extern metal_log_handler metal_get_log_handler(void);
|
||||
|
||||
/**
|
||||
* @brief Set the level for libmetal logging.
|
||||
* @param[in] level log message level.
|
||||
*/
|
||||
extern void metal_set_log_level(enum metal_log_level level);
|
||||
|
||||
/**
|
||||
* @brief Get the current level for libmetal logging.
|
||||
* @return Current log level.
|
||||
*/
|
||||
extern enum metal_log_level metal_get_log_level(void);
|
||||
|
||||
/**
|
||||
* @brief Default libmetal log handler. This handler prints libmetal log
|
||||
* messages to stderr.
|
||||
* @param[in] level log message level.
|
||||
* @param[in] format log message format string.
|
||||
* @return 0 on success, or -errno on failure.
|
||||
*/
|
||||
extern void metal_default_log_handler(enum metal_log_level level,
|
||||
const char *format, ...);
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief used by the metal_log() macro to update the format string
|
||||
*
|
||||
* If ML_FUNC_LINE is defined this macro generates a unified format
|
||||
* string for metal_log() and its convenience metal_*() macros, i.e. it
|
||||
* adds function-name:line-number prefix to all log messages.
|
||||
*
|
||||
* @param[in] fmt format string passed from the metal_log() macro
|
||||
*/
|
||||
#if defined(ML_FUNC_LINE)
|
||||
#define metal_fmt(fmt) "%s:%u " fmt, __func__, __LINE__
|
||||
#else /* ML_FUNC_LINE */
|
||||
#define metal_fmt(fmt) fmt
|
||||
#endif /* ML_FUNC_LINE */
|
||||
|
||||
/**
|
||||
* @brief Emit a log message if the log level permits.
|
||||
*
|
||||
* @param level Log level.
|
||||
* @param fmt Format string.
|
||||
* @param args... Variable number of arguments.
|
||||
*/
|
||||
#define metal_log(level, fmt, args...) ({ \
|
||||
if (_metal.common.log_handler && level <= _metal.common.log_level) \
|
||||
_metal.common.log_handler(level, metal_fmt(fmt), ##args); \
|
||||
})
|
||||
|
||||
#define metal_err(fmt, args...) metal_log(METAL_LOG_ERROR, fmt, ##args)
|
||||
#define metal_warn(fmt, args...) metal_log(METAL_LOG_WARNING, fmt, ##args)
|
||||
#define metal_info(fmt, args...) metal_log(METAL_LOG_INFO, fmt, ##args)
|
||||
#define metal_dbg(fmt, args...) metal_log(METAL_LOG_DEBUG, fmt, ##args)
|
||||
|
||||
/**
|
||||
* Convenience macros ML_ERR, ML_INFO, ML_DBG add source
|
||||
* function name and the line number before the message.
|
||||
* Inspired by pr_err, pr_info, etc. in the kernel's printk.h.
|
||||
* Keep the original ML_ERR, ML_INFO, ML_DBG until the open-amp
|
||||
* code is converted to use the new metal_*() macros.
|
||||
*/
|
||||
#define ML_ERR(fmt, args...) metal_err(fmt, ##args)
|
||||
#define ML_INFO(fmt, args...) metal_info(fmt, ##args)
|
||||
#define ML_DBG(fmt, args...) metal_dbg(fmt, ##args)
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <metal/system/generic/log.h>
|
||||
|
||||
#endif /* __METAL_METAL_LOG__H__ */
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2022 Xilinx, Inc. and Contributors. All rights reserved.
|
||||
* Copyright (c) 2022-2023 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file mutex.h
|
||||
* @brief Mutex primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_MUTEX__H__
|
||||
#define __METAL_MUTEX__H__
|
||||
|
||||
#include <metal/system/generic/mutex.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup mutex Mutex Interfaces
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initialize a libmetal mutex.
|
||||
* @param[in] mutex Mutex to initialize.
|
||||
*/
|
||||
static inline void metal_mutex_init(metal_mutex_t *mutex)
|
||||
{
|
||||
__metal_mutex_init(mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deinitialize a libmetal mutex.
|
||||
* @param[in] mutex Mutex to deinitialize.
|
||||
*/
|
||||
static inline void metal_mutex_deinit(metal_mutex_t *mutex)
|
||||
{
|
||||
__metal_mutex_deinit(mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Try to acquire a mutex
|
||||
* @param[in] mutex Mutex to mutex.
|
||||
* @return 0 on failure to acquire, non-zero on success.
|
||||
*/
|
||||
static inline int metal_mutex_try_acquire(metal_mutex_t *mutex)
|
||||
{
|
||||
return __metal_mutex_try_acquire(mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Acquire a mutex
|
||||
* @param[in] mutex Mutex to mutex.
|
||||
*/
|
||||
static inline void metal_mutex_acquire(metal_mutex_t *mutex)
|
||||
{
|
||||
__metal_mutex_acquire(mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Release a previously acquired mutex.
|
||||
* @param[in] mutex Mutex to mutex.
|
||||
* @see metal_mutex_try_acquire, metal_mutex_acquire
|
||||
*/
|
||||
static inline void metal_mutex_release(metal_mutex_t *mutex)
|
||||
{
|
||||
__metal_mutex_release(mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checked if a mutex has been acquired.
|
||||
* @param[in] mutex mutex to check.
|
||||
* @see metal_mutex_try_acquire, metal_mutex_acquire
|
||||
*/
|
||||
static inline int metal_mutex_is_acquired(metal_mutex_t *mutex)
|
||||
{
|
||||
return __metal_mutex_is_acquired(mutex);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_MUTEX__H__ */
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file arm/atomic.h
|
||||
* @brief Arm specific atomic primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_ARM_ATOMIC__H__
|
||||
#define __METAL_ARM_ATOMIC__H__
|
||||
|
||||
#endif /* __METAL_ARM_ATOMIC__H__ */
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2022 Xilinx, Inc. and Contributors. All rights reserved.
|
||||
* Copyright (c) 2022-2023 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file cpu.h
|
||||
* @brief CPU specific primitives
|
||||
*/
|
||||
|
||||
#ifndef __METAL_ARM_CPU__H__
|
||||
#define __METAL_ARM_CPU__H__
|
||||
|
||||
#define metal_cpu_yield()
|
||||
|
||||
#endif /* __METAL_ARM_CPU__H__ */
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file shmem.h
|
||||
* @brief Shared memory primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_SHMEM__H__
|
||||
#define __METAL_SHMEM__H__
|
||||
|
||||
#include <metal/io.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup shmem Shared Memory Interfaces
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Generic shared memory data structure. */
|
||||
struct metal_generic_shmem {
|
||||
const char *name;
|
||||
struct metal_io_region io;
|
||||
struct metal_list node;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Open a libmetal shared memory segment.
|
||||
*
|
||||
* Open a shared memory segment.
|
||||
*
|
||||
* @param[in] name Name of segment to open.
|
||||
* @param[in] size Size of segment.
|
||||
* @param[out] io I/O region handle, if successful.
|
||||
* @return 0 on success, or -errno on failure.
|
||||
*
|
||||
* @see metal_shmem_create
|
||||
*/
|
||||
extern int metal_shmem_open(const char *name, size_t size,
|
||||
struct metal_io_region **io);
|
||||
|
||||
/**
|
||||
* @brief Statically register a generic shared memory region.
|
||||
*
|
||||
* Shared memory regions may be statically registered at application
|
||||
* initialization, or may be dynamically opened. This interface is used for
|
||||
* static registration of regions. Subsequent calls to metal_shmem_open() look
|
||||
* up in this list of pre-registered regions.
|
||||
*
|
||||
* @param[in] shmem Generic shmem structure.
|
||||
* @return 0 on success, or -errno on failure.
|
||||
*/
|
||||
extern int metal_shmem_register_generic(struct metal_generic_shmem *shmem);
|
||||
|
||||
#ifdef METAL_INTERNAL
|
||||
|
||||
/**
|
||||
* @brief Open a statically registered shmem segment.
|
||||
*
|
||||
* This interface is meant for internal libmetal use within system specific
|
||||
* shmem implementations.
|
||||
*
|
||||
* @param[in] name Name of segment to open.
|
||||
* @param[in] size Size of segment.
|
||||
* @param[out] io I/O region handle, if successful.
|
||||
* @return 0 on success, or -errno on failure.
|
||||
*/
|
||||
int metal_shmem_open_generic(const char *name, size_t size,
|
||||
struct metal_io_region **result);
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_SHMEM__H__ */
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file sleep.h
|
||||
* @brief Sleep primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_SLEEP__H__
|
||||
#define __METAL_SLEEP__H__
|
||||
|
||||
#include <metal/system/generic/sleep.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup sleep Sleep Interfaces
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief delay in microseconds
|
||||
* delay the next execution in the calling thread
|
||||
* fo usec microseconds.
|
||||
*
|
||||
* @param[in] usec microsecond intervals
|
||||
* @return 0 on success, non-zero for failures
|
||||
*/
|
||||
static inline int metal_sleep_usec(unsigned int usec)
|
||||
{
|
||||
return __metal_sleep_usec(usec);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_SLEEP__H__ */
|
||||
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2022 Xilinx, Inc. and Contributors. All rights reserved.
|
||||
* Copyright (c) 2022-2023 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file softirq.h
|
||||
* @brief Soft Interrupt handling primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_SOFTIRQ__H__
|
||||
#define __METAL_SOFTIRQ__H__
|
||||
|
||||
#include <metal/irq.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup soft irq Interrupt Handling Interfaces
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief metal_softirq_init
|
||||
*
|
||||
* Initialize libmetal soft IRQs controller
|
||||
*
|
||||
* @return 0 on success, or negative value for failure
|
||||
*/
|
||||
int metal_softirq_init(void);
|
||||
|
||||
/**
|
||||
* @brief metal_softirq_dispatch
|
||||
*
|
||||
* Dispatch the pending soft IRQs
|
||||
*/
|
||||
void metal_softirq_dispatch(void);
|
||||
|
||||
/**
|
||||
* @brief metal_softirq_allocate
|
||||
*
|
||||
* Allocate soft IRQs
|
||||
*
|
||||
* This function doesn't have any locking, it is not supposed
|
||||
* to be called by multiple threads.
|
||||
*
|
||||
* @param[in] num number of soft irqs requested
|
||||
* @return soft irq base for success, or negative value for failure
|
||||
*/
|
||||
int metal_softirq_allocate(int num);
|
||||
|
||||
/**
|
||||
* @brief metal_softirq_set
|
||||
*
|
||||
* Set soft IRQ to pending
|
||||
*
|
||||
* @param[in] irq soft IRQ ID to set
|
||||
*/
|
||||
void metal_softirq_set(int irq);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_SOFTIRQ__H__ */
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file spinlock.h
|
||||
* @brief Spinlock primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_SPINLOCK__H__
|
||||
#define __METAL_SPINLOCK__H__
|
||||
|
||||
#include <metal/atomic.h>
|
||||
#include <metal/cpu.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup spinlock Spinlock Interfaces
|
||||
* @{
|
||||
*/
|
||||
|
||||
struct metal_spinlock {
|
||||
atomic_flag v;
|
||||
};
|
||||
|
||||
/** Static metal spinlock initialization. */
|
||||
#define METAL_SPINLOCK_INIT {ATOMIC_FLAG_INIT}
|
||||
|
||||
/**
|
||||
* @brief Initialize a libmetal spinlock.
|
||||
* @param[in] slock Spinlock to initialize.
|
||||
*/
|
||||
static inline void metal_spinlock_init(struct metal_spinlock *slock)
|
||||
{
|
||||
atomic_flag_clear(&slock->v);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Acquire a spinlock.
|
||||
* @param[in] slock Spinlock to acquire.
|
||||
* @see metal_spinlock_release
|
||||
*/
|
||||
static inline void metal_spinlock_acquire(struct metal_spinlock *slock)
|
||||
{
|
||||
while (atomic_flag_test_and_set(&slock->v)) {
|
||||
metal_cpu_yield();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Release a previously acquired spinlock.
|
||||
* @param[in] slock Spinlock to release.
|
||||
* @see metal_spinlock_acquire
|
||||
*/
|
||||
static inline void metal_spinlock_release(struct metal_spinlock *slock)
|
||||
{
|
||||
atomic_flag_clear(&slock->v);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_SPINLOCK__H__ */
|
||||
+152
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file sys.h
|
||||
* @brief System primitives for libmetal.
|
||||
* @brief Top level include internal to libmetal library code.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_SYS__H__
|
||||
#define __METAL_SYS__H__
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <metal/log.h>
|
||||
#include <metal/list.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup system Top Level Interfaces
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Physical address type. */
|
||||
typedef unsigned long metal_phys_addr_t;
|
||||
|
||||
/** Interrupt request number. */
|
||||
typedef int metal_irq_t;
|
||||
|
||||
/** Bad offset into shared memory or I/O region. */
|
||||
#define METAL_BAD_OFFSET ((unsigned long)-1)
|
||||
|
||||
/** Bad physical address value. */
|
||||
#define METAL_BAD_PHYS ((metal_phys_addr_t)-1)
|
||||
|
||||
/** Bad virtual address value. */
|
||||
#define METAL_BAD_VA ((void *)-1)
|
||||
|
||||
/** Bad IRQ. */
|
||||
#define METAL_BAD_IRQ ((metal_irq_t)-1)
|
||||
|
||||
/**
|
||||
* Initialization configuration for libmetal.
|
||||
*/
|
||||
struct metal_init_params {
|
||||
|
||||
/** log message handler (defaults to stderr). */
|
||||
metal_log_handler log_handler;
|
||||
|
||||
/** default log message level (defaults to emergency). */
|
||||
enum metal_log_level log_level;
|
||||
};
|
||||
|
||||
/**
|
||||
* System independent runtime state for libmetal. This is part of a system
|
||||
* specific singleton data structure (@see _metal).
|
||||
*/
|
||||
struct metal_common_state {
|
||||
/** reference count to track metal_init/metal_finish. */
|
||||
int ref_count;
|
||||
|
||||
/** Current log level. */
|
||||
enum metal_log_level log_level;
|
||||
|
||||
/** Current log handler (null for none). */
|
||||
metal_log_handler log_handler;
|
||||
|
||||
/** List of registered buses. */
|
||||
struct metal_list bus_list;
|
||||
|
||||
/** Generic statically defined shared memory segments. */
|
||||
struct metal_list generic_shmem_list;
|
||||
|
||||
/** Generic statically defined devices. */
|
||||
struct metal_list generic_device_list;
|
||||
};
|
||||
|
||||
struct metal_state;
|
||||
|
||||
#include <metal/system/generic/sys.h>
|
||||
|
||||
#ifndef METAL_INIT_DEFAULTS
|
||||
#define METAL_INIT_DEFAULTS \
|
||||
{ \
|
||||
.log_handler = metal_default_log_handler, \
|
||||
.log_level = METAL_LOG_INFO, \
|
||||
}
|
||||
#endif
|
||||
|
||||
/** System specific runtime data. */
|
||||
extern struct metal_state _metal;
|
||||
|
||||
/**
|
||||
* @brief Initialize libmetal.
|
||||
*
|
||||
* Initialize the libmetal library.
|
||||
*
|
||||
* @param[in] params Initialization params (@see metal_init_params).
|
||||
*
|
||||
* @return 0 on success, or -errno on failure.
|
||||
*
|
||||
* @see metal_finish
|
||||
*/
|
||||
extern int metal_init(const struct metal_init_params *params);
|
||||
|
||||
/**
|
||||
* @brief Shutdown libmetal.
|
||||
*
|
||||
* Shutdown the libmetal library, and release all reserved resources.
|
||||
*
|
||||
* @see metal_init
|
||||
*/
|
||||
extern void metal_finish(void);
|
||||
|
||||
#ifdef METAL_INTERNAL
|
||||
|
||||
/**
|
||||
* @brief libmetal system initialization.
|
||||
*
|
||||
* This function initializes libmetal on Linux or Generic platforms. This
|
||||
* involves obtaining necessary pieces of system information (sysfs mount path,
|
||||
* page size, etc.).
|
||||
*
|
||||
* @param[in] params Initialization parameters (@see metal_init_params).
|
||||
* @return 0 on success, or -errno on failure.
|
||||
*/
|
||||
extern int metal_sys_init(const struct metal_init_params *params);
|
||||
|
||||
/**
|
||||
* @brief libmetal system shutdown.
|
||||
*
|
||||
* This function shuts down and releases resources held by libmetal Linux or
|
||||
* Generic platform layers.
|
||||
*
|
||||
* @see metal_sys_init
|
||||
*/
|
||||
extern void metal_sys_finish(void);
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_SYS__H__ */
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file generic/alloc.c
|
||||
* @brief generic libmetal memory allocattion definitions.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_ALLOC__H__
|
||||
#error "Include metal/alloc.h instead of metal/generic/alloc.h"
|
||||
#endif
|
||||
|
||||
#ifndef __METAL_GENERIC_ALLOC__H__
|
||||
#define __METAL_GENERIC_ALLOC__H__
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static inline void *__metal_allocate_memory(unsigned int size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
static inline void __metal_free_memory(void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_GENERIC_ALLOC__H__ */
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file assert.h
|
||||
* @brief Generic assertion support.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_ASSERT__H__
|
||||
#error "Include metal/assert.h instead of metal/generic/assert.h"
|
||||
#endif
|
||||
|
||||
#ifndef __METAL_GENERIC_ASSERT__H__
|
||||
#define __METAL_GENERIC_ASSERT__H__
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
/**
|
||||
* @brief Assertion macro for bare-metal applications.
|
||||
* @param cond Condition to evaluate.
|
||||
*/
|
||||
#define metal_sys_assert(cond) assert(cond)
|
||||
|
||||
#endif /* __METAL_GENERIC_ASSERT__H__ */
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Linaro Limited. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file generic/cache.h
|
||||
* @brief generic cache operation primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_CACHE__H__
|
||||
#error "Include metal/cache.h instead of metal/generic/cache.h"
|
||||
#endif
|
||||
|
||||
#ifndef __METAL_GENERIC_CACHE__H__
|
||||
#define __METAL_GENERIC_CACHE__H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void metal_machine_cache_flush(void *addr, unsigned int len);
|
||||
extern void metal_machine_cache_invalidate(void *addr, unsigned int len);
|
||||
|
||||
static inline void __metal_cache_flush(void *addr, unsigned int len)
|
||||
{
|
||||
metal_machine_cache_flush(addr, len);
|
||||
}
|
||||
|
||||
static inline void __metal_cache_invalidate(void *addr, unsigned int len)
|
||||
{
|
||||
metal_machine_cache_invalidate(addr, len);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_GENERIC_CACHE__H__ */
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file generic/condition.h
|
||||
* @brief Generic condition variable primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_CONDITION__H__
|
||||
#error "Include metal/condition.h instead of metal/generic/condition.h"
|
||||
#endif
|
||||
|
||||
#ifndef __METAL_GENERIC_CONDITION__H__
|
||||
#define __METAL_GENERIC_CONDITION__H__
|
||||
|
||||
#include <metal/atomic.h>
|
||||
#include <stdint.h>
|
||||
#include <limits.h>
|
||||
#include <metal/errno.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct metal_condition {
|
||||
atomic_uintptr_t mptr; /**< mutex pointer.
|
||||
* The condition variable is attached to
|
||||
* this mutex when it is waiting.
|
||||
* It is also used to check correctness
|
||||
* in case there are multiple waiters.
|
||||
*/
|
||||
|
||||
atomic_int v; /**< condition variable value. */
|
||||
};
|
||||
|
||||
/** Static metal condition variable initialization. */
|
||||
#define METAL_CONDITION_INIT { ATOMIC_VAR_INIT(0), ATOMIC_VAR_INIT(0) }
|
||||
|
||||
static inline void metal_condition_init(struct metal_condition *cv)
|
||||
{
|
||||
atomic_init(&cv->mptr, 0);
|
||||
atomic_init(&cv->v, 0);
|
||||
}
|
||||
|
||||
static inline int metal_condition_signal(struct metal_condition *cv)
|
||||
{
|
||||
if (!cv)
|
||||
return -EINVAL;
|
||||
|
||||
/** wake up waiters if there are any. */
|
||||
atomic_fetch_add(&cv->v, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int metal_condition_broadcast(struct metal_condition *cv)
|
||||
{
|
||||
return metal_condition_signal(cv);
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_GENERIC_CONDITION__H__ */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user