Browse Source

initialize project with v003

Signed-off-by: abagu <352211526@qq.com>
master v003
abagu 5 years ago
commit
6e0a80814d
  1. 13
      .ccsproject
  2. 217
      .cproject
  3. 6
      .gitignore
  4. 34
      .project
  5. 166
      evmc.cfg
  6. 670
      src/ad9361.c
  7. 19
      src/ad9361.h
  8. 2094
      src/ad9361_lib/ad9361_api.c
  9. 501
      src/ad9361_lib/ad9361_api.h
  10. 597
      src/ad9361_lib/ad9361_conv.c
  11. 7120
      src/ad9361_lib/ad9361_dev.c
  12. 3510
      src/ad9361_lib/ad9361_dev.h
  13. 417
      src/ad9361_lib/adc_core.c
  14. 175
      src/ad9361_lib/adc_core.h
  15. 117
      src/ad9361_lib/common.h
  16. 103
      src/ad9361_lib/config.h
  17. 807
      src/ad9361_lib/dac_core.c
  18. 203
      src/ad9361_lib/dac_core.h
  19. 87
      src/ad9361_lib/platform.c
  20. 64
      src/ad9361_lib/platform.h
  21. 346
      src/ad9361_lib/util.c
  22. 142
      src/ad9361_lib/util.h
  23. 218
      src/ad9680.c
  24. 18
      src/ad9680.h
  25. 179
      src/ad9779.c
  26. 20
      src/ad9779.h
  27. 89
      src/axi0.c
  28. 24
      src/axi0.h
  29. 86
      src/axi1.c
  30. 25
      src/axi1.h
  31. 107
      src/emif_test.c
  32. 20
      src/emif_test.h
  33. 117
      src/gspi.c
  34. 39
      src/gspi.h
  35. 230
      src/k7_download.c
  36. 20
      src/k7_download.h
  37. 271
      src/main.c
  38. 100
      src/nandflash.c
  39. 15
      src/nandflash.h
  40. 169
      src/norflash.c
  41. 15
      src/norflash.h
  42. 192
      src/runtime.c
  43. 15
      src/runtime.h
  44. 246
      src/srio.c
  45. 20
      src/srio.h
  46. 35
      src/vsdef.h
  47. 16
      targetConfigs/TMS320C6678.ccxml
  48. 9
      targetConfigs/readme.txt
  49. 9
      vslib/cmdline.cmd
  50. 246
      vslib/vbios.c
  51. 45
      vslib/vbios.h
  52. 24
      vslib/vcmd.h
  53. 865
      vslib/vconsole.c
  54. 27
      vslib/vconsole.h
  55. 101
      vslib/vdebug.c
  56. 16
      vslib/vdebug.h
  57. 45
      vslib/vlock.c
  58. 17
      vslib/vlock.h
  59. 67
      vslib/vsem.c
  60. 17
      vslib/vsem.h
  61. 89
      vslib/vtask.c
  62. 23
      vslib/vtask.h
  63. 217
      vslib/vtelnetd.c
  64. 23
      vslib/vtelnetd.h
  65. 55
      vslib/vtftp.c
  66. 13
      vslib/vtftp.h
  67. 75
      vslib/vtimer.c
  68. 20
      vslib/vtimer.h

13
.ccsproject

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<?ccsproject version="1.0"?>
<projectOptions>
<deviceVariant value="com.ti.ccstudio.deviceModel.C6000.GenericC62xxDevice"/>
<deviceFamily value="C6000"/>
<deviceEndianness value="little"/>
<codegenToolVersion value="7.4.20"/>
<isElfFormat value="false"/>
<connection value="common/targetdb/connections/SD560V2USB_Connection.xml"/>
<rts value="libc.a"/>
<templateProperties value="id=org.eclipse.rtsc.project.templates.EmptyRtscApplication,buildProfile=release,isHybrid=true,"/>
<isTargetManual value="false"/>
</projectOptions>

217
.cproject

@ -0,0 +1,217 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?>
<cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule configRelations="2" moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="com.ti.ccstudio.buildDefinitions.C6000.Debug.1475700425">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.ti.ccstudio.buildDefinitions.C6000.Debug.1475700425" moduleId="org.eclipse.cdt.core.settings" name="Debug">
<externalSettings/>
<extensions>
<extension id="com.ti.ccstudio.binaryparser.CoffParser" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.ti.ccstudio.errorparser.CoffErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="com.ti.ccstudio.errorparser.LinkErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="com.ti.ccstudio.errorparser.AsmErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.rtsc.xdctools.parsers.ErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactExtension="out" artifactName="${ProjName}" buildProperties="" cleanCommand="${CG_CLEAN_CMD}" description="" errorParsers="org.eclipse.rtsc.xdctools.parsers.ErrorParser;com.ti.ccstudio.errorparser.CoffErrorParser;com.ti.ccstudio.errorparser.LinkErrorParser;com.ti.ccstudio.errorparser.AsmErrorParser" id="com.ti.ccstudio.buildDefinitions.C6000.Debug.1475700425" name="Debug" parent="com.ti.ccstudio.buildDefinitions.C6000.Debug" postannouncebuildStep="copy *.out to tftpd " postbuildStep="xcopy /Q /Y &quot;${PROJECT_LOC}\Debug\*.out&quot; &quot;e:\dspwork\tftpd\&quot;">
<folderInfo id="com.ti.ccstudio.buildDefinitions.C6000.Debug.1475700425." name="/" resourcePath="">
<toolChain id="com.ti.ccstudio.buildDefinitions.C6000_7.4.exe.DebugToolchain.124696814" name="TI Build Tools" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.exe.DebugToolchain" targetTool="com.ti.ccstudio.buildDefinitions.C6000_7.4.exe.linkerDebug.841646834">
<option id="com.ti.ccstudio.buildDefinitions.core.OPT_TAGS.1992767916" superClass="com.ti.ccstudio.buildDefinitions.core.OPT_TAGS" valueType="stringList">
<listOptionValue builtIn="false" value="DEVICE_CONFIGURATION_ID=TMS320C66XX.TMS320C6678"/>
<listOptionValue builtIn="false" value="DEVICE_ENDIANNESS=little"/>
<listOptionValue builtIn="false" value="OUTPUT_FORMAT=ELF"/>
<listOptionValue builtIn="false" value="CCS_MBS_VERSION=5.5.0"/>
<listOptionValue builtIn="false" value="RUNTIME_SUPPORT_LIBRARY=libc.a"/>
<listOptionValue builtIn="false" value="RTSC_MBS_VERSION=2.2.0"/>
<listOptionValue builtIn="false" value="XDC_VERSION=3.25.3.72"/>
<listOptionValue builtIn="false" value="RTSC_PRODUCTS=ctoolslib:1.0.0.02;ti.mas.dsplib.c66x:3.1.0.0;com.ti.sdo.edma3:2.11.5;ti.imglib.c66x:3.1.1.0;com.ti.rtsc.IPC:1.24.3.32;ti.mathlib.c66x:3.0.1.1;com.ti.biosmcsdk.mcsdk:2.1.2.6;com.ti.biosmcsdk.pdk.C6678L:1.1.2.6;com.ti.rtsc.NDK:2.21.2.43;com.ti.biosmcsdk.openem:1.0.0.2;com.ti.rtsc.OMP:1.1.3.02;com.ti.rtsc.SYSBIOS:6.35.4.50;com.ti.uia:1.3.1.08;com.ti.rtsc.XDAIS:7.21.1.07;"/>
<listOptionValue builtIn="false" value="INACTIVE_REPOS="/>
<listOptionValue builtIn="false" value="OUTPUT_TYPE=rtscApplication:executable"/>
</option>
<option id="com.ti.ccstudio.buildDefinitions.core.OPT_CODEGEN_VERSION.1327741481" name="Compiler version" superClass="com.ti.ccstudio.buildDefinitions.core.OPT_CODEGEN_VERSION" value="7.4.20" valueType="string"/>
<targetPlatform id="com.ti.ccstudio.buildDefinitions.C6000_7.4.exe.targetPlatformDebug.1597977238" name="Platform" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.exe.targetPlatformDebug"/>
<builder buildPath="${BuildDirectory}" id="com.ti.ccstudio.buildDefinitions.C6000_7.4.exe.builderDebug.1082218957" keepEnvironmentInBuildfile="false" name="GNU Make" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.exe.builderDebug"/>
<tool id="com.ti.ccstudio.buildDefinitions.C6000_7.4.exe.compilerDebug.1508208548" name="C6000 Compiler" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.exe.compilerDebug">
<option id="com.ti.ccstudio.buildDefinitions.C6000_7.4.compilerID.SILICON_VERSION.1859861277" name="Target processor version (--silicon_version, -mv)" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.compilerID.SILICON_VERSION" value="6600" valueType="string"/>
<option id="com.ti.ccstudio.buildDefinitions.C6000_7.4.compilerID.BIG_ENDIAN.1067161906" name="Generate big endian code [See 'General' page to edit] (--big_endian, -me)" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.compilerID.BIG_ENDIAN" value="false" valueType="boolean"/>
<option id="com.ti.ccstudio.buildDefinitions.C6000_7.4.compilerID.ABI.1774955533" name="Application binary interface (coffabi, eabi) [See 'General' page to edit] (--abi)" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.compilerID.ABI" value="com.ti.ccstudio.buildDefinitions.C6000_7.4.compilerID.ABI.eabi" valueType="enumerated"/>
<option id="com.ti.ccstudio.buildDefinitions.C6000_7.4.compilerID.DEBUGGING_MODEL.1413563977" name="Debugging model" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.compilerID.DEBUGGING_MODEL" value="com.ti.ccstudio.buildDefinitions.C6000_7.4.compilerID.DEBUGGING_MODEL.SYMDEBUG__DWARF" valueType="enumerated"/>
<option id="com.ti.ccstudio.buildDefinitions.C6000_7.4.compilerID.INCLUDE_PATH.307061837" name="Add dir to #include search path (--include_path, -I)" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.compilerID.INCLUDE_PATH" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${CG_TOOL_ROOT}/include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${VSKY_LIBDSP_ROOT}/packages/vsky/libdsp/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/}&quot;"/>
</option>
<option id="com.ti.ccstudio.buildDefinitions.C6000_7.4.compilerID.LANGUAGE_MODE.1676149233" name="Language mode" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.compilerID.LANGUAGE_MODE" value="com.ti.ccstudio.buildDefinitions.C6000_7.4.compilerID.LANGUAGE_MODE.RELAXED_ANSI" valueType="enumerated"/>
<option id="com.ti.ccstudio.buildDefinitions.C6000_7.4.compilerID.GCC.571139387" name="Enable support for GCC extensions (--gcc)" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.compilerID.GCC" value="true" valueType="boolean"/>
<option id="com.ti.ccstudio.buildDefinitions.C6000_7.4.compilerID.DISPLAY_ERROR_NUMBER.1730881275" name="Emit diagnostic identifier numbers (--display_error_number, -pden)" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.compilerID.DISPLAY_ERROR_NUMBER" value="true" valueType="boolean"/>
<option id="com.ti.ccstudio.buildDefinitions.C6000_7.4.compilerID.DIAG_WARNING.1326661886" name="Treat diagnostic &lt;id&gt; as warning (--diag_warning, -pdsw)" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.compilerID.DIAG_WARNING" valueType="stringList">
<listOptionValue builtIn="false" value="225"/>
</option>
<option id="com.ti.ccstudio.buildDefinitions.C6000_7.4.compilerID.DIAG_WRAP.387750443" name="Wrap diagnostic messages (--diag_wrap)" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.compilerID.DIAG_WRAP" value="com.ti.ccstudio.buildDefinitions.C6000_7.4.compilerID.DIAG_WRAP.off" valueType="enumerated"/>
<inputType id="com.ti.ccstudio.buildDefinitions.C6000_7.4.compiler.inputType__C_SRCS.1929580098" name="C Sources" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.compiler.inputType__C_SRCS"/>
<inputType id="com.ti.ccstudio.buildDefinitions.C6000_7.4.compiler.inputType__CPP_SRCS.361892281" name="C++ Sources" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.compiler.inputType__CPP_SRCS"/>
<inputType id="com.ti.ccstudio.buildDefinitions.C6000_7.4.compiler.inputType__ASM_SRCS.988559866" name="Assembly Sources" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.compiler.inputType__ASM_SRCS"/>
<inputType id="com.ti.ccstudio.buildDefinitions.C6000_7.4.compiler.inputType__ASM2_SRCS.666318701" name="Assembly Sources" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.compiler.inputType__ASM2_SRCS"/>
</tool>
<tool id="com.ti.ccstudio.buildDefinitions.C6000_7.4.exe.linkerDebug.841646834" name="C6000 Linker" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.exe.linkerDebug">
<option id="com.ti.ccstudio.buildDefinitions.C6000_7.4.linkerID.OUTPUT_FILE.750430387" name="Specify output file name (--output_file, -o)" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.linkerID.OUTPUT_FILE" value="&quot;${ProjName}.out&quot;" valueType="string"/>
<option id="com.ti.ccstudio.buildDefinitions.C6000_7.4.linkerID.MAP_FILE.218000572" name="Input and output sections listed into &lt;file&gt; (--map_file, -m)" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.linkerID.MAP_FILE" value="&quot;${ProjName}.map&quot;" valueType="string"/>
<option id="com.ti.ccstudio.buildDefinitions.C6000_7.4.linkerID.SEARCH_PATH.238279054" name="Add &lt;dir&gt; to library search path (--search_path, -i)" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.linkerID.SEARCH_PATH" valueType="libPaths">
<listOptionValue builtIn="false" value="&quot;${CG_TOOL_ROOT}/lib&quot;"/>
<listOptionValue builtIn="false" value="&quot;${CG_TOOL_ROOT}/include&quot;"/>
</option>
<option id="com.ti.ccstudio.buildDefinitions.C6000_7.4.linkerID.DISPLAY_ERROR_NUMBER.227046474" name="Emit diagnostic identifier numbers (--display_error_number)" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.linkerID.DISPLAY_ERROR_NUMBER" value="true" valueType="boolean"/>
<option id="com.ti.ccstudio.buildDefinitions.C6000_7.4.linkerID.DIAG_WRAP.346350764" name="Wrap diagnostic messages (--diag_wrap)" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.linkerID.DIAG_WRAP" value="com.ti.ccstudio.buildDefinitions.C6000_7.4.linkerID.DIAG_WRAP.off" valueType="enumerated"/>
<option id="com.ti.ccstudio.buildDefinitions.C6000_7.4.linkerID.XML_LINK_INFO.1193419725" name="Detailed link information data-base into &lt;file&gt; (--xml_link_info, -xml_link_info)" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.linkerID.XML_LINK_INFO" value="&quot;${ProjName}_linkInfo.xml&quot;" valueType="string"/>
<option id="com.ti.ccstudio.buildDefinitions.C6000_7.4.linkerID.LIBRARY.1518962461" name="Include library file or command file as input (--library, -l)" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.linkerID.LIBRARY" valueType="libs">
<listOptionValue builtIn="false" value="&quot;libc.a&quot;"/>
</option>
<inputType id="com.ti.ccstudio.buildDefinitions.C6000_7.4.exeLinker.inputType__CMD_SRCS.1470105918" name="Linker Command Files" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.exeLinker.inputType__CMD_SRCS"/>
<inputType id="com.ti.ccstudio.buildDefinitions.C6000_7.4.exeLinker.inputType__CMD2_SRCS.1245090026" name="Linker Command Files" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.exeLinker.inputType__CMD2_SRCS"/>
<inputType id="com.ti.ccstudio.buildDefinitions.C6000_7.4.exeLinker.inputType__GEN_CMDS.883960847" name="Generated Linker Command Files" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.exeLinker.inputType__GEN_CMDS"/>
</tool>
<tool id="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.52818659" name="XDCtools" superClass="com.ti.rtsc.buildDefinitions.XDC_3.16.tool">
<option id="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.XDC_PATH.543674395" name="Package repositories (--xdcpath)" superClass="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.XDC_PATH" valueType="stringList">
<listOptionValue builtIn="false" value="${VSKY_LIBDSP_ROOT}\packages"/>
<listOptionValue builtIn="false" value="${CTOOLSLIB_INSTALL_DIR}/packages/ti"/>
<listOptionValue builtIn="false" value="${TI_MAS_DSPLIB_C66X_INSTALL_DIR}/packages"/>
<listOptionValue builtIn="false" value="${EDMA3_LLD_INSTALL_DIR}/packages"/>
<listOptionValue builtIn="false" value="${TI_IMGLIB_C66X_INSTALL_DIR}/packages"/>
<listOptionValue builtIn="false" value="${IPC_CG_ROOT}/packages"/>
<listOptionValue builtIn="false" value="${TI_MATHLIB_C66X_INSTALL_DIR}/packages"/>
<listOptionValue builtIn="false" value="${TI_MCSDK_INSTALL_DIR}/demos"/>
<listOptionValue builtIn="false" value="${TI_PDK_C6678_INSTALL_DIR}/packages"/>
<listOptionValue builtIn="false" value="${NDK_INSTALL_DIR}/packages"/>
<listOptionValue builtIn="false" value="${COM_TI_BIOSMCSDK_OPENEM_INSTALL_DIR}/packages"/>
<listOptionValue builtIn="false" value="${COM_TI_RTSC_OMP_INSTALL_DIR}/packages"/>
<listOptionValue builtIn="false" value="${BIOS_CG_ROOT}/packages"/>
<listOptionValue builtIn="false" value="${COM_TI_UIA_INSTALL_DIR}/packages"/>
<listOptionValue builtIn="false" value="${XDAIS_CG_ROOT}/packages"/>
<listOptionValue builtIn="false" value="${XDAIS_CG_ROOT}/examples"/>
<listOptionValue builtIn="false" value="${TARGET_CONTENT_BASE}"/>
</option>
<option id="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.TARGET.656510846" name="Target (-t)" superClass="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.TARGET" value="ti.targets.elf.C66" valueType="string"/>
<option id="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.PLATFORM.711573940" name="Platform (-p)" superClass="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.PLATFORM" value="vsky.platforms.simple" valueType="string"/>
<option id="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.PLATFORM_RAW.469360293" name="Platform (-p)" superClass="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.PLATFORM_RAW" value="vsky.platforms.simple" valueType="string"/>
<option id="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.BUILD_PROFILE.845153020" name="Build-profile (-r)" superClass="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.BUILD_PROFILE" value="release" valueType="string"/>
<option id="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.CODEGEN_TOOL_DIR.983218953" name="Compiler tools directory (-c)" superClass="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.CODEGEN_TOOL_DIR" value="&quot;${CG_TOOL_ROOT}&quot;" valueType="string"/>
</tool>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
<cconfiguration id="com.ti.ccstudio.buildDefinitions.C6000.Release.34890251">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.ti.ccstudio.buildDefinitions.C6000.Release.34890251" moduleId="org.eclipse.cdt.core.settings" name="Release">
<externalSettings/>
<extensions>
<extension id="com.ti.ccstudio.binaryparser.CoffParser" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.ti.ccstudio.errorparser.CoffErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="com.ti.ccstudio.errorparser.LinkErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="com.ti.ccstudio.errorparser.AsmErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.rtsc.xdctools.parsers.ErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactExtension="out" artifactName="${ProjName}" buildProperties="" cleanCommand="${CG_CLEAN_CMD}" description="" errorParsers="org.eclipse.rtsc.xdctools.parsers.ErrorParser;com.ti.ccstudio.errorparser.CoffErrorParser;com.ti.ccstudio.errorparser.LinkErrorParser;com.ti.ccstudio.errorparser.AsmErrorParser" id="com.ti.ccstudio.buildDefinitions.C6000.Release.34890251" name="Release" parent="com.ti.ccstudio.buildDefinitions.C6000.Release">
<folderInfo id="com.ti.ccstudio.buildDefinitions.C6000.Release.34890251." name="/" resourcePath="">
<toolChain id="com.ti.ccstudio.buildDefinitions.C6000_7.4.exe.ReleaseToolchain.1092772910" name="TI Build Tools" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.exe.ReleaseToolchain" targetTool="com.ti.ccstudio.buildDefinitions.C6000_7.4.exe.linkerRelease.1458186395">
<option id="com.ti.ccstudio.buildDefinitions.core.OPT_TAGS.850401468" superClass="com.ti.ccstudio.buildDefinitions.core.OPT_TAGS" valueType="stringList">
<listOptionValue builtIn="false" value="DEVICE_CONFIGURATION_ID=com.ti.ccstudio.deviceModel.C6000.GenericC62xxDevice"/>
<listOptionValue builtIn="false" value="DEVICE_ENDIANNESS=little"/>
<listOptionValue builtIn="false" value="OUTPUT_FORMAT=COFF"/>
<listOptionValue builtIn="false" value="CCS_MBS_VERSION=5.5.0"/>
<listOptionValue builtIn="false" value="RUNTIME_SUPPORT_LIBRARY=libc.a"/>
<listOptionValue builtIn="false" value="RTSC_MBS_VERSION=2.2.0"/>
<listOptionValue builtIn="false" value="XDC_VERSION=3.25.3.72"/>
<listOptionValue builtIn="false" value="RTSC_PRODUCTS=ctoolslib:1.0.0.02;ti.mas.dsplib.c66x:3.1.0.0;com.ti.sdo.edma3:2.11.5;ti.imglib.c66x:3.1.1.0;com.ti.rtsc.IPC:1.24.3.32;ti.mathlib.c66x:3.0.1.1;com.ti.biosmcsdk.mcsdk:2.1.2.6;com.ti.biosmcsdk.pdk.C6657:1.1.2.6;com.ti.biosmcsdk.pdk.C6678L:1.1.2.6;com.ti.rtsc.NDK:2.21.2.43;com.ti.biosmcsdk.openem:1.0.0.2;com.ti.rtsc.OMP:1.1.3.02;com.ti.rtsc.SYSBIOS:6.35.4.50;com.ti.uia:1.3.1.08;com.ti.rtsc.XDAIS:7.21.1.07;"/>
<listOptionValue builtIn="false" value="OUTPUT_TYPE=rtscApplication:executable"/>
</option>
<option id="com.ti.ccstudio.buildDefinitions.core.OPT_CODEGEN_VERSION.197357223" name="Compiler version" superClass="com.ti.ccstudio.buildDefinitions.core.OPT_CODEGEN_VERSION" value="7.4.20" valueType="string"/>
<targetPlatform id="com.ti.ccstudio.buildDefinitions.C6000_7.4.exe.targetPlatformRelease.1314977289" name="Platform" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.exe.targetPlatformRelease"/>
<builder buildPath="${BuildDirectory}" id="com.ti.ccstudio.buildDefinitions.C6000_7.4.exe.builderRelease.305506631" keepEnvironmentInBuildfile="false" name="GNU Make" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.exe.builderRelease"/>
<tool id="com.ti.ccstudio.buildDefinitions.C6000_7.4.exe.compilerRelease.589480324" name="C6000 Compiler" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.exe.compilerRelease">
<option id="com.ti.ccstudio.buildDefinitions.C6000_7.4.compilerID.SILICON_VERSION.534299383" name="Target processor version (--silicon_version, -mv)" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.compilerID.SILICON_VERSION" value="6200" valueType="string"/>
<option id="com.ti.ccstudio.buildDefinitions.C6000_7.4.compilerID.DIAG_WARNING.1832870983" name="Treat diagnostic &lt;id&gt; as warning (--diag_warning, -pdsw)" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.compilerID.DIAG_WARNING" valueType="stringList">
<listOptionValue builtIn="false" value="225"/>
</option>
<option id="com.ti.ccstudio.buildDefinitions.C6000_7.4.compilerID.DISPLAY_ERROR_NUMBER.150825442" name="Emit diagnostic identifier numbers (--display_error_number, -pden)" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.compilerID.DISPLAY_ERROR_NUMBER" value="true" valueType="boolean"/>
<option id="com.ti.ccstudio.buildDefinitions.C6000_7.4.compilerID.DIAG_WRAP.170930405" name="Wrap diagnostic messages (--diag_wrap)" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.compilerID.DIAG_WRAP" value="com.ti.ccstudio.buildDefinitions.C6000_7.4.compilerID.DIAG_WRAP.off" valueType="enumerated"/>
<option id="com.ti.ccstudio.buildDefinitions.C6000_7.4.compilerID.INCLUDE_PATH.491514544" name="Add dir to #include search path (--include_path, -I)" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.compilerID.INCLUDE_PATH" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${CG_TOOL_ROOT}/include&quot;"/>
</option>
<option id="com.ti.ccstudio.buildDefinitions.C6000_7.4.compilerID.ABI.1807307170" name="Application binary interface (coffabi, eabi) [See 'General' page to edit] (--abi)" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.compilerID.ABI" value="com.ti.ccstudio.buildDefinitions.C6000_7.4.compilerID.ABI.coffabi" valueType="enumerated"/>
<inputType id="com.ti.ccstudio.buildDefinitions.C6000_7.4.compiler.inputType__C_SRCS.1535605445" name="C Sources" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.compiler.inputType__C_SRCS"/>
<inputType id="com.ti.ccstudio.buildDefinitions.C6000_7.4.compiler.inputType__CPP_SRCS.1413541345" name="C++ Sources" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.compiler.inputType__CPP_SRCS"/>
<inputType id="com.ti.ccstudio.buildDefinitions.C6000_7.4.compiler.inputType__ASM_SRCS.256319544" name="Assembly Sources" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.compiler.inputType__ASM_SRCS"/>
<inputType id="com.ti.ccstudio.buildDefinitions.C6000_7.4.compiler.inputType__ASM2_SRCS.1818742655" name="Assembly Sources" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.compiler.inputType__ASM2_SRCS"/>
</tool>
<tool id="com.ti.ccstudio.buildDefinitions.C6000_7.4.exe.linkerRelease.1458186395" name="C6000 Linker" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.exe.linkerRelease">
<option id="com.ti.ccstudio.buildDefinitions.C6000_7.4.linkerID.OUTPUT_FILE.1698097246" name="Specify output file name (--output_file, -o)" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.linkerID.OUTPUT_FILE" value="&quot;${ProjName}.out&quot;" valueType="string"/>
<option id="com.ti.ccstudio.buildDefinitions.C6000_7.4.linkerID.MAP_FILE.661939379" name="Input and output sections listed into &lt;file&gt; (--map_file, -m)" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.linkerID.MAP_FILE" value="&quot;${ProjName}.map&quot;" valueType="string"/>
<option id="com.ti.ccstudio.buildDefinitions.C6000_7.4.linkerID.XML_LINK_INFO.429153459" name="Detailed link information data-base into &lt;file&gt; (--xml_link_info, -xml_link_info)" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.linkerID.XML_LINK_INFO" value="&quot;${ProjName}_linkInfo.xml&quot;" valueType="string"/>
<option id="com.ti.ccstudio.buildDefinitions.C6000_7.4.linkerID.DISPLAY_ERROR_NUMBER.705205600" name="Emit diagnostic identifier numbers (--display_error_number)" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.linkerID.DISPLAY_ERROR_NUMBER" value="true" valueType="boolean"/>
<option id="com.ti.ccstudio.buildDefinitions.C6000_7.4.linkerID.DIAG_WRAP.1925920702" name="Wrap diagnostic messages (--diag_wrap)" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.linkerID.DIAG_WRAP" value="com.ti.ccstudio.buildDefinitions.C6000_7.4.linkerID.DIAG_WRAP.off" valueType="enumerated"/>
<option id="com.ti.ccstudio.buildDefinitions.C6000_7.4.linkerID.SEARCH_PATH.680650633" name="Add &lt;dir&gt; to library search path (--search_path, -i)" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.linkerID.SEARCH_PATH" valueType="libPaths">
<listOptionValue builtIn="false" value="&quot;${CG_TOOL_ROOT}/lib&quot;"/>
<listOptionValue builtIn="false" value="&quot;${CG_TOOL_ROOT}/include&quot;"/>
</option>
<option id="com.ti.ccstudio.buildDefinitions.C6000_7.4.linkerID.LIBRARY.1995435203" name="Include library file or command file as input (--library, -l)" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.linkerID.LIBRARY" valueType="libs">
<listOptionValue builtIn="false" value="&quot;libc.a&quot;"/>
</option>
<inputType id="com.ti.ccstudio.buildDefinitions.C6000_7.4.exeLinker.inputType__CMD_SRCS.1932415468" name="Linker Command Files" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.exeLinker.inputType__CMD_SRCS"/>
<inputType id="com.ti.ccstudio.buildDefinitions.C6000_7.4.exeLinker.inputType__CMD2_SRCS.1908966314" name="Linker Command Files" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.exeLinker.inputType__CMD2_SRCS"/>
<inputType id="com.ti.ccstudio.buildDefinitions.C6000_7.4.exeLinker.inputType__GEN_CMDS.1731740952" name="Generated Linker Command Files" superClass="com.ti.ccstudio.buildDefinitions.C6000_7.4.exeLinker.inputType__GEN_CMDS"/>
</tool>
<tool id="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.352690820" name="XDCtools" superClass="com.ti.rtsc.buildDefinitions.XDC_3.16.tool">
<option id="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.CODEGEN_TOOL_DIR.133563419" name="Compiler tools directory (-c)" superClass="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.CODEGEN_TOOL_DIR" value="&quot;${CG_TOOL_ROOT}&quot;" valueType="string"/>
<option id="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.TARGET.1841037940" name="Target (-t)" superClass="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.TARGET" value="ti.targets.elf.C66" valueType="string"/>
<option id="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.PLATFORM.1356740087" name="Platform (-p)" superClass="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.PLATFORM" value="vsky.platforms.simple" valueType="string"/>
<option id="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.PLATFORM_RAW.319080937" name="Platform (-p)" superClass="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.PLATFORM_RAW" value="vsky.platforms.simple" valueType="string"/>
<option id="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.BUILD_PROFILE.178965226" name="Build-profile (-r)" superClass="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.BUILD_PROFILE" value="release" valueType="string"/>
<option id="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.XDC_PATH.1314558459" name="Package repositories (--xdcpath)" superClass="com.ti.rtsc.buildDefinitions.XDC_3.16.tool.XDC_PATH" valueType="stringList">
<listOptionValue builtIn="false" value="${CTOOLSLIB_INSTALL_DIR}/packages/ti"/>
<listOptionValue builtIn="false" value="${TI_MAS_DSPLIB_C66X_INSTALL_DIR}/packages"/>
<listOptionValue builtIn="false" value="${EDMA3_LLD_INSTALL_DIR}/packages"/>
<listOptionValue builtIn="false" value="${TI_IMGLIB_C66X_INSTALL_DIR}/packages"/>
<listOptionValue builtIn="false" value="${IPC_CG_ROOT}/packages"/>
<listOptionValue builtIn="false" value="${TI_MATHLIB_C66X_INSTALL_DIR}/packages"/>
<listOptionValue builtIn="false" value="${TI_MCSDK_INSTALL_DIR}/demos"/>
<listOptionValue builtIn="false" value="${TI_PDK_C6657_INSTALL_DIR}/packages"/>
<listOptionValue builtIn="false" value="${TI_PDK_C6678_INSTALL_DIR}/packages"/>
<listOptionValue builtIn="false" value="${NDK_INSTALL_DIR}/packages"/>
<listOptionValue builtIn="false" value="${COM_TI_BIOSMCSDK_OPENEM_INSTALL_DIR}/packages"/>
<listOptionValue builtIn="false" value="${COM_TI_RTSC_OMP_INSTALL_DIR}/packages"/>
<listOptionValue builtIn="false" value="${BIOS_CG_ROOT}/packages"/>
<listOptionValue builtIn="false" value="${COM_TI_UIA_INSTALL_DIR}/packages"/>
<listOptionValue builtIn="false" value="${XDAIS_CG_ROOT}/packages"/>
<listOptionValue builtIn="false" value="${XDAIS_CG_ROOT}/examples"/>
<listOptionValue builtIn="false" value="E:\dspwork\libdsp\packages"/>
<listOptionValue builtIn="false" value="${TARGET_CONTENT_BASE}"/>
</option>
</tool>
</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="demo01.com.ti.ccstudio.buildDefinitions.C6000.ProjectType.2074444127" name="C6000" projectType="com.ti.ccstudio.buildDefinitions.C6000.ProjectType"/>
</storageModule>
<storageModule moduleId="scannerConfiguration"/>
<storageModule moduleId="org.eclipse.cdt.core.language.mapping">
<project-mappings>
<content-type-mapping configuration="" content-type="org.eclipse.cdt.core.asmSource" language="com.ti.ccstudio.core.TIASMLanguage"/>
<content-type-mapping configuration="" content-type="org.eclipse.cdt.core.cHeader" language="com.ti.ccstudio.core.TIGCCLanguage"/>
<content-type-mapping configuration="" content-type="org.eclipse.cdt.core.cSource" language="com.ti.ccstudio.core.TIGCCLanguage"/>
<content-type-mapping configuration="" content-type="org.eclipse.cdt.core.cxxHeader" language="com.ti.ccstudio.core.TIGPPLanguage"/>
<content-type-mapping configuration="" content-type="org.eclipse.cdt.core.cxxSource" language="com.ti.ccstudio.core.TIGPPLanguage"/>
</project-mappings>
</storageModule>
</cproject>

6
.gitignore

@ -0,0 +1,6 @@
Debug
.settings
.settings
*.out
*.bin
.config

34
.project

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>vs_xc003</name>
<comment></comment>
<projects>
</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>org.eclipse.rtsc.xdctools.buildDefinitions.XDC.xdcNature</nature>
<nature>com.ti.ccstudio.core.ccsNature</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>
<variableList>
<variable>
<name>VSKY_LIBDSP_ROOT</name>
<value>file:/E:/dspwork/libdsp</value>
</variable>
</variableList>
</projectDescription>

166
evmc.cfg

@ -0,0 +1,166 @@
/*
* @file srio.cfg
*
* @brief
* Memory Map and Program intiializations for the HPDSP Utility.
*
*/
/*
* Specify all needed RTSC MOudles and ocnfigure them.
*/
var Memory = xdc.useModule('xdc.runtime.Memory');
var BIOS = xdc.useModule('ti.sysbios.BIOS');
var Task = xdc.useModule('ti.sysbios.knl.Task');
var Queue = xdc.useModule('ti.sysbios.knl.Queue');
var HeapBuf = xdc.useModule('ti.sysbios.heaps.HeapBuf');
var Log = xdc.useModule('xdc.runtime.Log');
var Settings = xdc.useModule('vsky.libdsp.Settings');
var HiSpeed = xdc.useModule('vsky.libdsp.HiSpeed');
/*
* Allow storing of task names. By default if you name a task with a friendly display name it will not be saved
* to conserve RAM. This must be set to true to allow it. We use friendly names on the Task List display.
*/
//Defaults.common$.namedInstance = true;
Task.common$.namedInstance = true;
var Clock = xdc.useModule ('ti.sysbios.knl.Clock');
/*
* Interface with IPC. Depending on the version of BIOS you are using the
* module name may have changed.
*/
/* Use this for pre BIOS 6.30 */
/* var Sem = xdc.useModule ('ti.sysbios.ipc.Semaphore'); */
/* Use this for BIOS 6.30 plus to get the IPC module */
var Sem = xdc.useModule ('ti.sysbios.knl.Semaphore');
var Hwi = xdc.useModule ('ti.sysbios.hal.Hwi');
var CPINTC = xdc.useModule ('ti.sysbios.family.c66.tci66xx.CpIntc');
var Ecm = xdc.useModule ('ti.sysbios.family.c64p.EventCombiner');
/*
* Configure this to turn on the CPU Load Module for BIOS.
*
*/
/*
var Load = xdc.useModule('ti.sysbios.utils.Load');
Load.common$.diags_USER4 = Diags.ALWAYS_ON;
*/
var Diags = xdc.useModule('xdc.runtime.Diags');
/*
* Sets up the exception log so you can read it with ROV in CCS
*/
var LoggerBuf = xdc.useModule('xdc.runtime.LoggerBuf');
var Exc = xdc.useModule('ti.sysbios.family.c64p.Exception');
Exc.common$.logger = LoggerBuf.create();
Exc.enablePrint = true; /* prints exception details to the CCS console */
/*
* Give the Load module it's own LoggerBuf to make sure the
* events are not overwritten.
*/
/* var loggerBufParams = new LoggerBuf.Params();
loggerBufParams.exitFlush = true;
loggerBufParams.numEntries = 64;
Load.common$.logger = LoggerBuf.create(loggerBufParams);
*/
/*
* Use this load to configure NDK 2.2 and above using RTSC. In previous versions of
* the NDK RTSC configuration was not supported and you should comment this out.
*/
var Global = xdc.useModule('ti.ndk.config.Global');
/*
* This allows the heart beat (poll function) to be created but does not generate the stack threads
*
* Look in the cdoc (help files) to see what CfgAddEntry items can be configured. We tell it NOT
* to create any stack threads (services) as we configure those ourselves in our Main Task
* thread hpdspuaStart.
*/
Global.enableCodeGeneration = false;
/* Define a variable to set the MAR mode for MSMCSRAM as all cacheable */
var Cache = xdc.useModule('ti.sysbios.family.c66.Cache');
//Cache.MAR224_255 = 0x0000000f;
var Startup = xdc.useModule('xdc.runtime.Startup');
var System = xdc.useModule('xdc.runtime.System');
/*
* Create a Heap.
*/
var HeapMem = xdc.useModule('ti.sysbios.heaps.HeapMem');
var heapMemParams = new HeapMem.Params();
heapMemParams.size = 0x8000000;
heapMemParams.sectionName = "systemHeap";
Program.global.heap0 = HeapMem.create(heapMemParams);
/* This is the default memory heap. */
Memory.defaultHeapInstance = Program.global.heap0;
Program.sectMap["systemHeap"] = "DDR3";
/* Required if using System_printf to output on the console */
SysStd = xdc.useModule('xdc.runtime.SysStd');
System.SupportProxy = SysStd;
/*
* Define hooks and static tasks that will always be running.
*/
/*
* Register an EVM Init handler with BIOS. This will initialize the hardware. BIOS calls before it starts.
*
* If yuo are debugging with CCS, then this function will execute as CCS loads it if the option in your
* Target Configuraiton file (.ccxml) has the option set to execute all code before Main. That is the
* default.
*/
//Startup.lastFxns.$add('&board_init');
/*
* Create the stack Thread Task for our application.
*/
//var tskNdkStackTest = Task.create("&main_task");
//tskNdkStackTest.stackSize = 0x200000;
//tskNdkStackTest.priority = 0x2;
/*
* Create a Periodic task to handle all NDK polling functions.
* If you are using RTSC configuration with NDK 2.2 and above, this is done by default and
* you do not need to do this.
*/
/* var prdNdkClkParams = new Clock.Params ();
prdNdkClkParams.period = 0x64;
prdNdkClkParams.startFlag = true;
Program.global.clockInst1 = Clock.create("&llTimerTick", 5, prdNdkClkParams);
*/
/*
* If you are using RTSC configuration with NDK 2.2 and above, this is done by default, else
* register hooks so that the stack can track all Task creation
*/
//Task.common$.namedInstance = true;
//Task.addHookSet ({ registerFxn: '&NDK_hookInit', createFxn: '&NDK_hookCreate', });
/* Enable BIOS Task Scheduler */
BIOS.taskEnabled = true;
/*
* Enable Event Groups here and registering of ISR for specific GEM INTC is done
* using EventCombiner_dispatchPlug() and Hwi_eventMap() APIs
*/
Ecm.eventGroupHwiNum[0] = 7;
Ecm.eventGroupHwiNum[1] = 8;
Ecm.eventGroupHwiNum[2] = 9;
Ecm.eventGroupHwiNum[3] = 10;
Settings.hyperlink_clock = 156250000;
Settings.emac_port = 1;
Settings.emac_address = "80:00:00:03:12:2C";
Settings.sgmii_clock = 156250000;

670
src/ad9361.c

@ -0,0 +1,670 @@
/*
* ad9361.c
*
* Created on: 2019-7-16
* Author: Administrator
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <vsky/libdsp/inc/tsc.h>
#include <vslib/vbios.h>
#include "gspi.h"
#include "ad9361_lib/platform.h"
#include "ad9361_lib/ad9361_api.h"
#include "ad9361_lib/dac_core.h"
#include "ad9361_lib/adc_core.h"
#include "ad9361.h"
#include "axi1.h"
#if 0
static gspi_t _ad9361 = NULL;
static int __gspi_ad9361_init(void )
{
spi_dev_cfg_s format = {
.mode = SPI_CLK_MODE_0,
.speed = 5000000,
.bits = 8,
.endian = 0,
.t2delay = 0,
};
_ad9361 = gspi_open(GSPI_CS_AD9361, &format);
return 0;
}
uint8_t ad9361_read(uint16_t reg)
{
int elms = 0;
unsigned char buf[3];
if (!_ad9361)
__gspi_ad9361_init();
buf[0] = 0x03 & (reg >> 8);
buf[1] = reg & 0xFF;
elms = gspi_xfer(_ad9361, buf, 0, 2, &buf[2], 2, 1);
if (elms != sizeof buf) {
printf("error: ad9361 reg 0x%x read fail\r\n", reg);
return 0;
}
printf("ad9361 read reg:0x%04x, val: 0x%x\r\n", reg, buf[2]);
return buf[2] & 0xff;
}
int ad9361_write(uint16_t reg, uint8_t val)
{
int elms = 0;
unsigned char buf[3];
if (!_ad9361)
__gspi_ad9361_init();
buf[0] = 0x80 | ((reg >> 8) & 0x03);
buf[1] = reg & 0xff;
buf[2] = val & 0xff;
elms = gspi_xfer(_ad9361, buf, 0, 3, NULL, 0, 0);
if (elms != sizeof buf) {
printf("error: ad9361 reg 0x%x write fail\r\n", reg);
return -1;
}
printf("ad9361 write reg:0x%04x, val: 0x%x\r\n", reg, val);
return 0;
}
#endif //
static int __ad9361_spi_xfer(void *dev, const unsigned char *txbuf, unsigned n_tx, unsigned char *rxbuf, unsigned n_rx)
{
gspi_t gs = (gspi_t)dev;
gspi_xfer(gs, txbuf, 0, n_tx, rxbuf, n_tx, n_rx);
return 0;
}
static void __ad9361_udelay(unsigned long us)
{
tsc_delay(us);
}
static void __ad9361_axi_write(uint32_t addr, uint32_t data)
{
axi1_write(addr, data);
}
static uint32_t __ad9361_axi_read(uint32_t addr)
{
return axi1_read(addr);
}
static void __ad9361_reset(void)
{
axi1_write(0x1010, 0x0);
tsc_delay(100 * 1000);
axi1_write(0x1010, 0x1);
tsc_delay(100 * 1000);
printf("ad9361 reset success \r\n");
}
static AD9361_InitParam default_init_param = {
/* Device selection */
ID_AD9361, // dev_sel
/* Identification number */
0, //id_no
/* Reference Clock */
40000000UL, //reference_clk_rate
/* Base Configuration */
1, //two_rx_two_tx_mode_enable *** adi,2rx-2tx-mode-enable
1, //one_rx_one_tx_mode_use_rx_num *** adi,1rx-1tx-mode-use-rx-num
1, //one_rx_one_tx_mode_use_tx_num *** adi,1rx-1tx-mode-use-tx-num
//0, //frequency_division_duplex_mode_enable *** adi,frequency-division-duplex-mode-enable
1, //frequency_division_duplex_mode_enable *** adi,frequency-division-duplex-mode-enable
0, //frequency_division_duplex_independent_mode_enable *** adi,frequency-division-duplex-independent-mode-enable
0, //tdd_use_dual_synth_mode_enable *** adi,tdd-use-dual-synth-mode-enable
0, //tdd_skip_vco_cal_enable *** adi,tdd-skip-vco-cal-enable
0, //tx_fastlock_delay_ns *** adi,tx-fastlock-delay-ns
0, //rx_fastlock_delay_ns *** adi,rx-fastlock-delay-ns
0, //rx_fastlock_pincontrol_enable *** adi,rx-fastlock-pincontrol-enable
0, //tx_fastlock_pincontrol_enable *** adi,tx-fastlock-pincontrol-enable
0, //external_rx_lo_enable *** adi,external-rx-lo-enable
0, //external_tx_lo_enable *** adi,external-tx-lo-enable
5, //dc_offset_tracking_update_event_mask *** adi,dc-offset-tracking-update-event-mask
6, //dc_offset_attenuation_high_range *** adi,dc-offset-attenuation-high-range
5, //dc_offset_attenuation_low_range *** adi,dc-offset-attenuation-low-range
0x28, //dc_offset_count_high_range *** adi,dc-offset-count-high-range
0x32, //dc_offset_count_low_range *** adi,dc-offset-count-low-range
0, //split_gain_table_mode_enable *** adi,split-gain-table-mode-enable
MAX_SYNTH_FREF, //trx_synthesizer_target_fref_overwrite_hz *** adi,trx-synthesizer-target-fref-overwrite-hz
0, // qec_tracking_slow_mode_enable *** adi,qec-tracking-slow-mode-enable
/* ENSM Control */
0, //ensm_enable_pin_pulse_mode_enable *** adi,ensm-enable-pin-pulse-mode-enable
0, //ensm_enable_txnrx_control_enable *** adi,ensm-enable-txnrx-control-enable
/* LO Control */
//1200000000UL, //rx_synthesizer_frequency_hz *** adi,rx-synthesizer-frequency-hz
//1200000000UL, //tx_synthesizer_frequency_hz *** adi,tx-synthesizer-frequency-hz
2250000000UL, //rx_synthesizer_frequency_hz *** adi,rx-synthesizer-frequency-hz
2250000000UL, //tx_synthesizer_frequency_hz *** adi,tx-synthesizer-frequency-hz
/* Rate & BW Control */
{983040000, 245760000, 122880000, 61440000, 30720000, 30720000},//uint32_t rx_path_clock_frequencies[6] *** adi,rx-path-clock-frequencies
{983040000, 122880000, 122880000, 61440000, 30720000, 30720000},//uint32_t tx_path_clock_frequencies[6] *** adi,tx-path-clock-frequencies
//{1280000000, 80000000, 40000000, 20000000, 10000000, 10000000},//uint32_t rx_path_clock_frequencies[6] *** adi,rx-path-clock-frequencies
//{1280000000, 80000000, 40000000, 20000000, 10000000, 10000000},//uint32_t tx_path_clock_frequencies[6] *** adi,tx-path-clock-frequencies
//18000000,//rf_rx_bandwidth_hz *** adi,rf-rx-bandwidth-hz
//18000000,//rf_tx_bandwidth_hz *** adi,rf-tx-bandwidth-hz
56000000,//rf_rx_bandwidth_hz *** adi,rf-rx-bandwidth-hz
56000000,//rf_tx_bandwidth_hz *** adi,rf-tx-bandwidth-hz
/* RF Port Control */
0, //rx_rf_port_input_select *** adi,rx-rf-port-input-select
0, //tx_rf_port_input_select *** adi,tx-rf-port-input-select
/* TX Attenuation Control */
0, //tx_attenuation_mdB *** adi,tx-attenuation-mdB
0, //update_tx_gain_in_alert_enable *** adi,update-tx-gain-in-alert-enable
/* Reference Clock Control */
0, //xo_disable_use_ext_refclk_enable *** adi,xo-disable-use-ext-refclk-enable
{8, 5920}, //dcxo_coarse_and_fine_tune[2] *** adi,dcxo-coarse-and-fine-tune
CLKOUT_DISABLE, //clk_output_mode_select *** adi,clk-output-mode-select
//ADC_CLK_DIV_4, //clk_output_mode_select *** adi,clk-output-mode-select
/* Gain Control */
2, //gc_rx1_mode *** adi,gc-rx1-mode
2, //gc_rx2_mode *** adi,gc-rx2-mode
58, //gc_adc_large_overload_thresh *** adi,gc-adc-large-overload-thresh
4, //gc_adc_ovr_sample_size *** adi,gc-adc-ovr-sample-size
47, //gc_adc_small_overload_thresh *** adi,gc-adc-small-overload-thresh
8192, //gc_dec_pow_measurement_duration *** adi,gc-dec-pow-measurement-duration
0, //gc_dig_gain_enable *** adi,gc-dig-gain-enable
800, //gc_lmt_overload_high_thresh *** adi,gc-lmt-overload-high-thresh
704, //gc_lmt_overload_low_thresh *** adi,gc-lmt-overload-low-thresh
24, //gc_low_power_thresh *** adi,gc-low-power-thresh
15, //gc_max_dig_gain *** adi,gc-max-dig-gain
/* Gain MGC Control */
2, //mgc_dec_gain_step *** adi,mgc-dec-gain-step
2, //mgc_inc_gain_step *** adi,mgc-inc-gain-step
0, //mgc_rx1_ctrl_inp_enable *** adi,mgc-rx1-ctrl-inp-enable
0, //mgc_rx2_ctrl_inp_enable *** adi,mgc-rx2-ctrl-inp-enable
0, //mgc_split_table_ctrl_inp_gain_mode *** adi,mgc-split-table-ctrl-inp-gain-mode
/* Gain AGC Control */
10, //agc_adc_large_overload_exceed_counter *** adi,agc-adc-large-overload-exceed-counter
2, //agc_adc_large_overload_inc_steps *** adi,agc-adc-large-overload-inc-steps
0, //agc_adc_lmt_small_overload_prevent_gain_inc_enable *** adi,agc-adc-lmt-small-overload-prevent-gain-inc-enable
10, //agc_adc_small_overload_exceed_counter *** adi,agc-adc-small-overload-exceed-counter
4, //agc_dig_gain_step_size *** adi,agc-dig-gain-step-size
3, //agc_dig_saturation_exceed_counter *** adi,agc-dig-saturation-exceed-counter
1000, //agc_gain_update_interval_us *** adi,agc-gain-update-interval-us
0, //agc_immed_gain_change_if_large_adc_overload_enable *** adi,agc-immed-gain-change-if-large-adc-overload-enable
0, //agc_immed_gain_change_if_large_lmt_overload_enable *** adi,agc-immed-gain-change-if-large-lmt-overload-enable
10, //agc_inner_thresh_high *** adi,agc-inner-thresh-high
1, //agc_inner_thresh_high_dec_steps *** adi,agc-inner-thresh-high-dec-steps
12, //agc_inner_thresh_low *** adi,agc-inner-thresh-low
1, //agc_inner_thresh_low_inc_steps *** adi,agc-inner-thresh-low-inc-steps
10, //agc_lmt_overload_large_exceed_counter *** adi,agc-lmt-overload-large-exceed-counter
2, //agc_lmt_overload_large_inc_steps *** adi,agc-lmt-overload-large-inc-steps
10, //agc_lmt_overload_small_exceed_counter *** adi,agc-lmt-overload-small-exceed-counter
5, //agc_outer_thresh_high *** adi,agc-outer-thresh-high
2, //agc_outer_thresh_high_dec_steps *** adi,agc-outer-thresh-high-dec-steps
18, //agc_outer_thresh_low *** adi,agc-outer-thresh-low
2, //agc_outer_thresh_low_inc_steps *** adi,agc-outer-thresh-low-inc-steps
1, //agc_attack_delay_extra_margin_us; *** adi,agc-attack-delay-extra-margin-us
0, //agc_sync_for_gain_counter_enable *** adi,agc-sync-for-gain-counter-enable
/* Fast AGC */
64, //fagc_dec_pow_measuremnt_duration *** adi,fagc-dec-pow-measurement-duration
260, //fagc_state_wait_time_ns *** adi,fagc-state-wait-time-ns
/* Fast AGC - Low Power */
0, //fagc_allow_agc_gain_increase *** adi,fagc-allow-agc-gain-increase-enable
5, //fagc_lp_thresh_increment_time *** adi,fagc-lp-thresh-increment-time
1, //fagc_lp_thresh_increment_steps *** adi,fagc-lp-thresh-increment-steps
/* Fast AGC - Lock Level */
10, //fagc_lock_level *** adi,fagc-lock-level
1, //fagc_lock_level_lmt_gain_increase_en *** adi,fagc-lock-level-lmt-gain-increase-enable
5, //fagc_lock_level_gain_increase_upper_limit *** adi,fagc-lock-level-gain-increase-upper-limit
/* Fast AGC - Peak Detectors and Final Settling */
1, //fagc_lpf_final_settling_steps *** adi,fagc-lpf-final-settling-steps
1, //fagc_lmt_final_settling_steps *** adi,fagc-lmt-final-settling-steps
3, //fagc_final_overrange_count *** adi,fagc-final-overrange-count
/* Fast AGC - Final Power Test */
0, //fagc_gain_increase_after_gain_lock_en *** adi,fagc-gain-increase-after-gain-lock-enable
/* Fast AGC - Unlocking the Gain */
0, //fagc_gain_index_type_after_exit_rx_mode *** adi,fagc-gain-index-type-after-exit-rx-mode
1, //fagc_use_last_lock_level_for_set_gain_en *** adi,fagc-use-last-lock-level-for-set-gain-enable
1, //fagc_rst_gla_stronger_sig_thresh_exceeded_en *** adi,fagc-rst-gla-stronger-sig-thresh-exceeded-enable
5, //fagc_optimized_gain_offset *** adi,fagc-optimized-gain-offset
10, //fagc_rst_gla_stronger_sig_thresh_above_ll *** adi,fagc-rst-gla-stronger-sig-thresh-above-ll
1, //fagc_rst_gla_engergy_lost_sig_thresh_exceeded_en *** adi,fagc-rst-gla-engergy-lost-sig-thresh-exceeded-enable
1, //fagc_rst_gla_engergy_lost_goto_optim_gain_en *** adi,fagc-rst-gla-engergy-lost-goto-optim-gain-enable
10, //fagc_rst_gla_engergy_lost_sig_thresh_below_ll *** adi,fagc-rst-gla-engergy-lost-sig-thresh-below-ll
8, //fagc_energy_lost_stronger_sig_gain_lock_exit_cnt *** adi,fagc-energy-lost-stronger-sig-gain-lock-exit-cnt
1, //fagc_rst_gla_large_adc_overload_en *** adi,fagc-rst-gla-large-adc-overload-enable
1, //fagc_rst_gla_large_lmt_overload_en *** adi,fagc-rst-gla-large-lmt-overload-enable
0, //fagc_rst_gla_en_agc_pulled_high_en *** adi,fagc-rst-gla-en-agc-pulled-high-enable
0, //fagc_rst_gla_if_en_agc_pulled_high_mode *** adi,fagc-rst-gla-if-en-agc-pulled-high-mode
64, //fagc_power_measurement_duration_in_state5 *** adi,fagc-power-measurement-duration-in-state5
/* RSSI Control */
1, //rssi_delay *** adi,rssi-delay
1000, //rssi_duration *** adi,rssi-duration
3, //rssi_restart_mode *** adi,rssi-restart-mode
0, //rssi_unit_is_rx_samples_enable *** adi,rssi-unit-is-rx-samples-enable
1, //rssi_wait *** adi,rssi-wait
/* Aux ADC Control */
256, //aux_adc_decimation *** adi,aux-adc-decimation
40000000UL, //aux_adc_rate *** adi,aux-adc-rate
/* AuxDAC Control */
1, //aux_dac_manual_mode_enable *** adi,aux-dac-manual-mode-enable
0, //aux_dac1_default_value_mV *** adi,aux-dac1-default-value-mV
0, //aux_dac1_active_in_rx_enable *** adi,aux-dac1-active-in-rx-enable
0, //aux_dac1_active_in_tx_enable *** adi,aux-dac1-active-in-tx-enable
0, //aux_dac1_active_in_alert_enable *** adi,aux-dac1-active-in-alert-enable
0, //aux_dac1_rx_delay_us *** adi,aux-dac1-rx-delay-us
0, //aux_dac1_tx_delay_us *** adi,aux-dac1-tx-delay-us
0, //aux_dac2_default_value_mV *** adi,aux-dac2-default-value-mV
0, //aux_dac2_active_in_rx_enable *** adi,aux-dac2-active-in-rx-enable
0, //aux_dac2_active_in_tx_enable *** adi,aux-dac2-active-in-tx-enable
0, //aux_dac2_active_in_alert_enable *** adi,aux-dac2-active-in-alert-enable
0, //aux_dac2_rx_delay_us *** adi,aux-dac2-rx-delay-us
0, //aux_dac2_tx_delay_us *** adi,aux-dac2-tx-delay-us
/* Temperature Sensor Control */
256, //temp_sense_decimation *** adi,temp-sense-decimation
1000, //temp_sense_measurement_interval_ms *** adi,temp-sense-measurement-interval-ms
0xCE, //temp_sense_offset_signed *** adi,temp-sense-offset-signed
1, //temp_sense_periodic_measurement_enable *** adi,temp-sense-periodic-measurement-enable
/* Control Out Setup */
0xFF, //ctrl_outs_enable_mask *** adi,ctrl-outs-enable-mask
0, //ctrl_outs_index *** adi,ctrl-outs-index
/* External LNA Control */
0, //elna_settling_delay_ns *** adi,elna-settling-delay-ns
0, //elna_gain_mdB *** adi,elna-gain-mdB
0, //elna_bypass_loss_mdB *** adi,elna-bypass-loss-mdB
0, //elna_rx1_gpo0_control_enable *** adi,elna-rx1-gpo0-control-enable
0, //elna_rx2_gpo1_control_enable *** adi,elna-rx2-gpo1-control-enable
0, //elna_gaintable_all_index_enable *** adi,elna-gaintable-all-index-enable
/* Digital Interface Control */
0, //digital_interface_tune_skip_mode *** adi,digital-interface-tune-skip-mode
0, //digital_interface_tune_fir_disable *** adi,digital-interface-tune-fir-disable
1, //pp_tx_swap_enable *** adi,pp-tx-swap-enable
1, //pp_rx_swap_enable *** adi,pp-rx-swap-enable
0, //tx_channel_swap_enable *** adi,tx-channel-swap-enable
0, //rx_channel_swap_enable *** adi,rx-channel-swap-enable
1, //rx_frame_pulse_mode_enable *** adi,rx-frame-pulse-mode-enable
0, //two_t_two_r_timing_enable *** adi,2t2r-timing-enable
0, //invert_data_bus_enable *** adi,invert-data-bus-enable
0, //invert_data_clk_enable *** adi,invert-data-clk-enable
0, //fdd_alt_word_order_enable *** adi,fdd-alt-word-order-enable
0, //invert_rx_frame_enable *** adi,invert-rx-frame-enable
0, //fdd_rx_rate_2tx_enable *** adi,fdd-rx-rate-2tx-enable
0, //swap_ports_enable *** adi,swap-ports-enable
0, //single_data_rate_enable *** adi,single-data-rate-enable
1, //lvds_mode_enable *** adi,lvds-mode-enable
0, //half_duplex_mode_enable *** adi,half-duplex-mode-enable
0, //single_port_mode_enable *** adi,single-port-mode-enable
0, //full_port_enable *** adi,full-port-enable
0, //full_duplex_swap_bits_enable *** adi,full-duplex-swap-bits-enable
0, //delay_rx_data *** adi,delay-rx-data
0, //rx_data_clock_delay *** adi,rx-data-clock-delay
4, //rx_data_delay *** adi,rx-data-delay
7, //tx_fb_clock_delay *** adi,tx-fb-clock-delay
0, //tx_data_delay *** adi,tx-data-delay
150, //lvds_bias_mV *** adi,lvds-bias-mV
1, //lvds_rx_onchip_termination_enable *** adi,lvds-rx-onchip-termination-enable
0, //rx1rx2_phase_inversion_en *** adi,rx1-rx2-phase-inversion-enable
0xFF, //lvds_invert1_control *** adi,lvds-invert1-control
0x0F, //lvds_invert2_control *** adi,lvds-invert2-control
/* GPO Control */
0, //gpo0_inactive_state_high_enable *** adi,gpo0-inactive-state-high-enable
0, //gpo1_inactive_state_high_enable *** adi,gpo1-inactive-state-high-enable
0, //gpo2_inactive_state_high_enable *** adi,gpo2-inactive-state-high-enable
0, //gpo3_inactive_state_high_enable *** adi,gpo3-inactive-state-high-enable
0, //gpo0_slave_rx_enable *** adi,gpo0-slave-rx-enable
0, //gpo0_slave_tx_enable *** adi,gpo0-slave-tx-enable
0, //gpo1_slave_rx_enable *** adi,gpo1-slave-rx-enable
0, //gpo1_slave_tx_enable *** adi,gpo1-slave-tx-enable
0, //gpo2_slave_rx_enable *** adi,gpo2-slave-rx-enable
0, //gpo2_slave_tx_enable *** adi,gpo2-slave-tx-enable
0, //gpo3_slave_rx_enable *** adi,gpo3-slave-rx-enable
0, //gpo3_slave_tx_enable *** adi,gpo3-slave-tx-enable
0, //gpo0_rx_delay_us *** adi,gpo0-rx-delay-us
0, //gpo0_tx_delay_us *** adi,gpo0-tx-delay-us
0, //gpo1_rx_delay_us *** adi,gpo1-rx-delay-us
0, //gpo1_tx_delay_us *** adi,gpo1-tx-delay-us
0, //gpo2_rx_delay_us *** adi,gpo2-rx-delay-us
0, //gpo2_tx_delay_us *** adi,gpo2-tx-delay-us
0, //gpo3_rx_delay_us *** adi,gpo3-rx-delay-us
0, //gpo3_tx_delay_us *** adi,gpo3-tx-delay-us
/* Tx Monitor Control */
37000, //low_high_gain_threshold_mdB *** adi,txmon-low-high-thresh
0, //low_gain_dB *** adi,txmon-low-gain
24, //high_gain_dB *** adi,txmon-high-gain
0, //tx_mon_track_en *** adi,txmon-dc-tracking-enable
0, //one_shot_mode_en *** adi,txmon-one-shot-mode-enable
511, //tx_mon_delay *** adi,txmon-delay
8192, //tx_mon_duration *** adi,txmon-duration
2, //tx1_mon_front_end_gain *** adi,txmon-1-front-end-gain
2, //tx2_mon_front_end_gain *** adi,txmon-2-front-end-gain
48, //tx1_mon_lo_cm *** adi,txmon-1-lo-cm
48, //tx2_mon_lo_cm *** adi,txmon-2-lo-cm
/* GPIO definitions */
-1, //gpio_resetb *** reset-gpios
/* MCS Sync */
-1, //gpio_sync *** sync-gpios
-1, //gpio_cal_sw1 *** cal-sw1-gpios
-1, //gpio_cal_sw2 *** cal-sw2-gpios
/* External LO clocks */
NULL, //(*ad9361_rfpll_ext_recalc_rate)()
NULL, //(*ad9361_rfpll_ext_round_rate)()
NULL //(*ad9361_rfpll_ext_set_rate)()
};
static AD9361_RXFIRConfig rx_fir_config = { // BPF PASSBAND 3/20 fs to 1/4 fs
3, // rx
0, // rx_gain
1, // rx_dec
{-4, -6, -37, 35, 186, 86, -284, -315,
107, 219, -4, 271, 558, -307, -1182, -356,
658, 157, 207, 1648, 790, -2525, -2553, 748,
865, -476, 3737, 6560, -3583, -14731, -5278, 14819,
14819, -5278, -14731, -3583, 6560, 3737, -476, 865,
748, -2553, -2525, 790, 1648, 207, 157, 658,
-356, -1182, -307, 558, 271, -4, 219, 107,
-315, -284, 86, 186, 35, -37, -6, -4,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0}, // rx_coef[128]
64, // rx_coef_size
{0, 0, 0, 0, 0, 0}, //rx_path_clks[6]
0 // rx_bandwidth
};
static AD9361_TXFIRConfig tx_fir_config = { // BPF PASSBAND 3/20 fs to 1/4 fs
3, // tx
-6, // tx_gain
1, // tx_int
{-4, -6, -37, 35, 186, 86, -284, -315,
107, 219, -4, 271, 558, -307, -1182, -356,
658, 157, 207, 1648, 790, -2525, -2553, 748,
865, -476, 3737, 6560, -3583, -14731, -5278, 14819,
14819, -5278, -14731, -3583, 6560, 3737, -476, 865,
748, -2553, -2525, 790, 1648, 207, 157, 658,
-356, -1182, -307, 558, 271, -4, 219, 107,
-315, -284, 86, 186, 35, -37, -6, -4,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0}, // tx_coef[128]
64, // tx_coef_size
{0, 0, 0, 0, 0, 0}, // tx_path_clks[6]
0 // tx_bandwidth
};
static struct ad9361_rf_phy rx_phy;
int ad9361_phy_init(void )
{
gspi_t ad9361;
struct ad9361_platform_func opt = {
.ad9361_spi_xfer = __ad9361_spi_xfer,
.ad9361_udelay = __ad9361_udelay,
.ad9361_axi_write = __ad9361_axi_write,
.ad9361_axi_read = __ad9361_axi_read,
.ad9361_reset = __ad9361_reset,
};
do {
spi_dev_cfg_s format = {
.mode = SPI_CLK_MODE_0,
.speed = 5000000,
.bits = 8,
.endian = 0,
.t2delay = 0,
};
ad9361 = gspi_open(GSPI_CS_AD9361, &format);
} while(0);
opt.dev = ad9361;
ad9361_platform_init(&opt);
//
do {
uint32_t ensm_mode;
default_init_param.dev_sel = ID_AD9361;
default_init_param.gpio_sync = -1;
default_init_param.gpio_cal_sw1 = -1;
default_init_param.gpio_cal_sw2 = -1;
ad9361_init(&rx_phy, NULL, &default_init_param);
ad9361_set_tx_fir_config(&rx_phy, tx_fir_config);
ad9361_set_rx_fir_config(&rx_phy, rx_fir_config);
//ad9361_set_en_state_machine_mode(&rx_phy, ENSM_MODE_ALERT);
//ad9361_get_en_state_machine_mode(&rx_phy, &ensm_mode);
//printf("SPI control - Alert: %s\r\n", ensm_mode == ENSM_MODE_ALERT ? "OK" : "Error");
ad9361_set_en_state_machine_mode(&rx_phy, ENSM_MODE_FDD);
ad9361_get_en_state_machine_mode(&rx_phy, &ensm_mode);
printf("SPI control - RX: %s\n",ensm_mode == ENSM_MODE_FDD ? "OK" : "Error");
tsc_delay(10 * 1000);
//dac_init(&rx_phy, DATA_SEL_LB, 0);
adc_init(&rx_phy);
adc_set_calib_scale(&rx_phy, 0, 1, 0);
adc_set_calib_phase(&rx_phy, 0, 0, 0);
adc_set_calib_scale(&rx_phy, 1, 1, 0);
adc_set_calib_phase(&rx_phy, 1, 0, 0);
adc_set_calib_scale(&rx_phy, 2, 1, 0);
adc_set_calib_phase(&rx_phy, 2, 0, 0);
adc_set_calib_scale(&rx_phy, 3, 1, 0);
adc_set_calib_phase(&rx_phy, 3, 0, 0);
dac_init(&rx_phy, DATA_SEL_DMA, 0);
} while(0);
return 0;
}
void ad9361_status(char ch)
{
uint32_t bandwidth;
uint32_t sampling_freq;
uint64_t lo_freq;
uint32_t aa, bb;
uint8_t fir_en_dis;
uint8_t gc_mode;
uint32_t tx_att;
struct ad9361_rf_phy *phy = &rx_phy;
ad9361_get_rx_rf_bandwidth(phy, &bandwidth);
printf("ad9361_get_rx_rf_bandwidth :%d\r\n", bandwidth);
ad9361_get_rx_sampling_freq(phy, &sampling_freq);
printf("ad9361_get_rx_sampling_freq :%d\r\n", sampling_freq);
ad9361_get_rx_lo_freq(phy, &lo_freq);
aa = lo_freq/1000;
bb = lo_freq%1000;
//xil_printf("ad9361_get_rx_lo_freq :%d%03d\r\n", lo_freq/1000, lo_freq%1000);
printf("ad9361_get_rx_lo_freq :%d%03d\r\n", aa, bb);
ad9361_get_rx_fir_en_dis(phy, &fir_en_dis);
printf("ad9361_get_rx_fir_en_dis :%d\r\n", fir_en_dis);
ad9361_get_tx_rf_bandwidth(phy, &bandwidth);
printf("ad9361_get_tx_rf_bandwidth :%d\r\n", bandwidth);
ad9361_get_tx_sampling_freq(phy, &sampling_freq);
printf("ad9361_get_tx_sampling_freq :%d\r\n", sampling_freq);
ad9361_get_tx_lo_freq(phy, &lo_freq);
aa = lo_freq/1000;
bb = lo_freq%1000;
//xil_printf("ad9361_get_rx_lo_freq :%d%03d\r\n", lo_freq/1000, lo_freq%1000);
printf("ad9361_get_tx_lo_freq :%d%03d\r\n", aa, bb);
ad9361_get_tx_fir_en_dis(phy, &fir_en_dis);
printf("ad9361_get_tx_fir_en_dis :%d\r\n", fir_en_dis);
ad9361_get_tx_attenuation(phy, 1, &tx_att);
printf("tx_attenuation = %d\r\n",tx_att);
ad9361_get_rx_gain_control_mode(phy, 0, &gc_mode);
printf("ad9361_get_rx_gain_control_mode :%d\r\n", gc_mode);
printf("\r\n");
printf("phy->clks[BB_REFCLK]->rate :%d\r\n", phy->clks[BB_REFCLK]->rate);
printf("phy->clks[BBPLL_CLK]->rate :%d\r\n", phy->clks[BBPLL_CLK]->rate);
printf("phy->clks[ADC_CLK]->rate :%d\r\n", phy->clks[ADC_CLK]->rate);
printf("phy->clks[R2_CLK]->rate :%d\r\n", phy->clks[R2_CLK]->rate);
printf("phy->clks[R1_CLK]->rate :%d\r\n", phy->clks[R1_CLK]->rate);
printf("phy->clks[CLKRF_CLK]->rate :%d\r\n", phy->clks[CLKRF_CLK]->rate);
printf("phy->clks[RX_SAMPL_CLK]->rate :%d\r\n", phy->clks[RX_SAMPL_CLK]->rate);
}
static int do_ad9361(cmd_tbl_t tbl, int argc, char *argv[])
{
uint64_t lo_freq;
uint8_t gc_mode;
struct ad9361_rf_phy *phy = &rx_phy;
if (memcmp(argv[1], "bw", 2) == 0){
ad9361_set_tx_rf_bandwidth(phy, atol(argv[2]));
ad9361_set_rx_rf_bandwidth(phy, atol(argv[2]));
}
else if (memcmp(argv[1], "init", 4) == 0) {
ad9361_phy_init();
}
else if (memcmp(argv[1], "bistrx", 6) == 0) {
ad9361_bist_prbs(phy, BIST_INJ_RX);
}
else if (memcmp(argv[1], "bisttx", 6) == 0) {
ad9361_bist_prbs(phy, BIST_INJ_TX);
}
else if (memcmp(argv[1], "loopback", 8) == 0) {
ad9361_bist_loopback(phy, atol(argv[2]));
}
else if (memcmp(argv[1], "sf", 2) == 0){
ad9361_set_tx_sampling_freq(phy, atol(argv[2]));
ad9361_set_rx_sampling_freq(phy, atol(argv[2]));
}
else if (memcmp(argv[1], "txlo", 4) == 0){
ad9361_set_tx_lo_freq(phy, atoll(argv[2]));
//ad9361_set_rx_lo_freq(phy, atoll(argv[2]));
}
else if (memcmp(argv[1], "rxlo", 4) == 0){
//ad9361_set_tx_lo_freq(phy, atoll(argv[2]));
ad9361_set_rx_lo_freq(phy, atoll(argv[2]));
}
else if (memcmp(argv[1], "lo+", 3) == 0){
ad9361_get_rx_lo_freq(phy, &lo_freq);
ad9361_set_rx_lo_freq(phy, lo_freq + 100000);
ad9361_get_tx_lo_freq(phy, &lo_freq);
ad9361_set_tx_lo_freq(phy, lo_freq + 100000);
}
else if (memcmp(argv[1], "lo-", 3) == 0){
ad9361_get_rx_lo_freq(phy, &lo_freq);
ad9361_set_rx_lo_freq(phy, lo_freq - 100000);
ad9361_get_tx_lo_freq(phy, &lo_freq);
ad9361_set_tx_lo_freq(phy, lo_freq - 100000);
}
else if (memcmp(argv[1], "sta", 3) == 0){
ad9361_status(atoi(argv[2]));
}
else if(memcmp(argv[1], "mgc1", 4) == 0){
ad9361_set_rx_gain_control_mode (phy, 0, RF_GAIN_MGC);
ad9361_get_rx_gain_control_mode (phy, 0, &gc_mode);
printf("GAIN control - RX1-manual: %s\n", gc_mode == RF_GAIN_MGC ? "true" : "Error");
ad9361_set_rx_rf_gain (phy, 0, atol(argv[2]));
}
else if(memcmp(argv[1], "mgc2", 4) == 0){
ad9361_set_rx_gain_control_mode (phy, 1, RF_GAIN_MGC);
ad9361_get_rx_gain_control_mode (phy, 1, &gc_mode);
printf("GAIN control - RX2-manual: %s\n", gc_mode == RF_GAIN_MGC ? "true" : "Error");
ad9361_set_rx_rf_gain (phy, 1, atol(argv[2]));
}
else if(memcmp(argv[1], "fast_attack",11) == 0){
ad9361_set_rx_gain_control_mode (phy, 0, RF_GAIN_FASTATTACK_AGC);
ad9361_get_rx_gain_control_mode (phy, 0, &gc_mode);
printf("GAIN control - RX1-fast_attack: %s\n", gc_mode == RF_GAIN_FASTATTACK_AGC ? "true" : "Error");
ad9361_set_rx_gain_control_mode (phy, 1, RF_GAIN_FASTATTACK_AGC);
ad9361_get_rx_gain_control_mode (phy, 1, &gc_mode);
printf("GAIN control - RX2-fast_attack: %s\n", gc_mode == RF_GAIN_FASTATTACK_AGC ? "true" : "Error");
}
else if(memcmp(argv[1], "slow_attack",11) == 0){
ad9361_set_rx_gain_control_mode (phy, 0, RF_GAIN_SLOWATTACK_AGC);
ad9361_get_rx_gain_control_mode (phy, 0, &gc_mode);
printf("GAIN control - RX1-slow_attack: %s\n", gc_mode == RF_GAIN_SLOWATTACK_AGC ? "true" : "Error");
ad9361_set_rx_gain_control_mode (phy, 1, RF_GAIN_SLOWATTACK_AGC);
ad9361_get_rx_gain_control_mode (phy, 1, &gc_mode);
printf("GAIN control - RX2-slow_attack: %s\n", gc_mode == RF_GAIN_SLOWATTACK_AGC ? "true" : "Error");
}
else if (memcmp(argv[1],"rxextlo",7) == 0){
ad9361_set_rx_lo_int_ext(phy, EXT_LO);
}
else if (memcmp(argv[1],"rxintlo",7) == 0){
ad9361_set_rx_lo_int_ext(phy, INT_LO);
}
else if (memcmp(argv[1],"txextlo",7) == 0){
ad9361_set_tx_lo_int_ext(phy, EXT_LO);
}
else if (memcmp(argv[1],"txintlo",7) == 0){
ad9361_set_tx_lo_int_ext(phy, INT_LO);
}
else if (memcmp(argv[1], "att", 3) == 0){
ad9361_set_tx_attenuation(phy, 0, atol(argv[2]));
ad9361_set_tx_attenuation(phy, 1, atol(argv[2]));
}
// else if (memcmp(cmd, "dds", 3) == 0){
// dac_init(phy, DATA_SEL_DDS, 0);
// }
// else if (memcmp(cmd, "lb", 2) == 0){
// dac_init(phy, DATA_SEL_LB, 0);
// }
else if (memcmp(argv[1], "dma", 3) == 0){
dac_init(phy, DATA_SEL_DMA, 0);
axi1_write(0x01028, atol(argv[2]));
}
else if (memcmp(argv[1], "zero", 4) == 0){
dac_init(phy, DATA_SEL_ZERO, 0);
dac_datasel(phy, -1, DATA_SEL_ZERO);
}
else if(memcmp(argv[1], "temp", 4) == 0)
{
int32_t temp = ad9361_get_temp(phy);
printf("the temperature of 9361 is %d\r\n",temp);
}
else if (memcmp(argv[1], "?", 1) == 0){
printf("sta ad9361 status\r\n");
printf("init ad9361 init\r\n");
printf("bw [val] set_rf_bandwidth[Hz]\r\n");
printf("sf [val] set_sampling_freq[Hz]\r\n");
printf("txlo [val] set_txlo_freq[Hz]\r\n");
printf("rxlo [val] set_rxlo_freq[Hz]\r\n");
printf("lo+ set_lo_freq\r\n");
printf("lo- set_lo_freq\r\n");
printf("mgcx [val] set rx x[1:2] gain is manual x[mdB]\r\n");
printf("fast_attack set rx1 and rx2 gain is fast_attack\r\n");
printf("slow_attack set rx1 and rx2 gain is slow_attack\r\n");
printf("rxextlo set rx external lo\r\n");
printf("rxintlo set rx internal lo\r\n");
printf("txextlo set tx external lo\r\n");
printf("txintlo set tx internal lo\r\n");
printf("att [val] set_tx_attenuation[mdB]\r\n");
printf("dma [val] set 0:RX1->TX 1:RX2->TX x[0:1]\r\n");
printf("zero clear TX\r\n");
}
else {
printf("\"%s\" is invalid, Enter \"?\" show help\r\n", argv[1]);
}
return 0;
}
CON_CMD(ad9361, "ad9361 reg opts", NULL, do_ad9361)

19
src/ad9361.h

@ -0,0 +1,19 @@
/*
* ad9361.h
*
* Created on: 2019-7-16
* Author: Administrator
*/
#ifndef AD9361_H_
#define AD9361_H_
/*
* 6678 | <--- spi cs1 ---> | K7A | <---> | K7B | <--- spi --> ad9361
*
* */
extern int ad9361_phy_init(void );
extern void ad9361_status(char ch);
#endif /* AD9361_H_ */

2094
src/ad9361_lib/ad9361_api.c

File diff suppressed because it is too large

501
src/ad9361_lib/ad9361_api.h

@ -0,0 +1,501 @@
/***************************************************************************//**
* @file ad9361_api.h
* @brief Header file of AD9361 API Driver.
* @author DBogdan (dragos.bogdan@analog.com)
********************************************************************************
* 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 AD9361_API_H_
#define AD9361_API_H_
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include "util.h"
/******************************************************************************/
/*************************** Types Declarations *******************************/
/******************************************************************************/
typedef struct
{
/* Device selection */
enum dev_id dev_sel;
/* Identification number */
uint8_t id_no;
/* Reference Clock */
uint32_t reference_clk_rate;
/* Base Configuration */
uint8_t two_rx_two_tx_mode_enable; /* adi,2rx-2tx-mode-enable */
uint8_t one_rx_one_tx_mode_use_rx_num; /* adi,1rx-1tx-mode-use-rx-num */
uint8_t one_rx_one_tx_mode_use_tx_num; /* adi,1rx-1tx-mode-use-tx-num */
uint8_t frequency_division_duplex_mode_enable; /* adi,frequency-division-duplex-mode-enable */
uint8_t frequency_division_duplex_independent_mode_enable; /* adi,frequency-division-duplex-independent-mode-enable */
uint8_t tdd_use_dual_synth_mode_enable; /* adi,tdd-use-dual-synth-mode-enable */
uint8_t tdd_skip_vco_cal_enable; /* adi,tdd-skip-vco-cal-enable */
uint32_t tx_fastlock_delay_ns; /* adi,tx-fastlock-delay-ns */
uint32_t rx_fastlock_delay_ns; /* adi,rx-fastlock-delay-ns */
uint8_t rx_fastlock_pincontrol_enable; /* adi,rx-fastlock-pincontrol-enable */
uint8_t tx_fastlock_pincontrol_enable; /* adi,tx-fastlock-pincontrol-enable */
uint8_t external_rx_lo_enable; /* adi,external-rx-lo-enable */
uint8_t external_tx_lo_enable; /* adi,external-tx-lo-enable */
uint8_t dc_offset_tracking_update_event_mask; /* adi,dc-offset-tracking-update-event-mask */
uint8_t dc_offset_attenuation_high_range; /* adi,dc-offset-attenuation-high-range */
uint8_t dc_offset_attenuation_low_range; /* adi,dc-offset-attenuation-low-range */
uint8_t dc_offset_count_high_range; /* adi,dc-offset-count-high-range */
uint8_t dc_offset_count_low_range; /* adi,dc-offset-count-low-range */
uint8_t split_gain_table_mode_enable; /* adi,split-gain-table-mode-enable */
uint32_t trx_synthesizer_target_fref_overwrite_hz; /* adi,trx-synthesizer-target-fref-overwrite-hz */
uint8_t qec_tracking_slow_mode_enable; /* adi,qec-tracking-slow-mode-enable */
/* ENSM Control */
uint8_t ensm_enable_pin_pulse_mode_enable; /* adi,ensm-enable-pin-pulse-mode-enable */
uint8_t ensm_enable_txnrx_control_enable; /* adi,ensm-enable-txnrx-control-enable */
/* LO Control */
uint64_t rx_synthesizer_frequency_hz; /* adi,rx-synthesizer-frequency-hz */
uint64_t tx_synthesizer_frequency_hz; /* adi,tx-synthesizer-frequency-hz */
/* Rate & BW Control */
uint32_t rx_path_clock_frequencies[6]; /* adi,rx-path-clock-frequencies */
uint32_t tx_path_clock_frequencies[6]; /* adi,tx-path-clock-frequencies */
uint32_t rf_rx_bandwidth_hz; /* adi,rf-rx-bandwidth-hz */
uint32_t rf_tx_bandwidth_hz; /* adi,rf-tx-bandwidth-hz */
/* RF Port Control */
uint32_t rx_rf_port_input_select; /* adi,rx-rf-port-input-select */
uint32_t tx_rf_port_input_select; /* adi,tx-rf-port-input-select */
/* TX Attenuation Control */
int32_t tx_attenuation_mdB; /* adi,tx-attenuation-mdB */
uint8_t update_tx_gain_in_alert_enable; /* adi,update-tx-gain-in-alert-enable */
/* Reference Clock Control */
uint8_t xo_disable_use_ext_refclk_enable; /* adi,xo-disable-use-ext-refclk-enable */
uint32_t dcxo_coarse_and_fine_tune[2]; /* adi,dcxo-coarse-and-fine-tune */
uint32_t clk_output_mode_select; /* adi,clk-output-mode-select */
/* Gain Control */
uint8_t gc_rx1_mode; /* adi,gc-rx1-mode */
uint8_t gc_rx2_mode; /* adi,gc-rx2-mode */
uint8_t gc_adc_large_overload_thresh; /* adi,gc-adc-large-overload-thresh */
uint8_t gc_adc_ovr_sample_size; /* adi,gc-adc-ovr-sample-size */
uint8_t gc_adc_small_overload_thresh; /* adi,gc-adc-small-overload-thresh */
uint16_t gc_dec_pow_measurement_duration; /* adi,gc-dec-pow-measurement-duration */
uint8_t gc_dig_gain_enable; /* adi,gc-dig-gain-enable */
uint16_t gc_lmt_overload_high_thresh; /* adi,gc-lmt-overload-high-thresh */
uint16_t gc_lmt_overload_low_thresh; /* adi,gc-lmt-overload-low-thresh */
uint8_t gc_low_power_thresh; /* adi,gc-low-power-thresh */
uint8_t gc_max_dig_gain; /* adi,gc-max-dig-gain */
/* Gain MGC Control */
uint8_t mgc_dec_gain_step; /* adi,mgc-dec-gain-step */
uint8_t mgc_inc_gain_step; /* adi,mgc-inc-gain-step */
uint8_t mgc_rx1_ctrl_inp_enable; /* adi,mgc-rx1-ctrl-inp-enable */
uint8_t mgc_rx2_ctrl_inp_enable; /* adi,mgc-rx2-ctrl-inp-enable */
uint8_t mgc_split_table_ctrl_inp_gain_mode; /* adi,mgc-split-table-ctrl-inp-gain-mode */
/* Gain AGC Control */
uint8_t agc_adc_large_overload_exceed_counter; /* adi,agc-adc-large-overload-exceed-counter */
uint8_t agc_adc_large_overload_inc_steps; /* adi,agc-adc-large-overload-inc-steps */
uint8_t agc_adc_lmt_small_overload_prevent_gain_inc_enable; /* adi,agc-adc-lmt-small-overload-prevent-gain-inc-enable */
uint8_t agc_adc_small_overload_exceed_counter; /* adi,agc-adc-small-overload-exceed-counter */
uint8_t agc_dig_gain_step_size; /* adi,agc-dig-gain-step-size */
uint8_t agc_dig_saturation_exceed_counter; /* adi,agc-dig-saturation-exceed-counter */
uint32_t agc_gain_update_interval_us; /* adi,agc-gain-update-interval-us */
uint8_t agc_immed_gain_change_if_large_adc_overload_enable; /* adi,agc-immed-gain-change-if-large-adc-overload-enable */
uint8_t agc_immed_gain_change_if_large_lmt_overload_enable; /* adi,agc-immed-gain-change-if-large-lmt-overload-enable */
uint8_t agc_inner_thresh_high; /* adi,agc-inner-thresh-high */
uint8_t agc_inner_thresh_high_dec_steps; /* adi,agc-inner-thresh-high-dec-steps */
uint8_t agc_inner_thresh_low; /* adi,agc-inner-thresh-low */
uint8_t agc_inner_thresh_low_inc_steps; /* adi,agc-inner-thresh-low-inc-steps */
uint8_t agc_lmt_overload_large_exceed_counter; /* adi,agc-lmt-overload-large-exceed-counter */
uint8_t agc_lmt_overload_large_inc_steps; /* adi,agc-lmt-overload-large-inc-steps */
uint8_t agc_lmt_overload_small_exceed_counter; /* adi,agc-lmt-overload-small-exceed-counter */
uint8_t agc_outer_thresh_high; /* adi,agc-outer-thresh-high */
uint8_t agc_outer_thresh_high_dec_steps; /* adi,agc-outer-thresh-high-dec-steps */
uint8_t agc_outer_thresh_low; /* adi,agc-outer-thresh-low */
uint8_t agc_outer_thresh_low_inc_steps; /* adi,agc-outer-thresh-low-inc-steps */
uint32_t agc_attack_delay_extra_margin_us; /* adi,agc-attack-delay-extra-margin-us */
uint8_t agc_sync_for_gain_counter_enable; /* adi,agc-sync-for-gain-counter-enable */
/* Fast AGC */
uint32_t fagc_dec_pow_measuremnt_duration; /* adi,fagc-dec-pow-measurement-duration */
uint32_t fagc_state_wait_time_ns; /* adi,fagc-state-wait-time-ns */
/* Fast AGC - Low Power */
uint8_t fagc_allow_agc_gain_increase; /* adi,fagc-allow-agc-gain-increase-enable */
uint32_t fagc_lp_thresh_increment_time; /* adi,fagc-lp-thresh-increment-time */
uint32_t fagc_lp_thresh_increment_steps; /* adi,fagc-lp-thresh-increment-steps */
/* Fast AGC - Lock Level */
uint32_t fagc_lock_level; /* adi,fagc-lock-level */
uint8_t fagc_lock_level_lmt_gain_increase_en; /* adi,fagc-lock-level-lmt-gain-increase-enable */
uint32_t fagc_lock_level_gain_increase_upper_limit; /* adi,fagc-lock-level-gain-increase-upper-limit */
/* Fast AGC - Peak Detectors and Final Settling */
uint32_t fagc_lpf_final_settling_steps; /* adi,fagc-lpf-final-settling-steps */
uint32_t fagc_lmt_final_settling_steps; /* adi,fagc-lmt-final-settling-steps */
uint32_t fagc_final_overrange_count; /* adi,fagc-final-overrange-count */
/* Fast AGC - Final Power Test */
uint8_t fagc_gain_increase_after_gain_lock_en; /* adi,fagc-gain-increase-after-gain-lock-enable */
/* Fast AGC - Unlocking the Gain */
uint32_t fagc_gain_index_type_after_exit_rx_mode; /* adi,fagc-gain-index-type-after-exit-rx-mode */
uint8_t fagc_use_last_lock_level_for_set_gain_en; /* adi,fagc-use-last-lock-level-for-set-gain-enable */
uint8_t fagc_rst_gla_stronger_sig_thresh_exceeded_en; /* adi,fagc-rst-gla-stronger-sig-thresh-exceeded-enable */
uint32_t fagc_optimized_gain_offset; /* adi,fagc-optimized-gain-offset */
uint32_t fagc_rst_gla_stronger_sig_thresh_above_ll; /* adi,fagc-rst-gla-stronger-sig-thresh-above-ll */
uint8_t fagc_rst_gla_engergy_lost_sig_thresh_exceeded_en; /* adi,fagc-rst-gla-engergy-lost-sig-thresh-exceeded-enable */
uint8_t fagc_rst_gla_engergy_lost_goto_optim_gain_en; /* adi,fagc-rst-gla-engergy-lost-goto-optim-gain-enable */
uint32_t fagc_rst_gla_engergy_lost_sig_thresh_below_ll; /* adi,fagc-rst-gla-engergy-lost-sig-thresh-below-ll */
uint32_t fagc_energy_lost_stronger_sig_gain_lock_exit_cnt; /* adi,fagc-energy-lost-stronger-sig-gain-lock-exit-cnt */
uint8_t fagc_rst_gla_large_adc_overload_en; /* adi,fagc-rst-gla-large-adc-overload-enable */
uint8_t fagc_rst_gla_large_lmt_overload_en; /* adi,fagc-rst-gla-large-lmt-overload-enable */
uint8_t fagc_rst_gla_en_agc_pulled_high_en; /* adi,fagc-rst-gla-en-agc-pulled-high-enable */
uint32_t fagc_rst_gla_if_en_agc_pulled_high_mode; /* adi,fagc-rst-gla-if-en-agc-pulled-high-mode */
uint32_t fagc_power_measurement_duration_in_state5; /* adi,fagc-power-measurement-duration-in-state5 */
/* RSSI Control */
uint32_t rssi_delay; /* adi,rssi-delay */
uint32_t rssi_duration; /* adi,rssi-duration */
uint8_t rssi_restart_mode; /* adi,rssi-restart-mode */
uint8_t rssi_unit_is_rx_samples_enable; /* adi,rssi-unit-is-rx-samples-enable */
uint32_t rssi_wait; /* adi,rssi-wait */
/* Aux ADC Control */
uint32_t aux_adc_decimation; /* adi,aux-adc-decimation */
uint32_t aux_adc_rate; /* adi,aux-adc-rate */
/* AuxDAC Control */
uint8_t aux_dac_manual_mode_enable; /* adi,aux-dac-manual-mode-enable */
uint32_t aux_dac1_default_value_mV; /* adi,aux-dac1-default-value-mV */
uint8_t aux_dac1_active_in_rx_enable; /* adi,aux-dac1-active-in-rx-enable */
uint8_t aux_dac1_active_in_tx_enable; /* adi,aux-dac1-active-in-tx-enable */
uint8_t aux_dac1_active_in_alert_enable; /* adi,aux-dac1-active-in-alert-enable */
uint32_t aux_dac1_rx_delay_us; /* adi,aux-dac1-rx-delay-us */
uint32_t aux_dac1_tx_delay_us; /* adi,aux-dac1-tx-delay-us */
uint32_t aux_dac2_default_value_mV; /* adi,aux-dac2-default-value-mV */
uint8_t aux_dac2_active_in_rx_enable; /* adi,aux-dac2-active-in-rx-enable */
uint8_t aux_dac2_active_in_tx_enable; /* adi,aux-dac2-active-in-tx-enable */
uint8_t aux_dac2_active_in_alert_enable; /* adi,aux-dac2-active-in-alert-enable */
uint32_t aux_dac2_rx_delay_us; /* adi,aux-dac2-rx-delay-us */
uint32_t aux_dac2_tx_delay_us; /* adi,aux-dac2-tx-delay-us */
/* Temperature Sensor Control */
uint32_t temp_sense_decimation; /* adi,temp-sense-decimation */
uint16_t temp_sense_measurement_interval_ms; /* adi,temp-sense-measurement-interval-ms */
int8_t temp_sense_offset_signed; /* adi,temp-sense-offset-signed */
uint8_t temp_sense_periodic_measurement_enable; /* adi,temp-sense-periodic-measurement-enable */
/* Control Out Setup */
uint8_t ctrl_outs_enable_mask; /* adi,ctrl-outs-enable-mask */
uint8_t ctrl_outs_index; /* adi,ctrl-outs-index */
/* External LNA Control */
uint32_t elna_settling_delay_ns; /* adi,elna-settling-delay-ns */
uint32_t elna_gain_mdB; /* adi,elna-gain-mdB */
uint32_t elna_bypass_loss_mdB; /* adi,elna-bypass-loss-mdB */
uint8_t elna_rx1_gpo0_control_enable; /* adi,elna-rx1-gpo0-control-enable */
uint8_t elna_rx2_gpo1_control_enable; /* adi,elna-rx2-gpo1-control-enable */
uint8_t elna_gaintable_all_index_enable; /* adi,elna-gaintable-all-index-enable */
/* Digital Interface Control */
uint8_t digital_interface_tune_skip_mode; /* adi,digital-interface-tune-skip-mode */
uint8_t digital_interface_tune_fir_disable; /* adi,digital-interface-tune-fir-disable */
uint8_t pp_tx_swap_enable; /* adi,pp-tx-swap-enable */
uint8_t pp_rx_swap_enable; /* adi,pp-rx-swap-enable */
uint8_t tx_channel_swap_enable; /* adi,tx-channel-swap-enable */
uint8_t rx_channel_swap_enable; /* adi,rx-channel-swap-enable */
uint8_t rx_frame_pulse_mode_enable; /* adi,rx-frame-pulse-mode-enable */
uint8_t two_t_two_r_timing_enable; /* adi,2t2r-timing-enable */
uint8_t invert_data_bus_enable; /* adi,invert-data-bus-enable */
uint8_t invert_data_clk_enable; /* adi,invert-data-clk-enable */
uint8_t fdd_alt_word_order_enable; /* adi,fdd-alt-word-order-enable */
uint8_t invert_rx_frame_enable; /* adi,invert-rx-frame-enable */
uint8_t fdd_rx_rate_2tx_enable; /* adi,fdd-rx-rate-2tx-enable */
uint8_t swap_ports_enable; /* adi,swap-ports-enable */
uint8_t single_data_rate_enable; /* adi,single-data-rate-enable */
uint8_t lvds_mode_enable; /* adi,lvds-mode-enable */
uint8_t half_duplex_mode_enable; /* adi,half-duplex-mode-enable */
uint8_t single_port_mode_enable; /* adi,single-port-mode-enable */
uint8_t full_port_enable; /* adi,full-port-enable */
uint8_t full_duplex_swap_bits_enable; /* adi,full-duplex-swap-bits-enable */
uint32_t delay_rx_data; /* adi,delay-rx-data */
uint32_t rx_data_clock_delay; /* adi,rx-data-clock-delay */
uint32_t rx_data_delay; /* adi,rx-data-delay */
uint32_t tx_fb_clock_delay; /* adi,tx-fb-clock-delay */
uint32_t tx_data_delay; /* adi,tx-data-delay */
uint32_t lvds_bias_mV; /* adi,lvds-bias-mV */
uint8_t lvds_rx_onchip_termination_enable; /* adi,lvds-rx-onchip-termination-enable */
uint8_t rx1rx2_phase_inversion_en; /* adi,rx1-rx2-phase-inversion-enable */
uint8_t lvds_invert1_control; /* adi,lvds-invert1-control */
uint8_t lvds_invert2_control; /* adi,lvds-invert2-control */
/* GPO Control */
uint8_t gpo0_inactive_state_high_enable; /* adi,gpo0-inactive-state-high-enable */
uint8_t gpo1_inactive_state_high_enable; /* adi,gpo1-inactive-state-high-enable */
uint8_t gpo2_inactive_state_high_enable; /* adi,gpo2-inactive-state-high-enable */
uint8_t gpo3_inactive_state_high_enable; /* adi,gpo3-inactive-state-high-enable */
uint8_t gpo0_slave_rx_enable; /* adi,gpo0-slave-rx-enable */
uint8_t gpo0_slave_tx_enable; /* adi,gpo0-slave-tx-enable */
uint8_t gpo1_slave_rx_enable; /* adi,gpo1-slave-rx-enable */
uint8_t gpo1_slave_tx_enable; /* adi,gpo1-slave-tx-enable */
uint8_t gpo2_slave_rx_enable; /* adi,gpo2-slave-rx-enable */
uint8_t gpo2_slave_tx_enable; /* adi,gpo2-slave-tx-enable */
uint8_t gpo3_slave_rx_enable; /* adi,gpo3-slave-rx-enable */
uint8_t gpo3_slave_tx_enable; /* adi,gpo3-slave-tx-enable */
uint8_t gpo0_rx_delay_us; /* adi,gpo0-rx-delay-us */
uint8_t gpo0_tx_delay_us; /* adi,gpo0-tx-delay-us */
uint8_t gpo1_rx_delay_us; /* adi,gpo1-rx-delay-us */
uint8_t gpo1_tx_delay_us; /* adi,gpo1-tx-delay-us */
uint8_t gpo2_rx_delay_us; /* adi,gpo2-rx-delay-us */
uint8_t gpo2_tx_delay_us; /* adi,gpo2-tx-delay-us */
uint8_t gpo3_rx_delay_us; /* adi,gpo3-rx-delay-us */
uint8_t gpo3_tx_delay_us; /* adi,gpo3-tx-delay-us */
/* Tx Monitor Control */
uint32_t low_high_gain_threshold_mdB; /* adi,txmon-low-high-thresh */
uint32_t low_gain_dB; /* adi,txmon-low-gain */
uint32_t high_gain_dB; /* adi,txmon-high-gain */
uint8_t tx_mon_track_en; /* adi,txmon-dc-tracking-enable */
uint8_t one_shot_mode_en; /* adi,txmon-one-shot-mode-enable */
uint32_t tx_mon_delay; /* adi,txmon-delay */
uint32_t tx_mon_duration; /* adi,txmon-duration */
uint32_t tx1_mon_front_end_gain; /* adi,txmon-1-front-end-gain */
uint32_t tx2_mon_front_end_gain; /* adi,txmon-2-front-end-gain */
uint32_t tx1_mon_lo_cm; /* adi,txmon-1-lo-cm */
uint32_t tx2_mon_lo_cm; /* adi,txmon-2-lo-cm */
/* GPIO definitions */
int32_t gpio_resetb; /* reset-gpios */
/* MCS Sync */
int32_t gpio_sync; /* sync-gpios */
int32_t gpio_cal_sw1; /* cal-sw1-gpios */
int32_t gpio_cal_sw2; /* cal-sw2-gpios */
/* External LO clocks */
uint32_t (*ad9361_rfpll_ext_recalc_rate)(struct refclk_scale *clk_priv);
int32_t (*ad9361_rfpll_ext_round_rate)(struct refclk_scale *clk_priv, uint32_t rate);
int32_t (*ad9361_rfpll_ext_set_rate)(struct refclk_scale *clk_priv, uint32_t rate);
}AD9361_InitParam;
typedef struct
{
uint32_t rx; /* 1, 2, 3(both) */
int32_t rx_gain; /* -12, -6, 0, 6 */
uint32_t rx_dec; /* 1, 2, 4 */
int16_t rx_coef[128];
uint8_t rx_coef_size;
uint32_t rx_path_clks[6];
uint32_t rx_bandwidth;
}AD9361_RXFIRConfig;
typedef struct
{
uint32_t tx; /* 1, 2, 3(both) */
int32_t tx_gain; /* -6, 0 */
uint32_t tx_int; /* 1, 2, 4 */
int16_t tx_coef[128];
uint8_t tx_coef_size;
uint32_t tx_path_clks[6];
uint32_t tx_bandwidth;
}AD9361_TXFIRConfig;
enum ad9361_ensm_mode {
ENSM_MODE_TX,
ENSM_MODE_RX,
ENSM_MODE_ALERT,
ENSM_MODE_FDD,
ENSM_MODE_WAIT,
ENSM_MODE_SLEEP,
ENSM_MODE_PINCTRL,
ENSM_MODE_PINCTRL_FDD_INDEP,
};
#define ENABLE 1
#define DISABLE 0
#define RX1 0
#define RX2 1
#define TX1 0
#define TX2 1
#define A_BALANCED 0
#define B_BALANCED 1
#define C_BALANCED 2
#define A_N 3
#define A_P 4
#define B_N 5
#define B_P 6
#define C_N 7
#define C_P 8
#define TX_MON1 9
#define TX_MON2 10
#define TX_MON1_2 11
#define TXA 0
#define TXB 1
#define MODE_1x1 1
#define MODE_2x2 2
#define HIGHEST_OSR 0
#define NOMINAL_OSR 1
#define INT_LO 0
#define EXT_LO 1
/******************************************************************************/
/************************ Functions Declarations ******************************/
/******************************************************************************/
/* Initialize the AD9361 part. */
struct spi_device;
int32_t ad9361_init (struct ad9361_rf_phy *ad9361_phy, struct spi_device *spi, AD9361_InitParam *init_param);
/* Set the Enable State Machine (ENSM) mode. */
int32_t ad9361_set_en_state_machine_mode (struct ad9361_rf_phy *phy, uint32_t mode);
/* Get the Enable State Machine (ENSM) mode. */
int32_t ad9361_get_en_state_machine_mode (struct ad9361_rf_phy *phy, uint32_t *mode);
/* Set the receive RF gain for the selected channel. */
int32_t ad9361_set_rx_rf_gain (struct ad9361_rf_phy *phy, uint8_t ch, int32_t gain_db);
/* Get current receive RF gain for the selected channel. */
int32_t ad9361_get_rx_rf_gain (struct ad9361_rf_phy *phy, uint8_t ch, int32_t *gain_db);
/* Set the RX RF bandwidth. */
int32_t ad9361_set_rx_rf_bandwidth (struct ad9361_rf_phy *phy, uint32_t bandwidth_hz);
/* Get the RX RF bandwidth. */
int32_t ad9361_get_rx_rf_bandwidth (struct ad9361_rf_phy *phy, uint32_t *bandwidth_hz);
/* Set the RX sampling frequency. */
int32_t ad9361_set_rx_sampling_freq (struct ad9361_rf_phy *phy, uint32_t sampling_freq_hz);
/* Get current RX sampling frequency. */
int32_t ad9361_get_rx_sampling_freq (struct ad9361_rf_phy *phy, uint32_t *sampling_freq_hz);
/* Set the RX LO frequency. */
int32_t ad9361_set_rx_lo_freq (struct ad9361_rf_phy *phy, uint64_t lo_freq_hz);
/* Get current RX LO frequency. */
int32_t ad9361_get_rx_lo_freq (struct ad9361_rf_phy *phy, uint64_t *lo_freq_hz);
/* Switch between internal and external LO. */
int32_t ad9361_set_rx_lo_int_ext(struct ad9361_rf_phy *phy, uint8_t int_ext);
/* Get the RSSI for the selected channel. */
int32_t ad9361_get_rx_rssi (struct ad9361_rf_phy *phy, uint8_t ch, struct rf_rssi *rssi);
/* Set the gain control mode for the selected channel. */
int32_t ad9361_set_rx_gain_control_mode (struct ad9361_rf_phy *phy, uint8_t ch, uint8_t gc_mode);
/* Get the gain control mode for the selected channel. */
int32_t ad9361_get_rx_gain_control_mode (struct ad9361_rf_phy *phy, uint8_t ch, uint8_t *gc_mode);
/* Set the RX FIR filter configuration. */
int32_t ad9361_set_rx_fir_config (struct ad9361_rf_phy *phy, AD9361_RXFIRConfig fir_cfg);
/* Get the RX FIR filter configuration. */
int32_t ad9361_get_rx_fir_config(struct ad9361_rf_phy *phy, uint8_t rx_ch, AD9361_RXFIRConfig *fir_cfg);
/* Enable/disable the RX FIR filter. */
int32_t ad9361_set_rx_fir_en_dis (struct ad9361_rf_phy *phy, uint8_t en_dis);
/* Get the status of the RX FIR filter. */
int32_t ad9361_get_rx_fir_en_dis (struct ad9361_rf_phy *phy, uint8_t *en_dis);
/* Enable/disable the RX RFDC Tracking. */
int32_t ad9361_set_rx_rfdc_track_en_dis (struct ad9361_rf_phy *phy, uint8_t en_dis);
/* Get the status of the RX RFDC Tracking. */
int32_t ad9361_get_rx_rfdc_track_en_dis (struct ad9361_rf_phy *phy, uint8_t *en_dis);
/* Enable/disable the RX BasebandDC Tracking. */
int32_t ad9361_set_rx_bbdc_track_en_dis (struct ad9361_rf_phy *phy, uint8_t en_dis);
/* Get the status of the RX BasebandDC Tracking. */
int32_t ad9361_get_rx_bbdc_track_en_dis (struct ad9361_rf_phy *phy, uint8_t *en_dis);
/* Enable/disable the RX Quadrature Tracking. */
int32_t ad9361_set_rx_quad_track_en_dis (struct ad9361_rf_phy *phy, uint8_t en_dis);
/* Get the status of the RX Quadrature Tracking. */
int32_t ad9361_get_rx_quad_track_en_dis (struct ad9361_rf_phy *phy, uint8_t *en_dis);
/* Set the RX RF input port. */
int32_t ad9361_set_rx_rf_port_input (struct ad9361_rf_phy *phy, uint32_t mode);
/* Get the selected RX RF input port. */
int32_t ad9361_get_rx_rf_port_input (struct ad9361_rf_phy *phy, uint32_t *mode);
/* Store RX fastlock profile. */
int32_t ad9361_rx_fastlock_store(struct ad9361_rf_phy *phy, uint32_t profile);
/* Recall RX fastlock profile. */
int32_t ad9361_rx_fastlock_recall(struct ad9361_rf_phy *phy, uint32_t profile);
/* Load RX fastlock profile. */
int32_t ad9361_rx_fastlock_load(struct ad9361_rf_phy *phy, uint32_t profile, uint8_t *values);
/* Save RX fastlock profile. */
int32_t ad9361_rx_fastlock_save(struct ad9361_rf_phy *phy, uint32_t profile, uint8_t *values);
/* Set power down TX LO/Synthesizers */
int32_t ad9361_set_rx_lo_powerdown(struct ad9361_rf_phy *phy, uint8_t pd);
/* Get power down TX LO/Synthesizers */
int32_t ad9361_get_rx_lo_powerdown(struct ad9361_rf_phy *phy, uint8_t *pd);
/* Set the transmit attenuation for the selected channel. */
int32_t ad9361_set_tx_attenuation (struct ad9361_rf_phy *phy, uint8_t ch, uint32_t attenuation_mdb);
/* Get current transmit attenuation for the selected channel. */
int32_t ad9361_get_tx_attenuation (struct ad9361_rf_phy *phy, uint8_t ch, uint32_t *attenuation_mdb);
/* Set the TX RF bandwidth. */
int32_t ad9361_set_tx_rf_bandwidth (struct ad9361_rf_phy *phy, uint32_t bandwidth_hz);
/* Get the TX RF bandwidth. */
int32_t ad9361_get_tx_rf_bandwidth (struct ad9361_rf_phy *phy, uint32_t *bandwidth_hz);
/* Set the TX sampling frequency. */
int32_t ad9361_set_tx_sampling_freq (struct ad9361_rf_phy *phy, uint32_t sampling_freq_hz);
/* Get current TX sampling frequency. */
int32_t ad9361_get_tx_sampling_freq (struct ad9361_rf_phy *phy, uint32_t *sampling_freq_hz);
/* Set the TX LO frequency. */
int32_t ad9361_set_tx_lo_freq (struct ad9361_rf_phy *phy, uint64_t lo_freq_hz);
/* Get current TX LO frequency. */
int32_t ad9361_get_tx_lo_freq (struct ad9361_rf_phy *phy, uint64_t *lo_freq_hz);
/* Switch between internal and external LO. */
int32_t ad9361_set_tx_lo_int_ext(struct ad9361_rf_phy *phy, uint8_t int_ext);
/* Set the TX FIR filter configuration. */
int32_t ad9361_set_tx_fir_config (struct ad9361_rf_phy *phy, AD9361_TXFIRConfig fir_cfg);
/* Get the TX FIR filter configuration. */
int32_t ad9361_get_tx_fir_config(struct ad9361_rf_phy *phy, uint8_t tx_ch, AD9361_TXFIRConfig *fir_cfg);
/* Enable/disable the TX FIR filter. */
int32_t ad9361_set_tx_fir_en_dis (struct ad9361_rf_phy *phy, uint8_t en_dis);
/* Get the status of the TX FIR filter. */
int32_t ad9361_get_tx_fir_en_dis (struct ad9361_rf_phy *phy, uint8_t *en_dis);
/* Get the TX RSSI for the selected channel. */
int32_t ad9361_get_tx_rssi (struct ad9361_rf_phy *phy, uint8_t ch, uint32_t *rssi_db_x_1000);
/* Set the TX RF output port. */
int32_t ad9361_set_tx_rf_port_output (struct ad9361_rf_phy *phy, uint32_t mode);
/* Get the selected TX RF output port. */
int32_t ad9361_get_tx_rf_port_output (struct ad9361_rf_phy *phy, uint32_t *mode);
/* Enable/disable the auto calibration. */
int32_t ad9361_set_tx_auto_cal_en_dis (struct ad9361_rf_phy *phy, uint8_t en_dis);
/* Get the status of the auto calibration flag. */
int32_t ad9361_get_tx_auto_cal_en_dis (struct ad9361_rf_phy *phy, uint8_t *en_dis);
/* Store TX fastlock profile. */
int32_t ad9361_tx_fastlock_store(struct ad9361_rf_phy *phy, uint32_t profile);
/* Recall TX fastlock profile. */
int32_t ad9361_tx_fastlock_recall(struct ad9361_rf_phy *phy, uint32_t profile);
/* Load TX fastlock profile. */
int32_t ad9361_tx_fastlock_load(struct ad9361_rf_phy *phy, uint32_t profile, uint8_t *values);
/* Save TX fastlock profile. */
int32_t ad9361_tx_fastlock_save(struct ad9361_rf_phy *phy, uint32_t profile, uint8_t *values);
/* Set power down TX LO/Synthesizers */
int32_t ad9361_set_tx_lo_powerdown(struct ad9361_rf_phy *phy, uint8_t pd);
/* Get power down TX LO/Synthesizers */
int32_t ad9361_get_tx_lo_powerdown(struct ad9361_rf_phy *phy, uint8_t *pd);
/* Set the RX and TX path rates. */
int32_t ad9361_set_trx_path_clks(struct ad9361_rf_phy *phy, uint32_t *rx_path_clks, uint32_t *tx_path_clks);
/* Get the RX and TX path rates. */
int32_t ad9361_get_trx_path_clks(struct ad9361_rf_phy *phy, uint32_t *rx_path_clks, uint32_t *tx_path_clks);
/* Power Down RX/TX LO/Synthesizers */
int32_t ad9361_set_trx_lo_powerdown(struct ad9361_rf_phy *phy, uint8_t pd_rx, uint8_t pd_tx);
/* Set the number of channels mode. */
int32_t ad9361_set_no_ch_mode(struct ad9361_rf_phy *phy, uint8_t no_ch_mode);
/* Do multi chip synchronization. */
//int32_t ad9361_do_mcs(struct ad9361_rf_phy *phy_master, struct ad9361_rf_phy *phy_slave);
/* Enable/disable the TRX FIR filters. */
int32_t ad9361_set_trx_fir_en_dis (struct ad9361_rf_phy *phy, uint8_t en_dis);
/* Set the OSR rate governor. */
int32_t ad9361_set_trx_rate_gov (struct ad9361_rf_phy *phy, uint32_t rate_gov);
/* Get the OSR rate governor. */
int32_t ad9361_get_trx_rate_gov (struct ad9361_rf_phy *phy, uint32_t *rate_gov);
/* Perform the selected calibration. */
int32_t ad9361_do_calib(struct ad9361_rf_phy *phy, uint32_t cal, int32_t arg);
/* Load and enable TRX FIR filters configurations. */
int32_t ad9361_trx_load_enable_fir(struct ad9361_rf_phy *phy,
AD9361_RXFIRConfig rx_fir_cfg,
AD9361_TXFIRConfig tx_fir_cfg);
/* Do DCXO coarse tuning. */
int32_t ad9361_do_dcxo_tune_coarse(struct ad9361_rf_phy *phy,
uint32_t coarse);
/* Do DCXO fine tuning. */
int32_t ad9361_do_dcxo_tune_fine(struct ad9361_rf_phy *phy,
uint32_t fine);
#endif

597
src/ad9361_lib/ad9361_conv.c

@ -0,0 +1,597 @@
/***************************************************************************//**
* @file ad9361_conv.c
* @brief Implementation of AD9361 Conv Driver.
********************************************************************************
* Copyright 2014-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.
*******************************************************************************/
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <inttypes.h>
#include <string.h>
#include "ad9361_dev.h"
#include "platform.h"
#include "config.h"
#ifndef AXI_ADC_NOT_PRESENT
/**
* HDL loopback enable/disable.
* @param phy The AD9361 state structure.
* @param enable Enable/disable option.
* @return 0 in case of success, negative error code otherwise.
*/
int32_t ad9361_hdl_loopback(struct ad9361_rf_phy *phy, bool enable)
{
struct axiadc_converter *conv = phy->adc_conv;
struct axiadc_state *st = phy->adc_state;
int32_t reg, addr, chan;
uint32_t version = axiadc_read(st, 0x4000);
/* Still there but implemented a bit different */
if (PCORE_VERSION_MAJOR(version) > 7)
addr = 0x4418;
else
addr = 0x4414;
for (chan = 0; chan < conv->chip_info->num_channels; chan++) {
reg = axiadc_read(st, addr + (chan) * 0x40);
if (PCORE_VERSION_MAJOR(version) > 7) {
if (enable && reg != 0x8) {
conv->scratch_reg[chan] = reg;
reg = 0x8;
} else if (reg == 0x8) {
reg = conv->scratch_reg[chan];
}
} else {
/* DAC_LB_ENB If set enables loopback of receive data */
if (enable)
reg |= BIT(1);
else
reg &= ~BIT(1);
}
axiadc_write(st, addr + (chan) * 0x40, reg);
}
return 0;
}
/**
* Set IO delay.
* @param st The AXI ADC state structure.
* @param lane Lane number.
* @param val Value.
* @param tx The Synthesizer TX = 1, RX = 0.
* @return 0 in case of success, negative error code otherwise.
*/
static int32_t ad9361_iodelay_set(struct axiadc_state *st, unsigned lane,
unsigned val, bool tx)
{
if (tx) {
if (PCORE_VERSION_MAJOR(st->pcore_version) > 8)
axiadc_write(st, 0x4000 + ADI_REG_DELAY(lane), val);
else
return -ENODEV;
} else {
axiadc_idelay_set(st, lane, val);
}
return 0;
}
/**
* Set midscale IO delay.
* @param phy The AD9361 state structure.
* @param tx The Synthesizer TX = 1, RX = 0.
* @return 0 in case of success, negative error code otherwise.
*/
static int32_t ad9361_midscale_iodelay(struct ad9361_rf_phy *phy, bool tx)
{
struct axiadc_state *st = phy->adc_state;
int32_t ret = 0, i;
for (i = 0; i < 7; i++)
ret |= ad9361_iodelay_set(st, i, 15, tx);
return 0;
}
/**
* Digital tune IO delay.
* @param phy The AD9361 state structure.
* @param tx The Synthesizer TX = 1, RX = 0.
* @return 0 in case of success, negative error code otherwise.
*/
static int32_t ad9361_dig_tune_iodelay(struct ad9361_rf_phy *phy, bool tx)
{
struct axiadc_converter *conv = phy->adc_conv;
struct axiadc_state *st = phy->adc_state;
int32_t ret, i, j, chan, num_chan;
uint32_t s0, c0;
uint8_t field[32];
num_chan = (conv->chip_info->num_channels > 4) ? 4 : conv->chip_info->num_channels;
for (i = 0; i < 7; i++) {
for (j = 0; j < 32; j++) {
ad9361_iodelay_set(st, i, j, tx);
mdelay(1);
for (chan = 0; chan < num_chan; chan++)
axiadc_write(st, ADI_REG_CHAN_STATUS(chan),
ADI_PN_ERR | ADI_PN_OOS);
mdelay(10);
for (chan = 0, ret = 0; chan < num_chan; chan++)
ret |= axiadc_read(st, ADI_REG_CHAN_STATUS(chan));
field[j] = ret;
}
c0 = ad9361_find_opt(&field[0], 32, &s0);
ad9361_iodelay_set(st, i, s0 + c0 / 2, tx);
dev_dbg(&phy->spi->dev,
"%s Lane %"PRId32", window cnt %"PRIu32" , start %"PRIu32", IODELAY set to %"PRIu32"\n",
tx ? "TX" :"RX", i , c0, s0, s0 + c0 / 2);
}
return 0;
}
/**
* Digital tune verbose print.
* @param phy The AD9361 state structure.
* @param field Field.
* @param tx The Synthesizer TX = 1, RX = 0.
* @return 0 in case of success, negative error code otherwise.
*/
static void ad9361_dig_tune_verbose_print(struct ad9361_rf_phy *phy,
uint8_t field[][16], bool tx)
{
int32_t i, j;
printk("SAMPL CLK: %"PRIu32" tuning: %s\n",
clk_get_rate(phy, phy->ref_clk_scale[RX_SAMPL_CLK]), tx ? "TX" : "RX");
printk(" ");
for (i = 0; i < 16; i++)
printk("%"PRIx32":", i);
printk("\n");
for (i = 0; i < 2; i++) {
printk("%"PRIx32":", i);
for (j = 0; j < 16; j++) {
printk("%c ", (field[i][j] ? '#' : 'o'));
}
printk("\n");
}
printk("\n");
}
/**
* Digital interface timing analysis.
* @param phy The AD9361 state structure.
* @param buf The buffer.
* @param buflen The buffer length.
* @return The size in case of success, negative error code otherwise.
*/
int32_t ad9361_dig_interface_timing_analysis(struct ad9361_rf_phy *phy,
char *buf, int32_t buflen)
{
struct axiadc_state *st = phy->adc_state;
int32_t ret, i, j, chan, len = 0;
uint8_t field[16][16];
uint8_t rx;
dev_dbg(&phy->spi->dev, "%s:\n", __func__);
rx = ad9361_spi_read(phy->spi, REG_RX_CLOCK_DATA_DELAY);
ad9361_bist_prbs(phy, BIST_INJ_RX);
for (i = 0; i < 16; i++) {
for (j = 0; j < 16; j++) {
ad9361_spi_write(phy->spi, REG_RX_CLOCK_DATA_DELAY,
DATA_CLK_DELAY(j) | RX_DATA_DELAY(i));
for (chan = 0; chan < 4; chan++)
axiadc_write(st, ADI_REG_CHAN_STATUS(chan),
ADI_PN_ERR | ADI_PN_OOS);
mdelay(1);
if (axiadc_read(st, ADI_REG_STATUS) & ADI_STATUS) {
for (chan = 0, ret = 0; chan < 4; chan++)
ret |= axiadc_read(st, ADI_REG_CHAN_STATUS(chan));
}
else {
ret = 1;
}
field[i][j] = ret;
}
}
ad9361_spi_write(phy->spi, REG_RX_CLOCK_DATA_DELAY, rx);
ad9361_bist_prbs(phy, BIST_DISABLE);
len += snprintf(buf + len, buflen, "CLK: %"PRIu32" Hz 'o' = PASS\n",
clk_get_rate(phy, phy->ref_clk_scale[RX_SAMPL_CLK]));
len += snprintf(buf + len, buflen, "DC");
for (i = 0; i < 16; i++)
len += snprintf(buf + len, buflen, "%"PRIx32":", i);
len += snprintf(buf + len, buflen, "\n");
for (i = 0; i < 16; i++) {
len += snprintf(buf + len, buflen, "%"PRIx32":", i);
for (j = 0; j < 16; j++) {
len += snprintf(buf + len, buflen, "%c ",
(field[i][j] ? '.' : 'o'));
}
len += snprintf(buf + len, buflen, "\n");
}
len += snprintf(buf + len, buflen, "\n");
return len;
}
/**
* Digital tune.
* @param phy The AD9361 state structure.
* @param max_freq Maximum frequency.
* @param flags Flags: BE_VERBOSE, BE_MOREVERBOSE, DO_IDELAY, DO_ODELAY.
* @return 0 in case of success, negative error code otherwise.
*/
int32_t ad9361_dig_tune(struct ad9361_rf_phy *phy, uint32_t max_freq,
enum dig_tune_flags flags)
{
struct axiadc_converter *conv = phy->adc_conv;
struct axiadc_state *st = phy->adc_state;
int32_t ret, i, j, k, chan, t, num_chan, err = 0;
uint32_t s0, s1, c0, c1, tmp, saved = 0;
uint8_t field[2][16];
uint32_t saved_dsel[4], saved_chan_ctrl6[4], saved_chan_ctrl0[4];
uint32_t rates[3] = {25000000U, 40000000U, 61440000U};
uint32_t hdl_dac_version;
dev_dbg(&phy->spi->dev, "%s: freq %"PRIu32" flags 0x%X\n", __func__,
max_freq, flags);
hdl_dac_version = axiadc_read(st, 0x4000);
if ((phy->pdata->dig_interface_tune_skipmode == 2) ||
(flags & RESTORE_DEFAULT)) {
/* skip completely and use defaults */
ad9361_spi_write(phy->spi, REG_RX_CLOCK_DATA_DELAY,
phy->pdata->port_ctrl.rx_clk_data_delay);
ad9361_spi_write(phy->spi, REG_TX_CLOCK_DATA_DELAY,
phy->pdata->port_ctrl.tx_clk_data_delay);
return 0;
}
/* Mute TX, we don't want to transmit the PRBS */
ad9361_tx_mute(phy, 1);
if (flags & DO_IDELAY)
ad9361_midscale_iodelay(phy, 0);
if (flags & DO_ODELAY)
ad9361_midscale_iodelay(phy, 1);
if (!phy->pdata->fdd) {
ad9361_set_ensm_mode(phy, true, false);
ad9361_ensm_force_state(phy, ENSM_STATE_FDD);
} else {
ad9361_ensm_force_state(phy, ENSM_STATE_ALERT);
ad9361_ensm_restore_prev_state(phy);
}
num_chan = (conv->chip_info->num_channels > 4) ? 4 :
conv->chip_info->num_channels;
ad9361_bist_prbs(phy, BIST_INJ_RX);
for (t = 0; t < 2; t++) {
memset(field, 0, 32);
for (k = 0; (uint32_t)k < (max_freq ? ARRAY_SIZE(rates) : 1); k++) {
if (max_freq)
ad9361_set_trx_clock_chain_freq(phy,
((phy->pdata->port_ctrl.pp_conf[2] & LVDS_MODE) || !phy->pdata->rx2tx2) ?
rates[k] : rates[k] / 2);
for (i = 0; i < 2; i++) {
for (j = 0; j < 16; j++) {
ad9361_spi_write(phy->spi,
REG_RX_CLOCK_DATA_DELAY + t,
RX_DATA_DELAY(i == 0 ? j : 0) |
DATA_CLK_DELAY(i ? j : 0));
for (chan = 0; chan < num_chan; chan++)
axiadc_write(st, ADI_REG_CHAN_STATUS(chan),
ADI_PN_ERR | ADI_PN_OOS);
mdelay(4);
if ((t == 1) || (axiadc_read(st, ADI_REG_STATUS) & ADI_STATUS)) {
for (chan = 0, ret = 0; chan < num_chan; chan++) {
ret |= axiadc_read(st, ADI_REG_CHAN_STATUS(chan));
}
}
else {
ret = 1;
}
field[i][j] |= ret;
}
}
if ((flags & BE_MOREVERBOSE) && max_freq) {
ad9361_dig_tune_verbose_print(phy, field, t);
}
}
c0 = ad9361_find_opt(&field[0][0], 16, &s0);
c1 = ad9361_find_opt(&field[1][0], 16, &s1);
if (!c0 && !c1) {
ad9361_dig_tune_verbose_print(phy, field, t);
dev_err(&phy->spi->dev, "%s: Tuning %s FAILED!", __func__,
t ? "TX" : "RX");
err |= -EIO;
} else if (flags & BE_VERBOSE) {
ad9361_dig_tune_verbose_print(phy, field, t);
}
if (c1 > c0)
ad9361_spi_write(phy->spi, REG_RX_CLOCK_DATA_DELAY + t,
DATA_CLK_DELAY(s1 + c1 / 2) |
RX_DATA_DELAY(0));
else
ad9361_spi_write(phy->spi, REG_RX_CLOCK_DATA_DELAY + t,
DATA_CLK_DELAY(0) |
RX_DATA_DELAY(s0 + c0 / 2));
if (t == 0) {
if (flags & DO_IDELAY)
ad9361_dig_tune_iodelay(phy, 0);
/* Now do the loopback and tune the digital out */
ad9361_bist_prbs(phy, BIST_DISABLE);
axiadc_write(st, ADI_REG_RSTN, ADI_MMCM_RSTN);
axiadc_write(st, ADI_REG_RSTN, ADI_RSTN | ADI_MMCM_RSTN);
if (phy->pdata->dig_interface_tune_skipmode == 1) {
/* skip TX */
if (!(flags & SKIP_STORE_RESULT))
phy->pdata->port_ctrl.rx_clk_data_delay =
ad9361_spi_read(phy->spi, REG_RX_CLOCK_DATA_DELAY);
if (!phy->pdata->fdd) {
ad9361_set_ensm_mode(phy, phy->pdata->fdd,
phy->pdata->ensm_pin_ctrl);
ad9361_ensm_restore_prev_state(phy);
}
ad9361_tx_mute(phy, 0);
return 0;
}
ad9361_bist_loopback(phy, 1);
axiadc_write(st, 0x4000 + ADI_REG_RSTN, ADI_RSTN | ADI_MMCM_RSTN);
for (chan = 0; chan < num_chan; chan++) {
saved_chan_ctrl0[chan] = axiadc_read(st, ADI_REG_CHAN_CNTRL(chan));
axiadc_write(st, ADI_REG_CHAN_CNTRL(chan),
ADI_FORMAT_SIGNEXT | ADI_FORMAT_ENABLE |
ADI_ENABLE | ADI_IQCOR_ENB);
axiadc_set_pnsel(st, chan, ADC_PN_CUSTOM);
saved_chan_ctrl6[chan] = axiadc_read(st, 0x4414 + (chan) * 0x40);
if (PCORE_VERSION_MAJOR(hdl_dac_version) > 7)
{
saved_dsel[chan] = axiadc_read(st, 0x4418 + (chan) * 0x40);
axiadc_write(st, 0x4418 + (chan) * 0x40, 9);
axiadc_write(st, 0x4414 + (chan) * 0x40, 0); /* !IQCOR_ENB */
axiadc_write(st, 0x4044, 0x1);
}
else
axiadc_write(st, 0x4414 + (chan) * 0x40, 1); /* DAC_PN_ENB */
}
if (PCORE_VERSION_MAJOR(hdl_dac_version) < 8) {
saved = tmp = axiadc_read(st, 0x4048);
tmp &= ~0xF;
tmp |= 1;
axiadc_write(st, 0x4048, tmp);
}
} else {
if (flags & DO_ODELAY)
ad9361_dig_tune_iodelay(phy, 1);
ad9361_bist_loopback(phy, 0);
if (PCORE_VERSION_MAJOR(hdl_dac_version) < 8)
axiadc_write(st, 0x4048, saved);
for (chan = 0; chan < num_chan; chan++) {
axiadc_write(st, ADI_REG_CHAN_CNTRL(chan),
saved_chan_ctrl0[chan]);
axiadc_set_pnsel(st, chan, ADC_PN9);
if (PCORE_VERSION_MAJOR(hdl_dac_version) > 7)
{
axiadc_write(st, 0x4418 + (chan) * 0x40, saved_dsel[chan]);
axiadc_write(st, 0x4044, 0x1);
}
axiadc_write(st, 0x4414 + (chan) * 0x40, saved_chan_ctrl6[chan]);
}
if (err == -EIO) {
ad9361_spi_write(phy->spi, REG_RX_CLOCK_DATA_DELAY,
phy->pdata->port_ctrl.rx_clk_data_delay);
ad9361_spi_write(phy->spi, REG_TX_CLOCK_DATA_DELAY,
phy->pdata->port_ctrl.tx_clk_data_delay);
if (!max_freq)
err = 0;
} else if (!(flags & SKIP_STORE_RESULT)) {
phy->pdata->port_ctrl.rx_clk_data_delay =
ad9361_spi_read(phy->spi, REG_RX_CLOCK_DATA_DELAY);
phy->pdata->port_ctrl.tx_clk_data_delay =
ad9361_spi_read(phy->spi, REG_TX_CLOCK_DATA_DELAY);
}
if (!phy->pdata->fdd) {
ad9361_set_ensm_mode(phy, phy->pdata->fdd, phy->pdata->ensm_pin_ctrl);
ad9361_ensm_restore_prev_state(phy);
}
axiadc_write(st, ADI_REG_RSTN, ADI_MMCM_RSTN);
axiadc_write(st, ADI_REG_RSTN, ADI_RSTN | ADI_MMCM_RSTN);
ad9361_tx_mute(phy, 0);
return err;
}
}
return -EINVAL;
}
/**
* Setup the AD9361 device.
* @param phy The AD9361 state structure.
* @return 0 in case of success, negative error code otherwise.
*/
int32_t ad9361_post_setup(struct ad9361_rf_phy *phy)
{
struct axiadc_converter *conv = phy->adc_conv;
struct axiadc_state *st = phy->adc_state;
int32_t rx2tx2 = phy->pdata->rx2tx2;
int32_t tmp, num_chan, flags;
int32_t i, ret;
num_chan = (conv->chip_info->num_channels > 4) ? 4 : conv->chip_info->num_channels;
axiadc_write(st, ADI_REG_CNTRL, rx2tx2 ? 0 : ADI_R1_MODE);
tmp = axiadc_read(st, 0x4048);
if (!rx2tx2) {
axiadc_write(st, 0x4048, tmp | BIT(5)); /* R1_MODE */
axiadc_write(st, 0x404c,
(phy->pdata->port_ctrl.pp_conf[2] & LVDS_MODE) ? 1 : 0); /* RATE */
}
else {
tmp &= ~BIT(5);
axiadc_write(st, 0x4048, tmp);
axiadc_write(st, 0x404c,
(phy->pdata->port_ctrl.pp_conf[2] & LVDS_MODE) ? 3 : 1); /* RATE */
}
#ifdef ALTERA_PLATFORM
axiadc_write(st, 0x404c, 1);
#endif
for (i = 0; i < num_chan; i++) {
axiadc_write(st, ADI_REG_CHAN_CNTRL_1(i),
ADI_DCFILT_OFFSET(0));
axiadc_write(st, ADI_REG_CHAN_CNTRL_2(i),
(i & 1) ? 0x00004000 : 0x40000000);
axiadc_write(st, ADI_REG_CHAN_CNTRL(i),
ADI_FORMAT_SIGNEXT | ADI_FORMAT_ENABLE |
ADI_ENABLE | ADI_IQCOR_ENB);
}
flags = 0x0;
ret = ad9361_dig_tune(phy, ((conv->chip_info->num_channels > 4) ||
axiadc_read(st, 0x0004)) ? 0 : 61440000, flags);
if (ret < 0)
return ret;
if (flags & (DO_IDELAY | DO_ODELAY)) {
ret = ad9361_dig_tune(phy, (axiadc_read(st, ADI_REG_ID)) ?
0 : 61440000, flags & BE_VERBOSE);
if (ret < 0)
return ret;
}
ret = ad9361_set_trx_clock_chain(phy,
phy->pdata->rx_path_clks,
phy->pdata->tx_path_clks);
ad9361_ensm_force_state(phy, ENSM_STATE_ALERT);
ad9361_ensm_restore_prev_state(phy);
return ret;
}
#else
/**
* HDL loopback enable/disable.
* @param phy The AD9361 state structure.
* @param enable Enable/disable option.
* @return 0 in case of success, negative error code otherwise.
*/
int32_t ad9361_hdl_loopback(struct ad9361_rf_phy *phy, bool enable)
{
return -ENODEV;
}
/**
* Digital tune.
* @param phy The AD9361 state structure.
* @param max_freq Maximum frequency.
* @param flags Flags: BE_VERBOSE, BE_MOREVERBOSE, DO_IDELAY, DO_ODELAY.
* @return 0 in case of success, negative error code otherwise.
*/
int32_t ad9361_dig_tune(struct ad9361_rf_phy *phy, uint32_t max_freq,
enum dig_tune_flags flags)
{
return 0;
}
/**
* Setup the AD9361 device.
* @param phy The AD9361 state structure.
* @return 0 in case of success, negative error code otherwise.
*/
int32_t ad9361_post_setup(struct ad9361_rf_phy *phy)
{
return 0;
}
#endif

7120
src/ad9361_lib/ad9361_dev.c

File diff suppressed because it is too large

3510
src/ad9361_lib/ad9361_dev.h

File diff suppressed because it is too large

417
src/ad9361_lib/adc_core.c

@ -0,0 +1,417 @@
/***************************************************************************//**
* @file adc_core.c
* @brief Implementation of ADC Core Driver.
* @author DBogdan (dragos.bogdan@analog.com)
********************************************************************************
* 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 **********************************/
/******************************************************************************/
#include <stdint.h>
#include <stdlib.h>
#include "platform.h"
#include "adc_core.h"
//#include "parameters.h"
#include "util.h"
/******************************************************************************/
/********************** Macros and Constants Definitions **********************/
/******************************************************************************/
//#define FMCOMMS5
/******************************************************************************/
/************************ Variables Definitions *******************************/
/******************************************************************************/
struct adc_state adc_st;
/***************************************************************************//**
* @brief adc_read
*******************************************************************************/
void adc_read(struct ad9361_rf_phy *phy, uint32_t regAddr, uint32_t *data)
{
switch (phy->id_no)
{
case 0:
*data = Xil_In32(AD9361_RX_0_BASEADDR + regAddr);
break;
case 1:
*data = Xil_In32(AD9361_RX_1_BASEADDR + regAddr);
break;
default:
break;
}
}
/***************************************************************************//**
* @brief adc_write
*******************************************************************************/
void adc_write(struct ad9361_rf_phy *phy, uint32_t regAddr, uint32_t data)
{
switch (phy->id_no)
{
case 0:
Xil_Out32(AD9361_RX_0_BASEADDR + regAddr, data);
break;
case 1:
Xil_Out32(AD9361_RX_1_BASEADDR + regAddr, data);
break;
default:
break;
}
}
/***************************************************************************//**
* @brief adc_dma_read
*******************************************************************************/
#if 0
void adc_dma_read(uint32_t regAddr, uint32_t *data)
{
*data = Xil_In32(CF_AD9361_RX_DMA_BASEADDR + regAddr);
}
/***************************************************************************//**
* @brief adc_dma_write
*******************************************************************************/
void adc_dma_write(uint32_t regAddr, uint32_t data)
{
Xil_Out32(CF_AD9361_RX_DMA_BASEADDR + regAddr, data);
}
#endif
/***************************************************************************//**
* @brief adc_init
*******************************************************************************/
void adc_init(struct ad9361_rf_phy *phy)
{
adc_write(phy, ADC_REG_RSTN, 0);
adc_write(phy, ADC_REG_RSTN, ADC_RSTN);
adc_write(phy, ADC_REG_CHAN_CNTRL(0),
ADC_IQCOR_ENB | ADC_FORMAT_SIGNEXT | ADC_FORMAT_ENABLE | ADC_ENABLE);
adc_write(phy, ADC_REG_CHAN_CNTRL(1),
ADC_IQCOR_ENB | ADC_FORMAT_SIGNEXT | ADC_FORMAT_ENABLE | ADC_ENABLE);
adc_st.rx2tx2 = phy->pdata->rx2tx2;
if(adc_st.rx2tx2)
{
adc_write(phy, ADC_REG_CHAN_CNTRL(2),
ADC_IQCOR_ENB | ADC_FORMAT_SIGNEXT | ADC_FORMAT_ENABLE | ADC_ENABLE);
adc_write(phy, ADC_REG_CHAN_CNTRL(3),
ADC_IQCOR_ENB | ADC_FORMAT_SIGNEXT | ADC_FORMAT_ENABLE | ADC_ENABLE);
}
else
{
adc_write(phy, ADC_REG_CHAN_CNTRL(2), 0);
adc_write(phy, ADC_REG_CHAN_CNTRL(3), 0);
}
printf("adc_init done! %d\r\n", adc_st.rx2tx2);
}
#if 0
#include "xscugic.h"
#define ADC_DMAC_INTERRUPTS
#ifdef ADC_DMAC_INTERRUPTS
uint8_t adc_sot_flag = 0;
uint8_t adc_eot_flag = 0;
uint32_t adc_dmac_start_address = 0;
/***************************************************************************//**
* @brief adc_dmac_isr
*******************************************************************************/
void adc_dmac_isr(void *instance)
{
uint32_t reg_val;
adc_dma_read(AXI_DMAC_REG_IRQ_PENDING, &reg_val);
adc_dma_write(AXI_DMAC_REG_IRQ_PENDING, reg_val);
if(reg_val & AXI_DMAC_IRQ_SOT)
{
adc_sot_flag = 1;
adc_dmac_start_address += 32768;
adc_dma_write(AXI_DMAC_REG_DEST_ADDRESS, adc_dmac_start_address);
/* The current transfer was started and a new one is queued. */
adc_dma_write(AXI_DMAC_REG_START_TRANSFER, 0x1);
xil_printf("AXI_DMAC_IRQ_SOT\r\n");
}
if(reg_val & AXI_DMAC_IRQ_EOT)
{
adc_eot_flag = 1;
xil_printf("AXI_DMAC_IRQ_EOT\r\n");
}
}
#endif
/***************************************************************************//**
* @brief adc_capture
*******************************************************************************/
int32_t adc_capture(uint32_t size, uint32_t start_address)
{
uint32_t reg_val;
uint32_t transfer_id;
uint32_t length;
if(adc_st.rx2tx2)
{
length = (size * 8);
}
else
{
length = (size * 4);
}
#ifdef FMCOMMS5
length = (size * 16);
#endif
adc_dma_write(AXI_DMAC_REG_CTRL, 0x0);
adc_dma_write(AXI_DMAC_REG_CTRL, AXI_DMAC_CTRL_ENABLE);
adc_dma_write(AXI_DMAC_REG_IRQ_MASK, 0x0);
adc_dma_read(AXI_DMAC_REG_TRANSFER_ID, &transfer_id);
adc_dma_read(AXI_DMAC_REG_IRQ_PENDING, &reg_val);
adc_dma_write(AXI_DMAC_REG_IRQ_PENDING, reg_val);
#ifndef ADC_DMAC_INTERRUPTS
adc_dma_write(AXI_DMAC_REG_DEST_ADDRESS, start_address);
adc_dma_write(AXI_DMAC_REG_DEST_STRIDE, 0x0);
adc_dma_write(AXI_DMAC_REG_X_LENGTH, length - 1);
adc_dma_write(AXI_DMAC_REG_Y_LENGTH, 0x0);
adc_dma_write(AXI_DMAC_REG_START_TRANSFER, 0x1);
/* Wait until the new transfer is queued. */
do {
adc_dma_read(AXI_DMAC_REG_START_TRANSFER, &reg_val);
}
while(reg_val == 1);
/* Wait until the current transfer is completed. */
do {
adc_dma_read(AXI_DMAC_REG_IRQ_PENDING, &reg_val);
}
while(reg_val != (AXI_DMAC_IRQ_SOT | AXI_DMAC_IRQ_EOT));
adc_dma_write(AXI_DMAC_REG_IRQ_PENDING, reg_val);
/* Wait until the transfer with the ID transfer_id is completed. */
do {
adc_dma_read(AXI_DMAC_REG_TRANSFER_DONE, &reg_val);
}
while((reg_val & (1 << transfer_id)) != (1 << transfer_id));
#else
XScuGic_Config *gic_config;
XScuGic gic;
int32_t status;
gic_config = XScuGic_LookupConfig(XPAR_PS7_SCUGIC_0_DEVICE_ID);
if(gic_config == NULL)
xil_printf("%s %d Error\n", __FUNCTION__, __LINE__);
status = XScuGic_CfgInitialize(&gic, gic_config, gic_config->CpuBaseAddress);
if(status)
xil_printf("%s %d Error\n", __FUNCTION__, __LINE__);
/*
XScuGic_SetPriorityTriggerType(&gic, XPAR_FABRIC_AXI_AD9361_ADC_DMA_IRQ_INTR, 0x0, 0x3);
status = XScuGic_Connect(&gic, XPAR_FABRIC_AXI_AD9361_ADC_DMA_IRQ_INTR, (Xil_ExceptionHandler)adc_dmac_isr, NULL);
if(status)
xil_printf("%s %d Error\n", __FUNCTION__, __LINE__);
XScuGic_Enable(&gic, XPAR_FABRIC_AXI_AD9361_ADC_DMA_IRQ_INTR);
*/
Xil_ExceptionInit();
XScuGic_SetPriorityTriggerType(&gic, 89, 0x0, 0x3);
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler)XScuGic_InterruptHandler, (void *)&gic);
status = XScuGic_Connect(&gic, 89, (Xil_ExceptionHandler)adc_dmac_isr, NULL);
if(status)
xil_printf("%s %d Error\n", __FUNCTION__, __LINE__);
Xil_ExceptionEnable();
XScuGic_Enable(&gic, 89);
adc_dmac_start_address = start_address;
adc_dma_write(AXI_DMAC_REG_DEST_ADDRESS, adc_dmac_start_address);
adc_dma_write(AXI_DMAC_REG_DEST_STRIDE, 0x0);
adc_dma_write(AXI_DMAC_REG_X_LENGTH, length - 1);
adc_dma_write(AXI_DMAC_REG_Y_LENGTH, 0x0);
adc_dma_write(AXI_DMAC_REG_START_TRANSFER, 0x1);
xil_printf("AXI_DMAC_REG_START_TRANSFER\r\n");
while(adc_dmac_start_address < (start_address + length + 32768));
adc_dma_write(AXI_DMAC_REG_CTRL, 0x0);
#endif
xil_printf("adc_capture ok\r\n");
return 0;
}
#endif
/***************************************************************************//**
* @brief adc_set_calib_scale_phase
*******************************************************************************/
int32_t adc_set_calib_scale_phase(struct ad9361_rf_phy *phy,
uint32_t phase,
uint32_t chan,
int32_t val,
int32_t val2)
{
uint32_t fract;
uint64_t llval;
uint32_t tmp;
switch (val) {
case 1:
fract = 0x4000;
break;
case -1:
fract = 0xC000;
break;
case 0:
fract = 0;
if (val2 < 0) {
fract = 0x8000;
val2 *= -1;
}
break;
default:
return -1;
}
llval = (uint64_t)val2 * 0x4000UL + (1000000UL / 2);
do_div(&llval, 1000000UL);
fract |= llval;
adc_read(phy, ADC_REG_CHAN_CNTRL_2(chan), &tmp);
if (!((chan + phase) % 2)) {
tmp &= ~ADC_IQCOR_COEFF_1(~0);
tmp |= ADC_IQCOR_COEFF_1(fract);
} else {
tmp &= ~ADC_IQCOR_COEFF_2(~0);
tmp |= ADC_IQCOR_COEFF_2(fract);
}
adc_write(phy, ADC_REG_CHAN_CNTRL_2(chan), tmp);
return 0;
}
/***************************************************************************//**
* @brief adc_get_calib_scale_phase
*******************************************************************************/
int32_t adc_get_calib_scale_phase(struct ad9361_rf_phy *phy,
uint32_t phase,
uint32_t chan,
int32_t *val,
int32_t *val2)
{
uint32_t tmp;
int32_t sign;
uint64_t llval;
adc_read(phy, ADC_REG_CHAN_CNTRL_2(chan), &tmp);
/* format is 1.1.14 (sign, integer and fractional bits) */
if (!((phase + chan) % 2)) {
tmp = ADC_TO_IQCOR_COEFF_1(tmp);
} else {
tmp = ADC_TO_IQCOR_COEFF_2(tmp);
}
if (tmp & 0x8000)
sign = -1;
else
sign = 1;
if (tmp & 0x4000)
*val = 1 * sign;
else
*val = 0;
tmp &= ~0xC000;
llval = tmp * 1000000ULL + (0x4000 / 2);
do_div(&llval, 0x4000);
if (*val == 0)
*val2 = llval * sign;
else
*val2 = llval;
return 0;
}
/***************************************************************************//**
* @brief adc_set_calib_scale
*******************************************************************************/
int32_t adc_set_calib_scale(struct ad9361_rf_phy *phy,
uint32_t chan,
int32_t val,
int32_t val2)
{
return adc_set_calib_scale_phase(phy, 0, chan, val, val2);
}
/***************************************************************************//**
* @brief adc_get_calib_scale
*******************************************************************************/
int32_t adc_get_calib_scale(struct ad9361_rf_phy *phy,
uint32_t chan,
int32_t *val,
int32_t *val2)
{
return adc_get_calib_scale_phase(phy, 0, chan, val, val2);
}
/***************************************************************************//**
* @brief adc_set_calib_phase
*******************************************************************************/
int32_t adc_set_calib_phase(struct ad9361_rf_phy *phy,
uint32_t chan,
int32_t val,
int32_t val2)
{
return adc_set_calib_scale_phase(phy, 1, chan, val, val2);
}
/***************************************************************************//**
* @brief adc_get_calib_phase
*******************************************************************************/
int32_t adc_get_calib_phase(struct ad9361_rf_phy *phy,
uint32_t chan,
int32_t *val,
int32_t *val2)
{
return adc_get_calib_scale_phase(phy, 1, chan, val, val2);
}

175
src/ad9361_lib/adc_core.h

@ -0,0 +1,175 @@
/***************************************************************************//**
* @file adc_core.h
* @brief Header file of ADC Core Driver.
* @author DBogdan (dragos.bogdan@analog.com)
********************************************************************************
* 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 ADC_CORE_API_H_
#define ADC_CORE_API_H_
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include "ad9361_dev.h"
/******************************************************************************/
/********************** Macros and Constants Definitions **********************/
/******************************************************************************/
/* ADC COMMON */
#define ADC_REG_RSTN 0x0040
#define ADC_RSTN (1 << 0)
#define ADC_MMCM_RSTN (1 << 1)
#define ADC_REG_CNTRL 0x0044
#define ADC_R1_MODE (1 << 2)
#define ADC_DDR_EDGESEL (1 << 1)
#define ADC_PIN_MODE (1 << 0)
#define ADC_REG_STATUS 0x005C
#define ADC_MUX_PN_ERR (1 << 3)
#define ADC_MUX_PN_OOS (1 << 2)
#define ADC_MUX_OVER_RANGE (1 << 1)
#define ADC_STATUS (1 << 0)
#define ADC_REG_DMA_CNTRL 0x0080
#define ADC_DMA_STREAM (1 << 1)
#define ADC_DMA_START (1 << 0)
#define ADC_REG_DMA_COUNT 0x0084
#define ADC_DMA_COUNT(x) (((x) & 0xFFFFFFFF) << 0)
#define ADC_TO_DMA_COUNT(x) (((x) >> 0) & 0xFFFFFFFF)
#define ADC_REG_DMA_STATUS 0x0088
#define ADC_DMA_OVF (1 << 2)
#define ADC_DMA_UNF (1 << 1)
#define ADC_DMA_STATUS (1 << 0)
#define ADC_REG_DMA_BUSWIDTH 0x008C
#define ADC_DMA_BUSWIDTH(x) (((x) & 0xFFFFFFFF) << 0)
#define ADC_TO_DMA_BUSWIDTH(x) (((x) >> 0) & 0xFFFFFFFF)
/* ADC CHANNEL */
#define ADC_REG_CHAN_CNTRL(c) (0x0400 + (c) * 0x40)
#define ADC_LB_EN (1 << 11)
#define ADC_PN_SEL (1 << 10)
#define ADC_IQCOR_ENB (1 << 9)
#define ADC_DCFILT_ENB (1 << 8)
#define ADC_FORMAT_SIGNEXT (1 << 6)
#define ADC_FORMAT_TYPE (1 << 5)
#define ADC_FORMAT_ENABLE (1 << 4)
#define ADC_PN23_TYPE (1 << 1)
#define ADC_ENABLE (1 << 0)
#define ADC_REG_CHAN_STATUS(c) (0x0404 + (c) * 0x40)
#define ADC_PN_ERR (1 << 2)
#define ADC_PN_OOS (1 << 1)
#define ADC_OVER_RANGE (1 << 0)
#define ADC_REG_CHAN_CNTRL_1(c) (0x0410 + (c) * 0x40)
#define ADC_DCFILT_OFFSET(x) (((x) & 0xFFFF) << 16)
#define ADC_TO_DCFILT_OFFSET(x) (((x) >> 16) & 0xFFFF)
#define ADC_DCFILT_COEFF(x) (((x) & 0xFFFF) << 0)
#define ADC_TO_DCFILT_COEFF(x) (((x) >> 0) & 0xFFFF)
#define ADC_REG_CHAN_CNTRL_2(c) (0x0414 + (c) * 0x40)
#define ADC_IQCOR_COEFF_1(x) (((x) & 0xFFFF) << 16)
#define ADC_TO_IQCOR_COEFF_1(x) (((x) >> 16) & 0xFFFF)
#define ADC_IQCOR_COEFF_2(x) (((x) & 0xFFFF) << 0)
#define ADC_TO_IQCOR_COEFF_2(x) (((x) >> 0) & 0xFFFF)
#define ADC_REG_CHAN_CNTRL_3(c) (0x0418 + (c) * 0x40) /* v8.0 */
#define ADC_ADC_PN_SEL(x) (((x) & 0xF) << 16)
#define ADC_TO_ADC_PN_SEL(x) (((x) >> 16) & 0xF)
#define ADC_ADC_DATA_SEL(x) (((x) & 0xF) << 0)
#define ADC_TO_ADC_DATA_SEL(x) (((x) >> 0) & 0xF)
#define AXI_DMAC_REG_IRQ_MASK 0x80
#define AXI_DMAC_REG_IRQ_PENDING 0x84
#define AXI_DMAC_REG_IRQ_SOURCE 0x88
#define AXI_DMAC_REG_CTRL 0x400
#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
#define AXI_DMAC_REG_ACTIVE_TRANSFER_ID 0x42c
#define AXI_DMAC_REG_STATUS 0x430
#define AXI_DMAC_REG_CURRENT_DEST_ADDR 0x434
#define AXI_DMAC_REG_CURRENT_SRC_ADDR 0x438
#define AXI_DMAC_REG_DBG0 0x43c
#define AXI_DMAC_REG_DBG1 0x440
#define AXI_DMAC_CTRL_ENABLE (1 << 0)
#define AXI_DMAC_CTRL_PAUSE (1 << 1)
#define AXI_DMAC_IRQ_SOT (1 << 0)
#define AXI_DMAC_IRQ_EOT (1 << 1)
struct adc_state
{
bool rx2tx2;
};
#define M_pi 3.14159265358979323846
/******************************************************************************/
/************************ Functions Declarations ******************************/
/******************************************************************************/
void adc_init(struct ad9361_rf_phy *phy);
//int32_t adc_capture(uint32_t size, uint32_t start_address);
void adc_read(struct ad9361_rf_phy *phy, uint32_t regAddr, uint32_t *data);
void adc_write(struct ad9361_rf_phy *phy, uint32_t regAddr, uint32_t data);
int32_t adc_set_calib_scale(struct ad9361_rf_phy *phy,
uint32_t chan,
int32_t val,
int32_t val2);
int32_t adc_get_calib_scale(struct ad9361_rf_phy *phy,
uint32_t chan,
int32_t *val,
int32_t *val2);
int32_t adc_set_calib_phase(struct ad9361_rf_phy *phy,
uint32_t chan,
int32_t val,
int32_t val2);
int32_t adc_get_calib_phase(struct ad9361_rf_phy *phy,
uint32_t chan,
int32_t *val,
int32_t *val2);
#endif

117
src/ad9361_lib/common.h

@ -0,0 +1,117 @@
/***************************************************************************//**
* @file common.h
* @brief Header file of Common Driver.
* @author DBogdan (dragos.bogdan@analog.com)
********************************************************************************
* 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 COMMON_H_
#define COMMON_H_
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <stdint.h>
/******************************************************************************/
/********************** Macros and Constants Definitions **********************/
/******************************************************************************/
#define EIO 5 /* I/O error */
#define EAGAIN 11 /* Try again */
#define ENOMEM 12 /* Out of memory */
#define EFAULT 14 /* Bad address */
#define ENODEV 19 /* No such device */
#define EINVAL 22 /* Invalid argument */
#ifndef ETIMEDOUT
#define ETIMEDOUT 110 /* Connection timed out */
#endif
/******************************************************************************/
/*************************** Types Declarations *******************************/
/******************************************************************************/
#if defined (__STDC__) && (__STDC_VERSION__ >= 199901L)
#include <stdbool.h>
#else
typedef enum { false, true } bool;
#endif
/* copy from config.h */
#define HAVE_VERBOSE_MESSAGES /* Recommended during development prints errors and warnings */
//#define HAVE_DEBUG_MESSAGES /* For Debug purposes only */
/*
* In case memory footprint is a concern these options allow
* to disable unused functionality which may free up a few kb
*/
#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 AD9361_DEVICE 1 /* set it 1 if AD9361 device is used, 0 otherwise */
#define AD9364_DEVICE 0 /* set it 1 if AD9364 device is used, 0 otherwise */
#define AD9363A_DEVICE 0 /* set it 1 if AD9363A device is used, 0 otherwise */
//#define CONSOLE_COMMANDS
#define XILINX_PLATFORM
//#define ALTERA_PLATFORM
//#define FMCOMMS5
//#define PICOZED_SDR
//#define PICOZED_SDR_CMOS
#define CAPTURE_SCRIPT
#define AXI_ADC_NOT_PRESENT
#define TDD_SWITCH_STATE_EXAMPLE
struct clk {
const char *name;
uint32_t rate;
};
struct clk_hw {
struct clk *clk;
};
struct clk_init_data {
const char *name;
const struct clk_ops *ops;
const char **parent_names;
uint8_t num_parents;
uint32_t flags;
};
struct clk_onecell_data {
struct clk **clks;
uint32_t clk_num;
};
#endif

103
src/ad9361_lib/config.h

@ -0,0 +1,103 @@
/***************************************************************************//**
* @file config.h
* @brief Config file of AD9361/API Driver.
* @author DBogdan (dragos.bogdan@analog.com)
********************************************************************************
* 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 HAVE_VERBOSE_MESSAGES /* Recommended during development prints errors and warnings */
//#define HAVE_DEBUG_MESSAGES /* For Debug purposes only */
/*
* In case memory footprint is a concern these options allow
* to disable unused functionality which may free up a few kb
*/
#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 AD9361_DEVICE 1 /* set it 1 if AD9361 device is used, 0 otherwise */
#define AD9364_DEVICE 0 /* set it 1 if AD9364 device is used, 0 otherwise */
#define AD9363A_DEVICE 0 /* set it 1 if AD9363A device is used, 0 otherwise */
//#define CONSOLE_COMMANDS
#define XILINX_PLATFORM
//#define ALTERA_PLATFORM
//#define FMCOMMS5
//#define PICOZED_SDR
//#define PICOZED_SDR_CMOS
//#define CAPTURE_SCRIPT
#define AXI_ADC_NOT_PRESENT
#define TDD_SWITCH_STATE_EXAMPLE
#define XPAR_AXI_AD9361_BASEADDR 0x10000
#ifdef XPAR_AXI_AD9361_0_BASEADDR
#define AD9361_RX_0_BASEADDR XPAR_AXI_AD9361_0_BASEADDR
#define AD9361_TX_0_BASEADDR XPAR_AXI_AD9361_0_BASEADDR + 0x4000
#else
#define AD9361_RX_0_BASEADDR XPAR_AXI_AD9361_BASEADDR
#define AD9361_TX_0_BASEADDR XPAR_AXI_AD9361_BASEADDR + 0x4000
#endif
#ifdef XPAR_AXI_AD9361_1_BASEADDR
#define AD9361_RX_1_BASEADDR XPAR_AXI_AD9361_1_BASEADDR
#define AD9361_TX_1_BASEADDR XPAR_AXI_AD9361_1_BASEADDR + 0x4000
#else
#ifdef XPAR_AXI_AD9361_0_BASEADDR
#define AD9361_RX_1_BASEADDR XPAR_AXI_AD9361_0_BASEADDR
#define AD9361_TX_1_BASEADDR XPAR_AXI_AD9361_0_BASEADDR + 0x4000
#else
#define AD9361_RX_1_BASEADDR XPAR_AXI_AD9361_BASEADDR
#define AD9361_TX_1_BASEADDR XPAR_AXI_AD9361_BASEADDR + 0x4000
#endif
#endif
typedef struct{
unsigned int JBP1_RESETB;
unsigned int JBP1_ENABLE;
unsigned int JBP1_EN_AGC;
unsigned int JBP1_TXNRX;
unsigned int JBP1_HMC472_ATT;
unsigned int JBP1_HMC472_ATTB;
unsigned int JBP1_RTPATH;
}APB_M0;
extern APB_M0 *apb;
#endif

807
src/ad9361_lib/dac_core.c

@ -0,0 +1,807 @@
/***************************************************************************//**
* @file dac_core.c
* @brief Implementation of DAC Core Driver.
* @author DBogdan (dragos.bogdan@analog.com)
********************************************************************************
* 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 **********************************/
/******************************************************************************/
#include <stdint.h>
#include "platform.h"
#include "dac_core.h"
//#include "parameters.h"
#include "util.h"
/******************************************************************************/
/********************** Macros and Constants Definitions **********************/
/******************************************************************************/
//#define FMCOMMS5
/******************************************************************************/
/************************ Variables Definitions *******************************/
/******************************************************************************/
struct dds_state dds_st[2];
/******************************************************************************/
/********************** Macros and Constants Definitions **********************/
/******************************************************************************/
const uint16_t sine_lut[128] = {
0x000, 0x064, 0x0C8, 0x12C, 0x18F, 0x1F1, 0x252, 0x2B1,
0x30F, 0x36B, 0x3C5, 0x41C, 0x471, 0x4C3, 0x512, 0x55F,
0x5A7, 0x5ED, 0x62E, 0x66C, 0x6A6, 0x6DC, 0x70D, 0x73A,
0x763, 0x787, 0x7A7, 0x7C2, 0x7D8, 0x7E9, 0x7F5, 0x7FD,
0x7FF, 0x7FD, 0x7F5, 0x7E9, 0x7D8, 0x7C2, 0x7A7, 0x787,
0x763, 0x73A, 0x70D, 0x6DC, 0x6A6, 0x66C, 0x62E, 0x5ED,
0x5A7, 0x55F, 0x512, 0x4C3, 0x471, 0x41C, 0x3C5, 0x36B,
0x30F, 0x2B1, 0x252, 0x1F1, 0x18F, 0x12C, 0xC8, 0x64,
0x000, 0xF9B, 0xF37, 0xED3, 0xE70, 0xE0E, 0xDAD, 0xD4E,
0xCF0, 0xC94, 0xC3A, 0xBE3, 0xB8E, 0xB3C, 0xAED, 0xAA0,
0xA58, 0xA12, 0x9D1, 0x993, 0x959, 0x923, 0x8F2, 0x8C5,
0x89C, 0x878, 0x858, 0x83D, 0x827, 0x816, 0x80A, 0x802,
0x800, 0x802, 0x80A, 0x816, 0x827, 0x83D, 0x858, 0x878,
0x89C, 0x8C5, 0x8F2, 0x923, 0x959, 0x993, 0x9D1, 0xA12,
0xA58, 0xAA0, 0xAED, 0xB3C, 0xB8E, 0xBE3, 0xC3A, 0xC94,
0xCF0, 0xD4E, 0xDAD, 0xE0E, 0xE70, 0xED3, 0xF37, 0xF9B
};
/***************************************************************************//**
* @brief dac_read
*******************************************************************************/
void dac_read(struct ad9361_rf_phy *phy, uint32_t regAddr, uint32_t *data)
{
switch (phy->id_no)
{
case 0:
*data = Xil_In32(AD9361_TX_0_BASEADDR + regAddr);
break;
case 1:
*data = Xil_In32(AD9361_TX_1_BASEADDR + regAddr);
break;
default:
break;
}
}
/***************************************************************************//**
* @brief dac_write
*******************************************************************************/
void dac_write(struct ad9361_rf_phy *phy, uint32_t regAddr, uint32_t data)
{
switch (phy->id_no)
{
case 0:
Xil_Out32(AD9361_TX_0_BASEADDR + regAddr, data);
break;
case 1:
Xil_Out32(AD9361_TX_1_BASEADDR + regAddr, data);
break;
default:
break;
}
}
/***************************************************************************//**
* @brief dac_dma_read
*******************************************************************************/
#if 0
void dac_dma_read(uint32_t regAddr, uint32_t *data)
{
*data = Xil_In32(CF_AD9361_TX_DMA_BASEADDR + regAddr);
}
/***************************************************************************//**
* @brief dac_dma_write
*******************************************************************************/
void dac_dma_write(uint32_t regAddr, uint32_t data)
{
Xil_Out32(CF_AD9361_TX_DMA_BASEADDR + regAddr, data);
}
#endif
/***************************************************************************//**
* @brief dds_default_setup
*******************************************************************************/
int32_t dds_default_setup(struct ad9361_rf_phy *phy,
uint32_t chan, uint32_t phase,
uint32_t freq, int32_t scale)
{
dds_set_phase(phy, chan, phase);
dds_set_frequency(phy, chan, freq);
dds_set_scale(phy, chan, scale);
dds_st[phy->id_no].cached_freq[chan] = freq;
dds_st[phy->id_no].cached_phase[chan] = phase;
dds_st[phy->id_no].cached_scale[chan] = scale;
return 0;
}
/***************************************************************************//**
* @brief dac_stop
*******************************************************************************/
void dac_stop(struct ad9361_rf_phy *phy)
{
if (PCORE_VERSION_MAJOR(dds_st[phy->id_no].pcore_version) < 8)
{
dac_write(phy, DAC_REG_CNTRL_1, 0);
}
}
/***************************************************************************//**
* @brief dac_start_sync
*******************************************************************************/
void dac_start_sync(struct ad9361_rf_phy *phy, bool force_on)
{
if (PCORE_VERSION_MAJOR(dds_st[phy->id_no].pcore_version) < 8)
{
dac_write(phy, DAC_REG_CNTRL_1, (dds_st[phy->id_no].enable || force_on) ? DAC_ENABLE : 0);
}
else
{
dac_write(phy, DAC_REG_CNTRL_1, DAC_SYNC);
}
}
/***************************************************************************//**
* @brief dac_init
*******************************************************************************/
void dac_init(struct ad9361_rf_phy *phy, uint8_t data_sel, uint8_t config_dma)
{
/*uint32_t tx_count;
uint32_t index;
uint32_t index_i1;
uint32_t index_q1;
uint32_t index_i2;
uint32_t index_q2;
uint32_t index_mem;
uint32_t data_i1;
uint32_t data_q1;
uint32_t data_i2;
uint32_t data_q2;
uint32_t length;*/
uint32_t reg_ctrl_2;
dac_write(phy, DAC_REG_RSTN, 0x0);
dac_write(phy, DAC_REG_RSTN, DAC_RSTN | DAC_MMCM_RSTN);
dds_st[phy->id_no].dac_clk = &phy->clks[TX_SAMPL_CLK]->rate;
dds_st[phy->id_no].rx2tx2 = phy->pdata->rx2tx2;
dac_read(phy, DAC_REG_CNTRL_2, &reg_ctrl_2);
if(dds_st[phy->id_no].rx2tx2)
{
dds_st[phy->id_no].num_buf_channels = 4;
dac_write(phy, DAC_REG_RATECNTRL, DAC_RATE(3));
reg_ctrl_2 &= ~DAC_R1_MODE;
}
else
{
dds_st[phy->id_no].num_buf_channels = 2;
dac_write(phy, DAC_REG_RATECNTRL, DAC_RATE(1));
reg_ctrl_2 |= DAC_R1_MODE;
}
dac_write(phy, DAC_REG_CNTRL_2, reg_ctrl_2);
dac_read(phy, DAC_REG_VERSION, &dds_st[phy->id_no].pcore_version);
dac_stop(phy);
switch (data_sel) {
case DATA_SEL_DDS:
dds_default_setup(phy, DDS_CHAN_TX1_I_F1, 90000, 1000000, 250000);
dds_default_setup(phy, DDS_CHAN_TX1_I_F2, 90000, 1000000, 250000);
dds_default_setup(phy, DDS_CHAN_TX1_Q_F1, 0, 1000000, 250000);
dds_default_setup(phy, DDS_CHAN_TX1_Q_F2, 0, 1000000, 250000);
if(dds_st[phy->id_no].rx2tx2)
{
dds_default_setup(phy, DDS_CHAN_TX2_I_F1, 90000, 1000000, 250000);
dds_default_setup(phy, DDS_CHAN_TX2_I_F2, 90000, 1000000, 250000);
dds_default_setup(phy, DDS_CHAN_TX2_Q_F1, 0, 1000000, 250000);
dds_default_setup(phy, DDS_CHAN_TX2_Q_F2, 0, 1000000, 250000);
}
dac_datasel(phy, -1, DATA_SEL_DDS);
break;
case DATA_SEL_LB:
dac_datasel(phy, -1, DATA_SEL_LB);
break;
case DATA_SEL_DMA:
/*
if(config_dma)
{
tx_count = sizeof(sine_lut) / sizeof(uint16_t);
if(dds_st[phy->id_no].rx2tx2)
{
#ifdef FMCOMMS5
for(index = 0, index_mem = 0; index < (tx_count * 2); index += 2, index_mem += 4)
#else
for(index = 0, index_mem = 0; index < (tx_count * 2); index += 2, index_mem += 2)
#endif
{
index_i1 = index;
index_q1 = index + (tx_count / 2);
if(index_q1 >= (tx_count * 2))
index_q1 -= (tx_count * 2);
data_i1 = (sine_lut[index_i1 / 2] << 20);
data_q1 = (sine_lut[index_q1 / 2] << 4);
Xil_Out32(DAC_DDR_BASEADDR + index_mem * 4, data_i1 | data_q1);
index_i2 = index_i1;
index_q2 = index_q1;
if(index_i2 >= (tx_count * 2))
index_i2 -= (tx_count * 2);
if(index_q2 >= (tx_count * 2))
index_q2 -= (tx_count * 2);
data_i2 = (sine_lut[index_i2 / 2] << 20);
data_q2 = (sine_lut[index_q2 / 2] << 4);
Xil_Out32(DAC_DDR_BASEADDR + (index_mem + 1) * 4, data_i2 | data_q2);
#ifdef FMCOMMS5
Xil_Out32(DAC_DDR_BASEADDR + (index_mem + 2) * 4, data_i1 | data_q1);
Xil_Out32(DAC_DDR_BASEADDR + (index_mem + 3) * 4, data_i2 | data_q2);
#endif
}
}
else
{
for(index = 0; index < tx_count; index += 1)
{
index_i1 = index;
index_q1 = index + (tx_count / 4);
if(index_q1 >= tx_count)
index_q1 -= tx_count;
data_i1 = (sine_lut[index_i1] << 20);
data_q1 = (sine_lut[index_q1] << 4);
Xil_Out32(DAC_DDR_BASEADDR + index * 4, data_i1 | data_q1);
}
}
Xil_DCacheFlush();
if(dds_st[phy->id_no].rx2tx2)
{
length = (tx_count * 8);
}
else
{
length = (tx_count * 4);
}
#ifdef FMCOMMS5
length = (tx_count * 16);
#endif
dac_dma_write(AXI_DMAC_REG_CTRL, 0);
dac_dma_write(AXI_DMAC_REG_CTRL, AXI_DMAC_CTRL_ENABLE);
dac_dma_write(AXI_DMAC_REG_SRC_ADDRESS, DAC_DDR_BASEADDR);
dac_dma_write(AXI_DMAC_REG_SRC_STRIDE, 0x0);
dac_dma_write(AXI_DMAC_REG_X_LENGTH, length - 1);
dac_dma_write(AXI_DMAC_REG_Y_LENGTH, 0x0);
dac_dma_write(AXI_DMAC_REG_START_TRANSFER, 0x1);
}
*/
dac_datasel(phy, -1, DATA_SEL_DMA);
break;
default:
break;
}
//dds_st[phy->id_no].enable = true;
//dac_start_sync(phy, 0);
printf("dac_init done!\r\n");
#if 0
uint32_t tx_count;
uint32_t index;
uint32_t index_i1;
uint32_t index_q1;
uint32_t index_i2;
uint32_t index_q2;
uint32_t index_mem;
uint32_t data_i1;
uint32_t data_q1;
uint32_t data_i2;
uint32_t data_q2;
uint32_t length;
uint32_t reg_ctrl_2;
dac_write(phy, DAC_REG_RSTN, 0x0);
dac_write(phy, DAC_REG_RSTN, DAC_RSTN | DAC_MMCM_RSTN);
dds_st[phy->id_no].dac_clk = &phy->clks[TX_SAMPL_CLK]->rate;
dds_st[phy->id_no].rx2tx2 = phy->pdata->rx2tx2;
dac_read(phy, DAC_REG_CNTRL_2, &reg_ctrl_2);
if(dds_st[phy->id_no].rx2tx2)
{
dds_st[phy->id_no].num_buf_channels = 4;
dac_write(phy, DAC_REG_RATECNTRL, DAC_RATE(3));
reg_ctrl_2 &= ~DAC_R1_MODE;
}
else
{
dds_st[phy->id_no].num_buf_channels = 2;
dac_write(phy, DAC_REG_RATECNTRL, DAC_RATE(1));
reg_ctrl_2 |= DAC_R1_MODE;
}
dac_write(phy, DAC_REG_CNTRL_2, reg_ctrl_2);
dac_read(phy, DAC_REG_VERSION, &dds_st[phy->id_no].pcore_version);
dac_stop(phy);
switch (data_sel) {
case DATA_SEL_DDS:
dds_default_setup(phy, DDS_CHAN_TX1_I_F1, 90000, 1000000, 250000);
dds_default_setup(phy, DDS_CHAN_TX1_I_F2, 90000, 1000000, 250000);
dds_default_setup(phy, DDS_CHAN_TX1_Q_F1, 0, 1000000, 250000);
dds_default_setup(phy, DDS_CHAN_TX1_Q_F2, 0, 1000000, 250000);
if(dds_st[phy->id_no].rx2tx2)
{
dds_default_setup(phy, DDS_CHAN_TX2_I_F1, 90000, 1000000, 250000);
dds_default_setup(phy, DDS_CHAN_TX2_I_F2, 90000, 1000000, 250000);
dds_default_setup(phy, DDS_CHAN_TX2_Q_F1, 0, 1000000, 250000);
dds_default_setup(phy, DDS_CHAN_TX2_Q_F2, 0, 1000000, 250000);
}
dac_datasel(phy, -1, DATA_SEL_DDS);
break;
case DATA_SEL_DMA:
if(config_dma)
{
tx_count = sizeof(sine_lut) / sizeof(uint16_t);
if(dds_st[phy->id_no].rx2tx2)
{
#ifdef FMCOMMS5
for(index = 0, index_mem = 0; index < (tx_count * 2); index += 2, index_mem += 4)
#else
for(index = 0, index_mem = 0; index < (tx_count * 2); index += 2, index_mem += 2)
#endif
{
index_i1 = index;
index_q1 = index + (tx_count / 2);
if(index_q1 >= (tx_count * 2))
index_q1 -= (tx_count * 2);
data_i1 = (sine_lut[index_i1 / 2] << 20);
data_q1 = (sine_lut[index_q1 / 2] << 4);
Xil_Out32(DAC_DDR_BASEADDR + index_mem * 4, data_i1 | data_q1);
index_i2 = index_i1;
index_q2 = index_q1;
if(index_i2 >= (tx_count * 2))
index_i2 -= (tx_count * 2);
if(index_q2 >= (tx_count * 2))
index_q2 -= (tx_count * 2);
data_i2 = (sine_lut[index_i2 / 2] << 20);
data_q2 = (sine_lut[index_q2 / 2] << 4);
Xil_Out32(DAC_DDR_BASEADDR + (index_mem + 1) * 4, data_i2 | data_q2);
#ifdef FMCOMMS5
Xil_Out32(DAC_DDR_BASEADDR + (index_mem + 2) * 4, data_i1 | data_q1);
Xil_Out32(DAC_DDR_BASEADDR + (index_mem + 3) * 4, data_i2 | data_q2);
#endif
}
}
else
{
for(index = 0; index < tx_count; index += 1)
{
index_i1 = index;
index_q1 = index + (tx_count / 4);
if(index_q1 >= tx_count)
index_q1 -= tx_count;
data_i1 = (sine_lut[index_i1] << 20);
data_q1 = (sine_lut[index_q1] << 4);
Xil_Out32(DAC_DDR_BASEADDR + index * 4, data_i1 | data_q1);
}
}
Xil_DCacheFlush();
if(dds_st[phy->id_no].rx2tx2)
{
length = (tx_count * 8);
}
else
{
length = (tx_count * 4);
}
#ifdef FMCOMMS5
length = (tx_count * 16);
#endif
dac_dma_write(AXI_DMAC_REG_CTRL, 0);
dac_dma_write(AXI_DMAC_REG_CTRL, AXI_DMAC_CTRL_ENABLE);
dac_dma_write(AXI_DMAC_REG_SRC_ADDRESS, DAC_DDR_BASEADDR);
dac_dma_write(AXI_DMAC_REG_SRC_STRIDE, 0x0);
dac_dma_write(AXI_DMAC_REG_X_LENGTH, length - 1);
dac_dma_write(AXI_DMAC_REG_Y_LENGTH, 0x0);
dac_dma_write(AXI_DMAC_REG_START_TRANSFER, 0x1);
}
dac_datasel(phy, -1, DATA_SEL_DMA);
break;
default:
break;
}
dds_st[phy->id_no].enable = true;
dac_start_sync(phy, 0);
#endif
}
/***************************************************************************//**
* @brief dds_set_frequency
*******************************************************************************/
void dds_set_frequency(struct ad9361_rf_phy *phy, uint32_t chan, uint32_t freq)
{
uint64_t val64;
uint32_t reg;
dds_st[phy->id_no].cached_freq[chan] = freq;
dac_stop(phy);
dac_read(phy, DAC_REG_CHAN_CNTRL_2_IIOCHAN(chan), &reg);
reg &= ~DAC_DDS_INCR(~0);
val64 = (uint64_t) freq * 0xFFFFULL;
do_div(&val64, *dds_st[phy->id_no].dac_clk);
reg |= DAC_DDS_INCR(val64) | 1;
dac_write(phy, DAC_REG_CHAN_CNTRL_2_IIOCHAN(chan), reg);
dac_start_sync(phy, 0);
}
/***************************************************************************//**
* @brief dds_get_frequency
*******************************************************************************/
void dds_get_frequency(struct ad9361_rf_phy *phy, uint32_t chan, uint32_t *freq)
{
*freq = dds_st[phy->id_no].cached_freq[chan];
}
/***************************************************************************//**
* @brief dds_set_phase
*******************************************************************************/
void dds_set_phase(struct ad9361_rf_phy *phy, uint32_t chan, uint32_t phase)
{
uint64_t val64;
uint32_t reg;
dds_st[phy->id_no].cached_phase[chan] = phase;
dac_stop(phy);
dac_read(phy, DAC_REG_CHAN_CNTRL_2_IIOCHAN(chan), &reg);
reg &= ~DAC_DDS_INIT(~0);
val64 = (uint64_t) phase * 0x10000ULL + (360000 / 2);
do_div(&val64, 360000);
reg |= DAC_DDS_INIT(val64);
dac_write(phy, DAC_REG_CHAN_CNTRL_2_IIOCHAN(chan), reg);
dac_start_sync(phy, 0);
}
/***************************************************************************//**
* @brief dds_get_phase
*******************************************************************************/
void dds_get_phase(struct ad9361_rf_phy *phy, uint32_t chan, uint32_t *phase)
{
*phase = dds_st[phy->id_no].cached_phase[chan];
}
/***************************************************************************//**
* @brief dds_set_phase
*******************************************************************************/
void dds_set_scale(struct ad9361_rf_phy *phy, uint32_t chan, int32_t scale_micro_units)
{
uint32_t scale_reg;
uint32_t sign_part;
uint32_t int_part;
uint32_t fract_part;
if (PCORE_VERSION_MAJOR(dds_st[phy->id_no].pcore_version) > 6)
{
if(scale_micro_units >= 1000000)
{
sign_part = 0;
int_part = 1;
fract_part = 0;
dds_st[phy->id_no].cached_scale[chan] = 1000000;
goto set_scale_reg;
}
if(scale_micro_units <= -1000000)
{
sign_part = 1;
int_part = 1;
fract_part = 0;
dds_st[phy->id_no].cached_scale[chan] = -1000000;
goto set_scale_reg;
}
dds_st[phy->id_no].cached_scale[chan] = scale_micro_units;
if(scale_micro_units < 0)
{
sign_part = 1;
int_part = 0;
scale_micro_units *= -1;
}
else
{
sign_part = 0;
int_part = 0;
}
fract_part = (uint32_t)(((uint64_t)scale_micro_units * 0x4000) / 1000000);
set_scale_reg:
scale_reg = (sign_part << 15) | (int_part << 14) | fract_part;
}
else
{
if(scale_micro_units >= 1000000)
{
scale_reg = 0;
scale_micro_units = 1000000;
}
if(scale_micro_units <= 0)
{
scale_reg = 0;
scale_micro_units = 0;
}
dds_st[phy->id_no].cached_scale[chan] = scale_micro_units;
fract_part = (uint32_t)(scale_micro_units);
scale_reg = 500000 / fract_part;
}
dac_stop(phy);
dac_write(phy, DAC_REG_CHAN_CNTRL_1_IIOCHAN(chan), DAC_DDS_SCALE(scale_reg));
dac_start_sync(phy, 0);
}
/***************************************************************************//**
* @brief dds_get_phase
*******************************************************************************/
void dds_get_scale(struct ad9361_rf_phy *phy, uint32_t chan, int32_t *scale_micro_units)
{
*scale_micro_units = dds_st[phy->id_no].cached_scale[chan];
}
/***************************************************************************//**
* @brief dds_update
*******************************************************************************/
void dds_update(struct ad9361_rf_phy *phy)
{
uint32_t chan;
for(chan = DDS_CHAN_TX1_I_F1; chan <= DDS_CHAN_TX2_Q_F2; chan++)
{
dds_set_frequency(phy, chan, dds_st[phy->id_no].cached_freq[chan]);
dds_set_phase(phy, chan, dds_st[phy->id_no].cached_phase[chan]);
dds_set_scale(phy, chan, dds_st[phy->id_no].cached_scale[chan]);
}
}
/***************************************************************************//**
* @brief dac_datasel
*******************************************************************************/
int32_t dac_datasel(struct ad9361_rf_phy *phy, int32_t chan, enum dds_data_select sel)
{
int32_t i;
if (PCORE_VERSION_MAJOR(dds_st[phy->id_no].pcore_version) > 7) {
if (chan < 0) { /* ALL */
for (i = 0; i < dds_st[phy->id_no].num_buf_channels; i++) {
dac_write(phy, DAC_REG_CHAN_CNTRL_7(i), sel);
dds_st[phy->id_no].cached_datasel[i] = sel;
}
} else {
dac_write(phy, DAC_REG_CHAN_CNTRL_7(chan), sel);
dds_st[phy->id_no].cached_datasel[chan] = sel;
}
} else {
uint32_t reg;
switch(sel) {
case DATA_SEL_DDS:
case DATA_SEL_SED:
case DATA_SEL_DMA:
dac_read(phy, DAC_REG_CNTRL_2, &reg);
reg &= ~DAC_DATA_SEL(~0);
reg |= DAC_DATA_SEL(sel);
dac_write(phy, DAC_REG_CNTRL_2, reg);
break;
default:
return -EINVAL;
}
for (i = 0; i < dds_st[phy->id_no].num_buf_channels; i++) {
dds_st[phy->id_no].cached_datasel[i] = sel;
}
}
return 0;
}
/***************************************************************************//**
* @brief dac_get_datasel
*******************************************************************************/
void dac_get_datasel(struct ad9361_rf_phy *phy, int32_t chan, enum dds_data_select *sel)
{
*sel = dds_st[phy->id_no].cached_datasel[chan];
}
/***************************************************************************//**
* @brief dds_to_signed_mag_fmt
*******************************************************************************/
uint32_t dds_to_signed_mag_fmt(int32_t val, int32_t val2)
{
uint32_t i;
uint64_t val64;
/* format is 1.1.14 (sign, integer and fractional bits) */
switch (val) {
case 1:
i = 0x4000;
break;
case -1:
i = 0xC000;
break;
case 0:
i = 0;
if (val2 < 0) {
i = 0x8000;
val2 *= -1;
}
break;
default:
/* Invalid Value */
i = 0;
}
val64 = (uint64_t)val2 * 0x4000UL + (1000000UL / 2);
do_div(&val64, 1000000UL);
return i | val64;
}
/***************************************************************************//**
* @brief dds_from_signed_mag_fmt
*******************************************************************************/
void dds_from_signed_mag_fmt(uint32_t val,
int32_t *r_val,
int32_t *r_val2)
{
uint64_t val64;
int32_t sign;
if (val & 0x8000)
sign = -1;
else
sign = 1;
if (val & 0x4000)
*r_val = 1 * sign;
else
*r_val = 0;
val &= ~0xC000;
val64 = val * 1000000ULL + (0x4000 / 2);
do_div(&val64, 0x4000);
if (*r_val == 0)
*r_val2 = val64 * sign;
else
*r_val2 = val64;
}
/***************************************************************************//**
* @brief dds_set_calib_scale_phase
*******************************************************************************/
int32_t dds_set_calib_scale_phase(struct ad9361_rf_phy *phy,
uint32_t phase,
uint32_t chan,
int32_t val,
int32_t val2)
{
uint32_t reg;
uint32_t i;
if (PCORE_VERSION_MAJOR(dds_st[phy->id_no].pcore_version) < 8) {
return -1;
}
i = dds_to_signed_mag_fmt(val, val2);
dac_read(phy, DAC_REG_CHAN_CNTRL_8(chan), &reg);
if (!((chan + phase) % 2)) {
reg &= ~DAC_IQCOR_COEFF_1(~0);
reg |= DAC_IQCOR_COEFF_1(i);
} else {
reg &= ~DAC_IQCOR_COEFF_2(~0);
reg |= DAC_IQCOR_COEFF_2(i);
}
dac_write(phy, DAC_REG_CHAN_CNTRL_8(chan), reg);
dac_write(phy, DAC_REG_CHAN_CNTRL_6(chan), DAC_IQCOR_ENB);
return 0;
}
/***************************************************************************//**
* @brief dds_get_calib_scale_phase
*******************************************************************************/
int32_t dds_get_calib_scale_phase(struct ad9361_rf_phy *phy,
uint32_t phase,
uint32_t chan,
int32_t *val,
int32_t *val2)
{
uint32_t reg;
if (PCORE_VERSION_MAJOR(dds_st[phy->id_no].pcore_version) < 8) {
return -1;
}
dac_read(phy, DAC_REG_CHAN_CNTRL_8(chan), &reg);
/* format is 1.1.14 (sign, integer and fractional bits) */
if (!((phase + chan) % 2)) {
reg = DAC_TO_IQCOR_COEFF_1(reg);
} else {
reg = DAC_TO_IQCOR_COEFF_2(reg);
}
dds_from_signed_mag_fmt(reg, val, val2);
return 0;
}
/***************************************************************************//**
* @brief dds_set_calib_scale
*******************************************************************************/
int32_t dds_set_calib_scale(struct ad9361_rf_phy *phy,
uint32_t chan,
int32_t val,
int32_t val2)
{
return dds_set_calib_scale_phase(phy, 0, chan, val, val2);
}
/***************************************************************************//**
* @brief dds_get_calib_scale
*******************************************************************************/
int32_t dds_get_calib_scale(struct ad9361_rf_phy *phy,
uint32_t chan,
int32_t *val,
int32_t *val2)
{
return dds_get_calib_scale_phase(phy, 0, chan, val, val2);
}
/***************************************************************************//**
* @brief dds_set_calib_phase
*******************************************************************************/
int32_t dds_set_calib_phase(struct ad9361_rf_phy *phy,
uint32_t chan,
int32_t val,
int32_t val2)
{
return dds_set_calib_scale_phase(phy, 1, chan, val, val2);
}
/***************************************************************************//**
* @brief dds_get_calib_phase
*******************************************************************************/
int32_t dds_get_calib_phase(struct ad9361_rf_phy *phy,
uint32_t chan,
int32_t *val,
int32_t *val2)
{
return dds_get_calib_scale_phase(phy, 1, chan, val, val2);
}

203
src/ad9361_lib/dac_core.h

@ -0,0 +1,203 @@
/***************************************************************************//**
* @file dac_core.h
* @brief Header file of DAC Core Driver.
* @author DBogdan (dragos.bogdan@analog.com)
********************************************************************************
* 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 DAC_CORE_API_H_
#define DAC_CORE_API_H_
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include "ad9361_dev.h"
/******************************************************************************/
/********************** Macros and Constants Definitions **********************/
/******************************************************************************/
#define DAC_REG_VERSION 0x0000
#define DAC_VERSION(x) (((x) & 0xffffffff) << 0)
#define VERSION_IS(x,y,z) ((x) << 16 | (y) << 8 | (z))
#define DAC_REG_ID 0x0004
#define DAC_ID(x) (((x) & 0xffffffff) << 0)
#define DAC_REG_SCRATCH 0x0008
#define DAC_SCRATCH(x) (((x) & 0xffffffff) << 0)
#define PCORE_VERSION_MAJOR(version) (version >> 16)
#define DAC_REG_RSTN 0x0040
#define DAC_RSTN (1 << 0)
#define DAC_MMCM_RSTN (1 << 1)
#define DAC_REG_RATECNTRL 0x004C
#define DAC_RATE(x) (((x) & 0xFF) << 0)
#define DAC_TO_RATE(x) (((x) >> 0) & 0xFF)
#define DAC_REG_CNTRL_1 0x0048
#define DAC_ENABLE (1 << 0) /* v7.0 */
#define DAC_SYNC (1 << 0) /* v8.0 */
#define DAC_REG_CNTRL_2 0x0044
#define DAC_PAR_TYPE (1 << 7)
#define DAC_PAR_ENB (1 << 6)
#define DAC_R1_MODE (1 << 5)
#define DAC_DATA_FORMAT (1 << 4)
#define DAC_DATA_SEL(x) (((x) & 0xF) << 0) /* v7.0 */
#define DAC_TO_DATA_SEL(x) (((x) >> 0) & 0xF) /* v7.0 */
#define DAC_REG_VDMA_FRMCNT 0x0084
#define DAC_VDMA_FRMCNT(x) (((x) & 0xFFFFFFFF) << 0)
#define DAC_TO_VDMA_FRMCNT(x) (((x) >> 0) & 0xFFFFFFFF)
#define DAC_REG_VDMA_STATUS 0x0088
#define DAC_VDMA_OVF (1 << 1)
#define DAC_VDMA_UNF (1 << 0)
enum dds_data_select {
DATA_SEL_DDS,
DATA_SEL_SED,
DATA_SEL_DMA,
DATA_SEL_ZERO, /* OUTPUT 0 */
DATA_SEL_PN7,
DATA_SEL_PN15,
DATA_SEL_PN23,
DATA_SEL_PN31,
DATA_SEL_LB, /* loopback data (ADC) */
DATA_SEL_PNXX, /* (Device specific) */
};
#define DAC_REG_CHAN_CNTRL_1_IIOCHAN(x) (0x0400 + ((x) >> 1) * 0x40 + ((x) & 1) * 0x8)
#define DAC_DDS_SCALE(x) (((x) & 0xFFFF) << 0)
#define DAC_TO_DDS_SCALE(x) (((x) >> 0) & 0xFFFF)
#define DAC_REG_CHAN_CNTRL_2_IIOCHAN(x) (0x0404 + ((x) >> 1) * 0x40 + ((x) & 1) * 0x8)
#define DAC_DDS_INIT(x) (((x) & 0xFFFF) << 16)
#define DAC_TO_DDS_INIT(x) (((x) >> 16) & 0xFFFF)
#define DAC_DDS_INCR(x) (((x) & 0xFFFF) << 0)
#define DAC_TO_DDS_INCR(x) (((x) >> 0) & 0xFFFF)
#define DDS_CHAN_TX1_I_F1 0
#define DDS_CHAN_TX1_I_F2 1
#define DDS_CHAN_TX1_Q_F1 2
#define DDS_CHAN_TX1_Q_F2 3
#define DDS_CHAN_TX2_I_F1 4
#define DDS_CHAN_TX2_I_F2 5
#define DDS_CHAN_TX2_Q_F1 6
#define DDS_CHAN_TX2_Q_F2 7
#define AXI_DMAC_REG_IRQ_MASK 0x80
#define AXI_DMAC_REG_IRQ_PENDING 0x84
#define AXI_DMAC_REG_IRQ_SOURCE 0x88
#define AXI_DMAC_REG_CTRL 0x400
#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
#define AXI_DMAC_REG_ACTIVE_TRANSFER_ID 0x42c
#define AXI_DMAC_REG_STATUS 0x430
#define AXI_DMAC_REG_CURRENT_DEST_ADDR 0x434
#define AXI_DMAC_REG_CURRENT_SRC_ADDR 0x438
#define AXI_DMAC_REG_DBG0 0x43c
#define AXI_DMAC_REG_DBG1 0x440
#define AXI_DMAC_CTRL_ENABLE (1 << 0)
#define AXI_DMAC_CTRL_PAUSE (1 << 1)
#define AXI_DMAC_IRQ_SOT (1 << 0)
#define AXI_DMAC_IRQ_EOT (1 << 1)
struct dds_state
{
uint32_t cached_freq[8];
uint32_t cached_phase[8];
int32_t cached_scale[8];
enum dds_data_select cached_datasel[8];
uint32_t *dac_clk;
uint32_t pcore_version;
uint32_t num_buf_channels;
bool enable;
bool rx2tx2;
};
#define DAC_REG_CHAN_CNTRL_6(c) (0x0414 + (c) * 0x40)
#define DAC_IQCOR_ENB (1 << 2) /* v8.0 */
#define DAC_REG_CHAN_CNTRL_7(c) (0x0418 + (c) * 0x40) /* v8.0 */
#define DAC_DAC_DDS_SEL(x) (((x) & 0xF) << 0)
#define DAC_TO_DAC_DDS_SEL(x) (((x) >> 0) & 0xF)
#define DAC_REG_CHAN_CNTRL_8(c) (0x041C + (c) * 0x40) /* v8.0 */
#define DAC_IQCOR_COEFF_1(x) (((x) & 0xFFFF) << 16)
#define DAC_TO_IQCOR_COEFF_1(x) (((x) >> 16) & 0xFFFF)
#define DAC_IQCOR_COEFF_2(x) (((x) & 0xFFFF) << 0)
#define DAC_TO_IQCOR_COEFF_2(x) (((x) >> 0) & 0xFFFF)
/******************************************************************************/
/************************ Functions Declarations ******************************/
/******************************************************************************/
void dac_init(struct ad9361_rf_phy *phy, uint8_t data_sel, uint8_t config_dma);
void dds_set_frequency(struct ad9361_rf_phy *phy, uint32_t chan, uint32_t freq);
void dds_get_frequency(struct ad9361_rf_phy *phy, uint32_t chan, uint32_t *freq);
void dds_set_phase(struct ad9361_rf_phy *phy, uint32_t chan, uint32_t phase);
void dds_get_phase(struct ad9361_rf_phy *phy, uint32_t chan, uint32_t *phase);
void dds_set_scale(struct ad9361_rf_phy *phy, uint32_t chan, int32_t scale_micro_units);
void dds_get_scale(struct ad9361_rf_phy *phy, uint32_t chan, int32_t *scale_micro_units);
void dds_update(struct ad9361_rf_phy *phy);
int32_t dac_datasel(struct ad9361_rf_phy *phy, int32_t chan, enum dds_data_select sel);
void dac_get_datasel(struct ad9361_rf_phy *phy, int32_t chan, enum dds_data_select *sel);
int32_t dds_set_calib_scale(struct ad9361_rf_phy *phy,
uint32_t chan,
int32_t val,
int32_t val2);
int32_t dds_get_calib_scale(struct ad9361_rf_phy *phy,
uint32_t chan,
int32_t *val,
int32_t *val2);
int32_t dds_set_calib_phase(struct ad9361_rf_phy *phy,
uint32_t chan,
int32_t val,
int32_t val2);
int32_t dds_get_calib_phase(struct ad9361_rf_phy *phy,
uint32_t chan,
int32_t *val,
int32_t *val2);
#endif

87
src/ad9361_lib/platform.c

@ -0,0 +1,87 @@
#include "util.h"
#include "platform.h"
static struct ad9361_platform_func _opt = {0};
void udelay(unsigned long us)
{
if (_opt.ad9361_udelay)
_opt.ad9361_udelay(us);
}
void mdelay(unsigned long ms)
{
if (_opt.ad9361_udelay)
_opt.ad9361_udelay(1000 * ms);
}
void apb_reset()
{
if (_opt.ad9361_reset)
_opt.ad9361_reset();
}
int spi_write_then_read(struct spi_device *spi, const unsigned char *txbuf, unsigned n_tx,
unsigned char *rxbuf, unsigned n_rx)
{
if (_opt.ad9361_spi_xfer)
return _opt.ad9361_spi_xfer(_opt.dev, txbuf, n_tx, rxbuf, n_rx);
return SUCCESS;
}
void Xil_Out32(uint32_t addr, uint32_t data)
{
if (_opt.ad9361_axi_write)
_opt.ad9361_axi_write(addr, data);
}
uint32_t Xil_In32(uint32_t addr)
{
if (_opt.ad9361_axi_read)
return _opt.ad9361_axi_read(addr);
return 0;
}
/*
* Get next token from string *stringp, where tokens are possibly-empty
* strings separated by characters from delim.
*
* Writes NULs into the string at *stringp to end tokens.
* delim need not remain constant from call to call.
* On return, *stringp points past the last NUL written (if there might
* be further tokens), or is NULL (if there are definitely no more tokens).
*
* If *stringp is NULL, strsep returns NULL.
*/
char * strsep(char **stringp, const char *delim)
{
char *s;
const char *spanp;
int c, sc;
char *tok;
if ((s = *stringp) == NULL)
return (NULL);
for (tok = s;;) {
c = *s++;
spanp = delim;
do {
if ((sc = *spanp++) == c) {
if (c == 0)
s = NULL;
else
s[-1] = 0;
*stringp = s;
return (tok);
}
} while (sc != 0);
}
/* NOTREACHED */
}
extern int ad9361_platform_init(struct ad9361_platform_func *opt)
{
memcpy(&_opt, opt, sizeof *opt);
return 0;
}

64
src/ad9361_lib/platform.h

@ -0,0 +1,64 @@
/******************************************************************************
*
* Copyright (C) 2008 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
#ifndef __PLATFORM_H__
#define __PLATFORM_H__
struct spi_device;
int spi_write_then_read(struct spi_device *, const unsigned char *txbuf, unsigned n_tx,
unsigned char *rxbuf, unsigned n_rx);
void mdelay(unsigned long ms);
void udelay(unsigned long us);
void Xil_Out32(uint32_t addr, uint32_t data);
uint32_t Xil_In32(uint32_t addr);
/* replace apb struct */
void apb_reset(void);
char *strsep(char **, const char *);
struct ad9361_platform_func {
void *dev;
int (*ad9361_spi_xfer)(void *dev, const unsigned char *txbuf, unsigned n_tx, unsigned char *rxbuf, unsigned n_rx);
void (*ad9361_udelay)(unsigned long us);
void (*ad9361_axi_write)(uint32_t addr, uint32_t data);
uint32_t (*ad9361_axi_read)(uint32_t addr);
void (*ad9361_reset)(void);
};
extern int ad9361_platform_init(struct ad9361_platform_func *opt);
#endif

346
src/ad9361_lib/util.c

@ -0,0 +1,346 @@
/***************************************************************************//**
* @file util.c
* @brief Implementation of Util Driver.
* @author DBogdan (dragos.bogdan@analog.com)
********************************************************************************
* 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 **********************************/
/******************************************************************************/
#include "util.h"
#include "string.h"
#include "platform.h"
/******************************************************************************/
/*************************** Macros Definitions *******************************/
/******************************************************************************/
#define BITS_PER_LONG 32
/***************************************************************************//**
* @brief clk_prepare_enable
*******************************************************************************/
int32_t clk_prepare_enable(struct clk *clk)
{
if (clk) {
// Unused variable - fix compiler warning
}
return 0;
}
/***************************************************************************//**
* @brief clk_get_rate
*******************************************************************************/
uint32_t clk_get_rate(struct ad9361_rf_phy *phy,
struct refclk_scale *clk_priv)
{
uint32_t rate = 0;
uint32_t source;
source = clk_priv->source;
switch (source) {
case TX_REFCLK:
case RX_REFCLK:
case BB_REFCLK:
rate = ad9361_clk_factor_recalc_rate(clk_priv,
phy->clk_refin->rate);
break;
case TX_RFPLL_INT:
case RX_RFPLL_INT:
rate = ad9361_rfpll_int_recalc_rate(clk_priv,
phy->clks[clk_priv->parent_source]->rate);
case RX_RFPLL_DUMMY:
case TX_RFPLL_DUMMY:
rate = ad9361_rfpll_dummy_recalc_rate(clk_priv);
break;
case TX_RFPLL:
case RX_RFPLL:
rate = ad9361_rfpll_recalc_rate(clk_priv);
break;
case BBPLL_CLK:
rate = ad9361_bbpll_recalc_rate(clk_priv,
phy->clks[clk_priv->parent_source]->rate);
break;
case ADC_CLK:
case R2_CLK:
case R1_CLK:
case CLKRF_CLK:
case RX_SAMPL_CLK:
case DAC_CLK:
case T2_CLK:
case T1_CLK:
case CLKTF_CLK:
case TX_SAMPL_CLK:
rate = ad9361_clk_factor_recalc_rate(clk_priv,
phy->clks[clk_priv->parent_source]->rate);
break;
default:
break;
}
return rate;
}
/***************************************************************************//**
* @brief clk_set_rate
*******************************************************************************/
int32_t clk_set_rate(struct ad9361_rf_phy *phy,
struct refclk_scale *clk_priv,
uint32_t rate)
{
uint32_t source;
int32_t i;
uint32_t round_rate;
source = clk_priv->source;
if(phy->clks[source]->rate != rate)
{
switch (source) {
case TX_REFCLK:
case RX_REFCLK:
case BB_REFCLK:
round_rate = ad9361_clk_factor_round_rate(clk_priv, rate,
&phy->clk_refin->rate);
ad9361_clk_factor_set_rate(clk_priv, round_rate,
phy->clk_refin->rate);
phy->clks[source]->rate = ad9361_clk_factor_recalc_rate(clk_priv,
phy->clk_refin->rate);
break;
case TX_RFPLL_INT:
case RX_RFPLL_INT:
round_rate = ad9361_rfpll_int_round_rate(clk_priv, rate,
&phy->clks[clk_priv->parent_source]->rate);
ad9361_rfpll_int_set_rate(clk_priv, round_rate,
phy->clks[clk_priv->parent_source]->rate);
phy->clks[source]->rate = ad9361_rfpll_int_recalc_rate(clk_priv,
phy->clks[clk_priv->parent_source]->rate);
break;
case RX_RFPLL_DUMMY:
case TX_RFPLL_DUMMY:
ad9361_rfpll_dummy_set_rate(clk_priv, rate);
case TX_RFPLL:
case RX_RFPLL:
round_rate = ad9361_rfpll_round_rate(clk_priv, rate);
ad9361_rfpll_set_rate(clk_priv, round_rate);
phy->clks[source]->rate = ad9361_rfpll_recalc_rate(clk_priv);
break;
case BBPLL_CLK:
round_rate = ad9361_bbpll_round_rate(clk_priv, rate,
&phy->clks[clk_priv->parent_source]->rate);
ad9361_bbpll_set_rate(clk_priv, round_rate,
phy->clks[clk_priv->parent_source]->rate);
phy->clks[source]->rate = ad9361_bbpll_recalc_rate(clk_priv,
phy->clks[clk_priv->parent_source]->rate);
phy->bbpll_initialized = true;
break;
case ADC_CLK:
case R2_CLK:
case R1_CLK:
case CLKRF_CLK:
case RX_SAMPL_CLK:
case DAC_CLK:
case T2_CLK:
case T1_CLK:
case CLKTF_CLK:
case TX_SAMPL_CLK:
round_rate = ad9361_clk_factor_round_rate(clk_priv, rate,
&phy->clks[clk_priv->parent_source]->rate);
ad9361_clk_factor_set_rate(clk_priv, round_rate,
phy->clks[clk_priv->parent_source]->rate);
phy->clks[source]->rate = ad9361_clk_factor_recalc_rate(clk_priv,
phy->clks[clk_priv->parent_source]->rate);
break;
default:
break;
}
for(i = BB_REFCLK; i < BBPLL_CLK; i++)
{
phy->clks[i]->rate = ad9361_clk_factor_recalc_rate(phy->ref_clk_scale[i],
phy->clk_refin->rate);
}
phy->clks[BBPLL_CLK]->rate = ad9361_bbpll_recalc_rate(phy->ref_clk_scale[BBPLL_CLK],
phy->clks[phy->ref_clk_scale[BBPLL_CLK]->parent_source]->rate);
for(i = ADC_CLK; i < RX_RFPLL_INT; i++)
{
phy->clks[i]->rate = ad9361_clk_factor_recalc_rate(phy->ref_clk_scale[i],
phy->clks[phy->ref_clk_scale[i]->parent_source]->rate);
}
for(i = RX_RFPLL_INT; i < RX_RFPLL_DUMMY; i++)
{
phy->clks[i]->rate = ad9361_rfpll_int_recalc_rate(phy->ref_clk_scale[i],
phy->clks[phy->ref_clk_scale[i]->parent_source]->rate);
}
for(i = RX_RFPLL_DUMMY; i < RX_RFPLL; i++)
{
phy->clks[i]->rate = ad9361_rfpll_dummy_recalc_rate(phy->ref_clk_scale[i]);
}
for(i = RX_RFPLL; i < NUM_AD9361_CLKS; i++)
{
phy->clks[i]->rate = ad9361_rfpll_recalc_rate(phy->ref_clk_scale[i]);
}
} else {
if ((source == BBPLL_CLK) && !phy->bbpll_initialized) {
round_rate = ad9361_bbpll_round_rate(clk_priv, rate,
&phy->clks[clk_priv->parent_source]->rate);
ad9361_bbpll_set_rate(clk_priv, round_rate,
phy->clks[clk_priv->parent_source]->rate);
phy->clks[source]->rate = ad9361_bbpll_recalc_rate(clk_priv,
phy->clks[clk_priv->parent_source]->rate);
phy->bbpll_initialized = true;
}
}
return 0;
}
/***************************************************************************//**
* @brief int_sqrt
*******************************************************************************/
uint32_t int_sqrt(uint32_t x)
{
uint32_t b, m, y = 0;
if (x <= 1)
return x;
m = 1UL << (BITS_PER_LONG - 2);
while (m != 0) {
b = y + m;
y >>= 1;
if (x >= b) {
x -= b;
y += m;
}
m >>= 2;
}
return y;
}
/***************************************************************************//**
* @brief ilog2
*******************************************************************************/
int32_t ilog2(int32_t x)
{
int32_t A = !(!(x >> 16));
int32_t count = 0;
int32_t x_copy = x;
count = count + (A << 4);
x_copy = (((~A + 1) & (x >> 16)) + (~(~A + 1) & x));
A = !(!(x_copy >> 8));
count = count + (A << 3);
x_copy = (((~A + 1) & (x_copy >> 8)) + (~(~A + 1) & x_copy));
A = !(!(x_copy >> 4));
count = count + (A << 2);
x_copy = (((~A + 1) & (x_copy >> 4)) + (~(~A + 1) & x_copy));
A = !(!(x_copy >> 2));
count = count + (A << 1);
x_copy = (((~A + 1) & (x_copy >> 2)) + (~(~A + 1) & x_copy));
A = !(!(x_copy >> 1));
count = count + A;
return count;
}
/***************************************************************************//**
* @brief do_div
*******************************************************************************/
uint64_t do_div(uint64_t* n, uint64_t base)
{
uint64_t mod = 0;
mod = *n % base;
*n = *n / base;
return mod;
}
/***************************************************************************//**
* @brief find_first_bit
*******************************************************************************/
uint32_t find_first_bit(uint32_t word)
{
int32_t num = 0;
if ((word & 0xffff) == 0) {
num += 16;
word >>= 16;
}
if ((word & 0xff) == 0) {
num += 8;
word >>= 8;
}
if ((word & 0xf) == 0) {
num += 4;
word >>= 4;
}
if ((word & 0x3) == 0) {
num += 2;
word >>= 2;
}
if ((word & 0x1) == 0)
num += 1;
return num;
}
/***************************************************************************//**
* @brief ERR_PTR
*******************************************************************************/
void * ERR_PTR(long error)
{
return (void *) error;
}
/***************************************************************************//**
* @brief zmalloc
*******************************************************************************/
void *zmalloc(size_t size)
{
void *ptr = malloc(size);
if (ptr)
memset(ptr, 0, size);
//mdelay(1);
return ptr;
}

142
src/ad9361_lib/util.h

@ -0,0 +1,142 @@
/***************************************************************************//**
* @file util.h
* @brief Header file of Util driver.
* @author DBogdan (dragos.bogdan@analog.com)
********************************************************************************
* 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 __NO_OS_PORT_H__
#define __NO_OS_PORT_H__
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "ad9361_dev.h"
#include "common.h"
#include "config.h"
#ifndef bool
#define bool int
#endif
/******************************************************************************/
/********************** Macros and Constants Definitions **********************/
/******************************************************************************/
#define SUCCESS 0
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#endif
#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 DIV_ROUND_UP(x, y) (((x) + (y) - 1) / (y))
#define DIV_ROUND_CLOSEST(x, divisor) (((x) + (divisor) / 2) / (divisor))
#define BIT(x) (1 << (x))
#define CLK_IGNORE_UNUSED BIT(3)
#define CLK_GET_RATE_NOCACHE BIT(6)
#if defined(HAVE_VERBOSE_MESSAGES)
#define dev_err(dev, format, ...) do {printf(format, ## __VA_ARGS__);printf("\r\n"); } while (0)
#define dev_warn(dev, format, ...) do {printf(format, ## __VA_ARGS__);printf("\r\n"); } while (0)
#if defined(HAVE_DEBUG_MESSAGES)
#define dev_dbg(dev, format, ...) do {printf(format, ## __VA_ARGS__);printf("\r\n"); } while (0)
#else
#define dev_dbg(dev, format, ...) do { if (0) printf(format, ## __VA_ARGS__); } while (0)
#endif
#define printk(format, ...) printf(format, ## __VA_ARGS__)
#else
#define dev_err(dev, format, ...) do{ if (0) xil_printf(format, ## __VA_ARGS__); }while(0)
#define dev_warn(dev, format, ...) do{ if (0) xil_printf(format, ## __VA_ARGS__); }while(0)
#define dev_dbg(dev, format, ...) do{ if (0) xil_printf(format, ## __VA_ARGS__); }while(0)
#define printk(format, ...) do{ if (0) xil_printf(format, ## __VA_ARGS__); }while(0)
#endif
/*
struct device {
};
struct spi_device {
struct device dev;
uint8_t id_no;
};
*/
struct axiadc_state {
struct ad9361_rf_phy *phy;
uint32_t pcore_version;
};
struct axiadc_chip_info {
char *name;
int32_t num_channels;
};
struct axiadc_converter {
struct axiadc_chip_info *chip_info;
uint32_t scratch_reg[16];
};
#ifdef WIN32
#include "basetsd.h"
typedef SSIZE_T ssize_t;
#define strsep(s, ct) 0
#define snprintf(s, n, format, ...) 0
#define __func__ __FUNCTION__
#endif
/******************************************************************************/
/************************ Functions Declarations ******************************/
/******************************************************************************/
struct refclk_scale;
int32_t clk_prepare_enable(struct clk *clk);
uint32_t clk_get_rate(struct ad9361_rf_phy *phy, struct refclk_scale *clk_priv);
int32_t clk_set_rate(struct ad9361_rf_phy *phy, struct refclk_scale *clk_priv, uint32_t rate);
uint32_t int_sqrt(uint32_t x);
int32_t ilog2(int32_t x);
uint64_t do_div(uint64_t* n,
uint64_t base);
uint32_t find_first_bit(uint32_t word);
void * ERR_PTR(long error);
void *zmalloc(size_t size);
#endif

218
src/ad9680.c

@ -0,0 +1,218 @@
/*
* ad9680.c
*
* Created on: 2019-6-13
* Author: Administrator
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <vsky/libdsp/inc/tsc.h>
#include <vslib/vbios.h>
#include "gspi.h"
#include "axi0.h"
#include "ad9680.h"
/******************************************************************************/
#define AD9680_REG_INTERFACE_CONF_A 0x000
#define AD9680_REG_INTERFACE_CONF_B 0x001
#define AD9680_REG_CHIP_ID_LOW 0x004
#define AD9680_REG_CHIP_ID_HIGH 0x005
#define AD9680_REG_DEVICE_INDEX 0x008
#define AD9680_REG_CHIP_DEC_RATIO 0x201
#define AD9680_REG_ADC_TEST_MODE 0x550
#define AD9680_REG_OUTPUT_MODE 0x561
#define AD9680_REG_JESD204B_LANE_RATE_CTRL 0x56e
#define AD9680_REG_JESD204B_QUICK_CONFIG 0x570
#define AD9680_REG_LINK_CONTROL 0x571
#define AD9680_REG_JESD204B_SCR_LAN 0x58b
#define AD9680_REG_JESD204B_MF_CTRL 0x58d
#define AD9680_REG_JESD204B_CSN_CONFIG 0x58f
#define AD9680_REG_JESD204B_SUBCLASS_CONFIG 0x590
#define AD9680_REG_JESD204B_LANE_SERD_OUT0_ASSIGN 0x5B2
#define AD9680_REG_JESD204B_LANE_SERD_OUT1_ASSIGN 0x5b3
#define AD9680_REG_JESD204B_LANE_SERD_OUT2_ASSIGN 0x5b5
#define AD9680_REG_JESD204B_LANE_SERD_OUT3_ASSIGN 0x5b6
#define AD9680_REG_JESD204B_PLL_LOCK_STATUS 0x56F
#define AD9680_CHIP_ID 0x0C5
#define AD9680_TEST_OFF 0x000
#define AD9680_TEST_PN9 0x006
#define AD9680_TEST_PN23 0x005
#define AD9680_TEST_RAMP 0x00f
#define AD9680_FORMAT_2S_COMPLEMENT 0x001
#define AD9680_FORMAT_OFFSET_BINARY 0x000
static gspi_t _ad9680 = NULL;
static int __gspi_ad9680_init(void )
{
spi_dev_cfg_s format = {
.mode = SPI_CLK_MODE_1,
.speed = 5000000,
.bits = 8,
.endian = 0,
.t2delay = 0,
};
_ad9680 = gspi_open(GSPI_CS_AD9680, &format);
return 0;
}
uint8_t ad9680_read(uint16_t reg)
{
int elms = 0;
unsigned char buf[3];
if (!_ad9680)
__gspi_ad9680_init();
buf[0] = 0x80 | (reg >> 8);
buf[1] = reg & 0xFF;
elms = gspi_xfer(_ad9680, buf, 0, 2, &buf[2], 2, 1);
if (elms != sizeof buf) {
printf("error: ad9680 reg 0x%x read fail\r\n", reg);
return 0;
}
printf("ad9680 read reg:0x%04x, val: 0x%x\r\n", reg, buf[2]);
return buf[2] & 0xff;
}
int ad9680_write(uint16_t reg, uint8_t val)
{
int elms = 0;
unsigned char buf[3];
if (!_ad9680)
__gspi_ad9680_init();
buf[0] = 0x7F & (reg >> 8);
buf[1] = reg & 0xFF;
buf[2] = val & 0xFF;
elms = gspi_xfer(_ad9680, buf, 0, 3, NULL, 0, 0);
if (elms != sizeof buf) {
printf("error: ad9680 reg 0x%x write fail\r\n", reg);
return -1;
}
printf("ad9680 write reg:0x%04x, val: 0x%x\r\n", reg, val);
return 0;
}
int ad9680_setup(uint32_t speed)
{
uint8_t chip_id;
uint8_t pll_stat;
uint8_t temp;
/*enable axi scrambling*/
axi0_write(0x00c, 0x1);
printf("enable fpga jesd204 scrambing... \r\n");
ad9680_write(AD9680_REG_INTERFACE_CONF_A, 0x81); // 0x000 RESET
tsc_delay(250000);
chip_id = ad9680_read(AD9680_REG_CHIP_ID_LOW); //0x004
printf("AD CHIP ID (0x%x).\r\n", chip_id);
ad9680_write(AD9680_REG_LINK_CONTROL, 0x15); //0x571 disable link, ilas enable
temp = ad9680_read(AD9680_REG_LINK_CONTROL);
if(temp != 0x15){
printf("AD9680_REG_LINK_CONTROL ERROR! %x\r\n", temp);
}
ad9680_write(0x5b0, 0xaa); //JESD204B lane power-down; 0 = 역; 1 = 밑
ad9680_write(0x5b2, 0x0); //SERDOUT0÷繫돛롸토; 000 = 쭉서繫돛0; 001 = 쭉서繫돛1; 010 = 쭉서繫돛2; 011 = 쭉서繫돛3
ad9680_write(0x5b3, 0x1); //SERDOUT1÷繫돛롸토; 000 = 쭉서繫돛0; 001 = 쭉서繫돛1; 010 = 쭉서繫돛2; 011 = 쭉서繫돛3
ad9680_write(0x5b5, 0x2); //SERDOUT2÷繫돛롸토; 000 = 쭉서繫돛0; 001 = 쭉서繫돛1; 010 = 쭉서繫돛2; 011 = 쭉서繫돛3
ad9680_write(0x5b6, 0x3); //SERDOUT3÷繫돛롸토; 000 = 쭉서繫돛0; 001 = 쭉서繫돛1; 010 = 쭉서繫돛2; 011 = 쭉서繫돛3
ad9680_write(AD9680_REG_JESD204B_SCR_LAN, 0x83); //0x58b JESD204B parameters SCR/L
temp = ad9680_read(AD9680_REG_JESD204B_SCR_LAN);
if(temp != 0x83){
printf("AD9680_REG_JESD204B_SCR_LAN ERROR! %x\r\n", temp);
}
ad9680_write(AD9680_REG_JESD204B_MF_CTRL, 0x1f); //0x58d mf-frame-count
temp = ad9680_read(AD9680_REG_JESD204B_MF_CTRL);
if(temp != 0x1f){
printf("AD9680_REG_JESD204B_MF_CTRL ERROR! %x\r\n", temp);
}
ad9680_write(AD9680_REG_JESD204B_CSN_CONFIG, 0x0f); //0x58f 14-bit
temp = ad9680_read(AD9680_REG_JESD204B_CSN_CONFIG);
if(temp != 0x0f){
printf("AD9680_REG_JESD204B_CSN_CONFIG ERROR! %x\r\n", temp);
}
ad9680_write(AD9680_REG_JESD204B_SUBCLASS_CONFIG, 0x2f); //0x590 subclass-1, N'=16
temp = ad9680_read(AD9680_REG_JESD204B_SUBCLASS_CONFIG);
if(temp != 0x2f){
printf("AD9680_REG_JESD204B_SUBCLASS_CONFIG ERROR! %x\r\n", temp);
}
ad9680_write(AD9680_REG_JESD204B_QUICK_CONFIG, 0x89); //0x570 m=2, l=4, f= 1
temp = ad9680_read(AD9680_REG_JESD204B_QUICK_CONFIG);
if(temp != 0x89){
printf("AD9680_REG_JESD204B_QUICK_CONFIG ERROR! %x\r\n", temp);
}
if (speed < 625) {
ad9680_write(AD9680_REG_JESD204B_LANE_RATE_CTRL, 0x10); // low line rate mode must be enabled
} else {
ad9680_write(AD9680_REG_JESD204B_LANE_RATE_CTRL, 0x00); //0x56e low line rate mode must be disabled
}
temp = ad9680_read(AD9680_REG_JESD204B_LANE_RATE_CTRL);
if(temp != ((speed < 625) ? 0x10 : 0x00)){
printf("AD9680_REG_JESD204B_LANE_RATE_CTRL ERROR! %x\r\n", temp);
}
ad9680_write(AD9680_REG_LINK_CONTROL, 0x14); //0x571 link enable
temp = ad9680_read(AD9680_REG_LINK_CONTROL);
if(temp != 0x14){
printf("AD9680_REG_LINK_CONTROL ERROR! %x\r\n", temp);
}
tsc_delay(250000);
pll_stat = ad9680_read(AD9680_REG_JESD204B_PLL_LOCK_STATUS);//0x56f
if ((pll_stat & 0x80) != 0x80)
printf("AD9680: PLL is NOT locked!\r\n");
else
printf("AD9680: PLL is Succeed!\r\n");
/*jesd204 reset*/
tsc_delay(10000);
printf("jesd204 reset \r\n");
axi0_write(0x1044, 0x1);
axi0_write(0x1044, 0x0);
printf("AD9680 setup complete...\r\n");
return 0;
}
static int do_ad9680(cmd_tbl_t tbl, int argc, char *argv[])
{
uint32_t reg, val;
if (argc == 3 && argv[1][0] == 'r') {
reg = strtoul(argv[2], NULL, 0);
ad9680_read(reg & 0xffff);
} else if (argc == 4 && argv[1][0] == 'w') {
reg = strtoul(argv[2], NULL, 0);
val = strtoul(argv[3], NULL, 0);
ad9680_write(reg & 0xffff, val & 0xff);
} else if (argc == 3 && argv[1][0] == 's') {
val = strtoul(argv[2], NULL, 0);
ad9680_setup(val);
} else {
printf("usge: %s [r/w] [reg] [val] \r\n", argv[0]);
}
return 0;
}
CON_CMD(ad9680, "ad9680 reg opts", NULL, do_ad9680)

18
src/ad9680.h

@ -0,0 +1,18 @@
/*
* ad9680.h
*
* Created on: 2019-6-13
* Author: Administrator
*/
#ifndef AD9680_H_
#define AD9680_H_
/*
* 6678 | <---- spi cs1 ---->| K7A | <--- spi --> ad9680
* <- gpio12~15 cs0 ->|
* */
extern uint8_t ad9680_read(uint16_t reg);
extern int ad9680_write(uint16_t reg, uint8_t val);
extern int ad9680_setup(uint32_t speed);
#endif /* AD9280_H_ */

179
src/ad9779.c

@ -0,0 +1,179 @@
/*
* ad9779.c
*
* Created on: 2019-7-16
* Author: Administrator
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <vsky/libdsp/inc/tsc.h>
#include <vslib/vbios.h>
#include "gspi.h"
#include "axi1.h"
#include "ad9779.h"
static gspi_t _ad9779 = NULL;
static int __gspi_ad9779_init(void )
{
spi_dev_cfg_s format = {
.mode = SPI_CLK_MODE_1,
.speed = 5000000,
.bits = 8,
.endian = 0,
.t2delay = 0,
};
_ad9779 = gspi_open(GSPI_CS_AD9779, &format);
return 0;
}
uint8_t ad9779_read(uint8_t reg)
{
uint8_t buf[2];
int elms;
if (!_ad9779)
__gspi_ad9779_init();
buf[0] = 0x80 | reg;
elms = gspi_xfer(_ad9779, buf, 0, 1, &buf[1], 1, 1);
if (elms != sizeof buf) {
printf("error: ad9779 reg 0x%x read fail\r\n", reg);
return 0;
}
printf("ad9779 read reg:0x%04x, val: 0x%x\r\n", reg, buf[1]);
return buf[1];
}
int ad9779_write(uint8_t reg, uint8_t val)
{
uint8_t buf[2];
int elms;
if (!_ad9779)
__gspi_ad9779_init();
buf[0] = 0x7f & reg;
buf[1] = val;
elms = gspi_xfer(_ad9779, buf, 0, 2, NULL, 0, 0);
if (elms != sizeof buf) {
printf("error: ad9779 reg 0x%x write fail\r\n", reg);
return -1;
}
printf("ad9779 write reg:0x%04x, val: 0x%x\r\n", reg, val);
return 0;
}
int ad9779_setup(uint32_t fclk, uint32_t f0)
{
uint32_t val;
uint8_t f1, div;
uint8_t log[16 + 1] = { 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4};
/* refclk = 125Mhz
* VCO = refclk * N1 * N2; - 2G
* DACCLK = VCO / N1; - 1G
* DATACLK = DACCLK / F1; - 125M
* fclk = DATACLK / DATACLKDIV
*
* N1 = 2, N2 = 8, F1 = 8
* */
/* enable pll, set n1, n2;
* reg09:
* [7] enable pll
* [6~5] VCO = DACCLK * N1; 00-1, 01-2, 10-4, 11-8,
* [4~3] DACCLK = REFCLK * N2; 00-2, 01-4, 10-8, 11-16
* [2~0] 011 - The best performance
* */
val = (0x1 << 7) | (log[2] << 5) | ((log[8] - 1) << 3) | 0x3;
ad9779_write(0x09, val);
/* pll rate rang select (1956 ~ 2008)
* reg08:
* [7~2] 111101: 61 rate range
* [1~0] 11: The best performance
* */
ad9779_write(0x08, 0xf7);
/* wait pll lock
* reg00:
* [2] 0-unlock, 1-lock
* */
tsc_delay(10);
if ((0x2 & ad9779_read(0x00)))
printf("AD9779 PLL is Locked \r\n");
else
printf("AD9779: PLL is NOT locked!\r\n");
if (fclk < 125000000) {
f1 = 8;
div = 125000000 / fclk;
} else {
f1 = 1000000000 / fclk;
div = 1;
}
/* set f1
* reg01:
* [7:6] 00-1x, 01-2x, 10-4x, 11-8x
* */
val = ad9779_read(0x01);
val &= 0x3F;
val |= (log[f1] & 0x3) << 6;
ad9779_write(0x01, val);
/* set DATACLK
* reg03
* [5:4]: 00-1div, 01-2div, 10-4div, 11-1div
* **/
val = ad9779_read(0x03);
val &= 0xCF;
val |= (log[div] & 0x3) << 4;
ad9779_write(0x03, val);
/*
* same cfg ad9779 by axi bus
* */
//ad9779 sync
axi1_write(0x1004, 0x1);
axi1_write(0x1004, 0x0);
//ad9779 tx enable
axi1_write(0x1008, 0x1);
//FCW val
val = f0 / (fclk / 65536) ;
axi1_write(0x100C, val);
return 0;
}
static int do_ad9779(cmd_tbl_t tbl, int argc, char *argv[])
{
uint32_t reg, val;
if (argc == 3 && argv[1][0] == 'r') {
reg = strtoul(argv[2], NULL, 0);
ad9779_read(reg & 0xff);
} else if (argc == 4 && argv[1][0] == 'w') {
reg = strtoul(argv[2], NULL, 0);
val = strtoul(argv[3], NULL, 0);
ad9779_write(reg & 0xff, val & 0xff);
} else if (argc == 4 && argv[1][0] == 's') {
uint32_t fclk, f0;
fclk = atoi(argv[2]);
f0 = atoi(argv[3]);
ad9779_setup(fclk, f0);
} else {
printf("usge: %s [r/w/s] [reg/fclk] [val/f0] \r\n", argv[0]);
}
return 0;
}
CON_CMD(ad9779, "ad9779 reg opts", NULL, do_ad9779)

20
src/ad9779.h

@ -0,0 +1,20 @@
/*
* ad9779.h
*
* Created on: 2019-7-16
* Author: Administrator
*/
#ifndef AD9779_H_
#define AD9779_H_
/*
* 6678 | <--- spi cs1 ---> | K7A | <---> | K7B | <--- spi --> ad9779
* <- gpio12~15 cs6 ->|
*
* */
extern uint8_t ad9779_read(uint8_t reg);
extern int ad9779_write(uint8_t reg, uint8_t val);
extern int ad9779_setup(uint32_t fclk, uint32_t f0);
#endif /* AD9779_H_ */

89
src/axi0.c

@ -0,0 +1,89 @@
/*
* axi0.c
*
* Created on: 2019-7-17
* Author: Administrator
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <vslib/vbios.h>
#include "gspi.h"
#include "axi0.h"
static gspi_t _axi0 = NULL;
int axi0_init(void )
{
spi_dev_cfg_s format = {
.mode = SPI_CLK_MODE_1,
.speed = 5000000,
.bits = 8,
.endian = 0,
.t2delay = 0,
};
_axi0 = gspi_open(GSPI_CS_AXI0, &format);
return 0;
}
uint32_t axi0_read(uint32_t reg)
{
uint8_t w[3];
uint8_t r[4]; //M byte first
uint32_t val;
if (!_axi0)
axi0_init();
w[0] = 0x80 | ((reg >> 16) & 0xff); //bit[15]: 1-read, 0-write
w[1] = (reg >> 8)& 0xff;
w[2] = reg & 0xff;
gspi_xfer(_axi0, w, 0, 3, r, 3, 4);
val = ((r[0] << 24) | (r[1] << 16) | (r[2] << 8) | r[3]);
return val;
}
int axi0_write(uint32_t reg, uint32_t val)
{
uint8_t d[7];
if (!_axi0)
axi0_init();
d[0] = 0x7F & (reg >> 16);
d[1] = (reg >> 8) & 0xff;
d[2] = reg & 0xff;
d[3] = val >> 24 & 0xff; //M byte first
d[4] = val >> 16 & 0xff;
d[5] = val >> 8 & 0xff;
d[6] = val & 0xff;
gspi_xfer(_axi0, d, 0, 7, NULL, 0, 0);
return 0;
}
static int do_axi0(cmd_tbl_t tbl, int argc, char *argv[])
{
uint32_t reg, val;
if (argc == 3 && argv[1][0] == 'r') {
reg = strtoul(argv[2], NULL, 0);
val = axi0_read(reg);
printf("axi0 read reg:0x%04x, val: 0x%x\r\n", reg, val);
} else if (argc == 4 && argv[1][0] == 'w') {
reg = strtoul(argv[2], NULL, 0);
val = strtoul(argv[3], NULL, 0);
axi0_write(reg, val);
printf("axi0 write reg:0x%04x, val: 0x%x\r\n", reg, val);
} else {
printf("usge: %s [r/w] [reg] [val] \r\n", argv[0]);
}
return 0;
}
CON_CMD(axi0, "axi0 reg opts", NULL, do_axi0)

24
src/axi0.h

@ -0,0 +1,24 @@
/*
* axi0.h
*
* Created on: 2019-7-17
* Author: Administrator
*/
#ifndef AXI0_H_
#define AXI0_H_
/*
* 6678 | <---- spi cs1 ---->| K7A internal axi
* <- gpio12~15 cs1 ->|
* axi0 mem mmap
* 0x0000 ~ 0x0fff: ad9680 config space
* 0x1000 ~ 0x1fff: I/O space
* 0x2000 ~ 0x3fff: serv
* 0x4000 ~ 0x7fff: 16K mem space
* */
extern uint32_t axi0_read(uint32_t reg);
extern int axi0_write(uint32_t reg, uint32_t val);
#endif /* AXI0_H_ */

86
src/axi1.c

@ -0,0 +1,86 @@
/*
* axi1.c
*
* Created on: 2019-7-17
* Author: Administrator
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <vslib/vbios.h>
#include "gspi.h"
#include "axi1.h"
static gspi_t _axi1 = NULL;
static int __gspi_axi1_init(void )
{
spi_dev_cfg_s format = {
.mode = SPI_CLK_MODE_1,
.speed = 5000000,
.bits = 8,
.endian = 0,
.t2delay = 0,
};
_axi1 = gspi_open(GSPI_CS_AXI1, &format);
return 0;
}
uint32_t axi1_read(uint32_t reg)
{
uint8_t w[3];
uint8_t r[4]; //M byte first
uint32_t val;
if (!_axi1)
__gspi_axi1_init();
w[0] = 0x80 | ((reg >> 16) & 0xff); //bit[15]: 1-read, 0-write
w[1] = (reg >> 8) & 0xff;
w[2] = reg & 0xff;
gspi_xfer(_axi1, w, 0, 3, r, 3, 4);
val = ((r[0] << 24) | (r[1] << 16) | (r[2] << 8) | r[3]);
return val;
}
int axi1_write(uint32_t reg, uint32_t val)
{
uint8_t d[7];
if (!_axi1)
__gspi_axi1_init();
d[0] = 0x7F & (reg >> 16);
d[1] = (reg >> 8) & 0xff;
d[2] = reg & 0xff;
d[3] = val >> 24 & 0xff; //M byte first
d[4] = val >> 16 & 0xff;
d[5] = val >> 8 & 0xff;
d[6] = val & 0xff;
gspi_xfer(_axi1, d, 0, 7, NULL, 0, 0);
return 0;
}
static int do_axi1(cmd_tbl_t tbl, int argc, char *argv[])
{
uint32_t reg, val;
if (argc == 3 && argv[1][0] == 'r') {
reg = strtoul(argv[2], NULL, 0);
val = axi1_read(reg & 0xffff);
printf("axi1 read reg: 0x%x, val: 0x%x \r\n", reg, val);
} else if (argc == 4 && argv[1][0] == 'w') {
reg = strtoul(argv[2], NULL, 0);
val = strtoul(argv[3], NULL, 0);
axi1_write(reg & 0xffff, val);
printf("axi1 write reg: 0x%x, val: 0x%x \r\n", reg, val);
} else {
printf("usge: %s [r/w] [reg] [val] \r\n", argv[0]);
}
return 0;
}
CON_CMD(axi1, "axi1 reg opts", NULL, do_axi1)

25
src/axi1.h

@ -0,0 +1,25 @@
/*
* axi1.h
*
* Created on: 2019-7-17
* Author: Administrator
*/
#ifndef AXI1_H_
#define AXI1_H_
/*
* 6678 | <---- spi cs1 ---->| K7A| <--> |K7B internal axi
* <- gpio12~15 cs8 ->|
* axi0 mem mmap
* 0x0000 ~ 0x0fff: ad9361 config space
* 0x1000 [0] ad9779 reset pin
* 0x1004 [0] ad9779 sync pin
* 0x1008 [0] ad9779 tx enable pin
* 0x100C [0] ad9779 FCW val
* */
extern uint32_t axi1_read(uint32_t reg);
extern int axi1_write(uint32_t reg, uint32_t val);
#endif /* AXI1_H_ */

107
src/emif_test.c

@ -0,0 +1,107 @@
/*
* emif_cfg.c
*
* Created on: 2019-6-3
* Author: Administrator
*/
#include <stdio.h>
#include <stdlib.h>
#include <vsky/libdsp/inc/tsc.h>
#include <vsky/libdsp/inc/emif.h>
#include <vslib/vbios.h>
#include "emif_test.h"
#define NAND_CS0 (0)
#define NAND_CS1 (1)
#define SP3_CS (3)
int emif_init(void )
{
unsigned int bitmode = 0;
bitmode = (NAND_MODE << NAND_CS0) | (NAND_MODE << NAND_CS1) | (NOR_ASRAM_MODE << SP3_CS);
emif16_init_ex(bitmode);
return 0;
}
static int do_sp3r(cmd_tbl_t tbl, int argc, char *argv[])
{
uint32_t bass;
unsigned int reg;
uint32_t addr;
uint16_t val;
if (argc >= 2) {
reg = strtoul(argv[1], NULL, 0);
bass = emif16_chip_base(SP3_CS);
addr = bass + (reg << 1);
val = *(volatile uint16_t *)(addr);
printf("r reg: 0x%x, val: 0x%x, [0x%08x] \r\n", reg, val, addr);
}
return (0);
}
CON_CMD(sp3r, "read sp3 reg", NULL, do_sp3r)
static int do_sp3w(cmd_tbl_t tbl, int argc, char *argv[])
{
uint32_t bass;
unsigned int reg, val;
uint32_t addr;
if (argc >= 3) {
bass = emif16_chip_base(SP3_CS);
reg = strtoul(argv[1], NULL, 0);
val = strtoul(argv[2], NULL, 0);
addr = bass + (reg << 1);
*(volatile uint16_t *)(addr) = val & 0xffff;
printf("w reg: 0x%x, val: 0x%x, [0x%08x] \r\n", reg, val, addr);
}
return 0;
}
CON_CMD(sp3w, "write sp3 reg", NULL, do_sp3w)
static int do_er(cmd_tbl_t tbl, int argc, char *argv[])
{
int cs;
unsigned int reg, regbase, val;
if (argc >= 3) {
cs = atoi(argv[1]);
if (cs >= 0 && cs <= 3) {
reg = strtoul(argv[2], NULL, 0);
regbase = emif16_chip_base(cs);
val = *(volatile uint16_t *)(regbase + reg);
printf("r [%08x] %02x: %04x\r\n", (regbase + reg), reg, val);
}
}
return 0;
}
CON_CMD(er, "read reg from cs x", NULL, do_er)
static int do_ew(cmd_tbl_t tbl, int argc, char *argv[])
{
int cs;
unsigned int reg, regbase, val;
if (argc >= 4) {
cs = atoi(argv[1]);
if (cs >= 0 && cs <= 3) {
reg = strtoul(argv[2], NULL, 0);
val = strtoul(argv[3], NULL, 0);
regbase = emif16_chip_base(cs);
*(volatile uint16_t *)(regbase + reg) = val;
printf("w [%08x] %02x: %04x\r\n", (regbase + reg), reg, val);
}
}
return 0;
}
CON_CMD(ew, "write reg to cs x", NULL, do_ew)

20
src/emif_test.h

@ -0,0 +1,20 @@
/*
* emif_cfg.h
*
* Created on: 2019-6-3
* Author: Administrator
*/
#ifndef EMIF_CFG_H_
#define EMIF_CFG_H_
/*
* EMIF
* CS0 --> NAND
* CS1 --> XC3S400AN
* CS2 --> XC3S400AN
* CS3 --> XC3S400AN
* */
int emif_init(void );
#endif /* EMIF_CFG_H_ */

117
src/gspi.c

@ -0,0 +1,117 @@
/*
* gspi.c
*
* Created on: 2019-7-11
* Author: Administrator
*/
#include <stdio.h>
#include <string.h>
#include <vsky/libdsp/inc/tsc.h>
#include <vsky/libdsp/inc/gpio.h>
#include "vsdef.h"
#include "gspi.h"
struct gspi_controller;
struct gspi {
int cs;
spi_dev_cfg_s format;
struct gspi_controller *gc;
};
struct gspi_controller {
spi_dev_t sd;
int spi_cs;
int gpio_num;
int gpio_id[GPIO_MAX_COUNT];
int cs_count;
struct gspi gs[GSPI_MAX_CS_COUNT];
gspi_t last_gs;
};
static struct gspi_controller _gc;
int gspi_init(int spi_cs, int gpio_num, int gpio_id[])
{
int i, gs_count = 1;
struct gspi_controller *gc = &_gc;
spi_dev_cfg_s _def = {
SPI_CLK_MODE_0,
25000000,
8,
0,
0
};
memset(gc, 0, sizeof *gc);
gc->sd = spi_dev_open(0, spi_cs, &_def);
gc->spi_cs = spi_cs;
gc->gpio_num = gpio_num;
//init gpio setout
for (i = 0; i < gpio_num; ++i) {
gpio_init(gpio_id[i], GPIOF_OUT);
gc->gpio_id[i] = gpio_id[i];
gs_count *= 2;
}
//init busy gpio
gpio_init(K7_SPI_BUSY_GPIO, GPIOF_IN);
gc->cs_count = gs_count;
gc->last_gs = NULL;
return 0;
}
gspi_t gspi_open(int cs, spi_dev_cfg_s *format)
{
struct gspi_controller *gc = &_gc;
if (cs < gc->cs_count) {
gspi_t gs = &gc->gs[cs];
gs->cs = cs;
memcpy(&gs->format, format, sizeof *format);
gs->gc = gc;
return gs;
}
return NULL;
}
int gspi_xfer(gspi_t gs, const void *tx, uint32_t first_tx_elms, uint32_t tx_elms, void *rx, uint32_t first_rx_elms, uint32_t rx_elms)
{
int i, ret = 0, timeout = 0;
struct gspi_controller *gc = gs->gc;
//gspi cs
for (i = 0; i < gc->gpio_num; ++i)
gpio_set_value(gc->gpio_id[i], (gs->cs & 0x1 << i) ? 1 : 0);
//when opt ad9361 and axi1, must check gpio busy
if (gs->cs == GSPI_CS_AD9361 || gs->cs == GSPI_CS_AXI1) {
while((gpio_get_value(K7_SPI_BUSY_GPIO) & 0x1) == 0) {
if (timeout++ > 20) {//20ms timeout
printf("warning: gspi opt ad9361 or axi1, bus always busy \r\n");
goto _exit;
}
tsc_delay(1000);
}
}
/*advance.*/
if (gc->last_gs != gs) {
//cfg formate
spi_dev_set_cfg(gc->sd, &gs->format);
gc->last_gs = gs;
}
ret = spi_dev_xfer(gc->sd, tx, first_tx_elms, tx_elms, rx, first_rx_elms, rx_elms);
_exit:
//gspi cs
for (i = 0; i < gc->gpio_num; ++i)
gpio_set_value(gc->gpio_id[i], 0);
return ret;
}

39
src/gspi.h

@ -0,0 +1,39 @@
/*
* gspi.h
*
* Created on: 2019-7-11
* Author: Administrator
*/
#ifndef GSPI_H_
#define GSPI_H_
#include <vsky/libdsp/inc/spi.h>
/*
* spi cs and n gpio ext to more
* */
#define GPIO_MAX_COUNT 4
#define GSPI_MAX_CS_COUNT 16 // 2 ^ 4;
int gspi_init(int spi_cs, int gpio_num, int gpio_id[]);
enum {
GSPI_CS_AD9680 = 1,
GSPI_CS_AXI0,
GSPI_CS_LVCOMS5,
GSPI_CS_LVCOMS6,
GSPI_CS_LVCOMS7,
GSPI_CS_LVCOMS8,
GSPI_CS_AD9779,
GSPI_CS_AD9361,
GSPI_CS_AXI1,
};
typedef struct gspi *gspi_t;
gspi_t gspi_open(int cs, spi_dev_cfg_s *format);
int gspi_xfer(gspi_t gs, const void *tx, uint32_t first_tx_elms, uint32_t tx_elms,
void *rx, uint32_t first_rx_elms, uint32_t rx_elms);
#endif /* GSPI_H_ */

230
src/k7_download.c

@ -0,0 +1,230 @@
/*
* k7_download.c
*
* Created on: 2019-6-10
* Author: Administrator
*/
#include <stdio.h>
#include <stdlib.h>
#include <vsky/libdsp/inc/tsc.h>
#include <vsky/libdsp/inc/emif.h>
#include <vslib/vbios.h>
#include "vsdef.h"
/*
* 6678 | -- emif cs3 -- | SP3 | -- SeletMAP cs0 -- | K7 A |
* cs1 -- | K7 B |
*
* */
#define EMIF_SP3_CS (3)
#define K7_A_FPGA_M 0x5
#define K7_B_FPGA_M 0x6
#define K7_A_PROG 0x7
#define K7_B_PROG 0x8
#define K7_A_CS 0x9
#define K7_B_CS 0xA
#define K7_A_CLK 0xB
#define K7_B_CLK 0xC
#define K7_WR 0xd
#define K7_DATA 0xe
#define K7_A_DONE 0xF
#define K7_B_DONE 0x10
#define K7_A_INIT 0x11
#define K7_B_INIT 0x12
#define SWAP_BYTES 1
struct k7_reg {
uint32_t m;
uint32_t prog;
uint32_t cs;
uint32_t clk;
uint32_t wr;
uint32_t data;
uint32_t done;
uint32_t init;
};
static struct k7_reg _k7[2] = {
{K7_A_FPGA_M, K7_A_PROG, K7_A_CS, K7_A_CLK, K7_WR, K7_DATA, K7_A_DONE, K7_A_INIT},
{K7_B_FPGA_M, K7_B_PROG, K7_B_CS, K7_B_CLK, K7_WR, K7_DATA, K7_B_DONE, K7_B_INIT}
};
#define mdelay(x) tsc_delay((x) * 1000)
#define udelay(x) tsc_delay(x)
static uint8_t swap_uint8(uint8_t data){
uint8_t swapped;
if (SWAP_BYTES == 1){
swapped =( data << 4 )|( data >> 4 );
swapped =((swapped << 2) & 0xcc) | ((swapped >> 2) & 0x33);
swapped =((swapped << 1) & 0xaa) | ((swapped >> 1) & 0x55);
}
else
swapped = data;
return swapped;
}
static int sp3_reg_write(uint32_t reg, uint16_t val)
{
uint32_t addr;
addr = emif16_chip_base(EMIF_CS_SP3) + (reg << 1);
*(volatile uint16_t *)addr = val & 0xffff;
//printf("w reg: 0x%x, val: 0x%x, [0x%08x] \r\n", reg, val, addr);
return 0;
}
static uint16_t sp3_reg_read(uint32_t reg)
{
uint32_t addr;
addr = emif16_chip_base(EMIF_CS_SP3) + (reg << 1);
return *(volatile uint16_t *)addr & 0xffff;
}
static void shift_cclk(struct k7_reg *k7, uint32_t count)
{
uint32_t i;
sp3_reg_write(k7->clk, 0);
for (i = 0; i < count; ++i) {
sp3_reg_write(k7->clk, 1);
sp3_reg_write(k7->clk, 0);
}
}
static void shift_word_out(struct k7_reg *k7, uint8_t data8)
{
sp3_reg_write(k7->data, data8 & 0xFF);
shift_cclk(k7, 1);
}
int k7_flashboot(int k7_id)
{
uint32_t i = 0;
struct k7_reg *k7 = &_k7[k7_id]; //d36
/*M(2:0) set boot mode*/
if (k7_id == 0)
sp3_reg_write(k7->m, 0x2); //Master BPI mode for d11
else
sp3_reg_write(k7->m, 0x1); //Master SPI mode for d36
mdelay(2);
sp3_reg_write(k7->prog, 1);
sp3_reg_write(k7->cs, 1);
/*Configuration Reset*/
sp3_reg_write(k7->prog, 0);
mdelay(2);
sp3_reg_write(k7->prog, 1);
/* wait for DONE to assert */
i = 0;
while(sp3_reg_read(k7->done) == 0) {
mdelay(100);
if (i++ > 200) {
printf("err: done has not gone high \r\n");
return -3;
}
}
printf("K7 %c BOOT Success \r\n", (k7_id == 0) ? 'A' : 'B');
return 0;
}
int k7_download(int k7_id, uint32_t mem_addr, uint32_t len)
{
uint32_t i = 0;
volatile uint8_t *data = (uint8_t *)mem_addr;
struct k7_reg *k7 = &_k7[k7_id];
/*M(2:0) set 110 for SelectMap mode*/
sp3_reg_write(k7->m, 0x6);
mdelay(2);
sp3_reg_write(k7->clk, 0);
/*Bring cs, wr low and prog high*/
sp3_reg_write(k7->prog, 1);
sp3_reg_write(k7->wr, 0);
sp3_reg_write(k7->cs, 0);
mdelay(2);
/*Configuration Reset*/
sp3_reg_write(k7->prog, 0);
mdelay(2);
sp3_reg_write(k7->prog, 1);
/*wait for device initialization*/
while(sp3_reg_read(k7->init) == 0) {
if (++i > 200) {
printf("err: init has not gone high \r\n");
return -1;
}
mdelay(1);
}
/*configuration load*/
for (i = 0; i < len; ++i) {
shift_word_out(k7, swap_uint8(*(data + i)));
//udelay(2);
}
/*check init must be high*/
if (sp3_reg_read(k7->init) == 0) {
printf("err: init has be low \r\n");
return -2;
}
/* wait for DONE to assert */
i = 0;
while(sp3_reg_read(k7->done) == 0) {
shift_cclk(k7, 1);
if (i++ > 0x10000) {
printf("err: done has not gone high \r\n");
return -3;
}
}
/*compenstate for special startup conditions. */
shift_cclk(k7, 8);
printf("K7 %c BIN Download Success \r\n", (k7_id == 0) ? 'A' : 'B');
/*M(2:0) set 5 JTAG mode */
sp3_reg_write(k7->m, 5);
sp3_reg_write(k7->cs, 1);
return 0;
}
int do_k7(cmd_tbl_t tbl, int argc, char *argv[])
{
int k7_id = 0;
uint32_t mem_addr;
uint32_t len;
if (argc >= 4) {
k7_id = atoi(argv[1]);
mem_addr = strtoul(argv[2], NULL, 0);
len = strtoul(argv[3], NULL, 0);
printf("k7 %d mem: 0x%x, len: %d start upgrade\r\n", k7_id, mem_addr, len);
k7_download(k7_id, mem_addr, len);
}
return 0;
}
CON_CMD(k7, "k7 bin upgrade", NULL, do_k7)

20
src/k7_download.h

@ -0,0 +1,20 @@
/*
* k7_down.h
*
* Created on: 2019-6-10
* Author: Administrator
*/
#ifndef K7_DOWNLOAD_H_
#define K7_DOWNLOAD_H_
/*
* 1. dsp --> emif cs1 --> fpga --> k7 A/B
* */
int k7_download(int k7_id, uint32_t mem_addr, uint32_t len);
/*cfg k7 from spi/pbi boot*/
int k7_flashboot(int k7_id);
#endif /* K7_DOWN_H_ */

271
src/main.c

@ -0,0 +1,271 @@
/*
* main.c
*
* Created on: 2019-5-29
* Author: Administrator
*/
#include <stdio.h>
#include <string.h>
#include <xdc/std.h>
#include <xdc/runtime/System.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Queue.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/knl/Clock.h>
#include <ti/ndk/inc/netmain.h>
#include <vsky/libdsp/inc/tsc.h>
#include <vsky/libdsp/inc/emif.h>
#include <vsky/libdsp/inc/power_ctrl.h>
#include <vsky/libdsp/inc/gpio.h>
#include <vsky/libdsp/inc/spi.h>
#include <vsky/libdsp/inc/uart.h>
#include <vsky/libdsp/hispeed/resource_mgr.h>
#include <vsky/libdsp/hispeed/interrupt.h>
#include <vslib/vbios.h>
#include "vsdef.h"
#include "norflash.h"
#include "nandflash.h"
#include "ad9680.h"
#include "gspi.h"
#include "k7_download.h"
#include "srio.h"
#include "runtime.h"
#define mdelay(x) tsc_delay((x) * 1000)
static vsem_t _vsem = NULL;
static timer_t _tm = NULL;
static uart_t _u;
extern int net_server(SOCKET s, UINT32 unused);
static void __trigger_timer(void *param)
{
k7_trigger(); //1-first: trigger k7 start sample.
}
static void __k7_gpio_intr(void *arg)
{
if (_vsem)
vsem_signal(_vsem); //2-second: k7 data already sample complete.
}
static void __sample_task(void )
{
int ret;
printf("sample task running ... \r\n");
while(1) {
ret = vsem_wait(_vsem, 100);
if (ret == 0) {
vtask_sleep(10);
continue;
} else if (ret < 0) { //err
printf("sample task wait sem fail \r\n");
break;
} else {
k7_sample(); //3-second: dsp recv sample data by spi
}
}
}
static int __uart_puts(const char *s, int len)
{
static char last_ch = 0x00;
int i;
if (len < 0)
len = strlen(s);
for (i = 0; i < len; ++i) {
if(!(s[i] == ' ' && last_ch == '\r'))
uart_write(_u, s[i]);
last_ch = s[i];
}
return len;
}
static int __uart_gets(char *buf, int len, int blocking /*in millis*/)
{
static uint8_t _buf[1024];
static uint32_t _n = 0;
if (blocking <= 0) {
while(_n < sizeof _buf) {
if (uart_is_ready(_u))
_buf[_n++] = uart_read(_u);
else
break;
}
} else {
while(blocking > 0 && _n < sizeof _buf) {
if (uart_is_ready(_u)) {
_buf[_n++] = uart_read(_u);
} else {
if (_n >= len) {
break;
} else {
mdelay(1);
blocking--;
}
}
}
}
if (len > _n)
len = _n;
memcpy(buf, _buf, len);
_n -=len;
if (_n > 0)
memmove(_buf, &_buf[len], _n);
return len;
}
static void __usr_drv_init(void )
{
//systme tsc init.
tsc_init();
// uart init
do {
_u = uart_open(0);
uart_set_baudrate(_u, 115200);
uart_set_databits(_u, 8);
uart_set_stopbits(_u, 1);
uart_set_parity(_u, 0);
} while(0);
//emif bus init.
do {
unsigned int bitmode = 0;
bitmode = (NAND_MODE << EMIF_CS_NAND0) | (NAND_MODE << EMIF_CS_NAND1) | (NOR_ASRAM_MODE << EMIF_CS_SP3);
emif16_init_ex(bitmode);
} while(0);
//spi bus init
spi_bus_init(0, SPI_PIN_MODE_4);
//gpio + spi
do {
int gpio_id[] = {
K7_SPI_CS_GPIO_0,
K7_SPI_CS_GPIO_1,
K7_SPI_CS_GPIO_2,
K7_SPI_CS_GPIO_3
};
gspi_init(SPI_CS_K7, sizeof gpio_id / sizeof gpio_id[0], gpio_id);
} while(0);
//gpio intr by k7 use
do {
//cfg gpio input mode and enable rise edge intr.
gpio_init(K7_INTR_GPIO, GPIOF_IN);
gpio_bank_interrupt(0, 1);
gpio_set_rising_edge_interrupt(K7_INTR_GPIO, 1);
//register intr handle func
intr_install_mode2(CSL_GEM_GPINT11, NULL, __k7_gpio_intr);
} while(0);
//resource init
resource_mgr_init();
}
static void __usr_app_prev_func(void )
{
//nor
nor_init();
//nand
nand_init();
//runtime
runtime_init();
}
static void __app_run(void )
{
//startup k7 (D11) and (D36) code
if (1) { //from tftp
uint32_t size;
size = vtftp_load_file("192.168.0.18", "ppb_d11.bit", 0xC0000000);
k7_download(0, 0xC0000000, size);
mdelay(5);
size = vtftp_load_file("192.168.0.18", "ppb_d36.bit", 0xC0000000);
k7_download(1, 0xC0000000, size);
} else { //from D11 BPI / D36 SPI
k7_flashboot(0);
mdelay(5);
k7_flashboot(1);
}
mdelay(20);
//startup SRIO
srio_init();
//startup AD9680
ad9680_setup(1000);
//start a sample task from ad9680
_vsem = vsem_new();
vtask_create(__sample_task);
//create a server task for pc read sample data
DaemonNew( SOCK_DGRAM, 0, DEFAULT_PORT, net_server, OS_TASKPRINORM, OS_TASKSTKNORM, 0, 1);
//start a timer and pre 1s trigger once
_tm = timer_new(250, NULL, __trigger_timer);
timer_active(_tm);
while(1) {
vbios_loop();
vtask_sleep(5);
}
}
void main (int argc, char *argv[])
{
struct vbios_param vp;
struct vbios_term_param term_param = {__uart_puts, __uart_gets};
struct vbios_net_param net_param = {1, "192.168.0.123", "255.255.255.0", "192.168.0.1", "mydemo"};
vp.tp = &term_param;
vp.np = &net_param;
vp.usrDrvInitFunc = __usr_drv_init;
vp.usrAppPrevFunc = __usr_app_prev_func;
vp.usrAppFunc = __app_run;
vbios_init(&vp);
vbios_start();
}
int enter_pragrom_mode(void )
{
if (_tm)
timer_deactive(_tm);
intr_disable();
return 0;
}
int enter_run_mode(void )
{
if (_tm)
timer_active(_tm);
intr_enable();
return 0;
}

100
src/nandflash.c

@ -0,0 +1,100 @@
/*
* nandflash.c
*
* Created on: 2019-7-8
* Author: Administrator
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <vsky/libdsp/inc/nand.h>
#include <vslib/vbios.h>
#define NAND_TARGET0_CS 0 //emif cs0 --> nand target 0
#define NAND_TARGET1_CS 1 //emif cs1 --> nand target 1
static nand_flash_t g_nand;
int nand_init(void )
{
g_nand = nand_flash_open(NAND_TARGET0_CS, 0);
printf("nand manu id: 0x%x, dev id: %x \r\n", g_nand->manu_id, g_nand->dev_id);
printf("nand size: %d MB (%d block * %d pages * %d Byte) \r\n", \
(g_nand->block_count * (g_nand->page_count_per_block * g_nand->data_bytes_per_page / 1024)) / 1024,
g_nand->block_count, g_nand->page_count_per_block, g_nand->data_bytes_per_page);
return 0;
}
int nand_program(unsigned int mem_bass, unsigned int nand_addr, unsigned int size)
{
return 0;
}
int nand_test(unsigned int block, unsigned int num)
{
int err = 0;
unsigned int i, page;
uint8_t w_page[8192 + 744], r_page[8192 + 744];
while(num-- > 0) {
nand_flash_earse_block(g_nand, block);
for (page = 0; page < g_nand->page_count_per_block; ++page) {
for (i = 0; i < g_nand->data_bytes_per_page; ++i) {
w_page[i] = (page + i);
r_page[i] = 0;
}
nand_flash_write_page(g_nand, block, page, w_page);
nand_flash_read_page(g_nand, block, page, r_page);
for (i = 0; i < g_nand->data_bytes_per_page; ++i) {
if (r_page[i] != w_page[i]) {
err++;
printf("error: data invaild block: %d, page: %d, offset: %d \r\n", block, page, i);
break;
}
}
}
printf("nand block%d test: %s \r\n", block++, (err == 0) ? "success" : "fail");
}
return 0;
}
static int do_nand(cmd_tbl_t tbl, int argc, char *argv[])
{
if (argc >= 2 && (argv[1][0] == 't')) {
unsigned int block;
unsigned int num;
if (argc != 4) {
printf("usge: %s t [start_block] [count]\r\n", argv[0]);
return -1;
}
block = strtoul(argv[2], NULL, 0);
num = strtoul(argv[3], NULL, 0);
return nand_test(block, num);
}
if (argc >= 2 && argv[1][0] == 'w') {
unsigned int mem_bass;
unsigned int nand_addr;
unsigned int size;
if (argc != 5) {
printf("usge: %s w [mem_addr] [nand_addr] [size]\r\n", argv[0]);
return -1;
}
mem_bass = strtoul(argv[2], NULL, 0);
nand_addr = strtoul(argv[3], NULL, 0);
size = strtoul(argv[4], NULL, 0);
return nand_program(mem_bass, nand_addr, size);
}
printf("usge: %s [t/w] ... \r\n", argv[0]);
return 0;
}
CON_CMD(nand, "nand opts", NULL, do_nand)

15
src/nandflash.h

@ -0,0 +1,15 @@
/*
* nandflash.h
*
* Created on: 2019-7-8
* Author: Administrator
*/
#ifndef NANDFLASH_H_
#define NANDFLASH_H_
extern int nand_init(void );
extern int nand_program(unsigned int mem_bass, unsigned int nand_addr, unsigned int size);
#endif /* NANDFLASH_H_ */

169
src/norflash.c

@ -0,0 +1,169 @@
/*
* nor_test.c
*
* Created on: 2019-6-3
* Author: Administrator
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vsky/libdsp/inc/tsc.h>
#include <vsky/libdsp/inc/nor.h>
#include <vslib/vbios.h>
#include "vsdef.h"
void nor_test(nor_flash_t nf, unsigned int start_offset, unsigned int leng)
{
uint32_t test_addr;
uint32_t sector_size;
uint8_t src[4096];
uint8_t dest[4096];
int i, err = 0;
if (!nf) {
printf("fail: nor flash don't init \r\n");
return;
}
sector_size = nor_flash_sector_size(nf);
nor_flash_erase(nf, start_offset / sector_size, (start_offset + leng)/ sector_size);
for (test_addr = start_offset; test_addr < (start_offset + leng); test_addr += sector_size) {
for (i = 0; i < sizeof src; ++i) {
src[i] = i;
dest[i] = 0;
}
nor_flash_write(nf, src, test_addr, sizeof src);
tsc_delay(1000);
nor_flash_read(nf, dest, test_addr, sizeof dest);
err = 0;
for (i = 0; i < sizeof dest; ++i) {
if (src[i] != dest[i])
err++;
}
printf("nor test addr: 0x%x result err = %d \r\n", test_addr, err);
}
printf("nor test complete... \r\n");
}
static nor_flash_t _nf;
int nor_init(void )
{
uint32_t total_size, sectors;
_nf = nor_flash_open(NOR_FLASH_MODE_SPI, SPI_CS_NOR, 0);
total_size = nor_flash_size(_nf);
sectors = nor_flash_sectors(_nf);
printf("nor size: %dMB, sectors: %d \r\n", total_size / 1024 / 1024, sectors);
return 0;
}
int nor_program(unsigned int mem_bass, unsigned int nor_addr, unsigned int size)
{
int ret = 0;
nor_flash_t nf = _nf;
unsigned int total_size, block_count, block_size;
unsigned int block;
unsigned char *data = (unsigned char *)mem_bass;
unsigned char *buf;
unsigned int i, len, leng = 0;
if (!nf) {
printf("fail: nor flash don't init \r\n");
return -1;
}
total_size = nor_flash_size(nf);
block_count = nor_flash_sectors(nf);
block_size = nor_flash_sector_size(nf);
if (!(buf = malloc(block_size))) {
printf("fail: malloc block buff error \r\n");
return -1;
}
if (nor_addr + size > total_size) {
printf("fail: data size more than flash size \r\n");
return -2;
}
for (block = nor_addr / block_size; block < block_count; ++block) {
//erase block.
nor_flash_erase(nf, block, block);
//write data.
len = (size < block_size) ? size : block_size;
nor_flash_write(nf, data, nor_addr, len);
//verfiy data.
nor_flash_read(nf, buf, nor_addr, len);
for (i = 0; i < len; ++i) {
if (buf[i] != data[i]) {
printf("data verfiy fail: block: %d, i = %d \r\n", block, i);
ret = -1;
goto _exit;
}
}
data += len;
size -= len;
nor_addr += len;
leng += len;
printf("write file data to nor: %d \r\n", leng);
if (size <= 0)
break;
}
_exit:
return ret;
}
static int do_nor(cmd_tbl_t tbl, int argc, char *argv[])
{
if (argc >= 2) {
if (argv[1][0] == 't') {
unsigned int start_addr;
unsigned int leng;
if (argc != 4) {
printf("usge: %s t [addr] [leng]\r\n", argv[0]);
return -1;
}
start_addr = strtoul(argv[2], NULL, 0);
leng = strtoul(argv[3], NULL, 0);
enter_pragrom_mode();
nor_test(_nf, start_addr, leng);
enter_run_mode();
} else if (argv[1][0] == 'w') {
unsigned int mem_bass;
unsigned int nor_addr;
unsigned int size;
if (argc != 5) {
printf("usge: %s w [mem_addr] [nor_addr] [size]\r\n", argv[0]);
return -1;
}
mem_bass = strtoul(argv[2], NULL, 0);
nor_addr = strtoul(argv[3], NULL, 0);
size = strtoul(argv[4], NULL, 0);
enter_pragrom_mode();
nor_program(mem_bass, nor_addr, size);
enter_run_mode();
} else {
printf("usge: %s [t/w] ... \r\n", argv[0]);
return -1;
}
}
return 0;
}
CON_CMD(nor, "nor opts", NULL, do_nor)

15
src/norflash.h

@ -0,0 +1,15 @@
/*
* nor_test.h
*
* Created on: 2019-6-6
* Author: Administrator
*/
#ifndef NOR_TEST_H_
#define NOR_TEST_H_
int nor_init(void );
extern int nor_program(unsigned int mem_bass, unsigned int nor_addr, unsigned int size);
#endif /* NOR_TEST_H_ */

192
src/runtime.c

@ -0,0 +1,192 @@
/*
* runtime.c
*
* Created on: 2019-7-12
* Author: Administrator
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/ndk/inc/netmain.h>
#include <vslib/vbios.h>
#include "axi0.h"
#include "runtime.h"
#define SAMPLE_DATA_LENG (16 * 1024)
struct runtime {
vlock_t lock;
uint8_t count;
uint8_t w_i;
uint8_t r_i;
uint8_t resv;
uint8_t data_pp[2][SAMPLE_DATA_LENG];
uint8_t recv_buf[8192];
};
static struct runtime _rt;
static int dma_data(SOCKET sfd, struct sockaddr_in *from)
{
uint8_t *data;
uint32_t timeout = 0;
uint32_t buf[256 + 2] = {0};
int tot = 0, max;
const int hdr_size = 2 * sizeof buf[0];
//poll wait sample data recv complete.
while(_rt.count == 0) {
if (timeout++ >= 2000) {
printf("wait sample data time out \r\n");
break;
}
Task_sleep(1);
}
vlock_lock(_rt.lock);
_rt.count--;
data = _rt.data_pp[_rt.r_i];
vlock_unlock(_rt.lock);
max = sizeof buf - hdr_size;
buf[0] = 'd';
while(tot < SAMPLE_DATA_LENG) {
buf[1] = ((SAMPLE_DATA_LENG - tot) > max) ? max : (SAMPLE_DATA_LENG - tot);
memcpy(&buf[2], data + tot, buf[1]);
sendto(sfd, buf, sizeof buf, 0, (PSA)from, sizeof *from);
tot += buf[1];
}
buf[1] = 0;
sendto(sfd, buf, hdr_size, 0, (PSA)from, sizeof *from);
return 0;
}
static int do_process(SOCKET sfd, void *buf, int len, struct sockaddr_in *from, int *quit)
{
unsigned int *cmdbuf = (uint32_t *)buf;
unsigned int cmd;
if (len < sizeof cmdbuf[0])
return -1;
/*
* buf define
* word0 | word1 | word2 | word3
* cmd cs reg val
*
*/
cmd = cmdbuf[0];
switch (cmd) {
case 'd': /* read sample data. */
dma_data(sfd, from);
break;
case 't': /* send trigger to k7, start sample data. */
k7_trigger();
break;
default :
break;
}
return 0;
}
int net_server( SOCKET s, UINT32 unused )
{
struct sockaddr_in sin1;
struct timeval to;
int len, tmp;
char *pBuf;
HANDLE hBuffer;
int quit = 0;
(void)unused;
// Configure our socket timeout to be 2 seconds
to.tv_sec = 2;
to.tv_usec = 0;
setsockopt( s, SOL_SOCKET, SO_SNDTIMEO, &to, sizeof( to ) );
setsockopt( s, SOL_SOCKET, SO_RCVTIMEO, &to, sizeof( to ) );
for(;;)
{
tmp = sizeof( sin1 );
len = (int)recvncfrom( s, (void **)&pBuf, 0, (PSA)&sin1, &tmp, &hBuffer );
// Spit any data back out
if( len >= 0 )
{
if (len <= sizeof _rt.recv_buf)
memcpy(_rt.recv_buf, pBuf, len);
else {
printf("error: udp packet more than 8k \n");
break;
}
do_process(s, _rt.recv_buf, len, &sin1, &quit);
recvncfree( hBuffer );
}
else
break;
}
// Since the socket is still open, return "1"
// (we need to leave UDP sockets open)
return (quit == 0) ? 1 : 0;
}
int runtime_init()
{
memset(&_rt, 0, sizeof _rt);
_rt.lock = vlock_new();
return 0;
}
void k7_trigger(void )
{
axi0_write(0x1048, 1);
axi0_write(0x1048, 0);
}
int k7_sample(void )
{
int i;
uint32_t *val = (uint32_t *)_rt.data_pp[_rt.w_i];
uint16_t addr_bass = 0x4000;
// printf("AAA %d \r\n", time_millis());
for (i = 0; i < SAMPLE_DATA_LENG / 4; ++i) {
val[i] = axi0_read(addr_bass);
addr_bass += 4;
}
// printf("BBB %d \r\n", time_millis());
vlock_lock(_rt.lock);
if (_rt.count++ == 1)
_rt.count = 1;
_rt.r_i = _rt.w_i;
_rt.w_i = (_rt.w_i == 0) ? 1 : 0;
vlock_unlock(_rt.lock);
return 0;
}
static int do_mm(cmd_tbl_t tbl, int argc, char *argv[])
{
unsigned int addr, val;
if (argc == 3 && argv[1][0] == 'r') {
addr = strtoul(argv[2], 0, NULL);
val = *(volatile unsigned int *)addr;
printf("0x%08x: 0x%08x \r\n", addr, val);
} else {
printf("usage. %s [r] [addr] \r\n", argv[0]);
}
return 0;
}
CON_CMD(mm, "mm show opt", NULL, do_mm);

15
src/runtime.h

@ -0,0 +1,15 @@
/*
* runtime.h
*
* Created on: 2019-7-12
* Author: Administrator
*/
#ifndef RUNTIME_H_
#define RUNTIME_H_
extern int runtime_init();
extern void k7_trigger(void );
extern int k7_sample(void );
#endif /* RUNTIME_H_ */

246
src/srio.c

@ -0,0 +1,246 @@
/*
* srio.c
*
* Created on: 2019-7-25
* Author: Administrator
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <vsky/libdsp/inc/tsc.h>
#include <vsky/libdsp/hispeed/resource_mgr.h>
#include <vsky/libdsp/hispeed/srio_func_ext.h>
#include <vslib/vbios.h>
#include "srio.h"
#include "axi0.h"
#include "axi1.h"
#define SRIO_LOCAL_MEM_SRC 0xC0000000
#define SRIO_LOCAL_MEM_DEST 0xE0000000
#define SRIO_FPGA_MEM_DEST 0x11110000
typedef struct sd {
uint16_t node_id;
struct {
uint16_t k7_node;
int srio_port;
vsem_t sem;
}k7[2];
}sd_s;
static sd_s srio;
static void __data_init(uint32_t leng, uint32_t times)
{
int i;
uint8_t bass = times & 0xff;
uint32_t *src = (uint32_t *)SRIO_LOCAL_MEM_SRC;
uint32_t *dest = (uint32_t *)SRIO_LOCAL_MEM_DEST;
for (i = 0; i < leng / 4; ++i) {
src[i] = (bass << 24) | i;
dest[i] = 0xffffffff;
}
Osal_CacheWriteBack(src, leng);
Osal_CacheWriteBack(dest, leng);
}
void __data_verify(uint32_t leng, uint32_t times)
{
int i, err = 0;
uint32_t *src = (uint32_t *)SRIO_LOCAL_MEM_SRC;
uint32_t *dest = (uint32_t *)SRIO_LOCAL_MEM_DEST;
Osal_CacheInvalidate(src, leng);
Osal_CacheInvalidate(dest, leng);
for (i = 0; i < leng / 4; ++i) {
if (src[i] != dest[i]) {
err++;
printf("0x%08x: 0x%08x (0x%08x)\r\n", (uint32_t)&dest[i], dest[i], src[i]);
}
}
printf("srio swrite poll test time %d result: %s (err = %d) \r\n", times, (err == 0) ? "success" : "fail", err);
}
static void __doorbell_cb(int port, void *param)
{
sd_s *sr = (sd_s *)param;
if (port == sr->k7[0].srio_port)
vsem_signal(sr->k7[0].sem);
if (port == sr->k7[1].srio_port)
vsem_signal(sr->k7[1].sem);
}
int srio_init(void)
{
memset(&srio, 0, sizeof srio);
srio.node_id = SRIO_NODE_DSP;
srio.k7[0].k7_node = SRIO_NODE_K7A;
srio.k7[0].srio_port = 2;
srio.k7[0].sem = vsem_new();
srio.k7[1].k7_node = SRIO_NODE_K7B;
srio.k7[1].srio_port = 0;
srio.k7[1].sem = vsem_new();
srio_func_init(srio.node_id, &srio, __doorbell_cb);
printf("srio link ok \r\n");
//init test data buff.
__data_init(0x100000, 0);
//axi0 init fgpa srio cfg
axi0_write(0x2014, 0x1);
axi0_write(0x2010, 0xd11);
axi0_write(0x200C, 0xd31);
axi1_write(0x2014, 0x1);
axi1_write(0x2010, 0xd36);
axi1_write(0x200C, 0xd31);
//d11
axi0_write(0x2018, SRIO_LOCAL_MEM_DEST);
axi0_write(0x201C, SRIO_FPGA_MEM_DEST);
axi0_write(0x2020, 256);
//d36
axi1_write(0x2018, SRIO_LOCAL_MEM_DEST);
axi1_write(0x201C, SRIO_FPGA_MEM_DEST);
axi1_write(0x2020, 256);
return 0;
}
int srio_swrite(int k7_id, uint32_t mem_addr, uint32_t rapid_addr, uint32_t len, int doorbell_enable)
{
return srio_func_swrite(srio.k7[k7_id].srio_port, srio.k7[k7_id].k7_node, (uint8_t *)mem_addr, (uint8_t *)rapid_addr, len, doorbell_enable);
}
int srio_nread(int k7_id, uint32_t mem_addr, uint32_t rapid_addr, uint32_t len)
{
return srio_func_nread(srio.k7[k7_id].srio_port, srio.k7[k7_id].k7_node, (uint8_t *)rapid_addr, (uint8_t *)mem_addr, len);
}
int srio_doorbell(int k7_id)
{
return srio_func_doorbell(srio.k7[k7_id].srio_port, srio.k7[k7_id].k7_node);
}
static int do_srio(cmd_tbl_t tbl, int argc, char *argv[])
{
int i, ret, k7_id = 0;
uint32_t leng, times;
if (argc == 2) {
if (argv[1][0] == 'u') {
printf("cache invalid .. \r\n");
Osal_CacheInvalidate((void *)SRIO_LOCAL_MEM_DEST, 0x100000);
Osal_Sync();
} else {
goto _usage;
}
} else if (argc == 3) {
if (argv[1][0] == 'd') {
k7_id = atoi(argv[2]);
printf("srio k7_%c doorbell \r\n", (k7_id == 0 ? 'A' : 'B'));
srio_doorbell(k7_id);
} if (argv[1][0] == 's'){
/*
k7_id = atoi(argv[2]);
leng = 0x100000;
unsigned int start;
unsigned int MB = 0;
start = time_millis();
if (k7_id == 0)
axi0_write(0x2020, leng);
else
axi1_write(0x2020, leng);
do {
srio_swrite(k7_id, SRIO_LOCAL_MEM_SRC, SRIO_FPGA_MEM_DEST, leng, 1);
//wait fpga send doorbell
ret = vsem_wait(srio.k7[k7_id].sem, 10000);
if (ret <= 0) {
printf("wait sem fail or timeout!!!! \r\n");
break;
}
MB += 2;
} while((time_millis() - start) < 1000);
printf("srio with k7_%c speed test 1s tran %d MByte \r\n", (k7_id == 0) ? 'A' : 'B', MB);
*/
unsigned int start, end;
unsigned int nlen = 0;
k7_id = atoi(argv[2]);
leng = 0x10000000; //256M
__data_init(leng, k7_id);
if (k7_id == 0)
axi0_write(0x2020, leng);
else
axi1_write(0x2020, leng);
start = time_millis();
printf("speed test start time %d ms \r\n", start);
while(nlen < leng) {
srio_swrite(k7_id, SRIO_LOCAL_MEM_SRC + nlen, SRIO_FPGA_MEM_DEST + nlen, 0x100000, 0);
nlen += 0x100000;
}
srio_doorbell(k7_id);
vsem_wait(srio.k7[k7_id].sem, 0);
end = time_millis();
printf("speed test end time %d ms \r\n", end);
__data_verify(leng, k7_id);
printf("srio with k7_%c tran %d MByte use %d ms\r\n", (k7_id == 0) ? 'A' : 'B', (leng * 2) / 0x100000, (end - start));
}else {
goto _usage;
}
} else if (argc == 5) {
if (argv[1][0] == 't') {
k7_id = atoi(argv[2]);
leng = strtoul(argv[3], 0, NULL);
times = strtoul(argv[4], 0, NULL);
if (leng & 0xff != 0) {
printf("warn: leng must algin 256B \r\n");
leng &= 0xFFFFFF00;
}
printf("srio with k7_%c poll test from fpga leng: 0x%x, times: %d \r\n", (k7_id == 0) ? 'A' : 'B', leng, times);
if (k7_id == 0)
axi0_write(0x2020, leng);
else
axi1_write(0x2020, leng);
for (i = 0; i < times; ++i) {
__data_init(leng, i);
srio_swrite(k7_id, SRIO_LOCAL_MEM_SRC, SRIO_FPGA_MEM_DEST, leng, 1);
//wait fpga send doorbell
ret = vsem_wait(srio.k7[k7_id].sem, 10000);
if (ret == 0) { //timeout
printf("srio with k7%d poll test times %d ,wait doorbell timeout !!!!\r\n", k7_id, i);
return 0;
} else if (ret < 0) { //fail
printf("srio with k7%d poll test times %d ,wait sync signal fail !!!!\r\n", k7_id, i);
} else { //suceess
__data_verify(leng, i);
}
}
}
}
return 0;
_usage:
printf("usage: %s [k7_id: 0/1] [func: s/n/d] [fpga_addr] [data_len] \r\n", argv[0]);
return 0;
}
CON_CMD(srio, "srio opts", NULL, do_srio)

20
src/srio.h

@ -0,0 +1,20 @@
/*
* srio.h
*
* Created on: 2019-7-25
* Author: Administrator
*/
#ifndef SRIO_H_
#define SRIO_H_
#define SRIO_NODE_DSP 0xD31
#define SRIO_NODE_K7A 0xD11
#define SRIO_NODE_K7B 0xD36
extern int srio_init(void );
extern int srio_swrite(int k7_id, uint32_t mem_addr, uint32_t rapid_addr, uint32_t len, int doorbell_enable);
extern int srio_nread(int k7_id, uint32_t mem_addr, uint32_t rapid_addr, uint32_t len);
extern int srio_doorbell(int k7_id);
#endif /* SRIO_H_ */

35
src/vsdef.h

@ -0,0 +1,35 @@
/*
* vsdef.h
*
* Created on: 2019-7-5
* Author: Administrator
*/
#ifndef VSDEF_H_
#define VSDEF_H_
/*emif cs define*/
#define EMIF_CS_NAND0 (0) // emif cs0 --> nand target0
#define EMIF_CS_NAND1 (1) // emif cs1 --> nand target1
#define EMIF_CS_SP3 (3) // emif cs3 --> XC3S400AN (fpga)
/*spi cs define*/
#define SPI_CS_NOR (0) //spi cs0 --> nor flash
#define SPI_CS_K7 (1) //spi cs1 --> K7 A
/* gpio as spi cs1 ext cs pin */
#define K7_SPI_CS_GPIO_0 (12)
#define K7_SPI_CS_GPIO_1 (13)
#define K7_SPI_CS_GPIO_2 (14)
#define K7_SPI_CS_GPIO_3 (15)
#define K7_SPI_BUSY_GPIO (9)
#define K7_INTR_GPIO (11)
extern int enter_pragrom_mode(void );
extern int enter_run_mode(void );
#define DEFAULT_PORT 64000
#endif /* VSDEF_H_ */

16
targetConfigs/TMS320C6678.ccxml

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<configurations XML_version="1.2" id="configurations_0">
<configuration XML_version="1.2" id="configuration_0">
<instance XML_version="1.2" desc="Spectrum Digital XDS560V2 STM USB Emulator" href="connections/SD560V2USB_Connection.xml" id="Spectrum Digital XDS560V2 STM USB Emulator" xml="SD560V2USB_Connection.xml" xmlpath="connections"/>
<connection XML_version="1.2" id="Spectrum Digital XDS560V2 STM USB Emulator">
<instance XML_version="1.2" href="drivers/tixds560icepick_d.xml" id="drivers" xml="tixds560icepick_d.xml" xmlpath="drivers"/>
<instance XML_version="1.2" href="drivers/tixds560c66xx.xml" id="drivers" xml="tixds560c66xx.xml" xmlpath="drivers"/>
<instance XML_version="1.2" href="drivers/tixds560cs_dap.xml" id="drivers" xml="tixds560cs_dap.xml" xmlpath="drivers"/>
<instance XML_version="1.2" href="drivers/tixds560csstm.xml" id="drivers" xml="tixds560csstm.xml" xmlpath="drivers"/>
<instance XML_version="1.2" href="drivers/tixds560etbcs.xml" id="drivers" xml="tixds560etbcs.xml" xmlpath="drivers"/>
<platform XML_version="1.2" id="platform_0">
<instance XML_version="1.2" desc="TMS320C6678" href="devices/C6678.xml" id="TMS320C6678" xml="C6678.xml" xmlpath="devices"/>
</platform>
</connection>
</configuration>
</configurations>

9
targetConfigs/readme.txt

@ -0,0 +1,9 @@
The 'targetConfigs' folder contains target-configuration (.ccxml) files, automatically generated based
on the device and connection settings specified in your project on the Properties > General page.
Please note that in automatic target-configuration management, changes to the project's device and/or
connection settings will either modify an existing or generate a new target-configuration file. Thus,
if you manually edit these auto-generated files, you may need to re-apply your changes. Alternatively,
you may create your own target-configuration file for this project and manage it manually. You can
always switch back to automatic target-configuration management by checking the "Manage the project's
target-configuration automatically" checkbox on the project's Properties > General page.

9
vslib/cmdline.cmd

@ -0,0 +1,9 @@
--retain="*(.cmdline_cmd)"
SECTIONS
{
.dsp_cmd_section: fill = 0x0 align =0x4 {
__cmdline_cmd_start = .;
*(.cmdline_cmd)
__cmdline_cmd_end = .;
} > DDR3
}

246
vslib/vbios.c

@ -0,0 +1,246 @@
/*
* vbios.c
*
* Created on: 2019-8-13
* Author: Administrator
*/
#include <ti/sysbios/BIOS.h>
#include <ti/ndk/inc/netmain.h>
#include <ti/ndk/inc/tools/servers.h>
#include "vbios.h"
struct vbios {
int net_enable;
struct vbios_net_param vnp;
struct vbios_term_param vtp;
struct vbios_param vp;
vsem_t sem;
};
static struct vbios _vs;
static HANDLE hCfg;
static char *TaskName[] = { "Telnet","HTTP","NAT","DHCPS","DHCPC","DNS" };
static char *ReportStr[] = { "","Running","Updated","Complete","Fault" };
static char *StatusStr[] = { "Disabled","Waiting","IPTerm","Failed","Enabled" };
static void NetworkOpen(void )
{
/* Create our local servers */
TaskCreate( echosrv, "echosrv", OS_TASKPRINORM, 0x1400, 0, 0, 0 );
vsem_signal(_vs.sem);
}
static void NetworkClose(void )
{
}
static void NetworkIPAddr( IPN IPAddr, uint32_t IfIdx, uint32_t fAdd )
{
IPN IPTmp;
if( fAdd )
printf("Network Added: ");
else
printf("Network Removed: ");
/* Print a message */
IPTmp = ntohl( IPAddr );
printf("If-%d:%d.%d.%d.%d \r\n", IfIdx,
(uint8_t)(IPTmp>>24)&0xFF, (uint8_t)(IPTmp>>16)&0xFF,
(uint8_t)(IPTmp>>8)&0xFF, (uint8_t)IPTmp&0xFF );
return;
}
static void service_report( uint32_t item, uint32_t status, uint32_t report, HANDLE h )
{
printf( "Service Status: %-9s: %-9s: %-9s \r\n", TaskName[item-1], StatusStr[status],ReportStr[report/256]);
}
static void __net_ndk_start(void )
{
int32_t rc;
struct vbios_net_param *vnp = &_vs.vnp;
/* Start the NDK stack - The stack will start the Ethernet driver */
rc = NC_SystemOpen( NC_PRIORITY_HIGH, NC_OPMODE_INTERRUPT );
if( rc ) {
printf("NC_SystemOpen Failed (%d). Will die in an infinite loop so you need to reset...\n",rc);
for(;;);
}
/*
* Create and build the system configuration from scratch.
*/
/* Create a new configuration */
if (!(hCfg = CfgNew())) {
printf("Unable to create a configuration for the IP stack.\n");
goto _exit;
}
do {
CI_IPNET NA;
/* Setup an IP address to this EVM */
bzero( &NA, sizeof(NA) );
NA.IPAddr = inet_addr(vnp->ip);
NA.IPMask = inet_addr(vnp->mask);
strcpy( NA.Domain, vnp->domain);
/* Add the address to interface 1 */
CfgAddEntry( hCfg, CFGTAG_IPNET, 1, 0, sizeof(CI_IPNET), (uint8_t *)&NA, 0 );
}while(0);
if (_vs.vnp.telnet_enable) {
CI_SERVICE_TELNET telnet;
/*telnet init same param*/
vtelnetd_init();
/* Specify TELNET service */
bzero( &telnet, sizeof(telnet) );
telnet.cisargs.IPAddr = INADDR_ANY;
telnet.cisargs.pCbSrv = &service_report;
telnet.param.MaxCon = TELNET_CLINET_MAX_COUNT;
telnet.param.Callback = &vtelnetd_client;
CfgAddEntry( hCfg, CFGTAG_SERVICE, CFGITEM_SERVICE_TELNET, 0,
sizeof(telnet), (uint8_t *)&telnet, &(telnet.cisargs.hService) );
}
/*
** Configure IPStack/OS Options
*/
/* Set debug message level */
rc = DBG_WARN;
CfgAddEntry( hCfg, CFGTAG_OS, CFGITEM_OS_DBGPRINTLEVEL,
CFG_ADDMODE_UNIQUE, sizeof(uint), (uint8_t *)&rc, 0 );
/*
** This code sets up the TCP and UDP buffer sizes
** (Note 8192 is actually the default. This code is here to
** illustrate how the buffer and limit sizes are configured.)
*/
/* TCP Transmit buffer size */
//rc = 8192;
rc = 64000;
CfgAddEntry( hCfg, CFGTAG_IP, CFGITEM_IP_SOCKTCPTXBUF,
CFG_ADDMODE_UNIQUE, sizeof(uint), (uint8_t *)&rc, 0 );
/* TCP Receive buffer size (copy mode) */
//rc = 8192;
rc = 64000;
CfgAddEntry( hCfg, CFGTAG_IP, CFGITEM_IP_SOCKTCPRXBUF,
CFG_ADDMODE_UNIQUE, sizeof(uint), (uint8_t *)&rc, 0 );
/* TCP Receive limit (non-copy mode) */
//rc = 8192;
rc = 64000;
CfgAddEntry( hCfg, CFGTAG_IP, CFGITEM_IP_SOCKTCPRXLIMIT,
CFG_ADDMODE_UNIQUE, sizeof(uint), (uint8_t *)&rc, 0 );
/* UDP Receive limit */
rc = 8192;
CfgAddEntry( hCfg, CFGTAG_IP, CFGITEM_IP_SOCKUDPRXLIMIT,
CFG_ADDMODE_UNIQUE, sizeof(uint), (uint8_t *)&rc, 0 );
/*
** Boot the system using this configuration
**
** We keep booting until the function returns 0. This allows
** us to have a "reboot" command.
*/
do
{
rc = NC_NetStart( hCfg, NetworkOpen, NetworkClose, NetworkIPAddr );
} while( rc > 0 );
printf("Done with this utility. Shutting things down\n");
/* Delete Configuration */
CfgFree( hCfg );
/* Close the OS */
_exit:
printf("Exiting the system\n");
NC_SystemClose();
}
static void __main_task(void )
{
if (_vs.net_enable) {
vsem_wait(_vs.sem, 0);
fdOpenSession(TaskSelf());
}
if (_vs.vp.usrAppFunc)
_vs.vp.usrAppFunc();
if (_vs.net_enable)
fdCloseSession(TaskSelf());
}
static int __vbios_puts(void *param, const char *s, int len)
{
if (_vs.vtp.puts)
return _vs.vtp.puts(s, len);
return 0;
}
static int __vbios_gets(void *param, char *buf, int len, int blocking /*in millis*/)
{
if (_vs.vtp.gets)
return _vs.vtp.gets(buf, len, blocking);
return 0;
}
static vconsole_t _vb_tty = NULL;
int vbios_init(struct vbios_param *vp)
{
memset(&_vs, 0, sizeof _vs);
memcpy(&_vs.vp, vp, sizeof *vp);
if (vp->tp) {
memcpy(&_vs.vtp, vp->tp, sizeof *vp->tp);
struct vconsole_param vp;
vp.debug_console = 1;
vp.prompt = "vs> ";
vp.param = NULL;
vp.puts = __vbios_puts;
vp.gets = __vbios_gets;
_vb_tty = vconsole_new(&vp);
}
if (vp->usrDrvInitFunc)
vp->usrDrvInitFunc();
if (vp->usrAppPrevFunc)
vp->usrAppPrevFunc();
if (vp->np) {
_vs.net_enable = 1;
memcpy(&_vs.vnp, vp->np, sizeof *vp->np);
_vs.sem = vsem_new();
vtask_create(__net_ndk_start);
}
return 0;
}
void vbios_start(void )
{
vtask_create(__main_task);
BIOS_start();
}
void vbios_loop(void )
{
return vconsole_loop(_vb_tty);
}

45
vslib/vbios.h

@ -0,0 +1,45 @@
/*
* vbios.h
*
* Created on: 2019-8-13
* Author: Administrator
*/
#ifndef VBIOS_H_
#define VBIOS_H_
#include "vtask.h"
#include "vsem.h"
#include "vlock.h"
#include "vtimer.h"
#include "vtelnetd.h"
#include "vtftp.h"
#include "vconsole.h"
#include "vcmd.h"
//std io redirect
struct vbios_term_param {
int (*puts)(const char *s, int len);
int (*gets)(char *buf, int len, int blocking /*in millis*/);
};
struct vbios_net_param {
int telnet_enable;
char ip[32];
char mask[32];
char gate[32];
char domain[32];
};
struct vbios_param {
struct vbios_term_param *tp; //NULL no enable termial
struct vbios_net_param *np; //NULL no enable net
void (*usrDrvInitFunc)(void );
void (*usrAppPrevFunc)(void );
void (*usrAppFunc)(void );
};
extern int vbios_init(struct vbios_param *vp);
extern void vbios_start(void );
extern void vbios_loop(void );
#endif /* VBIOS_H_ */

24
vslib/vcmd.h

@ -0,0 +1,24 @@
#ifndef __CMD_H__
#define __CMD_H__
#ifdef __cplusplus
extern "C" {
#endif
struct cmd_tbl_s {
const char *name;
const char *help;
void * user;
int (*cmd)(struct cmd_tbl_s *, int argc, char *argv[]);
};
typedef struct cmd_tbl_s *cmd_tbl_t;
#define CON_CMD(name, usage, _user, handler) \
struct cmd_tbl_s __con_cmd_##name __attribute__((unused, section(".cmdline_cmd"))) = \
{ #name, usage, _user, handler};
#ifdef __cplusplus
}
#endif
#endif

865
vslib/vconsole.c

@ -0,0 +1,865 @@
/*
* console.c
*
* Created on: 2019-7-4
* Author: Administrator
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "vcmd.h"
#include "vdebug.h"
#include "vconsole.h"
#define TARGET_BUFFER_SIZE (256)
#define PROMPT_MAX_LEN (8)
#define TARGET_CMD_HISTORY 32
#define TARGET_CMD_MAXARGS (8)
enum KEY_ACTION {
KEY_NULL = 0, /* NULL */
CTRL_A = 1, /* Ctrl+a */
CTRL_B = 2, /* Ctrl-b */
CTRL_C = 3, /* Ctrl-c */
CTRL_D = 4, /* Ctrl-d */
CTRL_E = 5, /* Ctrl-e */
CTRL_F = 6, /* Ctrl-f */
CTRL_H = 8, /* Ctrl-h */
TAB = 9, /* Tab */
CTRL_K = 11, /* Ctrl+k */
CTRL_L = 12, /* Ctrl+l */
ENTER = 13, /* Enter */
CTRL_N = 14, /* Ctrl-n */
CTRL_P = 16, /* Ctrl-p */
CTRL_T = 20, /* Ctrl-t */
CTRL_U = 21, /* Ctrl+u */
CTRL_W = 23, /* Ctrl+w */
ESC = 27, /* Escape */
BACKSPACE = 127 /* Backspace */
};
struct console {
char buf[TARGET_BUFFER_SIZE]; /* edited line buffer */
int buflen;
int len; /* current edited line length */
char prompt[PROMPT_MAX_LEN]; /* prompt to display */
int plen; /* prompt length */
int pos; /* current cursor poistion */
int oldpos; /* previouse refresh cursor position */
int cols; /* number of columns in terminal */
int maxrows; /* maximum num of rows used so for (mulitline mode) */
int hindex; /* the history index we are currently editing */
char *history[TARGET_CMD_HISTORY];
int history_len;
/*io interface func*/
void *param;
int (*puts)(void *param, const char *s, int len);
int (*gets)(void *param, char *buf, int len, int blocking /*in millis*/);
int debug_console;
int exit;
char last_ch;
int start; /*0-no prompt, 1- have prompt*/
};
struct linebuf {
char *buf;
int buflen;
int len;
};
extern struct cmd_tbl_s __cmdline_cmd_start, __cmdline_cmd_end;
void *strdup(const char *str)
{
void *m;
int len = strlen(str);
m = calloc(1, len + 1);
memcpy(m, str, len);
return m;
}
static int tputs(vconsole_t cs, const char *buf, int len)
{
if (cs->puts)
cs->puts(cs->param, buf, len);
return len;
}
static int tgets(vconsole_t cs, char *buf, int len, int blocking)
{
int ret;
if (cs->gets)
ret = cs->gets(cs->param, buf, len, blocking);
return ret;
}
static void linebuf_init(struct linebuf *ln, char *buf, int len)
{
ln->buf = buf;
ln->buflen = len;
ln->len = 0;
}
static int linebuf_len(struct linebuf *ln)
{
return ln->len;
}
static int linebuf_append(struct linebuf *ln, const char *s, int len)
{
if (len + ln->len > ln->buflen) {
len = ln->buflen - ln->len;
}
if (len > 0) {
memcpy(ln->buf + ln->len, s, len);
ln->len += len;
}
return (len);
}
/*
* Use the ESC [6n escape sequence to query the horizontal cursor position
* and return it. On error -1 is returned, on success the position of the
* cursor.
*/
static int get_cursor_position(vconsole_t cs)
{
char buf[32];
int cols, rows;
unsigned int i = 0;
/* Report cursor location */
if (tputs(cs, "\x1b[6n", 4) != 4)
return -1;
/* Read the response: ESC [ rows ; cols R */
while (i < sizeof(buf)-1) {
if (tgets(cs, buf + i, 1, 1000) != 1)
break;
if (buf[i] == 'R')
break;
i++;
}
buf[i] = '\0';
/* Parse it. */
if (buf[0] != ESC || buf[1] != '[')
return -1;
if (sscanf(buf+2,"%d;%d",&rows,&cols) != 2)
return -1;
return cols;
}
/*
* Try to get the number of columns in the current terminal, or assume 80
* if it fails.
*/
static int get_columns(vconsole_t cs)
{
char seq[32];
int start, cols;
/* Get the initial position so we can restore it later. */
start = get_cursor_position(cs);
if (start == -1)
goto failed;
/* Go to right margin and get position. */
if (tputs(cs, "\x1b[999C", 6) != 6)
goto failed;
cols = get_cursor_position(cs);
if (cols == -1)
goto failed;
/* Restore position. */
if (cols > start) {
snprintf(seq,32,"\x1b[%dD",cols-start);
if (tputs(cs, seq, strlen(seq)) == -1) {
/* Can't recover... */
}
}
return cols;
failed:
return 80;
}
/*
* Single line low level line refresh.
*
* Rewrite the currently edited line accordingly to the buffer content,
* cursor position, and number of columns of the terminal.
*/
static void refresh_single_line(vconsole_t cs)
{
struct linebuf lb;
char line[512];
char seq[64] = {0};
char *buf = cs->buf;
size_t len = cs->len;
size_t pos = cs->pos;
while((cs->plen + pos) >= cs->cols) {
buf++;
len--;
pos--;
}
while (cs->plen+len > cs->cols) {
len--;
}
linebuf_init(&lb, line, sizeof line);
/* Cursor to left edge */
linebuf_append(&lb, "\r", 1);
linebuf_append(&lb, cs->prompt, cs->plen);
linebuf_append(&lb, buf, len);
/* Erase to right */
linebuf_append(&lb, "\x1b[0K", 4);
/* Move cursor to original position. */
snprintf(seq, 64, "\r\x1b[%dC", (int)(pos + cs->plen));
linebuf_append(&lb, seq, strlen(seq));
tputs(cs, line, linebuf_len(&lb));
}
static void refresh_line(vconsole_t cs)
{
refresh_single_line(cs);
}
/*
* Delete the character at the right of the cursor without altering the cursor
* position. Basically this is what happens with the "Delete" keyboard key.
*/
static void edit_delete(vconsole_t cs)
{
if (cs->len > 0 && cs->pos < cs->len) {
memmove(cs->buf + cs->pos, cs->buf + cs->pos + 1, cs->len - cs->pos - 1);
cs->len--;
cs->buf[cs->len] = '\0';
refresh_line(cs);
}
}
/* Backspace implementation. */
static void edit_backspace(vconsole_t cs)
{
if (cs->pos > 0 && cs->len > 0) {
memmove(cs->buf + cs->pos - 1, cs->buf + cs->pos, cs->len - cs->pos);
cs->pos--;
cs->len--;
cs->buf[cs->len] = '\0';
refresh_line(cs);
}
}
/*
* Delete the previosu word, maintaining the cursor at the start of the
* current word.
*/
static void edit_delete_prev(vconsole_t cs)
{
size_t old_pos = cs->pos;
size_t diff;
while (cs->pos > 0 && cs->buf[cs->pos - 1] == ' ')
cs->pos--;
while (cs->pos > 0 && cs->buf[cs->pos - 1] != ' ')
cs->pos--;
diff = old_pos - cs->pos;
memmove(cs->buf + cs->pos, cs->buf + old_pos, cs->len - old_pos + 1);
cs->len -= diff;
refresh_line(cs);
}
/*
* Insert the character 'c' at cursor current position.
*
* On error writing to the terminal -1 is returned, otherwise 0.
*/
static void edit_insert(vconsole_t cs, char c)
{
if (cs->len < sizeof cs->buf) {
if (cs->len == cs->pos) {
cs->buf[cs->pos] = c;
cs->pos++;
cs->len++;
cs->buf[cs->len] = '\0';
if ((cs->plen + cs->len) < cs->cols) {
/* Avoid a full update of the line in the
* trivial case. */
tputs(cs, &c, 1);
} else {
refresh_line(cs);
}
} else {
memmove(cs->buf + cs->pos + 1, cs->buf + cs->pos, cs->len - cs->pos);
cs->buf[cs->pos] = c;
cs->len++;
cs->pos++;
cs->buf[cs->len] = '\0';
refresh_line(cs);
}
}
}
static void move_right(vconsole_t cs)
{
if (cs->pos != cs->len) {
++cs->pos;
refresh_line(cs);
}
}
static void move_left(vconsole_t cs)
{
if (cs->pos > 0) {
cs->pos--;
refresh_line(cs);
}
}
static void move_home(vconsole_t cs)
{
if (cs->pos != 0) {
cs->pos = 0;
refresh_line(cs);
}
}
static void move_end(vconsole_t cs)
{
if (cs->pos != cs->len) {
cs->pos = cs->len;
refresh_line(cs);
}
}
static int history_add(vconsole_t cs, const char *line)
{
char *copy;
if (cs->history_len && !strcmp(cs->history[cs->history_len - 1], line))
return 0;
copy = strdup(line);
if (!copy)
return 0;
if (cs->history_len == TARGET_CMD_HISTORY) {
free(cs->history[0]);
memmove(cs->history, cs->history + 1, sizeof (char *) * (cs->history_len - 1));
--cs->history_len;
}
cs->history[cs->history_len++] = copy;
return 1;
}
static int history_free(vconsole_t cs)
{
while(cs->history_len > 0) {
--cs->history_len;
if (cs->history[cs->history_len]) {
free(cs->history[cs->history_len]);
cs->history[cs->history_len] = NULL;
}
}
return 0;
}
/*
* Substitute the currently edited line with the next or previous history
* entry as specified by 'dir'
*/
static void edit_history(vconsole_t cs, int dir)
{
if (cs->history_len > 0) {
cs->hindex += dir;
if (cs->hindex < 0) {
cs->hindex = cs->history_len - 1;
} else if (cs->hindex >= cs->history_len) {
cs->hindex = 0;
}
strncpy(cs->buf, cs->history[cs->hindex], cs->buflen);
cs->buf[cs->buflen - 1] = '\0';
cs->len = cs->pos = strlen(cs->buf);
refresh_line(cs);
}
}
static void history_prev(vconsole_t cs)
{
edit_history(cs, -1);
}
static void history_next(vconsole_t cs)
{
edit_history(cs, 1);
}
static void reset_linestate(vconsole_t cs)
{
memset(cs->buf, 0, sizeof cs->buf);
cs->oldpos = 0;
cs->pos = 0;
cs->len = 0;
cs->hindex = cs->history_len;
tputs(cs, cs->prompt, cs->plen);
}
static int get_mached(const char *buf, int len)
{
cmd_tbl_t it = &__cmdline_cmd_start;
int n, mached = 0;
while (it < &__cmdline_cmd_end) {
n = strlen(it->name);
if (n > len)
n = len;
if (memcmp(it->name, buf, n) == 0)
++mached;
++it;
}
return (mached);
}
static int fill_mached(int mached, const char *vec[], const char *buf, int len)
{
cmd_tbl_t it = &__cmdline_cmd_start;
int i = 0, n;
while (it < &__cmdline_cmd_end) {
n = strlen(it->name);
if (n > len)
n = len;
if (memcmp(it->name, buf, n) == 0) {
vec[i++] = it->name;
if (i >= mached)
break;
}
++it;
}
return (i);
}
/*
* This is an helper function for cmd_loop() and is called when the
* user types the <tab> key in order to complete the string currently in the
* input.
*/
static int do_complete_line(vconsole_t cs, int mached)
{
const char *cvec[TARGET_CMD_HISTORY];
int nread, nwritten;
size_t stop = 0, i = 0;
char c = 0;
if (fill_mached(mached, cvec, cs->buf, cs->len) != mached)
return 0;
while(!stop) {
/* Show completion or original buffer */
if (i < mached) {
struct console saved = *cs;
cs->len = cs->pos = strlen(cvec[i]);
sprintf(cs->buf, "%s", (char *)cvec[i]);
refresh_line(cs);
cs->len = saved.len;
cs->pos = saved.pos;
memcpy(cs->buf, saved.buf, saved.buflen);
} else {
refresh_line(cs);
}
nread = tgets(cs, &c, 1, 1000);
if (nread <= 0)
return 0;
switch(c) {
case TAB: /* tab */
i = (i+1) % (mached + 1);
if (i == mached) {
tputs(cs, "\x7", 1); /* beep */
}
break;
case ESC: /* escape */
/* Re-show original buffer */
if (i < mached)
refresh_line(cs);
stop = 1;
break;
default:
/* Update buffer and return */
if (i < mached) {
nwritten = snprintf(cs->buf, cs->buflen, "%s", cvec[i]);
cs->len = cs->pos = nwritten;
}
stop = 1;
break;
}
}
return c; /* Return last read character */
}
static int complete_line(vconsole_t cs)
{
int mached = get_mached(cs->buf, cs->len);
if (mached <= 0) {
tputs(cs, "\x7", 1);
return 0;
}
return do_complete_line(cs, mached);
}
static int parse_line(char *cmd, int len, char *argv[], int _maxargs)
{
int argc;
char *p;
int position;
/* Init params */
p = cmd;
position = 0;
argc = 0;
while ((position < len) && (argc < _maxargs)) {
/* Skip all blanks */
while (((*p) == ' ') && (position < len)) {
*p = '\0';
p++;
position++;
}
/* Process begin of a string */
if (*p == '"') {
p++;
position++;
argv[argc] = p;
argc++;
/* Skip this string */
while ((*p != '"') && (position < len)) {
p++;
position++;
}
/* Skip '"' */
*p = '\0';
p++;
position++;
} else {/* Normal char */
argv[argc] = p;
argc++;
while (((*p) != ' ') && ((*p) != '\t') && (position < len)) {
p++;
position++;
}
}
}
return argc;
}
int cmd_process(vconsole_t cs, char *line)
{
int i, argc, namelen;
int size = strlen(line);
char *argv[TARGET_CMD_MAXARGS + 1];
cmd_tbl_t it = &__cmdline_cmd_start;
/* split line */
for (i = 0; i < TARGET_CMD_MAXARGS + 1; ++i) {
argv[i] = NULL;
}
argc = parse_line(line, size, argv, TARGET_CMD_MAXARGS + 1);
if (argc <= 0)
goto recovery;
debug_update_console(cs);
while (it < &__cmdline_cmd_end) {
namelen = strlen(it->name);
if (strncmp(argv[0], it->name, namelen) == 0) {
it->user = cs;
it->cmd(it, argc, argv);
return 1;
}
++it;
}
/* recovery line */
recovery:
for (i = 0; i < size; ++i) {
if (line[i] == '\0')
line[i] = ' ';
}
return 0;
}
static void do_command(vconsole_t cs)
{
tputs(cs, "\r\n", 2);
if (cs->len > 0) {
/* add to history */
history_add(cs, cs->buf);
cmd_process(cs, cs->buf);
}
//start next cmd, print prompt...
if (!cs->exit)
reset_linestate(cs);
}
vconsole_t vconsole_new(struct vconsole_param *cp)
{
vconsole_t cs;
if (!(cs = calloc(1, sizeof *cs)))
return NULL;
cs->buflen = sizeof cs->buf;
if (cp->prompt) {
cs->plen = strlen(cp->prompt);
memcpy(cs->prompt, cp->prompt, cs->plen);
} else {
strcpy(cs->prompt, "> ");
}
cs->param = cp->param;
cs->puts = cp->puts;
cs->gets = cp->gets;
if (cp->debug_console) {
cs->debug_console = 1;
cs->exit = 0;
debug_init(cs);
}
cs->cols = get_columns(cs);
return cs;
}
void vconsole_free(vconsole_t cs)
{
if (cs) {
history_free(cs);
free(cs);
}
}
int vconsole_puts(vconsole_t cs, const char *s, int len)
{
return tputs(cs, s, len);
}
int vconsole_status(vconsole_t cs)
{
return cs->exit;
}
void vconsole_loop(vconsole_t cs)
{
int nread;
char c, seq[3];
//use firset loop puts "abc> "
if (cs->start == 0) {
reset_linestate(cs);
cs->start = 1;
}
nread = tgets(cs, &c, 1, -1);
if (nread <= 0)
return;
/* if c == TAB, do completion? */
if (c == TAB) {
c = complete_line(cs);
if (c <= 0) {
return;
}
}
switch (c) {
case ENTER: //'\r'
do_command(cs);
break;
case '\n': // '\n'
if (cs->last_ch != ENTER) //'\r\n' pre '\r' already handle
do_command(cs);
break;
case CTRL_C: /* ctrl-c */
reset_linestate(cs);
break;
case BACKSPACE: /* backspace */
case CTRL_H:
edit_backspace(cs);
break;
case CTRL_D: /* ctrl-d, remove the right of cursor. */
if (cs->len > 0) {
edit_delete(cs);
} else {
reset_linestate(cs);
}
break;
case CTRL_T: /* ctrl-t, swaps current char with previous */
if (cs->pos > 0 && cs->pos < cs->len) {
int aux = cs->buf[cs->pos - 1];
cs->buf[cs->pos-1] = cs->buf[cs->pos];
cs->buf[cs->pos] = aux;
if (cs->pos != cs->len - 1) cs->pos++;
refresh_line(cs);
}
break;
case CTRL_B: /* ctrl -b */
move_left(cs);
break;
case CTRL_F: /* ctrl-f */
move_right(cs);
break;
case CTRL_L:
tputs(cs, "\x1b[H\x1b[2J",7);
refresh_line(cs);
break;
case CTRL_U: /* ctrl-u, delete the whole line */
cs->buf[0] = '\0';
cs->pos = cs->len = 0;
refresh_line(cs);
break;
case CTRL_K: /* ctrl-k, delete from current to end of line */
cs->buf[cs->pos] = '\0';
cs->len = cs->pos;
refresh_line(cs);
break;
case CTRL_A: /* ctrl-a, goto start of the line */
move_home(cs);
break;
case CTRL_E: /* ctrl-e, goto end of the line */
move_end(cs);
break;
case CTRL_W:
edit_delete_prev(cs);
break;
case CTRL_P:
history_prev(cs);
break;
case CTRL_N:
history_next(cs);
break;
case ESC: /* escape sequence */
/* Read the next two bytes representing the escape sequence.
* Use two calls to handle slow terminals returning the two
* chars at different times. */
if (tgets(cs, seq, 1, 1000) <= 0)
break;
if (tgets(cs, seq + 1 ,1, 1000) <= 0)
break;
/* ESC [ sequences. */
if (seq[0] == '[') {
if (seq[1] >= '0' && seq[1] <= '9') {
/* Extended escape, read additional byte. */
if (tgets(cs, seq + 2, 1, 1000) <= 0)
break;
if (seq[2] == '~') {
switch(seq[1]) {
case '3': /* Delete key. */
edit_delete(cs);
break;
}
}
} else {
switch(seq[1]) {
case 'A': /* Up */
history_prev(cs);
break;
case 'B': /* Down */
history_next(cs);
break;
case 'C': /* Right */
move_right(cs);
break;
case 'D': /* Left */
move_left(cs);
break;
case 'H': /* Home */
move_home(cs);
break;
case 'F': /* End*/
move_end(cs);
break;
}
}
} else if (seq[0] == 'O') { /* ESC O sequences. */
switch(seq[1]) {
case 'H': /* Home */
move_home(cs);
break;
case 'F': /* End*/
move_end(cs);
break;
}
}
break;
default:
edit_insert(cs, c);
break;
}
cs->last_ch = c;
}
static int do_help(cmd_tbl_t tbl, int argc, char *argv[])
{
cmd_tbl_t it = &__cmdline_cmd_start;
vconsole_t cs = (vconsole_t)tbl->user;
while(it < &__cmdline_cmd_end) {
tputs(cs, it->name, -1);
tputs(cs, "\t", 1);
tputs(cs, it->help, -1);
tputs(cs, "\r\n", 2);
++it;
}
return 0;
}
CON_CMD(help, "mm show opt", NULL, do_help);
static int do_clear(cmd_tbl_t tbl, int argc, char *argv[])
{
vconsole_t cs = (vconsole_t)tbl->user;
tputs(cs, "\x1b[H\x1b[2J",7);
return 0;
}
CON_CMD(clear, "clear the screen", NULL, do_clear);
static int do_exit(cmd_tbl_t tbl, int argc, char *argv[])
{
vconsole_t cs = (vconsole_t)tbl->user;
if (!cs->debug_console)
cs->exit = 1;
return 0;
}
CON_CMD(exit, "exit the console", NULL, do_exit);

27
vslib/vconsole.h

@ -0,0 +1,27 @@
/*
* console.h
*
* Created on: 2019-7-4
* Author: Administrator
*/
#ifndef VCONSOLE_H_
#define VCONSOLE_H_
typedef struct console *vconsole_t;
struct vconsole_param {
int debug_console; /*debug default tty*/
char *prompt; /*NULL use default prompt: '> '*/
void *param;
int (*puts)(void *param, const char *s, int len);
int (*gets)(void *param, char *buf, int len, int blocking /*in millis*/);
};
vconsole_t vconsole_new(struct vconsole_param *cp);
void vconsole_free(vconsole_t cs);
void vconsole_loop(vconsole_t cs);
int vconsole_puts(vconsole_t cs, const char *s, int len);
int vconsole_status(vconsole_t cs); /*return: 0-running, 1-exit*/
#endif /* CONSOLE_H_ */

101
vslib/vdebug.c

@ -0,0 +1,101 @@
/*
* debug.c
*
* Created on: 2019-5-29
* Author: Administrator
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <file.h>
#include <vsky/libdsp/inc/uart.h>
#include "vconsole.h"
#define SERIAL_DEV_NAME "vtty"
static vconsole_t _cs = NULL;
static int dopen (const char *path, unsigned flags, int llv_fd)
{
if (strcmp(path, "stdin") == 0) {
return 0;
} else if (strcmp(path, "stdout") == 0) {
return 1;
} else if (strcmp(path, "stderr")) {
return 2;
}
return -1;
}
static int dclose ( int dev_fd)
{
return 0;
}
static int dread(int dev_fd, char *buf, unsigned count)
{
return 0;
}
static int dwrite(int dev_fd, const char *buf, unsigned count)
{
int n;
if (_cs) {
n = vconsole_puts(_cs, buf, count);
}
return n;
}
static off_t dlseek(int dev_fd, off_t ioffset, int origin)
{
return (off_t)-1;
}
int dunlink(const char * path)
{
return -1;
}
int drename(const char *old_name, const char *new_name)
{
return -1;
}
int debug_init(vconsole_t cs)
{
char dev[64] = {0};
_cs = cs;
add_device(SERIAL_DEV_NAME,
_MSA,
dopen,
dclose,
dread,
dwrite,
dlseek,
dunlink,
drename);
snprintf(dev, sizeof dev, "%s:stderr", SERIAL_DEV_NAME);
freopen(dev, "w", stderr);
snprintf(dev, sizeof dev, "%s:stdout", SERIAL_DEV_NAME);
freopen(dev, "w", stdout);
snprintf(dev, sizeof dev, "%s:stdin", SERIAL_DEV_NAME);
freopen(dev, "r", stdin);
setvbuf(stderr, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stdin, NULL, _IONBF, 0);
return 0;
}
void debug_update_console(vconsole_t cs)
{
_cs = cs;
}

16
vslib/vdebug.h

@ -0,0 +1,16 @@
/*
* debug.h
*
* Created on: 2019-5-29
* Author: Administrator
*/
#ifndef DEBUG_H_
#define DEBUG_H_
#include "vconsole.h"
void debug_init(vconsole_t cs);
void debug_update_console(vconsole_t cs);
#endif /* DEBUG_H_ */

45
vslib/vlock.c

@ -0,0 +1,45 @@
/*
* vlock.c
*
* Created on: 2019-4-2
* Author: Administrator
*/
#include <stdlib.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Clock.h>
#include <ti/sysbios/knl/Semaphore.h>
#include "vlock.h"
struct vlock {
Semaphore_Handle sem;
};
vlock_t vlock_new(void )
{
Semaphore_Params semPrms;
vlock_t vk;
vk = malloc(sizeof *vk);
Semaphore_Params_init(&semPrms);
semPrms.mode = Semaphore_Mode_BINARY;
vk->sem = Semaphore_create(1, &semPrms, NULL);
return vk;
}
void vlock_free(vlock_t vk)
{
if (vk) {
Semaphore_delete(&vk->sem);
free(vk);
vk = NULL;
}
}
void vlock_lock(vlock_t vk)
{
Semaphore_pend(vk->sem, BIOS_WAIT_FOREVER);
}
void vlock_unlock(vlock_t vk)
{
Semaphore_post(vk->sem);
}

17
vslib/vlock.h

@ -0,0 +1,17 @@
/*
* vlock.h
*
* Created on: 2019-4-2
* Author: Administrator
*/
#ifndef VLOCK_H_
#define VLOCK_H_
typedef struct vlock *vlock_t;
vlock_t vlock_new(void );
void vlock_free(vlock_t vk);
void vlock_lock(vlock_t vk);
void vlock_unlock(vlock_t vk);
#endif /* VLOCK_H_ */

67
vslib/vsem.c

@ -0,0 +1,67 @@
/*
* vsem.c
*
* Created on: 2019-3-29
* Author: Administrator
*/
#include <stdlib.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Clock.h>
#include <ti/sysbios/knl/Semaphore.h>
#include "vsem.h"
struct vsem {
Semaphore_Handle sem;
};
vsem_t vsem_new(void )
{
Semaphore_Params semPrms;
vsem_t vs;
vs = malloc(sizeof *vs);
Semaphore_Params_init(&semPrms);
semPrms.mode = Semaphore_Mode_BINARY;
vs->sem = Semaphore_create(0, &semPrms, NULL);
return vs;
}
void vsem_free(vsem_t vs)
{
if (vs) {
Semaphore_delete(&vs->sem);
free(vs);
vs = NULL;
}
}
int vsem_wait(vsem_t vs, unsigned int timeout)
{
UInt bios6_timeout;
Int status;
if (timeout == 0)
bios6_timeout = BIOS_WAIT_FOREVER;
else {
bios6_timeout = timeout / Clock_tickPeriod;
/*
* Don't let nonzero timeout round to 0 - semantically very
* different
*/
if (timeout && (!bios6_timeout)) {
bios6_timeout = 1;
}
}
status = Semaphore_pend(vs->sem, bios6_timeout);
if (status == 1) //success
return 1;
else if (status == 0) //timeout
return 0;
else //error
return -1;
}
void vsem_signal(vsem_t vs)
{
Semaphore_post(vs->sem);
}

17
vslib/vsem.h

@ -0,0 +1,17 @@
/*
* vsem.h
*
* Created on: 2019-3-29
* Author: Administrator
*/
#ifndef VSEM_H_
#define VSEM_H_
typedef struct vsem *vsem_t;
vsem_t vsem_new(void );
void vsem_free(vsem_t vs);
int vsem_wait(vsem_t vs, unsigned int timeout /*0-forever*/);
void vsem_signal(vsem_t vs);
#endif /* VSEM_H_ */

89
vslib/vtask.c

@ -0,0 +1,89 @@
/*
* vtask.c
*
* Created on: 2019-3-22
* Author: Administrator
*/
#include <stdio.h>
#include <stdlib.h>
#include <xdc/std.h>
#include <xdc/runtime/System.h>
#include <xdc/runtime/Error.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/ndk/inc/netmain.h>
#include "vtask.h"
struct vtask {
Task_Handle task;
};
vtask_t vtask_create(void (*vtk_pthread)(void ))
{
Task_Params taskParams;
Error_Block eb;
vtask_t tk;
if (!(tk = malloc(sizeof *tk)))
goto _err;
/* Create 1 task with priority 15 */
Error_init(&eb);
Task_Params_init(&taskParams);
taskParams.stackSize = VTASK_STACK_SIZE;
taskParams.priority = OS_TASKPRINORM;
if (!(tk->task = Task_create((Task_FuncPtr)vtk_pthread, &taskParams, &eb)))
goto _err;
return tk;
_err:
printf("vtask create failed\n");
if (tk)
free(tk);
return NULL;
}
vtask_t vtask_create_2(void (*vtk_pthread)(void *arg), void *arg)
{
Task_Params taskParams;
Error_Block eb;
vtask_t tk;
if (!(tk = malloc(sizeof *tk)))
goto _err;
/* Create 1 task with priority 15 */
Error_init(&eb);
Task_Params_init(&taskParams);
taskParams.arg0 = (UArg)arg;
taskParams.stackSize = VTASK_STACK_SIZE;
taskParams.priority = OS_TASKPRINORM;
if (!(tk->task = Task_create((Task_FuncPtr)vtk_pthread, &taskParams, &eb)))
goto _err;
return tk;
_err:
printf("vtask create failed\n");
if (tk)
free(tk);
return NULL;
}
void vtask_delete(vtask_t tk)
{
if (tk) {
Task_delete(&tk->task);
free(tk);
}
}
void vtask_sleep(int ms)
{
Task_yield();
Task_sleep(ms);
}

23
vslib/vtask.h

@ -0,0 +1,23 @@
/*
* vtask.h
*
* Created on: 2019-3-22
* Author: abagu
*/
#ifndef VTASK_H_
#define VTASK_H_
#include <ti/sysbios/knl/Task.h>
//#define VTASK_PRI_LEVEL_DEFAULT OS_TASKPRINORM // priority low 0 --> high 31
#define VTASK_STACK_SIZE (0x80000) //stack size 512K
typedef struct vtask *vtask_t;
vtask_t vtask_create(void (*vtk_pthread)(void));
vtask_t vtask_create_2(void (*vtk_pthread)(void *arg), void *arg);
void vtask_delete(vtask_t tk);
void vtask_sleep(int ms);
#endif /* VTASK_H_ */

217
vslib/vtelnetd.c

@ -0,0 +1,217 @@
/*
* vtelnet.c
*
* Created on: 2019-5-30
* Author: Administrator
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/knl/Semaphore.h>
#include "vconsole.h"
#include "vtelnetd.h"
#define MORE_THAN_CLIENTS "Error: more than max clients. \r\n"
#define THREAD_ERROR "Error: create thread failed.\r\n"
struct vtelnetd;
typedef struct telnet_client {
struct vtelnetd *vtld;
int login;
SOCKET sock;
SA addr;
int err;
}telnet_client_s;
typedef struct vtelnetd {
int inited;
Semaphore_Handle mutex;
telnet_client_s client[TELNET_CLINET_MAX_COUNT];
}vtelnetd_s;
static vtelnetd_s _vtld = {0};
static void __report_error(HANDLE fd, const char *s)
{
send(fd, (void *)s, strlen(s), 0);
fdClose(fd);
}
static int do_puts(void *param, const char *s, int len)
{
int i, sendlen = 0;
char line[260];
telnet_client_s *tc = (telnet_client_s *)param;
if (len < 0)
len = strlen(s);
for (i = 0; i < len; ++i) {
line[i] = s[i];
if (line[i] == ' ' && i > 0 && line[i-1] == '\r') {
len -= 1;
i--;
}
}
if (tc) {
sendlen = send(tc->sock, (void *)line, len, 0);
if (sendlen != len) {
printf("sock send fail \r\n");
tc->err = 1;
}
//fd1 task can schedule by time
Task_sleep(1);
}
return sendlen;
}
//static int do_getch(void *priv)
//{
// int ret = 0;
// char ch = 0;
// telnet_client_s *tc = (telnet_client_s *)priv;
// if (tc) {
// ret = recv(tc->sock, &ch, 1, 0);
// if (ret == 0) {
// ch = 0;
// } else if (ret < 0) {
// if (fdError() != EWOULDBLOCK) {
// printf("sock recv fail \r\n");
// tc->err = 1;
// return 0;
// }
// }
// }
//
// return ch;
//}
static int do_gets(void *param, char *buf, int len, int blocking)
{
int n = 0, retlen, errno;
telnet_client_s *tc = (telnet_client_s *)param;
if (tc) {
while(n < len) {
retlen = recv(tc->sock, buf + n, len - n, 0);
if (retlen < 0) {
errno = fdError();
if (errno == EWOULDBLOCK) {
continue;
} else {
break;
}
} else if (retlen == 0) {
break;
} else {
n += retlen;
}
}
}
return n;
}
static void __console_client_task(UINT32 arg)
{
telnet_client_s *tc = (telnet_client_s *)arg;
vtelnetd_s *vtld = tc->vtld;
struct vconsole_param cp;
vconsole_t cs;
fdOpenSession(TaskSelf());
do_puts(tc, "welcome vsky telnet \r\n", -1);
cp.debug_console = 0;
cp.prompt = "telnet> ";
cp.param = tc;
cp.puts = do_puts;
cp.gets = do_gets;
cs = vconsole_new(&cp);
if (cs == NULL) {
printf("console new fail \r\n");
return;
}
while(tc->login) {
vconsole_loop(cs);
Task_sleep(5);
if (tc->err)
break;
if (vconsole_status(cs))
break;
}
printf("vsky telnet exit \r\n");
vconsole_free(cs);
Semaphore_pend(vtld->mutex, BIOS_WAIT_FOREVER);
fdClose(tc->sock);
tc->login = 0;
Semaphore_post(vtld->mutex);
Task_exit();
}
void vtelnetd_init(void )
{
_vtld.mutex = Semaphore_create(1, NULL, NULL);
_vtld.inited = 1;
}
SOCKET vtelnetd_client(PSA client)
{
int i;
HANDLE fd1, fd2;
vtelnetd_s *vtld = &_vtld;
telnet_client_s *tc = NULL;
/* Create the local pipe - abort on error */
if (pipe(&fd1, &fd2 ) != 0)
return(INVALID_SOCKET);
/* find free telnet client instance. */
Semaphore_pend(vtld->mutex, BIOS_WAIT_FOREVER);
for (i = 0; i < TELNET_CLINET_MAX_COUNT; ++i) {
if (!vtld->client[i].login) {
tc = &vtld->client[i];
tc->vtld = vtld;
tc->login = 1;
tc->sock = fd2;
tc->addr = *client;
tc->err = 0;
if (NULL == TaskCreate(__console_client_task, NULL, OS_TASKPRINORM, 0x80000, (UINT32)tc, 0, 0)) {
__report_error(fd2, THREAD_ERROR);
tc->login = 0;
}
break;
}
}
Semaphore_post(vtld->mutex);
/* no free telnet clinet instance. */
if (!tc)
__report_error(fd2, MORE_THAN_CLIENTS);
return (SOCKET) fd1;
}
void nvt_print(char *fmt, ...)
{
char buf[260] = {0};
int len;
va_list arg_ptr;
va_start( arg_ptr, fmt );
len = vsprintf( (char *)buf, fmt, arg_ptr );
va_end( arg_ptr );
(void) len;
}

23
vslib/vtelnetd.h

@ -0,0 +1,23 @@
/*
* vtelnet.h
*
* Created on: 2019-5-30
* Author: Administrator
*/
#ifndef VTELNET_H_
#define VTELNET_H_
#include <ti/ndk/inc/netmain.h>
#define TELNET_CLINET_MAX_COUNT 2
extern void vtelnetd_init(void );
extern SOCKET vtelnetd_client(PSA client);
/*
* NVT: Net Virtual Terminal
*/
extern int nvt_puts(const char *str, int len);
extern void nvt_print(char *fmt, ...);
#endif /* VTELNET_H_ */

55
vslib/vtftp.c

@ -0,0 +1,55 @@
/*
* vtftp.c
*
* Created on: 2019-6-10
* Author: Administrator
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <ti/ndk/inc/netmain.h>
#include <ti/ndk/inc/tools/servers.h>
#include <ti/ndk/inc/nettools/nettools.h>
#include <ti/ndk/inc/tools/console.h>
#include "vcmd.h"
uint32_t vtftp_load_file(char *ip, char *file, uint32_t mem)
{
IPN ipInt;
uint32_t filesize = 0x2000000; // 32M;
printf("tftp download file %s from %s to mem: 0x%x \r\n", file, ip, mem);
ConStrToIPN(ip, &ipInt);
if (NtTftpRecv(ipInt, file, (char *)mem, &filesize, NULL) < 0) {
printf("tftp download fail \r\n");
return 0;
}
printf("tftp file download success and filesize: %d \r\n", filesize);
return filesize;
}
int do_tftp(cmd_tbl_t tbl, int argc, char *argv[])
{
char *ip;
char *filename;
uint32_t mem_bass;
//IPN ipInt;
//uint32_t filesize = 0x2000000; // 32M
if (argc != 4) {
printf("usage: %s [ip] [file] [mem_addr] \r\n", argv[0]);
return -1;
}
ip = argv[1];
filename = argv[2];
mem_bass = strtoul(argv[3], NULL, 0);
vtftp_load_file(ip, filename, mem_bass);
return 0;
}
CON_CMD(tftp, "tftp down", NULL, do_tftp)

13
vslib/vtftp.h

@ -0,0 +1,13 @@
/*
* vtftp.h
*
* Created on: 2019-6-10
* Author: Administrator
*/
#ifndef VTFTP_H_
#define VTFTP_H_
extern uint32_t vtftp_load_file(char *ip, char *file, uint32_t mem);
#endif /* VTFTP_H_ */

75
vslib/vtimer.c

@ -0,0 +1,75 @@
/*
* vtimer.c
*
* Created on: 2019-7-10
* Author: Administrator
*/
#include <stdio.h>
#include <stdlib.h>
#include <xdc/std.h>
#include <xdc/runtime/System.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Clock.h>
#include "vtimer.h"
struct timer {
Clock_Handle clk;
void *param;
void (*on_time)(void *param);
};
static Void _clkFxn(UArg arg0)
{
timer_t tm = (timer_t)arg0;
if (tm && tm->on_time)
tm->on_time(tm->param);
}
timer_t timer_new(int tick_ms, void *param, void (*on_time)(void *param))
{
timer_t tm;
Clock_Params clkParams;
tm = calloc(1, sizeof *tm);
if (tm) {
Clock_Params_init(&clkParams);
clkParams.period = tick_ms;
clkParams.startFlag = 0; //FLASE
clkParams.arg = (UArg)tm;
tm->clk = Clock_create(_clkFxn, tick_ms, &clkParams, NULL);
tm->param = param;
tm->on_time = on_time;
}
return tm;
}
void timer_free(timer_t tm)
{
if (tm) {
Clock_delete(&tm->clk);
free(tm);
}
}
int timer_active(timer_t tm)
{
if (tm)
Clock_start(tm->clk);
return 0;
}
int timer_deactive(timer_t tm)
{
if (tm)
Clock_stop(tm->clk);
return 0;
}
unsigned int time_millis(void )
{
return (unsigned int)Clock_getTicks();
}

20
vslib/vtimer.h

@ -0,0 +1,20 @@
/*
* vtimer.h
*
* Created on: 2019-7-10
* Author: Administrator
*/
#ifndef VTIMER_H_
#define VTIMER_H_
typedef struct timer *timer_t;
timer_t timer_new(int tick_ms, void *param, void (*on_time)(void *param));
void timer_free(timer_t tm);
int timer_active(timer_t tm);
int timer_deactive(timer_t tm);
unsigned int time_millis(void );
#endif /* VTIMER_H_ */
Loading…
Cancel
Save