add dj_47dr_lmx vitis project

refer to readme for details
This commit is contained in:
2024-07-04 20:32:14 +08:00
parent 8f5171133e
commit 81467ace82
4795 changed files with 1617712 additions and 0 deletions
@@ -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.1087926654">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="xilinx.gnu.arm.a53.exe.debug.1087926654" 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.1087926654" name="Debug" parent="xilinx.gnu.arm.a53.exe.debug">
<folderInfo id="xilinx.gnu.arm.a53.exe.debug.1087926654." name="/" resourcePath="">
<toolChain id="xilinx.gnu.arm.a53.exe.debug.toolchain.1679071922" 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.1784884120" 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.15341786" 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.685551161" name="ARM v8 gcc assembler" superClass="xilinx.gnu.arm.a53.c.toolchain.assembler.debug">
<inputType id="xilinx.gnu.assembler.input.282608500" superClass="xilinx.gnu.assembler.input"/>
</tool>
<tool id="xilinx.gnu.arm.a53.c.toolchain.compiler.debug.236198026" 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.774964005" name="Optimization Level" superClass="xilinx.gnu.compiler.option.optimization.level" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.option.debugging.level.804909331" 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.409716720" 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.1144532034" 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.1953457552" name="C source files" superClass="xilinx.gnu.arm.a53.c.compiler.input"/>
</tool>
<tool id="xilinx.gnu.arm.a53.cxx.toolchain.compiler.debug.424911718" 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.617747108" name="Optimization Level" superClass="xilinx.gnu.compiler.option.optimization.level" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.option.debugging.level.97685479" 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.1723716761" 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.1397501986" 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.1674855016" name="ARM v8 archiver" superClass="xilinx.gnu.arm.a53.toolchain.archiver"/>
<tool id="xilinx.gnu.arm.a53.c.toolchain.linker.debug.344414566" name="ARM v8 gcc linker" superClass="xilinx.gnu.arm.a53.c.toolchain.linker.debug">
<option id="xilinx.gnu.linker.inferred.swplatform.lpath.1450803969" 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.107391861" 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.2084836593" name="Linker Script" superClass="xilinx.gnu.c.linker.option.lscript" value="../src/lscript.ld" valueType="string"/>
<inputType id="xilinx.gnu.linker.input.1571982657" superClass="xilinx.gnu.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
<inputType id="xilinx.gnu.linker.input.lscript.1472821553" name="Linker Script" superClass="xilinx.gnu.linker.input.lscript"/>
</tool>
<tool id="xilinx.gnu.arm.a53.cxx.toolchain.linker.debug.1804225163" name="ARM v8 g++ linker" superClass="xilinx.gnu.arm.a53.cxx.toolchain.linker.debug">
<option id="xilinx.gnu.linker.inferred.swplatform.lpath.884678074" 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.729977912" 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.2116096968" 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.349885347" 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.424068119">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="xilinx.gnu.arm.a53.exe.release.424068119" 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.424068119" name="Release" parent="xilinx.gnu.arm.a53.exe.release">
<folderInfo id="xilinx.gnu.arm.a53.exe.release.424068119." name="/" resourcePath="">
<toolChain id="xilinx.gnu.arm.a53.exe.release.toolchain.560744959" 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.2091191829" 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.1828331243" 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.1279131821" name="ARM v8 gcc assembler" superClass="xilinx.gnu.arm.a53.c.toolchain.assembler.release">
<inputType id="xilinx.gnu.assembler.input.2141065934" superClass="xilinx.gnu.assembler.input"/>
</tool>
<tool id="xilinx.gnu.arm.a53.c.toolchain.compiler.release.717765690" 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.184902333" name="Optimization Level" superClass="xilinx.gnu.compiler.option.optimization.level" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.option.debugging.level.1170168946" 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.1339654708" 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.1927589466" 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.1164731440" name="C source files" superClass="xilinx.gnu.arm.a53.c.compiler.input"/>
</tool>
<tool id="xilinx.gnu.arm.a53.cxx.toolchain.compiler.release.1888204362" 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.1597006854" name="Optimization Level" superClass="xilinx.gnu.compiler.option.optimization.level" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.option.debugging.level.1395916011" 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.1171051639" 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.1202484770" 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.1254128175" name="ARM v8 archiver" superClass="xilinx.gnu.arm.a53.toolchain.archiver"/>
<tool id="xilinx.gnu.arm.a53.c.toolchain.linker.release.1658224400" name="ARM v8 gcc linker" superClass="xilinx.gnu.arm.a53.c.toolchain.linker.release">
<option id="xilinx.gnu.linker.inferred.swplatform.lpath.2102060144" 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.1190181320" 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.1097871832" name="Linker Script" superClass="xilinx.gnu.c.linker.option.lscript" value="../src/lscript.ld" valueType="string"/>
<inputType id="xilinx.gnu.linker.input.1103748637" superClass="xilinx.gnu.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
<inputType id="xilinx.gnu.linker.input.lscript.2139522133" name="Linker Script" superClass="xilinx.gnu.linker.input.lscript"/>
</tool>
<tool id="xilinx.gnu.arm.a53.cxx.toolchain.linker.release.636828394" name="ARM v8 g++ linker" superClass="xilinx.gnu.arm.a53.cxx.toolchain.linker.release">
<option id="xilinx.gnu.linker.inferred.swplatform.lpath.1140367069" 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.836638957" 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.1840824798" 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.997910128" 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.1684004503" 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.debug.1087926654;xilinx.gnu.arm.a53.exe.debug.1087926654.;xilinx.gnu.arm.a53.c.toolchain.compiler.debug.236198026;xilinx.gnu.arm.a53.c.compiler.input.1953457552">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.xilinx.managedbuilder.ui.ARMA53GCCManagedMakePerProjectProfileC"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="xilinx.gnu.arm.a53.exe.release.424068119;xilinx.gnu.arm.a53.exe.release.424068119.">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.xilinx.managedbuilder.ui.ARMA53GCCManagedMakePerProjectProfileC"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="xilinx.gnu.arm.a53.exe.release.424068119;xilinx.gnu.arm.a53.exe.release.424068119.;xilinx.gnu.arm.a53.c.toolchain.compiler.release.717765690;xilinx.gnu.arm.a53.c.compiler.input.1164731440">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.xilinx.managedbuilder.ui.ARMA53GCCManagedMakePerProjectProfileC"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="xilinx.gnu.arm.a53.exe.debug.1087926654;xilinx.gnu.arm.a53.exe.debug.1087926654.">
<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>dj_47dr_platform</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>
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6d03716e09c569dced4c3bc9492138d5eed6eafe7102eb15ace592a00ce69bfb
size 34437472
@@ -0,0 +1 @@
1960514743
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,11 @@
<?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/Workspace/vivado/vivado_pub/projects/dj_47dr/dj_47dr_lmx/vitis_classic/dj_47dr_basic" platform="/home/josh/Workspace/vivado/vivado_pub/projects/dj_47dr/dj_47dr_lmx/vitis_classic/dj_47dr_platform/export/dj_47dr_platform/dj_47dr_platform.xpfm" platformUID="xilinx:::0.0(custom)" systemProject="dj_47dr_basic_system" sysConfig="dj_47dr_platform" runtime="cpp" cpu="standalone_psu_cortexa53_0" cpuInstance="psu_cortexa53_0" os="standalone" mssSignature="c6670d350bc5ad3b0c7e7d49c8d56f6d">
<configuration name="Debug" id="xilinx.gnu.arm.a53.exe.debug.1087926654">
<configBuildOptions xsi:type="sdkproject:SdkOptions"/>
<lastBuildOptions xsi:type="sdkproject:SdkOptions"/>
</configuration>
<configuration name="Release" id="xilinx.gnu.arm.a53.exe.release.424068119" dirty="true">
<configBuildOptions xsi:type="sdkproject:SdkOptions"/>
</configuration>
<template appTemplateName="empty_application"/>
</sdkproject:SdkProject>
@@ -0,0 +1,30 @@
# README.md
> Vivado Project Name: dj_47dr_lmx
>
> Vitis Project Name: dj_47dr_basic
>
> Board: RFSOC_47DR_Z7045
>
> Device: xczu47dr-2ffve1156i(u15), lmk04828(u66), lmk2594(u67), lmk2594(u68)
>
> Date: 2024/07/04
>
> Archiver: Josh Gao
1. 注意事项
本工程启用了动态 DDR 配置,依赖于 FSBL 启动,在启动时 FSBL 会使用 I2C 读取 DDR 的 SPD EEPROM 获得 DDR 参数,并初始化 DDR 控制器。
由于原理图与 Xilinx 开发板 I2C Mux Slave 连接不一致,FSBL 已将 I2C Mux 的 Slave 选择改为 `0x04`。若重新建立 PS 工程,注意修改 FSBL,否则可能无法正常启动。
2. 实现的功能
- 配置了 LMK04828,使用 10 MHz 输入时钟和 122.88 MHz VCXO 完成配置,PLL2 锁定,输出时钟频率为 245.76 MHz。
- 配置了两片 LMK2594,RF 部分使用外部采样时钟,采样率为 4.9152 Gbps。
- 初始化了 RF Data Converter,自发自收测试 ch5 发 ch5 收正常,信号功率和 EVM 等未测量。
3. 存在的问题
- LMK04828 PLL1 锁定时间较长(约 1 分钟),单独配置 LMK04828 时同样存在该问题。
- LMK2594 SPI 回读异常,ILA 可以看见回读,但是 PS 程序中无回读,问题待查;通过 LED 灯判断两片 LMK2594 均锁定。
@@ -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;
}
@@ -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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_val);
} while(reg_val == 1);
/* Wait until the current transfer is completed. */
do {
axi_dmac_read(dmac, AXI_DMAC_REG_IRQ_PENDING, &reg_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, &reg_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;
}
@@ -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
@@ -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;
}
@@ -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
@@ -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
@@ -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;
}
@@ -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,129 @@
/***************************************************************************//**
* @file lmx2594.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 "../lmx2594/lmx2594.h"
#include <stdlib.h>
#include <stdio.h>
#include "../../../include/error.h"
/***************************************************************************//**
* @brief lmx2594_read
*******************************************************************************/
int32_t lmx2594_read(struct lmx2594_dev *dev,
uint8_t reg_addr,
uint16_t *reg_data)
{
uint8_t tx_buf[1];
uint8_t rx_buf[2];
int32_t ret;
tx_buf[0] = 0x80 | reg_addr;
ret = spi_write_and_read_3wire(dev->spi_desc,
tx_buf, rx_buf, 1, 2);
*reg_data = rx_buf[1];
*reg_data |= ((uint16_t)rx_buf[0]) << 8;
return ret;
}
/***************************************************************************//**
* @brief lmx2594_write
*******************************************************************************/
int32_t lmx2594_write(struct lmx2594_dev *dev,
uint8_t reg_addr,
uint16_t reg_data)
{
uint8_t buf[3];
int32_t ret;
buf[0] = reg_addr;
buf[1] = reg_data >> 8;
buf[2] = reg_data & 0xFF;
ret = spi_write_and_read_3wire(dev->spi_desc,
buf, NULL, 3, 0);
return ret;
}
/***************************************************************************//**
* @brief lmx2594_init
*******************************************************************************/
int32_t lmx2594_init(struct lmx2594_dev **device,
const struct lmx2594_init_param *init_param)
{
int ret = SUCCESS;
struct lmx2594_dev *dev;
dev = (struct lmx2594_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 lmx2594_setup().
*
* @param dev - The device structure.
*
* @return SUCCESS in case of success, negative error code otherwise.
*******************************************************************************/
int32_t lmx2594_remove(struct lmx2594_dev *dev)
{
int32_t ret;
ret = spi_remove(dev->spi_desc);
free(dev);
return ret;
}
@@ -0,0 +1,89 @@
/***************************************************************************//**
* @file lmx2594.h
* @brief Header file of lmx2594 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 LMX2594_H_
#define LMX2594_H_
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <stdint.h>
#include "../../../include/delay.h"
#include "../../../include/spi.h"
/******************************************************************************/
/********************** Macros and Constants Definitions **********************/
/******************************************************************************/
/******************************************************************************/
/*************************** Types Declarations *******************************/
/******************************************************************************/
struct lmx2594_dev {
/* SPI */
spi_desc *spi_desc;
};
struct lmx2594_init_param {
/* SPI */
spi_init_param *spi_init;
};
struct lmx2594_config {
uint8_t addr;
uint16_t value;
};
/******************************************************************************/
/************************ Functions Declarations ******************************/
/******************************************************************************/
int32_t lmx2594_read(struct lmx2594_dev *dev,
uint8_t reg_addr,
uint16_t *reg_data);
int32_t lmx2594_write(struct lmx2594_dev *dev,
uint8_t reg_addr,
uint16_t reg_data);
int32_t lmx2594_init(struct lmx2594_dev **device,
const struct lmx2594_init_param *init_param);
int32_t lmx2594_remove(struct lmx2594_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
@@ -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
};
@@ -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(&dividend, 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,41 @@
#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"
#include "../adi_noos/drivers/frequency/lmx2594/lmx2594.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;
extern struct lmx2594_init_param lmx2594_adc_init_param;
extern struct lmx2594_init_param lmx2594_dac_init_param;
extern const struct lmx2594_config lmx2594_default_config[];
extern const uint32_t lmx2594_default_config_len;
#endif /* SRC_DEV_PROFILE_H_ */
@@ -0,0 +1,166 @@
#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 = 137;
const struct lmk04828_config lmk04828_default_config[] = {
{0x0000, 0x90}, // [7] reset; [4] 3-wire mode disabled
{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,166 @@
#include "dev_profile.h"
#include "../app_config.h"
#include "../adi_noos/drivers/frequency/lmx2594/lmx2594.h"
static spi_init_param lmx2594_adc_spi_init = {
.device_id = SPI_DEVICE_ID,
.max_speed_hz = SPI_ENGINE_MAX_SPEED,
.mode = SPI_MODE_0,
.chip_select = SPI_CS_LMX2594_ADC,
.platform_ops = SPI_OPS,
.extra = SPI_PARAM
};
static spi_init_param lmx2594_dac_spi_init = {
.device_id = SPI_DEVICE_ID,
.max_speed_hz = SPI_ENGINE_MAX_SPEED,
.mode = SPI_MODE_0,
.chip_select = SPI_CS_LMX2594_DAC,
.platform_ops = SPI_OPS,
.extra = SPI_PARAM
};
struct lmx2594_init_param lmx2594_adc_init_param = {
/* SPI */
.spi_init = &lmx2594_adc_spi_init
};
struct lmx2594_init_param lmx2594_dac_init_param = {
/* SPI */
.spi_init = &lmx2594_dac_spi_init
};
const uint32_t lmx2594_default_config_len = 110;
const struct lmx2594_config lmx2594_default_config[] = {
// 0 ~ 78: General configuration
// 79 ~ 106: Ramping configuration
// 107 ~ 112: Readback registers
// Recommended Initial Power-Up Sequence
// For the most reliable programming, TI recommends this procedure::
// 1. Apply power to device.
// 2. Program RESET = 1 to reset registers.
// 3. Program RESET = 0 to remove reset.
// 4. Program registers as shown in the register map in REVERSE order from highest to lowest.
// 5. Wait 10 ms.
// 6. Program register R0 one additional time with FCAL_EN = 1 to ensure that the VCO calibration runs from a stable state.
// Reset
{ 0, 0x0002},
// Remove Reset
{ 0, 0x0000},
// Reverse order programming
{106, 0x0000},
{105, 0x0021},
{104, 0x0000},
{103, 0xD555},
{102, 0x3F97},
{101, 0x0011},
{100, 0x0000},
{ 99, 0x2AAB},
{ 98, 0x01A0},
{ 97, 0x0888},
{ 96, 0x0000},
{ 95, 0x0000}, // fixed
{ 94, 0x0000}, // fixed
{ 93, 0x0000}, // fixed
{ 92, 0x0000}, // fixed
{ 91, 0x0000}, // fixed
{ 90, 0x0000}, // fixed
{ 89, 0x0000}, // fixed
{ 88, 0x0000}, // fixed
{ 87, 0x0000}, // fixed
{ 86, 0x5879},
{ 85, 0xEC58},
{ 84, 0x0001},
{ 83, 0x54C9},
{ 82, 0x2961},
{ 81, 0x0000},
{ 80, 0x4000},
{ 79, 0x001F},
{ 78, 0x0003}, // [8:1] VCO_CAPCTRL_STRT
{ 77, 0x0000}, // fixed
{ 76, 0x000C}, // fixed
{ 75, 0x0800}, // [10:6] CHDIV
{ 74, 0x0000}, // [11:6] JESD_DAC4_CTRL; [5:0] JESD_DAC3_CTRL
{ 73, 0x003F}, // [11:6] JESD_DAC2_CTRL; [5:0] JESD_DAC1_CTRL
{ 72, 0x0001}, // [10:0] SYSREF_DIV
{ 71, 0x0081}, // [7:5] SYSREF_DIV_PRE; [4] SYSREF_PULSE; [3] SYSREF_EN; [2] SYSREF_REPEAT
{ 70, 0xC350}, // [15:0] MASH_RST_COUNT
{ 69, 0x0000}, // [15:0] MASH_RST_COUNT
{ 68, 0x03E8}, // fixed
{ 67, 0x0000}, // fixed
{ 66, 0x01F4}, // fixed
{ 65, 0x0000}, // fixed
{ 64, 0x1388}, // fixed
{ 63, 0x0000}, // fixed
{ 62, 0x0322}, // fixed
{ 61, 0x00A8}, // fixed
{ 60, 0x0000}, // [15:0] LD_DLY
{ 59, 0x0001}, // [0] LD_TYPE
{ 58, 0x9001}, // [15] INPIN_IGNORE; [14] INPIN_HYST; [13:12] INPIN_LVL; [11:9] INPIN_FMT
{ 57, 0x0020}, // fixed
{ 56, 0x0000}, // fixed
{ 55, 0x0000}, // fixed
{ 54, 0x0000}, // fixed
{ 53, 0x0000}, // fixed
{ 52, 0x0820}, // fixed
{ 51, 0x0080}, // fixed
{ 50, 0x0000}, // fixed
{ 49, 0x4180}, // fixed
{ 48, 0x0300}, // fixed
{ 47, 0x0300}, // fixed
{ 46, 0x07FC}, // [1:0] OUTB_MUX
{ 45, 0xC0DF}, // [12:11] OUTA_MUX; [10:9] OUT_ISET; [5:0] OUTB_PWR
{ 44, 0x1AA3}, // [13:8] OUTA_PWR; [7] OUTB_PD; [6] OUTA_PD; [5] MASH_RESET_N; [2:0] MASH_ORDER
{ 43, 0x0000}, // [15:0] PLL_NUM
{ 42, 0x0000}, // [15:0] PLL_NUM
{ 41, 0x0000}, // [15:0] MASH_SEE
{ 40, 0x0000}, // [15:0] MASH_SEE
{ 39, 0x03E8}, // [15:0] PLL_DEN
{ 38, 0x0000}, // [15:0] PLL_DEN
{ 37, 0x0304}, // [37] MASH_SEED_EN; [13:8] PFD_DLY_SEL
{ 36, 0x0028}, // [15:0] PLL_N
{ 35, 0x0004}, // fixed
{ 34, 0x0000}, // [2:0] PLL_N
{ 33, 0x1E21}, // fixed
{ 32, 0x0393}, // fixed
{ 31, 0x43EC}, // [14] SEG1_EN
{ 30, 0x318C}, // fixed
{ 29, 0x318C}, // fixed
{ 28, 0x0488}, // fixed
{ 27, 0x0002}, // fixed
{ 26, 0x0DB0}, // fixed
{ 25, 0x0C2B}, // fixed
{ 24, 0x071A}, // fixed
{ 23, 0x007C}, // fixed
{ 22, 0x0001}, // fixed
{ 21, 0x0401}, // fixed
{ 20, 0xE048}, // [13:11] VCO_SEL. [10] VCO_SEL_FORCE
{ 19, 0x27B7}, // [7:0] VCO_CAPCTRL
{ 18, 0x0064}, // fixed
{ 17, 0x012C}, // [8:0] VCO_DACISET_STRT
{ 16, 0x0080}, // [8:0] VCO_DACISET
{ 15, 0x064F}, // fixed
{ 14, 0x1E70}, // [6:4] CPG
{ 13, 0x4000}, // fixed
{ 12, 0x5001}, // [11:0] PLL_R_PR
{ 11, 0x0018}, // [11:4] PLL_R
{ 10, 0x10D8}, // [11:7] MULT
{ 9, 0x0604}, // [12] OSC_2X
{ 8, 0x2000}, // [14] VCO_DACISET_FORCE; [11] VCO_CAPCTRL_FORCE
{ 7, 0x40B2}, // [14] OUT_FORCE
{ 6, 0xC802}, // fixed
{ 5, 0x00C8}, // fixed
{ 4, 0x0C43}, // [15:8] ACAL_CMP_DLY
{ 3, 0x0642}, // fixed
{ 2, 0x0500}, // fixed
{ 1, 0x0809}, // [2:0] CAL_CLK_DIV
{ 0, 0x2598}, // [15] RAMP_EN; [14] VCO_PHASE_SYNC; [9] OUT_MUTE; [8:7] FCAL_HPFD_ADJ; [6:5] FCAL_LPFD_ADJ; [3] FCAL_EN; [2] MUXOUT_LD_SEL; [1] RESET; [0] POWERDOWN
// one more time
{ 0, 0x2598}
};
@@ -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,191 @@
/***************************************************************************//**
* @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;
struct lmx2594_dev *lmx2594_adc_inst;
struct lmx2594_dev *lmx2594_dac_inst;
XRFdc RFdc;
XGpioPs Gpio;
/***************************************************************************//**
* @brief main
*******************************************************************************/
int main(void)
{
int32_t Status;
uint8_t Lmk04828Read;
uint16_t Lmx2594Read;
// 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
Status = lmk04828_read(lmk04828_inst, 0x0182, &Lmk04828Read);
if ((Lmk04828Read & 0x02) == 0x02) {
xil_printf("LMK04828 PLL1 Locked.\r\n");
}
else {
xil_printf("LMK04828 PLL1 NOT lock!\r\n");
}
Status = lmk04828_read(lmk04828_inst, 0x0183, &Lmk04828Read);
if ((Lmk04828Read & 0x02) == 0x02) {
xil_printf("LMK04828 PLL2 Locked.\r\n");
}
else {
xil_printf("LMK04828 PLL2 NOT lock!\r\n");
}
/**********************************************************/
/************* LMX2594 for DAC Configuration **************/
/**********************************************************/
Status = lmx2594_init(&lmx2594_dac_inst, &lmx2594_dac_init_param);
for(int i = 0; i < lmx2594_default_config_len; i++)
{
Status = lmx2594_write(lmx2594_dac_inst, lmx2594_default_config[i].addr, lmx2594_default_config[i].value);
if (lmx2594_default_config[i].addr == 0)
{
mdelay(500);
}
}
// check vco lock status
Status = lmx2594_read(lmx2594_dac_inst, 110, &Lmx2594Read);
if (((Lmx2594Read >> 9) & 0x03) == 0x02) {
xil_printf("LMX2594 for DAC Config Done.\r\n");
}
else {
xil_printf("LMX2594 for DAC not lock!\r\n");
}
Status = lmx2594_write(lmx2594_dac_inst, 0x00, 0x259C);
/**********************************************************/
/************* LMX2594 for ADC Configuration **************/
/**********************************************************/
Status = lmx2594_init(&lmx2594_adc_inst, &lmx2594_adc_init_param);
for(int i = 0; i < lmx2594_default_config_len; i++)
{
Status = lmx2594_write(lmx2594_adc_inst, lmx2594_default_config[i].addr, lmx2594_default_config[i].value);
if (lmx2594_default_config[i].addr == 0)
{
mdelay(500);
}
}
Status = lmx2594_read(lmx2594_adc_inst, 0, &Lmx2594Read);
// check vco lock status
Status = lmx2594_read(lmx2594_adc_inst, 110, &Lmx2594Read);
if (((Lmx2594Read >> 9) & 0x03) == 0x02) {
xil_printf("LMX2594 for ADC Config Done.\r\n");
}
else {
xil_printf("LMX2594 for ADC not lock!\r\n");
}
Status = lmx2594_write(lmx2594_adc_inst, 0x00, 0x259C);
print("Done.\n");
return 0;
}
@@ -0,0 +1,78 @@
/***************************************************************************//**
* @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
#define SPI_CS_LMX2594_ADC 0x01
#define SPI_CS_LMX2594_DAC 0x02
#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.1953250129">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.xilinx.sdx.system.managedbuilder.debugConfiguration.1953250129" 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.1953250129" name="Debug" parent="com.xilinx.sdx.system.managedbuilder.debugConfiguration">
<folderInfo id="com.xilinx.sdx.system.managedbuilder.debugConfiguration.1953250129." name="/" resourcePath="">
<toolChain id="com.xilinx.sdx.system.managedbuilder.debug.toolChain.1075629955" name="System Toolchain" superClass="com.xilinx.sdx.system.managedbuilder.debug.toolChain">
<targetPlatform id="com.xilinx.sdx.system.managedbuilder.debugConfiguration.1953250129..806398817" name=""/>
<builder buildPath="${workspace_loc:/dj_47dr_basic_system}/Debug" enableAutoBuild="true" id="com.xilinx.sdx.system.managedbuilder.systemBuilder.1381068159" managedBuildOn="true" name="System Project Builder.Debug" superClass="com.xilinx.sdx.system.managedbuilder.systemBuilder"/>
<tool id="com.xilinx.sdx.system.managedbuilder.toolchain.cfjoinTool.913406354" 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.924124141">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.xilinx.sdx.system.managedbuilder.releaseConfiguration.924124141" 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.924124141" name="Release" parent="com.xilinx.sdx.system.managedbuilder.releaseConfiguration">
<folderInfo id="com.xilinx.sdx.system.managedbuilder.releaseConfiguration.924124141." name="/" resourcePath="">
<toolChain id="com.xilinx.sdx.system.managedbuilder.release.toolChain.1829898184" name="System Toolchain" superClass="com.xilinx.sdx.system.managedbuilder.release.toolChain">
<targetPlatform id="com.xilinx.sdx.system.managedbuilder.releaseConfiguration.924124141..309382124" name=""/>
<builder buildPath="${workspace_loc:/dj_47dr_basic_system}/Release" enableAutoBuild="true" id="com.xilinx.sdx.system.managedbuilder.systemBuilder.1681191785" managedBuildOn="true" name="System Project Builder.Release" superClass="com.xilinx.sdx.system.managedbuilder.systemBuilder"/>
<tool id="com.xilinx.sdx.system.managedbuilder.toolchain.cfjoinTool.1184162170" 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.1305483594" 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>
@@ -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/Workspace/vivado/vivado_pub/projects/dj_47dr/dj_47dr_lmx/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/Workspace/vivado/vivado_pub/projects/dj_47dr/dj_47dr_lmx/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/Workspace/vivado/vivado_pub/projects/dj_47dr/dj_47dr_lmx/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/Workspace/vivado/vivado_pub/projects/dj_47dr/dj_47dr_lmx/vitis_classic/dj_47dr_platform/export/dj_47dr_platform/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/Workspace/vivado/vivado_pub/projects/dj_47dr/dj_47dr_lmx/vitis_classic/dj_47dr_platform/export/dj_47dr_platform/sw/dj_47dr_platform/boot/fsbl.elf
set bp_15_4_fsbl_bp [bpadd -addr &XFsbl_Exit]
con -block -timeout 60
bpremove $bp_15_4_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/Workspace/vivado/vivado_pub/projects/dj_47dr/dj_47dr_lmx/vitis_classic/dj_47dr_basic/Debug/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,19 @@
<?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:sdkproject="http://www.xilinx.com/sdkproject" xmlns:systemproject="http://www.xilinx.com/systemproject" name="dj_47dr_basic_system" platform="/home/josh/Workspace/vivado/vivado_pub/projects/dj_47dr/dj_47dr_lmx/vitis_classic/dj_47dr_platform/export/dj_47dr_platform/dj_47dr_platform.xpfm" platformUID="xilinx:::0.0(custom)" sysConfig="dj_47dr_platform" runtime="cpp" rootFSLocation="" linuxImage="" sysroot="">
<configuration name="Debug" id="com.xilinx.sdx.system.managedbuilder.debugConfiguration.1953250129">
<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="sdkproject:SdkOptions" generateSdCard="true"/>
</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="sdkproject:SdkOptions" generateSdCard="true"/>
</lastBuildOptions>
</configuration>
<configuration name="Release" id="com.xilinx.sdx.system.managedbuilder.releaseConfiguration.924124141">
<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="sdkproject:SdkOptions" generateSdCard="true"/>
</configBuildOptions>
</configuration>
</systemproject:SystemProject>
@@ -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.158563212">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="xilinx.gnu.arm.a53.exe.debug.158563212" 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.158563212" name="Debug" parent="xilinx.gnu.arm.a53.exe.debug">
<folderInfo id="xilinx.gnu.arm.a53.exe.debug.158563212." name="/" resourcePath="">
<toolChain id="xilinx.gnu.arm.a53.exe.debug.toolchain.322285947" 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.628586529" isAbstract="false" name="Debug Platform" superClass="xilinx.arm.a53.target.gnu.base.debug"/>
<builder buildPath="${workspace_loc:/dj_47dr_mts}/Debug" enableAutoBuild="true" id="xilinx.gnu.arm.a53.toolchain.builder.debug.1776652555" 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.2107071673" name="ARM v8 gcc assembler" superClass="xilinx.gnu.arm.a53.c.toolchain.assembler.debug">
<inputType id="xilinx.gnu.assembler.input.647781912" superClass="xilinx.gnu.assembler.input"/>
</tool>
<tool id="xilinx.gnu.arm.a53.c.toolchain.compiler.debug.1155184730" 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.1739911927" name="Optimization Level" superClass="xilinx.gnu.compiler.option.optimization.level" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.option.debugging.level.1908069509" 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.1944679017" name="Software Platform Include Path" superClass="xilinx.gnu.compiler.inferred.swplatform.includes" valueType="includePath">
<listOptionValue builtIn="false" value="${resolvePlatformFile:project=dj_47dr_mts,fileType=bspInclude}"/>
</option>
<option id="xilinx.gnu.compiler.inferred.swplatform.flags.2014456475" 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.671360491" name="C source files" superClass="xilinx.gnu.arm.a53.c.compiler.input"/>
</tool>
<tool id="xilinx.gnu.arm.a53.cxx.toolchain.compiler.debug.1536306921" 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.116231871" name="Optimization Level" superClass="xilinx.gnu.compiler.option.optimization.level" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.option.debugging.level.1439910193" 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.2024154703" name="Software Platform Include Path" superClass="xilinx.gnu.compiler.inferred.swplatform.includes" valueType="includePath">
<listOptionValue builtIn="false" value="${resolvePlatformFile:project=dj_47dr_mts,fileType=bspInclude}"/>
</option>
<option id="xilinx.gnu.compiler.inferred.swplatform.flags.1139705309" 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.354014247" name="ARM v8 archiver" superClass="xilinx.gnu.arm.a53.toolchain.archiver"/>
<tool id="xilinx.gnu.arm.a53.c.toolchain.linker.debug.833817717" name="ARM v8 gcc linker" superClass="xilinx.gnu.arm.a53.c.toolchain.linker.debug">
<option id="xilinx.gnu.linker.inferred.swplatform.lpath.1973042842" name="Software Platform Library Path" superClass="xilinx.gnu.linker.inferred.swplatform.lpath" valueType="libPaths">
<listOptionValue builtIn="false" value="${resolvePlatformFile:project=dj_47dr_mts,fileType=bspLib}"/>
</option>
<option id="xilinx.gnu.linker.inferred.swplatform.flags.1845638130" 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.1601654390" name="Linker Script" superClass="xilinx.gnu.c.linker.option.lscript" value="../src/lscript.ld" valueType="string"/>
<inputType id="xilinx.gnu.linker.input.1042003683" superClass="xilinx.gnu.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
<inputType id="xilinx.gnu.linker.input.lscript.1694954729" name="Linker Script" superClass="xilinx.gnu.linker.input.lscript"/>
</tool>
<tool id="xilinx.gnu.arm.a53.cxx.toolchain.linker.debug.1110670355" name="ARM v8 g++ linker" superClass="xilinx.gnu.arm.a53.cxx.toolchain.linker.debug">
<option id="xilinx.gnu.linker.inferred.swplatform.lpath.323686415" name="Software Platform Library Path" superClass="xilinx.gnu.linker.inferred.swplatform.lpath" valueType="libPaths">
<listOptionValue builtIn="false" value="${resolvePlatformFile:project=dj_47dr_mts,fileType=bspLib}"/>
</option>
<option id="xilinx.gnu.linker.inferred.swplatform.flags.808437612" 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.68136015" 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.1558687961" 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.282746296">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="xilinx.gnu.arm.a53.exe.release.282746296" 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.282746296" name="Release" parent="xilinx.gnu.arm.a53.exe.release">
<folderInfo id="xilinx.gnu.arm.a53.exe.release.282746296." name="/" resourcePath="">
<toolChain id="xilinx.gnu.arm.a53.exe.release.toolchain.862831174" 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.640467664" isAbstract="false" name="Release Platform" superClass="xilinx.arm.a53.target.gnu.base.release"/>
<builder buildPath="${workspace_loc:/dj_47dr_mts}/Release" enableAutoBuild="true" id="xilinx.gnu.arm.a53.toolchain.builder.release.28437882" 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.1824721835" name="ARM v8 gcc assembler" superClass="xilinx.gnu.arm.a53.c.toolchain.assembler.release">
<inputType id="xilinx.gnu.assembler.input.1836415490" superClass="xilinx.gnu.assembler.input"/>
</tool>
<tool id="xilinx.gnu.arm.a53.c.toolchain.compiler.release.552882432" 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.988329560" name="Optimization Level" superClass="xilinx.gnu.compiler.option.optimization.level" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.option.debugging.level.1100036499" 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.737599586" name="Software Platform Include Path" superClass="xilinx.gnu.compiler.inferred.swplatform.includes" valueType="includePath">
<listOptionValue builtIn="false" value="${resolvePlatformFile:project=dj_47dr_mts,fileType=bspInclude}"/>
</option>
<option id="xilinx.gnu.compiler.inferred.swplatform.flags.1955276766" 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.332632958" name="C source files" superClass="xilinx.gnu.arm.a53.c.compiler.input"/>
</tool>
<tool id="xilinx.gnu.arm.a53.cxx.toolchain.compiler.release.1366798674" 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.1846755719" name="Optimization Level" superClass="xilinx.gnu.compiler.option.optimization.level" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.option.debugging.level.1874579327" 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.475115679" name="Software Platform Include Path" superClass="xilinx.gnu.compiler.inferred.swplatform.includes" valueType="includePath">
<listOptionValue builtIn="false" value="${resolvePlatformFile:project=dj_47dr_mts,fileType=bspInclude}"/>
</option>
<option id="xilinx.gnu.compiler.inferred.swplatform.flags.707035890" 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.1014801900" name="ARM v8 archiver" superClass="xilinx.gnu.arm.a53.toolchain.archiver"/>
<tool id="xilinx.gnu.arm.a53.c.toolchain.linker.release.1798451608" name="ARM v8 gcc linker" superClass="xilinx.gnu.arm.a53.c.toolchain.linker.release">
<option id="xilinx.gnu.linker.inferred.swplatform.lpath.1728481040" name="Software Platform Library Path" superClass="xilinx.gnu.linker.inferred.swplatform.lpath" valueType="libPaths">
<listOptionValue builtIn="false" value="${resolvePlatformFile:project=dj_47dr_mts,fileType=bspLib}"/>
</option>
<option id="xilinx.gnu.linker.inferred.swplatform.flags.1410867553" 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.2136837639" name="Linker Script" superClass="xilinx.gnu.c.linker.option.lscript" value="../src/lscript.ld" valueType="string"/>
<inputType id="xilinx.gnu.linker.input.2039595446" superClass="xilinx.gnu.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
<inputType id="xilinx.gnu.linker.input.lscript.2089304981" name="Linker Script" superClass="xilinx.gnu.linker.input.lscript"/>
</tool>
<tool id="xilinx.gnu.arm.a53.cxx.toolchain.linker.release.369819748" name="ARM v8 g++ linker" superClass="xilinx.gnu.arm.a53.cxx.toolchain.linker.release">
<option id="xilinx.gnu.linker.inferred.swplatform.lpath.1503143709" name="Software Platform Library Path" superClass="xilinx.gnu.linker.inferred.swplatform.lpath" valueType="libPaths">
<listOptionValue builtIn="false" value="${resolvePlatformFile:project=dj_47dr_mts,fileType=bspLib}"/>
</option>
<option id="xilinx.gnu.linker.inferred.swplatform.flags.668245247" 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.181154543" 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.1412340299" 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_mts.xilinx.gnu.arm.a53.exe.953006360" 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.debug.158563212;xilinx.gnu.arm.a53.exe.debug.158563212.;xilinx.gnu.arm.a53.c.toolchain.compiler.debug.1155184730;xilinx.gnu.arm.a53.c.compiler.input.671360491">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.xilinx.managedbuilder.ui.ARMA53GCCManagedMakePerProjectProfileC"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="xilinx.gnu.arm.a53.exe.release.282746296;xilinx.gnu.arm.a53.exe.release.282746296.;xilinx.gnu.arm.a53.c.toolchain.compiler.release.552882432;xilinx.gnu.arm.a53.c.compiler.input.332632958">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.xilinx.managedbuilder.ui.ARMA53GCCManagedMakePerProjectProfileC"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="xilinx.gnu.arm.a53.exe.release.282746296;xilinx.gnu.arm.a53.exe.release.282746296.">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.xilinx.managedbuilder.ui.ARMA53GCCManagedMakePerProjectProfileC"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="xilinx.gnu.arm.a53.exe.debug.158563212;xilinx.gnu.arm.a53.exe.debug.158563212.">
<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_mts"/>
</configuration>
<configuration configurationName="Release">
<resource resourceType="PROJECT" workspacePath="/dj_47dr_mts"/>
</configuration>
</storageModule>
</cproject>
@@ -0,0 +1,2 @@
/Debug/
/Release/
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>dj_47dr_mts</name>
<comment>Created by Vitis v2024.1</comment>
<projects>
<project>dj_47dr_platform</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>
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6d03716e09c569dced4c3bc9492138d5eed6eafe7102eb15ace592a00ce69bfb
size 34437472
@@ -0,0 +1 @@
1960514743
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,11 @@
<?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_mts" location="/home/josh/Workspace/vivado/vivado_pub/projects/dj_47dr/dj_47dr_lmx/vitis_classic/dj_47dr_mts" platform="/home/josh/Workspace/vivado/vivado_pub/projects/dj_47dr/dj_47dr_lmx/vitis_classic/dj_47dr_platform/export/dj_47dr_platform/dj_47dr_platform.xpfm" platformUID="xilinx:::0.0(custom)" systemProject="dj_47dr_mts_system" sysConfig="dj_47dr_platform" 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.158563212">
<configBuildOptions xsi:type="sdkproject:SdkOptions"/>
<lastBuildOptions xsi:type="sdkproject:SdkOptions"/>
</configuration>
<configuration name="Release" id="xilinx.gnu.arm.a53.exe.release.282746296" dirty="true">
<configBuildOptions xsi:type="sdkproject:SdkOptions"/>
</configuration>
<template appTemplateName="empty_application"/>
</sdkproject:SdkProject>
@@ -0,0 +1,30 @@
# README.md
> Vivado Project Name: dj_47dr_lmx
>
> Vitis Project Name: dj_47dr_mts
>
> Board: RFSOC_47DR_Z7045
>
> Device: xczu47dr-2ffve1156i(u15), lmk04828(u66), lmk2594(u67), lmk2594(u68)
>
> Date: 2024/07/04
>
> Archiver: Josh Gao
1. 注意事项
本工程启用了动态 DDR 配置,依赖于 FSBL 启动,在启动时 FSBL 会使用 I2C 读取 DDR 的 SPD EEPROM 获得 DDR 参数,并初始化 DDR 控制器。
由于原理图与 Xilinx 开发板 I2C Mux Slave 连接不一致,FSBL 已将 I2C Mux 的 Slave 选择改为 `0x04`。若重新建立 PS 工程,注意修改 FSBL,否则可能无法正常启动。
2. 实现的功能
- 配置了 LMK04828,使用 10 MHz 输入时钟和 122.88 MHz VCXO 完成配置,PLL2 锁定,输出时钟频率为 245.76 MHz。
- 配置了两片 LMK2594,RF 部分使用外部采样时钟,采样率为 4.9152 Gbps。
- 参考 RFSoC Eval 板卡完成了多通道同步,输出结果显示 RF-ADC 和 RF-DAC 均完成同步。
3. 存在的问题
- LMK04828 PLL1 锁定时间较长(约 1 分钟),单独配置 LMK04828 时同样存在该问题。
- LMK2594 SPI 回读异常,ILA 可以看见回读,但是 PS 程序中无回读,问题待查;通过 LED 灯判断两片 LMK2594 均锁定。
@@ -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;
}
@@ -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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_val);
} while(reg_val == 1);
/* Wait until the current transfer is completed. */
do {
axi_dmac_read(dmac, AXI_DMAC_REG_IRQ_PENDING, &reg_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, &reg_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;
}
@@ -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
@@ -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;
}
@@ -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
@@ -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
@@ -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;
}
@@ -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,129 @@
/***************************************************************************//**
* @file lmx2594.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 "../lmx2594/lmx2594.h"
#include <stdlib.h>
#include <stdio.h>
#include "../../../include/error.h"
/***************************************************************************//**
* @brief lmx2594_read
*******************************************************************************/
int32_t lmx2594_read(struct lmx2594_dev *dev,
uint8_t reg_addr,
uint16_t *reg_data)
{
uint8_t tx_buf[1];
uint8_t rx_buf[2];
int32_t ret;
tx_buf[0] = 0x80 | reg_addr;
ret = spi_write_and_read_3wire(dev->spi_desc,
tx_buf, rx_buf, 1, 2);
*reg_data = rx_buf[1];
*reg_data |= ((uint16_t)rx_buf[0]) << 8;
return ret;
}
/***************************************************************************//**
* @brief lmx2594_write
*******************************************************************************/
int32_t lmx2594_write(struct lmx2594_dev *dev,
uint8_t reg_addr,
uint16_t reg_data)
{
uint8_t buf[3];
int32_t ret;
buf[0] = reg_addr;
buf[1] = reg_data >> 8;
buf[2] = reg_data & 0xFF;
ret = spi_write_and_read_3wire(dev->spi_desc,
buf, NULL, 3, 0);
return ret;
}
/***************************************************************************//**
* @brief lmx2594_init
*******************************************************************************/
int32_t lmx2594_init(struct lmx2594_dev **device,
const struct lmx2594_init_param *init_param)
{
int ret = SUCCESS;
struct lmx2594_dev *dev;
dev = (struct lmx2594_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 lmx2594_setup().
*
* @param dev - The device structure.
*
* @return SUCCESS in case of success, negative error code otherwise.
*******************************************************************************/
int32_t lmx2594_remove(struct lmx2594_dev *dev)
{
int32_t ret;
ret = spi_remove(dev->spi_desc);
free(dev);
return ret;
}
@@ -0,0 +1,89 @@
/***************************************************************************//**
* @file lmx2594.h
* @brief Header file of lmx2594 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 LMX2594_H_
#define LMX2594_H_
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <stdint.h>
#include "../../../include/delay.h"
#include "../../../include/spi.h"
/******************************************************************************/
/********************** Macros and Constants Definitions **********************/
/******************************************************************************/
/******************************************************************************/
/*************************** Types Declarations *******************************/
/******************************************************************************/
struct lmx2594_dev {
/* SPI */
spi_desc *spi_desc;
};
struct lmx2594_init_param {
/* SPI */
spi_init_param *spi_init;
};
struct lmx2594_config {
uint8_t addr;
uint16_t value;
};
/******************************************************************************/
/************************ Functions Declarations ******************************/
/******************************************************************************/
int32_t lmx2594_read(struct lmx2594_dev *dev,
uint8_t reg_addr,
uint16_t *reg_data);
int32_t lmx2594_write(struct lmx2594_dev *dev,
uint8_t reg_addr,
uint16_t reg_data);
int32_t lmx2594_init(struct lmx2594_dev **device,
const struct lmx2594_init_param *init_param);
int32_t lmx2594_remove(struct lmx2594_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
@@ -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
};
@@ -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(&dividend, 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,69 @@
/*****************************************************************************/
/**
* Description: Global configurations.
*
* Date: 2021-04-28 13:19
* Last Edit Time: 2022-05-23 20:32
*
* Revisions: Rev 0.0
* History:
* [2021-04-28]: Initial edition.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
*
******************************************************************************/
#ifndef CONFIG_H_
#define CONFIG_H_
#define XILINX_PLATFORM
#include "xparameters.h"
#include "xparameters_ps.h"
/************ Hardware Configs ************/
#define FCLK_CLK0_HZ XPAR_CPU_CORTEXA53_0_TIMESTAMP_CLK_FREQ
/********* Zynq Platform Configs **********/
//Hardware Parameter
#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 */
// interrupt controller
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
// gpio
#define GPIO_DEVICE_ID XPAR_PSU_GPIO_0_DEVICE_ID
#define GPIO_INTR_ID XPS_GPIO_INT_ID
#define GPIO_OFFSET 78
#define GPIO_INPUT 0
#define GPIO_OUTPUT 1
#define GPIO_DISABLE 0
#define GPIO_ENABLE 1
// rfdc
#define RFDC_DEVICE_ID XPAR_XRFDC_0_DEVICE_ID
#define RFDC_INTR_ID XPAR_FABRIC_RFDC_0_VEC_ID
// spi
#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
#define SPI_CS_LMX2594_ADC 0x01
#define SPI_CS_LMX2594_DAC 0x02
#endif
@@ -0,0 +1,40 @@
#ifndef DEV_PROFILE_H_
#define DEV_PROFILE_H_
#include <inttypes.h>
#include "../app_config.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"
#include "../adi_noos/drivers/frequency/lmx2594/lmx2594.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;
extern struct lmx2594_init_param lmx2594_adc_init_param;
extern struct lmx2594_init_param lmx2594_dac_init_param;
extern const struct lmx2594_config lmx2594_default_config[];
extern const uint32_t lmx2594_default_config_len;
#endif /* SRC_DEV_PROFILE_H_ */
@@ -0,0 +1,166 @@
#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 = 137;
const struct lmk04828_config lmk04828_default_config[] = {
{0x0000, 0x90}, // [7] reset; [4] 3-wire mode disabled
{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,166 @@
#include "dev_profile.h"
#include "../app_config.h"
#include "../adi_noos/drivers/frequency/lmx2594/lmx2594.h"
static spi_init_param lmx2594_adc_spi_init = {
.device_id = SPI_DEVICE_ID,
.max_speed_hz = SPI_ENGINE_MAX_SPEED,
.mode = SPI_MODE_0,
.chip_select = SPI_CS_LMX2594_ADC,
.platform_ops = SPI_OPS,
.extra = SPI_PARAM
};
static spi_init_param lmx2594_dac_spi_init = {
.device_id = SPI_DEVICE_ID,
.max_speed_hz = SPI_ENGINE_MAX_SPEED,
.mode = SPI_MODE_0,
.chip_select = SPI_CS_LMX2594_DAC,
.platform_ops = SPI_OPS,
.extra = SPI_PARAM
};
struct lmx2594_init_param lmx2594_adc_init_param = {
/* SPI */
.spi_init = &lmx2594_adc_spi_init
};
struct lmx2594_init_param lmx2594_dac_init_param = {
/* SPI */
.spi_init = &lmx2594_dac_spi_init
};
const uint32_t lmx2594_default_config_len = 110;
const struct lmx2594_config lmx2594_default_config[] = {
// 0 ~ 78: General configuration
// 79 ~ 106: Ramping configuration
// 107 ~ 112: Readback registers
// Recommended Initial Power-Up Sequence
// For the most reliable programming, TI recommends this procedure::
// 1. Apply power to device.
// 2. Program RESET = 1 to reset registers.
// 3. Program RESET = 0 to remove reset.
// 4. Program registers as shown in the register map in REVERSE order from highest to lowest.
// 5. Wait 10 ms.
// 6. Program register R0 one additional time with FCAL_EN = 1 to ensure that the VCO calibration runs from a stable state.
// Reset
{ 0, 0x0002},
// Remove Reset
{ 0, 0x0000},
// Reverse order programming
{106, 0x0000},
{105, 0x0021},
{104, 0x0000},
{103, 0xD555},
{102, 0x3F97},
{101, 0x0011},
{100, 0x0000},
{ 99, 0x2AAB},
{ 98, 0x01A0},
{ 97, 0x0888},
{ 96, 0x0000},
{ 95, 0x0000}, // fixed
{ 94, 0x0000}, // fixed
{ 93, 0x0000}, // fixed
{ 92, 0x0000}, // fixed
{ 91, 0x0000}, // fixed
{ 90, 0x0000}, // fixed
{ 89, 0x0000}, // fixed
{ 88, 0x0000}, // fixed
{ 87, 0x0000}, // fixed
{ 86, 0x5879},
{ 85, 0xEC58},
{ 84, 0x0001},
{ 83, 0x54C9},
{ 82, 0x2961},
{ 81, 0x0000},
{ 80, 0x4000},
{ 79, 0x001F},
{ 78, 0x0003}, // [8:1] VCO_CAPCTRL_STRT
{ 77, 0x0000}, // fixed
{ 76, 0x000C}, // fixed
{ 75, 0x0800}, // [10:6] CHDIV
{ 74, 0x0000}, // [11:6] JESD_DAC4_CTRL; [5:0] JESD_DAC3_CTRL
{ 73, 0x003F}, // [11:6] JESD_DAC2_CTRL; [5:0] JESD_DAC1_CTRL
{ 72, 0x0001}, // [10:0] SYSREF_DIV
{ 71, 0x0081}, // [7:5] SYSREF_DIV_PRE; [4] SYSREF_PULSE; [3] SYSREF_EN; [2] SYSREF_REPEAT
{ 70, 0xC350}, // [15:0] MASH_RST_COUNT
{ 69, 0x0000}, // [15:0] MASH_RST_COUNT
{ 68, 0x03E8}, // fixed
{ 67, 0x0000}, // fixed
{ 66, 0x01F4}, // fixed
{ 65, 0x0000}, // fixed
{ 64, 0x1388}, // fixed
{ 63, 0x0000}, // fixed
{ 62, 0x0322}, // fixed
{ 61, 0x00A8}, // fixed
{ 60, 0x0000}, // [15:0] LD_DLY
{ 59, 0x0001}, // [0] LD_TYPE
{ 58, 0x9001}, // [15] INPIN_IGNORE; [14] INPIN_HYST; [13:12] INPIN_LVL; [11:9] INPIN_FMT
{ 57, 0x0020}, // fixed
{ 56, 0x0000}, // fixed
{ 55, 0x0000}, // fixed
{ 54, 0x0000}, // fixed
{ 53, 0x0000}, // fixed
{ 52, 0x0820}, // fixed
{ 51, 0x0080}, // fixed
{ 50, 0x0000}, // fixed
{ 49, 0x4180}, // fixed
{ 48, 0x0300}, // fixed
{ 47, 0x0300}, // fixed
{ 46, 0x07FC}, // [1:0] OUTB_MUX
{ 45, 0xC0DF}, // [12:11] OUTA_MUX; [10:9] OUT_ISET; [5:0] OUTB_PWR
{ 44, 0x1AA3}, // [13:8] OUTA_PWR; [7] OUTB_PD; [6] OUTA_PD; [5] MASH_RESET_N; [2:0] MASH_ORDER
{ 43, 0x0000}, // [15:0] PLL_NUM
{ 42, 0x0000}, // [15:0] PLL_NUM
{ 41, 0x0000}, // [15:0] MASH_SEE
{ 40, 0x0000}, // [15:0] MASH_SEE
{ 39, 0x03E8}, // [15:0] PLL_DEN
{ 38, 0x0000}, // [15:0] PLL_DEN
{ 37, 0x0304}, // [37] MASH_SEED_EN; [13:8] PFD_DLY_SEL
{ 36, 0x0028}, // [15:0] PLL_N
{ 35, 0x0004}, // fixed
{ 34, 0x0000}, // [2:0] PLL_N
{ 33, 0x1E21}, // fixed
{ 32, 0x0393}, // fixed
{ 31, 0x43EC}, // [14] SEG1_EN
{ 30, 0x318C}, // fixed
{ 29, 0x318C}, // fixed
{ 28, 0x0488}, // fixed
{ 27, 0x0002}, // fixed
{ 26, 0x0DB0}, // fixed
{ 25, 0x0C2B}, // fixed
{ 24, 0x071A}, // fixed
{ 23, 0x007C}, // fixed
{ 22, 0x0001}, // fixed
{ 21, 0x0401}, // fixed
{ 20, 0xE048}, // [13:11] VCO_SEL. [10] VCO_SEL_FORCE
{ 19, 0x27B7}, // [7:0] VCO_CAPCTRL
{ 18, 0x0064}, // fixed
{ 17, 0x012C}, // [8:0] VCO_DACISET_STRT
{ 16, 0x0080}, // [8:0] VCO_DACISET
{ 15, 0x064F}, // fixed
{ 14, 0x1E70}, // [6:4] CPG
{ 13, 0x4000}, // fixed
{ 12, 0x5001}, // [11:0] PLL_R_PR
{ 11, 0x0018}, // [11:4] PLL_R
{ 10, 0x10D8}, // [11:7] MULT
{ 9, 0x0604}, // [12] OSC_2X
{ 8, 0x2000}, // [14] VCO_DACISET_FORCE; [11] VCO_CAPCTRL_FORCE
{ 7, 0x40B2}, // [14] OUT_FORCE
{ 6, 0xC802}, // fixed
{ 5, 0x00C8}, // fixed
{ 4, 0x0C43}, // [15:8] ACAL_CMP_DLY
{ 3, 0x0642}, // fixed
{ 2, 0x0500}, // fixed
{ 1, 0x0809}, // [2:0] CAL_CLK_DIV
{ 0, 0x2598}, // [15] RAMP_EN; [14] VCO_PHASE_SYNC; [9] OUT_MUTE; [8:7] FCAL_HPFD_ADJ; [6:5] FCAL_LPFD_ADJ; [3] FCAL_EN; [2] MUXOUT_LD_SEL; [1] RESET; [0] POWERDOWN
// one more time
{ 0, 0x2598}
};
@@ -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,539 @@
/***************************************************************************//**
* @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 copyright00
* 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"
//add
/************************** Constant Definitions ****************************/
/*
* The following constants map to the XPAR parameters created in the
* xparameters.h file. They are defined here such that a user can easily
* change all the needed parameters in one place.
*/
#ifdef __BAREMETAL__
#define RFDC_DEVICE_ID XPAR_XRFDC_0_DEVICE_ID
#define I2CBUS 1
#else
#define RFDC_DEVICE_ID 0
#define I2CBUS 12
#endif
/**************************** Type Definitions ******************************/
#define DEFAULT_LOGGER_ON
/***************** Macros (Inline Functions) Definitions ********************/
#ifdef __BAREMETAL__
#define printf xil_printf
#endif
/************************** Function Prototypes *****************************/
int RFdcMTS_Example(u16 RFdcDeviceId); //u16: unsigned short int
//end add
/******************************************************************************/
/************************ 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;
struct lmx2594_dev *lmx2594_adc_inst;
struct lmx2594_dev *lmx2594_dac_inst;
XRFdc RFdc;
XGpioPs Gpio;
void my_log_handler(enum metal_log_level level,
const char *format, ...)
{
#ifdef DEFAULT_LOGGER_ON
char msg[1024];
va_list args;
static const char * const level_strs[] = {
"metal: emergency: ",
"metal: alert: ",
"metal: critical: ",
"metal: error: ",
"metal: warning: ",
"metal: notice: ",
"metal: info: ",
"metal: debug: ",
};
va_start(args, format);
vsnprintf(msg, sizeof(msg), format, args);
va_end(args);
if (level <= METAL_LOG_EMERGENCY || level > METAL_LOG_DEBUG)
level = METAL_LOG_EMERGENCY;
fprintf(stderr, "%s%s", level_strs[level], msg);
#else
(void)level;
(void)format;
#endif
}
//add
static XRFdc RFdcInst; /* RFdc driver instance */
/****************************************************************************/
/**
*
* Main function that invokes the MTS example in this file.
*
* @param None.
*
* @return
* - XRFDC_SUCCESS if the example has completed successfully.
* - XRFDC_FAILURE if the example has failed.
*
* @note None.
*
//end add
/*******************************************************************************/
/**
* @brief main
*******************************************************************************/
int main(void)
{
int32_t Status;
uint8_t Lmk04828Read;
uint16_t Lmx2594Read;
// 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
Status = lmk04828_read(lmk04828_inst, 0x0182, &Lmk04828Read);
if ((Lmk04828Read & 0x02) == 0x02) {
xil_printf("LMK04828 PLL1 Locked.\r\n");
}
else {
xil_printf("LMK04828 PLL1 NOT lock!\r\n");
}
Status = lmk04828_read(lmk04828_inst, 0x0183, &Lmk04828Read);
if ((Lmk04828Read & 0x02) == 0x02) {
xil_printf("LMK04828 PLL2 Locked.\r\n");
}
else {
xil_printf("LMK04828 PLL2 NOT lock!\r\n");
}
/**********************************************************/
/************* LMX2594 for DAC Configuration **************/
/**********************************************************/
Status = lmx2594_init(&lmx2594_dac_inst, &lmx2594_dac_init_param);
for(int i = 0; i < lmx2594_default_config_len; i++)
{
Status = lmx2594_write(lmx2594_dac_inst, lmx2594_default_config[i].addr, lmx2594_default_config[i].value);
if (lmx2594_default_config[i].addr == 0)
{
mdelay(500);
}
}
// check vco lock status
Status = lmx2594_read(lmx2594_dac_inst, 110, &Lmx2594Read);
if (((Lmx2594Read >> 9) & 0x03) == 0x02) {
xil_printf("LMX2594 for DAC Config Done.\r\n");
}
else {
xil_printf("LMX2594 for DAC not lock!\r\n");
}
Status = lmx2594_write(lmx2594_dac_inst, 0x00, 0x259C);
/**********************************************************/
/************* LMX2594 for ADC Configuration **************/
/**********************************************************/
Status = lmx2594_init(&lmx2594_adc_inst, &lmx2594_adc_init_param);
for(int i = 0; i < lmx2594_default_config_len; i++)
{
Status = lmx2594_write(lmx2594_adc_inst, lmx2594_default_config[i].addr, lmx2594_default_config[i].value);
if (lmx2594_default_config[i].addr == 0)
{
mdelay(500);
}
}
Status = lmx2594_read(lmx2594_adc_inst, 0, &Lmx2594Read);
// check vco lock status
Status = lmx2594_read(lmx2594_adc_inst, 110, &Lmx2594Read);
if (((Lmx2594Read >> 9) & 0x03) == 0x02) {
xil_printf("LMX2594 for ADC Config Done.\r\n");
}
else {
xil_printf("LMX2594 for ADC not lock!\r\n");
}
Status = lmx2594_write(lmx2594_adc_inst, 0x00, 0x259C);
//add
printf("RFdc MTS Example Test\r\n");
/*
* Specify the Device ID that is generated in xparameters.h.
*/
Status = RFdcMTS_Example(RFDC_DEVICE_ID);
if (Status != XRFDC_SUCCESS) {
printf("MTS Example Test failed\r\n");
return XRFDC_FAILURE;
}
printf("Successfully ran MTS Example\r\n");
return XRFDC_SUCCESS;
//end add
print("Done.\n");
return 0;
}
//add
/****************************************************************************/
/**
*
* This function runs a MTS test on the RFSoC data converter device using the
* driver APIs.
* This function does the following tasks:
* - Initialize the RFdc device driver instance
* - Test MTS feature.
*
* @param RFdcDeviceId is the XPAR_<XRFDC_instance>_DEVICE_ID value
* from xparameters.h.
*
* @return
* - XRFDC_SUCCESS if the example has completed successfully.
* - XRFDC_FAILURE if the example has failed.
*
* @note None
*
****************************************************************************/
int RFdcMTS_Example(u16 RFdcDeviceId)
{
int status, status_adc, status_dac, i;
u32 factor;
XRFdc_Config *ConfigPtr;
XRFdc *RFdcInstPtr = &RFdcInst;
#ifndef __BAREMETAL__
struct metal_device *deviceptr;
#endif
struct metal_init_params init_param = METAL_INIT_DEFAULTS;
if (metal_init(&init_param)) {
printf("ERROR: Failed to run metal initialization\n");
return XRFDC_FAILURE;
}
metal_set_log_handler(my_log_handler);
metal_set_log_level(METAL_LOG_DEBUG);
ConfigPtr = XRFdc_LookupConfig(RFdcDeviceId);
if (ConfigPtr == NULL) {
return XRFDC_FAILURE;
}
#ifndef __BAREMETAL__
status = XRFdc_RegisterMetal(RFdcInstPtr, RFdcDeviceId, &deviceptr);
if (status != XRFDC_SUCCESS) {
return XRFDC_FAILURE;
}
#endif
status = XRFdc_CfgInitialize(RFdcInstPtr, ConfigPtr);
if (status != XRFDC_SUCCESS) {
printf("RFdc Init Failure\n\r");
}
//add
//end add
printf("=== RFdc Initialized - Running Multi-tile Sync ===\n");
/* ADC MTS Settings */
XRFdc_MultiConverter_Sync_Config ADC_Sync_Config;
/* DAC MTS Settings */
XRFdc_MultiConverter_Sync_Config DAC_Sync_Config;
//end add
/* Run MTS for the ADC & DAC */
printf("\n=== Run DAC Sync ===\n");
/* Initialize DAC MTS Settings */
XRFdc_MultiConverter_Init (&DAC_Sync_Config, 0, 0, XRFDC_TILE_ID0);
DAC_Sync_Config.Tiles = 0xF; /* Sync DAC tiles 0 and 1 */
status_dac = XRFdc_MultiConverter_Sync(RFdcInstPtr, XRFDC_DAC_TILE,
&DAC_Sync_Config);
if(status_dac == XRFDC_MTS_OK){
printf("INFO : DAC Multi-Tile-Sync completed successfully\n");
}else{
printf("ERROR : DAC Multi-Tile-Sync did not complete successfully. Error code is %u \n",status_dac);
return status_dac;
}
printf("\n=== Run ADC Sync ===\n");
/* Initialize ADC MTS Settings */
XRFdc_MultiConverter_Init (&ADC_Sync_Config, 0, 0, XRFDC_TILE_ID0);
ADC_Sync_Config.Tiles = 0xF; /* Sync ADC tiles 0, 1, 2, 3 */
status_adc = XRFdc_MultiConverter_Sync(RFdcInstPtr, XRFDC_ADC_TILE,
&ADC_Sync_Config);
if(status_adc == XRFDC_MTS_OK){
printf("INFO : ADC Multi-Tile-Sync completed successfully\n");
}else{
printf("ERROR : ADC Multi-Tile-Sync did not complete successfully. Error code is %u \n",status_adc);
return status_adc;
}
/*
* Report Overall Latency in T1 (Sample Clocks) and
* Offsets (in terms of PL words) added to each FIFO
*/
printf("\n\n=== Multi-Tile Sync Report ===\n");
for(i=0; i<4; i++) {
if((1<<i)&DAC_Sync_Config.Tiles) {
XRFdc_GetInterpolationFactor(RFdcInstPtr, i, 0, &factor);
printf("DAC%d: Latency(T1) =%3d, Adjusted Delay"
"Offset(T%d) =%3d\n", i, DAC_Sync_Config.Latency[i],
factor, DAC_Sync_Config.Offset[i]);
}
}
for(i=0; i<4; i++) {
if((1<<i)&ADC_Sync_Config.Tiles) {
XRFdc_GetDecimationFactor(RFdcInstPtr, i, 0, &factor);
printf("ADC%d: Latency(T1) =%3d, Adjusted Delay"
"Offset(T%d) =%3d\n", i, ADC_Sync_Config.Latency[i],
factor, ADC_Sync_Config.Offset[i]);
}
}
//add
int SysRefEnable;
//Disable the analog SYSREF receiver with the API command
SysRefEnable = 0;
status_dac|=XRFdc_MTS_Sysref_Config(RFdcInstPtr, &DAC_Sync_Config,&ADC_Sync_Config, SysRefEnable);
status_adc|=XRFdc_MTS_Sysref_Config(RFdcInstPtr, &DAC_Sync_Config,&ADC_Sync_Config, SysRefEnable);
//Arm the mixer settings, NCO phase reset
//DAC Mixer Settings
XRFdc_Mixer_Settings DAC_Mixer_Settings;
DAC_Mixer_Settings.CoarseMixFreq = XRFDC_COARSE_MIX_OFF;
DAC_Mixer_Settings.MixerType = XRFDC_MIXER_TYPE_FINE;
DAC_Mixer_Settings.MixerMode = XRFDC_MIXER_MODE_C2R;
DAC_Mixer_Settings.PhaseOffset = 0;
DAC_Mixer_Settings.Freq = 1050;
DAC_Mixer_Settings.FineMixerScale = XRFDC_MIXER_SCALE_AUTO;
DAC_Mixer_Settings.EventSource = XRFDC_EVNT_SRC_SYSREF;
// int Tile_Id;
// //DAC sample rate
// for(Tile_Id=0; Tile_Id<4; Tile_Id++) {
// status = XRFdc_DynamicPLLConfig(RFdcInstPtr, 1, Tile_Id, XRFDC_EXTERNAL_CLK, 3932.16, 3932.16);
// if (status != XRFDC_SUCCESS) {
// printf("XRFdc DAC DynamicPLLConfig Failure\n\r");
// }
// }
// for(int i = 0;i < 4;i++)
// {
// for(int j = 0;j < 1;j++)
// {
// status = XRFdc_SetInterpolationFactor(RFdcInstPtr, i, j, XRFDC_INTERP_DECIM_16X);
// if (status != XRFDC_SUCCESS) {
// printf("XRFdc DAC SetInterpolationFactor Failure\n\r");
// }
// }
// }
//DAC NCO reset
for(int i = 0;i < 4;i++)
{
for(int j = 0;j < 1;j++)
{
status = XRFdc_SetMixerSettings(RFdcInstPtr, XRFDC_DAC_TILE, i, j, &DAC_Mixer_Settings);
if (status != XRFDC_SUCCESS) {
printf("XRFdc_SetMixerSettings FAILED \n\n");
//return XRFDC_FAILURE;
}
status = XRFdc_ResetNCOPhase(RFdcInstPtr, XRFDC_DAC_TILE, i, j);
if (status != XRFDC_SUCCESS) {
printf("XRFdc_ResetNCOPhase FAILED \n\n");
//return XRFDC_FAILURE;
}
}
}
//ADC Mixer Settings
XRFdc_Mixer_Settings ADC_Mixer_Settings;
ADC_Mixer_Settings.CoarseMixFreq = XRFDC_COARSE_MIX_OFF;
ADC_Mixer_Settings.MixerType = XRFDC_MIXER_TYPE_FINE;
ADC_Mixer_Settings.MixerMode = XRFDC_MIXER_MODE_R2C;
ADC_Mixer_Settings.PhaseOffset = 0;
ADC_Mixer_Settings.Freq = 1050;
ADC_Mixer_Settings.FineMixerScale = XRFDC_MIXER_SCALE_AUTO;
ADC_Mixer_Settings.EventSource = XRFDC_EVNT_SRC_SYSREF;
// //ADC sample rate
// for(Tile_Id=0; Tile_Id<4; Tile_Id++) {
// status = XRFdc_DynamicPLLConfig(RFdcInstPtr, 0, Tile_Id, XRFDC_EXTERNAL_CLK, 3932.16, 3932.16);
// if (status != XRFDC_SUCCESS) {
// printf("XRFdc ADC DynamicPLLConfig Failure\n\r");
// }
// }
//ADC NCO reset
for(int i = 0;i < 4;i++)
{
for(int j = 0;j < 2;j++)
{
status = XRFdc_SetMixerSettings(RFdcInstPtr, XRFDC_ADC_TILE, i, j, &ADC_Mixer_Settings);
if (status != XRFDC_SUCCESS) {
printf("XRFdc_SetMixerSettings FAILED \n\n");
//return XRFDC_FAILURE;
}
status = XRFdc_ResetNCOPhase(RFdcInstPtr, XRFDC_ADC_TILE, i, j);
if (status != XRFDC_SUCCESS) {
printf("XRFdc_ResetNCOPhase FAILED \n\n");
//return XRFDC_FAILURE;
}
}
}
//Enable the analog SYSREF receiver with the API command
SysRefEnable = 1;
status_dac|=XRFdc_MTS_Sysref_Config(RFdcInstPtr, &DAC_Sync_Config,&ADC_Sync_Config, SysRefEnable);
status_adc|=XRFdc_MTS_Sysref_Config(RFdcInstPtr, &DAC_Sync_Config,&ADC_Sync_Config, SysRefEnable);
//Wait long enough to ensure a rising edge has been detected, at this point the update would commence
mdelay(500);
//Disable the analog SYSREF receiver with the API command
SysRefEnable = 0;
status_dac|=XRFdc_MTS_Sysref_Config(RFdcInstPtr, &DAC_Sync_Config,&ADC_Sync_Config, SysRefEnable);
status_adc|=XRFdc_MTS_Sysref_Config(RFdcInstPtr, &DAC_Sync_Config,&ADC_Sync_Config, SysRefEnable);
return XRFDC_MTS_OK;
//end add
}
//end add
@@ -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.1907431564">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.xilinx.sdx.system.managedbuilder.debugConfiguration.1907431564" 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.1907431564" name="Debug" parent="com.xilinx.sdx.system.managedbuilder.debugConfiguration">
<folderInfo id="com.xilinx.sdx.system.managedbuilder.debugConfiguration.1907431564." name="/" resourcePath="">
<toolChain id="com.xilinx.sdx.system.managedbuilder.debug.toolChain.1605498756" name="System Toolchain" superClass="com.xilinx.sdx.system.managedbuilder.debug.toolChain">
<targetPlatform id="com.xilinx.sdx.system.managedbuilder.debugConfiguration.1907431564..1450315932" name=""/>
<builder buildPath="${workspace_loc:/dj_47dr_mts_system}/Debug" enableAutoBuild="true" id="com.xilinx.sdx.system.managedbuilder.systemBuilder.1645440061" managedBuildOn="true" name="System Project Builder.Debug" superClass="com.xilinx.sdx.system.managedbuilder.systemBuilder"/>
<tool id="com.xilinx.sdx.system.managedbuilder.toolchain.cfjoinTool.2058446700" 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.166903256">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.xilinx.sdx.system.managedbuilder.releaseConfiguration.166903256" 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.166903256" name="Release" parent="com.xilinx.sdx.system.managedbuilder.releaseConfiguration">
<folderInfo id="com.xilinx.sdx.system.managedbuilder.releaseConfiguration.166903256." name="/" resourcePath="">
<toolChain id="com.xilinx.sdx.system.managedbuilder.release.toolChain.814794348" name="System Toolchain" superClass="com.xilinx.sdx.system.managedbuilder.release.toolChain">
<targetPlatform id="com.xilinx.sdx.system.managedbuilder.releaseConfiguration.166903256..2005574638" name=""/>
<builder buildPath="${workspace_loc:/dj_47dr_mts_system}/Release" enableAutoBuild="true" id="com.xilinx.sdx.system.managedbuilder.systemBuilder.1119047007" managedBuildOn="true" name="System Project Builder.Release" superClass="com.xilinx.sdx.system.managedbuilder.systemBuilder"/>
<tool id="com.xilinx.sdx.system.managedbuilder.toolchain.cfjoinTool.1660593477" 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_mts_system.com.xilinx.sdx.system.managedbuilder.projectType.1131096103" 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/

Some files were not shown because too many files have changed in this diff Show More