Update gitignore, add dl814_z7 project

gitignore structure is updated to work with single and multi project situation under a single project directory
This commit is contained in:
2023-03-29 10:42:01 +08:00
parent b000e2702e
commit cd256a8cd6
2246 changed files with 7838223 additions and 86 deletions
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Product Version: Vivado v2019.1.3 (64-bit) -->
<!-- -->
<!-- Copyright 1986-2019 Xilinx, Inc. All Rights Reserved. -->
<labtools version="1" minor="0"/>
@@ -0,0 +1,162 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="xilinx.gnu.armv7.exe.debug.416271401">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="xilinx.gnu.armv7.exe.debug.416271401" moduleId="org.eclipse.cdt.core.settings" name="Debug">
<externalSettings/>
<extensions>
<extension id="com.xilinx.sdk.managedbuilder.XELF.arm.a53.x32" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactExtension="elf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="xilinx.gnu.armv7.exe.debug.416271401" name="Debug" parent="xilinx.gnu.armv7.exe.debug" prebuildStep="a9-linaro-pre-build-step">
<folderInfo id="xilinx.gnu.armv7.exe.debug.416271401." name="/" resourcePath="">
<toolChain id="xilinx.gnu.armv7.exe.debug.toolchain.2075827492" name="Xilinx ARM v7 GNU Toolchain" superClass="xilinx.gnu.armv7.exe.debug.toolchain">
<targetPlatform binaryParser="com.xilinx.sdk.managedbuilder.XELF.arm.a53.x32" id="xilinx.armv7.target.gnu.base.debug.1837356537" isAbstract="false" name="Debug Platform" superClass="xilinx.armv7.target.gnu.base.debug"/>
<builder buildPath="${workspace_loc:/phy_bc}/Debug" enableAutoBuild="true" id="xilinx.gnu.armv7.toolchain.builder.debug.127682394" managedBuildOn="true" name="GNU make.Debug" superClass="xilinx.gnu.armv7.toolchain.builder.debug"/>
<tool id="xilinx.gnu.armv7.c.toolchain.assembler.debug.253875859" name="ARM v7 gcc assembler" superClass="xilinx.gnu.armv7.c.toolchain.assembler.debug">
<inputType id="xilinx.gnu.assembler.input.1368181035" superClass="xilinx.gnu.assembler.input"/>
</tool>
<tool id="xilinx.gnu.armv7.c.toolchain.compiler.debug.679882649" name="ARM v7 gcc compiler" superClass="xilinx.gnu.armv7.c.toolchain.compiler.debug">
<option defaultValue="gnu.c.optimization.level.none" id="xilinx.gnu.compiler.option.optimization.level.1084229862" superClass="xilinx.gnu.compiler.option.optimization.level" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.option.debugging.level.1416322180" superClass="xilinx.gnu.compiler.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.inferred.swplatform.includes.70085766" superClass="xilinx.gnu.compiler.inferred.swplatform.includes" valueType="includePath">
<listOptionValue builtIn="false" value="../../phy_bc_bsp/ps7_cortexa9_0/include"/>
</option>
<option id="xilinx.gnu.compiler.misc.other.1993818460" superClass="xilinx.gnu.compiler.misc.other" value="-c -fmessage-length=0 -MT&quot;$@&quot; -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard" valueType="string"/>
<inputType id="xilinx.gnu.armv7.c.compiler.input.636704376" name="C source files" superClass="xilinx.gnu.armv7.c.compiler.input"/>
</tool>
<tool id="xilinx.gnu.armv7.cxx.toolchain.compiler.debug.1041936956" name="ARM v7 g++ compiler" superClass="xilinx.gnu.armv7.cxx.toolchain.compiler.debug">
<option defaultValue="gnu.c.optimization.level.none" id="xilinx.gnu.compiler.option.optimization.level.628040683" superClass="xilinx.gnu.compiler.option.optimization.level" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.option.debugging.level.514302329" superClass="xilinx.gnu.compiler.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.inferred.swplatform.includes.243487337" superClass="xilinx.gnu.compiler.inferred.swplatform.includes" valueType="includePath">
<listOptionValue builtIn="false" value="../../phy_bc_bsp/ps7_cortexa9_0/include"/>
</option>
</tool>
<tool id="xilinx.gnu.armv7.toolchain.archiver.1758739882" name="ARM v7 archiver" superClass="xilinx.gnu.armv7.toolchain.archiver"/>
<tool id="xilinx.gnu.armv7.c.toolchain.linker.debug.710579770" name="ARM v7 gcc linker" superClass="xilinx.gnu.armv7.c.toolchain.linker.debug">
<option id="xilinx.gnu.linker.inferred.swplatform.lpath.741210871" superClass="xilinx.gnu.linker.inferred.swplatform.lpath" valueType="libPaths">
<listOptionValue builtIn="false" value="../../phy_bc_bsp/ps7_cortexa9_0/lib"/>
</option>
<option id="xilinx.gnu.linker.inferred.swplatform.flags.1395895390" superClass="xilinx.gnu.linker.inferred.swplatform.flags" valueType="libs">
<listOptionValue builtIn="false" value="-Wl,--start-group,-lxil,-lgcc,-lc,--end-group"/>
</option>
<option id="xilinx.gnu.c.linker.option.lscript.2094517967" superClass="xilinx.gnu.c.linker.option.lscript" value="../src/lscript.ld" valueType="string"/>
<option id="xilinx.gnu.c.link.option.ldflags.228590312" superClass="xilinx.gnu.c.link.option.ldflags" value=" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -Wl,-build-id=none -specs=Xilinx.spec" valueType="string"/>
<inputType id="xilinx.gnu.linker.input.397485833" superClass="xilinx.gnu.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
<inputType id="xilinx.gnu.linker.input.lscript.652800322" name="Linker Script" superClass="xilinx.gnu.linker.input.lscript"/>
</tool>
<tool id="xilinx.gnu.armv7.cxx.toolchain.linker.debug.1001419735" name="ARM v7 g++ linker" superClass="xilinx.gnu.armv7.cxx.toolchain.linker.debug">
<option id="xilinx.gnu.linker.inferred.swplatform.lpath.849935655" superClass="xilinx.gnu.linker.inferred.swplatform.lpath" valueType="libPaths">
<listOptionValue builtIn="false" value="../../phy_bc_bsp/ps7_cortexa9_0/lib"/>
</option>
<option id="xilinx.gnu.linker.inferred.swplatform.flags.330526304" superClass="xilinx.gnu.linker.inferred.swplatform.flags" valueType="libs">
<listOptionValue builtIn="false" value="-Wl,--start-group,-lxil,-lgcc,-lc,--end-group"/>
</option>
<option id="xilinx.gnu.c.linker.option.lscript.110040861" superClass="xilinx.gnu.c.linker.option.lscript" value="../src/lscript.ld" valueType="string"/>
</tool>
<tool id="xilinx.gnu.armv7.size.debug.807917101" name="ARM v7 Print Size" superClass="xilinx.gnu.armv7.size.debug"/>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
<cconfiguration id="xilinx.gnu.armv7.exe.release.878188619">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="xilinx.gnu.armv7.exe.release.878188619" moduleId="org.eclipse.cdt.core.settings" name="Release">
<externalSettings/>
<extensions>
<extension id="com.xilinx.sdk.managedbuilder.XELF.arm.a53.x32" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactExtension="elf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="xilinx.gnu.armv7.exe.release.878188619" name="Release" parent="xilinx.gnu.armv7.exe.release" prebuildStep="a9-linaro-pre-build-step">
<folderInfo id="xilinx.gnu.armv7.exe.release.878188619." name="/" resourcePath="">
<toolChain id="xilinx.gnu.armv7.exe.release.toolchain.1626819326" name="Xilinx ARM v7 GNU Toolchain" superClass="xilinx.gnu.armv7.exe.release.toolchain">
<targetPlatform binaryParser="com.xilinx.sdk.managedbuilder.XELF.arm.a53.x32" id="xilinx.armv7.target.gnu.base.release.1911626616" isAbstract="false" name="Release Platform" superClass="xilinx.armv7.target.gnu.base.release"/>
<builder buildPath="${workspace_loc:/phy_bc}/Release" enableAutoBuild="true" id="xilinx.gnu.armv7.toolchain.builder.release.402286835" managedBuildOn="true" name="GNU make.Release" superClass="xilinx.gnu.armv7.toolchain.builder.release"/>
<tool id="xilinx.gnu.armv7.c.toolchain.assembler.release.1802410101" name="ARM v7 gcc assembler" superClass="xilinx.gnu.armv7.c.toolchain.assembler.release">
<inputType id="xilinx.gnu.assembler.input.2035608353" superClass="xilinx.gnu.assembler.input"/>
</tool>
<tool id="xilinx.gnu.armv7.c.toolchain.compiler.release.430950301" name="ARM v7 gcc compiler" superClass="xilinx.gnu.armv7.c.toolchain.compiler.release">
<option defaultValue="gnu.c.optimization.level.more" id="xilinx.gnu.compiler.option.optimization.level.1929557509" superClass="xilinx.gnu.compiler.option.optimization.level" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.option.debugging.level.1427233868" superClass="xilinx.gnu.compiler.option.debugging.level" value="gnu.c.debugging.level.none" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.inferred.swplatform.includes.803460729" superClass="xilinx.gnu.compiler.inferred.swplatform.includes" valueType="includePath">
<listOptionValue builtIn="false" value="../../phy_bc_bsp/ps7_cortexa9_0/include"/>
</option>
<option id="xilinx.gnu.compiler.misc.other.1208176685" superClass="xilinx.gnu.compiler.misc.other" value="-c -fmessage-length=0 -MT&quot;$@&quot; -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard" valueType="string"/>
<inputType id="xilinx.gnu.armv7.c.compiler.input.1442430310" name="C source files" superClass="xilinx.gnu.armv7.c.compiler.input"/>
</tool>
<tool id="xilinx.gnu.armv7.cxx.toolchain.compiler.release.1470170385" name="ARM v7 g++ compiler" superClass="xilinx.gnu.armv7.cxx.toolchain.compiler.release">
<option defaultValue="gnu.c.optimization.level.more" id="xilinx.gnu.compiler.option.optimization.level.1362074025" superClass="xilinx.gnu.compiler.option.optimization.level" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.option.debugging.level.964694910" superClass="xilinx.gnu.compiler.option.debugging.level" value="gnu.c.debugging.level.none" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.inferred.swplatform.includes.441950715" superClass="xilinx.gnu.compiler.inferred.swplatform.includes" valueType="includePath">
<listOptionValue builtIn="false" value="../../phy_bc_bsp/ps7_cortexa9_0/include"/>
</option>
</tool>
<tool id="xilinx.gnu.armv7.toolchain.archiver.1434706632" name="ARM v7 archiver" superClass="xilinx.gnu.armv7.toolchain.archiver"/>
<tool id="xilinx.gnu.armv7.c.toolchain.linker.release.1464167740" name="ARM v7 gcc linker" superClass="xilinx.gnu.armv7.c.toolchain.linker.release">
<option id="xilinx.gnu.linker.inferred.swplatform.lpath.1603410452" superClass="xilinx.gnu.linker.inferred.swplatform.lpath" valueType="libPaths">
<listOptionValue builtIn="false" value="../../phy_bc_bsp/ps7_cortexa9_0/lib"/>
</option>
<option id="xilinx.gnu.linker.inferred.swplatform.flags.1982477170" superClass="xilinx.gnu.linker.inferred.swplatform.flags" valueType="libs">
<listOptionValue builtIn="false" value="-Wl,--start-group,-lxil,-lgcc,-lc,--end-group"/>
</option>
<option id="xilinx.gnu.c.linker.option.lscript.272181693" superClass="xilinx.gnu.c.linker.option.lscript" value="../src/lscript.ld" valueType="string"/>
<option id="xilinx.gnu.c.link.option.ldflags.1790193159" superClass="xilinx.gnu.c.link.option.ldflags" value=" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -Wl,-build-id=none -specs=Xilinx.spec" valueType="string"/>
<inputType id="xilinx.gnu.linker.input.1787429959" superClass="xilinx.gnu.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
<inputType id="xilinx.gnu.linker.input.lscript.1296435155" name="Linker Script" superClass="xilinx.gnu.linker.input.lscript"/>
</tool>
<tool id="xilinx.gnu.armv7.cxx.toolchain.linker.release.1383632386" name="ARM v7 g++ linker" superClass="xilinx.gnu.armv7.cxx.toolchain.linker.release">
<option id="xilinx.gnu.linker.inferred.swplatform.lpath.1729131388" superClass="xilinx.gnu.linker.inferred.swplatform.lpath" valueType="libPaths">
<listOptionValue builtIn="false" value="../../phy_bc_bsp/ps7_cortexa9_0/lib"/>
</option>
<option id="xilinx.gnu.linker.inferred.swplatform.flags.1768822872" superClass="xilinx.gnu.linker.inferred.swplatform.flags" valueType="libs">
<listOptionValue builtIn="false" value="-Wl,--start-group,-lxil,-lgcc,-lc,--end-group"/>
</option>
<option id="xilinx.gnu.c.linker.option.lscript.1331110261" superClass="xilinx.gnu.c.linker.option.lscript" value="../src/lscript.ld" valueType="string"/>
</tool>
<tool id="xilinx.gnu.armv7.size.release.1083487166" name="ARM v7 Print Size" superClass="xilinx.gnu.armv7.size.release"/>
</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="phy_bc.xilinx.gnu.armv7.exe.1613013619" name="Xilinx ARM v7 Executable" projectType="xilinx.gnu.armv7.exe"/>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="xilinx.gnu.armv7.exe.debug.416271401;xilinx.gnu.armv7.exe.debug.416271401.;xilinx.gnu.armv7.c.toolchain.compiler.debug.679882649;xilinx.gnu.armv7.c.compiler.input.636704376">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.xilinx.managedbuilder.ui.ARMA53X32GCCManagedMakePerProjectProfileC"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="xilinx.gnu.armv7.exe.debug.416271401;xilinx.gnu.armv7.exe.debug.416271401.">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.xilinx.managedbuilder.ui.ARMA53X32GCCManagedMakePerProjectProfileC"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="xilinx.gnu.armv7.exe.release.878188619;xilinx.gnu.armv7.exe.release.878188619.">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.xilinx.managedbuilder.ui.ARMA53X32GCCManagedMakePerProjectProfileC"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="xilinx.gnu.armv7.exe.release.878188619;xilinx.gnu.armv7.exe.release.878188619.;xilinx.gnu.armv7.c.toolchain.compiler.release.430950301;xilinx.gnu.armv7.c.compiler.input.1442430310">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.xilinx.managedbuilder.ui.ARMA53X32GCCManagedMakePerProjectProfileC"/>
</scannerConfigBuildInfo>
</storageModule>
</cproject>
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>phy_bc</name>
<comment>Created by SDK v2019.1. phy_bc_bsp - ps7_cortexa9_0</comment>
<projects>
<project>phy_bc_bsp</project>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
</projectDescription>
@@ -0,0 +1 @@
Empty application. Add your own sources.
@@ -0,0 +1,2 @@
*startfile:
crti%O%s crtbegin%O%s
@@ -0,0 +1,449 @@
/*****************************************************************************/
/**
* Description: A simple AXI DMA api.
*
* Author: Fan Hao
* Date: 2022-06-18 16:37
* LastEditors: Fan Hao
* LastEditTime: 2022-06-18 17:38
* Revisions: Rev 0.0
* History:
* [2022-06-18]: Initial version.
*
* Copyright(c) 2022 Beijing Institute of Technology.
* Lab of Communication and Networking
*
******************************************************************************/
/***************************** Include Files *********************************/
#include <inttypes.h>
#include <stdbool.h>
#include "xaxidma.h"
#include "xtime_l.h"
#include "xil_cache.h"
#include "axi_dma.h"
#include "../error.h"
#include "../common.h"
/************************** Constant Definitions *****************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/**************************** Type Definitions *******************************/
/************************** Variable Definitions *****************************/
/*****************************************************************************/
/**
* @brief Initialize the DMA descriptor instance, allocate space for
* descriptor.
*
* @param instPtr a second rank pointer to DMA descriptor instance
* @param configPtr a pointer to DMA descriptor instance configuration
* set.
*
* @return SUCCESS
* ENOMEM memory allocate failed.
* other error codes
*
******************************************************************************/
int32_t Dma_Init(DMA_DESC** instPtr, const DMA_CONFIG* configPtr){
ASSERT(configPtr != NULL);
int32_t Status = SUCCESS;
*instPtr = (DMA_DESC*) malloc(sizeof(DMA_DESC));
if ((*instPtr) == NULL) {
goto err;
}
(*instPtr)->isTxDone = false;
(*instPtr)->isRxDone = false;
(*instPtr)->isError = false;
(*instPtr)->isListening = false;
memcpy(&((*instPtr)->configs), configPtr, sizeof(DMA_CONFIG));
(*instPtr)->axiDmaPtr = (XAxiDma*) malloc(sizeof(XAxiDma));
if ((*instPtr)->axiDmaPtr == NULL) {
free((*instPtr)->axiDmaPtr);
goto err;
}
XAxiDma_Config* damConfigPtr = NULL;
damConfigPtr = XAxiDma_LookupConfig(configPtr->devId);
if (damConfigPtr == NULL) {
DBG_PRINT("No config found for %d\r\n", configPtr->devId);
goto err;
}
/* Initialize DMA engine */
Status = XAxiDma_CfgInitialize((*instPtr)->axiDmaPtr, damConfigPtr);
if (Status != SUCCESS) {
DBG_ERROR("DMA initialize failed. device id: %d\r\n", configPtr->devId);
goto err;
}
if(XAxiDma_HasSg((*instPtr)->axiDmaPtr)){
DBG_ERROR("DMA Device configured as SG mode \r\n");
goto err;
}
// Clear all pending interrupt.
XAxiDma_IntrAckIrq((*instPtr)->axiDmaPtr, XAXIDMA_IRQ_ALL_MASK,
XAXIDMA_DMA_TO_DEVICE);
XAxiDma_IntrAckIrq((*instPtr)->axiDmaPtr, XAXIDMA_IRQ_ALL_MASK,
XAXIDMA_DEVICE_TO_DMA);
/* Disable all interrupts before setup */
XAxiDma_IntrDisable((*instPtr)->axiDmaPtr, XAXIDMA_IRQ_ALL_MASK,
XAXIDMA_DMA_TO_DEVICE);
XAxiDma_IntrDisable((*instPtr)->axiDmaPtr, XAXIDMA_IRQ_ALL_MASK,
XAXIDMA_DEVICE_TO_DMA);
(*instPtr)->isInitialized = true;
return SUCCESS;
err:
free(*instPtr);
return Status;
}
/*****************************************************************************/
/**
* @brief Enable DMA IRQs.
*
* @param instPtr a pointer to DMA descriptor instance.
*
* @return SUCCESS
* EDINVAL device not initialized.
*
******************************************************************************/
int32_t Dma_IrqEnable(DMA_DESC* instPtr){
if(instPtr == NULL || instPtr->isInitialized == false){
return EDINVAL;
}
/* Enable all interrupts */
XAxiDma_IntrEnable(instPtr->axiDmaPtr, XAXIDMA_IRQ_ALL_MASK, XAXIDMA_DMA_TO_DEVICE);
XAxiDma_IntrEnable(instPtr->axiDmaPtr, XAXIDMA_IRQ_ALL_MASK, XAXIDMA_DEVICE_TO_DMA);
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Enable DMA listening feature and start a receive procedure.
*
* @param instPtr a pointer to DMA descriptor instance.
* @param dataBuff a pointer to data buffer.
*
* @return SUCCESS
* EDINVAL device not initialized.
*
******************************************************************************/
int32_t Dma_ListenEnable(DMA_DESC* instPtr, uint8_t* dataBuff){
if(instPtr == NULL || instPtr->isInitialized == false || dataBuff == NULL){
return EDINVAL;
}
instPtr->isListening = true;
instPtr->listenBuff = dataBuff;
// if(XAxiDma_Busy(instPtr->axiDmaPtr, XAXIDMA_DEVICE_TO_DMA) == false){
return XAxiDma_SimpleTransfer(instPtr->axiDmaPtr,(uintptr_t)instPtr->listenBuff,
instPtr->configs.defaultTransLen, XAXIDMA_DEVICE_TO_DMA);
// }
// else{
// return SUCCESS;
// }
}
/*****************************************************************************/
/**
* @brief Disable DMA listening feature and start a receive procedure.
*
* @param instPtr a pointer to DMA descriptor instance.
*
* @return SUCCESS
* EDINVAL device not initialized.
*
******************************************************************************/
int32_t Dma_ListenDisable(DMA_DESC* instPtr){
if(instPtr == NULL || instPtr->isInitialized == false){
return EDINVAL;
}
instPtr->isListening = false;
instPtr->listenBuff = NULL;
if(XAxiDma_Busy(instPtr->axiDmaPtr, XAXIDMA_DEVICE_TO_DMA) == true){
DBG_WARNING("an unfinished transfer is on going.\r\n");
}
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Transfer a specific length of data (DMA->Device), none-blocking
* transfer.
*
* @param instPtr a pointer to DMA descriptor instance.
* @param dataBuff a pointer to data buffer.
* @param dataLen length of data need to be transfer.
*
* @return SUCCESS
* EDINVAL device not initialized.
*
******************************************************************************/
int32_t Dma_SendData(DMA_DESC* instPtr, uint8_t* dataBuff, int32_t dataLen){
int32_t Status = SUCCESS;
if(dataLen > instPtr->configs.transMax){
return FAILURE;
}
// Flush the SrcBuffer before the DMA transfer
// Xil_DCacheFlushRange((uintptr_t)dataBuff, dataLen);
// Set txDone flage to false, before transmission
instPtr->isTxDone = false;
// Assert a send trigger
Status = XAxiDma_SimpleTransfer(instPtr->axiDmaPtr, (uintptr_t)dataBuff,
dataLen, XAXIDMA_DMA_TO_DEVICE);
if (Status != XST_SUCCESS) {
return FAILURE;
}
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Transfer a specific length of data (DMA->Device), blocking transfer.
*
* @param instPtr a pointer to DMA descriptor instance.
* @param dataBuff a pointer to data buffer.
* @param dataLen length of data need to be transfer.
*
* @return SUCCESS
* ETIMEOUT transfer timeout.
* other error codes.
*
******************************************************************************/
int32_t Dma_BlockingSendData(DMA_DESC* instPtr, uint8_t* dataBuff, int32_t dataLen){
int32_t Status = SUCCESS;
if(dataLen > instPtr->configs.transMax){
return EINVAL;
}
Status = Dma_SendData(instPtr, dataBuff, dataLen);
if(Status == SUCCESS){
DBG_ERROR("Failed to setup a DMA transfer (DMA->Device).\r\n");
return Status;
}
XTime tCur = 0;
XTime tTimeOut = 0;
XTime_GetTime(&tCur);
tTimeOut = tCur + instPtr->configs.timeoutTh;
while(instPtr->isTxDone == false && instPtr->isError == false){
XTime_GetTime(&tCur);
if(tCur >= tTimeOut){
return ETIMEOUT;
}
}
if(instPtr->isError == true){
return FAILURE;
}
// Set txDone flage to false, after transmission
instPtr->isTxDone = false;
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Transfer a specific length of data (Device->DMA), none-blocking
* transfer.
*
* @param instPtr a pointer to DMA descriptor instance.
* @param dataBuff a pointer to data buffer.
* @param dataLen length of data need to be transfer.
*
* @return SUCCESS
* EDINVAL device not initialized.
*
******************************************************************************/
int32_t Dma_RecvData(DMA_DESC* instPtr, uint8_t* dataBuff, int32_t dataLen){
int32_t Status = SUCCESS;
if(dataLen > instPtr->configs.transMax){
return FAILURE;
}
// Set txDone flage to false, before transmission
instPtr->isRxDone = false;
// Assert a send trigger
Status = XAxiDma_SimpleTransfer(instPtr->axiDmaPtr,(uintptr_t)dataBuff,
dataLen, XAXIDMA_DEVICE_TO_DMA);
if (Status != XST_SUCCESS) {
return FAILURE;
}
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Transfer a specific length of data (Device->DMA), blocking transfer.
*
* @param instPtr a pointer to DMA descriptor instance.
* @param dataBuff a pointer to data buffer.
* @param dataLen length of data need to be transfer.
*
* @return SUCCESS
* EDINVAL device not initialized.
*
******************************************************************************/
int32_t Dma_BlockingRecvData(DMA_DESC* instPtr, uint8_t* dataBuff, int32_t dataLen){
int32_t Status = SUCCESS;
if(dataLen > instPtr->configs.transMax){
return FAILURE;
}
Status = Dma_RecvData(instPtr, dataBuff, dataLen);
if(Status == SUCCESS){
DBG_ERROR("Failed to setup a DMA transfer (Device->DMA).\r\n");
return Status;
}
XTime tCur = 0;
XTime tTimeOut = 0;
XTime_GetTime(&tCur);
tTimeOut = tCur + instPtr->configs.timeoutTh;
while(instPtr->isTxDone == false && instPtr->isError == false){
XTime_GetTime(&tCur);
if(tCur >= tTimeOut){
return ETIMEOUT;
}
}
if(instPtr->isError == true){
return FAILURE;
}
// Set txDone flage to false, after transmission
instPtr->isTxDone = false;
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Handler for DMA->Device transfer.
*
* @param instPtr a pointer to DMA descriptor instance.
*
* @return SUCCESS
* error codes
*
******************************************************************************/
int32_t Dma_SendIrqHandler(DMA_DESC* instPtr){
if(instPtr == NULL || instPtr->isInitialized == false){
return FAILURE;
}
int32_t Status = SUCCESS;
uint32_t IrqStatus = 0;
/* Read pending interrupts */
IrqStatus = XAxiDma_IntrGetIrq(instPtr->axiDmaPtr, XAXIDMA_DMA_TO_DEVICE);
/* Acknowledge pending interrupts */
XAxiDma_IntrAckIrq(instPtr->axiDmaPtr, IrqStatus, XAXIDMA_DMA_TO_DEVICE);
/* If no interrupt is asserted, we do not do anything */
if (!(IrqStatus & XAXIDMA_IRQ_ALL_MASK)) {
return EIGNORE;
}
/* If error interrupt is asserted, raise error flag, reset the
* hardware to recover from the error, and return with no further
* processing.
*/
if ((IrqStatus & XAXIDMA_IRQ_ERROR_MASK)) {
instPtr->isError = true;
/* Reset should never fail for transmit channel */
XAxiDma_Reset(instPtr->axiDmaPtr);
while (XAxiDma_ResetIsDone(instPtr->axiDmaPtr) == false) {
// FIXME: Add time out check
}
return EUNEXP;
}
/* If Completion interrupt is asserted, then set the TxDone flag */
if ((IrqStatus & XAXIDMA_IRQ_IOC_MASK)) {
instPtr->isTxDone = true;
}
return Status;
}
/*****************************************************************************/
/**
* @brief Handler for Device->DMA transfer.
*
* @param instPtr a pointer to DMA descriptor instance.
*
* @return SUCCESS
* error codes
*
******************************************************************************/
int32_t Dma_RecvIrqHandler(DMA_DESC* instPtr){
if(instPtr == NULL || instPtr->isInitialized == false){
return FAILURE;
}
int32_t Status = SUCCESS;
uint32_t IrqStatus = 0;
/* Read pending interrupts */
IrqStatus = XAxiDma_IntrGetIrq(instPtr->axiDmaPtr, XAXIDMA_DEVICE_TO_DMA);
/* Acknowledge pending interrupts */
XAxiDma_IntrAckIrq(instPtr->axiDmaPtr, IrqStatus, XAXIDMA_DEVICE_TO_DMA);
/* If no interrupt is asserted, we do not do anything */
if (!(IrqStatus & XAXIDMA_IRQ_ALL_MASK)) {
return EIGNORE;
}
/* If error interrupt is asserted, raise error flag, reset the
* hardware to recover from the error, and return with no further
* processing.
*/
if ((IrqStatus & XAXIDMA_IRQ_ERROR_MASK)) {
instPtr->isError = true;
/* Reset should never fail for transmit channel */
XAxiDma_Reset(instPtr->axiDmaPtr);
while (XAxiDma_ResetIsDone(instPtr->axiDmaPtr)) {
// FIXME: Add time out check
_nop_();
}
return EUNEXP;
}
/* If completion interrupt is asserted, then set RxDone flag */
if ((IrqStatus & XAXIDMA_IRQ_IOC_MASK)) {
// // Invalid the DestBuffer after the DMA transfer
// int RingIndex = 0;
// uintptr_t dstAddr;
// uint32_t transLen;
// dstAddr = XAxiDma_ReadReg(instPtr->axiDmaPtr->RxBdRing[RingIndex].ChanBase, XAXIDMA_DESTADDR_OFFSET);
// if (instPtr->axiDmaPtr->AddrWidth > 32){
// dstAddr |= ((uintptr_t)(XAxiDma_ReadReg(instPtr->axiDmaPtr->RxBdRing[RingIndex].ChanBase,
// XAXIDMA_DESTADDR_MSB_OFFSET))<<32);
// }
// transLen = XAxiDma_ReadReg(InstancePtr->RxBdRing[RingIndex].ChanBase, XAXIDMA_BUFFLEN_OFFSET)
// Xil_DCacheInvalidateRange(dstAddr, transLen);
instPtr->isRxDone = true;
}
if(instPtr->isListening == true){
// Continuous receiving
Status = XAxiDma_SimpleTransfer(instPtr->axiDmaPtr,(uintptr_t)instPtr->listenBuff,
instPtr->configs.defaultTransLen, XAXIDMA_DEVICE_TO_DMA);
if(Status != SUCCESS){
DBG_ERROR("Failed to start a new SimpleTransfer in XAXIDMA_DEVICE_TO_DMA channel.\r\n");
}
}
return Status;
}
@@ -0,0 +1,62 @@
/*****************************************************************************/
/**
* Description: A simple AXI DMA api.
* prototypes.
*
* Author: Fan Hao
* Date: 2022-06-18 16:37
* LastEditors: Fan Hao
* LastEditTime: 2022-06-18 17:40
* Revisions: Rev 0.0
* History:
* [2022-06-18]: Initial version.
*
* Copyright(c) 2022 Beijing Institute of Technology.
* Lab of Communication and Networking
*
******************************************************************************/
#ifndef AXI_DMA_H_
#define AXI_DMA_H_
/***************************** Include Files *********************************/
#include <inttypes.h>
#include <stdbool.h>
#include "xaxidma.h"
/************************** Constant Definitions *****************************/
/***************** Macros (Inline Functions) Definitions *********************/
/**************************** Type Definitions *******************************/
typedef struct{
uint32_t devId;
uint32_t transMax;
uint32_t defaultTransLen;
uint32_t timeoutTh;
}DMA_CONFIG;
typedef struct{
bool isTxDone;
bool isRxDone;
bool isError;
bool isListening;
bool isInitialized;
uint8_t* listenBuff;
XAxiDma* axiDmaPtr;
DMA_CONFIG configs;
}DMA_DESC;
/************************** Variable Definitions *****************************/
/************************** Function Prototypes ******************************/
int32_t Dma_Init(DMA_DESC** instPtr, const DMA_CONFIG* configPtr);
int32_t Dma_IrqEnable(DMA_DESC* instPtr);
int32_t Dma_ListenEnable(DMA_DESC* instPtr, uint8_t* dataBuff);
int32_t Dma_ListenDisable(DMA_DESC* instPtr);
int32_t Dma_SendData(DMA_DESC* instPtr, uint8_t* dataBuff, int32_t dataLen);
int32_t Dma_BlockingSendData(DMA_DESC* instPtr, uint8_t* dataBuff, int32_t dataLen);
int32_t Dma_RecvData(DMA_DESC* instPtr, uint8_t* dataBuff, int32_t dataLen);
int32_t Dma_BlockingRecvData(DMA_DESC* instPtr, uint8_t* dataBuff, int32_t dataLen);
int32_t Dma_SendIrqHandler(DMA_DESC* instPtr);
int32_t Dma_RecvIrqHandler(DMA_DESC* instPtr);
#endif //AXI_DMA_H_
@@ -0,0 +1,211 @@
/*****************************************************************************/
/**
* Description: Implementations of chip to chip data bridge.
*
* Author: Fan Hao
* Date: 2022-09-02 15:01
* LastEditors: Fan Hao
* LastEditTime: 2022-09-02 15:49
* Revisions: Rev 0.0
* History:
* [2022-09-02]: Initial version
*
* Note:
* Branch from Analog Devices version (by DBogdan [email protected]).
*
* Copyright(c) 2022 Beijing Institute of Technology.
* Lab of Communication and Networking
*
******************************************************************************/
/***************************** Include Files **********************************/
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <stdbool.h>
#include "c2c_bridge.h"
#include "xgpio.h"
#include "../axi_dma/axi_dma.h"
#include "../util/util.h"
#include "../error.h"
#include "../common.h"
/************************** Constant Definitions *****************************/
// C2C Configs
#define C2C_GPIO_OUT_CH 1
#define C2C_SEND_TRIGGER BIT(0)
#define C2C_RECV_TRIGGER BIT(1)
/************************** Variable Definitions *****************************/
C2C_DESC* c2cInstPtr = NULL;
/************************** Function Prototypes ******************************/
inline bool C2c_IsSendBusy(C2C_DESC* instPtr){
ASSERT(instPtr != NULL);
return (instPtr->txDone == false);
}
inline bool C2c_IsRecvBusy(C2C_DESC* instPtr){
ASSERT(instPtr != NULL);
return (instPtr->rxDone == false);
}
/*****************************************************************************/
/**
* @brief Initialize c2c bridge descriptor instance.
*
* @param instPtr second rank pointer to c2c instance.
* @param configPtr pointer to c2c instance configuration struct.
*
* @return NONE
*
******************************************************************************/
int32_t C2c_Init(C2C_DESC** instPtr, C2C_CONFIG* configPtr){
ASSERT(configPtr != NULL);
int32_t Status = SUCCESS;
(*instPtr) = (C2C_DESC*)malloc(sizeof(C2C_DESC));
if((*instPtr) == NULL){
return MEMORY_ALLOC_ERROR;
}
memcpy(&(*instPtr)->c2cCofig, configPtr, sizeof(C2C_CONFIG));
Status = Dma_Init(&((*instPtr)->axiDmaInst), &(*instPtr)->c2cCofig.dmaConfig);
if(Status != SUCCESS){
DBG_ERROR("C2C axi DMA init failed, with error code: %d.\r\n", Status);
return Status;
}
(*instPtr)->isInit = true;
(*instPtr)->txDone = true;
(*instPtr)->rxDone = true;
(*instPtr)->lastRxBuff = (uintptr_t)NULL;
(*instPtr)->lastRxBuffSize = 0;
return SUCCESS;
}
int32_t C2c_IrqEnable(C2C_DESC* instPtr){
if(instPtr==NULL || instPtr->isInit == false){
return FAILURE;
}
/* Enable all interrupts */
return Dma_IrqEnable(instPtr->axiDmaInst);
}
/*****************************************************************************/
/**
* @brief Send data through c2c bridge.
*
* @param instPtr second rank pointer to c2c instance.
* @param buff data buffer stores the data needs to be sent
* @param dLen data length needs to be sent
*
* @return NONE
*
******************************************************************************/
int32_t C2c_SendData(C2C_DESC* instPtr, uint8_t* buff, uint32_t dLen){
ASSERT(instPtr != NULL);
ASSERT(buff != NULL);
if(instPtr->isInit == false){
return DEVICE_INVALIDE_ERROR;
}
if(dLen > instPtr->c2cCofig.capacity){
return PARAMETER_ERROR;
}
IO_Out32((uintptr_t)(buff + C2C_HEAD_OFFSET), C2C_HEADER);
IO_Out32((uintptr_t)(buff + C2C_DLEN_OFFSET), dLen + C2C_HEADER_LEN);
instPtr->txDone = false;
instPtr->lastTxBuff = (uintptr_t)buff;
instPtr->lastTxBuffSize = dLen;
if (SUCCESS == Dma_SendData(instPtr->axiDmaInst, buff, dLen + C2C_HEADER_LEN)){
return SUCCESS;
}
else{
return FAILURE;
}
return SUCCESS;
}
int32_t C2c_BlockingSendData(C2C_DESC* instPtr, uint8_t* buff, uint32_t dLen) {
ASSERT(instPtr != NULL);
ASSERT(buff != NULL);
if(instPtr->isInit == false){
return DEVICE_INVALIDE_ERROR;
}
if(dLen > instPtr->c2cCofig.capacity){
return PARAMETER_ERROR;
}
IO_Out32((uintptr_t)(buff + C2C_HEAD_OFFSET), C2C_HEADER);
IO_Out32((uintptr_t)(buff + C2C_DLEN_OFFSET), dLen + C2C_HEADER_LEN);
instPtr->txDone = false;
instPtr->lastTxBuff = (uintptr_t)buff;
instPtr->lastTxBuffSize = dLen;
if (SUCCESS == Dma_BlockingSendData(instPtr->axiDmaInst, buff, dLen + C2C_HEADER_LEN)){
return SUCCESS;
}
else{
return FAILURE;
}
}
/*****************************************************************************/
/**
* @brief Receive data from c2c bridge.
*
* @param instPtr second rank pointer to c2c instance.
* @param buff data buffer stores the received data.
* @param dLen data length that received
*
* @return NONE
*
******************************************************************************/
int32_t C2c_RecvData(C2C_DESC* instPtr, uint8_t* buff, uint32_t buffSize){
ASSERT(instPtr != NULL);
ASSERT(buff != NULL);
if(instPtr->isInit == false){
return DEVICE_INVALIDE_ERROR;
}
instPtr->rxDone = false;
instPtr->lastRxBuff = (uintptr_t)buff;
instPtr->lastRxBuffSize = buffSize;
if (SUCCESS == Dma_RecvData(instPtr->axiDmaInst, buff, buffSize)){
return SUCCESS;
}
else{
return FAILURE;
}
}
int32_t C2c_SendIrqHandler(C2C_DESC* instPtr){
ASSERT(instPtr != NULL);
if(instPtr->isInit == false){
return DEVICE_INVALIDE_ERROR;
}
instPtr->txDone = true;
if (SUCCESS == Dma_SendIrqHandler(instPtr->axiDmaInst)){
return SUCCESS;
}
else{
return UNEXPECTED_ERROR;
}
}
int32_t C2c_RecvIrqHandler(C2C_DESC* instPtr){
ASSERT(instPtr != NULL);
if(instPtr->isInit == false){
return DEVICE_INVALIDE_ERROR;
}
instPtr->rxDone = true;
if (SUCCESS == Dma_RecvIrqHandler(instPtr->axiDmaInst)){
return SUCCESS;
}
else{
return UNEXPECTED_ERROR;
}
if(IO_In32(instPtr->lastRxBuff + C2C_HEAD_OFFSET) != C2C_HEADER){
return IGNORE_ERROR;
}
if(IO_In32(instPtr->lastRxBuff + C2C_DLEN_OFFSET) > instPtr->lastRxBuffSize){
return IGNORE_ERROR;
}
return SUCCESS;
}
@@ -0,0 +1,62 @@
/*****************************************************************************/
/**
* Description: Chip to chip data bridge.
*
* Author: Fan Hao
* Date: 2022-09-02 15:01
* LastEditors: Fan Hao
* LastEditTime: 2022-09-02 15:49
* Revisions: Rev 0.0
* History:
* [2022-09-02]: Initial version
* [2023-02-23]: DMA version
*
* Note:
* Branch from Analog Devices version (by DBogdan [email protected]).
*
* Copyright(c) 2022 Beijing Institute of Technology.
* Lab of Communication and Networking
*
******************************************************************************/
#include <inttypes.h>
#include <stdbool.h>
#include "../axi_dma/axi_dma.h"
/************************** Constant Definitions *****************************/
#define C2C_HEADER_LEN 8 //bytes
#define C2C_HEADER 0x7E7E7E7E
#define C2C_HEAD_OFFSET 0
#define C2C_DLEN_OFFSET 4
#define C2C_PLOAD_OFFSET 8
#define C2C_BUFF_MAX 1024
/**************************** Type Definitions *******************************/
typedef struct {
uint32_t capacity;
DMA_CONFIG dmaConfig;
} C2C_CONFIG;
typedef struct {
C2C_CONFIG c2cCofig;
DMA_DESC* axiDmaInst;
bool isInit;
bool txDone;
bool rxDone;
uintptr_t lastTxBuff;
uint32_t lastTxBuffSize;
uintptr_t lastRxBuff;
uint32_t lastRxBuffSize;
} C2C_DESC;
/************************** Variable Definitions *****************************/
extern C2C_DESC* c2cInstPtr;
/************************** Function Prototypes ******************************/
int32_t C2c_Init(C2C_DESC** instPtr, C2C_CONFIG* configPtr);
int32_t C2c_IrqEnable(C2C_DESC* instPtr);
int32_t C2c_SendData(C2C_DESC* instPtr, uint8_t* buff, uint32_t dLen);
int32_t C2c_RecvData(C2C_DESC* instPtr, uint8_t* buff, uint32_t buffSize);
int32_t C2c_BlockingSendData(C2C_DESC* instPtr, uint8_t* buff, uint32_t dLen);
bool C2c_IsSendBusy(C2C_DESC* instPtr);
bool C2c_IsRecvBusy(C2C_DESC* instPtr);
int32_t C2c_SendIrqHandler(C2C_DESC* instPtr);
int32_t C2c_RecvIrqHandler(C2C_DESC* instPtr);
@@ -0,0 +1,158 @@
/*****************************************************************************/
/**
* Description: A simple circular FIFO bounded queue
*
* Author: Fan Hao
* Date: 2023-02-23 10:29
* LastEditors: Fan Hao
* LastEditTime: 2023-02-23 13:18
* Revisions: Rev 0.0
* History:
* [2023-02-23]: Initial Version.
*
* Copyright(c) 2023 Beijing Institute of Technology.
* Lab of Communication and Networking
* NOTE: Forked from https://github.com/chrismerck/rpa_queue.git
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
#include "circ_queue.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
// uncomment to print debug messages
//#define QUEUE_DEBUG
struct CIRC_QUEUE_S {
void **data;
volatile uint32_t nelts; /**< # elements */
uint32_t in; /**< next empty location */
uint32_t out; /**< next filled location */
uint32_t bounds;/**< max size of queue */
uint32_t full_waiters;
uint32_t empty_waiters;
pthread_mutex_t *one_big_mutex;
pthread_cond_t *not_empty;
pthread_cond_t *not_full;
};
#ifdef QUEUE_DEBUG
static void Q_DBG(const char*msg, CIRC_QUEUE *q) {
printf("#%d in %d out %d\t%s\n",
q->nelts, q->in, q->out,
msg
);
}
#else
#define Q_DBG(x,y)
#endif
void CircQueueFree(CIRC_QUEUE * queue)
{
assert(queue != NULL);
if (queue->data) free(queue->data);
free(queue);
}
/**
* Initialize the CIRC_QUEUE.
*/
bool CircQueueCreate(CIRC_QUEUE **q, uint32_t queueCapacity)
{
assert(q != NULL);
CIRC_QUEUE *queue;
queue = malloc(sizeof(CIRC_QUEUE));
if (!queue) {
return false;
}
*q = queue;
memset(queue, 0, sizeof(CIRC_QUEUE));
/* Set all the data in the queue to NULL */
queue->data = malloc(queueCapacity * sizeof(void*));
if(queue->data == NULL){
goto error;
}
queue->bounds = queueCapacity;
queue->nelts = 0;
queue->in = 0;
queue->out = 0;
return true;
error:
free(queue);
return false;
}
inline bool isCircQueueFull(CIRC_QUEUE *queue){
assert(queue != NULL);
return ((queue)->nelts == (queue)->bounds);
}
inline bool isCircQueueEmpty(CIRC_QUEUE *queue){
assert(queue != NULL);
return ((queue)->nelts == 0);
}
/**
* Push new data onto the queue.
*/
bool CircQueuePush(CIRC_QUEUE *queue, void *data)
{
assert(queue != NULL);
if (isCircQueueFull(queue)) {
return false;
}
queue->data[queue->in] = data;
queue->in++;
if (queue->in >= queue->bounds) {
queue->in -= queue->bounds;
}
queue->nelts++;
return true;
}
/**
* Return current number of element in queue.
*/
inline uint32_t CircQueueSize(CIRC_QUEUE *queue) {
return queue->nelts;
}
/**
* Retrieves the next item from the queue.
*/
bool CircQueuePop(CIRC_QUEUE *queue, void **data)
{
assert(queue != NULL);
if (isCircQueueEmpty(queue)) {
return false;
}
*data = queue->data[queue->out];
queue->nelts--;
queue->out++;
if (queue->out >= queue->bounds) {
queue->out -= queue->bounds;
}
return true;
}
@@ -0,0 +1,103 @@
/*****************************************************************************/
/**
* Description: A simple circular FIFO bounded queue
*
* Author: Fan Hao
* Date: 2023-02-23 10:29
* LastEditors: Fan Hao
* LastEditTime: 2023-02-23 12:53
* Revisions: Rev 0.0
* History:
* [2023-02-23]: Initial Version.
*
* Copyright(c) 2023 Beijing Institute of Technology.
* Lab of Communication and Networking
* NOTE: Forked from https://github.com/chrismerck/rpa_queue.git
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
#ifndef CIRC_QUEUE_H
#define CIRC_QUEUE_H
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
/**
* opaque structure
*/
typedef struct CIRC_QUEUE_S CIRC_QUEUE;
/**
* create a FIFO queue
* @param queue The new queue
* @param queue_capacity maximum size of the queue
* @param a pool to allocate queue from
*/
bool CircQueueCreate(CIRC_QUEUE **queue, uint32_t queue_capacity);
/** free queue memory -- call after destroy
* @note we do not free in destroy() to follow pthreads convention
*/
void CircQueueFree(CIRC_QUEUE * queue);
/**
* Detects when the CIRC_QUEUE is full. This utility function is expected
* to be called from within critical sections, and is not threadsafe.
*/
bool isCircQueueFull(CIRC_QUEUE *queue);
/**
* Detects when the CIRC_QUEUE is empty. This utility function is expected
* to be called from within critical sections, and is not threadsafe.
*/
bool isCircQueueEmpty(CIRC_QUEUE *queue);
/**
* push/add an object to the queue, blocking if the queue is already full
*
* @param queue the queue
* @param data the data
* @returns RPA_EINTR the blocking was interrupted (try again)
* @returns RPA_EOF the queue has been terminated
* @returns RPA_SUCCESS on a successful push
*/
bool CircQueuePush(CIRC_QUEUE *queue, void *data);
/**
* pop/get an object from the queue, blocking if the queue is already empty
*
* @param queue the queue
* @param data the data
* @returns RPA_EINTR the blocking was interrupted (try again)
* @returns RPA_EOF if the queue has been terminated
* @returns RPA_SUCCESS on a successful pop
*/
bool CircQueuePop(CIRC_QUEUE *queue, void **data);
/**
* returns the size of the queue.
*
* @warning this is not threadsafe, and is intended for reporting/monitoring
* of the queue.
* @param queue the queue
* @returns the size of the queue
*/
uint32_t CircQueueSize(CIRC_QUEUE *queue);
#endif /* CIRC_QUEUE_H */
@@ -0,0 +1,95 @@
/*****************************************************************************/
/**
* Description: Implementations of common functions.
*
* Author: Fan Hao
* Date: 2022-06-18 16:37
* LastEditors: Fan Hao
* LastEditTime: 2022-06-18 17:01
* Revisions: Rev 0.0
* History:
* [2022-06-18]: Initial version.
*
* Copyright(c) 2022 Beijing Institute of Technology.
* Lab of Communication and Networking
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "util/util.h"
#include "common.h"
#include "error.h"
#include "config/app_config.h"
/************************** Constant Definitions *****************************/
/***************** Macros (Inline Functions) Definitions *********************/
/**************************** Type Definitions *******************************/
/************************** Variable Definitions *****************************/
/*****************************************************************************/
/**
* @brief Append frame CRC-16 result to frame data buffer.
*
* @param buffPtr
* @param dataLen
*
* @return SUCCESS append successfully
* Other frame cannot be recognized.
*
******************************************************************************/
int AppendCrc(uint8_t* buffPtr, uint32_t dataLen) {
ASSERT(buffPtr != NULL);
int32_t Status = SUCCESS;
if (dataLen == 0) {
return FAILURE;
}
uint16_t crc = 0;
Status = crc16_gen(buffPtr, dataLen - COMMON_CRC_LEN, 0x1021, &crc);
if(Status != SUCCESS){
DBG_ERROR("C2C gernerate failed, error code: %d.\r\n", Status);
}
uint8_t* crcSegPtr = (buffPtr + dataLen - COMMON_CRC_LEN);
#ifdef CRC_COMPARE
*crcSegPtr = (uint8_t) crc & 0x00FF;
*(crcSegPtr + 1) = (uint8_t)((crc & 0xFF00) >> 8);
#else
*crcSegPtr = (uint8_t)((crc & 0xFF00) >> 8); (uint8_t) crc & 0x00FF;
*(crcSegPtr + 1) = (uint8_t) crc & 0x00FF;
#endif
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Check the frame CRC-16, witch can infer the frame should be dump
* or not.
*
* @param frameBuffPtr
* @param frameType
*
* @return true CRC check passed, good frame.
* false CRC check failed, bad frame.
*
******************************************************************************/
bool CrcCheck(uint8_t* buffPtr, uint32_t dataLen){
if (dataLen == 0) {
return false;
}
bool ret = false;
#ifdef CRC_COMPARE
ret = crc16_check(buffPtr, dataLen - COMMON_CRC_LEN, dataLen - COMMON_CRC_LEN, 0x1021);
#else
uint16_t crc = 0;
uint32_t Status = 0;
Status = crc16_gen(buffPtr, dataLen, 0x1021, &crc);
if(Status != SUCCESS){
DBG_ERROR("C2C gernerate failed, error code: %d.\r\n", Status);
}
ret = (crc == 0);
#endif
return ret;
}
@@ -0,0 +1,77 @@
/*****************************************************************************/
/**
* Description: Common definitions and common function prototypes.
*
* Author: Fan Hao
* Date: 2021-12-04 16:32
* LastEditors: Fan Hao
* LastEditTime: 2021-12-05 19:40
* Revisions: Rev 0.0
* History:
* [2021-12-04]: Initial version.
* [2022-06-18]: Code simplification: remove link layer utilities.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
*
******************************************************************************/
/***************************** Include Files *********************************/
#ifndef MAIN_COMMON_H_
#define MAIN_COMMON_H_
#include <stdbool.h>
#include <stdint.h>
#include <assert.h>
#include "error.h"
#include "util/util.h"
#include "config/app_config.h"
/************************** Constant Definitions *****************************/
#define BROADCAST_ID 0x0F
#define NONE_ID 0x0E
#define COMMON_CRC_LEN 2
/***************** Macros (Inline Functions) Definitions *********************/
#define ASSERT(exp) assert(exp)
#define _nop_() asm("nop")
#define HALT_IF_ERR(status, msg, ...) \
if (SUCCESS != status) { \
printf("ERROR: #%d " msg, status, ##__VA_ARGS__); \
exit(status); \
}
/* Stringify */
#define STR(x) #x
// #define _814_DEBUG_LEVEL 3
#if _814_DEBUG_LEVEL == 1
#define DBG_ERROR(MSG, ...) printf("["__FILE__", %04d] ERROR: "MSG,__LINE__, ##__VA_ARGS__)
#define DBG_WARNING(MSG, ...) {}
#define DBG_INFO(MSG, ...) {}
#define DBG_PRINT(MSG, ...) printf(MSG, ##__VA_ARGS__)
#elif _814_DEBUG_LEVEL == 2
#define DBG_ERROR(MSG, ...) printf("["__FILE__", %04d] ERROR: "MSG,__LINE__, ##__VA_ARGS__)
#define DBG_WARNING(MSG, ...) printf("WARNING: "MSG, ##__VA_ARGS__)
#define DBG_INFO(MSG, ...) {}
#define DBG_PRINT(MSG, ...) printf(MSG, ##__VA_ARGS__)
#elif _814_DEBUG_LEVEL == 3
#define DBG_ERROR(MSG, ...) printf("["__FILE__", %04d] ERROR: "MSG,__LINE__, ##__VA_ARGS__)
#define DBG_WARNING(MSG, ...) printf("WARNING: "MSG, ##__VA_ARGS__)
#define DBG_INFO(MSG, ...) printf("INFO: "MSG, ##__VA_ARGS__)
#define DBG_PRINT(MSG, ...) printf(MSG, ##__VA_ARGS__)
#else
#define DBG_ERROR(MSG, ...) {}
#define DBG_WARNING(MSG, ...) {}
#define DBG_INFO(MSG, ...) {}
#define DBG_PRINT(MSG, ...) {}
#endif
/**************************** Type Definitions *******************************/
/************************** Variable Definitions *****************************/
/************************** Function Prototypes ******************************/
int AppendCrc(uint8_t* buffPtr, uint32_t dataLen);
bool CrcCheck(uint8_t* buffPtr, uint32_t dataLen);
#endif /* COMMON_H_ */
@@ -0,0 +1,79 @@
/*****************************************************************************/
/**
* Description: Global configurations.
*
* Author: Fan Hao
* Date: 2021-04-28 13:19
* Last Editors: Fan Hao
* Last Edit Time: [2022-05-23 20:32]
*
* Revisions: Rev 0.0
* History:
* [2021-04-28]: Initial edition.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
*
******************************************************************************/
#ifndef CONFIG_H_
#define CONFIG_H_
#define XILINX_PLATFORM
#include "xparameters.h"
#include "../util/util.h"
/*********** Indoor Test Mode ************/
/************ Hardware Configs ************/
#define CPU_CLK_HZ XPAR_CPU_CORTEXA9_0_CPU_CLK_FREQ_HZ
/********* Zynq Platform Configs **********/
// Check crc validation by computing crc value and comparing.
#define CRC_COMPARE
// Device ID Configs
#define INTC_DEVICE_ID XPAR_PS7_SCUGIC_0_DEVICE_ID
#define C2C_AXI_DMA_DEVICE_ID XPAR_C2C_DMA_AXI_DMA_C2C_DEVICE_ID
#define XGPIO_OUTPUT_CH 1
#define XGPIOINPUT_CH 2
#define C2C_RXBUFF_BASSADDR (XPAR_PS7_RAM_0_S_AXI_BASEADDR + 0x00004000)
#define C2C_TXBUFF_BASSADDR (C2C_RXBUFF_BASSADDR + C2C_BUFF_SIZE*C2C_BUFF_NUM)
#define C2C_BUFF_SIZE 1024
#define C2C_BUFF_NUM 16
#define GLINK_RXBUFF_BASSADDR (C2C_TXBUFF_BASSADDR + C2C_BUFF_SIZE*C2C_BUFF_NUM)
#define GLINK_TXBUFF_BASSADDR (GLINK_RXBUFF_BASSADDR + GLINK_BUFF_SIZE*GLINK_BUFF_NUM)
#define GLINK_BUFF_SIZE 1024
#define GLINK_BUFF_NUM 16
// Interrupt Configs
#define C2C_TX_INTR_ID XPAR_FABRIC_C2C_DMA_AXI_DMA_C2C_MM2S_INTROUT_INTR
#define C2C_RX_INTR_ID XPAR_FABRIC_C2C_DMA_AXI_DMA_C2C_S2MM_INTROUT_INTR
#define GLINK_TX_INTR_ID XPAR_FABRIC_GLINK_DMA_AXI_DMA_GLINK_MM2S_INTROUT_INTR
#define GLINK_RX_INTR_ID XPAR_FABRIC_GLINK_DMA_AXI_DMA_GLINK_S2MM_INTROUT_INTR
// Glink Configs
#define GLINK_CTRL_GPIO_DEVICE_ID XPAR_GLINK_CTRL_DEVICE_ID
#define PWDOWN_CTRL_GPIO_DEVICE_ID XPAR_PWDOWN_CTRL_DEVICE_ID
#define GLINK_AXI_DMA_DEVICE_ID XPAR_GLINK_DMA_AXI_DMA_GLINK_DEVICE_ID
#define GLINK_NODE_ID 0x0003
#define GLINK_TARGET_ID 0x0008
#define GLINK_TARGET_SUBADDR 0x0001
#define GLINK_NT_RECV1_SUBADDR 0x00005000
#define GLINK_NT_SEND1_SUBADDR 0x00005200
#define GLINK_NT_RECV2_SUBADDR 0x00005400
#define GLINK_NT_SEND2_SUBADDR 0x00005600
#define GLINK_NT_RECV3_SUBADDR 0x00005800
#define GLINK_NT_SEND3_SUBADDR 0x00005A00
#define GLINK_NT_RECV4_SUBADDR 0x00005C00
#define GLINK_NT_SEND4_SUBADDR 0x00005E00
#define GLINK_NT_RECV5_SUBADDR 0x00006000
#define GLINK_NT_SEND5_SUBADDR 0x00006200
#define GLINK_NT_RECV6_SUBADDR 0x00006400
#define GLINK_NT_SEND6_SUBADDR 0x00006600
#endif
@@ -0,0 +1,55 @@
/*****************************************************************************/
/**
* Description: Error code definitions.
*
* Author: Fan Hao
* Date: 2022-06-18 16:37
* LastEditors: Fan Hao
* LastEditTime: 2022-06-18 17:12
* Revisions: Rev 0.0
* History:
* [2022-06-18]: Initial version.
*
* Copyright(c) 2022 Beijing Institute of Technology.
* Lab of Communication and Networking
*
******************************************************************************/
#ifndef SRC_ERROR_H_
#define SRC_ERROR_H_
#include <errno.h>
/******************************************************************************/
/********************** Macros and Constants Definitions **********************/
/******************************************************************************/
#ifdef SUCCESS
#undef SUCCESS
#endif
#define SUCCESS 0
#ifdef FAILURE
#undef FAILURE
#endif
#define FAILURE -1
#define MEMORY_ALLOC_ERROR -2 /*!< Memory allocation failed */
#define DATA_CRC_ERROR -3 /*!< Data crc check failed */
#define PARAMETER_ERROR -4 /*!< Data crc check failed */
#define COMMAND_ERROR -5 /*!< Command Configuration is invalid */
#define UKNOWN_COMMAND_ERROR -6 /*!< Received an unsupported command */
#define IGNORE_ERROR -7 /*!< Received an unsupported command, and ignore it */
#define DEVICE_INVALIDE_ERROR -8 /*!< Device is invalid (sleep or power off) */
#define DEVICE_BUSY_ERROR -9 /*!< Device is busy */
#define TIMEOUT_ERROR -10
#define UNEXPECTED_ERROR -11 /*!< Encounter an unexpected error */
#define EDINVAL DEVICE_INVALIDE_ERROR
#define ETIMEOUT TIMEOUT_ERROR
#define EIGNORE IGNORE_ERROR
#define EUNEXP UNEXPECTED_ERROR
#define IS_ERR_VALUE(x) ((x) < 0)
#endif // ERROR_H_
@@ -0,0 +1,257 @@
/*****************************************************************************/
/**
* Description: Glink smart driver
*
* Author: Fan Hao
* Date: 2022-06-18 16:37
* LastEditors: Fan Hao
* LastEditTime: 2022-06-18 17:38
* Revisions: Rev 0.1
* History:
* [2022-06-18]: Initial version.
* [2023-02-23]: Non buffer, using axi dma driver.
*
* Copyright(c) 2022 Beijing Institute of Technology.
* Lab of Communication and Networking
*
******************************************************************************/
/***************************** Include Files *********************************/
#include <inttypes.h>
#include <stdbool.h>
#include "glink.h"
#include "xaxidma.h"
#include "xgpio.h"
#include "sleep.h"
#include "xtime_l.h"
#include "xil_cache.h"
#include "../error.h"
#include "../common.h"
#include "../util/util.h"
#include "../config/app_config.h"
/************************** Constant Definitions *****************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
static int32_t Glink_GpioMaskedWrite(GLINK_DESC* instPtr, uint32_t channel, uint32_t mask, uint32_t value);
static uint32_t Glink_GpioMaskedRead(GLINK_DESC* instPtr, uint32_t channel, uint32_t mask);
static int32_t Glink_GpioMaskedDirectionWrite(GLINK_DESC* instPtr, uint32_t channel, uint32_t mask, uint32_t value);
static uint32_t Glink_GpioMaskedDirectionRead(GLINK_DESC* instPtr, uint32_t channel, uint32_t mask);
static void Glink_SendTrigger(GLINK_DESC* instPtr);
/**************************** Type Definitions *******************************/
/************************** Variable Definitions *****************************/
GLINK_DESC* glinkInstPtr = NULL;
static int32_t Glink_GpioMaskedWrite(GLINK_DESC* instPtr, uint32_t channel, uint32_t mask, uint32_t value){
uint32_t ioValue = 0;
ioValue = XGpio_DiscreteRead(instPtr->ctrlGpioPtr, channel);
ioValue = (ioValue & (~mask)) | field_prep(mask, value);
XGpio_DiscreteWrite(instPtr->ctrlGpioPtr, channel, ioValue);
return SUCCESS;
}
static uint32_t Glink_GpioMaskedRead(GLINK_DESC* instPtr, uint32_t channel, uint32_t mask){
uint32_t ioValue = 0;
ioValue = XGpio_DiscreteRead(instPtr->ctrlGpioPtr, channel);
return field_get(mask, ioValue);
}
static int32_t Glink_GpioMaskedDirectionWrite(GLINK_DESC* instPtr, uint32_t channel, uint32_t mask, uint32_t value){
uint32_t ioConfig = 0;
uint32_t ioValue = 0;
ioConfig = XGpio_GetDataDirection(instPtr->ctrlGpioPtr, channel);
ioValue = XGpio_DiscreteRead(instPtr->ctrlGpioPtr, channel);
ioValue = (ioValue & (~mask)) | field_prep(mask, value);
XGpio_SetDataDirection(instPtr->ctrlGpioPtr, channel, ioConfig & (~mask));
XGpio_DiscreteWrite(instPtr->ctrlGpioPtr, channel, ioValue);
return SUCCESS;
}
static uint32_t Glink_GpioMaskedDirectionRead(GLINK_DESC* instPtr, uint32_t channel, uint32_t mask){
uint32_t ioConfig = 0;
uint32_t ioValue = 0;
ioConfig = XGpio_GetDataDirection(instPtr->ctrlGpioPtr, channel);
XGpio_SetDataDirection(instPtr->ctrlGpioPtr, channel, ioConfig | mask);
ioValue = XGpio_DiscreteRead(instPtr->ctrlGpioPtr, channel);
return field_get(mask, ioValue);
}
static void Glink_SendTrigger(GLINK_DESC* instPtr){
uint32_t triggerValue = 0;
triggerValue = Glink_GpioMaskedRead(instPtr, GLINK_TRIGGER_CH, GLINK_TRIGGER_MASK);
triggerValue = ~triggerValue;
Glink_GpioMaskedDirectionWrite(instPtr, GLINK_TRIGGER_CH, GLINK_TRIGGER_MASK, triggerValue);
return;
}
inline bool Glink_IsSendBusy(GLINK_DESC* instPtr){
ASSERT(instPtr != NULL);
return (instPtr->txDone == false);
}
inline bool Glink_IsRecvBusy(GLINK_DESC* instPtr){
return (instPtr->rxDone == false);
}
/*****************************************************************************/
/**
* @brief Initialize the glink descriptor instance, allocate space for
* message buffers.
*
* @param instPtr a second rank pointer to glink descriptor instance
* @param configPtr a pointer to glink descriptor instance configuration
* set.
*
* @return SUCCESS
* MEMORY_ALLOC_ERROR memory allocate failed.
*
******************************************************************************/
int32_t Glink_Init(GLINK_DESC** instPtr, const GLINK_CONFIG* configPtr){
ASSERT(configPtr != NULL);
int32_t Status = SUCCESS;
*instPtr = (GLINK_DESC*) malloc(sizeof(GLINK_DESC));
if ((*instPtr) == NULL) {
return MEMORY_ALLOC_ERROR;
}
(*instPtr)->txDone = true;
(*instPtr)->rxDone = true;
memcpy(&((*instPtr)->configs), configPtr, sizeof(GLINK_CONFIG));
/* Initialize DMA engine */
Status = Dma_Init(&((*instPtr)->axiDmaPtr),&((*instPtr)->configs.dmaConfig));
if (Status != SUCCESS) {
DBG_ERROR("AXI DMA initialize failed. device id: %d\r\n", GLINK_FIFO_DMA_DEVICE_ID);
return FAILURE;
}
// GPIO Init
(*instPtr)->ctrlGpioPtr = (XGpio*) malloc(sizeof(XGpio));
if ((*instPtr)->ctrlGpioPtr == NULL) {
return MEMORY_ALLOC_ERROR;
}
Status = XGpio_Initialize((*instPtr)->ctrlGpioPtr, GLINK_CTRL_GPIO_DEVICE_ID);
if(Status != SUCCESS){
DBG_ERROR("GPIO Device initialize failed \r\n");
return FAILURE;
}
XGpio_SetDataDirection((*instPtr)->ctrlGpioPtr, GLINK_GPIO_CH1, GLINK_GPIO_CH1_IO_CONFIG);
XGpio_SetDataDirection((*instPtr)->ctrlGpioPtr, GLINK_GPIO_CH2, GLINK_GPIO_CH2_IO_CONFIG);
(*instPtr)->isInit = true;
// Initial configs
// Halt Glink in reset
Glink_GpioMaskedWrite(*instPtr, GLINK_RESET_CH, GLINK_RESET_MASK, GLINK_RESET);
usleep(10); // sleep 10us
Glink_SetNodeId(*instPtr, (*instPtr)->configs.nodeId);
Glink_GpioMaskedWrite(*instPtr, GLINK_SNTCFG_CH, GLINK_SNTCFG_MASK,
(*instPtr)->configs.smartNtConfig);
Glink_GpioMaskedWrite(*instPtr, GLINK_SNCCFG0_CH, GLINK_SNCCFG0_MASK,
(*instPtr)->configs.smartNcConfig0);
Glink_GpioMaskedWrite(*instPtr, GLINK_SNCCFG1_CH, GLINK_SNCCFG1_MASK,
(*instPtr)->configs.smartNcConfig1);
usleep(10); // sleep 10us wait for signal stabilize
// Enable Glink
Glink_GpioMaskedWrite(*instPtr, GLINK_RESET_CH, GLINK_RESET_MASK, GLINK_ENABLE);
usleep(10); // sleep 10us wait for signal stabilize
return Status;
}
int32_t Glink_IrqEnable(GLINK_DESC* instPtr){
if(instPtr==NULL || instPtr->isInit == false){
return FAILURE;
}
/* Enable all interrupts */
return Dma_IrqEnable(instPtr->axiDmaPtr);
}
int32_t Glink_SetNodeId(GLINK_DESC* instPtr, uint16_t nodeId){
if(instPtr == NULL || instPtr->isInit == false){
return DEVICE_INVALIDE_ERROR;
}
Glink_GpioMaskedWrite(instPtr, GLINK_NODE_ID_CH, GLINK_NODE_ID_MASK, nodeId);
return SUCCESS;
}
int16_t Glink_ReadSeg(uint16_t* addr, uint32_t offset){
return (*(addr + offset));
}
void Glink_WriteSeg(uint16_t* addr, uint32_t offset, uint16_t data){
volatile uint16_t *localAddr = addr + offset;
*localAddr = data;
}
int32_t Glink_RecvData(GLINK_DESC* instPtr, uint8_t* dataBuff, int32_t buffSize){
if(instPtr == NULL || instPtr->isInit == false){
return DEVICE_INVALIDE_ERROR;
}
instPtr->rxDone = false;
instPtr->lastRxBuff = (uintptr_t)dataBuff;
instPtr->lastRxBuffSize = buffSize;
if (SUCCESS == Dma_RecvData(instPtr->axiDmaPtr, dataBuff, buffSize)){
return SUCCESS;
}
else{
return FAILURE;
}
}
/****************************************************************************/
/**
* This is a utility function to implement a Glink data transmission.
*
* @param buffPtr a pointer to data buffer, which need to be 2 byte aligned.
* @param dataLen length of data needs to be sent.
* @param subaddrId taget subAddress
*
* @return None.
*
* @note None.
*
*****************************************************************************/
int32_t Glink_SendData(GLINK_DESC* instPtr, uint8_t* dataBuff, int32_t dataLen, uint16_t subAddr){
if(dataLen > 512){
return FAILURE;
}
uint16_t* txHeaderPtr = NULL;
// Flush the SrcBuffer before the DMA transfer
// Xil_DCacheFlushRange((UINTPTR)instPtr->configs.txBaseaddr, GLINK_TRANS_LEN);
txHeaderPtr = (uint16_t*) dataBuff;
// Insert frame header.
*(txHeaderPtr+GLINK_TX_SUBADDR_OFFSET) = subAddr;
*(txHeaderPtr+GLINK_TX_DATALEN_OFFSET) = 0x1400|((dataLen == 512)? 0: dataLen);
*(txHeaderPtr+GLINK_TX_TARGETID_OFFSET) = 0x4000 | GLINK_TARGET_ID;
// Set txDone flage to false, before transmission
instPtr->txDone = false;
instPtr->lastTxBuff = (uintptr_t)dataBuff;
instPtr->lastTxBuffSize = dataLen;
// Assert a send trigger
Glink_SendTrigger(instPtr);
if (SUCCESS == Dma_SendData(instPtr->axiDmaPtr, dataBuff, dataLen + GLINK_MSG_HEADER_LEN_BYTES)){
return SUCCESS;
}
else{
return FAILURE;
}
}
int32_t Glink_TxIrqHandler(GLINK_DESC* instPtr){
instPtr->txDone = true;
if(instPtr == NULL || instPtr->isInit == false){
return FAILURE;
}
return Dma_SendIrqHandler(instPtr->axiDmaPtr);
}
int32_t Glink_RxIrqHandler(GLINK_DESC* instPtr){
instPtr->rxDone = true;
if(instPtr == NULL || instPtr->isInit == false){
return FAILURE;
}
return Dma_RecvIrqHandler(instPtr->axiDmaPtr);
}
@@ -0,0 +1,111 @@
/*****************************************************************************/
/**
* Description: Glink Smart driver
* prototypes.
*
* Author: Fan Hao
* Date: 2022-06-18 16:37
* LastEditors: Fan Hao
* LastEditTime: 2022-06-18 17:40
* Revisions: Rev 0.1
* History:
* [2022-06-18]: Initial version.
* [2023-02-23]: Non buffer, using axi dma driver.
*
* Copyright(c) 2022 Beijing Institute of Technology.
* Lab of Communication and Networking
*
******************************************************************************/
#ifndef SRC_GLINK_GLINK_H_
#define SRC_GLINK_GLINK_H_
/***************************** Include Files *********************************/
#include <inttypes.h>
#include <stdbool.h>
#include "../axi_dma/axi_dma.h"
#include "xgpio.h"
/************************** Constant Definitions *****************************/
#define GLINK_GPIO_CH1 1
#define GLINK_GPIO_CH2 2
#define GLINK_GPIO_CH1_IO_CONFIG 0x0000C000
#define GLINK_GPIO_CH2_IO_CONFIG 0x00000000
#define GLINK_NODE_ID_CH 1
#define GLINK_NODE_ID_MASK 0x00000FFF
#define GLINK_TRIGGER_CH 1
#define GLINK_TRIGGER_MASK 0x00001000
#define GLINK_RESET_CH 1
#define GLINK_RESET_MASK 0x00002000
#define GLINK_IDLE_CH 1
#define GLINK_IDLE_MASK 0x00004000
#define GLINK_ERROR_CH 1
#define GLINK_ERROR_MASK 0x00008000
#define GLINK_SNTCFG_CH 1
#define GLINK_SNTCFG_MASK 0xFFFF0000
#define GLINK_SNCCFG0_CH 2
#define GLINK_SNCCFG0_MASK 0x0000FFFF
#define GLINK_SNCCFG1_CH 2
#define GLINK_SNCCFG1_MASK 0xFFFF0000
#define GLINK_RESET 1
#define GLINK_ENABLE 0
#define GLINK_MSG_HEADER_LEN_BYTES (2*3)// 16bit*3
#define GLINK_MSG_LEN 512
#define GLINK_TRANS_LEN 1024
#define GLINK_TX_SUBADDR_OFFSET 0
#define GLINK_TX_TARGETID_OFFSET 1
#define GLINK_TX_DATALEN_OFFSET 2
#define GLINK_TX_PAYLOAD_OFFSET 3
#define GLINK_RX_SOURCEID_OFFSET 0
#define GLINK_RX_SUBADDR_OFFSET 1
#define GLINK_RX_DATALEN_OFFSET 2
#define GLINK_RX_PAYLOAD_OFFSET 3
#define GLINK_TIMEOUT 166667UL //500us
/***************** Macros (Inline Functions) Definitions *********************/
/**************************** Type Definitions *******************************/
typedef struct{
uint16_t nodeId;
uint16_t smartNtConfig;
uint16_t smartNcConfig0;
uint16_t smartNcConfig1;
DMA_CONFIG dmaConfig;
}GLINK_CONFIG;
typedef struct{
GLINK_CONFIG configs;
bool isInit;
bool txDone;
bool rxDone;
uintptr_t lastTxBuff;
uint32_t lastTxBuffSize;
uintptr_t lastRxBuff;
uint32_t lastRxBuffSize;
DMA_DESC* axiDmaPtr;
XGpio* ctrlGpioPtr;
}GLINK_DESC;
/************************** Variable Definitions *****************************/
extern GLINK_DESC* glinkInstPtr;
/************************** Function Prototypes ******************************/
int32_t Glink_Init(GLINK_DESC** instPtr, const GLINK_CONFIG* configPtr);
int32_t Glink_SetNodeId(GLINK_DESC* instPtr, uint16_t nodeId);
int32_t Glink_IrqEnable(GLINK_DESC* instPtr);
int32_t Glink_RecvData(GLINK_DESC* instPtr, uint8_t* dataBuff, int32_t buffSize);
int32_t Glink_SendData(GLINK_DESC* instPtr, uint8_t* dataBuff, int32_t dataLen, uint16_t subAddr);
bool Glink_IsSendBusy(GLINK_DESC* instPtr);
bool Glink_IsRecvBusy(GLINK_DESC* instPtr);
int32_t Glink_TxIrqHandler(GLINK_DESC* instPtr);
int32_t Glink_RxIrqHandler(GLINK_DESC* instPtr);
int16_t Glink_ReadSeg(uint16_t* addr, uint32_t offset);
void Glink_WriteSeg(uint16_t* addr, uint32_t offset, uint16_t data);
#endif
@@ -0,0 +1,288 @@
/*******************************************************************/
/* */
/* This file is automatically generated by linker script generator.*/
/* */
/* Version: 2019.1.3 */
/* */
/* Copyright (c) 2010-2016 Xilinx, Inc. All rights reserved. */
/* */
/* Description : Cortex-A9 Linker Script */
/* */
/*******************************************************************/
_STACK_SIZE = DEFINED(_STACK_SIZE) ? _STACK_SIZE : 0x2000;
_HEAP_SIZE = DEFINED(_HEAP_SIZE) ? _HEAP_SIZE : 0x2000;
_ABORT_STACK_SIZE = DEFINED(_ABORT_STACK_SIZE) ? _ABORT_STACK_SIZE : 1024;
_SUPERVISOR_STACK_SIZE = DEFINED(_SUPERVISOR_STACK_SIZE) ? _SUPERVISOR_STACK_SIZE : 2048;
_IRQ_STACK_SIZE = DEFINED(_IRQ_STACK_SIZE) ? _IRQ_STACK_SIZE : 1024;
_FIQ_STACK_SIZE = DEFINED(_FIQ_STACK_SIZE) ? _FIQ_STACK_SIZE : 1024;
_UNDEF_STACK_SIZE = DEFINED(_UNDEF_STACK_SIZE) ? _UNDEF_STACK_SIZE : 1024;
/* Define Memories in the system */
MEMORY
{
ps7_ddr_0 : ORIGIN = 0x100000, LENGTH = 0x1FF00000
ps7_qspi_linear_0 : ORIGIN = 0xFC000000, LENGTH = 0x1000000
ps7_ram_0 : ORIGIN = 0x0, LENGTH = 0x30000
ps7_ram_1 : ORIGIN = 0xFFFF0000, LENGTH = 0xFE00
}
/* Specify the default entry point to the program */
ENTRY(_vector_table)
/* Define the sections, and where they are mapped in memory */
SECTIONS
{
.text : {
KEEP (*(.vectors))
*(.boot)
*(.text)
*(.text.*)
*(.gnu.linkonce.t.*)
*(.plt)
*(.gnu_warning)
*(.gcc_execpt_table)
*(.glue_7)
*(.glue_7t)
*(.vfp11_veneer)
*(.ARM.extab)
*(.gnu.linkonce.armextab.*)
} > ps7_ddr_0
.init : {
KEEP (*(.init))
} > ps7_ddr_0
.fini : {
KEEP (*(.fini))
} > ps7_ddr_0
.rodata : {
__rodata_start = .;
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r.*)
__rodata_end = .;
} > ps7_ddr_0
.rodata1 : {
__rodata1_start = .;
*(.rodata1)
*(.rodata1.*)
__rodata1_end = .;
} > ps7_ddr_0
.sdata2 : {
__sdata2_start = .;
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
__sdata2_end = .;
} > ps7_ddr_0
.sbss2 : {
__sbss2_start = .;
*(.sbss2)
*(.sbss2.*)
*(.gnu.linkonce.sb2.*)
__sbss2_end = .;
} > ps7_ddr_0
.data : {
__data_start = .;
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
*(.jcr)
*(.got)
*(.got.plt)
__data_end = .;
} > ps7_ddr_0
.data1 : {
__data1_start = .;
*(.data1)
*(.data1.*)
__data1_end = .;
} > ps7_ddr_0
.got : {
*(.got)
} > ps7_ddr_0
.ctors : {
__CTOR_LIST__ = .;
___CTORS_LIST___ = .;
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE(*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
__CTOR_END__ = .;
___CTORS_END___ = .;
} > ps7_ddr_0
.dtors : {
__DTOR_LIST__ = .;
___DTORS_LIST___ = .;
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE(*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
__DTOR_END__ = .;
___DTORS_END___ = .;
} > ps7_ddr_0
.fixup : {
__fixup_start = .;
*(.fixup)
__fixup_end = .;
} > ps7_ddr_0
.eh_frame : {
*(.eh_frame)
} > ps7_ddr_0
.eh_framehdr : {
__eh_framehdr_start = .;
*(.eh_framehdr)
__eh_framehdr_end = .;
} > ps7_ddr_0
.gcc_except_table : {
*(.gcc_except_table)
} > ps7_ddr_0
.mmu_tbl (ALIGN(16384)) : {
__mmu_tbl_start = .;
*(.mmu_tbl)
__mmu_tbl_end = .;
} > ps7_ddr_0
.ARM.exidx : {
__exidx_start = .;
*(.ARM.exidx*)
*(.gnu.linkonce.armexidix.*.*)
__exidx_end = .;
} > ps7_ddr_0
.preinit_array : {
__preinit_array_start = .;
KEEP (*(SORT(.preinit_array.*)))
KEEP (*(.preinit_array))
__preinit_array_end = .;
} > ps7_ddr_0
.init_array : {
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
} > ps7_ddr_0
.fini_array : {
__fini_array_start = .;
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array))
__fini_array_end = .;
} > ps7_ddr_0
.ARM.attributes : {
__ARM.attributes_start = .;
*(.ARM.attributes)
__ARM.attributes_end = .;
} > ps7_ddr_0
.sdata : {
__sdata_start = .;
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
__sdata_end = .;
} > ps7_ddr_0
.sbss (NOLOAD) : {
__sbss_start = .;
*(.sbss)
*(.sbss.*)
*(.gnu.linkonce.sb.*)
__sbss_end = .;
} > ps7_ddr_0
.tdata : {
__tdata_start = .;
*(.tdata)
*(.tdata.*)
*(.gnu.linkonce.td.*)
__tdata_end = .;
} > ps7_ddr_0
.tbss : {
__tbss_start = .;
*(.tbss)
*(.tbss.*)
*(.gnu.linkonce.tb.*)
__tbss_end = .;
} > ps7_ddr_0
.bss (NOLOAD) : {
__bss_start = .;
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
__bss_end = .;
} > ps7_ddr_0
_SDA_BASE_ = __sdata_start + ((__sbss_end - __sdata_start) / 2 );
_SDA2_BASE_ = __sdata2_start + ((__sbss2_end - __sdata2_start) / 2 );
/* Generate Stack and Heap definitions */
.heap (NOLOAD) : {
. = ALIGN(16);
_heap = .;
HeapBase = .;
_heap_start = .;
. += _HEAP_SIZE;
_heap_end = .;
HeapLimit = .;
} > ps7_ddr_0
.stack (NOLOAD) : {
. = ALIGN(16);
_stack_end = .;
. += _STACK_SIZE;
. = ALIGN(16);
_stack = .;
__stack = _stack;
. = ALIGN(16);
_irq_stack_end = .;
. += _IRQ_STACK_SIZE;
. = ALIGN(16);
__irq_stack = .;
_supervisor_stack_end = .;
. += _SUPERVISOR_STACK_SIZE;
. = ALIGN(16);
__supervisor_stack = .;
_abort_stack_end = .;
. += _ABORT_STACK_SIZE;
. = ALIGN(16);
__abort_stack = .;
_fiq_stack_end = .;
. += _FIQ_STACK_SIZE;
. = ALIGN(16);
__fiq_stack = .;
_undef_stack_end = .;
. += _UNDEF_STACK_SIZE;
. = ALIGN(16);
__undef_stack = .;
} > ps7_ddr_0
_end = .;
}
@@ -0,0 +1,649 @@
/*****************************************************************************/
/**
* Description: main.c
*
* Author: Fan Hao
* Date: 2021-11-13 13:19
* Last Editors: Fan Hao
* Last Edit Time: [2022-03-28 20:32]
*
* Revisions: Rev 0.0
* History:
* [2021-11-13]: Initial edition.
* [2022-03-28]: Add bit error test mode.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
*
******************************************************************************/
/***************************** Include Files *********************************/
// Standard
#include <stdbool.h>
#include <inttypes.h>
#include <stdio.h>
// Xilinx
#include "xscugic.h" // The generic interrupt controller driver component
#include "xil_exception.h" // ARM Cortex A9 specific exception related APIs
#include "sleep.h" // Sleep APIs for Cortex A9
#include "xgpio.h" //
#include "xadcps.h"
// User
#include "common.h"
#include "error.h"
#include "mmu_ctrl.h"
#include "config/app_config.h"
#include "glink/glink.h"
#include "c2c_bridge/c2c_bridge.h"
#include "queue/queue.h"
#include "circ_queue/circ_queue.h"
#define C2C_FRAME_LEN 532
#define GLINK_FRAME_LEN 532
/************************** Function Prototypes ******************************/
int XADC_Init(XAdcPs* instPtr, uint16_t devId);
int SetupInterruptSystem(uint32_t devId, XScuGic* instPtr);
// C2C bridge
void C2c_TxIntrHandler(void *Callback);
void C2c_RxIntrHandler(void *Callback);
// Glink
int GlinkRecvData(void* buffPtr, int32_t* dataLen);
int GlinkSendData2Addr(void* buffPtr, int32_t dataLen, uint16_t subaddrId);
void Glink_TxIntrHandler(void *Callback);
void Glink_RxIntrHandler(void *Callback);
/************************** Constant Definitions *****************************/
const GLINK_CONFIG glinkConfig = {
.nodeId = GLINK_NODE_ID,
.smartNtConfig = 0x4000,
.smartNcConfig0 = 0x0003,
.smartNcConfig1 = 0x0400,
.dmaConfig = {
.devId = GLINK_AXI_DMA_DEVICE_ID,
.transMax = C2C_BUFF_MAX,
.defaultTransLen = C2C_BUFF_MAX,
.timeoutTh = 500
}
};
C2C_CONFIG c2cConfig = {
.capacity = C2C_BUFF_MAX,
.dmaConfig = {
.devId = C2C_AXI_DMA_DEVICE_ID,
.transMax = C2C_BUFF_MAX,
.defaultTransLen = C2C_BUFF_MAX,
.timeoutTh = 500
}
};
/**************************** Type Definitions *******************************/
typedef struct {
uint16_t glinkSubAddr;
uint8_t extra[14];
} C2C_EXTRA;
/*********************** Driver Instance Definitions **************************/
static XScuGic intcInst; // General interrupt controller instance
static C2C_EXTRA c2cExtraBuff;
static XAdcPs XAdcInst; /* XADC driver instance */
static XGpio PwdownGpio; /* XADC driver instance */
static CIRC_QUEUE* c2cSendQueue;
static CIRC_QUEUE* glinkSendQueue;
/****************************************************************************/
/**
*
* This function runs a test on the XADC/ADC device using the
* driver APIs.
* This function does the following tasks:
* - Initiate the XADC device driver instance
* - Run self-test on the device
* - Setup the sequence registers to continuously monitor on-chip
*
* @param XAdcDeviceId is the XPAR_<SYSMON_ADC_instance>_DEVICE_ID value
* from xparameters.h.
*
* @return
*
* @note None
*
****************************************************************************/
int XADC_Init(XAdcPs* instPtr, uint16_t devId){
int Status;
XAdcPs_Config *ConfigPtr;
/*
* Initialize the XAdc driver.
*/
ConfigPtr = XAdcPs_LookupConfig(devId);
if (ConfigPtr == NULL) {
return XST_FAILURE;
}
XAdcPs_CfgInitialize(instPtr, ConfigPtr,
ConfigPtr->BaseAddress);
/*
* Self Test the XADC/ADC device
*/
Status = XAdcPs_SelfTest(instPtr);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Disable the Channel Sequencer before configuring the Sequence
* registers.
*/
XAdcPs_SetSequencerMode(instPtr, XADCPS_SEQ_MODE_SAFE);
return SUCCESS;
}
/****************************************************************************/
/**
* This function is responsible for initializing the SCUGIC instance, looking
* for the device configuration based on the unique device ID, initializing a
* SCUGIC instance, and initialize the interrupt at IRQ_F2P[0:0]
*
* @param devId is the XPAR_<GPIO_instance>_DEVICE_ID value from
* "xparameters.h".
* @param instancePtr is a reference to the XScuGic driver Instance.
*
* @return XST_SUCCESS if initialize successful.
* XST_FAILURE if initialization failed.
*
*****************************************************************************/
int SetupInterruptSystem(uint32_t deviceID, XScuGic* instPtr) {
XScuGic_Config *configPtr;
int Status;
uint32_t intrState;
// Initialize the GIC instance.
configPtr = XScuGic_LookupConfig(deviceID);
Status = XScuGic_CfgInitialize(instPtr, configPtr,
configPtr->CpuBaseAddress);
if (Status != SUCCESS) {
return Status;
}
// Perform a self-test to ensure that the hardware was built correctly.
Status = XScuGic_SelfTest(instPtr);
if (Status != SUCCESS) {
return Status;
}
// Clear any pending interrupt flags
intrState = XScuGic_CPUReadReg(instPtr, XSCUGIC_INT_ACK_OFFSET);
XScuGic_CPUWriteReg(instPtr, XSCUGIC_EOI_OFFSET, intrState);
/*
* FOR PRIORITY:
* 0 is highest priority, 0xF8(248) is lowest. There are 32 priority levels
* supported with a step of 8. Hence the supported priorities are 0, 8, 16,
* 32, 40 ..., 248.
*
* FOR TRIGGER:
* SFI Read Only b10 always
* PPI Read Only depending on how the PPIs are configured.
* b01 Active HIGH level sensitive
* b11 Rising edge sensitive
* SPI LSB is read only.
* b01 Active HIGH level sensitive
* b11 Rising edge sensitive
*/
/* Set the priority of IRQ_F2P[1:1] to 0x00 (highest) and a trigger for a
* rising edge 0x03.
*/
// Initialize glink interrupt.
XScuGic_SetPriorityTriggerType(instPtr, GLINK_TX_INTR_ID, 0x00, 0x03);
XScuGic_SetPriorityTriggerType(instPtr, GLINK_RX_INTR_ID, 0x20, 0x03);
// Connect the interrupt service routine isr1 to the interrupt controller
Status = XScuGic_Connect(instPtr, GLINK_TX_INTR_ID,
(Xil_InterruptHandler)Glink_TxIntrHandler,
instPtr);
if (Status != XST_SUCCESS) {
return Status;
}
Status = XScuGic_Connect(instPtr, GLINK_RX_INTR_ID,
(Xil_InterruptHandler)Glink_RxIntrHandler,
instPtr);
if (Status != XST_SUCCESS) {
return Status;
}
// Initialize c2c interrupt.
XScuGic_SetPriorityTriggerType(instPtr, C2C_TX_INTR_ID, 0x00, 0x03);
XScuGic_SetPriorityTriggerType(instPtr, C2C_RX_INTR_ID, 0x20, 0x03);
// Connect the interrupt service routine isr1 to the interrupt controller
Status = XScuGic_Connect(instPtr, C2C_RX_INTR_ID,
(Xil_ExceptionHandler) C2c_RxIntrHandler, (void *) instPtr);
if (Status != SUCCESS) {
return Status;
}
Status = XScuGic_Connect(instPtr, C2C_TX_INTR_ID,
(Xil_ExceptionHandler) C2c_TxIntrHandler, (void *) instPtr);
if (Status != SUCCESS) {
return Status;
}
// Enable interrupts for IRQ_F2P
XScuGic_Enable(instPtr, GLINK_TX_INTR_ID);
XScuGic_Enable(instPtr, GLINK_RX_INTR_ID);
XScuGic_Enable(instPtr, C2C_TX_INTR_ID);
XScuGic_Enable(instPtr, C2C_RX_INTR_ID);
/* Initialize the exception table and register the interrupt controller
* handler with the exception table
*/
Xil_ExceptionInit();
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler) XScuGic_InterruptHandler,
(void *) instPtr);
// Enable non-critical exceptions
Xil_ExceptionEnable();
return SUCCESS;
} // SetupInterruptSystem
/*****************************************************************************/
/*
*
* This is the C2C DMA TX Interrupt handler function.
*
* It gets the interrupt status from the hardware, acknowledges it, and if any
* error happens, it resets the hardware. Otherwise, if a completion interrupt
* is present, then sets the TxDone.flag
*
* @param Callback is a pointer to TX channel of the DMA engine.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void C2c_TxIntrHandler(void *Callback) {
int32_t Status;
Status = C2c_SendIrqHandler(c2cInstPtr);
if(Status != SUCCESS){
DBG_WARNING("Glink_TxIrqHandler runs failed with error code: %ld\r\n", Status);
}
return;
} //Glink_TxIntrHandler
/****************************************************************************/
/**
* This function is a interrupt service routine for IRQ_F2P[1:1], IRQ_F2P[1:1]
* tells CPU that the data in OCM is ready!
*
* @param callBackRef is the SCUGIC instance pointer.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
uint32_t c2cRecvCnt = 0;
void C2c_RxIntrHandler(void *callBackRef) {
int32_t Status;
Status = C2c_RecvIrqHandler(c2cInstPtr);
if(Status != SUCCESS){
// Restart receiving
C2c_RecvData(c2cInstPtr, (uint8_t*)c2cInstPtr->lastRxBuff, C2C_FRAME_LEN);
return;
}
//Push to queue
CircQueuePush(glinkSendQueue, (uint8_t*)c2cInstPtr->lastRxBuff);
// Start listening a new packet.
uintptr_t newC2cRecvBuff = (c2cInstPtr->lastRxBuff >= C2C_RXBUFF_BASSADDR + (C2C_BUFF_NUM-1)*C2C_BUFF_SIZE) ?
C2C_RXBUFF_BASSADDR : (c2cInstPtr->lastRxBuff + C2C_BUFF_SIZE);
C2c_RecvData(c2cInstPtr, (uint8_t *)newC2cRecvBuff, C2C_FRAME_LEN);
c2cRecvCnt++;
return;
} // C2cRxIntr_Handler
/*****************************************************************************/
/*
*
* This is the Glink DMA TX Interrupt handler function.
*
* It gets the interrupt status from the hardware, acknowledges it, and if any
* error happens, it resets the hardware. Otherwise, if a completion interrupt
* is present, then sets the TxDone.flag
*
* @param Callback is a pointer to TX channel of the DMA engine.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void Glink_TxIntrHandler(void *Callback) {
int32_t Status = SUCCESS;
Status = Glink_TxIrqHandler(glinkInstPtr);
if(Status != SUCCESS){
DBG_WARNING("Glink_TxIrqHandler runs failed with error code: %ld\r\n", Status);
_nop_();
}
return;
} //C2c_TxIntrHandler
/*****************************************************************************/
/*
*
* This is the DMA RX interrupt handler function
*
* It gets the interrupt status from the hardware, acknowledges it, and if any
* error happens, it resets the hardware. Otherwise, if a completion interrupt
* is present, then it sets the RxDone flag.
*
* @param Callback is a pointer to RX channel of the DMA engine.
*
* @return None.
*
* @note None.
*
******************************************************************************/
uint32_t frameCnt = 0;
void Glink_RxIntrHandler(void *Callback){
frameCnt ++;
int32_t Status;
uint16_t *msgRecvPtr;
Status = Glink_RxIrqHandler(glinkInstPtr);
msgRecvPtr = (uint16_t *)glinkInstPtr->lastRxBuff;
if(Status != SUCCESS){
DBG_PRINT("####\tInterComm message handler runs failed.\n\r");
Glink_RecvData(glinkInstPtr, (uint8_t *)glinkInstPtr->lastRxBuff, GLINK_FRAME_LEN);
_nop_();
}
else{
if(((*msgRecvPtr) & 0x0FFF) != GLINK_TARGET_ID){
// Restart Listening...
Glink_RecvData(glinkInstPtr, (uint8_t *)glinkInstPtr->lastRxBuff, GLINK_FRAME_LEN);
_nop_();
return;
}
//sleep or wake
uint16_t msgType, cmdCode;
msgType = *(msgRecvPtr + GLINK_RX_PAYLOAD_OFFSET);
if(msgType == 0x0012){
cmdCode = *(msgRecvPtr + GLINK_RX_PAYLOAD_OFFSET + 1);
if(cmdCode == 0xAAAA){
// sleep
XGpio_DiscreteWrite(&PwdownGpio, 1, 0);
}
else if(cmdCode == 0xCCCC){
// wake up
XGpio_DiscreteWrite(&PwdownGpio, 1, 1);
}
else {
// ignore
}
}
//Push to queue
CircQueuePush(c2cSendQueue, msgRecvPtr);
// Start listening a new packet.
uintptr_t newGlinkRecvBuff = (glinkInstPtr->lastRxBuff >= GLINK_RXBUFF_BASSADDR + (GLINK_BUFF_NUM-1)*GLINK_BUFF_SIZE) ?
GLINK_RXBUFF_BASSADDR : (glinkInstPtr->lastRxBuff + GLINK_BUFF_SIZE);
Glink_RecvData(glinkInstPtr, (uint8_t*)newGlinkRecvBuff, GLINK_FRAME_LEN);
}
} //Glink_RxIntrHandler
/*****************************************************************************/
/**
* @brief Main function, initialize all the device needed, initialize
* interrupt system, halt in while(1) wait for event interrupt.
*
* @param None.
*
* @return
*
******************************************************************************/
int main(void) {
// Xil_ICacheEnable();
// Xil_DCacheDisable();
Xil_SetTlbAttributes(0x00000000,
MMU_L1_SECT | MMU_L1_DOMAIN(15) | MMU_L1_SHAREABLE
| MMU_L1_GLOBAL | MMU_L1_EXEC | MMU_L1_FULLACS
| 0x00001000); //non-cacheable
int Status = SUCCESS;
// Initialize XADC
Status = XADC_Init(&XAdcInst, XPAR_PS7_XADC_0_DEVICE_ID);
if (Status == SUCCESS) {
DBG_INFO("XADC Init SUCCESS! \r\n");
}
else {
DBG_ERROR("XADC Init FAILED, ErrorCode: %d\r\n, Status");
return Status;
}
// Initialize Glink
Status = Glink_Init(&glinkInstPtr, &glinkConfig);
if (Status == SUCCESS) {
DBG_INFO("Glink Init SUCCESS! \r\n");
}
else {
DBG_ERROR("Glink Init FAILED, ErrorCode: %d\r\n, Status");
return Status;
}
// Initialize C2C bridge
Status = C2c_Init(&c2cInstPtr, &c2cConfig);
if (Status == SUCCESS) {
DBG_INFO("Intc Init SUCCESS! \r\n");
}
else {
DBG_ERROR("C2C bridge Init FAILED, ErrorCode: %d\r\n, Status");
return Status;
}
// Initialize GIC.
Status = SetupInterruptSystem(INTC_DEVICE_ID, &intcInst);
if (Status == SUCCESS) {
DBG_INFO("Intc Init SUCCESS! \r\n");
}
else {
DBG_ERROR("Intc Init FAILED, ErrorCode: %d\r\n, Status");
return Status;
}
/* Initialize the PwdownGpio driver */
Status = XGpio_Initialize(&PwdownGpio, XPAR_PWDOWN_CTRL_DEVICE_ID);
if (Status != XST_SUCCESS) {
xil_printf("Gpio Initialization Failed\r\n");
return XST_FAILURE;
}
XGpio_SetDataDirection(&PwdownGpio, 1, 0);//output
XGpio_DiscreteWrite(&PwdownGpio, 1, 1);//1 wake 0 sleep
Status = CircQueueCreate(&c2cSendQueue, C2C_BUFF_NUM);
if (Status == true) {
DBG_INFO("C2C queue init SUCCESS!\r\n");
}
else {
DBG_ERROR("C2C queue init, with error code: %d.\r\n", Status);
return MEMORY_ALLOC_ERROR;
}
Status = CircQueueCreate(&glinkSendQueue, GLINK_BUFF_NUM);
if (Status == true) {
DBG_INFO("Glink queue init SUCCESS!\r\n");
}
else {
DBG_ERROR("Glink queue init, with error code: %d.\r\n", Status);
return MEMORY_ALLOC_ERROR;
}
// Start C2C listening.
Status = C2c_RecvData(c2cInstPtr, (uint8_t *)C2C_RXBUFF_BASSADDR, C2C_FRAME_LEN);
if (Status == SUCCESS) {
DBG_INFO("C2c start listening SUCCESS!\r\n");
}
else {
DBG_ERROR("C2c message listening enable FAILED, with error code: %d.\r\n", Status);
return Status;
}
Status = C2c_IrqEnable(c2cInstPtr);
if (Status == SUCCESS) {
DBG_INFO("C2c interrupts enable SUCCESS!\r\n");
}
else {
DBG_ERROR("C2c interrupts enable FAILED, with error code: %d.\r\n", Status);
return Status;
}
// Start Glink listening.
Status = Glink_RecvData(glinkInstPtr, (uint8_t *)GLINK_RXBUFF_BASSADDR, GLINK_FRAME_LEN);
if (Status == SUCCESS) {
DBG_INFO("Glink start listening SUCCESS!\r\n");
}
else {
DBG_ERROR("Glink message listening enable FAILED, with error code: %d.\r\n", Status);
return Status;
}
Status = Glink_IrqEnable(glinkInstPtr);
if (Status == SUCCESS) {
DBG_INFO("Glink interrupts enable SUCCESS!\r\n");
}
else {
DBG_ERROR("Glink interrupts enable FAILED, with error code: %d.\r\n", Status);
return Status;
}
// For Remote Monitoring
uint32_t TempRawData;
uint32_t VccRawData;
uint16_t TempData;
uint16_t VccData;
// For glink->c2c relay
uint8_t *c2cSendBuff;
uint8_t *c2cSendQueueEl;
size_t c2cSendElementSize;
// For c2c->glink relay
uint8_t *glinkSendBuff;
uint8_t *glinkSendQueueEl;
size_t glinkSendElementSize;
c2cSendBuff = (uint8_t *) C2C_TXBUFF_BASSADDR;
glinkSendBuff = (uint8_t *) GLINK_TXBUFF_BASSADDR;
while(true){
if(!isCircQueueEmpty(c2cSendQueue) && !C2c_IsSendBusy(c2cInstPtr)){
TempRawData = XAdcPs_GetAdcData(&XAdcInst, XADCPS_CH_TEMP);
TempData = (uint16_t)(XAdcPs_RawToTemperature(TempRawData) * 10);
VccRawData = XAdcPs_GetAdcData(&XAdcInst, XADCPS_CH_VCCPINT);
VccData = (uint16_t)(XAdcPs_RawToVoltage(VccRawData) * 10);
c2cExtraBuff.extra[0] = (uint8_t)(TempData);
c2cExtraBuff.extra[1] = (uint8_t)(TempData>>8);
c2cExtraBuff.extra[2] = (uint8_t)(VccData);
c2cExtraBuff.extra[3] = (uint8_t)(VccData>>8);
// Pop element
CircQueuePop(c2cSendQueue, &c2cSendQueueEl);
// Get frame length.
c2cSendElementSize = (Glink_ReadSeg((uint16_t *)c2cSendQueueEl, GLINK_RX_DATALEN_OFFSET) & 0x01FF) == 0 ?
512 : (Glink_ReadSeg((uint16_t *)c2cSendQueueEl, GLINK_RX_DATALEN_OFFSET) & 0x01FF);
// C2C Framing
memcpy(c2cSendBuff + C2C_PLOAD_OFFSET, c2cSendQueueEl + GLINK_MSG_HEADER_LEN_BYTES, c2cSendElementSize);
// Update remote monitor info
memcpy((uint8_t*)(c2cSendBuff + C2C_PLOAD_OFFSET + c2cSendElementSize), &c2cExtraBuff, sizeof(C2C_EXTRA));
// Append CRC
Status = AppendCrc(c2cSendBuff + C2C_PLOAD_OFFSET + c2cSendElementSize, sizeof(C2C_EXTRA) + COMMON_CRC_LEN);
if(Status != SUCCESS){
DBG_ERROR("C2C extra data crc append error, with error code: %d.\r\n", Status);
continue;
}
// Relay glink received datat to C2C
Status = C2c_SendData(c2cInstPtr, c2cSendBuff, c2cSendElementSize + (sizeof(C2C_EXTRA) + COMMON_CRC_LEN));
if(Status != SUCCESS){
DBG_ERROR("C2c_SendData error, with error code: %d.\r\n", Status);
_nop_();
}
}
if(!isCircQueueEmpty(glinkSendQueue) && !Glink_IsSendBusy(glinkInstPtr)){
// Pop element
CircQueuePop(glinkSendQueue, &glinkSendQueueEl);
// Get frame length.
glinkSendElementSize = IO_In32((uintptr_t)(glinkSendQueueEl + C2C_DLEN_OFFSET)) - C2C_HEADER_LEN;
glinkSendQueueEl = glinkSendQueueEl + C2C_HEADER_LEN;
if(glinkSendElementSize > C2C_FRAME_LEN || glinkSendElementSize < (sizeof(C2C_EXTRA) + COMMON_CRC_LEN)){
// error occurred
DBG_ERROR("C2C data error.\r\n");
continue;
}
// Check frame validation
if(CrcCheck(glinkSendQueueEl + glinkSendElementSize - (sizeof(C2C_EXTRA) + COMMON_CRC_LEN), sizeof(C2C_EXTRA) + COMMON_CRC_LEN) == true){
// Sync Remote Monitor info
memcpy(&c2cExtraBuff, glinkSendQueueEl + glinkSendElementSize - (sizeof(C2C_EXTRA) + COMMON_CRC_LEN), sizeof(C2C_EXTRA));
// Glink framing
memcpy(glinkSendBuff + GLINK_MSG_HEADER_LEN_BYTES, glinkSendQueueEl, glinkSendElementSize - (sizeof(C2C_EXTRA) + COMMON_CRC_LEN));
// Relay C2C received data to Glink.
Glink_SendData(glinkInstPtr, glinkSendBuff, glinkSendElementSize - (sizeof(C2C_EXTRA) + COMMON_CRC_LEN), c2cExtraBuff.glinkSubAddr);
}
else{
DBG_ERROR("C2C Extra data crc check failed.\r\n");
continue;
}
}
}
// uint8_t glinkTxBuff[512];
// uint32_t cnt = 0;
// uint16_t addrId = 1;
// while(cnt < 10000){
// for(int i = 0; i<512; i++){
// glinkTxBuff[i] = i + cnt;
// }
// GlinkSendData2Addr(glinkTxBuff, 512,1);
// usleep(15);
// GlinkSendData2Addr(glinkTxBuff, 512,2);
// usleep(15);
// GlinkSendData2Addr(glinkTxBuff, 512,3);
// usleep(15);
// GlinkSendData2Addr(glinkTxBuff, 512,4);
// usleep(15);
// cnt ++;
// addrId = (addrId == 4)? 1 : addrId+1;
// usleep(4900);
// }
// uint8_t* c2cTxBuff = (uint8_t*)C2C_TXBUFF_BASSADDR;
// int cnt = 0;
// while(cnt < 10240){
// if(!C2c_IsSendBusy(c2cInstPtr)){
// for(int i = 0; i<C2C_FRAME_LEN; i++){
// c2cTxBuff[i] = i + cnt;
// }
// Status = C2c_SendData(c2cInstPtr, c2cTxBuff, C2C_FRAME_LEN);
// if(Status != SUCCESS){
// DBG_ERROR("C2c_SendData error, with error code: %d.\r\n", Status);
// _nop_();
// }
//
// cnt ++;
// }
// }
// while(true){
// }
//
// return 0;
} // main
@@ -0,0 +1,26 @@
/*
* mmu_ctrl.h
*
* Created on: 2023Äê1ÔÂ7ÈÕ
* Author: Gatsby_Van
*/
#ifndef SRC_MMU_CTRL_H_
#define SRC_MMU_CTRL_H_
#include "xil_mmu.h"
#define MMU_L1_PAGE 0x00000001
#define MMU_L1_SECT 0x00000002
#define MMU_L1_SUPERSECT 0x00040002
#define MMU_L1_DOMAIN(x) ((x & 0x0F) << 4)
#define MMU_L1_SHAREABLE 0x00010000
#define MMU_L1_NON_SHAREABLE 0x00000000
#define MMU_L1_GLOBAL 0x00000000
#define MMU_L1_NON_GLOBAL 0x00020000
#define MMU_L1_EXEC 0x00000000
#define MMU_L1_NON_EXEC 0x00000010
#define MMU_L1_EXEC 0x00000000
#define MMU_L1_NON_EXEC 0x00000010
#define MMU_L1_NONACS 0x00000000
#define MMU_L1_FULLACS 0x00000C00
#endif /* SRC_MMU_CTRL_H_ */
@@ -0,0 +1,312 @@
/*****************************************************************************/
/**
* Description: A simple sorted queue.
*
* Author: Fan Hao
* Date: 2023-02-23 12:55
* LastEditors: Fan Hao
* LastEditTime: 2023-02-23 13:06
* Revisions: Rev 0.0
* History:
* [2023-02-23]: Initial Version.
*
* Copyright(c) 2023 Beijing Institute of Technology.
* Lab of Communication and Networking
* NOTE: Forked form https://github.com/tobithiel/Queue.git
* 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 THE
* AUTHORS OR COPYRIGHT HOLDERS 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.
******************************************************************************/
#include "queue.h"
#include <stdbool.h>
static int32_t QueuePushInternal(QUEUE *q , void *el, size_t size);
static int32_t QueuePopInternal(QUEUE *q, void **e, size_t *size, int (*cmp)(void *, void *), void *cmpel);
static int32_t QueueFlushInternal(QUEUE *q, uint8_t fd, void (*ff)(void *));
static int32_t QueueDestroyInternal(QUEUE *q, uint8_t fd, void (*ff)(void *));
static int32_t QueuePushInternal(QUEUE *q , void *el, size_t size) {
if(q == NULL) // queue not valid
return Q_ERR_INVALID;
// max_elements already reached?
// if condition _needs_ to be in sync with while loop below!
if(q->numEls == (QUEUE_MAX - 1) || isQueueFull(q)) {
return Q_ERR_FULL;
}
QUEUE_ELEMENT *newEl = (QUEUE_ELEMENT *)malloc(sizeof(QUEUE_ELEMENT));
if(newEl == NULL) { // could not allocate memory for new elements
return Q_ERR_MEM;
}
newEl->data = el;
newEl->size = size;
newEl->next = NULL;
if(q->sort == 0 || q->firstEl == NULL) {
// insert at the end when we don't want to sort or the queue is empty
if(q->lastEl == NULL)
q->firstEl = newEl;
else
q->lastEl->next = newEl;
q->lastEl = newEl;
}
else {
// search appropriate place to sort element in
QUEUE_ELEMENT *s = q->firstEl; // s != NULL, because of if condition above
QUEUE_ELEMENT *t = NULL;
int ascFirstEl = q->ascOrder != 0 && q->cmpEl(s->data, el) >= 0;
int descFirstEl = q->ascOrder == 0 && q->cmpEl(s->data, el) <= 0;
if(ascFirstEl == 0 && descFirstEl == 0) {
// element will be inserted between s and t
for(s = q->firstEl, t = s->next; s != NULL && t != NULL; s = t, t = t->next) {
if(q->ascOrder != 0 && q->cmpEl(s->data, el) <= 0 && q->cmpEl(el, t->data) <= 0) {
// asc: s <= e <= t
break;
}
else if(q->ascOrder == 0 && q->cmpEl(s->data, el) >= 0 && q->cmpEl(el, t->data) >= 0) {
// desc: s >= e >= t
break;
}
}
// actually insert
s->next = newEl;
newEl->next = t;
if(t == NULL)
q->lastEl = newEl;
}
else if(ascFirstEl != 0 || descFirstEl != 0) {
// add at front
newEl->next = q->firstEl;
q->firstEl = newEl;
}
}
q->numEls++;
return Q_OK;
}
static int32_t QueuePopInternal(QUEUE *q, void **e, size_t *size, int (*cmp)(void *, void *), void *cmpel) {
if(q == NULL) { // queue not valid
*e = NULL;
return Q_ERR_INVALID;
}
// are elements in the queue?
if(isQueueEmpty(q)) {
return Q_ERR_EMPTY;
}
// get first element (which fulfills the requirements)
QUEUE_ELEMENT *elPrev = NULL, *el = q->firstEl;
while(cmp != NULL && el != NULL && 0 != cmp(el, cmpel)) {
elPrev = el;
el = el->next;
}
if(el != NULL && elPrev == NULL) {
// first element is removed
q->firstEl = el->next;
if(q->firstEl == NULL)
q->lastEl = NULL;
q->numEls--;
*e = el->data;
*size = el->size;
free(el);
}
else if(el != NULL && elPrev != NULL) {
// element in the middle is removed
elPrev->next = el->next;
q->numEls--;
*e = el->data;
*size = el->size;
free(el);
}
else {
// element is invalid
*e = NULL;
*size = 0;
return Q_ERR_INVALID_ELEMENT;
}
return Q_OK;
}
static int32_t QueueFlushInternal(QUEUE *q, uint8_t fd, void (*ff)(void *)) {
if(q == NULL)
return Q_ERR_INVALID;
QUEUE_ELEMENT *qe = q->firstEl;
QUEUE_ELEMENT *nqe = NULL;
while(qe != NULL) {
nqe = qe->next;
if(fd != 0 && ff == NULL) {
free(qe->data);
} else if(fd != 0 && ff != NULL) {
ff(qe->data);
}
free(qe);
qe = nqe;
}
q->firstEl = NULL;
q->lastEl = NULL;
q->numEls = 0;
return Q_OK;
}
static int32_t QueueDestroyInternal(QUEUE *q, uint8_t fd, void (*ff)(void *)) {
// this method will not immediately return on error,
// it will try to release all the memory that was allocated.
int error = Q_OK;
// release internal element memory
error = QueueFlushInternal(q, fd, ff);
// destroy queue
free(q);
return error;
}
QUEUE *QueueCreate(void) {
QUEUE *q = (QUEUE *)malloc(sizeof(QUEUE));
if(q != NULL) {
q->firstEl = NULL;
q->lastEl = NULL;
q->numEls = 0;
q->maxEls = -1;
q->sort = false;
q->ascOrder = true;
q->cmpEl = NULL;
}
return q;
}
QUEUE *QueueCreateLimited(uintX_t max_elements) {
QUEUE *q = QueueCreate();
if(q != NULL)
q->maxEls = max_elements;
return q;
}
QUEUE *QueueCreateSorted(bool asc, int (*cmp)(void *, void *)) {
if(cmp == NULL)
return NULL;
QUEUE *q = QueueCreate();
if(q != NULL) {
q->sort = 1;
q->ascOrder = asc;
q->cmpEl = cmp;
}
return q;
}
QUEUE *QueueCreateLimitedSorted(uintX_t maxElements, bool asc, int (*cmp)(void *, void *)) {
if(cmp == NULL)
return NULL;
QUEUE *q = QueueCreate();
if(q != NULL) {
q->maxEls = maxElements;
q->sort = 1;
q->ascOrder = asc;
q->cmpEl = cmp;
}
return q;
}
int32_t QueueDestroy(QUEUE *q) {
if(q == NULL)
return Q_ERR_INVALID;
return QueueDestroyInternal(q, 0, NULL);
}
int32_t QueueDestroyComplete(QUEUE *q, void (*ff)(void *)) {
if(q == NULL)
return Q_ERR_INVALID;
return QueueDestroyInternal(q, 1, ff);
}
int32_t QueueFlush(QUEUE *q) {
if(q == NULL)
return Q_ERR_INVALID;
int32_t r = QueueFlushInternal(q, 0, NULL);
return r;
}
int32_t QueueFlushComplete(QUEUE *q, void (*ff)(void *)) {
if(q == NULL)
return Q_ERR_INVALID;
int32_t r = QueueFlushInternal(q, 1, ff);
return r;
}
uintX_t QueueElements(QUEUE *q) {
uintX_t ret = QUEUE_MAX;
if(q == NULL)
return ret;
ret = q->numEls;
return ret;
}
bool isQueueFull(QUEUE *q){
if(q == NULL)
return Q_ERR_INVALID;
bool ret;
if(q->maxEls != -1 && q->numEls == q->maxEls)
ret = true;
else
ret = false;
return ret;
}
bool isQueueEmpty(QUEUE *q) {
if(q == NULL)
return Q_ERR_INVALID;
bool ret;
if(q->firstEl == NULL || q->lastEl == NULL || q->numEls == 0)
ret = true;
else
ret = false;
return ret;
}
int32_t QueuePush(QUEUE *q, void *el, size_t size) {
if(q == NULL)
return Q_ERR_INVALID;
int32_t r = QueuePushInternal(q, el, size);
return r;
}
int32_t QueuePop(QUEUE *q, void **e, size_t *size) {
*e = NULL;
if(q == NULL)
return Q_ERR_INVALID;
int32_t r = QueuePopInternal(q, e, size, NULL, NULL);
return r;
}
int32_t QueuePopFiltered(QUEUE *q, void **e, size_t *size, int (*cmp)(void *, void *), void *cmpel) {
*e = NULL;
if(q == NULL)
return Q_ERR_INVALID;
int32_t r = QueuePopInternal(q, e, size, cmp, cmpel);
return r;
}
int32_t QueueFlushPush(QUEUE *q, void (*ff)(void *), void *e, size_t size) {
if(q == NULL)
return Q_ERR_INVALID;
int32_t r = QueueFlushInternal(q, 0, NULL);
r = QueuePushInternal(q, e, size);
return r;
}
int32_t QueueFlushCompletePush(QUEUE *q, void (*ff)(void *), void *e, size_t size) {
if(q == NULL)
return Q_ERR_INVALID;
int32_t r = QueueFlushInternal(q, 1, ff);
r = QueuePushInternal(q, e, size);
return r;
}
@@ -0,0 +1,228 @@
/*****************************************************************************/
/**
* Description: A brief description of this file
*
* Author: Fan Hao
* Date: 2023-02-23 12:55
* LastEditors: Fan Hao
* LastEditTime: 2023-02-23 13:09
* Revisions: Rev 0.0
* History:
* [2023-02-23]: Initial Version.
*
* Copyright(c) 2023 Beijing Institute of Technology.
* Lab of Communication and Networking
* NOTE: Forked form https://github.com/tobithiel/Queue.git
* 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 THE
* AUTHORS OR COPYRIGHT HOLDERS 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.
******************************************************************************/
#ifndef __QUEUE_H__
#define __QUEUE_H__
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h> /* (u)intX_t */
/**
* type which is used for counting the number of elements.
* needed for limited queues
*/
#ifndef QUEUE_MAX
typedef uint16_t uintX_t;
#define QUEUE_MAX UINT16_MAX
#endif
/**
* simple macros to reduce necessary casting to void *
* or function pointers
*/
#define DEFINE_Q_DESTROY(fname, type) int32_t fname(QUEUE *q, void (*ff)(type *)) { return QueueDestroyComplete(q, (void (*)(void *))ff); }
#define DEFINE_Q_FLUSH(fname, type) int32_t fname(QUEUE *q, void (*ff)(type *)) { return QueueFlushComplete(q, (void (*)(void *))ff); }
#define DEFINE_Q_POP(fname, type, size) int32_t fname(QUEUE *q, type **e, size_t *size) { return QueuePop(q, (void **)e, size_t *size); }
#define DEFINE_Q_PUHS(fname, type, size) int32_t fname(QUEUE *q, type *e, size_t size) { return QueuePush(q, (void *)e, size); }
#define DEFINE_Q_FLUSH_PUSH(fname, type, size) int32_t fname(QUEUE *q, void (*ff)(type *), type *e, size_t size) { return QueueFlushCompletePush(q, (void (*)(void *))ff, (void *)e, size); }
/**
* returned error codes, everything except Q_OK should be < 0
*/
typedef enum {
Q_OK = 0,
Q_ERR_INVALID = -1,
Q_ERR_MEM = -2,
Q_ERR_FULL = -3,
Q_ERR_EMPTY = -4,
Q_ERR_INVALID_ELEMENT = -5,
} QUEUE_ERROR;
typedef struct QUEUE_ELEMENT_S {
void *data;
size_t size;
struct QUEUE_ELEMENT_S *next;
} QUEUE_ELEMENT;
typedef struct QUEUE_S {
QUEUE_ELEMENT *firstEl, *lastEl;
// (max.) number of elements
uintX_t numEls;
uintX_t maxEls;
// sorted queue
bool sort;
bool ascOrder;
int (*cmpEl)(void *, void *);
} QUEUE;
/**
* initializes and allocates a queue with unlimited elements
*
* returns NULL on error, or a pointer to the queue
*/
QUEUE *QueueCreate(void);
/**
* initializes and allocates a queue
*
* max_elements - maximum number of elements which are allowed in the queue, == 0 for "unlimited"
*
* returns NULL on error, or a pointer to the queue
*/
QUEUE *QueueCreateLimited(uintX_t max_elements);
/**
* just like QueueCreate()
* additionally you can specify a comparator function so that your elements are ordered in the queue
* elements will only be ordered if you create the queue with this method
* the compare function should return 0 if both elements are the same, < 0 if the first is smaller
* and > 0 if the second is smaller
*
* asc - sort in ascending order if not 0
* cmp - comparator function, NULL will create an error
*
* returns NULL on error, or a pointer to the queue
*/
QUEUE *QueueCreateSorted(bool asc, int (*cmp)(void *, void *));
/**
* see QueueCreateLimited() and QueueCreateSorted()
*/
QUEUE *QueueCreateLimitedSorted(uintX_t maxElements, bool asc, int (*cmp)(void *, void *));
/**
* releases the memory internally allocated and destroys the queue
* you have to release the memory the elements in the queue use
*
* q - the queue to be destroyed
*/
int32_t QueueDestroy(QUEUE *q);
/**
* in addition to QueueDestroy(), this function will also free the memory of your elements
*
* q - the queue to be destroyed
* ff - the free function to be used for the elements (free() if NULL)
*/
int32_t QueueDestroyComplete(QUEUE *q, void (*ff)(void *));
/**
* deletes all the elements from the queue, but does not release their memory
*
* q - the queue
*/
int32_t QueueFlush(QUEUE *q);
/**
* just like QueueFlush, but releases the memory of the elements
*
* q - the queue
* ff - the free function to be used for the elements (free() if NULL)
*/
int32_t QueueFlushComplete(QUEUE *q, void (*ff)(void *));
/**
* just like QueueFlush, followed by an QueuePush atomically
*
* q - the queue
* ff - the free function to be used for the elements (free() if NULL)
* e - the element
*/
int32_t QueueFlushPush(QUEUE *q, void (*ff)(void *), void *e, size_t size);
/**
* just like QueueFlushComplete, followed by an QueuePush atomically
*
* q - the queue
* ff - the free function to be used for the elements (free() if NULL)
* e - the element
*/
int32_t QueueFlushCompletePush(QUEUE *q, void (*ff)(void *), void *e, size_t size);
/**
* returns the number of elements in the queue
*
* q - the queue
*
* returns number of elements or UINTX_MAX if an error occured
*/
uintX_t QueueElements(QUEUE *q);
/**
* returns wether the queue is full
* returns empty if there was an error
*
* q - the queue
*
* returns zero if queue is NOT empty, < 0 => error
*/
bool isQueueFull(QUEUE *q);
/**
* returns wether the queue is empty
* returns empty if there was an error
*
* q - the queue
*
* returns zero if queue is NOT empty, < 0 => error
*/
bool isQueueEmpty(QUEUE *q);
/**
* put a new element at the end of the queue
* will produce an error if you called queue_no_new_data()
*
* q - the queue
* e - the element
*
* returns 0 if everything worked, > 0 if max_elements is reached, < 0 if error occured
*/
int32_t QueuePush(QUEUE *q, void *e, size_t size);
/**
* get the first element of the queue
*
* q - the queue
* e - pointer which will be set to the element
*
* returns 0 if everything worked, > 0 if no elements in queue, < 0 if error occured
*/
int32_t QueuePop(QUEUE *q, void **e, size_t *size);
/**
* gets the first element for which the given compare function returns 0 (equal)
* does NOT wait if no elements in the queue
* the compare function should return 0 if both elements are the same, < 0 if the first is smaller
* and > 0 if the second is smaller
*
* q - the queue
* e - pointer which will be set to the element
* cmp - comparator function, NULL will create an error
* cmpel - element with which should be compared
*
* returns 0 if everything worked, < 0 => error, Q_ERR_NUM_ELEMENTS(<0) if no element fulfills the requirement
*/
int32_t QueuePopFiltered(QUEUE *q, void **e, size_t *size, int (*cmp)(void *, void *), void *cmpel);
#endif /* __QUEUE_H__ */
@@ -0,0 +1,417 @@
/*****************************************************************************/
/**
* Description: CRC implementation file
*
* Author: Hao Fan
* Date: 2021-11-16 00:50
* LastEditors: Hao Fan
* LastEditTime: 2022-07-17 20:53
* Revisions: Rev 0.0
* History:
* [2022-07-17]: Add CRC16_0x8005 CRC8_0x31.
* [2022-01-06]: Initial verion (Basic CRC-16).
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
*
******************************************************************************/
#include "util.h"
#include "../error.h"
#ifdef __CRC_LSB
// CRC-16-CCITT G(X)=X16+X12+X5+1
// Reversed
static const uint16_t crc16_1021_lsb_lut[256] = {
0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF,
0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7,
0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E,
0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876,
0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD,
0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5,
0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C,
0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974,
0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB,
0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3,
0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A,
0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72,
0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9,
0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1,
0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738,
0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70,
0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7,
0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF,
0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036,
0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E,
0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5,
0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD,
0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134,
0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C,
0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3,
0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB,
0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232,
0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A,
0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1,
0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9,
0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330,
0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78
};
// CRC-16-MAXIM G(X)=X16+X15+X2+1
const uint16_t crc16_8005_lsb_lut[256] = {
0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
};
// CRC-8-MAXIM G(X)=X8+X5+X4+1
const uint8_t crc8_31_lsb_lut[256] = {
0x00, 0x5E, 0xBC, 0xE2, 0x61, 0x3F, 0xDD, 0x83,
0xC2, 0x9C, 0x7E, 0x20, 0xA3, 0xFD, 0x1F, 0x41,
0x9D, 0xC3, 0x21, 0x7F, 0xFC, 0xA2, 0x40, 0x1E,
0x5F, 0x01, 0xE3, 0xBD, 0x3E, 0x60, 0x82, 0xDC,
0x23, 0x7D, 0x9F, 0xC1, 0x42, 0x1C, 0xFE, 0xA0,
0xE1, 0xBF, 0x5D, 0x03, 0x80, 0xDE, 0x3C, 0x62,
0xBE, 0xE0, 0x02, 0x5C, 0xDF, 0x81, 0x63, 0x3D,
0x7C, 0x22, 0xC0, 0x9E, 0x1D, 0x43, 0xA1, 0xFF,
0x46, 0x18, 0xFA, 0xA4, 0x27, 0x79, 0x9B, 0xC5,
0x84, 0xDA, 0x38, 0x66, 0xE5, 0xBB, 0x59, 0x07,
0xDB, 0x85, 0x67, 0x39, 0xBA, 0xE4, 0x06, 0x58,
0x19, 0x47, 0xA5, 0xFB, 0x78, 0x26, 0xC4, 0x9A,
0x65, 0x3B, 0xD9, 0x87, 0x04, 0x5A, 0xB8, 0xE6,
0xA7, 0xF9, 0x1B, 0x45, 0xC6, 0x98, 0x7A, 0x24,
0xF8, 0xA6, 0x44, 0x1A, 0x99, 0xC7, 0x25, 0x7B,
0x3A, 0x64, 0x86, 0xD8, 0x5B, 0x05, 0xE7, 0xB9,
0x8C, 0xD2, 0x30, 0x6E, 0xED, 0xB3, 0x51, 0x0F,
0x4E, 0x10, 0xF2, 0xAC, 0x2F, 0x71, 0x93, 0xCD,
0x11, 0x4F, 0xAD, 0xF3, 0x70, 0x2E, 0xCC, 0x92,
0xD3, 0x8D, 0x6F, 0x31, 0xB2, 0xEC, 0x0E, 0x50,
0xAF, 0xF1, 0x13, 0x4D, 0xCE, 0x90, 0x72, 0x2C,
0x6D, 0x33, 0xD1, 0x8F, 0x0C, 0x52, 0xB0, 0xEE,
0x32, 0x6C, 0x8E, 0xD0, 0x53, 0x0D, 0xEF, 0xB1,
0xF0, 0xAE, 0x4C, 0x12, 0x91, 0xCF, 0x2D, 0x73,
0xCA, 0x94, 0x76, 0x28, 0xAB, 0xF5, 0x17, 0x49,
0x08, 0x56, 0xB4, 0xEA, 0x69, 0x37, 0xD5, 0x8B,
0x57, 0x09, 0xEB, 0xB5, 0x36, 0x68, 0x8A, 0xD4,
0x95, 0xCB, 0x29, 0x77, 0xF4, 0xAA, 0x48, 0x16,
0xE9, 0xB7, 0x55, 0x0B, 0x88, 0xD6, 0x34, 0x6A,
0x2B, 0x75, 0x97, 0xC9, 0x4A, 0x14, 0xF6, 0xA8,
0x74, 0x2A, 0xC8, 0x96, 0x15, 0x4B, 0xA9, 0xF7,
0xB6, 0xE8, 0x0A, 0x54, 0xD7, 0x89, 0x6B, 0x35
};
#else
// CRC-16-CCITT G(X)=X16+X12+X5+1
static const uint16_t crc16_1021_msb_lut[256] = {
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
};
// CRC-16-MAXIM G(X)=X16+X15+X2+1
const uint16_t crc16_8005_msb_lut[256] = {
0x0000, 0x8005, 0x800F, 0x000A, 0x801B, 0x001E, 0x0014, 0x8011,
0x8033, 0x0036, 0x003C, 0x8039, 0x0028, 0x802D, 0x8027, 0x0022,
0x8063, 0x0066, 0x006C, 0x8069, 0x0078, 0x807D, 0x8077, 0x0072,
0x0050, 0x8055, 0x805F, 0x005A, 0x804B, 0x004E, 0x0044, 0x8041,
0x80C3, 0x00C6, 0x00CC, 0x80C9, 0x00D8, 0x80DD, 0x80D7, 0x00D2,
0x00F0, 0x80F5, 0x80FF, 0x00FA, 0x80EB, 0x00EE, 0x00E4, 0x80E1,
0x00A0, 0x80A5, 0x80AF, 0x00AA, 0x80BB, 0x00BE, 0x00B4, 0x80B1,
0x8093, 0x0096, 0x009C, 0x8099, 0x0088, 0x808D, 0x8087, 0x0082,
0x8183, 0x0186, 0x018C, 0x8189, 0x0198, 0x819D, 0x8197, 0x0192,
0x01B0, 0x81B5, 0x81BF, 0x01BA, 0x81AB, 0x01AE, 0x01A4, 0x81A1,
0x01E0, 0x81E5, 0x81EF, 0x01EA, 0x81FB, 0x01FE, 0x01F4, 0x81F1,
0x81D3, 0x01D6, 0x01DC, 0x81D9, 0x01C8, 0x81CD, 0x81C7, 0x01C2,
0x0140, 0x8145, 0x814F, 0x014A, 0x815B, 0x015E, 0x0154, 0x8151,
0x8173, 0x0176, 0x017C, 0x8179, 0x0168, 0x816D, 0x8167, 0x0162,
0x8123, 0x0126, 0x012C, 0x8129, 0x0138, 0x813D, 0x8137, 0x0132,
0x0110, 0x8115, 0x811F, 0x011A, 0x810B, 0x010E, 0x0104, 0x8101,
0x8303, 0x0306, 0x030C, 0x8309, 0x0318, 0x831D, 0x8317, 0x0312,
0x0330, 0x8335, 0x833F, 0x033A, 0x832B, 0x032E, 0x0324, 0x8321,
0x0360, 0x8365, 0x836F, 0x036A, 0x837B, 0x037E, 0x0374, 0x8371,
0x8353, 0x0356, 0x035C, 0x8359, 0x0348, 0x834D, 0x8347, 0x0342,
0x03C0, 0x83C5, 0x83CF, 0x03CA, 0x83DB, 0x03DE, 0x03D4, 0x83D1,
0x83F3, 0x03F6, 0x03FC, 0x83F9, 0x03E8, 0x83ED, 0x83E7, 0x03E2,
0x83A3, 0x03A6, 0x03AC, 0x83A9, 0x03B8, 0x83BD, 0x83B7, 0x03B2,
0x0390, 0x8395, 0x839F, 0x039A, 0x838B, 0x038E, 0x0384, 0x8381,
0x0280, 0x8285, 0x828F, 0x028A, 0x829B, 0x029E, 0x0294, 0x8291,
0x82B3, 0x02B6, 0x02BC, 0x82B9, 0x02A8, 0x82AD, 0x82A7, 0x02A2,
0x82E3, 0x02E6, 0x02EC, 0x82E9, 0x02F8, 0x82FD, 0x82F7, 0x02F2,
0x02D0, 0x82D5, 0x82DF, 0x02DA, 0x82CB, 0x02CE, 0x02C4, 0x82C1,
0x8243, 0x0246, 0x024C, 0x8249, 0x0258, 0x825D, 0x8257, 0x0252,
0x0270, 0x8275, 0x827F, 0x027A, 0x826B, 0x026E, 0x0264, 0x8261,
0x0220, 0x8225, 0x822F, 0x022A, 0x823B, 0x023E, 0x0234, 0x8231,
0x8213, 0x0216, 0x021C, 0x8219, 0x0208, 0x820D, 0x8207, 0x0202
};
// CRC-8-MAXIM G(X)=X8+X5+X4+1
const uint8_t crc8_31_msb_lut[256] = {
0x00, 0x31, 0x62, 0x53, 0xC4, 0xF5, 0xA6, 0x97,
0xB9, 0x88, 0xDB, 0xEA, 0x7D, 0x4C, 0x1F, 0x2E,
0x43, 0x72, 0x21, 0x10, 0x87, 0xB6, 0xE5, 0xD4,
0xFA, 0xCB, 0x98, 0xA9, 0x3E, 0x0F, 0x5C, 0x6D,
0x86, 0xB7, 0xE4, 0xD5, 0x42, 0x73, 0x20, 0x11,
0x3F, 0x0E, 0x5D, 0x6C, 0xFB, 0xCA, 0x99, 0xA8,
0xC5, 0xF4, 0xA7, 0x96, 0x01, 0x30, 0x63, 0x52,
0x7C, 0x4D, 0x1E, 0x2F, 0xB8, 0x89, 0xDA, 0xEB,
0x3D, 0x0C, 0x5F, 0x6E, 0xF9, 0xC8, 0x9B, 0xAA,
0x84, 0xB5, 0xE6, 0xD7, 0x40, 0x71, 0x22, 0x13,
0x7E, 0x4F, 0x1C, 0x2D, 0xBA, 0x8B, 0xD8, 0xE9,
0xC7, 0xF6, 0xA5, 0x94, 0x03, 0x32, 0x61, 0x50,
0xBB, 0x8A, 0xD9, 0xE8, 0x7F, 0x4E, 0x1D, 0x2C,
0x02, 0x33, 0x60, 0x51, 0xC6, 0xF7, 0xA4, 0x95,
0xF8, 0xC9, 0x9A, 0xAB, 0x3C, 0x0D, 0x5E, 0x6F,
0x41, 0x70, 0x23, 0x12, 0x85, 0xB4, 0xE7, 0xD6,
0x7A, 0x4B, 0x18, 0x29, 0xBE, 0x8F, 0xDC, 0xED,
0xC3, 0xF2, 0xA1, 0x90, 0x07, 0x36, 0x65, 0x54,
0x39, 0x08, 0x5B, 0x6A, 0xFD, 0xCC, 0x9F, 0xAE,
0x80, 0xB1, 0xE2, 0xD3, 0x44, 0x75, 0x26, 0x17,
0xFC, 0xCD, 0x9E, 0xAF, 0x38, 0x09, 0x5A, 0x6B,
0x45, 0x74, 0x27, 0x16, 0x81, 0xB0, 0xE3, 0xD2,
0xBF, 0x8E, 0xDD, 0xEC, 0x7B, 0x4A, 0x19, 0x28,
0x06, 0x37, 0x64, 0x55, 0xC2, 0xF3, 0xA0, 0x91,
0x47, 0x76, 0x25, 0x14, 0x83, 0xB2, 0xE1, 0xD0,
0xFE, 0xCF, 0x9C, 0xAD, 0x3A, 0x0B, 0x58, 0x69,
0x04, 0x35, 0x66, 0x57, 0xC0, 0xF1, 0xA2, 0x93,
0xBD, 0x8C, 0xDF, 0xEE, 0x79, 0x48, 0x1B, 0x2A,
0xC1, 0xF0, 0xA3, 0x92, 0x05, 0x34, 0x67, 0x56,
0x78, 0x49, 0x1A, 0x2B, 0xBC, 0x8D, 0xDE, 0xEF,
0x82, 0xB3, 0xE0, 0xD1, 0x46, 0x77, 0x24, 0x15,
0x3B, 0x0A, 0x59, 0x68, 0xFF, 0xCE, 0x9D, 0xAC
};
#endif
/* CRC lookup table algorithm
#define CRC_BIT_NUM 8u/16u/32u/64u
#define BITS_IN_BYTE 8u
uint8_t dataBuff[ARRAY_SIZE] = { 0x32, 0x33, …};
uint8_t/uint16_t/uint32_t crc_val = 0x0;
// LSB
for(int i = 0; i < sizeof(dataBuff); i++)
{
crc_val = (crc_val >> BITS_IN_BYTE) ^ crc_lsb_lut[(uint8)(crc_val^dataBuff[i])];
}
// MSB
for(int i = 0; i < sizeof(dataBuff); i++)
{
crc_val = (crc_val << BITS_IN_BYTE) ^ crc_msb_lut[(uint8)((crc_val>>8)^dataBuff[i])];
}
*/
/*****************************************************************************/
/**
* @brief CRC8 generator
*
* @param buffPtr data buffer pointer.
* @param dataLen data length
* @param poly polynomials of crc
* @param crcVal a pointer to store generated crc value
*
* @return SUCCESS
* FAILURE
*
******************************************************************************/
int crc8_gen(uint8_t* buffPtr, uint32_t dataLen, uint16_t poly, uint8_t* crcVal) {
uint8_t crc = CRC8_INIT;
const uint8_t* crc_lut = NULL;
switch(poly){
#ifdef __CRC_LSB
case 0x31:
crc_lut = crc8_31_lsb_lut;
break;
default:
return FAILURE;
#else
case 0x31:
crc_lut = crc8_31_msb_lut;
break;
default:
return FAILURE;
#endif
}
for(int i = 0; i < dataLen; i++){
crc = crc_lut[(uint8_t)(crc^buffPtr[i])];
}
*crcVal = crc;
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief CRC16 generator
*
* @param buffPtr data buffer pointer.
* @param dataLen data length
* @param poly polynomials of crc
* @param crcVal a pointer to store generated crc value
*
* @return SUCCESS
* FAILURE
*
******************************************************************************/
int crc16_gen(uint8_t* buffPtr, uint32_t dataLen, uint16_t poly, uint16_t* crcVal) {
uint16_t crc = CRC16_INIT;
const uint16_t* crc_lut = NULL;
switch(poly){
#ifdef __CRC_LSB
case 0x8005:
crc_lut = crc16_8005_lsb_lut;
break;
case 0x1021:
crc_lut = crc16_1021_lsb_lut;
break;
default:
return FAILURE;
#else
case 0x8005:
crc_lut = crc16_8005_msb_lut;
break;
case 0x1021:
crc_lut = crc16_1021_msb_lut;
break;
default:
return FAILURE;
#endif
}
for(int i = 0; i < dataLen; i++){
#ifdef __CRC_LSB
crc = (crc>>8) ^ crc_lut[(uint8_t)(crc^buffPtr[i])];
#else
crc = (crc<<8) ^ crc_lut[(uint8_t)((crc >> 8)^buffPtr[i])];
#endif
}
*crcVal = crc;
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief CRC8 compare cheker
*
* @param buffPtr data buffer pointer.
* @param dataLen data length
* @param crcOffset byte offset of crc stored position.
* @param poly polynomials of crc
*
* @return true
* false
*
******************************************************************************/
bool crc8_check(uint8_t* buffPtr, uint32_t dataLen, uint32_t crcOffset, uint16_t poly) {
int Status = SUCCESS;
uint8_t crc_comp;
uint8_t crc;
if (dataLen == 0) {
return false;
}
crc_comp = (uint8_t)(*(buffPtr + crcOffset));
Status = crc8_gen(buffPtr, dataLen, poly, &crc);
if(Status == SUCCESS){
if (crc == crc_comp) {
return true;
}
else {
return false;
}
}
else{
return false;
}
}
/*****************************************************************************/
/**
* @brief CRC16 compare cheker
*
* @param buffPtr data buffer pointer.
* @param dataLen data length
* @param crcOffset byte offset of crc stored position.
* @param poly polynomials of crc
*
* @return true
* fasle
*
******************************************************************************/
bool crc16_check(uint8_t* buffPtr, uint32_t dataLen, uint32_t crcOffset, uint16_t poly) {
int Status = SUCCESS;
uint16_t crc_comp;
uint16_t crc;
if (dataLen == 0) {
return false;
}
crc_comp = (uint16_t)(*(buffPtr + crcOffset));
crc_comp |= (uint16_t)((*(buffPtr + crcOffset + 1)) << 8);
Status = crc16_gen(buffPtr, dataLen, poly, &crc);
if(Status == SUCCESS){
if (crc == crc_comp) {
return true;
}
else {
return false;
}
}
else{
return false;
}
}
@@ -0,0 +1,148 @@
/*****************************************************************************/
/**
* Description: CRC utility functions.
*
* Author: Hao Fan
* Date: 2021-11-16 00:50
* LastEditors: Hao Fan
* LastEditTime: 2022-03-28 20:53
* Revisions: Rev 0.0
* History:
* [2022-01-06]: Initial verion (Basic CRC-16).
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
*
******************************************************************************/
#include "util.h"
#ifdef __CRC_LSB
// CRC-16-CCITT G(X)=X16+X12+X5+1
// Reversed
static const uint16_t crc_lut[256] = {0x0000, 0x1189, 0x2312, 0x329B, 0x4624,
0x57AD, 0x6536, 0x74BF, 0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5,
0xE97E, 0xF8F7, 0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7,
0x643E, 0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876,
0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD, 0xAD4A,
0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5, 0x3183, 0x200A,
0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C, 0xBDCB, 0xAC42, 0x9ED9,
0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974, 0x4204, 0x538D, 0x6116, 0x709F,
0x0420, 0x15A9, 0x2732, 0x36BB, 0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868,
0x99E1, 0xAB7A, 0xBAF3, 0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528,
0x37B3, 0x263A, 0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB,
0xAA72, 0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9,
0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1, 0x7387,
0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738, 0xFFCF, 0xEE46,
0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70, 0x8408, 0x9581, 0xA71A,
0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7, 0x0840, 0x19C9, 0x2B52, 0x3ADB,
0x4E64, 0x5FED, 0x6D76, 0x7CFF, 0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD,
0xC324, 0xF1BF, 0xE036, 0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C,
0x7DF7, 0x6C7E, 0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C,
0xD1B5, 0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD,
0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134, 0x39C3,
0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C, 0xC60C, 0xD785,
0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3, 0x4A44, 0x5BCD, 0x6956,
0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB, 0xD68D, 0xC704, 0xF59F, 0xE416,
0x90A9, 0x8120, 0xB3BB, 0xA232, 0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1,
0x0D68, 0x3FF3, 0x2E7A, 0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3,
0x8238, 0x93B1, 0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70,
0x1FF9, 0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330,
0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78};
#else
// CRC-16-CCITT G(X)=X16+X12+X5+1
static const uint16_t crc_lut[256] = {0x0000, 0x1021, 0x2042, 0x3063, 0x4084,
0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad,
0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7,
0x62d6, 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a,
0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672,
0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719,
0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7,
0x0840, 0x1861, 0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948,
0x9969, 0xa90a, 0xb92b, 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50,
0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b,
0xab1a, 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97,
0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe,
0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca,
0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3,
0x5004, 0x4025, 0x7046, 0x6067, 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d,
0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214,
0x6277, 0x7256, 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c,
0xc50d, 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3,
0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, 0xd94c, 0xc96d,
0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806,
0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e,
0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1,
0x1ad0, 0x2ab3, 0x3a92, 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b,
0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0,
0x0cc1, 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0};
#endif
/*****************************************************************************/
/**
* @brief Generate crc using lookup table.
*
* @param buffPtr a pointer to data buffer.
* @param dataLen data length
*
* @return 16 bit integer crc value
*
******************************************************************************/
uint16_t crc_gen(uint8_t *buffPtr, uint32_t dataLen)
{
uint8_t data = 0;
uint16_t crc = CRC16_INIT;
while (dataLen != 0)
{
#ifdef __CRC_LSB
data = (uint8_t)(crc & 0x00FF);
crc >>= 8;
crc = crc ^ crc_lut[data ^ *buffPtr];
#else
data = (uint8_t)((crc >> 8) & 0x00FF);
crc <<= 8;
crc = crc ^ crc_lut[data ^ (*buffPtr)];
#endif
buffPtr++;
dataLen--;
}
return crc;
}
/*****************************************************************************/
/**
* @brief Check data validation by crc.
*
* @param buffPtr a pointer to data buffer.
* @param dataLen data length
* @param crcOffset offset of crc position in data buffer.
*
* @return true
* false
*
******************************************************************************/
bool crc_check(uint8_t *buffPtr, uint32_t dataLen, uint32_t crcOffset)
{
uint16_t crc;
uint16_t crc_comp;
if (dataLen == 0)
{
return false;
}
crc_comp = (uint16_t)(*(buffPtr + crcOffset));
crc_comp |= (uint16_t)((*(buffPtr + crcOffset + 1)) << 8);
crc = crc_gen(buffPtr, dataLen);
if (crc == crc_comp)
{
return true;
}
else
{
return false;
}
}
@@ -0,0 +1,231 @@
Generating CRC table for crc8-31-lsb
0x00, 0x5E, 0xBC, 0xE2, 0x61, 0x3F, 0xDD, 0x83,
0xC2, 0x9C, 0x7E, 0x20, 0xA3, 0xFD, 0x1F, 0x41,
0x9D, 0xC3, 0x21, 0x7F, 0xFC, 0xA2, 0x40, 0x1E,
0x5F, 0x01, 0xE3, 0xBD, 0x3E, 0x60, 0x82, 0xDC,
0x23, 0x7D, 0x9F, 0xC1, 0x42, 0x1C, 0xFE, 0xA0,
0xE1, 0xBF, 0x5D, 0x03, 0x80, 0xDE, 0x3C, 0x62,
0xBE, 0xE0, 0x02, 0x5C, 0xDF, 0x81, 0x63, 0x3D,
0x7C, 0x22, 0xC0, 0x9E, 0x1D, 0x43, 0xA1, 0xFF,
0x46, 0x18, 0xFA, 0xA4, 0x27, 0x79, 0x9B, 0xC5,
0x84, 0xDA, 0x38, 0x66, 0xE5, 0xBB, 0x59, 0x07,
0xDB, 0x85, 0x67, 0x39, 0xBA, 0xE4, 0x06, 0x58,
0x19, 0x47, 0xA5, 0xFB, 0x78, 0x26, 0xC4, 0x9A,
0x65, 0x3B, 0xD9, 0x87, 0x04, 0x5A, 0xB8, 0xE6,
0xA7, 0xF9, 0x1B, 0x45, 0xC6, 0x98, 0x7A, 0x24,
0xF8, 0xA6, 0x44, 0x1A, 0x99, 0xC7, 0x25, 0x7B,
0x3A, 0x64, 0x86, 0xD8, 0x5B, 0x05, 0xE7, 0xB9,
0x8C, 0xD2, 0x30, 0x6E, 0xED, 0xB3, 0x51, 0x0F,
0x4E, 0x10, 0xF2, 0xAC, 0x2F, 0x71, 0x93, 0xCD,
0x11, 0x4F, 0xAD, 0xF3, 0x70, 0x2E, 0xCC, 0x92,
0xD3, 0x8D, 0x6F, 0x31, 0xB2, 0xEC, 0x0E, 0x50,
0xAF, 0xF1, 0x13, 0x4D, 0xCE, 0x90, 0x72, 0x2C,
0x6D, 0x33, 0xD1, 0x8F, 0x0C, 0x52, 0xB0, 0xEE,
0x32, 0x6C, 0x8E, 0xD0, 0x53, 0x0D, 0xEF, 0xB1,
0xF0, 0xAE, 0x4C, 0x12, 0x91, 0xCF, 0x2D, 0x73,
0xCA, 0x94, 0x76, 0x28, 0xAB, 0xF5, 0x17, 0x49,
0x08, 0x56, 0xB4, 0xEA, 0x69, 0x37, 0xD5, 0x8B,
0x57, 0x09, 0xEB, 0xB5, 0x36, 0x68, 0x8A, 0xD4,
0x95, 0xCB, 0x29, 0x77, 0xF4, 0xAA, 0x48, 0x16,
0xE9, 0xB7, 0x55, 0x0B, 0x88, 0xD6, 0x34, 0x6A,
0x2B, 0x75, 0x97, 0xC9, 0x4A, 0x14, 0xF6, 0xA8,
0x74, 0x2A, 0xC8, 0x96, 0x15, 0x4B, 0xA9, 0xF7,
0xB6, 0xE8, 0x0A, 0x54, 0xD7, 0x89, 0x6B, 0x35,
Generating CRC table for crc8-31-msb
0x00, 0x31, 0x62, 0x53, 0xC4, 0xF5, 0xA6, 0x97,
0xB9, 0x88, 0xDB, 0xEA, 0x7D, 0x4C, 0x1F, 0x2E,
0x43, 0x72, 0x21, 0x10, 0x87, 0xB6, 0xE5, 0xD4,
0xFA, 0xCB, 0x98, 0xA9, 0x3E, 0x0F, 0x5C, 0x6D,
0x86, 0xB7, 0xE4, 0xD5, 0x42, 0x73, 0x20, 0x11,
0x3F, 0x0E, 0x5D, 0x6C, 0xFB, 0xCA, 0x99, 0xA8,
0xC5, 0xF4, 0xA7, 0x96, 0x01, 0x30, 0x63, 0x52,
0x7C, 0x4D, 0x1E, 0x2F, 0xB8, 0x89, 0xDA, 0xEB,
0x3D, 0x0C, 0x5F, 0x6E, 0xF9, 0xC8, 0x9B, 0xAA,
0x84, 0xB5, 0xE6, 0xD7, 0x40, 0x71, 0x22, 0x13,
0x7E, 0x4F, 0x1C, 0x2D, 0xBA, 0x8B, 0xD8, 0xE9,
0xC7, 0xF6, 0xA5, 0x94, 0x03, 0x32, 0x61, 0x50,
0xBB, 0x8A, 0xD9, 0xE8, 0x7F, 0x4E, 0x1D, 0x2C,
0x02, 0x33, 0x60, 0x51, 0xC6, 0xF7, 0xA4, 0x95,
0xF8, 0xC9, 0x9A, 0xAB, 0x3C, 0x0D, 0x5E, 0x6F,
0x41, 0x70, 0x23, 0x12, 0x85, 0xB4, 0xE7, 0xD6,
0x7A, 0x4B, 0x18, 0x29, 0xBE, 0x8F, 0xDC, 0xED,
0xC3, 0xF2, 0xA1, 0x90, 0x07, 0x36, 0x65, 0x54,
0x39, 0x08, 0x5B, 0x6A, 0xFD, 0xCC, 0x9F, 0xAE,
0x80, 0xB1, 0xE2, 0xD3, 0x44, 0x75, 0x26, 0x17,
0xFC, 0xCD, 0x9E, 0xAF, 0x38, 0x09, 0x5A, 0x6B,
0x45, 0x74, 0x27, 0x16, 0x81, 0xB0, 0xE3, 0xD2,
0xBF, 0x8E, 0xDD, 0xEC, 0x7B, 0x4A, 0x19, 0x28,
0x06, 0x37, 0x64, 0x55, 0xC2, 0xF3, 0xA0, 0x91,
0x47, 0x76, 0x25, 0x14, 0x83, 0xB2, 0xE1, 0xD0,
0xFE, 0xCF, 0x9C, 0xAD, 0x3A, 0x0B, 0x58, 0x69,
0x04, 0x35, 0x66, 0x57, 0xC0, 0xF1, 0xA2, 0x93,
0xBD, 0x8C, 0xDF, 0xEE, 0x79, 0x48, 0x1B, 0x2A,
0xC1, 0xF0, 0xA3, 0x92, 0x05, 0x34, 0x67, 0x56,
0x78, 0x49, 0x1A, 0x2B, 0xBC, 0x8D, 0xDE, 0xEF,
0x82, 0xB3, 0xE0, 0xD1, 0x46, 0x77, 0x24, 0x15,
0x3B, 0x0A, 0x59, 0x68, 0xFF, 0xCE, 0x9D, 0xAC,
Generating CRC table for crc16-8005-lsb
0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040,
Generating CRC table for crc16-8005-msb
0x0000, 0x8005, 0x800F, 0x000A, 0x801B, 0x001E, 0x0014, 0x8011,
0x8033, 0x0036, 0x003C, 0x8039, 0x0028, 0x802D, 0x8027, 0x0022,
0x8063, 0x0066, 0x006C, 0x8069, 0x0078, 0x807D, 0x8077, 0x0072,
0x0050, 0x8055, 0x805F, 0x005A, 0x804B, 0x004E, 0x0044, 0x8041,
0x80C3, 0x00C6, 0x00CC, 0x80C9, 0x00D8, 0x80DD, 0x80D7, 0x00D2,
0x00F0, 0x80F5, 0x80FF, 0x00FA, 0x80EB, 0x00EE, 0x00E4, 0x80E1,
0x00A0, 0x80A5, 0x80AF, 0x00AA, 0x80BB, 0x00BE, 0x00B4, 0x80B1,
0x8093, 0x0096, 0x009C, 0x8099, 0x0088, 0x808D, 0x8087, 0x0082,
0x8183, 0x0186, 0x018C, 0x8189, 0x0198, 0x819D, 0x8197, 0x0192,
0x01B0, 0x81B5, 0x81BF, 0x01BA, 0x81AB, 0x01AE, 0x01A4, 0x81A1,
0x01E0, 0x81E5, 0x81EF, 0x01EA, 0x81FB, 0x01FE, 0x01F4, 0x81F1,
0x81D3, 0x01D6, 0x01DC, 0x81D9, 0x01C8, 0x81CD, 0x81C7, 0x01C2,
0x0140, 0x8145, 0x814F, 0x014A, 0x815B, 0x015E, 0x0154, 0x8151,
0x8173, 0x0176, 0x017C, 0x8179, 0x0168, 0x816D, 0x8167, 0x0162,
0x8123, 0x0126, 0x012C, 0x8129, 0x0138, 0x813D, 0x8137, 0x0132,
0x0110, 0x8115, 0x811F, 0x011A, 0x810B, 0x010E, 0x0104, 0x8101,
0x8303, 0x0306, 0x030C, 0x8309, 0x0318, 0x831D, 0x8317, 0x0312,
0x0330, 0x8335, 0x833F, 0x033A, 0x832B, 0x032E, 0x0324, 0x8321,
0x0360, 0x8365, 0x836F, 0x036A, 0x837B, 0x037E, 0x0374, 0x8371,
0x8353, 0x0356, 0x035C, 0x8359, 0x0348, 0x834D, 0x8347, 0x0342,
0x03C0, 0x83C5, 0x83CF, 0x03CA, 0x83DB, 0x03DE, 0x03D4, 0x83D1,
0x83F3, 0x03F6, 0x03FC, 0x83F9, 0x03E8, 0x83ED, 0x83E7, 0x03E2,
0x83A3, 0x03A6, 0x03AC, 0x83A9, 0x03B8, 0x83BD, 0x83B7, 0x03B2,
0x0390, 0x8395, 0x839F, 0x039A, 0x838B, 0x038E, 0x0384, 0x8381,
0x0280, 0x8285, 0x828F, 0x028A, 0x829B, 0x029E, 0x0294, 0x8291,
0x82B3, 0x02B6, 0x02BC, 0x82B9, 0x02A8, 0x82AD, 0x82A7, 0x02A2,
0x82E3, 0x02E6, 0x02EC, 0x82E9, 0x02F8, 0x82FD, 0x82F7, 0x02F2,
0x02D0, 0x82D5, 0x82DF, 0x02DA, 0x82CB, 0x02CE, 0x02C4, 0x82C1,
0x8243, 0x0246, 0x024C, 0x8249, 0x0258, 0x825D, 0x8257, 0x0252,
0x0270, 0x8275, 0x827F, 0x027A, 0x826B, 0x026E, 0x0264, 0x8261,
0x0220, 0x8225, 0x822F, 0x022A, 0x823B, 0x023E, 0x0234, 0x8231,
0x8213, 0x0216, 0x021C, 0x8219, 0x0208, 0x820D, 0x8207, 0x0202,
Generating CRC table for crc16-1021-lsb
0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF,
0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7,
0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E,
0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876,
0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD,
0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5,
0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C,
0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974,
0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB,
0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3,
0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A,
0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72,
0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9,
0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1,
0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738,
0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70,
0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7,
0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF,
0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036,
0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E,
0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5,
0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD,
0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134,
0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C,
0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3,
0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB,
0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232,
0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A,
0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1,
0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9,
0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330,
0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78,
Generating CRC table for crc16-1021-msb
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0,
#define CRC_BIT_NUM 8u/16u/32u/64u
#define BITS_IN_BYTE 8u
uint8_t dataBuff[ARRAY_SIZE] = { 0x32, 0x33, ...;
uint8_t/uint16_t/uint32_t crc_val = 0x0;
// LSB
for(int i = 0; i < sizeof(dataBuff); i++)
{
crc_val = (crc_val >> BITS_IN_BYTE) ^ crc_lsb_lut[(uint8)(crc_val^dataBuff[i])];
}
// MSB
for(int i = 0; i < sizeof(dataBuff); i++)
{
crc_val = (crc_val << BITS_IN_BYTE) ^ crc_msb_lut[(uint8)((crc_val>>8)^dataBuff[i])];
}
@@ -0,0 +1,350 @@
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <string.h>
#include <stdlib.h>
#include "util.h"
#include "../error.h"
/******************************************************************************/
/************************** Functions Implementation **************************/
/******************************************************************************/
#ifdef __BITSWAP_TABLE
static uint8_t byte_flipLR[256] = {
0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
};
#endif
inline void IO_Out32(uintptr_t addr, uint32_t value){
volatile uint32_t *localAddr = (volatile uint32_t *)addr;
*localAddr = value;
}
inline uint32_t IO_In32(uintptr_t addr){
return *(volatile uint32_t*) addr;
}
uint8_t byte_bit_swap(uint8_t byte){
#ifdef __BITSWAP_TABLE
return byte_flipLR[byte];
#else
return bit_swap_constant_8(byte);
#endif
}
uint32_t word_bit_swap(uint32_t word){
#ifdef __BITSWAP_TABLE
uint32_t rv_word = (byte_flipLR[word & 0xff] << 24) |
(byte_flipLR[(word >> 8) & 0xff] << 16) |
(byte_flipLR[(word >> 16) & 0xff] << 8) |
(byte_flipLR[(word >> 24) & 0xff]);
return rv_word;
#else
word = (((word & 0xaaaaaaaa) >> 1) | ((word & 0x55555555) << 1));
word = (((word & 0xcccccccc) >> 2) | ((word & 0x33333333) << 2));
word = (((word & 0xf0f0f0f0) >> 4) | ((word & 0x0f0f0f0f) << 4));
word = (((word & 0xff00ff00) >> 8) | ((word & 0x00ff00ff) << 8));
return((word >> 16) | (word << 16));
#endif
}
uint32_t count_ones(uint32_t word){
#ifdef __GNUC__
return __builtin_popcount(word);
#else
uint32_t one_count = 0;
while (word) {
if (word & 0x00000001)
one_count ++;
word >>= 1;
}
return one_count;
#endif
}
double fix2double(int32_t val, uint8_t frac_bits){
return (((double)val)/(BIT(frac_bits)));
}
/**
* Find first set bit in word.
*/
uint32_t find_first_set_bit(uint32_t word)
{
#ifdef __GNUC__
if(word != 0){
return __builtin_ctz(word);
}
else{
return 32;
}
#else
uint32_t first_set_bit = 0;
while (word) {
if (word & 0x1)
return first_set_bit;
word >>= 1;
first_set_bit ++;
}
return 32;
#endif
}
/**
* Find last set bit in word.
*/
uint32_t find_last_set_bit(uint32_t word)
{
#ifdef __GNUC__
if(word != 0){
return (31-__builtin_clz(word));
}
else{
return 32;
}
#else
uint32_t bit = 0;
uint32_t last_set_bit = 32;
while (word) {
if (word & 0x1)
last_set_bit = bit;
word >>= 1;
bit ++;
}
return last_set_bit;
#endif
}
/**
* Locate the closest element in an array.
*/
uint32_t find_closest(int32_t val,
const int32_t *array,
uint32_t size)
{
int32_t diff = abs(array[0] - val);
uint32_t ret = 0;
uint32_t i;
for (i = 1; i < size; i++) {
if (abs(array[i] - val) < diff) {
diff = abs(array[i] - val);
ret = i;
}
}
return ret;
}
/**
* Shift the value and apply the specified mask.
*/
uint32_t field_prep(uint32_t mask, uint32_t val)
{
return (val << find_first_set_bit(mask)) & mask;
}
/**
* Get a field specified by a mask from a word.
*/
uint32_t field_get(uint32_t mask, uint32_t word)
{
return (word & mask) >> find_first_set_bit(mask);
}
/**
* Log base 2 of the given number.
*/
int32_t log_base_2(uint32_t x)
{
return find_last_set_bit(x);
}
/**
* Find greatest common divisor of the given two numbers.
*/
uint32_t greatest_common_divisor(uint32_t a,
uint32_t b)
{
uint32_t div;
uint32_t common_div = 1;
if ((a == 0) || (b == 0))
return max(a, b);
for (div = 1; (div <= a) && (div <= b); div++)
if (!(a % div) && !(b % div))
common_div = div;
return common_div;
}
/**
* Calculate best rational approximation for a given fraction.
*/
void rational_best_approximation(uint32_t given_numerator,
uint32_t given_denominator,
uint32_t max_numerator,
uint32_t max_denominator,
uint32_t *best_numerator,
uint32_t *best_denominator)
{
uint32_t gcd;
gcd = greatest_common_divisor(given_numerator, given_denominator);
*best_numerator = given_numerator / gcd;
*best_denominator = given_denominator / gcd;
if ((*best_numerator > max_numerator) ||
(*best_denominator > max_denominator)) {
*best_numerator = 0;
*best_denominator = 0;
}
}
/**
* Calculate the number of set bits.
*/
uint32_t hweight8(uint32_t word)
{
uint32_t count = 0;
while (word) {
if (word & 0x1)
count++;
word >>= 1;
}
return count;
}
/**
* Calculate the quotient and the remainder of an integer division.
*/
uint64_t do_div(uint64_t* n,
uint64_t base)
{
uint64_t mod = 0;
mod = *n % base;
*n = *n / base;
return mod;
}
/**
* Unsigned 64bit divide with 64bit divisor and remainder
*/
uint64_t div64_u64_rem(uint64_t dividend, uint64_t divisor, uint64_t *remainder)
{
*remainder = dividend % divisor;
return dividend / divisor;
}
/**
* Unsigned 64bit divide with 32bit divisor with remainder
*/
uint64_t div_u64_rem(uint64_t dividend, uint32_t divisor, uint32_t *remainder)
{
*remainder = do_div(&dividend, divisor);
return dividend;
}
/**
* Signed 64bit divide with 32bit divisor with remainder
*/
int64_t div_s64_rem(int64_t dividend, int32_t divisor, int32_t *remainder)
{
*remainder = dividend % divisor;
return dividend / divisor;
}
/**
* Unsigned 64bit divide with 32bit divisor
*/
uint64_t div_u64(uint64_t dividend, uint32_t divisor)
{
uint32_t remainder;
return div_u64_rem(dividend, divisor, &remainder);
}
/**
* Signed 64bit divide with 32bit divisor
*/
int64_t div_s64(int64_t dividend, int32_t divisor)
{
int32_t remainder;
return div_s64_rem(dividend, divisor, &remainder);
}
/**
* Converts from string to int32_t
* @param *str
* @return int32_t
*/
int32_t str_to_int32(const char *str)
{
char *end;
int32_t value = strtol(str, &end, 0);
if (end == str)
return FAILURE;
else
return value;
}
/**
* Converts from string to uint32_t
* @param *str
* @return uint32_t
*/
uint32_t srt_to_uint32(const char *str)
{
char *end;
uint32_t value = strtoul(str, &end, 0);
if (end == str)
return FAILURE;
else
return value;
}
@@ -0,0 +1,191 @@
/***************************************************************************//**
* @file util.h
* @brief Implementation of utility functions.
* @author DBogdan ([email protected])
********************************************************************************
* Copyright 2018(c) Analog Devices, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* - Neither the name of Analog Devices, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* - The use of this software may or may not infringe the patent rights
* of one or more patent holders. This license does not release you
* from the requirement that you obtain separate licenses from these
* patent holders to use this software.
* - Use of the software either in source or binary form, must be run
* on or directly connected to an Analog Devices Inc. component.
*
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#ifndef UTIL_H_
#define UTIL_H_
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
/******************************************************************************/
/********************** Macros and Constants Definitions **********************/
/******************************************************************************/
#define __BITSWAP_TABLE
//#define __CRC_LSB
#define CRC16_INIT 0x0000
#define CRC8_INIT 0x00
#define BIT(x) (1 << (x))
#define ARRAY_SIZE(x) \
(sizeof(x) / sizeof((x)[0]))
#define DIV_ROUND_UP(x,y) \
(((x) + (y) - 1) / (y))
#define DIV_ROUND_CLOSEST(x, y) \
(((x) + (y) / 2) / (y))
#define DIV_ROUND_CLOSEST_ULL(x, y) \
DIV_ROUND_CLOSEST(x, y)
#define min(x, y) \
(((x) < (y)) ? (x) : (y))
#define min_t(type, x, y) \
(type)min((type)(x), (type)(y))
#define max(x, y) \
(((x) > (y)) ? (x) : (y))
#define max_t(type, x, y) \
(type)max((type)(x), (type)(y))
#define clamp(val, min_val, max_val) \
(max(min((val), (max_val)), (min_val)))
#define clamp_t(type, val, min_val, max_val) \
(type)clamp((type)(val), (type)(min_val), (type)(max_val))
#define swap(x, y) \
{typeof(x) _tmp_ = (x); (x) = (y); (y) = _tmp_;}
#define round_up(x,y) \
(((x)+(y)-1)/(y))
#define BITS_PER_LONG 32
#define GENMASK(h, l) ({ \
uint32_t t = (uint32_t)(~0UL); \
t = t << (BITS_PER_LONG - (h - l + 1)); \
t = t >> (BITS_PER_LONG - (h + 1)); \
t; \
})
#define bswap_constant_32(x) \
((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
(((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
#define bswap_constant_16(x) ((((x) & (uint16_t)0xff00) >> 8) | \
(((x) & (uint16_t)0x00ff) << 8))
#define bit_swap_constant_8(x) \
((((x) & 0x80) >> 7) | \
(((x) & 0x40) >> 5) | \
(((x) & 0x20) >> 3) | \
(((x) & 0x10) >> 1) | \
(((x) & 0x08) << 1) | \
(((x) & 0x04) << 3) | \
(((x) & 0x02) << 5) | \
(((x) & 0x01) << 7))
#define U16_MAX ((uint16_t)~0U)
#define S16_MAX ((int16_t)(U16_MAX>>1))
#define DIV_U64(x, y) (x / y)
#define UNUSED_PARAM(x) ((void)x)
#define shift_right(x, s) ((x) < 0 ? -(-(x) >> (s)) : (x) >> (s))
/******************************************************************************/
/************************ Functions Declarations ******************************/
/******************************************************************************/
void IO_Out32(uintptr_t addr, uint32_t value);
uint32_t IO_In32(uintptr_t addr);
/* flip a byte left to right*/
uint8_t byte_bit_swap(uint8_t byte);
/* flip a 32bit word left to right */
uint32_t word_bit_swap(uint32_t word);
/* Returns the number of 1-bits in digit. */
uint32_t count_ones(uint32_t word);
/* convert a fixed number to a double. */
double fix2double(int32_t val, uint8_t frac_bits);
/* Find first set bit in word. */
uint32_t find_first_set_bit(uint32_t word);
/* Find last set bit in word. */
uint32_t find_last_set_bit(uint32_t word);
/* Locate the closest element in an array. */
uint32_t find_closest(int32_t val,
const int32_t *array,
uint32_t size);
/* Shift the value and apply the specified mask. */
uint32_t field_prep(uint32_t mask, uint32_t val);
/* Get a field specified by a mask from a word. */
uint32_t field_get(uint32_t mask, uint32_t word);
/* Log base 2 of the given number. */
int32_t log_base_2(uint32_t x);
/* Find greatest common divisor of the given two numbers. */
uint32_t greatest_common_divisor(uint32_t a,
uint32_t b);
/* Calculate best rational approximation for a given fraction. */
void rational_best_approximation(uint32_t given_numerator,
uint32_t given_denominator,
uint32_t max_numerator,
uint32_t max_denominator,
uint32_t *best_numerator,
uint32_t *best_denominator);
/* Calculate the number of set bits. */
uint32_t hweight8(uint32_t word);
/* Calculate the quotient and the remainder of an integer division. */
uint64_t do_div(uint64_t* n,
uint64_t base);
/* Unsigned 64bit divide with 64bit divisor and remainder */
uint64_t div64_u64_rem(uint64_t dividend, uint64_t divisor,
uint64_t *remainder);
/* Unsigned 64bit divide with 32bit divisor with remainder */
uint64_t div_u64_rem(uint64_t dividend, uint32_t divisor, uint32_t *remainder);
int64_t div_s64_rem(int64_t dividend, int32_t divisor, int32_t *remainder);
/* Unsigned 64bit divide with 32bit divisor */
uint64_t div_u64(uint64_t dividend, uint32_t divisor);
int64_t div_s64(int64_t dividend, int32_t divisor);
/* Converts from string to int32_t */
int32_t str_to_int32(const char *str);
/* Converts from string to uint32_t */
uint32_t srt_to_uint32(const char *str);
int crc16_gen(uint8_t* buffPtr, uint32_t dataLen, uint16_t poly, uint16_t* crcVal);
bool crc16_check(uint8_t* buffPtr, uint32_t dataLen, uint32_t crcOffset, uint16_t poly);
int crc8_gen(uint8_t* buffPtr, uint32_t dataLen, uint16_t poly, uint8_t* crcVal);
bool crc8_check(uint8_t* buffPtr, uint32_t dataLen, uint32_t crcOffset, uint16_t poly);
#endif // UTIL_H_
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="org.eclipse.cdt.core.default.config.644736180">
<storageModule buildSystemId="org.eclipse.cdt.core.defaultConfigDataProvider" id="org.eclipse.cdt.core.default.config.644736180" moduleId="org.eclipse.cdt.core.settings" name="Configuration">
<externalSettings/>
<extensions/>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
</cproject>
@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>phy_bc_bsp</name>
<comment>Created by SDK v2019.1</comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.make.core.makeBuilder</name>
<arguments>
<dictionary>
<key>org.eclipse.cdt.core.errorOutputParser</key>
<value>org.eclipse.cdt.core.GASErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.GCCErrorParser;org.eclipse.cdt.core.GmakeErrorParser;org.eclipse.cdt.core.VCErrorParser;org.eclipse.cdt.core.CWDLocator;org.eclipse.cdt.core.MakeErrorParser;</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.append_environment</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.build.arguments</key>
<value></value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.build.command</key>
<value>make</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.build.target.auto</key>
<value>all</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.build.target.clean</key>
<value>clean</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.build.target.inc</key>
<value>all</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableFullBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enabledIncrementalBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.environment</key>
<value></value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.stopOnError</key>
<value>false</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
<value>true</value>
</dictionary>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.xilinx.sdk.sw.SwProjectNature</nature>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.make.core.makeNature</nature>
</natures>
</projectDescription>
@@ -0,0 +1,4 @@
THIRPARTY=false
HW_PROJECT_REFERENCE=system_top_hw_platform_0
PROCESSOR=ps7_cortexa9_0
MSS_FILE=system.mss
@@ -0,0 +1,35 @@
# Makefile generated by Xilinx.
PROCESSOR = ps7_cortexa9_0
LIBRARIES = ${PROCESSOR}/lib/libxil.a
BSP_MAKEFILES := $(wildcard $(PROCESSOR)/libsrc/*/src/Makefile)
SUBDIRS := $(patsubst %/Makefile, %, $(BSP_MAKEFILES))
ifneq (,$(findstring win,$(RDI_PLATFORM)))
SHELL = CMD
endif
all: libs
@echo 'Finished building libraries'
include: $(addsuffix /make.include,$(SUBDIRS))
libs: $(addsuffix /make.libs,$(SUBDIRS))
clean: $(addsuffix /make.clean,$(SUBDIRS))
$(PROCESSOR)/lib/libxil.a: $(PROCESSOR)/lib/libxil_init.a
cp -f $< $@
%/make.include: $(if $(wildcard $(PROCESSOR)/lib/libxil_init.a),$(PROCESSOR)/lib/libxil.a,)
@echo "Running Make include in $(subst /make.include,,$@)"
$(MAKE) -C $(subst /make.include,,$@) -s include "SHELL=$(SHELL)" "COMPILER=arm-none-eabi-gcc" "ARCHIVER=arm-none-eabi-ar" "COMPILER_FLAGS= -O2 -c" "EXTRA_COMPILER_FLAGS=-mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -nostartfiles -g -Wall -Wextra"
%/make.libs: include
@echo "Running Make libs in $(subst /make.libs,,$@)"
$(MAKE) -C $(subst /make.libs,,$@) -s libs "SHELL=$(SHELL)" "COMPILER=arm-none-eabi-gcc" "ARCHIVER=arm-none-eabi-ar" "COMPILER_FLAGS= -O2 -c" "EXTRA_COMPILER_FLAGS=-mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -nostartfiles -g -Wall -Wextra"
%/make.clean:
$(MAKE) -C $(subst /make.clean,,$@) -s clean
clean:
rm -f ${PROCESSOR}/lib/libxil.a
@@ -0,0 +1,213 @@
PARAMETER VERSION = 2.2.0
BEGIN OS
PARAMETER OS_NAME = standalone
PARAMETER OS_VER = 7.0
PARAMETER PROC_INSTANCE = ps7_cortexa9_0
PARAMETER stdin = ps7_coresight_comp_0
PARAMETER stdout = ps7_coresight_comp_0
END
BEGIN PROCESSOR
PARAMETER DRIVER_NAME = cpu_cortexa9
PARAMETER DRIVER_VER = 2.7
PARAMETER HW_INSTANCE = ps7_cortexa9_0
END
BEGIN DRIVER
PARAMETER DRIVER_NAME = axidma
PARAMETER DRIVER_VER = 9.9
PARAMETER HW_INSTANCE = c2c_dma_axi_dma_c2c
END
BEGIN DRIVER
PARAMETER DRIVER_NAME = gpio
PARAMETER DRIVER_VER = 4.4
PARAMETER HW_INSTANCE = glink_ctrl
END
BEGIN DRIVER
PARAMETER DRIVER_NAME = axidma
PARAMETER DRIVER_VER = 9.9
PARAMETER HW_INSTANCE = glink_dma_axi_dma_glink
END
BEGIN DRIVER
PARAMETER DRIVER_NAME = generic
PARAMETER DRIVER_VER = 2.0
PARAMETER HW_INSTANCE = ps7_afi_0
END
BEGIN DRIVER
PARAMETER DRIVER_NAME = generic
PARAMETER DRIVER_VER = 2.0
PARAMETER HW_INSTANCE = ps7_afi_1
END
BEGIN DRIVER
PARAMETER DRIVER_NAME = generic
PARAMETER DRIVER_VER = 2.0
PARAMETER HW_INSTANCE = ps7_afi_2
END
BEGIN DRIVER
PARAMETER DRIVER_NAME = generic
PARAMETER DRIVER_VER = 2.0
PARAMETER HW_INSTANCE = ps7_afi_3
END
BEGIN DRIVER
PARAMETER DRIVER_NAME = coresightps_dcc
PARAMETER DRIVER_VER = 1.5
PARAMETER HW_INSTANCE = ps7_coresight_comp_0
END
BEGIN DRIVER
PARAMETER DRIVER_NAME = ddrps
PARAMETER DRIVER_VER = 1.0
PARAMETER HW_INSTANCE = ps7_ddr_0
END
BEGIN DRIVER
PARAMETER DRIVER_NAME = generic
PARAMETER DRIVER_VER = 2.0
PARAMETER HW_INSTANCE = ps7_ddrc_0
END
BEGIN DRIVER
PARAMETER DRIVER_NAME = devcfg
PARAMETER DRIVER_VER = 3.5
PARAMETER HW_INSTANCE = ps7_dev_cfg_0
END
BEGIN DRIVER
PARAMETER DRIVER_NAME = dmaps
PARAMETER DRIVER_VER = 2.4
PARAMETER HW_INSTANCE = ps7_dma_ns
END
BEGIN DRIVER
PARAMETER DRIVER_NAME = dmaps
PARAMETER DRIVER_VER = 2.4
PARAMETER HW_INSTANCE = ps7_dma_s
END
BEGIN DRIVER
PARAMETER DRIVER_NAME = generic
PARAMETER DRIVER_VER = 2.0
PARAMETER HW_INSTANCE = ps7_globaltimer_0
END
BEGIN DRIVER
PARAMETER DRIVER_NAME = generic
PARAMETER DRIVER_VER = 2.0
PARAMETER HW_INSTANCE = ps7_gpv_0
END
BEGIN DRIVER
PARAMETER DRIVER_NAME = generic
PARAMETER DRIVER_VER = 2.0
PARAMETER HW_INSTANCE = ps7_intc_dist_0
END
BEGIN DRIVER
PARAMETER DRIVER_NAME = generic
PARAMETER DRIVER_VER = 2.0
PARAMETER HW_INSTANCE = ps7_iop_bus_config_0
END
BEGIN DRIVER
PARAMETER DRIVER_NAME = generic
PARAMETER DRIVER_VER = 2.0
PARAMETER HW_INSTANCE = ps7_l2cachec_0
END
BEGIN DRIVER
PARAMETER DRIVER_NAME = generic
PARAMETER DRIVER_VER = 2.0
PARAMETER HW_INSTANCE = ps7_ocmc_0
END
BEGIN DRIVER
PARAMETER DRIVER_NAME = generic
PARAMETER DRIVER_VER = 2.0
PARAMETER HW_INSTANCE = ps7_pl310_0
END
BEGIN DRIVER
PARAMETER DRIVER_NAME = generic
PARAMETER DRIVER_VER = 2.0
PARAMETER HW_INSTANCE = ps7_pmu_0
END
BEGIN DRIVER
PARAMETER DRIVER_NAME = qspips
PARAMETER DRIVER_VER = 3.6
PARAMETER HW_INSTANCE = ps7_qspi_0
END
BEGIN DRIVER
PARAMETER DRIVER_NAME = generic
PARAMETER DRIVER_VER = 2.0
PARAMETER HW_INSTANCE = ps7_qspi_linear_0
END
BEGIN DRIVER
PARAMETER DRIVER_NAME = generic
PARAMETER DRIVER_VER = 2.0
PARAMETER HW_INSTANCE = ps7_ram_0
END
BEGIN DRIVER
PARAMETER DRIVER_NAME = generic
PARAMETER DRIVER_VER = 2.0
PARAMETER HW_INSTANCE = ps7_ram_1
END
BEGIN DRIVER
PARAMETER DRIVER_NAME = generic
PARAMETER DRIVER_VER = 2.0
PARAMETER HW_INSTANCE = ps7_scuc_0
END
BEGIN DRIVER
PARAMETER DRIVER_NAME = scugic
PARAMETER DRIVER_VER = 4.0
PARAMETER HW_INSTANCE = ps7_scugic_0
END
BEGIN DRIVER
PARAMETER DRIVER_NAME = scutimer
PARAMETER DRIVER_VER = 2.1
PARAMETER HW_INSTANCE = ps7_scutimer_0
END
BEGIN DRIVER
PARAMETER DRIVER_NAME = scuwdt
PARAMETER DRIVER_VER = 2.1
PARAMETER HW_INSTANCE = ps7_scuwdt_0
END
BEGIN DRIVER
PARAMETER DRIVER_NAME = generic
PARAMETER DRIVER_VER = 2.0
PARAMETER HW_INSTANCE = ps7_slcr_0
END
BEGIN DRIVER
PARAMETER DRIVER_NAME = xadcps
PARAMETER DRIVER_VER = 2.3
PARAMETER HW_INSTANCE = ps7_xadc_0
END
BEGIN DRIVER
PARAMETER DRIVER_NAME = gpio
PARAMETER DRIVER_VER = 4.4
PARAMETER HW_INSTANCE = pwdown_ctrl
END