chore: merge GE program

* merge GE code
* update fold structure
* enable to build two types of projects separately
This commit is contained in:
Gatsby Van
2024-12-24 13:27:22 +08:00
parent 384a51a198
commit 3470b6f6dc
78 changed files with 43504 additions and 1754 deletions
+11 -2
View File
@@ -2,7 +2,16 @@ include scripts/generic_variables.mk
PLATFORM := xilinx PLATFORM := xilinx
TARGET_PROJ ?= node TARGET_PROJ ?= node
BUILD_DIR := $(PROJECT)/build
CONFIG_FILE := $(PROJECT)/config.json ifeq ($(TARGET_PROJ), node)
BUILD_DIR := $(PROJECT)/build/node
CONFIG_FILE := $(PROJECT)/config/node.json
else ifeq ($(TARGET_PROJ), ge)
XILINX_VITIS_CLASSIC := y
BUILD_DIR := $(PROJECT)/build/ge
CONFIG_FILE := $(PROJECT)/config/ge.json
else
$(error Unsupported target PROJECT: $(TARGET_PROJ))
endif
include scripts/generic.mk include scripts/generic.mk
+4
View File
@@ -53,6 +53,10 @@
- 重写总线驱动程序,采用 **PS UART 控制器**完成总线信息的收发。 - 重写总线驱动程序,采用 **PS UART 控制器**完成总线信息的收发。
- 更新总线控制协议,基于《网控模块 GLINK 协议》实现核心交互逻辑。 - 更新总线控制协议,基于《网控模块 GLINK 协议》实现核心交互逻辑。
- 使用折算的方式模拟新体制中的三档速率:
- 2Kbps:10Kbps模拟,Payload 128b, 占空比 40%
- 128Kbps:200Kbps模拟,Payload 1280b, 占空比 50%
- 256Kbps:1.2Mbps模拟,Payload 2560b, 占空比 50%
--- ---
+29 -3
View File
@@ -1,9 +1,35 @@
@echo off @echo off
set "platform=xilinx" set "platform=xilinx"
set "tools_dir=%~dp0scripts\platform\%platform%" set "tools_dir=%~dp0scripts\platform\%platform%"
set "platform_ver=2019.1"
set "work_dir=%~dp0build" :menu
set "config=%~dp0config.json" echo Please select the project needed to be built:
echo 1. NODE Project (SDK 2019.1)
echo 2. GE Project (Vitis 2024.1)
set /p choice="Choose a project (1 or 2): "
if "%choice%"=="1" (
echo Building NODE Project ^(SDK 2019.1^)
set "platform_ver=2019.1"
set "work_dir=%~dp0build\node"
set "config=%~dp0config\node.json"
goto end
) else if "%choice%"=="2" (
echo Building GE Project ^(Vitis 2024.1^)
set "platform_ver=2024.1"
set "work_dir=%~dp0build\ge"
set "config=%~dp0config\ge.json"
goto end
) else (
echo Invalid choice. Please enter 1 or 2.
goto menu
)
:end
echo Start Building
echo Platform version: %platform_ver%
echo Build directory: %work_dir%
echo Configuration file: %config%
REM Change working dir to the dir where this script is located REM Change working dir to the dir where this script is located
cd /d "%~dp0" cd /d "%~dp0"
+39
View File
@@ -0,0 +1,39 @@
{
"project_name": "ky-xtz",
"version": "0.0.0",
"hw_design": "hw/kykk_ge_hw_v0.0.hdf",
"apps": {
"xtzge_app": {
"sources": [
"src/ge_app.c",
"src/include",
"src/ge_config",
"src/drivers",
"src/hardware",
"src/networking",
"src/time_ctrl",
"src/mpc",
"src/util",
"src/system_monitor.h",
"src/system_monitor.c"
],
"target_cpu": "ps7_cortexa9_0",
"os": "standalone",
"language": "C",
"mem_layout" : {
"heap_size": "0x800000",
"stack_size": "0x20000"
},
"build_config": {
"debug": {
"include-path": ["src", "src/include"],
"libraries": ["m"]
},
"release": {
"include-path": ["src", "src/include"],
"libraries": ["m"]
}
}
}
}
}
+13 -2
View File
@@ -1,10 +1,21 @@
{ {
"project_name": "ky-xtz", "project_name": "ky-xtz",
"version": "0.0.0", "version": "0.0.0",
"hw_design": "hw/hsjl_node_v0.0.0.hdf", "hw_design": "hw/kykk_node_hw_v0.0.hdf",
"apps": { "apps": {
"xtz_app": { "xtz_app": {
"sources": ["src/*"], "sources": [
"src/node_app.c",
"src/include",
"src/node_config",
"src/drivers",
"src/networking",
"src/time_ctrl",
"src/systembus",
"src/util",
"src/system_monitor.h",
"src/system_monitor.c"
],
"target_cpu": "ps7_cortexa9_0", "target_cpu": "ps7_cortexa9_0",
"os": "standalone", "os": "standalone",
"language": "C", "language": "C",
Binary file not shown.
-135
View File
@@ -1,135 +0,0 @@
/***************************************************************************//**
* @file i2c.c
* @brief Implementation of the I2C Interface
* @author Antoniu Miclaus ([email protected])
********************************************************************************
* Copyright 2020(c) Analog Devices, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* - Neither the name of Analog Devices, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* - The use of this software may or may not infringe the patent rights
* of one or more patent holders. This license does not release you
* from the requirement that you obtain separate licenses from these
* patent holders to use this software.
* - Use of the software either in source or binary form, must be run
* on or directly connected to an Analog Devices Inc. component.
*
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#include <inttypes.h>
#include "i2c.h"
#include <stdlib.h>
#include "error.h"
/**
* @brief Initialize the I2C communication peripheral.
* @param desc - The I2C descriptor.
* @param param - The structure that contains the I2C parameters.
* @return 0 in case of success, -1 otherwise.
*/
int32_t i2c_init(struct i2c_desc **desc,
const struct i2c_init_param *param)
{
int32_t ret;
if (!param || !param->platform_ops)
return -EINVAL;
if (!param->platform_ops->i2c_ops_init)
return -ENOSYS;
ret = param->platform_ops->i2c_ops_init(desc, param);
if (ret)
return ret;
(*desc)->platform_ops = param->platform_ops;
return 0;
}
/**
* @brief Free the resources allocated by i2c_init().
* @param desc - The I2C descriptor.
* @return 0 in case of success, -1 otherwise.
*/
int32_t i2c_remove(struct i2c_desc *desc)
{
if (!desc || !desc->platform_ops)
return -EINVAL;
if (!desc->platform_ops->i2c_ops_remove)
return -ENOSYS;
return desc->platform_ops->i2c_ops_remove(desc);
}
/**
* @brief I2C Write data to slave device.
* @param desc - The I2C descriptor.
* @param data - The buffer with the transmitted/received data.
* @param bytes_number - Number of bytes to write.
* @param stop_bit - Stop conditional control.
* Example: 0 - A stop condition will not be generated.
* 1 - A stop condition will be generated.
* @return 0 in case of success, -1 otherwise.
*/
int32_t i2c_write(struct i2c_desc *desc,
uint8_t *data,
uint8_t bytes_number,
uint8_t stop_bit)
{
if (!desc || !desc->platform_ops)
return -EINVAL;
if (!desc->platform_ops->i2c_ops_write)
return -ENOSYS;
return desc->platform_ops->i2c_ops_write(desc, data, bytes_number,
stop_bit);
}
/**
* @brief I2C Read data from slave device.
* @param desc - The i2c descriptor.
* @param data - The buffer with the transmitted/received data.
* @param bytes_number - Number of bytes to read.
* @param stop_bit - Stop conditional control.
* Example: 0 - A stop condition will not be generated.
* 1 - A stop condition will be generated.
* @return 0 in case of success, -1 otherwise.
*/
int32_t i2c_read(struct i2c_desc *desc,
uint8_t *data,
uint8_t bytes_number,
uint8_t stop_bit)
{
if (!desc || !desc->platform_ops)
return -EINVAL;
if (!desc->platform_ops->i2c_ops_read)
return -ENOSYS;
return desc->platform_ops->i2c_ops_read(desc, data, bytes_number,
stop_bit);
}
-161
View File
@@ -1,161 +0,0 @@
/***************************************************************************//**
* @file spi.c
* @brief Implementation of the SPI Interface
* @author Antoniu Miclaus ([email protected])
********************************************************************************
* Copyright 2020(c) Analog Devices, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* - Neither the name of Analog Devices, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* - The use of this software may or may not infringe the patent rights
* of one or more patent holders. This license does not release you
* from the requirement that you obtain separate licenses from these
* patent holders to use this software.
* - Use of the software either in source or binary form, must be run
* on or directly connected to an Analog Devices Inc. component.
*
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#include <inttypes.h>
#include "spi.h"
#include <stdlib.h>
#include "error.h"
/**
* @brief Initialize the SPI communication peripheral.
* @param desc - The SPI descriptor.
* @param param - The structure that contains the SPI parameters.
* @return 0 in case of success, -1 otherwise.
*/
int32_t spi_init(struct spi_desc **desc,
const struct spi_init_param *param)
{
int32_t ret;
if (!param || !param->platform_ops)
return -EINVAL;
if (!param->platform_ops->init)
return -ENOSYS;
ret = param->platform_ops->init(desc, param);
if (ret)
return ret;
(*desc)->platform_ops = param->platform_ops;
(*desc)->parent = param->parent;
return 0;
}
/**
* @brief Free the resources allocated by spi_init().
* @param desc - The SPI descriptor.
* @return 0 in case of success, -1 otherwise.
*/
int32_t spi_remove(struct spi_desc *desc)
{
if (!desc || !desc->platform_ops)
return -EINVAL;
if (!desc->platform_ops->remove)
return -ENOSYS;
return desc->platform_ops->remove(desc);
}
/**
* @brief Write and read data to/from SPI.
* @param desc - The SPI descriptor.
* @param data - The buffer with the transmitted/received data.
* @param bytes_number - Number of bytes to write/read.
* @return 0 in case of success, -1 otherwise.
*/
int32_t spi_write_and_read(struct spi_desc *desc,
uint8_t *data,
uint16_t bytes_number)
{
if (!desc || !desc->platform_ops)
return -EINVAL;
if (!desc->platform_ops->write_and_read)
return -ENOSYS;
return desc->platform_ops->write_and_read(desc, data, bytes_number);
}
/**
* @brief Write and read data to/from SPI in 3 wire mode.
* @param desc - The SPI descriptor.
* @param write_data - The buffer with the transmitted data.
* @param read_data - The buffer with the received data.
* @param write_bytes_number - Number of bytes to write.
* @param read_bytes_number - Number of bytes to read.
* @return SUCCESS in case of success, FAILURE otherwise.
*/
int32_t spi_write_and_read_3wire(struct spi_desc *desc,
uint8_t *write_data,
uint8_t *read_data,
uint16_t write_bytes_number,
uint16_t read_bytes_number)
{
if (!desc || !desc->platform_ops)
return -EINVAL;
if (!desc->platform_ops->write_and_read_3wire)
return -ENOSYS;
return desc->platform_ops->write_and_read_3wire(desc, write_data, read_data,
write_bytes_number, read_bytes_number);
}
/**
* @brief Iterate over head list and send all spi messages
* @param desc - The SPI descriptor.
* @param msgs - Array of messages.
* @param len - Number of messages in the array.
* @return 0 in case of success, negativ error code otherwise.
*/
int32_t spi_transfer(struct spi_desc *desc,
struct spi_msg *msgs,
uint32_t len)
{
int32_t ret;
uint32_t i;
if (!desc || !desc->platform_ops)
return -EINVAL;
if (desc->platform_ops->transfer)
return desc->platform_ops->transfer(desc, msgs, len);
for (i = 0; i < len; i++) {
if (msgs[i].rx_buff != msgs[i].tx_buff || !msgs[i].tx_buff)
return -EINVAL;
ret = spi_write_and_read(desc, msgs[i].rx_buff,
msgs[i].bytes_number);
if (IS_ERR_VALUE(ret))
return ret;
}
return 0;
}
-111
View File
@@ -1,111 +0,0 @@
/***************************************************************************//**
* @file trng.c
* @brief Implementation of the TRNG Interface
* @author Antoniu Miclaus ([email protected])
********************************************************************************
* Copyright 2023(c) Analog Devices, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* - Neither the name of Analog Devices, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* - The use of this software may or may not infringe the patent rights
* of one or more patent holders. This license does not release you
* from the requirement that you obtain separate licenses from these
* patent holders to use this software.
* - Use of the software either in source or binary form, must be run
* on or directly connected to an Analog Devices Inc. component.
*
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <inttypes.h>
#include "trng.h"
#include <stdlib.h>
#include "error.h"
/******************************************************************************/
/************************ Functions Definitions *******************************/
/******************************************************************************/
/**
* @brief Initialize the TRNG.
* @param desc - The TRNG descriptor.
* @param param - The structure that contains the TRNG parameters.
* @return 0 in case of success, -1 otherwise.
*/
int trng_init(struct trng_desc **desc,
const struct trng_init_param *param)
{
int ret;
if (!param || !param->platform_ops)
return -EINVAL;
if (!param->platform_ops->init)
return -ENOSYS;
ret = param->platform_ops->init(desc, param);
if (ret)
return ret;
(*desc)->platform_ops = param->platform_ops;
return 0;
}
/**
* @brief Free the resources allocated by trng_init().
* @param desc - The TRNG descriptor.
* @return 0 in case of success, -1 otherwise.
*/
int trng_remove(struct trng_desc *desc)
{
if (!desc || !desc->platform_ops)
return -EINVAL;
if (!desc->platform_ops->remove)
return -ENOSYS;
return desc->platform_ops->remove(desc);
}
/**
* @brief Fill buffer with rng data.
* @param desc - The TRNG descriptor.
* @param buff - Buffer to be filled
* @param len - Size of the buffer
* @return 0 in case of success, -1 otherwise.
*/
int trng_fill_buffer(struct trng_desc *desc, uint8_t *buff,
uint32_t len)
{
if (!desc || !desc->platform_ops)
return -EINVAL;
if (!desc->platform_ops->fill_buffer)
return -ENOSYS;
return desc->platform_ops->fill_buffer(desc, buff, len);
}
+2 -2
View File
@@ -47,8 +47,8 @@
#include <stdint.h> #include <stdint.h>
#include "spi_engine_private.h" #include "spi_engine_private.h"
#include "../axi_dmac/axi_dmac.h" #include "drivers/axi_core/axi_dmac/axi_dmac.h"
#include "../../platform/xilinx_spi.h" #include "drivers/platform/xilinx_spi.h"
/******************************************************************************/ /******************************************************************************/
/********************** Macros and Constants Definitions **********************/ /********************** Macros and Constants Definitions **********************/
-514
View File
@@ -1,514 +0,0 @@
/***************************************************************************//**
* @file xilinx/xilinx_i2c.c
* @brief Implementation of Xilinx I2C Generic Driver.
* @author Antoniu Miclaus ([email protected])
********************************************************************************
* Copyright 2019(c) Analog Devices, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* - Neither the name of Analog Devices, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* - The use of this software may or may not infringe the patent rights
* of one or more patent holders. This license does not release you
* from the requirement that you obtain separate licenses from these
* patent holders to use this software.
* - Use of the software either in source or binary form, must be run
* on or directly connected to an Analog Devices Inc. component.
*
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <stdlib.h>
#include <xparameters.h>
#ifdef XPAR_XIIC_NUM_INSTANCES
#include <xiic.h>
#endif
#ifdef XPAR_XIICPS_NUM_INSTANCES
#include <xiicps.h>
#endif
#include "error.h"
#include "i2c.h"
#include "xilinx_i2c.h"
#include "list.h"
/******************************************************************************/
/*************************** Types Declarations *******************************/
/******************************************************************************/
static struct list_desc *pl_list = NULL;
static struct iterator *pl_it = NULL;
#ifdef XIICPS_H
static struct list_desc *ps_list = NULL;
static struct iterator *ps_it = NULL;
#endif /* XIICPS_H */
/**
* @struct inst_table_item
* @brief Table item for I2C cores already started.
*/
struct inst_table_item {
/** Instance the BSP driver uses for this core. */
void *instance;
/** Core ID in BSP. */
uint32_t device_id;
/** Number of ADI driver instances running on this core. */
uint32_t inst_no;
};
#ifdef XPAR_XIICPS_NUM_INSTANCES
/** Save the current state of the bitrate to not change it each time */
static uint32_t ps_last_bitrate = 0;
#endif
/**
* @brief Xilinx platform specific I2C platform ops structure
*/
const struct i2c_platform_ops xil_i2c_ops = {
.i2c_ops_init = &xil_i2c_init,
.i2c_ops_write = &xil_i2c_write,
.i2c_ops_read = &xil_i2c_read,
.i2c_ops_remove = &xil_i2c_remove
};
/******************************************************************************/
/************************ Functions Definitions *******************************/
/******************************************************************************/
/**
* @brief Compare two I2C cores by ID.
* @param el1 - First I2C core to compare.
* @param el2 - Second I2C core to compare.
* @return \ref 0 if the two cores have the same ID,
* \ref difference between the first and the second IDs otherwise.
*/
static int32_t xil_i2c_cmp(void *el1, void *el2)
{
struct inst_table_item *sel1 = el1, *sel2 = el2;
return (sel1->device_id - sel2->device_id);
}
/**
* @brief Configure slave address and bitrate if needed
* @param desc - Descriptor of the I2C device
* @return 0 in case of success, -1 otherwise.
*/
static int32_t xil_i2c_set_transmission_config(struct i2c_desc *desc)
{
struct xil_i2c_desc *xil_i2c_desc = desc->extra;
#ifdef XIICPS_H
int32_t ret;
#endif
switch (xil_i2c_desc->type) {
case IIC_PL:
#ifdef XIIC_H
break;
#endif
return -1;
case IIC_PS:
#ifdef XIICPS_H
if (desc->max_speed_hz != ps_last_bitrate) {
ret = XIicPs_SetSClk(xil_i2c_desc->instance, desc->max_speed_hz);
if (ret != XST_SUCCESS)
return -1;
ps_last_bitrate = desc->max_speed_hz;
}
break;
#endif
return -1;
default:
return -1;
}
return 0;
}
/**
* @brief Initialize the I2C communication peripheral.
* @param desc - The I2C descriptor.
* @param param - The structure that contains the I2C parameters.
* @return 0 in case of success, -1 otherwise.
*/
int32_t xil_i2c_init(struct i2c_desc **desc,
const struct i2c_init_param *param)
{
int32_t ret;
struct i2c_desc *idesc;
struct xil_i2c_desc *xdesc;
struct xil_i2c_init_param *xinit;
idesc = (struct i2c_desc *)malloc(sizeof(*idesc));
xdesc = (struct xil_i2c_desc *)malloc(sizeof(*xdesc));
if(!idesc || !xdesc)
goto error;
idesc->max_speed_hz = param->max_speed_hz;
idesc->slave_address = param->slave_address;
xinit = param->extra;
idesc->extra = xdesc;
xdesc->type = xinit->type;
xdesc->device_id = xinit->device_id;
switch (xinit->type) {
case IIC_PL:
#ifdef XIIC_H
; /** Intentional empty statement */
struct inst_table_item tab_check_pl;
struct inst_table_item *temp_el_pl;
if (!pl_list)
list_init(&pl_list, LIST_DEFAULT, xil_i2c_cmp);
if (!pl_it)
iterator_init(&pl_it, pl_list, true);
tab_check_pl.device_id = xdesc->device_id;
if (!IS_ERR_VALUE(list_read_find(pl_list, (void **)&temp_el_pl,
&tab_check_pl))) {
xdesc->instance = temp_el_pl->instance;
temp_el_pl->inst_no++;
break;
}
xdesc->instance = (XIic *)malloc(sizeof(XIic));
if(!xdesc->instance)
goto pl_error;
xdesc->config = XIic_LookupConfig(xinit->device_id);
if(xdesc->config == NULL)
goto pl_error;
ret = XIic_CfgInitialize(xdesc->instance,
xdesc->config,
((XIic_Config*)xdesc->config)
->BaseAddress);
if(ret != 0)
goto pl_error;
ret = XIic_Start(xdesc->instance);
if(ret != 0)
goto pl_error;
ret = XIic_SetAddress(xdesc->instance,
XII_ADDR_TO_SEND_TYPE,
param->slave_address);
if(ret != 0)
goto pl_error;
ret = XIic_SelfTest(xdesc->instance);
if(ret < 0)
goto pl_error;
ret = XIic_SetGpOutput(xdesc->instance, 1);
if(ret < 0)
goto pl_error;
temp_el_pl = (struct inst_table_item*)calloc(1, sizeof(*temp_el_pl));
temp_el_pl->device_id = xinit->device_id;
temp_el_pl->inst_no = 1;
temp_el_pl->instance = xdesc->instance;
pl_list->push(pl_list, temp_el_pl);
break;
pl_error:
free(xdesc->instance);
#endif
goto error;
case IIC_PS:
#ifdef XIICPS_H
; /** Intentional empty statement */
struct inst_table_item tab_check_ps;
struct inst_table_item *temp_el_ps;
if (!pl_list)
list_init(&ps_list, LIST_DEFAULT, xil_i2c_cmp);
if (!pl_it)
iterator_init(&ps_it, ps_list, true);
tab_check_ps.device_id = xdesc->device_id;
if (!IS_ERR_VALUE(list_read_find(ps_list,
(void **)&temp_el_ps,
&tab_check_ps))) {
xdesc->instance = temp_el_ps->instance;
temp_el_ps->inst_no++;
break;
}
xdesc->instance = (XIicPs *)malloc(sizeof(XIicPs));
if(!xdesc->instance)
goto ps_error;
xdesc->config = XIicPs_LookupConfig(xinit->device_id);
if(xdesc->config == NULL)
goto ps_error;
ret = XIicPs_CfgInitialize(xdesc->instance,
xdesc->config,
((XIicPs_Config*)xdesc->config)
->BaseAddress);
if(ret != 0)
goto ps_error;
XIicPs_SetSClk(xdesc->instance, param->max_speed_hz);
temp_el_ps = (struct inst_table_item*)calloc(1, sizeof(*temp_el_ps));
temp_el_ps->device_id = xinit->device_id;
temp_el_ps->inst_no = 1;
temp_el_ps->instance = xdesc->instance;
ps_list->push(ps_list, temp_el_ps);
break;
ps_error:
free(xdesc->instance);
#endif
goto error;
default:
goto error;
break;
}
*desc = idesc;
return 0;
error:
free(idesc);
free(xdesc);
return -1;
}
/**
* @brief Free the resources allocated by i2c_init().
* @param desc - The I2C descriptor.
* @return 0 in case of success, -1 otherwise.
*/
int32_t xil_i2c_remove(struct i2c_desc *desc)
{
struct xil_i2c_desc *xdesc;
int32_t ret;
xdesc = desc->extra;
switch (xdesc->type) {
case IIC_PL:
#ifdef XIIC_H
; /** Intentional empty statement */
struct inst_table_item tab_check_pl;
struct inst_table_item *temp_el_pl;
tab_check_pl.device_id = xdesc->device_id;
ret = iterator_find(pl_it, &tab_check_pl);
if (ret != 0)
goto error;
iterator_read(pl_it, (void **)&temp_el_pl);
temp_el_pl->inst_no--;
if (temp_el_pl->inst_no != 0)
break;
ret = XIic_Stop(((XIic *)xdesc->instance));
if(ret != 0)
goto error;
/** Remove list element */
iterator_get(pl_it, (void **)&temp_el_pl);
free(temp_el_pl);
break;
#endif
goto error;
case IIC_PS:
#ifdef XIICPS_H
; /** Intentional empty statement */
struct inst_table_item tab_check_ps;
struct inst_table_item *temp_el_ps;
tab_check_ps.device_id = xdesc->device_id;
ret = iterator_find(ps_it, &tab_check_ps);
if (ret != 0)
goto error;
iterator_read(ps_it, (void **)&temp_el_ps);
temp_el_ps->inst_no--;
if (temp_el_ps->inst_no != 0)
break;
/** Remove list element */
iterator_get(ps_it, (void **)&temp_el_ps);
free(temp_el_ps);
break;
#endif
/* Intended fallthrough */
error:
default:
return -1;
}
free(desc->extra);
free(desc);
return 0;
}
/**
* @brief Write data to a slave device.
* @param desc - The I2C descriptor.
* @param data - Buffer that stores the transmission data.
* @param bytes_number - Number of bytes to write.
* @param stop_bit - Stop condition control.
* Example: 0 - A stop condition will not be generated;
* 1 - A stop condition will be generated.
* @return 0 in case of success, -1 otherwise.
*/
int32_t xil_i2c_write(struct i2c_desc *desc,
uint8_t *data,
uint8_t bytes_number,
uint8_t stop_bit)
{
struct xil_i2c_desc *xdesc;
int32_t ret;
xdesc = desc->extra;
switch (xdesc->type) {
case IIC_PL:
#ifdef XIIC_H
ret = xil_i2c_set_transmission_config(desc);
if (ret != 0)
return -1;
XIic_Send(((XIic*)xdesc->instance)->BaseAddress,
desc->slave_address,
data,
bytes_number,
stop_bit ? XIIC_STOP : XIIC_REPEATED_START);
break;
#endif
goto error;
case IIC_PS:
#ifdef XIICPS_H
ret = xil_i2c_set_transmission_config(desc);
if (ret != 0)
return -1;
ret = XIicPs_SetOptions(xdesc->instance,
stop_bit ? 0 : XIICPS_REP_START_OPTION);
if(ret != 0)
goto error;
XIicPs_MasterSend(xdesc->instance,
data,
bytes_number,
desc->slave_address);
if(ret != 0)
goto error;
break;
#endif
/* Intended fallthrough */
error:
default:
return -1;
}
return 0;
}
/**
* @brief Read data from a slave device.
* @param desc - The I2C descriptor.
* @param data - Buffer that will store the received data.
* @param bytes_number - Number of bytes to read.
* @param stop_bit - Stop condition control.
* Example: 0 - A stop condition will not be generated;
* 1 - A stop condition will be generated.
* @return 0 in case of success, -1 otherwise.
*/
int32_t xil_i2c_read(struct i2c_desc *desc,
uint8_t *data,
uint8_t bytes_number,
uint8_t stop_bit)
{
struct xil_i2c_desc *xdesc;
int32_t ret;
xdesc = desc->extra;
switch (xdesc->type) {
case IIC_PL:
#ifdef XIIC_H
ret = xil_i2c_set_transmission_config(desc);
if (ret != 0)
return -1;
ret = XIic_Recv(((XIic*)xdesc->instance)->BaseAddress,
desc->slave_address,
data,
bytes_number,
stop_bit ? XIIC_STOP : XIIC_REPEATED_START);
if(ret != bytes_number)
goto error;
break;
#endif
goto error;
case IIC_PS:
#ifdef XIICPS_H
ret = xil_i2c_set_transmission_config(desc);
if (ret != 0)
return -1;
ret = XIicPs_SetOptions(xdesc->instance,
stop_bit ? 0 : XIICPS_REP_START_OPTION);
if(ret != 0)
goto error;
XIicPs_MasterRecv(xdesc->instance,
data,
bytes_number,
desc->slave_address);
if(ret != 0)
goto error;
break;
#endif
/* Intended fallthrough */
error:
default:
return -1;
break;
}
return 0;
}
-115
View File
@@ -1,115 +0,0 @@
/*******************************************************************************
* @file xilinx/xilinx_i2c.h
* @brief Header containing types used in the i2c driver.
* @author scuciurean ([email protected])
********************************************************************************
* Copyright 2019(c) Analog Devices, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* - Neither the name of Analog Devices, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* - The use of this software may or may not infringe the patent rights
* of one or more patent holders. This license does not release you
* from the requirement that you obtain separate licenses from these
* patent holders to use this software.
* - Use of the software either in source or binary form, must be run
* on or directly connected to an Analog Devices Inc. component.
*
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#ifndef XILINX_I2C_H_
#define XILINX_I2C_H_
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <stdint.h>
/******************************************************************************/
/*************************** Types Declarations *******************************/
/******************************************************************************/
/**
* @enum xil_i2c_type
* @brief Xilinx platform architecture sections
*/
enum xil_i2c_type {
/** Programmable Logic */
IIC_PL,
/** Processing System */
IIC_PS
};
/**
* @struct xil_i2c_init
* @brief Structure holding the initialization parameters for Xilinx platform
* specific I2C parameters.
*/
struct xil_i2c_init_param {
/** Xilinx architecture */
enum xil_i2c_type type;
/** Device ID */
uint32_t device_id;
};
/**
* @struct xil_i2c_desc
* @brief Xilinx platform specific I2C descriptor
*/
struct xil_i2c_desc {
/** Xilinx architecture */
enum xil_i2c_type type;
/** Device ID */
uint32_t device_id;
/** Xilinx I2C configuration */
void *config;
/** Xilinx I2C Instance */
void *instance;
};
/**
* @brief Xilinx platform specific i2c platform ops structure
*/
extern const struct i2c_platform_ops xil_i2c_ops;
/******************************************************************************/
/************************ Functions Declarations ******************************/
/******************************************************************************/
/* Initialize the I2C communication peripheral. */
int32_t xil_i2c_init(struct i2c_desc **desc,
const struct i2c_init_param *param);
/* Free the resources allocated by i2c_init(). */
int32_t xil_i2c_remove(struct i2c_desc *desc);
/* I2C Write data */
int32_t xil_i2c_write(struct i2c_desc *desc, uint8_t *data,
uint8_t bytes_number, uint8_t stop_bit);
/* I2C Read data. */
int32_t xil_i2c_read(struct i2c_desc *desc, uint8_t *data,
uint8_t bytes_number, uint8_t stop_bit);
#endif // XILINX_I2C_H_
+610
View File
@@ -0,0 +1,610 @@
/*****************************************************************************/
/**
* Description: main.c
*
* 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 <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
// Xilinx
#include "sleep.h"
#include "xil_cache.h"
#include "xscugic.h"
#include "xscutimer.h"
#include "xgpiops.h"
#include "drivers/platform/xilinx_irq.h"
#include "drivers/platform/xilinx_timer.h"
// App
#include "common.h"
#include "error.h"
#include "timer.h"
#include "mpc/mpc.h"
#include "networking/phy_layer/phy_layer.h"
#include "networking/link_layer/link_layer.h"
#include "ge_config/app_config.h"
#include "ge_config/dev_profile/dev_profile.h"
// RF-Driver
#include "hardware/headless.h"
#include "hardware/platform_drivers.h"
/************************** Function Prototypes ******************************/
static int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr);
static void Phy_IntrHandler(void *context);
static void PeriodicPull_Handler(void *callBackRef);
static void ScuTimer_IntrHandler(void *context);
static void Mpc_RxIntrHandler(void *context);
static void Mpc_TxIntrHandler(void *context);
static bool LinklayerPush2Up(RING_BUFFER *buff);
static bool LinklayerPopFromUp(RING_BUFFER **buff);
/************************** Constant Definitions *****************************/
struct callback_desc phy_callback_desc =
{
.callback = Phy_IntrHandler,
.ctx = NULL
};
struct callback_desc periodicpull_callback_desc =
{
.callback = PeriodicPull_Handler,
.ctx = NULL
};
struct callback_desc mpc_rx_callback_desc =
{
.callback = Mpc_RxIntrHandler,
.ctx = NULL
};
struct callback_desc mpc_tx_callback_desc =
{
.callback = Mpc_TxIntrHandler,
.ctx = NULL
};
struct callback_desc scutm_callback_desc =
{
.callback = ScuTimer_IntrHandler,
.ctx = NULL
};
L2_CONFIG linkConfig = {
.myType = L2_NODE_HEAD,
.clustId = 1U,
.myId = 1U,
.headId = 1U,
.netScale = 2U,
.phyInstPtr = NULL, // physical layer reference
.tmcInstPtr = NULL,
.pushUpHandle = LinklayerPush2Up,
.popUpHandle = LinklayerPopFromUp
};
// L2_CONFIG linkConfig = {
// .myType = L2_NODE_MEMBER,
// .clustId = 1U,
// .myId = 2U,
// .headId = 1U,
// .netScale = 2U,
// .phyInstPtr = NULL, // physical layer reference
// .tmcInstPtr = NULL,
// .pushUpHandle = LinklayerPush2Up,
// .popUpHandle = LinklayerPopFromUp
// };
static PHY_CONFIG phyConfig =
{
.devId = 0,
.baseAddr = PHY_BASEADDR,
.antBramId = PHY_ANTCONFIG_BRAM_DEVICE_ID,
.antInfoBramId = -1,
.txBramId = PHY_TXBUFF_BRAM_DEVICE_ID,
.rxBramId = PHY_RXBUFF_BRAM_DEVICE_ID,
.hwXadcId = PHY_HW_XADC_DEVICE_ID,
.get_clk_state = NULL,
.get_ad_lock_state = NULL,
.get_ad0_temp = NULL,
.get_ad1_temp = NULL
};
TMC_CONFIG tmcConfig =
{
.baseAddr = TIME_CONTROLLER_BASEADDR,
.reset = 10
};
static MPC_CONFIG mpcConfig = {
.bramId = MPC_BRAM_ID,
.gpioId = MPC_GPIO_ID,
.txQueueMax = 16,
.rxQueueMax = 16
};
#ifdef APP_EMULATE_DATA
uint8_t testDataLj[] =
{
0xEA, 0xDF, 0x3F, 0x27, 0xCE, 0x9B, 0xE6, 0x3F,
0xB5, 0xA3, 0x38, 0x47, 0x1D, 0x1D, 0xFA, 0x3F,
0x39, 0xB4, 0xC8, 0x76, 0xBE, 0xAB, 0x8E, 0x40,
0xC9, 0xE8, 0x80, 0x24, 0xEC, 0xCB, 0x13, 0x40,
0x37, 0x38, 0x7F, 0x22, 0x72, 0x06, 0xF0, 0x01,
0x00, 0x00, 0xB8, 0xAA, 0x08, 0x47, 0x1E, 0xC6,
0xB0, 0x47, 0x54, 0xFD, 0xEB, 0x45, 0xA1, 0x8A,
0x86, 0x44, 0x43, 0xB6, 0xC8, 0x44, 0x4E, 0x19,
0xA8, 0x42
};
uint8_t testDataFlj[] =
{
0xFD, 0x1E, 0xA5, 0x22, 0x72, 0x02, 0x5A, 0x02,
0x00, 0x00, 0x81, 0x97, 0x39, 0x3F, 0xF1, 0xF4,
0xC0, 0x3F, 0x27, 0xF1, 0x65, 0x44, 0x53, 0x5C,
0xD3, 0x3F, 0xB5, 0x24, 0xA6, 0x22, 0x72, 0x02,
0x83, 0x01, 0x00, 0x00, 0xFC, 0xE0, 0x44, 0x47,
0xB7, 0x83, 0x35, 0x47, 0xA4, 0xBF, 0xE5, 0xC4,
0xE8, 0xDC, 0xD1, 0x44, 0x5D, 0x5D, 0xE7, 0x44,
0x7D, 0x1B, 0xE8, 0xC1, 0x60, 0x97, 0x57, 0x42,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x5D, 0x86, 0xA6, 0x22, 0x72, 0x02, 0xA5, 0x02,
0x00, 0x00, 0x97, 0x4E, 0xB5, 0x47, 0xC4, 0x2A,
0xB0, 0x47, 0x2D, 0x00, 0x21, 0xC5, 0x8A, 0x85,
0xD1, 0x44, 0x23, 0xFD, 0xC8, 0x44, 0xA1, 0xC4,
0xEA, 0xC1, 0x91, 0x4E, 0x71, 0xC2, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6D, 0xAD,
0xA6, 0x22, 0x72, 0x02, 0xA5, 0x02, 0x00, 0x00,
0xCD, 0x07, 0xD6, 0x47, 0x1D, 0xA4, 0xCE, 0x47,
0x6E, 0x61, 0x33, 0xC5, 0x85, 0x55, 0xD1, 0x44,
0x9C, 0x16, 0xBD, 0x44, 0x36, 0xC0, 0xEB, 0xC1,
0xF0, 0xFF, 0x5B, 0x42, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x78, 0x25, 0x03, 0x00
};
#endif
/************************** Function Prototypes ******************************/
static struct irq_ctrl_desc *intcDescPtr; // General interrupt controller descriptor
static struct timer_desc *logTmPtr;
static MPC *mpcDescPtr;
static PHY_INST *phyInstPtr;
static TMC_INST *tmcInstPtr = NULL;
L2_INST *linkInstPtr;
static bool LinklayerPush2Up(RING_BUFFER *buff){
return Mpc_PushSvcFrame(mpcDescPtr, (void*)buff);
}
static bool LinklayerPopFromUp(RING_BUFFER **buff) {
return Mpc_PopSvcFrame(mpcDescPtr, (void**)buff);
}
/****************************************************************************/
/**
* 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 intcDesc A pointer to INTC descriptor
*
* @return SUCCESS if initialize successful.
* FAILURE if initialization failed.
*
*****************************************************************************/
static int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr)
{
int32_t Status;
struct xil_irq_desc *xil_dev;
Status = irq_ctrl_init(&descPtr, &intc_init_param);
if (Status != SUCCESS)
{
DBG_ERROR("Intc Init FAILED, ErrorCode: %" PRId32 ".\n", Status);
return Status;
}
xil_dev = (struct xil_irq_desc *)(descPtr->extra);
// Clear any pending interrupt flags
uint32_t intrState = XScuGic_CPUReadReg((XScuGic *)(xil_dev->instance), XSCUGIC_INT_ACK_OFFSET);
XScuGic_CPUWriteReg((XScuGic *)(xil_dev->instance), XSCUGIC_EOI_OFFSET, intrState);
/* Initialize physical layer interrupt. */
Status = irq_trigger_level_set(descPtr, PHY_INTR_ID, IRQ_EDGE_RISING);
if (Status != SUCCESS)
{
DBG_ERROR("PHY_INTR trigger level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
return Status;
}
// Set highest interrupt priority
Status = irq_set_priority(descPtr, PHY_INTR_ID, 0x08);
if (Status != SUCCESS)
{
DBG_ERROR("PHY_INTR priority level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
return Status;
}
// Connect the interrupt service routine isr1 to the interrupt controller
Status = irq_register_callback(descPtr, PHY_INTR_ID, &phy_callback_desc);
if (Status != SUCCESS)
{
DBG_ERROR("PHY_INTR register callback FAILED, ErrorCode: %" PRId32 ".\n", Status);
return Status;
}
/* Initialize linklayer layer interrupt. */
Status = irq_trigger_level_set(descPtr, PERIODIC_5MS_INTR_ID, IRQ_EDGE_RISING);
if (Status != SUCCESS)
{
DBG_ERROR("PERIODIC_5MS_INTR_ID trigger level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
return Status;
}
// Set highest interrupt priority
Status = irq_set_priority(descPtr, PERIODIC_5MS_INTR_ID, 0x00);
if (Status != SUCCESS)
{
DBG_ERROR("PERIODIC_5MS_INTR_ID priority level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
return Status;
}
// Connect the interrupt service routine isr1 to the interrupt controller
Status = irq_register_callback(descPtr, PERIODIC_5MS_INTR_ID, &periodicpull_callback_desc);
if (Status != SUCCESS)
{
DBG_ERROR("PHY_INTR register callback FAILED, ErrorCode: %" PRId32 ".\n", Status);
return Status;
}
/* Initialize system bus interrupt. */
Status = irq_trigger_level_set(descPtr, MPC_TX_INTR_ID, IRQ_EDGE_RISING);
if (Status != SUCCESS)
{
DBG_ERROR("PHY_INTR trigger level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
return Status;
}
// Set interrupt priority
Status = irq_set_priority(descPtr, MPC_TX_INTR_ID, 0x10);
if (Status != SUCCESS)
{
DBG_ERROR("PHY_INTR priority level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
return Status;
}
// Connect the interrupt service routine isr1 to the interrupt controller
Status = irq_register_callback(descPtr, MPC_TX_INTR_ID, &mpc_tx_callback_desc);
if (Status != SUCCESS)
{
DBG_ERROR("PHY_INTR register callback FAILED, ErrorCode: %" PRId32 ".\n", Status);
return Status;
}
Status = irq_trigger_level_set(descPtr, MPC_RX_INTR_ID, IRQ_EDGE_RISING);
if (Status != SUCCESS)
{
DBG_ERROR("PHY_INTR trigger level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
return Status;
}
// Set interrupt priority
Status = irq_set_priority(descPtr, MPC_RX_INTR_ID, 0x18);
if (Status != SUCCESS)
{
DBG_ERROR("PHY_INTR priority level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
return Status;
}
// Connect the interrupt service routine isr1 to the interrupt controller
Status = irq_register_callback(descPtr, MPC_RX_INTR_ID, &mpc_rx_callback_desc);
if (Status != SUCCESS)
{
DBG_ERROR("PHY_INTR register callback FAILED, ErrorCode: %" PRId32 ".\n", Status);
return Status;
}
/* Initialize Scu timer interrupt. */
// Connect the interrupt service routine isr1 to the interrupt controller
Status = irq_register_callback(descPtr, SCUTIMER_INTR_ID, &scutm_callback_desc);
if (Status != SUCCESS)
{
DBG_ERROR("PHY_INTR register callback FAILED, ErrorCode: %" PRId32 ".\n", Status);
return Status;
}
// Enable interrupts
irq_enable(descPtr, PHY_INTR_ID);
irq_enable(descPtr, PERIODIC_5MS_INTR_ID);
irq_enable(descPtr, MPC_RX_INTR_ID);
irq_enable(descPtr, MPC_TX_INTR_ID);
// irq_enable(descPtr, SCUTIMER_INTR_ID);
// Enable Exceptions
Status = irq_global_enable(descPtr);
if (Status != SUCCESS)
{
DBG_ERROR("IRQ global enable FAILED, ErrorCode: %" PRId32 ".\n", Status);
return Status;
}
return SUCCESS;
} // SetupInterruptSystem
/****************************************************************************/
/**
* 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 context
*
* @return None.
*
*****************************************************************************/
static void Phy_IntrHandler(void *context)
{
Phy_UpdateState(phyInstPtr);
} // PhyIntr_Handler
/****************************************************************************/
/**
* Handler of periodic 5ms interrupt
*
* @param callBackRef is the linklayer instance pointer.
*
* @return None.
*
*****************************************************************************/
static void PeriodicPull_Handler(void *callBackRef)
{
int32_t Status;
Status = Linklayer_Proc(linkInstPtr);
if (Status != SUCCESS)
{
DBG_ERROR("Link layer runs failed, with error code: %" PRId32 "\n", Status);
_nop_();
}
} // PeriodicPull_Handler
/*****************************************************************************/
/**
* @brief Handler of System Bus RX done interrupt.
*
* @param context
*
* @return None.
*
******************************************************************************/
static void Mpc_RxIntrHandler(void *context)
{
int32_t Status;
Status = Mpc_RxIrqHandler(mpcDescPtr);
if (Status != SUCCESS)
{
DBG_ERROR("Mpc_RxIrqHandler exit with error code %" PRId32 ",\n", Status);
}
}
/*****************************************************************************/
/**
* @brief Handler of System Bus TX done interrupt.
*
* @param context
*
* @return None.
*
******************************************************************************/
static void Mpc_TxIntrHandler(void *context)
{
int32_t Status;
Status = Mpc_TxIrqHandler(mpcDescPtr);
if (Status != SUCCESS)
{
DBG_ERROR("Mpc_TxIrqHandler exit with error code %" PRId32 ",\n", Status);
}
}
/*****************************************************************************/
/**
* @brief Handler of ScuTimer interrupt.
*
* @param context
*
* @return None.
*
******************************************************************************/
static void ScuTimer_IntrHandler(void *context)
{
struct xil_timer_desc *xdesc;
xdesc = (struct xil_timer_desc *)(logTmPtr->extra);
if (XScuTimer_IsExpired((XScuTimer *)xdesc->instance))
{
// Refresh log
Phy_RefreshHwSate(phyInstPtr);
if (TimeCtrl_GetIntCnt(tmcInstPtr) - phyInstPtr->lastLogTime >= PHY_LOG_EXPIRE)
{
Phy_UpdateLogging(phyInstPtr);
}
if (Mpc_IsEnable(mpcDescPtr))
{
if (Mpc_PendRemoteTest(mpcDescPtr) != SUCCESS)
{
DBG_ERROR("Failed to apply remote test.\n");
}
#ifdef APP_EMULATE_DATA
if (L2_GetNodeType(linkInstPtr) == L2_NODE_HEAD)
{
SysMonitor_UpdateSendPayload(testDataFlj, PAYLOAD_LEN_FLJ_TX);
}
else
{
SysMonitor_UpdateSendPayload(testDataLj, PAYLOAD_LEN_LJ_TX);
}
#endif
}
XScuTimer_ClearInterruptStatus((XScuTimer *)xdesc->instance);
}
else
{
DBG_WARNING("UNEXPECTED CALL of ScuTimer_IntrHandler\n");
}
}
/*****************************************************************************/
/**
* @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)
{
int32_t Status;
DBG_PRINT("Application Version: %2d.%2d.%4d.\n", _APP_VER_MAIN, _APP_VER_MINOR, _APP_VER_PATCH);
/* System Monitor Initialize */
Status = SysMonitor_Init();
if (Status == SUCCESS)
{
DBG_PRINT("System monitor Init SUCCESS! \n");
}
else
{
DBG_PRINT("System monitor Init FAILED! \n");
return Status;
}
Status = HARDWARE_initialize();
if (Status == SUCCESS)
{
DBG_PRINT("Hardware Init SUCCESS! \n");
}
else
{
DBG_PRINT("Hardware Init FAILED! \n");
return Status;
}
// Init time controller
Status = TimeCtrl_Init(&tmcInstPtr, &tmcConfig);
if (Status == SUCCESS)
{
DBG_PRINT("TmcCtrl Init SUCCESS! \n");
}
else
{
DBG_PRINT("TmcCtrl Init FAILED! \n");
return Status;
}
/* Physical Layer Initialize */
Status = Phy_Init(&phyInstPtr, &phyConfig);
if (Status == SUCCESS)
{
DBG_PRINT("Physical layer Init SUCCESS! \n");
}
else
{
DBG_PRINT("Physical layer FAILED! \n");
return Status;
}
/* Link Layer Initialize */
linkConfig.phyInstPtr = phyInstPtr;
linkConfig.tmcInstPtr = tmcInstPtr;
Status = Linklayer_Init(&linkInstPtr, &linkConfig);
if (Status == SUCCESS)
{
DBG_PRINT("LinkLayer Init SUCCESS! \n");
}
else
{
DBG_PRINT("Linklayer Init FAILED! \n");
return Status;
}
/* System Bus Initialize */
Status = Mpc_Init(&mpcDescPtr, &mpcConfig);
if (Status != SUCCESS)
{
DBG_ERROR("MPC init FAILED, with error code: %" PRId32 "\n", Status);
return Status;
}
/* System Monitor log timer Initialize */
Status = timer_init(&logTmPtr, &scutimer_init_param);
if (Status != SUCCESS)
{
DBG_ERROR("SCU Timer init FAILED, with error code: %" PRId32 "\n", Status);
return Status;
}
/* interrupts Initialize */
Status = SetupInterruptSystem(intcDescPtr);
if (Status == SUCCESS)
{
DBG_INFO("Interrupt system setup SUCCESS!\n");
}
else
{
DBG_ERROR("Interrupt system setup FAILED, ErrorCode: %" PRId32 ".\n", Status);
return Status;
}
// Start System Monitor logging.
timer_start(logTmPtr);
DBG_PRINT("Physical started...\n");
Phy_Start(phyInstPtr);
while (true)
{
// System bus handler
if (Mpc_IsReqPending(mpcDescPtr))
{
Status = Mpc_HandleCmd(mpcDescPtr);
if (Status != SUCCESS)
{
DBG_ERROR("Mpc_HandleCmd exit with ErrorCode: %" PRId32 ".\n", Status);
}
}
if (Mpc_IsRsqPending(mpcDescPtr) && (!Mpc_IsTxBusy(mpcDescPtr)))
{
usleep(2000);
Status = Mpc_MakeResp(mpcDescPtr);
if (Status != SUCCESS)
{
DBG_ERROR("Mpc_HandleCmd exit with ErrorCode: %" PRId32 ".\n", Status);
}
}
if (Mpc_IsSvcUpPending(mpcDescPtr))
{
Status = Mpc_UploadSvcData(mpcDescPtr);
if (Status != SUCCESS)
{
DBG_ERROR("Mpc_HandleCmd exit with ErrorCode: %" PRId32 ".\n", Status);
}
}
if (Mpc_IsSvcDownPending(mpcDescPtr))
{
RING_BUFFER *msg = NULL;
Mpc_PopSvcFrame(mpcDescPtr, (void**)&msg);
Mpc_PushSvcFrame(mpcDescPtr, (void*)msg);
if (Status != SUCCESS)
{
DBG_ERROR("Mpc_HandleCmd exit with ErrorCode: %" PRId32 ".\n", Status);
}
}
}
} // main
+101
View File
@@ -0,0 +1,101 @@
/*****************************************************************************/
/**
* Description: Global configurations.
*
* 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"
/******** Software Version ********/
#define _APP_VER 0x00010008
#define _APP_VER_MAIN ((_APP_VER & 0xFF000000) >> 24)
#define _APP_VER_MINOR ((_APP_VER & 0x00FF0000) >> 16)
#define _APP_VER_PATCH (_APP_VER & 0x0000FFFF)
/*********** Debug Info Level ************/
// #define _DEBUG_LEVEL 1
// 3 - print all debug info
// 2 - print warnings and errors
// 1 - print only errors
// other - print nothing
#define APP_EMULATE_DATA
#define DATALINK_ENABLE_AUTORECONNECT
#define DATALINK_ENABLE_AUTOTIMESYNC
//#define DATALINK_ENABLE_BERTEST
/************ Hardware Configs ************/
#define CPU_CLK_HZ XPAR_CPU_CORTEXA9_0_CPU_CLK_FREQ_HZ
#define GLOBAL_TIMER_CLK_HZ (CPU_CLK_HZ/2)
#define SCU_TIMER_CLK_HZ (CPU_CLK_HZ/2)
#define FCLK_CLK0_HZ 100000000
/********* Zynq Platform Configs **********/
// SCU Timer (for logging)
#define SCUTIMER_DEVICE_ID XPAR_PS7_SCUTIMER_0_DEVICE_ID
#define SCUTIMER_INTR_ID XPAR_SCUTIMER_INTR
// Physical Layer Configs
#define PHY_DEVICE_ID 0
#define PHY_BASEADDR XPAR_PHYC_BASEADDR
#define PHY_BEAM_SET_PRESET
#define PHY_BEAM_FORMING_ENABLE
// -- Antenna Bram Configs
#define PHY_ANTCONFIG_BRAM_DEVICE_ID XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_DEVICE_ID
// -- Buffers
#define PHY_TXBUFF_BRAM_DEVICE_ID XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_DEVICE_ID
#define PHY_RXBUFF_BRAM_DEVICE_ID XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_DEVICE_ID
// -- Xadc
#define PHY_HW_XADC_DEVICE_ID XPAR_PS7_XADC_0_DEVICE_ID
// -- Interrupt id
#define PHY_INTR_ID XPAR_FABRIC_PHY_IRQ_INTR
#define PERIODIC_5MS_INTR_ID XPAR_FABRIC_PHY_5MS_DELAY_2MS_INTR
// Time Controller Configs
#define TIME_CONTROLLER_BASEADDR XPAR_TMC_BASEADDR
// System Bus Configs
#define MPC_BRAM_ID XPAR_MPC_BRAM_INTERFACE_MPC_BRAM_CTRL_DEVICE_ID
#define MPC_GPIO_ID XPAR_MPC_GPIO_DEVICE_ID
#define MPC_TX_INTR_ID XPAR_FABRIC_MPC_TX_IRQ_INTR
#define MPC_RX_INTR_ID XPAR_FABRIC_MPC_RX_IRQ_INTR
// Global Timer config
#define GLOBAL_TIMER_DEVICE_ID XPAR_GLOBAL_TMR_DEVICE_ID
#define GLOBAL_TIMER_BASEADDR XPAR_GLOBAL_TMR_BASEADDR
#define GLOBAL_TIMER_INTR_ID XPAR_GLOBAL_TMR_INTR
// INTC configis
#define INTC_DEVICE_ID XPAR_SCUGIC_0_DEVICE_ID
// Configuration Check
#if defined(PHY_BEAM_SET_PRESET) && !defined(PHY_BEAM_FORMING_ENABLE)
#define PHY_BEAM_FORMING_ENABLE
#warning To impliment beam scan must enable beam forming...
#endif
#if defined(DATALINK_ENABLE_BERTEST)
#if !defined(DATALINK_ENABLE_AUTOTIMESYNC)
#warning To enbale bit error rate test, auto time-sync should be enabled...
#endif
#endif
#endif
+13
View File
@@ -0,0 +1,13 @@
#ifndef _DEV_PROFILE_H_
#define _DEV_PROFILE_H_
#include "irq.h"
#include "error.h"
#include "../app_config.h"
// device parameters
extern struct irq_init_param intc_init_param;
extern struct timer_init_param scutimer_init_param;
extern struct global_timer_init_param globaltimer_init_param;
#endif /* SRC_DEV_PROFILE_H_ */
@@ -1,6 +1,6 @@
#include "dev_profile.h" #include "dev_profile.h"
#include "global_timer.h" #include "global_timer.h"
#include "../config/app_config.h" #include "../app_config.h"
struct global_timer_init_param globaltimer_init_param = { struct global_timer_init_param globaltimer_init_param = {
.base_addr = GLOBAL_TIMER_BASEADDR, .base_addr = GLOBAL_TIMER_BASEADDR,
+13
View File
@@ -0,0 +1,13 @@
#include "dev_profile.h"
#include "irq.h"
#include "../app_config.h"
#include "drivers/platform/xilinx_irq.h"
struct xil_irq_init_param xil_intc_init_param = {
.type = IRQ_PS
};
struct irq_init_param intc_init_param = {
.irq_ctrl_id = INTC_DEVICE_ID,
.platform_ops = &xil_irq_ops,
.extra = &xil_intc_init_param
};
+17
View File
@@ -0,0 +1,17 @@
#include "dev_profile.h"
#include "timer.h"
#include "../app_config.h"
#include "drivers/platform/xilinx_timer.h"
struct xil_timer_init_param xil_scutimer_init_param = {
.active_tmr = 0,
.type = TIMER_PS
};
struct timer_init_param scutimer_init_param = {
.id = SCUTIMER_DEVICE_ID,
.freq_hz = SCU_TIMER_CLK_HZ,
.ticks_count = (SCU_TIMER_CLK_HZ/2), //update log every 500ms
.platform_ops = &xil_timer_ops,
.extra = &xil_scutimer_init_param
};
+275
View File
@@ -0,0 +1,275 @@
/**
* \file common.c
* \brief Contains Mykonos API common wrapper functions for user hardware platform drivers
*/
/**
* \page Disclaimer Legal Disclaimer
* Copyright 2015-2017 Analog Devices Inc.
* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file.
*
*/
#include <stdio.h>
#include <time.h>
#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include "common.h"
#include "platform_drivers.h"
#include "parameters.h"
ADI_LOGLEVEL CMB_LOGLEVEL = ADIHAL_LOG_NONE;
static uint32_t _desired_time_to_elapse_us = 0;
struct spi_desc *spi_ad_desc;
struct gpio_desc *gpio_ad9371_resetb;
struct gpio_desc *gpio_ad9528_resetb;
struct gpio_desc *gpio_ad9528_sysref_req;
commonErr_t CMB_initPlatform(void)
{
struct spi_init_param spi_param;
int32_t status = COMMONERR_OK;
status |= gpio_get(&gpio_ad9371_resetb, AD9371_RESET_B);
status |= gpio_get(&gpio_ad9528_resetb, AD9528_RESET_B);
status |= gpio_get(&gpio_ad9528_sysref_req, AD9528_SYSREF_REQ);
spi_param.id = 0;
spi_param.mode = SPI_MODE_0;
spi_param.chip_select = AD9371_CS;
spi_param.max_speed_hz = 25000000u;
status |= spi_init(&spi_ad_desc, &spi_param);
if (status != SUCCESS) {
return COMMONERR_FAILED;
}
return COMMONERR_OK;
}
commonErr_t CMB_closeHardware(void)
{
return(COMMONERR_OK);
}
commonErr_t CMB_setGPIO(uint32_t GPIO)
{
return(COMMONERR_OK);
}
commonErr_t CMB_hardReset(uint8_t spiChipSelectIndex)
{
struct gpio_desc *reset_gpio;
switch (spiChipSelectIndex) {
case AD9371_CS:
reset_gpio = gpio_ad9371_resetb;
break;
case AD9528_CS:
reset_gpio = gpio_ad9528_resetb;
break;
default:
return(COMMONERR_FAILED);
}
gpio_direction_output(reset_gpio, 1);
CMB_wait_ms(1);
gpio_direction_output(reset_gpio, 0);
CMB_wait_ms(1);
gpio_direction_output(reset_gpio, 1);
CMB_wait_ms(1);
return(COMMONERR_OK);
}
commonErr_t CMB_setSPIOptions(spiSettings_t *spiSettings)
{
return(COMMONERR_OK);
}
commonErr_t CMB_setSPIChannel(uint16_t chipSelectIndex )
{
return(COMMONERR_OK);
}
commonErr_t CMB_SPIWriteByte(spiSettings_t *spiSettings, uint16_t addr,
uint8_t data)
{
uint8_t buf[3];
spi_ad_desc->chip_select = spiSettings->chipSelectIndex - 1;
buf[0] = (uint8_t) ((addr >> 8) & 0x7f);
buf[1] = (uint8_t) (addr & 0xff);
buf[2] = (uint8_t) data;
spi_write_and_read(spi_ad_desc, buf, 3);
return(COMMONERR_OK);
}
commonErr_t CMB_SPIWriteBytes(spiSettings_t *spiSettings, uint16_t *addr,
uint8_t *data, uint32_t count)
{
uint32_t index;
for (index = 0; index < count; index++)
if (CMB_SPIWriteByte(spiSettings, *(addr + index),
*(data + index)) != COMMONERR_OK)
return(COMMONERR_FAILED);
return(COMMONERR_OK);
}
commonErr_t CMB_SPIReadByte(spiSettings_t *spiSettings, uint16_t addr,
uint8_t *readdata)
{
uint8_t buf[3];
spi_ad_desc->chip_select = spiSettings->chipSelectIndex - 1;
buf[0] = (uint8_t) ((addr >> 8) | 0x80);
buf[1] = (uint8_t) (addr & 0xff);
buf[2] = (uint8_t) 0x00;
spi_write_and_read(spi_ad_desc, buf, 3);
*readdata = buf[2];
return(COMMONERR_OK);
}
commonErr_t CMB_SPIWriteField(spiSettings_t *spiSettings, uint16_t addr,
uint8_t field_val, uint8_t mask, uint8_t start_bit)
{
uint8_t data;
if (CMB_SPIReadByte(spiSettings, addr, &data) != COMMONERR_OK)
return(COMMONERR_FAILED);
data = (data & ~mask) | ((field_val << start_bit) & mask);
if (CMB_SPIWriteByte(spiSettings, addr, data) != COMMONERR_OK)
return(COMMONERR_FAILED);
return(COMMONERR_OK);
}
/* read a field in a single register space (not multibyte fields) */
commonErr_t CMB_SPIReadField(spiSettings_t *spiSettings, uint16_t addr,
uint8_t *field_val, uint8_t mask, uint8_t start_bit)
{
uint8_t data;
if (CMB_SPIReadByte(spiSettings, addr, &data) != COMMONERR_OK)
return(COMMONERR_FAILED);
data = (data & mask) >> start_bit;
*field_val = data;
return(COMMONERR_OK);
}
commonErr_t CMB_writeToLog(ADI_LOGLEVEL level, uint8_t deviceIndex,
uint32_t errorCode, const char *comment)
{
if((CMB_LOGLEVEL & ADIHAL_LOG_ERROR) && (level == ADIHAL_LOG_ERROR)) {
printf("ERROR: %d: %s", (int)errorCode, comment);
} else if((CMB_LOGLEVEL & ADIHAL_LOG_WARNING)
&& (level == ADIHAL_LOG_WARNING)) {
printf("WARNING: %d: %s",(int)errorCode, comment);
} else if((CMB_LOGLEVEL & ADIHAL_LOG_MESSAGE)
&& (level == ADIHAL_LOG_MESSAGE)) {
printf("MESSAGE: %d: %s",(int)errorCode, comment);
} else if(CMB_LOGLEVEL == ADIHAL_LOG_NONE ) {
//printf("MESSAGE: %d: %s",(int)errorCode, comment);
} else {
printf("Undefined Log Level: 0x%X", level);
}
return(COMMONERR_OK);
}
/* if filename null, a default path will be used in logging.c */
commonErr_t CMB_openLog(const char *filename)
{
return(COMMONERR_OK);
}
commonErr_t CMB_closeLog(void)
{
return(COMMONERR_OK);
}
commonErr_t CMB_flushLog(void)
{
return(COMMONERR_OK);
}
commonErr_t CMB_wait_ms(uint32_t time_ms)
{
mdelay(time_ms);
return(COMMONERR_OK);
}
commonErr_t CMB_wait_us(uint32_t time_us)
{
udelay(time_us);
return(COMMONERR_OK);
}
commonErr_t CMB_setTimeout_ms(uint32_t timeOut_ms)
{
#ifdef _XPARAMETERS_PS_H_
_desired_time_to_elapse_us = timeOut_ms * 1000;
#else
_desired_time_to_elapse_us = timeOut_ms * 50; // FIXME
#endif
return(COMMONERR_OK);
}
commonErr_t CMB_setTimeout_us(uint32_t timeOut_us)
{
_desired_time_to_elapse_us = timeOut_us;
return(COMMONERR_OK);
}
commonErr_t CMB_hasTimeoutExpired()
{
udelay(1);
_desired_time_to_elapse_us--;
if (_desired_time_to_elapse_us > 0)
return(COMMONERR_OK);
return(COMMONERR_FAILED);
}
commonErr_t CMB_regRead(uint32_t offset, uint32_t *data)
{
return(COMMONERR_OK);
}
commonErr_t CMB_regWrite(uint32_t offset, uint32_t data)
{
return(COMMONERR_OK);
}
commonErr_t CMB_memRead(uint32_t offset, uint32_t *data, uint32_t len)
{
return(COMMONERR_OK);
}
commonErr_t CMB_memWrite(uint32_t offset, uint32_t *data, uint32_t len)
{
return(COMMONERR_OK);
}
+131
View File
@@ -0,0 +1,131 @@
/**
* \file common.h
* \brief Contains type definitions and prototype declarations for common.c
*/
/**
* \page Disclaimer Legal Disclaimer
* Copyright 2015-2017 Analog Devices Inc.
* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file.
*
*/
#ifndef _HW_COMMON_H_
#define _HW_COMMON_H_
#ifdef __cplusplus
extern "C" {
#endif
/* build project settings include the path to the desired platform folder for correct includes */
#include "stdint.h"
#define THROW_ERROR()
#define SPIARRAYSIZE 1024
/* assuming 3 byte SPI message - integer math enforces floor() */
#define SPIARRAYTRIPSIZE ((SPIARRAYSIZE / 3) * 3)
/*========================================
* Enums and structures
*=======================================*/
/* proposed to increase number of error return values to make unique for each return */
typedef enum
{
ADIERR_OK=0,
ADIERR_INV_PARM,
ADIERR_FAILED
} ADI_ERR;
/*!< \brief COMMON layer error reporting enumerated types */
typedef enum
{
COMMONERR_OK=0,
COMMONERR_FAILED
} commonErr_t;
/* bit 0 is MESSAGE, bit 1 is WARNING, bit 2 is ERROR */
typedef enum
{
ADIHAL_LOG_NONE = 0x0,
ADIHAL_LOG_MESSAGE = 0x1,
ADIHAL_LOG_WARNING = 0x2,
ADIHAL_LOG_ERROR = 0x4,
ADIHAL_LOG_SPI = 0x8,
ADIHAL_LOG_AXI_REG = 0x10,
ADIHAL_LOG_AXI_MEM = 0x20,
ADIHAL_LOG_ALL = 0x3F
} ADI_LOGLEVEL;
/**
* \brief Data structure to hold SPI settings for all system device types
*/
typedef struct
{
uint8_t chipSelectIndex; ///< valid 1~8
uint8_t writeBitPolarity; ///< the level of the write bit of a SPI write instruction word, value is inverted for SPI read operation
uint8_t longInstructionWord; ///< 1 = 16bit instruction word, 0 = 8bit instruction word
uint8_t MSBFirst; ///< 1 = MSBFirst, 0 = LSBFirst
uint8_t CPHA; ///< clock phase, sets which clock edge the data updates (valid 0 or 1)
uint8_t CPOL; ///< clock polarity 0 = clock starts low, 1 = clock starts high
uint8_t enSpiStreaming; ///< Not implemented. SW feature to improve SPI throughput.
uint8_t autoIncAddrUp; ///< Not implemented. For SPI Streaming, set address increment direction. 1= next addr = addr+1, 0:addr = addr-1
uint8_t fourWireMode; ///< 1: Use 4-wire SPI, 0: 3-wire SPI (SDIO pin is bidirectional). NOTE: ADI's FPGA platform always uses 4-wire mode.
uint32_t spiClkFreq_Hz; ///< SPI Clk frequency in Hz (default 25000000), platform will use next lowest frequency that it's baud rate generator can create */
} spiSettings_t;
/* global variable so application layer can set the log level */
extern ADI_LOGLEVEL CMB_LOGLEVEL;
extern struct spi_desc *spi_ad_desc;
extern struct gpio_desc *gpio_ad9371_resetb;
extern struct gpio_desc *gpio_ad9528_resetb;
extern struct gpio_desc *gpio_ad9528_sysref_req;
/* initialize hardware platform */
commonErr_t CMB_initPlatform(void);
/* close hardware pointers */
commonErr_t CMB_closeHardware(void);
/* GPIO function */
commonErr_t CMB_setGPIO(uint32_t GPIO);
/* hardware reset function */
commonErr_t CMB_hardReset(uint8_t spiChipSelectIndex);
/* SPI read/write functions */
commonErr_t CMB_setSPIOptions(spiSettings_t *spiSettings); /* allows the platform HAL to work with devices with various SPI settings */
commonErr_t CMB_setSPIChannel(uint16_t chipSelectIndex ); /* value of 0 deasserts all chip selects */
commonErr_t CMB_SPIWriteByte(spiSettings_t *spiSettings, uint16_t addr, uint8_t data); /* single SPI byte write function */
commonErr_t CMB_SPIWriteBytes(spiSettings_t *spiSettings, uint16_t *addr, uint8_t *data, uint32_t count);
commonErr_t CMB_SPIReadByte (spiSettings_t *spiSettings, uint16_t addr, uint8_t *readdata); /* single SPI byte read function */
commonErr_t CMB_SPIWriteField(spiSettings_t *spiSettings, uint16_t addr, uint8_t field_val, uint8_t mask, uint8_t start_bit); /* write a field in a single register */
commonErr_t CMB_SPIReadField (spiSettings_t *spiSettings, uint16_t addr, uint8_t *field_val, uint8_t mask, uint8_t start_bit); /* read a field in a single register */
/* platform timer functions */
commonErr_t CMB_wait_ms(uint32_t time_ms);
commonErr_t CMB_wait_us(uint32_t time_us);
commonErr_t CMB_setTimeout_ms(uint32_t timeOut_ms);
commonErr_t CMB_setTimeout_us(uint32_t timeOut_us);
commonErr_t CMB_hasTimeoutExpired();
/* platform logging functions */
commonErr_t CMB_openLog(const char *filename);
commonErr_t CMB_closeLog(void);
commonErr_t CMB_writeToLog(ADI_LOGLEVEL level, uint8_t deviceIndex, uint32_t errorCode, const char *comment);
commonErr_t CMB_flushLog(void);
/* platform FPGA AXI register read/write functions */
commonErr_t CMB_regRead(uint32_t offset, uint32_t *data);
commonErr_t CMB_regWrite(uint32_t offset, uint32_t data);
/* platform DDR3 memory read/write functions */
commonErr_t CMB_memRead(uint32_t offset, uint32_t *data, uint32_t len);
commonErr_t CMB_memWrite(uint32_t offset, uint32_t *data, uint32_t len);
#ifdef __cplusplus
}
#endif
#endif
File diff suppressed because it is too large Load Diff
+349
View File
@@ -0,0 +1,349 @@
/*
* headless.h
*
* Created on: 2021��6��8��
* Author: Josh
*/
#ifndef SRC_HEADLESS_H_
#define SRC_HEADLESS_H_
/***************************** Include Files ********************************/
#include <stdlib.h>
#include <stdio.h>
#include "xil_cache.h"
#include "xscugic.h"
//#include "xgpio.h"
#include "common.h"
#include "./mykonos/ad9528.h"
#include "./mykonos/mykonos.h"
#include "./mykonos/Mykonos_M3.h"
#include "./mykonos/mykonos_gpio.h"
#include "myk_ad9528init.h"
#include "myk_init.h"
#include "parameters.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
#define HW_PRINT(...) __asm__("nop")
// #define HW_PRINT(...) printf(__VA_ARGS__)
/************************** Variable Definitions *****************************/
/************************** Function Prototypes ******************************/
/*****************************************************************************/
/*
*
* This function setups ad9528 and ad9371 via spi.
*
* @param None.
*
* @return
* - ADIERR_FAILED if successful,
* - ADIERR_OK if not succesful
*
* @note None.
*
******************************************************************************/
int HARDWARE_initialize();
int HARDWARE_ad9371Config(void);
/*****************************************************************************/
/*
*
* Setup up Axi Gpio, through which ad9371 can be reconfigured. Axi Gpio
* instance and interrupt system initialization are included.
*
* @param None.
*
* @return
* - ADIERR_FAILED if successful,
* - ADIERR_OK if not succesful
*
* @note None.
*
******************************************************************************/
int HW_ad9371DynamicCfgInit(void);
/*****************************************************************************/
/*
*
* Setup up interrupt system, initialize exception handlers.
*
* @param DeviceId is the unique identifier for a device.
* @param GicPtr is a pointer to the XScuGic instance.
*
* @return
* - XST_SUCCESS if successful,
* - XST_FAILURE if not succesful
*
* @note None.
*
******************************************************************************/
int HW_setupIntrSystem(u16 DeviceId, XScuGic * GicPtr);
/*****************************************************************************/
/*
*
* Make the connection between the Int_Id of the interrupt source and the
* associated handler. Set the interrupt priority and trigger type for the
* specified IRQ source..
*
* @param GicPtr is a pointer to the XScuGic instance.
* @param Int_Id contains the ID of the interrupt source and should be
* in the range of 0 to XSCUGIC_MAX_NUM_INTR_INPUTS - 1
* @param Handler to the handler for that interrupt.
* @param CallBackRef is the callback reference, usually the instance
* pointer of the connecting driver.
* @param Priority is the new priority for the IRQ source. 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.
* @param Trigger is the new trigger type for the IRQ source.
* Each bit pair describes the configuration for an INT_ID.
* 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/
*
* @return
* - XST_SUCCESS if successful,
* - XST_FAILURE if not succesful
*
* @note None.
*
******************************************************************************/
int HW_connectIntr(XScuGic *GicPtr,u32 IntrId,Xil_InterruptHandler Handler,
void *CallBackRef, u8 Priority, u8 Trigger);
/*****************************************************************************/
/*
*
* Initialize Analog Device related configuration profile. This is a HARDWARE-
* ASSOTIATED function, which may differ between different board.
*
* @param None.
*
* @return
* - ADIERR_OK if configuration profile exists,
* - ADIERR_FAILED if onfiguration profile does not exist
*
* @note None.
*
******************************************************************************/
int HW_adiCfgProfileInit(void);
/******************************************************************************/
/**
*
* This function conducts AD9528 device configuration initializing procedure.
*
* @param clockAD9528_device is a pointer to the data structure holding
* AD9528 settings, which contains basic AD9528 settings such as
* spi and gpio.
*
* @return
* - ADIERR_OK if successful.
* - ADIERR_FAILED if not successful.
*
* @note None.
*
*******************************************************************************/
int HW_9528Config(ad9528Device_t *clockAD9528_device);
/******************************************************************************/
/**
*
* This function read AD9528 reg508 status, to check whether ad9528 is locked or
* not.
*
* @param clockAD9528_device is a pointer to the data structure holding
* AD9528 settings, which contains basic AD9528 settings.
*
* @return
* - ADIERR_OK if successful.
* - ADIERR_FAILED if not successful.
*
* @note None.
*
*******************************************************************************/
int HW_9528GetLockStatus(ad9528Device_t *device, uint8_t *reg508);
/******************************************************************************/
/**
*
* Conduct AD9371 device configuration initializing procedure.
*
* @param clockAD9528_device is a pointer to the data structure holding
* AD9528 settings, which contains basic AD9528 settings.
* @param mykDevice is ADI hardware layer settings pointer specific to
* a Mykonos instance which contains basic settings such as spi,
* gpio, tx/rx and jesd configurations.
*
* @return
* - ADIERR_OK if successful.
* - ADIERR_FAILED if not successful.
*
* @note None.
*
*******************************************************************************/
int HW_9371Config(ad9528Device_t *clockAD9528_device, mykonosDevice_t *mykDevice);
/******************************************************************************/
/**
*
* Read AD9371's RX framer, ORX framer and TX deframer status, to check jesd204b
* sync status.
*
* @param mykDevice is ADI hardware layer settings pointer specific to
* a Mykonos instance which contains basic settings such as spi,
* gpio, tx/rx and jesd configurations.
* @param framerStatus is the RX framer status byte read
* framerStatus | Description
* -------------|-----------------------------------------------------------------------------
* [7] | SYSREF phase error ? a new SYSREF had different timing than the first that set the LMFC timing.
* [6] | Framer lane FIFO read/write pointer delta has changed. Can help debug issues with deterministic latency.
* [5] | Framer has received the SYSREF and has retimed its LMFC
* [4:2] | Framer ILAS state: 0=CGS, 1= 1st Multframe, 2= 2nd Multiframe, 3= 3rd Multiframe, 4= 4th multiframe, 5= Last multiframe, 6=invalid, 7= ILAS complete
* [1:0] | Framer Tx state: 0=CGS, 1= ILAS, 2 = ADC Data
* @param obsFramerStatus is the ORX framer status byte read
* obsFramerStatus | Description
* ----------------|-----------------------------------------------------------------------------
* [7] | SYSREF phase error ? a new SYSREF had different timing than the first that set the LMFC timing.
* [6] | Framer lane FIFO read/write pointer delta has changed. Can help debug issues with deterministic latency.
* [5] | Framer has received the SYSREF and has retimed its LMFC
* [4:2] | Framer ILAS state: 0=CGS, 1= 1st Multframe, 2= 2nd Multiframe, 3= 3rd Multiframe, 4= 4th multiframe, 5= Last multiframe, 6=invalid, 7= ILAS complete
* [1:0] | Framer Tx state: 0=CGS, 1= ILAS, 2 = ADC Data
* @param deframerStatus is the TX deframer status byte read
* deframerStatus | Bit Name | Description
* ----------------|--------------------------|---------------------------------------------
* [7] | Unused | Unused
* [6] | Deframer IRQ | This bit indicates that the IRQ interrupt was asserted.
* [5] | Deframer SYSREF Received | When this bit is set, it indicates that the SYSREF pulse was received by the deframer IP
* [4] | Deframer Receiver Error | This bit is set when PRBS has received an error.
* [3] | Valid Checksum | This bit is set when the received ILAS checksum is valid.
* [2] | EOF Event | This bit captures the internal status of the framer End of Frame event. Value =1 if framing error during ILAS
* [1] | EOMF Event | This bit captures the internal status of the framer End of Multi-Frame event. Value =1 if framing error during ILAS
* [0] | FS Lost | This bit captures the internal status of the framer Frame Symbol event. Value =1 if framing error during ILAS or user data (invalid replacement characters)
*
* @return
* - ADIERR_OK if successful.
* - ADIERR_FAILED if not successful.
*
* @note None.
*
*******************************************************************************/
int HW_9371CheckJesdStatus(mykonosDevice_t *mykDevice, uint8_t *framerStatus,
uint8_t *obsFramerStatus, uint8_t *deframerStatus);
/******************************************************************************/
/**
*
* This function conducts AD9371/9375 samll RF PLL frequcny change procedure. The
* procedure is performed as follows:
* 1. Move the device into the radio off state.
* 2. Program the new local oscillator (LO) frequency.
* 3. Reset the external channel.(ignored)
* 4. Move the device back into the radio on state.
* 5. Reenable tracking calibrations.(ignored)
*
* @param mykDevice is ADI hardware layer settings pointer specific to
* a Mykonos instance which contains basic settings such as spi,
* gpio, tx/rx and jesd configurations.
* @param freq_Hz is the target frequancy in Hz.
*
* @return None.
*
* @note The procedure is used when a radio frequency (RF) phased-lock loop
* (PLL) change is required with the following conditions:
* - A desire to change the Rx, Tx, and ORx frequencies.
* - The frequency step change is less than 100 MHz.
* - The frequency step does not cross the divide by 2 boundaries outlined
* in AD9371/9375-UG-992-Rev.B-Table 96.
*
*******************************************************************************/
int HW_9371SmallFrequencyChange(mykonosDevice_t *mykDevice, uint64_t freq_Hz);
/******************************************************************************/
/**
*
* This function conducts AD9371/9375 large RF PLL frequcny change procedure. The
* procedure is performed as follows:
* 1. Move the device into the radio off state.
* 2. Program the new local oscillator (LO) frequency.
* 3. Rerun the initialization calibrations.
* 4. Move the device back into the radio on state.
* 5. Reenable tracking calibrations.(ignored)
*
* @param mykDevice is ADI hardware layer settings pointer specific to
* a Mykonos instance which contains basic settings such as spi,
* gpio, tx/rx and jesd configurations.
* @param freq_Hz is the target frequancy in Hz.
*
* @return None.
*
* @note The procedure is used when a radio frequency (RF) phased-lock loop
* (PLL) change is required with the following conditions:
* - A desire to change the Rx, Tx, and ORx frequencies.
* - The frequency step change is more than 100 MHz.
* - The frequency step does cross the divide by 2 boundaries outlined
* in AD9371/9375-UG-992-Rev.B-Table 96.
*
*******************************************************************************/
int HW_9371LargeFrequencyChange(mykonosDevice_t *mykDevice, uint64_t freq_Hz);
/******************************************************************************/
/**
*
* Handles AD9371 TX & RX frequency change axi gpio interruput.
*
* @param CallBackRef is the callback reference, usually the instance
* pointer of the connecting driver.
*
* @return None.
*
* @note None.
*
*******************************************************************************/
void FreqIntrHandler(void *CallbackRef);
/******************************************************************************/
/**
*
* Handles AD9371 Rx gain index change axi gpio interruput.
*
* @param CallBackRef is the callback reference, usually the instance
* pointer of the connecting driver.
*
* @return None.
*
* @note None.
*
*******************************************************************************/
void GainIntrHandler(void *CallbackRef);
/******************************************************************************/
/**
*
* Handles AD9371 Tx attenuation change axi gpio interruput.
*
* @param CallBackRef is the callback reference, usually the instance
* pointer of the connecting driver.
*
* @return None.
*
* @note None.
*
*******************************************************************************/
void AttnIntrHandler(void *CallbackRef);
#endif /* SRC_HEADLESS_H_ */
+189
View File
@@ -0,0 +1,189 @@
///*
// * myk_clock_init.c
// *
// */
//
///**
//* \page Disclaimer Legal Disclaimer
//* Copyright 2015-2017 Analog Devices Inc.
//* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file.
//*
//*/
//
//#ifndef MYK_CLOCK_INIT_C_
//#define MYK_CLOCK_INIT_C_
//#include <stdint.h>
//#include <stdlib.h>
//#include <stddef.h>
//#include "common.h"
//
//#include "ad9528.h"
//#include "t_ad9528.h"
//#include "myk_ad9528init.h"
//#include "parameters.h"
//
//static ad9528pll1Settings_t clockPll1Settings =
//{
// .refA_Frequency_Hz = 30720000,
// .refA_Divider = 1,
// .refA_bufferCtrl = DISABLED,
// .refB_Frequency_Hz = 0,
// .refB_Divider = 1,
// .refB_bufferCtrl = DISABLED,
// .vcxo_Frequency_Hz = 122880000,
// .vcxoBufferCtrl = NEG_SINGLE_ENDED,
// .nDivider = 4,
// .bypassPll1 = 0
//};
//
//static ad9528pll2Settings_t clockPll2Settings =
//{
// .rfDivider = 4,
// .n2Divider = 10,
// .totalNdiv = 30
//};
//
//static ad9528outputSettings_t clockOutputSettings =
//{
// .outPowerDown = 53237, // 0xCFF5
// .outSource = {
// CHANNEL_DIV, CHANNEL_DIV, CHANNEL_DIV, SYSREF,
// CHANNEL_DIV, CHANNEL_DIV, CHANNEL_DIV, CHANNEL_DIV,
// CHANNEL_DIV, CHANNEL_DIV, CHANNEL_DIV, CHANNEL_DIV,
// SYSREF, CHANNEL_DIV},
// .outBufferCtrl = {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
// .outAnalogDelay = {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
// .outDigitalDelay = {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
// .outChannelDiv = {10,10,10,10,10,10,10,10,10,10,10,10,10,10},
// .outFrequency_Hz = {122880000, 122880000, 122880000, 122880000, 122880000, 122880000, 122880000, 122880000, 122880000, 122880000, 122880000, 122880000, 122880000, 122880000}
//};
//
//static ad9528sysrefSettings_t clockSysrefSettings =
//{
// .sysrefRequestMethod = PIN,
// .sysrefSource = INTERNAL,
// .sysrefPinEdgeMode = LEVEL_ACTIVE_HIGH,
// .sysrefPinBufferMode = DISABLED,
// .sysrefPatternMode = NSHOT,
// .sysrefNshotMode = ONE_PULSE,
// .sysrefDivide = 512
//};
//
//static spiSettings_t clockSpiSettings =
//{
// .chipSelectIndex = AD9528_CS, //chip select Index
// .writeBitPolarity = 0, //Write bit polarity
// .longInstructionWord = 1, //16bit instruction word
// .MSBFirst = 1, //MSB first
// .CPHA = 0, //Clock phase
// .CPOL = 0, //Clock polarity
// .enSpiStreaming = 0, //uint8_t enSpiStreaming;
// .autoIncAddrUp = 1, //uint8_t autoIncAddrUp;
// .fourWireMode = 1 //uint8_t fourWireMode;
//};
//
//ad9528Device_t clockAD9528_ =
//{
// &clockSpiSettings,
// &clockPll1Settings,
// &clockPll2Settings,
// &clockOutputSettings,
// &clockSysrefSettings
//};
//
//ad9528Device_t *ad9528Init = &clockAD9528_;
//
//#endif /* MYK_CLOCK_INIT_C_ */
/* AD9528 data structure initialization file */
#include <stdint.h>
#include <stdlib.h>
#include <stddef.h>
#include "common.h"
#include "./mykonos/ad9528.h"
#include "./mykonos/t_ad9528.h"
#include "myk_ad9528init.h"
#include "parameters.h"
static ad9528pll1Settings_t clockPll1Settings = {
.refA_Frequency_Hz = 122880000,
.refA_Divider = 1,
.refA_bufferCtrl = SINGLE_ENDED,
.refB_Frequency_Hz = 0,
.refB_Divider = 1,
.refB_bufferCtrl = DISABLED,
.vcxo_Frequency_Hz = 122880000,
.vcxoBufferCtrl = DIFFERENTIAL,
.nDivider = 1,
.bypassPll1 = 0
};
static ad9528pll2Settings_t clockPll2Settings = {
.rfDivider = 3,
.n2Divider = 10,
.totalNdiv = 30
};
/*******************************************************************
* Output Distribution Settings
* 9369CE02A uses the following clock outputs
* OUT 1: FPGA_REF_CLK
* OUT 2: FPGA_AUX_CLK
* OUT 3: FPGA_SYSREF
* OUT 12: SYSREF_IN
* OUT 13: DEV_CLK_IN
*******************************************************************
*/
static ad9528outputSettings_t clockOutputSettings = {
.outPowerDown = 0x0,
.outSource = {
SYSREF, SYSREF, CHANNEL_DIV, SYSREF,
CHANNEL_DIV, CHANNEL_DIV, SYSREF, SYSREF,
CHANNEL_DIV, CHANNEL_DIV, CHANNEL_DIV, CHANNEL_DIV,
SYSREF , CHANNEL_DIV
},
.outBufferCtrl = {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
.outAnalogDelay = {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
.outDigitalDelay = {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
.outChannelDiv = {10,10,10,10,10,10,10,10,10,10,10,10,10,10},
.outFrequency_Hz = {
122880000, 122880000, 122880000, 122880000,
122880000, 122880000, 122880000, 122880000,
122880000, 122880000, 122880000, 122880000,
122880000, 122880000
}
};
static ad9528sysrefSettings_t clockSysrefSettings = {
.sysrefRequestMethod = SPI,
.sysrefSource = INTERNAL,
.sysrefPinEdgeMode = LEVEL_ACTIVE_HIGH,
.sysrefPinBufferMode = DISABLED,
.sysrefPatternMode = CONTINUOUS,
.sysrefNshotMode = FOUR_PULSES,
.sysrefDivide = 512
};
static spiSettings_t clockSpiSettings = {
.chipSelectIndex = 2, //chip select Index
.writeBitPolarity = 0, //Write bit polarity
.longInstructionWord = 1, //16bit instruction word
.MSBFirst = 1, //MSB first
.CPHA = 0, //Clock phase
.CPOL = 0, //Clock polarity
.enSpiStreaming = 0, //uint8_t enSpiStreaming;
.autoIncAddrUp = 1, //uint8_t autoIncAddrUp;
.fourWireMode = 1 //uint8_t fourWireMode;
};
ad9528Device_t clockAD9528_ = {
&clockSpiSettings,
&clockPll1Settings,
&clockPll2Settings,
&clockOutputSettings,
&clockSysrefSettings
};
ad9528Device_t *ad9528Init = &clockAD9528_;
+20
View File
@@ -0,0 +1,20 @@
/*
* myk_clock_init.h
*
*/
/**
* \page Disclaimer Legal Disclaimer
* Copyright 2015-2017 Analog Devices Inc.
* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file.
*
*/
#ifndef MYK_CLOCK_INIT_H_
#define MYK_CLOCK_INIT_H_
#include "./mykonos/ad9528.h"
extern ad9528Device_t *ad9528Init;
#endif /* MYK_CLOCK_INIT_H_ */
+558
View File
@@ -0,0 +1,558 @@
/**
* \file myk_init.c
*
* \brief Contains init setting structure declarations for the _instance API
*
* The top level structure mykonosDevice_t mykDevice uses keyword
* extern to allow the application layer main() to have visibility
* to these settings.
*
* All data structures required for operation have been initialized with values which reflect
* these settings:
*
* Device Clock = $122.88$ Mhz
* Rx enabled channels = $2$
* Tx enabled channels = $2$
*
* Mykonos Framer:
* Lane Rate = $4915.2$ Mbs
* L = $2$
* K = $32$
* M = $4$
* F = $4$
*
* Mykonos Deframer:
* Lane Rate = $4915.2$ Mbs
* L = $2$
* K = $32$
* M = $4$
* F = $4$
*
* Mykonos Observation framer:
* Lane Rate = $4915.2$ Mbs
* L = $2$
* K = $32$
* M = $4$
* F = $4$
*
* Using these profiles:
* $Rx 100Mhz, IQrate 122.88Mhz, Dec5$
* $Tx 100/100Mhz, IQrate 122.88Mhz, Dec5$
* $ORX 100Mhz, IQrate 122.88Mhz, Dec5$
* $SRx 20Mhz, IQrate 30.72Mhz, Dec5$
*
*/
/**
* \page Disclaimer Legal Disclaimer
* Copyright 2015-2017 Analog Devices Inc.
* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file.
*
*/
#include <stddef.h>
#include "./mykonos/t_mykonos.h"
#include "myk_init.h"
#include "parameters.h"
#include "./mykonos/mykonos_gpio.h"
static int16_t txFirCoefs[] = {-94,-26,282,177,-438,-368,756,732,-1170,-1337,1758,2479,-2648,-5088,4064,16760,16759,4110,-4881,-2247,2888,1917,-1440,-1296,745,828,-358,-474,164,298,-16,-94};
static mykonosFir_t txFir =
{
6, /* Filter gain in dB*/
32, /* Number of coefficients in the FIR filter*/
&txFirCoefs[0] /* A pointer to an array of filter coefficients*/
};
static int16_t rxFirCoefs[] = {-20,6,66,22,-128,-54,240,126,-402,-248,634,444,-956,-756,1400,1244,-2028,-2050,2978,3538,-4646,-7046,9536,30880,30880,9536,-7046,-4646,3538,2978,-2050,-2028,1244,1400,-756,-956,444,634,-248,-402,126,240,-54,-128,22,66,6,-20};
static mykonosFir_t rxFir =
{
-6, /* Filter gain in dB*/
48, /* Number of coefficients in the FIR filter*/
&rxFirCoefs[0] /* A pointer to an array of filter coefficients*/
};
static int16_t obsrxFirCoefs[] = {-14,-19,44,41,-89,-95,175,178,-303,-317,499,527,-779,-843,1184,1317,-1781,-2059,2760,3350,-4962,-7433,9822,32154,32154,9822,-7433,-4962,3350,2760,-2059,-1781,1317,1184,-843,-779,527,499,-317,-303,178,175,-95,-89,41,44,-19,-14};
static mykonosFir_t obsrxFir =
{
-6, /* Filter gain in dB*/
48, /* Number of coefficients in the FIR filter*/
&obsrxFirCoefs[0]/* A pointer to an array of filter coefficients*/
};
static int16_t snifferFirCoefs[] = {-1,-5,-14,-23,-16,24,92,137,80,-120,-378,-471,-174,507,1174,1183,98,-1771,-3216,-2641,942,7027,13533,17738,17738,13533,7027,942,-2641,-3216,-1771,98,1183,1174,507,-174,-471,-378,-120,80,137,92,24,-16,-23,-14,-5,-1};
static mykonosFir_t snifferRxFir=
{
-6, /* Filter gain in dB*/
48, /* Number of coefficients in the FIR filter*/
&snifferFirCoefs[0]/* A pointer to an array of filter coefficients*/
};
static mykonosJesd204bFramerConfig_t rxFramer =
{
0, /* JESD204B Configuration Bank ID -extension to Device ID (Valid 0..15)*/
0, /* JESD204B Configuration Device ID - link identification number. (Valid 0..255)*/
0, /* JESD204B Configuration starting Lane ID. If more than one lane used, each lane will increment from the Lane0 ID. (Valid 0..31)*/
4, /* number of ADCs (0, 2, or 4) - 2 ADCs per receive chain*/
32, /* number of frames in a multiframe (default=32), F*K must be a multiple of 4. (F=2*M/numberOfLanes)*/
0, /* scrambling off if framerScramble= 0, if framerScramble>0 scramble is enabled.*/
1, /* 0=use internal SYSREF, 1= use external SYSREF*/
0x03, /* serializerLanesEnabled - bit per lane, [0] = Lane0 enabled, [1] = Lane1 enabled*/
0xE4, /* serializerLaneCrossbar*/
22, /* serializerAmplitude - default 22 (valid (0-31)*/
4, /* preEmphasis - < default 4 (valid 0 - 7)*/
0, /* invertLanePolarity - default 0 ([0] will invert lane [0], bit1 will invert lane1)*/
0, /* lmfcOffset - LMFC_Offset offset value for deterministic latency setting*/
0, /* Flag for determining if SYSREF on relink should be set. Where, if > 0 = set, 0 = not set*/
0, /* Flag for determining if auto channel select for the xbar should be set. Where, if > 0 = set, '0' = not set*/
0, /* Selects SYNCb input source. Where, 0 = use RXSYNCB for this framer, 1 = use OBSRX_SYNCB for this framer*/
0, /* Flag for determining if CMOS mode for RX Sync signal is used. Where, if > 0 = CMOS, '0' = LVDS*/
0, /* Selects framer bit repeat or oversampling mode for lane rate matching. Where, 0 = bitRepeat mode (changes effective lanerate), 1 = overSample (maintains same lane rate between ObsRx framer and Rx framer and oversamples the ADC samples)*/
0 /* Flag for determining if API will calculate the appropriate settings for framer lane outputs to physical lanes. Where, if '0' = API will set automatic lane crossbar, '1' = set to manual mode and the value in serializerLaneCrossbar will be used*/
};
static mykonosJesd204bFramerConfig_t obsRxFramer =
{
0, /* JESD204B Configuration Bank ID -extension to Device ID (Valid 0..15)*/
0, /* JESD204B Configuration Device ID - link identification number. (Valid 0..255)*/
0, /* JESD204B Configuration starting Lane ID. If more than one lane used, each lane will increment from the Lane0 ID. (Valid 0..31)*/
2, /* number of ADCs (0, 2, or 4) - 2 ADCs per receive chain*/
32, /* number of frames in a multiframe (default=32), F*K must be a multiple of 4. (F=2*M/numberOfLanes)*/
0, /* scrambling off if framerScramble= 0, if framerScramble>0 scramble is enabled.*/
1, /* 0=use internal SYSREF, 1= use external SYSREF*/
0x04, /* serializerLanesEnabled - bit per lane, [0] = Lane0 enabled, [1] = Lane1 enabled*/
0xE4, /* Lane crossbar to map framer lane outputs to physical lanes*/
22, /* serializerAmplitude - default 22 (valid (0-31)*/
4, /* preEmphasis - < default 4 (valid 0 - 7)*/
0, /* invertLanePolarity - default 0 ([0] will invert lane [0], bit1 will invert lane1)*/
0, /* lmfcOffset - LMFC_Offset offset value for deterministic latency setting*/
0, /* Flag for determining if SYSREF on relink should be set. Where, if > 0 = set, 0 = not set*/
0, /* Flag for determining if auto channel select for the xbar should be set. Where, if > 0 = set, '0' = not set*/
1, /* Selects SYNCb input source. Where, 0 = use RXSYNCB for this framer, 1 = use OBSRX_SYNCB for this framer*/
0, /* Flag for determining if CMOS mode for RX Sync signal is used. Where, if > 0 = CMOS, '0' = LVDS*/
0, /* Selects framer bit repeat or oversampling mode for lane rate matching. Where, 0 = bitRepeat mode (changes effective lanerate), 1 = overSample (maintains same lane rate between ObsRx framer and Rx framer and oversamples the ADC samples)*/
0 /* Flag for determining if API will calculate the appropriate settings for framer lane outputs to physical lanes. Where, if '0' = API will set automatic lane crossbar, '1' = set to manual mode and the value in serializerLaneCrossbar will be used*/
};
static mykonosJesd204bDeframerConfig_t deframer =
{
0, /* bankId extension to Device ID (Valid 0..15)*/
0, /* deviceId link identification number. (Valid 0..255)*/
0, /* lane0Id Lane0 ID. (Valid 0..31)*/
4, /* M number of DACss (0, 2, or 4) - 2 DACs per transmit chain */
32, /* K #frames in a multiframe (default=32), F*K=multiple of 4. (F=2*M/numberOfLanes)*/
0, /* scramble scrambling off if scramble= 0.*/
1, /* External SYSREF select. 0 = use internal SYSREF, 1 = external SYSREF*/
0x03, /* Deserializer lane select bit field. Where, [0] = Lane0 enabled, [1] = Lane1 enabled, etc */
0xE4, /* Lane crossbar to map physical lanes to deframer lane inputs [1:0] = Deframer Input 0 Lane section, [3:2] = Deframer Input 1 lane select, etc */
1, /* Equalizer setting. Applied to all deserializer lanes. Range is 0..4*/
0, /* PN inversion per each lane. bit[0] = 1 Invert PN of Lane 0, bit[1] = Invert PN of Lane 1, etc).*/
0, /* LMFC_Offset offset value to adjust deterministic latency. Range is 0..31*/
0, /* Flag for determining if SYSREF on relink should be set. Where, if > 0 = set, '0' = not set*/
0, /* Flag for determining if auto channel select for the xbar should be set. Where, if > 0 = set, '0' = not set*/
0, /* Flag for determining if CMOS mode for TX Sync signal is used. Where, if > 0 = CMOS, '0' = LVDS*/
0 /* Flag for determining if API will calculate the appropriate settings for deframer lane in to physical lanes. Where, if '0' = API will set automatic lane crossbar, '1' = set to manual mode and the value in deserializerLaneCrossbar will be used*/
};
static mykonosRxGainControl_t rxGainControl =
{
MGC, /* Current Rx gain control mode setting*/
255, /* Rx1 Gain Index, can be used in different ways for manual and AGC gain control*/
255, /* Rx2 Gain Index, can be used in different ways for manual and AGC gain control*/
255, /* Max gain index for the currently loaded Rx1 Gain table*/
195, /* Min gain index for the currently loaded Rx1 Gain table*/
255, /* Max gain index for the currently loaded Rx2 Gain table*/
195, /* Min gain index for the currently loaded Rx2 Gain table*/
0, /* Stores Rx1 RSSI value read back from the Mykonos*/
0 /* Stores Rx2 RSSI value read back from the Mykonos*/
};
static mykonosORxGainControl_t orxGainControl =
{
MGC, /* Current ORx gain control mode setting*/
255, /* ORx1 Gain Index, can be used in different ways for manual and AGC gain control*/
255, /* ORx2 Gain Index, can be used in different ways for manual and AGC gain control*/
255, /* Max gain index for the currently loaded ORx Gain table*/
237 /* Min gain index for the currently loaded ORx Gain table*/
};
static mykonosSnifferGainControl_t snifferGainControl =
{
MGC, /* Current Sniffer gain control mode setting*/
255, /* Current Sniffer gain index. Can be used differently for MANUAL Gain control/AGC*/
255, /* Max gain index for the currently loaded Sniffer Gain table*/
203 /* Min gain index for the currently loaded Sniffer Gain table*/
};
static mykonosPeakDetAgcCfg_t rxPeakAgc =
{
0x0C, /* apdHighThresh: */
0x08, /* apdLowThresh */
0xB5, /* hb2HighThresh */
0x80, /* hb2LowThresh */
0x40, /* hb2VeryLowThresh */
0x06, /* apdHighThreshExceededCnt */
0x04, /* apdLowThreshExceededCnt */
0x06, /* hb2HighThreshExceededCnt */
0x04, /* hb2LowThreshExceededCnt */
0x04, /* hb2VeryLowThreshExceededCnt */
0x4, /* apdHighGainStepAttack */
0x2, /* apdLowGainStepRecovery */
0x4, /* hb2HighGainStepAttack */
0x2, /* hb2LowGainStepRecovery */
0x4, /* hb2VeryLowGainStepRecovery */
0x1, /* apdFastAttack */
0x1, /* hb2FastAttack */
0x1, /* hb2OverloadDetectEnable */
0x1, /* hb2OverloadDurationCnt */
0x1 /* hb2OverloadThreshCnt */
};
static mykonosPowerMeasAgcCfg_t rxPwrAgc =
{
0x01, /* pmdUpperHighThresh */
0x03, /* pmdUpperLowThresh */
0x0C, /* pmdLowerHighThresh */
0x00, /* pmdLowerLowThresh */
0x4, /* pmdUpperHighGainStepAttack */
0x2, /* pmdUpperLowGainStepAttack */
0x2, /* pmdLowerHighGainStepRecovery */
0x4, /* pmdLowerLowGainStepRecovery */
0x08, /* pmdMeasDuration */
0x02 /* pmdMeasConfig */
};
static mykonosAgcCfg_t rxAgcConfig =
{
255, /* agcRx1MaxGainIndex */
195, /* agcRx1MinGainIndex */
255, /* agcRx2MaxGainIndex */
195, /* agcRx2MinGainIndex: */
255, /* agcObsRxMaxGainIndex */
203, /* agcObsRxMinGainIndex */
1, /* agcObsRxSelect */
1, /* agcPeakThresholdMode */
1, /* agcLowThsPreventGainIncrease */
30720, /* agcGainUpdateCounter */
3, /* agcSlowLoopSettlingDelay */
2, /* agcPeakWaitTime */
1, /* agcResetOnRxEnable */
0, /* agcEnableSyncPulseForGainCounter */
&rxPeakAgc,
&rxPwrAgc
};
static mykonosPeakDetAgcCfg_t obsRxPeakAgc =
{
0x1F, /* apdHighThresh: */
0x16, /* apdLowThresh */
0xB5, /* hb2HighThresh */
0x80, /* hb2LowThresh */
0x40, /* hb2VeryLowThresh */
0x06, /* apdHighThreshExceededCnt */
0x04, /* apdLowThreshExceededCnt */
0x06, /* hb2HighThreshExceededCnt */
0x04, /* hb2LowThreshExceededCnt */
0x04, /* hb2VeryLowThreshExceededCnt */
0x4, /* apdHighGainStepAttack */
0x2, /* apdLowGainStepRecovery */
0x4, /* hb2HighGainStepAttack */
0x2, /* hb2LowGainStepRecovery */
0x4, /* hb2VeryLowGainStepRecovery */
0x1, /* apdFastAttack */
0x1, /* hb2FastAttack */
0x1, /* hb2OverloadDetectEnable */
0x1, /* hb2OverloadDurationCnt */
0x1 /* hb2OverloadThreshCnt */
};
static mykonosPowerMeasAgcCfg_t obsRxPwrAgc =
{
0x01, /* pmdUpperHighThresh */
0x03, /* pmdUpperLowThresh */
0x0C, /* pmdLowerHighThresh */
0x00, /* pmdLowerLowThresh */
0x4, /* pmdUpperHighGainStepAttack */
0x2, /* pmdUpperLowGainStepAttack */
0x2, /* pmdLowerHighGainStepRecovery */
0x4, /* pmdLowerLowGainStepRecovery */
0x08, /* pmdMeasDuration */
0x02 /* pmdMeasConfig */
};
static mykonosAgcCfg_t obsRxAgcConfig =
{
255, /* agcRx1MaxGainIndex */
195, /* agcRx1MinGainIndex */
255, /* agcRx2MaxGainIndex */
195, /* agcRx2MinGainIndex: */
255, /* agcObsRxMaxGainIndex */
203, /* agcObsRxMinGainIndex */
1, /* agcObsRxSelect */
1, /* agcPeakThresholdMode */
1, /* agcLowThsPreventGainIncrease */
30720, /* agcGainUpdateCounter */
3, /* agcSlowLoopSettlingDelay */
2, /* agcPeakWaitTime */
1, /* agcResetOnRxEnable */
0, /* agcEnableSyncPulseForGainCounter */
&obsRxPeakAgc,
&obsRxPwrAgc
};
static mykonosRxProfile_t rxProfile =
{/* Rx 100MHz, IQrate 122.88MSPS, Dec5 */
1, /* The divider used to generate the ADC clock*/
&rxFir, /* Pointer to Rx FIR filter structure*/
2, /* Rx FIR decimation (1,2,4)*/
5, /* Decimation of Dec5 or Dec4 filter (5,4)*/
1, /* If set, and DEC5 filter used, will use a higher rejection DEC5 FIR filter (1=Enabled, 0=Disabled)*/
1, /* RX Half band 1 decimation (1 or 2)*/
122880, /* Rx IQ data rate in kHz*/
100000000, /* The Rx RF passband bandwidth for the profile*/
100000, /* Rx BBF 3dB corner in kHz*/
NULL /* pointer to custom ADC profile*/
};
static mykonosRxProfile_t orxProfile =
{/* ORX 100MHz, IQrate 122.88MSPS, Dec5 */
1, /* The divider used to generate the ADC clock*/
&obsrxFir, /* Pointer to Rx FIR filter structure or NULL*/
2, /* Rx FIR decimation (1,2,4)*/
5, /* Decimation of Dec5 or Dec4 filter (5,4)*/
0, /* If set, and DEC5 filter used, will use a higher rejection DEC5 FIR filter (1=Enabled, 0=Disabled)*/
1, /* RX Half band 1 decimation (1 or 2)*/
122880, /* Rx IQ data rate in kHz*/
100000000, /* The Rx RF passband bandwidth for the profile*/
100000, /* Rx BBF 3dB corner in kHz*/
NULL /* pointer to custom ADC profile*/
};
static mykonosRxProfile_t snifferProfile =
{ /* SRx 20MHz, IQrate 30.72MSPS, Dec5 */
1, /* The divider used to generate the ADC clock*/
&snifferRxFir, /* Pointer to Rx FIR filter structure or NULL*/
4, /* Rx FIR decimation (1,2,4)*/
5, /* Decimation of Dec5 or Dec4 filter (5,4)*/
0, /* If set, and DEC5 filter used, will use a higher rejection DEC5 FIR filter (1=Enabled, 0=Disabled)*/
2, /* RX Half band 1 decimation (1 or 2)*/
30720, /* Rx IQ data rate in kHz*/
10000000, /* The Rx RF passband bandwidth for the profile*/
100000, /* Rx BBF 3dB corner in kHz*/
NULL /* pointer to custom ADC profile*/
};
static mykonosTxProfile_t txProfile =
{ /* Tx 20/100MHz, IQrate 122.88MSPS, Dec5 */
DACDIV_2p5, /* The divider used to generate the DAC clock*/
&txFir, /* Pointer to Tx FIR filter structure*/
2, /* The Tx digital FIR filter interpolation (1,2,4)*/
2, /* Tx Halfband1 filter interpolation (1,2)*/
1, /* Tx Halfband2 filter interpolation (1,2)*/
1, /* TxInputHbInterpolation (1,2)*/
122880, /* Tx IQ data rate in kHz*/
100000000, /* Primary Signal BW*/
100000000, /* The Tx RF passband bandwidth for the profile*/
710539, /* The DAC filter 3dB corner in kHz*/
50000, /* Tx BBF 3dB corner in kHz*/
0 /* Enable DPD, only valid for AD9373*/
};
static mykonosDigClocks_t mykonosClocks =
{
122880, /* CLKPLL and device reference clock frequency in kHz*/
9830400, /* CLKPLL VCO frequency in kHz*/
VCODIV_2, /* CLKPLL VCO divider*/
4 /* CLKPLL high speed clock divider*/
};
static mykonosRxSettings_t rxSettings =
{
&rxProfile, /* Rx datapath profile, 3dB corner frequencies, and digital filter enables*/
&rxFramer, /* Rx JESD204b framer configuration structure*/
&rxGainControl, /* Rx Gain control settings structure*/
&rxAgcConfig, /* Rx AGC control settings structure*/
RX1_RX2, /* The desired Rx Channels to enable during initialization*/
0, /* Internal LO = 0, external LO*2 = 1*/
2550000000U, /* Rx PLL LO Frequency (internal or external LO)*/
0 /* Flag to choose if complex baseband or real IF data are selected for Rx and ObsRx paths. Where, if > 0 = real IF data, '0' = zero IF (IQ) data*/
};
static mykonosDpdConfig_t dpdConfig =
{
5, /* 1/2^(damping + 8) fraction of power `forgotten' per sample (default: `1/8192' = 5, valid 0 to 15), 0 = infinite damping*/
1, /* number of weights to use for int8_cpx weights weights member of this structure (default = 1)*/
2, /* DPD model version: one of four different generalized polynomial models: 0 = same as R0 silicon, 1-3 are new and the best one depends on the PA (default: 2)*/
1, /* 1 = Update saved model whenever peak Tx digital RMS is within 1dB of historical peak Tx RMS*/
20, /* Determines how much weight the loaded prior model has on DPD modeling (Valid 0 - 32, default 20)*/
0, /* Default off = 0, 1=enables automatic outlier removal during DPD modeling */
512, /* Number of samples to capture (default: 512, valid 64-32768)*/
4096, /* threshold for sample in AM-AM plot outside of 1:1 line to be thrown out. (default: 50% = 8192/2, valid 8192 to 1)*/
0, /* 16th of an ORx sample (16=1sample), (default 0, valid -64 to 64)*/
255, /* Default 255 (-30dBFs=(20Log10(value/8192)), (valid range 1 to 8191)*/
{{64,0},{0,0},{0,0}}/* DPD model error weighting (real/imag valid from -128 to 127)*/
};
static mykonosClgcConfig_t clgcConfig =
{
-2000, /* (value = 100 * dB (valid range -32768 to 32767) - total gain and attenuation from Mykonos Tx1 output to ORx1 input in (dB * 100)*/
-2000, /* (value = 100 * dB (valid range -32768 to 32767) - total gain and attenuation from Mykonos Tx2 output to ORx2 input in (dB * 100)*/
0, /* (valid range 0 - 40dB), no default, depends on PA, Protects PA by making sure Tx1Atten is not reduced below the limit*/
0, /* (valid range 0 - 40dB), no default, depends on PA, Protects PA by making sure Tx2Atten is not reduced below the limit*/
75, /* valid range 1-100, default 75*/
75, /* valid range 1-100, default 45*/
0, /* 0= allow CLGC to run, but Tx1Atten will not be updated. User can still read back power measurements. 1=CLGC runs, and Tx1Atten automatically updated*/
0, /* 0= allow CLGC to run, but Tx2Atten will not be updated. User can still read back power measurements. 1=CLGC runs, and Tx2Atten automatically updated*/
0, /* 16th of an ORx sample (16=1sample), (default 0, valid -64 to 64)*/
255, /* Default 255 (-30dBFs=(20Log10(value/8192)), (valid range 1 to 8191)*/
600, /* Threshold for Tx1 in order to stop tracking, value = 100 * dB, default 6db then value = 600*/
600, /* Threshold for Tx2 in order to stop tracking, value = 100 * dB, default 6db then value = 600*/
0, /* Threshold feature enable for Tx1, 0 = disable, 1 = enable, default = 0*/
0 /* Threshold feature enable for Tx1, 0 = disable, 1 = enable, default = 0*/
};
static mykonosVswrConfig_t vswrConfig =
{
0, /* 16th of an ORx sample (16=1sample), (default 0, valid -64 to 64)*/
255, /* Default 255 (-30dBFs=(20Log10(value/8192)), (valid range 1 to 8191)*/
0, /* 3p3V GPIO pin to use to control VSWR switch for Tx1 (valid 0-11) (output from Mykonos)*/
1, /* 3p3V GPIO pin to use to control VSWR switch for Tx2 (valid 0-11) (output from Mykonos)*/
0, /* 3p3v GPIO pin polarity for forward path of Tx1, opposite used for reflection path (1 = high level, 0 = low level)*/
0, /* 3p3v GPIO pin polarity for forward path of Tx2, opposite used for reflection path (1 = high level, 0 = low level)*/
50, /* Delay for Tx1 after flipping the VSWR switch until measurement is made. In us resolution*/
50 /* Delay for Tx2 after flipping the VSWR switch until measurement is made. In us resolution*/
};
static mykonosTxSettings_t txSettings =
{
&txProfile, /* Tx datapath profile, 3dB corner frequencies, and digital filter enables*/
&deframer, /* Mykonos JESD204b deframer config for the Tx data path*/
TX1_TX2, /* The desired Tx channels to enable during initialization*/
0, /* Internal LO=0, external LO*2 if =1*/
2500000000U, /* Tx PLL LO frequency (internal or external LO)*/
TXATTEN_0P05_DB,/* Initial and current Tx1 Attenuation*/
10000, /* Initial and current Tx1 Attenuation mdB*/
10000, /* Initial and current Tx2 Attenuation mdB*/
NULL, /* DPD,CLGC,VSWR settings. Only valid for AD9373 device, set pointer to NULL otherwise*/
NULL, /* CLGC Config Structure. Only valid for AD9373 device, set pointer to NULL otherwise*/
NULL /* VSWR Config Structure. Only valid for AD9373 device, set pointer to NULL otherwise*/
};
static mykonosObsRxSettings_t obsRxSettings =
{
&orxProfile, /* ORx datapath profile, 3dB corner frequencies, and digital filter enables*/
&orxGainControl,/* ObsRx gain control settings structure*/
&obsRxAgcConfig,/* ORx AGC control settings structure*/
&snifferProfile,/* Sniffer datapath profile, 3dB corner frequencies, and digital filter enables*/
&snifferGainControl,/* SnRx gain control settings structure*/
&obsRxFramer, /* ObsRx JESD204b framer configuration structure */
(MYK_ORX1_ORX2 | MYK_SNRXA_B_C),/* obsRxChannel */
OBSLO_TX_PLL, /* (obsRxLoSource) The Obs Rx mixer can use the Tx Synth(TX_PLL) or Sniffer Synth (SNIFFER_PLL) */
2600000000U, /* SnRx PLL LO frequency in Hz */
0, /* Flag to choose if complex baseband or real IF data are selected for Rx and ObsRx paths. Where if > 0 = real IF data, '0' = complex data*/
NULL, /* Custom Loopback ADC profile to set the bandwidth of the ADC response */
OBS_RXOFF /* Default ObsRx channel to enter when radioOn called */
};
static mykonosArmGpioConfig_t armGpio =
{
1, // useRx2EnablePin; /*!< 0= RX1_ENABLE controls RX1 and RX2, 1 = separate RX1_ENABLE/RX2_ENABLE pins */
1, // useTx2EnablePin; /*!< 0= TX1_ENABLE controls TX1 and TX2, 1 = separate TX1_ENABLE/TX2_ENABLE pins */
1, // txRxPinMode; /*!< 0= ARM command mode, 1 = Pin mode to power up Tx/Rx chains */
0, // orxPinMode; /*!< 0= ARM command mode, 1 = Pin mode to power up ObsRx receiver*/
/*Mykonos ARM input GPIO pins -- Only valid if orxPinMode = 1 */
0, // orxTriggerPin; /*!< Select desired GPIO pin (valid 4-15) */
0, // orxMode2Pin; /*!< Select desired GPIO pin (valid 0-18) */
0, // orxMode1Pin; /*!< Select desired GPIO pin (valid 0-18) */
0, // orxMode0Pin; /*!< Select desired GPIO pin (valid 0-18) */
/* Mykonos ARM output GPIO pins -- always available, even when pin mode not enabled*/
0, // rx1EnableAck; /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
0, // rx2EnableAck; /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
0, // tx1EnableAck; /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
0, // tx2EnableAck; /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
0, // orx1EnableAck; /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
0, // orx2EnableAck; /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
0, // srxEnableAck; /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
0 // txObsSelect; /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
/* When 2Tx are used with only 1 ORx input, this GPIO tells the BBIC which Tx channel is */
/* active for calibrations, so BBIC can route correct RF Tx path into the single ORx input*/
};
static mykonosGpio3v3_t gpio3v3 =
{
0, /*!< Oe per pin, 1=output, 0 = input */
GPIO3V3_BITBANG_MODE, /*!< Mode for GPIO3V3[3:0] */
GPIO3V3_BITBANG_MODE, /*!< Mode for GPIO3V3[7:4] */
GPIO3V3_BITBANG_MODE, /*!< Mode for GPIO3V3[11:8] */
};
static mykonosGpioLowVoltage_t gpio =
{
0,/* Oe per pin, 1=output, 0 = input */
GPIO_MONITOR_MODE,/* Mode for GPIO[3:0] */
GPIO_MONITOR_MODE,/* Mode for GPIO[7:4] */
GPIO_MONITOR_MODE,/* Mode for GPIO[11:8] */
GPIO_MONITOR_MODE,/* Mode for GPIO[15:12] */
GPIO_MONITOR_MODE,/* Mode for GPIO[18:16] */
};
static mykonosAuxIo_t mykonosAuxIo =
{
0, //auxDacEnableMask uint16_t
{0,0,0,0,0,0,0,0,0,0}, //AuxDacValue uint16[10]
{0,0,0,0,0,0,0,0,0,0}, //AuxDacSlope uint8[10]
{0,0,0,0,0,0,0,0,0,0}, //AuxDacVref uint8[10]
&gpio3v3, //pointer to gpio3v3 struct
&gpio, //pointer to gpio1v8 struct
&armGpio
};
static spiSettings_t mykSpiSettings =
{
1, /* chip select index - valid 1~8 */
0, /* the level of the write bit of a SPI write instruction word, value is inverted for SPI read operation */
1, /* 1 = 16-bit instruction word, 0 = 8-bit instruction word */
1, /* 1 = MSBFirst, 0 = LSBFirst */
0, /* clock phase, sets which clock edge the data updates (valid 0 or 1) */
0, /* clock polarity 0 = clock starts low, 1 = clock starts high */
0, /* Not implemented in ADIs platform layer. SW feature to improve SPI throughput */
1, /* Not implemented in ADIs platform layer. For SPI Streaming, set address increment direction. 1= next addr = addr+1, 0:addr=addr-1 */
1 /* 1: Use 4-wire SPI, 0: 3-wire SPI (SDIO pin is bidirectional). NOTE: ADI's FPGA platform always uses 4-wire mode */
};
static mykonosTempSensorConfig_t tempSensor =
{
7, /* 3-bit value that controls the AuxADC decimation factor when used for temp sensor calculations; AuxADC_decimation = 256 * 2^tempDecimation*/
67, /* 8-bit offset that gets added to temp sensor code internally*/
1, /* this bit overrides the factory-calibrated fuse offset and uses the value stored in the offset member*/
15, /* 4-bit code with a resolution of 1°C/LSB, each time a temperature measurement is performed, the device compares the current temperature against the previous value.*/
};
static mykonosTempSensorStatus_t tempStatus =
{
0, /* 16-bit signed temperature value (in deg C) that is read back*/
0, /* If the absolute value of the difference is greater than the value in temperature configuration tempWindow, the windowExceeded flag is set.*/
0, /* when windowExceeded member gets set, this bit is set to 1 if current value is greater than previous value, else reset*/
0, /* when the reading is complete and a valid temperature value stored in tempCode.*/
};
mykonosDevice_t mykDevice =
{
&mykSpiSettings, /* SPI settings data structure pointer */
&rxSettings, /* Rx settings data structure pointer */
&txSettings, /* Tx settings data structure pointer */
&obsRxSettings, /* ObsRx settings data structure pointer */
&mykonosAuxIo, /* Auxiliary IO settings data structure pointer */
&mykonosClocks, /* Holds settings for CLKPLL and reference clock */
0 /* Mykonos initialize function uses this as an output to remember which profile data structure pointers are valid */
};
+24
View File
@@ -0,0 +1,24 @@
/**
* \file myk_init.h
*
* \brief Contains structure definitions for myk_init.c
*
* The top level structure mykonosDevice_t mykDevice uses keyword
* extern to allow the application layer main() to have visibility
* to these settings.
*/
/**
* \page Disclaimer Legal Disclaimer
* Copyright 2015-2017 Analog Devices Inc.
* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file.
*
*/
#ifndef MYK_INIT_H_
#define MYK_INIT_H_
extern mykonosDevice_t mykDevice;
#endif
File diff suppressed because it is too large Load Diff
+13
View File
@@ -0,0 +1,13 @@
/**
SOFTWARE LICENSE AGREEMENT
20180301-AD937X-CTSLA
**/
// Version 5.2.2
#ifndef SRC_MYKONOS_BIN_H_
#define SRC_MYKONOS_BIN_H_
unsigned char firmware_Mykonos_M3_bin[];
unsigned int firmware_Mykonos_M3_bin_len;
#endif
+740
View File
@@ -0,0 +1,740 @@
/**
* \file ad9528.c
* \brief Contains source code for configuring and initializing AD9528 clock device
*/
/**
* \page Disclaimer Legal Disclaimer
* Copyright 2015-2017 Analog Devices Inc.
* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file.
*
*/
#include "ad9528.h"
/**
* \brief Performs a hard reset on the AD9528 DUT
*
* <B>Dependencies</B>
* - device->spiSettings->chipSelectIndex
*
* \param device is structure pointer to the AD9528 data structure containing settings
* \return Returns enum ADI_ERR, ADIERR_OK=pass, !ADIERR_OK=fail
*/
ADI_ERR AD9528_resetDevice(ad9528Device_t *device)
{
/* toggle RESETB on device with matching spi chip select index */
CMB_hardReset(device->spiSettings->chipSelectIndex);
return ADIERR_OK;
}
/**
* \brief Sets the AD9528 device SPI settings (3wire/4wire, MSBFirst, etc).
*
* This function will use the settings in the device->spiSettings structure
* to set SPI stream mode, address auto increment direction, MSBFirst/LSBfirst,
* and 3wire/4wire mode. The AD9528 device always uses SPI MODE 0 (CPHA=0, CPOL=0).
* This function will update your device->spiSettings to set CHPA=0 and CPOL=0 and
* longInstructionWord =1 to use a 16bit instruction word.
*
* <B>Dependencies</B>
* - writes device->spiSettings->CPHA = 0
* - writes device->spiSettings->CPOL = 0
* - writes device->spiSettings->longInstructionWord = 1
*
* - device->spiSettings->MSBFirst
* - device->spiSettings->enSpiStreaming
* - device->spiSettings->autoIncAddrUp
* - device->spiSettings->fourWireMode
*
* \param device is structure pointer to the AD9528 data structure containing settings
*
* \return Returns enum ADI_ERR, ADIERR_OK=pass, !ADIERR_OK=fail
*/
ADI_ERR AD9528_setSpiSettings(ad9528Device_t *device)
{
//device->spiSettings->enSpiStreaming
uint8_t spiReg = 0;
device->spiSettings->CPHA = 0;
device->spiSettings->CPOL = 0;
device->spiSettings->longInstructionWord = 1;
if (device->spiSettings->MSBFirst == 0)
{
spiReg |= 0x42; /* SPI bit is 1=LSB first */
}
if (device->spiSettings->autoIncAddrUp > 0)
{
spiReg |= 0x24;
}
if (device->spiSettings->fourWireMode > 0)
{
spiReg |= 0x18;
}
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_ADI_SPI_CONFIG_A, spiReg);
if (device->spiSettings->enSpiStreaming > 0)
{
/* Allow SPI streaming mode: SPI message ends when chip select deasserts */
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_ADI_SPI_CONFIG_B, 0x00);
}
else
{
/* Force single instruction mode */
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_ADI_SPI_CONFIG_B, 0x80);
}
return ADIERR_OK;
}
/**
* \brief Helper function for ADI transceiver eval boards to init the AD9528 data structure
*
* This function inits the AD9528 device data structure with defaults that
* are known to work with the ADI AD9369 and AD9371 evaluation boards. NOTE: This function will
* modify the contents of the AD9528 device data structure.
*
* <B>Dependencies</B>
* - spi->chipSelectIndex
* - spi
*
* \param device Pointer to the AD9528 device data structure to initialize
* \param vcxoFrequency_Hz The VCXO frequency that is connected to the AD9528
* \param refAFrequency_Hz The reference clock frequency being input into the AD9528 REFCLK A input
* \param outputDeviceClock_Hz Desired output clock frequency to the FPGA and transceiver device
*
* \return Returns enum ADI_ERR, 0=pass, >0 = fail
*/
ADI_ERR AD9528_initDeviceDataStruct(ad9528Device_t *device, uint32_t vcxoFrequency_Hz, uint32_t refAFrequency_Hz, uint32_t outputDeviceClock_Hz)
{
// uint16_t chDiv;
// uint8_t i = 0;
//
// uint32_t pll1PfdFreq_Hz = 0;
// uint8_t pll1Ndiv = 0;
// uint8_t validPll1DivSetting = 0;
// uint8_t refAdiv = 1;
//
//
// uint8_t pll2RfDiv = 3; /* Valid values 3,4,5 */
// uint16_t pll2Ndiv = 1; /* Valid values 1-256 */
// uint32_t pll2InputFreq_Hz = 0;
// uint64_t pll2VcoFreq_Hz = 0;
// uint16_t pll2NdivStart = 0;
// uint8_t validPll2DivSetting = 0;
// uint64_t chDivU64 = 0;
//
// static const uint64_t PLL2_MIN_VCO_FREQ_HZ = 3450000000ULL;
// static const uint64_t PLL2_MAX_VCO_FREQ_HZ = 4025000000ULL;
// /*******************************************************************
// * PLL1 Settings
// *******************************************************************
// */
//
// /* find valid PLL1 Ndiv and REFA div */
// for (pll1Ndiv = 1; pll1Ndiv < 20; pll1Ndiv++)
// {
// pll1PfdFreq_Hz = vcxoFrequency_Hz / pll1Ndiv;
//
// if ((pll1PfdFreq_Hz <= 110000000) && (pll1PfdFreq_Hz >= 1000000) &&
// (pll1PfdFreq_Hz <= refAFrequency_Hz) &&
// (refAFrequency_Hz % pll1PfdFreq_Hz == 0)
// )
// {
// validPll1DivSetting = 1;
// refAdiv = refAFrequency_Hz / pll1PfdFreq_Hz ;
// break;
// }
// }
//
// if (validPll1DivSetting == 0)
// {
// return ADIERR_INV_PARM;
// }
//
// device->pll1Settings->nDivider = pll1Ndiv; //This init function always runs PLL1 at 30.72MHz Pfd rate
// device->pll1Settings->refA_bufferCtrl = DIFFERENTIAL; //DISABLED = 0, SINGLE_ENDED, NEG_SINGLE_ENDED, DIFFERENTIAL
// device->pll1Settings->refA_Divider = refAdiv;
// device->pll1Settings->refA_Frequency_Hz = refAFrequency_Hz;
// device->pll1Settings->refB_bufferCtrl = DISABLED; //DISABLED = 0, SINGLE_ENDED, NEG_SINGLE_ENDED, DIFFERENTIAL
// device->pll1Settings->refB_Divider = 1;
// device->pll1Settings->refB_Frequency_Hz = 0;
// device->pll1Settings->vcxoBufferCtrl = NEG_SINGLE_ENDED; //DISABLED = 0, SINGLE_ENDED, NEG_SINGLE_ENDED, DIFFERENTIAL
// device->pll1Settings->vcxo_Frequency_Hz = vcxoFrequency_Hz;
//
// /*******************************************************************
// * PLL2 Settings
// *******************************************************************
// */
//
// /*******************************************************************
// * Output Distribution Settings
// * 9369CE02A uses the following clock outputs
// * OUT 1: FPGA REFCLK
// * OUT 3: FPGA SYSREF
// * OUT 12: DUT SYSREF
// * OUT 13: DUT REFCLK
// *******************************************************************
// */
//
// /* PLL 2 input clock can be several different things. Currently hard coded by this init funciton to use
// * PLL 1 output (VCXO Frequency) with no scaling
// */
// pll2InputFreq_Hz = device->pll1Settings->vcxo_Frequency_Hz;
// validPll2DivSetting = 0;
//
// /* Sweep PLL2 Divider settings to find something that has a valid integer divide (3,4,5)*/
// for (pll2RfDiv = 3; pll2RfDiv <= 5; pll2RfDiv++)
// {
//
// pll2NdivStart = (PLL2_MIN_VCO_FREQ_HZ / pll2RfDiv / pll2InputFreq_Hz);
// /* find valid PLL2 Ndiv (1-256) */
// for (pll2Ndiv = pll2NdivStart; pll2Ndiv <= 256; pll2Ndiv++)
// {
// pll2VcoFreq_Hz = (pll2InputFreq_Hz * pll2RfDiv * pll2Ndiv);
//
// if (pll2VcoFreq_Hz < PLL2_MIN_VCO_FREQ_HZ)
// {
// /* Continue to next PLL2 N div */
// continue;
// }
// else if (pll2VcoFreq_Hz > PLL2_MAX_VCO_FREQ_HZ)
// {
// /* Break to next PLL2 RF div */
// break;
// }
//
// if (((pll2VcoFreq_Hz / pll2RfDiv) % outputDeviceClock_Hz) == 0)
// {
//
// device->pll2Settings->rfDivider = pll2RfDiv;
// device->pll2Settings->n2Divider = pll2Ndiv;
// device->pll2Settings->totalNdiv = pll2RfDiv * pll2Ndiv;
// chDivU64 = ((pll2VcoFreq_Hz / pll2RfDiv) / outputDeviceClock_Hz);
//
// if ((chDivU64 < 1) || (chDivU64 > 256))
// {
// return ADIERR_INV_PARM;
// }
// else
// {
// chDiv = (uint16_t)(chDivU64);
// }
//
// validPll2DivSetting = 1;
// break;
// }
// }
//
// if (validPll2DivSetting == 1)
// {
// break;
// }
// }
//
// if (validPll2DivSetting == 0)
// {
// return ADIERR_INV_PARM;
// }
//
// device->outputSettings->outPowerDown = (uint16_t)(~0x300A); //enable outputs 13,12,3 and 1
//
// for (i=0; i<14; i++){
// device->outputSettings->outSource[i] = CHANNEL_DIV; //CHANNEL_DIV , PLL1_OUTPUT, SYSREF, INV_PLL1_OUTPUT
// device->outputSettings->outBufferCtrl[i] = LVDS; //LVDS, LVDS_BOOST, HSTL
// device->outputSettings->outChannelDiv[i] = chDiv;
// device->outputSettings->outFrequency_Hz[i] = outputDeviceClock_Hz;
// device->outputSettings->outAnalogDelay[i] = 0;
// device->outputSettings->outDigitalDelay[i] = 0;
// }
//
//
// device->outputSettings->outSource[3] = SYSREF;
// device->outputSettings->outSource[12] = SYSREF;
//
//
// device->sysrefSettings->sysrefDivide = 512; //SYSREF frequency = VCXO / 2 / sysrefDivde
// device->sysrefSettings->sysrefNshotMode = ONE_PULSE; //ONE_PULSE=0, TWO_PULSES=2, FOUR_PULSES=3, SIX_PULSES=4, EIGHT_PULSES=5
// device->sysrefSettings->sysrefPatternMode = NSHOT; //NSHOT=0, CONTINUOUS=1, PRBS=2, STOP=3
// device->sysrefSettings->sysrefPinBufferMode = DISABLED; //DISABLED = 0, SINGLE_ENDED, NEG_SINGLE_ENDED, DIFFERENTIAL
// device->sysrefSettings->sysrefPinEdgeMode = LEVEL_ACTIVE_HIGH; //LEVEL_ACTIVE_HIGH=0, LEVEL_ACTIVE_LOW=1, RISING_EDGE=2, FALLING_EDGE=3
// device->sysrefSettings->sysrefRequestMethod = SPI; //SPI=0,PIN=1
// device->sysrefSettings->sysrefSource = INTERNAL; //EXTERNAL=0, EXT_RESAMPLED=1, INTERNAL=2
return ADIERR_OK;
}
/**
* \brief Debug function to print out summary of AD9528 setup
*
* \param device AD9528 Device data structure describing setup of device.
*
* \return Returns enum ADI_ERR, 0=pass, >0 = fail
***********************************************************************************/
ADI_ERR AD9528_reportClockRates(ad9528Device_t *device)
{
return ADIERR_OK;
} //debug function to help verify data structure is setup correctly.
/**
* \brief Initializes the AD9528 by writing all SPI registers
*
* Initializes the AD9528 for use with the AD9369 transceiver. Designed to work with
* a reference clock of 122.88MHz. Reference clock is expected to be 30.72MHz.
* The output clocks from the AD9528 can run at 122.88M, 153.6M, 184.32M, 245.76M, or 307.2M.
* Typical setup: REFA frequency = 30.72, VCXO = 122.88MHz
* SYNC(SYSREF) pulses output at rate of 120kHz
*
* <B>Dependencies</B>
* - All parameters in device structure
*
* \param device is structure pointer to AD9528 clock device structure
*
* \return Returns enum ADI_ERR, 0=pass, >0 = fail
*/
ADI_ERR AD9528_initialize(ad9528Device_t *device) { //writes all registers to desired values, leaves clock outputs off, SYSREF output disabled.
uint8_t pll2_Adiv=0;
uint8_t pll2_Bdiv=0;
uint8_t reg108=0;
uint8_t reg109=0;
uint8_t i = 0;
uint8_t j = 0;
uint8_t reg508;
ADI_ERR retval = ADIERR_OK;
CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, ADIERR_OK, "\n// AD9528_initialize\n");
//CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_ADI_SPI_CONFIG_A, 0x18); //[4] and [3] =1 enable 4 wire SPI
//CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_ADI_SPI_CONFIG_B, 0x00);
retval = AD9528_setSpiSettings(device);
if (retval != ADIERR_OK)
{
return retval;
}
/**********************************************************************
* Configure PLL1
**********************************************************************
*/
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_REF_A_DIVIDER_LSB,
device->pll1Settings->refA_Divider & 0xFF); //REF A div[7:0]
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_REF_A_DIVIDER_MSB,
(device->pll1Settings->refA_Divider >> 8) & 0x03); //REF A div[9:8]
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_REF_B_DIVIDER_LSB,
device->pll1Settings->refB_Divider & 0xFF); //REF B div[7:0]
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_REF_B_DIVIDER_MSB,
(device->pll1Settings->refB_Divider >> 8) & 0x03); //REF B div[9:8]
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL1_N_DIV_LSB,
device->pll1Settings->nDivider & 0xFF); //PLL1 N div[7:0]
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL1_N_DIV_MSB,
(device->pll1Settings->nDivider >> 8) & 0x03); //PLL1 N div[9:8]
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL1_CHARGEPUMP,
0x0A); //PLL1 Charge Pump control 1
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL1_CP_CTRL2,
0x03); //PLL1 Charge Pump control 2
switch (device->pll1Settings->refA_bufferCtrl){
case DISABLED:
reg108 &= ~0x28;
reg109 &= ~0x01;
break; //clear all REFA enable bits
case SINGLE_ENDED:
reg108 |= 0x08;
reg109 &= ~0x01;
break; //Set REFA receiver enable, clear REFA SE negative input enable
case NEG_SINGLE_ENDED:
reg108 |= 0x08;
reg108 &= ~0x10;
reg109 |= 0x01;
break; //Disable REFA diff receiver, enable REFA receiver and use negative REFA input
case DIFFERENTIAL:
reg108 |= 0x28;
reg109 &= ~0x01;
break;
default:
reg108 |= 0x08;
reg109 &= ~0x01;
break; //default to single ended case
}
switch (device->pll1Settings->refB_bufferCtrl){
case DISABLED:
reg108 &= ~0x50;
reg109 &= ~0x02;
break; //clear all REFB enable bits
case SINGLE_ENDED:
reg108 |= 0x10;
reg109 &= ~0x02;
break; //Set REFB receiver enable, clear REFB SE negative input enable
case NEG_SINGLE_ENDED:
reg108 |= 0x10;
reg108 &= ~0x40;
reg109 |= 0x02;
break; //Disable REFB diff receiver, enable REFB receiver and use negative REFB input
case DIFFERENTIAL:
reg108 |= 0x50;
reg109 &= ~0x02;
break;
default:
reg108 |= 0x10;
reg109 &= ~0x02;
break; //default to single ended case
}
switch (device->pll1Settings->vcxoBufferCtrl){
case DISABLED:
reg108 &= ~0x03;
reg108 |= 0x04;
break; //power down VCXO input
case SINGLE_ENDED:
reg108 &= ~0x07;
break; //Clear VCXO receiver power down, defaults to Single ended mode
case NEG_SINGLE_ENDED:
reg108 &= ~0x07;
reg108 |= 0x02;
break; //Clear VCXO power down, enable Negative single ended mode[1]
case DIFFERENTIAL:
reg108 &= ~0x07;
reg108 |= 0x01;
break; //Clear VCXO power down, enable differential input buffer[0]
default:
reg108 &= ~0x07;
break; //default to positive single ended case
}
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_INPUT_RECEIVERS1,
reg108); //Input receiver settings (single ended or differential clock inputs)
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_INPUT_RECEIVERS2,
reg109); //Input receiver settings
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_INPUT_RECEIVERS3,
0x0A); //Reference selection mode
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL1_FASTLOCK,
0x00); //Disable Fast lock
/**********************************************************************
* Configure PLL2
**********************************************************************
*/
pll2_Bdiv = device->pll2Settings->totalNdiv / 4;
pll2_Adiv = device->pll2Settings->totalNdiv % 4;
if (pll2_Adiv > 3) { //A div valid range (0 to 3)
CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, ADIERR_INV_PARM, "\n// AD9528 PLL2 A Divider out of range (0 to 3)\n");
return ADIERR_INV_PARM;
}
if (pll2_Bdiv < 3 || pll2_Bdiv > 63) {
CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, ADIERR_INV_PARM, "\n// AD9528 PLL2 B Divider out of range (3 to 63)\n");
return ADIERR_INV_PARM;
}
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL2_CHARGEPUMP,
0xE6); //PLL2 Charge Pump[7:0]
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL2_N_DIV,
((pll2_Adiv & 0x3) << 6) | (pll2_Bdiv & 0x3F)); //PLL2 A and B divider
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL2_CTRL, 0x03); //PLL2 control
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL2_VCO_CTRL, 0x01); //Manual VCO CAL
if (device->pll2Settings->rfDivider < 3 || device->pll2Settings->rfDivider > 5) {
CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, ADIERR_INV_PARM, "\n// AD9528 PLL2 RF Divider out of range (3,4, or 5)\n");
return ADIERR_INV_PARM;
}
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL2_VCO_DIV,
device->pll2Settings->rfDivider); //VCO divider
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL2_LF_CTRL1,
0x3A); //PLL2 Loop filter [7:0]
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL2_LF_CTRL2,
0x00); //PLL2 Loop filter [8]
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL2_RDIV,
0x00); //R divider
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL2_REPLICA_CHDIV,
(device->pll2Settings->totalNdiv / device->pll2Settings->rfDivider)
-1 ); //Replica channel divider: Ndivider = rfDivider * R divider
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL2_REPLICA_DIV_PHASE,
0x00); //Replica Channel Divider phase
/**********************************************************************
* Configure Output Distribution
**********************************************************************
*/
for (i=0; i<14; i=i+1){
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_CH_OUT0_CTRL1 + j,
((device->outputSettings->outSource[i] & 0x7) << 5) |
(device->outputSettings->outAnalogDelay[i] & 0x1F));
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_CH_OUT0_CTRL2 + j,
((device->outputSettings->outBufferCtrl[i] & 0x3) << 6) |
(device->outputSettings->outDigitalDelay[i] & 0x3F));
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_CH_OUT0_CHDIV + j,
device->outputSettings->outChannelDiv[i]-1);
j = j+3;
}
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_OUTPUT_SYNC, 0x00); //Sync outputs
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_MASK_SYNC1, 0x00); //Mask SYNC[7:0]
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_MASK_SYNC2, 0x00); //Mask SYNC[13:8]
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_EN_OUTPUT_PATH_SEL1,
0x00); //Bypass SYSREF resample [6:0], bit0:Enable VCXO to feed output distrubution
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_EN_OUTPUT_PATH_SEL2,
0x00); //Bypass SYSREF resample [13:7]
/**********************************************************************
* Configure SYSREF operation
**********************************************************************
*/
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_SYSERF_DIV_LSB,
device->sysrefSettings->sysrefDivide & 0xFF); //SYSREF divider [7:0]
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_SYSERF_DIV_MSB,
(device->sysrefSettings->sysrefDivide >> 8) & 0xFF); //SYSREF divider [7:0]
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_SYSREF_CTRL3,
((device->sysrefSettings->sysrefRequestMethod & 0x1) << 7) |
((device->sysrefSettings->sysrefPinEdgeMode & 0x3) << 5) );
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_SYSREF_CTRL4,
((device->sysrefSettings->sysrefSource & 0x03) << 6) |
((device->sysrefSettings->sysrefPatternMode & 0x3) << 4 ) |
((device->sysrefSettings->sysrefNshotMode & 0x7) << 1) );
if(device->sysrefSettings->sysrefPinBufferMode == DISABLED)
{
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_SYSREF_CTRL5,
0x04); //power down input buffer for external SYSREF
}
else if(device->sysrefSettings->sysrefPinBufferMode == SINGLE_ENDED)
{
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_SYSREF_CTRL5,
0x00); //enable positive singled ended input
}
else if(device->sysrefSettings->sysrefPinBufferMode == NEG_SINGLE_ENDED)
{
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_SYSREF_CTRL5,
0x02); //enable negative singled ended input
}
else if(device->sysrefSettings->sysrefPinBufferMode == DIFFERENTIAL)
{
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_SYSREF_CTRL5,
0x01); //enable differential input buffer
}
else
{
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_SYSREF_CTRL5,
0x04); //power down input buffer for external SYSREF
}
/**********************************************************************
* Power down control
**********************************************************************
*/
if (device->pll1Settings->bypassPll1 > 0)
{
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_POWERDOWN_CTRL,
0x14);// power up PLL2 and output distribution, power down PLL1
}
else
{
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_POWERDOWN_CTRL,
0x10);// power up PLL1, PLL2 and output distribution
}
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_CH_POWERDOWN1,
device->outputSettings->outPowerDown & 0xFF); //power down out[7:0]
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_CH_POWERDOWN2,
((device->outputSettings->outPowerDown >> 8) & 0x3F)); //power down out[13:8]
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_LDO_ENABLES1,
0xFF); //LDO enable per output channel [7:0]
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_LDO_ENABLES2,
0xFF); //LDO enable per output channel [15:8]
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_STATUS0_CTRL,
0x07); //STATUS 0 outputs REFA present
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_STATUS1_CTRL,
0x01); //STATUS 1 outputs PLL1 and PLL2 locked
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_STATUS_OE,
0x0C);// Make Status0 and Status1 outputs after reset.
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_IO_UPDATE,
0x01); //IO update to make all these settings valid in the 9528
CMB_setTimeout_ms(1000);
do{
CMB_SPIReadByte(device->spiSettings, AD9528_ADDR_STATUS_READBACK0, &reg508);
if(CMB_hasTimeoutExpired() > 0)
{
return ADIERR_FAILED;
}
}while((reg508 & 0xA2) != 0xA2);
return ADIERR_OK;
}
/// Send a SPI message to request a SYSREF pulse or continuous SYSREF from the AD9528.
/*******************************************************************************//**
* Requests a SYSREF from the AD9528. It will use whatever settings for SYSREF
* that are current configured in the AD9528. This could be a single pulse,
* multiple pulses, or continuous pulses.
* <B>Dependencies</B>
* - device->spiSettings
* - device->sysrefSettings->sysrefPatternMode
*
* \param device is structure pointer to AD9528 clock device structure
* \param enableSYSREF If NSHOT SYSREF mode, this parameter is ignored. If PRBS/CONTINUOUS SYSREF mode, 1= enable SYSREF, 0= disable SYSREF.
*
* \return Returns enum ADI_ERR, 0=pass, >0 = fail
***********************************************************************************/
ADI_ERR AD9528_requestSysref(ad9528Device_t *device, uint8_t enableSYSREF){
uint8_t _enableSYSREF=0;
if (device->sysrefSettings->sysrefPatternMode == NSHOT || enableSYSREF > 0)
{
_enableSYSREF = 1;
}
else
{
_enableSYSREF = 0;
}
CMB_SPIWriteField(device->spiSettings, AD9528_ADDR_SYSREF_CTRL4, _enableSYSREF, 0x01, 0x00); //Set SPI SYSREF request bit
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_IO_UPDATE, 0x01); //IO update to make all these settings valid in the 9528
return ADIERR_OK;
}
/// Allow changing the 9528 SYSREF frequency and pattern mode(CONTINUOUS, PRBS vs NSHOT mode)
/*******************************************************************************//**
* NOTE: this function will update the device structure with the parameter values passed
* into this function. The device->sysrefSettings->sysrefPatternMode, device->sysrefSettings->sysrefNshotMode,
* and device->sysrefSettings->sysrefDivide values will be updated in the device structure.
*
* <B>Dependencies</B>
* - device->spiSettings
*
* \param device is structure pointer to AD9528 clock device structure
* \param divideFromPll1Out Sets the SYSREF pulse frequency. SYSREF frequency = PLL1_VCXO frequency/divideFromPll1Out
* \param sysrefPatternMode Valid settings: NSHOT, CONTINUOUS, PRBS, STOP
* \param nShotPulses Valid settings: ONE_PULSE=0, TWO_PULSES=2, FOUR_PULSES=3, SIX_PULSES=4, EIGHT_PULSES=5
*
* \return Returns enum ADI_ERR, 0=pass, >0 = fail
***********************************************************************************/
ADI_ERR AD9528_setupSYSREF(ad9528Device_t *device, uint16_t divideFromPll1Out, sysrefPatternMode_t sysrefPatternMode, sysrefNshotMode_t nShotPulses)
{
uint8_t reg403=0;
device->sysrefSettings->sysrefPatternMode = sysrefPatternMode;
device->sysrefSettings->sysrefNshotMode = nShotPulses;
device->sysrefSettings->sysrefDivide = divideFromPll1Out >> 1; //SYSREF frequency is (PLL1)VCXO frequency / 2 / device->sysrefSettings->sysrefDivide
CMB_SPIReadByte(device->spiSettings, AD9528_ADDR_SYSREF_CTRL4, &reg403);
reg403 = reg403 & ~0x01; //clear bit 0 to stop a continuous sysref if it is on.
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_SYSREF_CTRL4, reg403);
reg403 = reg403 & ~0x3E; //clear bits for pattern mode and Nshot mode bitfields
reg403 = reg403 | ((sysrefPatternMode & 0x3) << 4) | ((nShotPulses & 0x7) << 1);
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_SYSREF_CTRL4, reg403); //update internal sysref pattern mode and Nshot mode (number of pulses)
//SYSREF request bit x403[0] is left 0. The next call to AD9528_requestSysref will start the SYSREF
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_IO_UPDATE, 0x01); //IO update to make all these settings valid in the 9528
return ADIERR_OK;
}
/// Update the AD9528 clock outputs that are enabled.
/*******************************************************************************//**
* NOTE: this function will update the device structure with the parameter values passed
* into this function. The device->sysrefSettings->sysrefPatternMode, device->sysrefSettings->sysrefNshotMode,
* and device->sysrefSettings->sysrefDivide values will be updated in the device structure.
*
* <B>Dependencies</B>
* - device->spiSettings
*
* \param device is structure pointer to AD9528 clock device structure
* \param clkEnable Sets which clock outputs are enabled. Bit per clock output. bit0 = out0, etc.
*
* \return Returns enum ADI_ERR, 0=pass, >0 = fail
***********************************************************************************/
ADI_ERR AD9528_enableClockOutputs(ad9528Device_t *device, uint16_t clkEnable)
{ //clkEnable: bit per clock output
device->outputSettings->outPowerDown = ~clkEnable;
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_CH_POWERDOWN1, device->outputSettings->outPowerDown & 0xFF); //power down out[7:0]
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_CH_POWERDOWN2, ((device->outputSettings->outPowerDown >> 8) & 0x3F)); //power down out[13:8]
CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_IO_UPDATE, 0x01); //IO update to make all these settings valid in the 9528
return ADIERR_OK;
}
/// Waits for PLL1 and PLL2 to lock and the REFA and VCXO clocks to be present
/*******************************************************************************//**
* Waits until Reference A clock and VCXO clock input to be detected (present),
* and PLL1 and PLL2 to lock. Will timeout after 1 second and return ADIERR_FAILED.
* If clock are detected and PLLs locked, returns ADIERR_OK.
*
* <B>Dependencies</B>
* - device->spiSettings
*
* \param device is structure pointer to AD9528 clock device structure
*
* \return Returns enum ADI_ERR, 0=pass, >0 = fail
***********************************************************************************/
ADI_ERR AD9528_waitForPllLock(ad9528Device_t *device)
{
uint8_t reg508;
CMB_setTimeout_ms(1000);
do{
CMB_SPIReadByte(device->spiSettings, AD9528_ADDR_STATUS_READBACK0, &reg508);
if(CMB_hasTimeoutExpired() > 0)
{
return ADIERR_FAILED;
}
}while((reg508 & 0x27) != 0x27);
return ADIERR_OK;
}
/// Reads the Lock Status of the PLLs and present detect of the reference clocks
/*******************************************************************************//**
* NOTE: This is a non blocking function that reads a register to see if PLL1
* and PLL2 are locked and Reference clock A and the VCXO input clock are
* detected (present). If the *status parameter is not NULL, the status will
* be returned. If *status is NULL, the error return value will denote if
* the PllStatus is locked or not with ADIERR_OK or ADIERR_FAILED.
*
* <B>Dependencies</B>
* - device->spiSettings
*
* \param device is structure pointer to AD9528 clock device structure
*
* \return Returns enum ADI_ERR, 0=pass, >0 = fail
***********************************************************************************/
ADI_ERR AD9528_readPllStatus(ad9528Device_t *device, uint8_t *status)
{
uint8_t reg508;
//bit5 is VCXO clock detected
//bit2 is REFCLK A detected
//bit1 is PLL2 lock detect
//bit0 is PLL1 lock detect
/* read twice to refresh status bits */
CMB_SPIReadByte(device->spiSettings, AD9528_ADDR_STATUS_READBACK0, &reg508);
CMB_SPIReadByte(device->spiSettings, AD9528_ADDR_STATUS_READBACK0, &reg508);
/* if status is a valid pointer, return the PLL status */
if (status > 0)
{
*status = reg508;
}
/* PLLs 1 and 2 are locked and VCXO and REFA detected if reg508 has bits 5,2,1 and 0 set */
if((reg508 & 0x27) == 0x27)
return ADIERR_OK;
else
return ADIERR_FAILED;
}
+44
View File
@@ -0,0 +1,44 @@
/**
* \file ad9528.h
* \brief Contains function declarations and ad9528Device_t structure typedef for ad9528.c
*/
/**
* \page Disclaimer Legal Disclaimer
* Copyright 2015-2017 Analog Devices Inc.
* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file.
*
*/
#ifndef _AD9528_LIB_H_
#define _AD9528_LIB_H_
#include <stdint.h>
#include "../common.h"
#include "t_ad9528.h"
#ifdef __cplusplus
extern "C" {
#endif
#define CLEMENTE_TDD_AD9528_CLKOUT_INDEX 13
//Helper function to setup the 9528 device data structure specifically for the ADI transceiver evaluation cards
ADI_ERR AD9528_initDeviceDataStruct(ad9528Device_t *device, uint32_t vcxoFrequency_Hz, uint32_t refAFrequency_Hz, uint32_t outputDeviceClock_Hz);
ADI_ERR AD9528_reportClockRates(ad9528Device_t *device); //debug function to help verify data structure is setup correctly.
//AD9528 API functions
ADI_ERR AD9528_resetDevice(ad9528Device_t *device);
ADI_ERR AD9528_setSpiSettings(ad9528Device_t *device);
ADI_ERR AD9528_initialize(ad9528Device_t *device); //writes all registers to desired values, leaves clock outputs off.
ADI_ERR AD9528_waitForPllLock(ad9528Device_t *device);
ADI_ERR AD9528_readPllStatus(ad9528Device_t *device, uint8_t *status);
ADI_ERR AD9528_enableClockOutputs(ad9528Device_t *device, uint16_t clkEnable); //clkEnable: bit per clock output
ADI_ERR AD9528_setupSYSREF(ad9528Device_t *device, uint16_t divideFromPll1Out, sysrefPatternMode_t sysrefPatternMode, sysrefNshotMode_t nShotPulses);
ADI_ERR AD9528_requestSysref(ad9528Device_t *device, uint8_t enableSYSREF);
#ifdef __cplusplus
}
#endif
#endif
File diff suppressed because it is too large Load Diff
+277
View File
@@ -0,0 +1,277 @@
/*!
* \file mykonos.h
* \brief Contains macro definitions and function prototypes for mykonos.c
*
* Mykonos API version: 1.5.2.3566
*/
/**
* \page Disclaimer Legal Disclaimer
* Copyright 2015-2017 Analog Devices Inc.
* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file.
*
*/
#ifndef _MYKONOS_LIB_H_
#define _MYKONOS_LIB_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "t_mykonos.h"
#include "mykonos_version.h"
#define TX_PROFILE_VALID 0x01
#define RX_PROFILE_VALID 0x02
#define ORX_PROFILE_VALID 0x04
#define SNIFF_PROFILE_VALID 0x08
/*
****************************************************************************
* General Initialization functions
****************************************************************************
*/
mykonosErr_t MYKONOS_resetDevice(mykonosDevice_t *device);
mykonosErr_t MYKONOS_getDeviceRev(mykonosDevice_t *device, uint8_t *revision);
mykonosErr_t MYKONOS_getProductId(mykonosDevice_t *device, uint8_t *productId);
mykonosErr_t MYKONOS_setSpiSettings(mykonosDevice_t *device);
mykonosErr_t MYKONOS_verifyDeviceDataStructure(mykonosDevice_t *device);
mykonosErr_t MYKONOS_verifyProfiles(mykonosDevice_t *device);
mykonosErr_t MYKONOS_initialize(mykonosDevice_t *device);
mykonosErr_t MYKONOS_waitForEvent(mykonosDevice_t *device, waitEvent_t waitEvent, uint32_t timeout_us);
mykonosErr_t MYKONOS_readEventStatus(mykonosDevice_t *device, waitEvent_t waitEvent, uint8_t *eventDone);
mykonosErr_t MYKONOS_getApiVersion (mykonosDevice_t *device, uint32_t *siVer, uint32_t *majorVer, uint32_t *minorVer, uint32_t *buildVer);
/*
*****************************************************************************
* PLL / Synthesizer functions
*****************************************************************************
*/
mykonosErr_t MYKONOS_initDigitalClocks(mykonosDevice_t *device);
mykonosErr_t MYKONOS_setRfPllFrequency(mykonosDevice_t *device, mykonosRfPllName_t pllName, uint64_t rfPllLoFrequency_Hz);
mykonosErr_t MYKONOS_getRfPllFrequency(mykonosDevice_t *device, mykonosRfPllName_t pllName, uint64_t *rfPllLoFrequency_Hz);
mykonosErr_t MYKONOS_checkPllsLockStatus(mykonosDevice_t *device, uint8_t *pllLockStatus);
mykonosErr_t MYKONOS_setRfPllLoopFilter(mykonosDevice_t *device, mykonosRfPllName_t pllName, uint16_t loopBandwidth_kHz, uint8_t stability);
mykonosErr_t MYKONOS_getRfPllLoopFilter(mykonosDevice_t *device, mykonosRfPllName_t pllName, uint16_t *loopBandwidth_kHz, uint8_t *stability);
/*
*****************************************************************************
* ARM Processor Control Functions
*****************************************************************************
*/
mykonosErr_t MYKONOS_initArm(mykonosDevice_t *device);
mykonosErr_t MYKONOS_loadArmFromBinary(mykonosDevice_t *device, uint8_t *binary, uint32_t count);
mykonosErr_t MYKONOS_loadArmConcurrent(mykonosDevice_t *device, uint8_t *binary, uint32_t count);
mykonosErr_t MYKONOS_verifyArmChecksum(mykonosDevice_t *device);
mykonosErr_t MYKONOS_checkArmState(mykonosDevice_t *device, mykonosArmState_t armStateCheck);
mykonosErr_t MYKONOS_getArmVersion(mykonosDevice_t *device, uint8_t *majorVer, uint8_t *minorVer, uint8_t *rcVer, mykonosBuild_t *buildType);
mykonosErr_t MYKONOS_configDpd(mykonosDevice_t *device);
mykonosErr_t MYKONOS_getDpdConfig(mykonosDevice_t *device);
mykonosErr_t MYKONOS_getDpdStatus(mykonosDevice_t *device, mykonosTxChannels_t txChannel, mykonosDpdStatus_t *dpdStatus);
mykonosErr_t MYKONOS_restoreDpdModel(mykonosDevice_t *device, mykonosTxChannels_t txChannel, uint8_t *modelDataBuffer, uint32_t modelNumberBytes);
mykonosErr_t MYKONOS_saveDpdModel(mykonosDevice_t *device, mykonosTxChannels_t txChannel, uint8_t *modelDataBuffer, uint32_t modelNumberBytes);
mykonosErr_t MYKONOS_setDpdActState(mykonosDevice_t *device, mykonosTxChannels_t txChannel, uint8_t actState);
mykonosErr_t MYKONOS_resetDpd(mykonosDevice_t *device, mykonosTxChannels_t txChannel, mykonosDpdResetMode_t reset);
mykonosErr_t MYKONOS_setDpdBypassConfig(mykonosDevice_t *device, mykonosDpdBypassConfig_t *actConfig);
mykonosErr_t MYKONOS_getDpdBypassConfig(mykonosDevice_t *device, mykonosDpdBypassConfig_t *actConfig);
mykonosErr_t MYKONOS_setDpdActuatorCheck(mykonosDevice_t *device, mykonosDpdActuatorCheck_t *actCheck);
mykonosErr_t MYKONOS_getDpdActuatorCheck(mykonosDevice_t *device, mykonosDpdActuatorCheck_t *actCheck);
mykonosErr_t MYKONOS_setClgcAttenTuningConfig(mykonosDevice_t *device, mykonosClgcAttenTuningConfig_t *attRangeCfg);
mykonosErr_t MYKONOS_getClgcAttenTuningConfig(mykonosDevice_t *device, mykonosClgcAttenTuningConfig_t *attRangeCfg);
mykonosErr_t MYKONOS_configClgc(mykonosDevice_t *device);
mykonosErr_t MYKONOS_getClgcConfig(mykonosDevice_t *device);
mykonosErr_t MYKONOS_getClgcStatus(mykonosDevice_t *device, mykonosTxChannels_t txChannel, mykonosClgcStatus_t *clgcStatus);
mykonosErr_t MYKONOS_setClgcGain(mykonosDevice_t *device, mykonosTxChannels_t txChannel, int16_t gain);
mykonosErr_t MYKONOS_configVswr(mykonosDevice_t *device);
mykonosErr_t MYKONOS_getVswrConfig(mykonosDevice_t *device);
mykonosErr_t MYKONOS_getVswrStatus(mykonosDevice_t *device, mykonosTxChannels_t txChannel, mykonosVswrStatus_t *vswrStatus);
mykonosErr_t MYKONOS_runInitCals(mykonosDevice_t *device, uint32_t calMask);
mykonosErr_t MYKONOS_waitInitCals(mykonosDevice_t *device, uint32_t timeoutMs, uint8_t *errorFlag, uint8_t *errorCode);
mykonosErr_t MYKONOS_abortInitCals(mykonosDevice_t *device, uint32_t *calsCompleted);
mykonosErr_t MYKONOS_getInitCalStatus(mykonosDevice_t *device, mykonosInitCalStatus_t *initCalStatus);
mykonosErr_t MYKONOS_resetExtTxLolChannel(mykonosDevice_t *device, mykonosTxChannels_t channelSel);
mykonosErr_t MYKONOS_radioOn(mykonosDevice_t *device);
mykonosErr_t MYKONOS_radioOff(mykonosDevice_t *device);
mykonosErr_t MYKONOS_getRadioState(mykonosDevice_t *device, uint32_t *radioStatus);
mykonosErr_t MYKONOS_enableTrackingCals(mykonosDevice_t *device, uint32_t enableMask);
mykonosErr_t MYKONOS_rescheduleTrackingCal(mykonosDevice_t *device, mykonosTrackingCalibrations_t trackingCal);
mykonosErr_t MYKONOS_setAllTrackCalState(mykonosDevice_t *device, uint32_t trackingCalMask);
mykonosErr_t MYKONOS_getAllTrackCalState(mykonosDevice_t *device, uint32_t *trackCals);
mykonosErr_t MYKONOS_setTrackingCalState(mykonosDevice_t *device, mykonosTrackingCalibrations_t trackingCal, uint8_t trackCalState);
mykonosErr_t MYKONOS_getTrackingCalState(mykonosDevice_t *device, mykonosTrackingCalibrations_t trackingCal, uint8_t *trackCalState);
mykonosErr_t MYKONOS_getEnabledTrackingCals(mykonosDevice_t *device, uint32_t *enableMask);
mykonosErr_t MYKONOS_getPendingTrackingCals(mykonosDevice_t *device, uint32_t *pendingCalMask);
mykonosErr_t MYKONOS_getTxLolStatus(mykonosDevice_t *device, mykonosTxChannels_t txChannel, mykonosTxLolStatus_t *txLolStatus);
mykonosErr_t MYKONOS_getTxQecStatus(mykonosDevice_t *device, mykonosTxChannels_t txChannel, mykonosTxQecStatus_t *txQecStatus);
mykonosErr_t MYKONOS_getRxQecStatus(mykonosDevice_t *device, mykonosRxChannels_t rxChannel, mykonosRxQecStatus_t *rxQecStatus);
mykonosErr_t MYKONOS_getOrxQecStatus(mykonosDevice_t *device, mykonosObsRxChannels_t orxChannel, mykonosOrxQecStatus_t *orxQecStatus);
mykonosErr_t MYKONOS_setSnifferChannel(mykonosDevice_t *device, mykonosSnifferChannel_t snifferChannel);
mykonosErr_t MYKONOS_setRadioControlPinMode(mykonosDevice_t *device);
mykonosErr_t MYKONOS_setPathDelay(mykonosDevice_t *device, mykonosPathdelay_t *pathDelay);
mykonosErr_t MYKONOS_getPathDelay(mykonosDevice_t *device, mykonosPathDelaySel_t select, mykonosPathdelay_t *pathDelay);
mykonosErr_t MYKONOS_getDpdErrorCounters(mykonosDevice_t *device, mykonosTxChannels_t txChannel, mykonosDpdErrorCounters_t *dpdErrCnt);
/* Low level ARM functions */
mykonosErr_t MYKONOS_readArmMem(mykonosDevice_t *device, uint32_t address, uint8_t *returnData, uint32_t bytesToRead, uint8_t autoIncrement);
mykonosErr_t MYKONOS_writeArmMem(mykonosDevice_t *device, uint32_t address, uint8_t *data, uint32_t byteCount);
mykonosErr_t MYKONOS_writeArmConfig(mykonosDevice_t *device, uint8_t objectId, uint16_t offset, uint8_t *data, uint8_t byteCount);
mykonosErr_t MYKONOS_readArmConfig(mykonosDevice_t *device, uint8_t objectId, uint16_t offset, uint8_t *data, uint8_t byteCount);
mykonosErr_t MYKONOS_sendArmCommand(mykonosDevice_t *device, uint8_t opCode, uint8_t *extendedData, uint8_t extendedDataNumBytes);
mykonosErr_t MYKONOS_readArmCmdStatus(mykonosDevice_t *device, uint16_t *errorWord, uint16_t *statusWord);
mykonosErr_t MYKONOS_readArmCmdStatusByte(mykonosDevice_t *device, uint8_t opCode, uint8_t *cmdStatByte);
mykonosErr_t MYKONOS_waitArmCmdStatus(mykonosDevice_t *device, uint8_t opCode, uint32_t timeoutMs, uint8_t *cmdStatByte);
mykonosErr_t MYKONOS_writeArmProfile(mykonosDevice_t *device);
mykonosErr_t MYKONOS_loadAdcProfiles(mykonosDevice_t *device);
/*
*****************************************************************************
* JESD204B Datapath Functions
*****************************************************************************
*/
/* Functions to setup the JESD204B IP */
mykonosErr_t MYKONOS_resetDeframer(mykonosDevice_t *device);
mykonosErr_t MYKONOS_setupSerializers(mykonosDevice_t *device);
mykonosErr_t MYKONOS_setupDeserializers(mykonosDevice_t *device);
mykonosErr_t MYKONOS_setupJesd204bFramer(mykonosDevice_t *device);
mykonosErr_t MYKONOS_setupJesd204bObsRxFramer(mykonosDevice_t *device);
mykonosErr_t MYKONOS_setupJesd204bDeframer(mykonosDevice_t *device);
mykonosErr_t MYKONOS_enableRxFramerLink(mykonosDevice_t *device, uint8_t enable);
mykonosErr_t MYKONOS_enableObsRxFramerLink(mykonosDevice_t *device, uint8_t enable);
/* Functions to initialize the JESD204B link */
mykonosErr_t MYKONOS_enableMultichipSync(mykonosDevice_t *device, uint8_t enableMcs, uint8_t *mcsStatus);
mykonosErr_t MYKONOS_enableSysrefToRxFramer(mykonosDevice_t *device, uint8_t enable);
mykonosErr_t MYKONOS_enableSysrefToObsRxFramer(mykonosDevice_t *device, uint8_t enable);
mykonosErr_t MYKONOS_enableSysrefToDeframer(mykonosDevice_t *device, uint8_t enable);
/* Functions to help debug the JESD204B link */
mykonosErr_t MYKONOS_readRxFramerStatus(mykonosDevice_t *device, uint8_t *framerStatus);
mykonosErr_t MYKONOS_readOrxFramerStatus(mykonosDevice_t *device, uint8_t *obsFramerStatus);
mykonosErr_t MYKONOS_readDeframerStatus(mykonosDevice_t *device, uint8_t *deframerStatus);
mykonosErr_t MYKONOS_getDeframerFifoDepth(mykonosDevice_t *device, uint8_t *fifoDepth, uint8_t *readEnLmfcCount);
/* PRBS debug functions */
mykonosErr_t MYKONOS_enableRxFramerPrbs(mykonosDevice_t *device, mykonosPrbsOrder_t polyOrder, uint8_t enable);
mykonosErr_t MYKONOS_enableObsRxFramerPrbs(mykonosDevice_t *device, mykonosPrbsOrder_t polyOrder, uint8_t enable);
mykonosErr_t MYKONOS_rxInjectPrbsError(mykonosDevice_t *device);
mykonosErr_t MYKONOS_obsRxInjectPrbsError(mykonosDevice_t *device);
mykonosErr_t MYKONOS_enableDeframerPrbsChecker(mykonosDevice_t *device, uint8_t lanes, mykonosPrbsOrder_t polyOrder, uint8_t enable);
mykonosErr_t MYKONOS_clearDeframerPrbsCounters(mykonosDevice_t *device);
mykonosErr_t MYKONOS_readDeframerPrbsCounters(mykonosDevice_t *device, uint8_t counterSelect, uint32_t *prbsErrorCount);
/* Miscellaneous debug functions */
mykonosErr_t MYKONOS_jesd204bIlasCheck(mykonosDevice_t *device, uint16_t *mismatch);
mykonosErr_t MYKONOS_setRxFramerDataSource(mykonosDevice_t *device, uint8_t dataSource);
mykonosErr_t MYKONOS_setObsRxFramerDataSource(mykonosDevice_t *device, uint8_t dataSource);
/*
*****************************************************************************
* Shared Data path functions
*****************************************************************************
*/
mykonosErr_t MYKONOS_programFir(mykonosDevice_t *device, mykonosfirName_t filterToProgram, mykonosFir_t *firFilter);
mykonosErr_t MYKONOS_readFir(mykonosDevice_t *device, mykonosfirName_t filterToRead, mykonosFir_t *firFilter);
/*
*****************************************************************************
* Rx Data path functions
*****************************************************************************
*/
mykonosErr_t MYKONOS_programRxGainTable(mykonosDevice_t *device, uint8_t *gainTablePtr, uint8_t numGainIndexesInTable, mykonosGainTable_t rxChannel);
mykonosErr_t MYKONOS_setRx1ManualGain(mykonosDevice_t *device, uint8_t gainIndex);
mykonosErr_t MYKONOS_setRx2ManualGain(mykonosDevice_t *device, uint8_t gainIndex);
mykonosErr_t MYKONOS_getRx1Gain(mykonosDevice_t *device, uint8_t *rx1GainIndex);
mykonosErr_t MYKONOS_getRx2Gain(mykonosDevice_t *device, uint8_t *rx2GainIndex);
mykonosErr_t MYKONOS_setupRxAgc(mykonosDevice_t *device);
mykonosErr_t MYKONOS_resetRxAgc(mykonosDevice_t *device);
mykonosErr_t MYKONOS_setRxAgcMinMaxGainIndex(mykonosDevice_t *device, mykonosRxChannels_t rxChannelSelect, uint8_t maxGainIndex, uint8_t minGainIndex);
mykonosErr_t MYKONOS_setObsRxAgcMinMaxGainIndex(mykonosDevice_t *device, mykonosObsRxChannels_t obsRxChannelSelect, uint8_t maxGainIndex, uint8_t minGainIndex);
mykonosErr_t MYKONOS_setRx1TempGainComp(mykonosDevice_t *device, int16_t rx1TempCompGain_mdB);
mykonosErr_t MYKONOS_getRx1TempGainComp(mykonosDevice_t *device, int16_t *rx1TempCompGain_mdB);
mykonosErr_t MYKONOS_setRx2TempGainComp(mykonosDevice_t *device, int16_t rx2TempCompGain_mdB);
mykonosErr_t MYKONOS_getRx2TempGainComp(mykonosDevice_t *device, int16_t *rx2TempCompGain_mdB);
mykonosErr_t MYKONOS_setObsRxTempGainComp(mykonosDevice_t *device, int16_t obsRxTempCompGain_mdB);
mykonosErr_t MYKONOS_getObsRxTempGainComp(mykonosDevice_t *device, int16_t *obsRxTempCompGain_mdB);
mykonosErr_t MYKONOS_enableRxGainCtrSyncPulse(mykonosDevice_t *device, uint8_t enable);
mykonosErr_t MYKONOS_setRxGainControlMode(mykonosDevice_t *device, mykonosGainMode_t mode);
mykonosErr_t MYKONOS_getRx1DecPower(mykonosDevice_t *device, uint16_t *rx1DecPower_mdBFS);
mykonosErr_t MYKONOS_getRx2DecPower(mykonosDevice_t *device, uint16_t *rx2DecPower_mdBFS);
/*
*****************************************************************************
* Observation Rx Data path functions
*****************************************************************************
*/
mykonosErr_t MYKONOS_setDefaultObsRxPath(mykonosDevice_t *device, mykonosObsRxChannels_t defaultObsRxCh);
mykonosErr_t MYKONOS_setObsRxPathSource(mykonosDevice_t *device, mykonosObsRxChannels_t obsRxCh);
mykonosErr_t MYKONOS_getObsRxPathSource(mykonosDevice_t *device, mykonosObsRxChannels_t *obsRxCh);
mykonosErr_t MYKONOS_setObsRxManualGain(mykonosDevice_t *device, mykonosObsRxChannels_t obsRxCh, uint8_t gainIndex);
mykonosErr_t MYKONOS_getObsRxGain(mykonosDevice_t *device, uint8_t *gainIndex);
mykonosErr_t MYKONOS_setupObsRxAgc(mykonosDevice_t *device);
mykonosErr_t MYKONOS_enableObsRxGainCtrSyncPulse(mykonosDevice_t *device, uint8_t enable);
mykonosErr_t MYKONOS_setObsRxGainControlMode(mykonosDevice_t *device, mykonosGainMode_t mode);
mykonosErr_t MYKONOS_getObsRxDecPower(mykonosDevice_t *device, uint16_t *obsRxDecPower_mdBFS);
/*
*****************************************************************************
* Tx Data path functions
*****************************************************************************
*/
mykonosErr_t MYKONOS_setTx1Attenuation(mykonosDevice_t *device, uint16_t tx1Attenuation_mdB);
mykonosErr_t MYKONOS_setTx2Attenuation(mykonosDevice_t *device, uint16_t tx2Attenuation_mdB);
mykonosErr_t MYKONOS_getTx1Attenuation(mykonosDevice_t *device, uint16_t *tx1Attenuation_mdB);
mykonosErr_t MYKONOS_getTx2Attenuation(mykonosDevice_t *device, uint16_t *tx2Attenuation_mdB);
mykonosErr_t MYKONOS_getTxFilterOverRangeStatus(mykonosDevice_t *device, uint8_t *txFilterStatus);
mykonosErr_t MYKONOS_enableTxNco(mykonosDevice_t *device, uint8_t enable, int32_t tx1ToneFreq_kHz, int32_t tx2ToneFreq_kHz);
/*
*****************************************************************************
* PA Protection Functions
*****************************************************************************
*/
mykonosErr_t MYKONOS_setupPaProtection(mykonosDevice_t *device, uint16_t powerThreshold, uint8_t attenStepSize, uint8_t avgDuration, uint8_t stickyFlagEnable, uint8_t txAttenControlEnable);
mykonosErr_t MYKONOS_enablePaProtection(mykonosDevice_t *device, uint8_t enable);
mykonosErr_t MYKONOS_getDacPower(mykonosDevice_t *device, mykonosTxChannels_t channel, uint16_t *channelPower);
mykonosErr_t MYKONOS_getPaProtectErrorFlagStatus(mykonosDevice_t *device, uint8_t *errorFlagStatus);
mykonosErr_t MYKONOS_clearPaErrorFlag(mykonosDevice_t *device);
/*
*****************************************************************************
* Low level functions and helper functions. BBP should not need to call
*****************************************************************************
*/
const char* getMykonosErrorMessage(mykonosErr_t errorCode);
mykonosErr_t MYKONOS_initSubRegisterTables(mykonosDevice_t *device);
mykonosErr_t MYKONOS_setTxPfirSyncClk(mykonosDevice_t *device); /* Helper function */
mykonosErr_t MYKONOS_setRxPfirSyncClk(mykonosDevice_t *device); /* Helper function */
/*
*****************************************************************************
* Functions to configure DC offsets
*****************************************************************************
*/
mykonosErr_t MYKONOS_setRfDcOffsetCnt(mykonosDevice_t *device, mykonosDcOffsetChannels_t channel, uint16_t measureCount);
mykonosErr_t MYKONOS_getRfDcOffsetCnt(mykonosDevice_t *device, mykonosDcOffsetChannels_t channel, uint16_t *measureCount);
mykonosErr_t MYKONOS_setDigDcOffsetMShift(mykonosDevice_t *device, mykonosDcOffsetChannels_t channel, uint8_t mShift);
mykonosErr_t MYKONOS_getDigDcOffsetMShift(mykonosDevice_t *device, mykonosDcOffsetChannels_t channel, uint8_t *mShift);
mykonosErr_t MYKONOS_setDigDcOffsetEn(mykonosDevice_t *device, uint8_t enableMask);
mykonosErr_t MYKONOS_getDigDcOffsetEn(mykonosDevice_t *device, uint8_t *enableMask);
#ifdef __cplusplus
}
#endif
#endif
+136
View File
@@ -0,0 +1,136 @@
/**
* \file mykonosMmap.c
* \brief Contains the Mykonos memory mapping
*
* Mykonos API version: 1.5.2.3566
*/
/**
* \page Disclaimer Legal Disclaimer
* Copyright 2015-2017 Analog Devices Inc.
* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file.
*
*/
#include <stdint.h>
uint8_t mykonosMmap [] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x13,0x03,0x03,0x13,0x13,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
0x00,0xE4,0xE4,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xA5,0xA5,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x01,0x00,0xE4,0xE4,0x00,0x00,0x00,0x1F,0x00,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9F,0xE0,0x20,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xF5,0x8F,0x0F,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
/*!< Mykonos memory map */
File diff suppressed because it is too large Load Diff
+172
View File
@@ -0,0 +1,172 @@
/*!
* \file mykonos_gpio.h
* \brief Contains macro definitions and function prototypes for mykonos_gpio.c
*
* Mykonos API version: 1.5.2.3566
*/
/**
* \page Disclaimer Legal Disclaimer
* Copyright 2015-2017 Analog Devices Inc.
* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file.
*
*/
#ifndef MYKONOSGPIO_H_
#define MYKONOSGPIO_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "t_mykonos.h"
#include "t_mykonos_gpio.h"
/*
*****************************************************************************
* GPIO functions
*****************************************************************************
*/
/* GPIO CMOS and SPI setting Functions */
mykonosGpioErr_t MYKONOS_setGpioDrv(mykonosDevice_t *device, uint32_t gpioDrv);
mykonosGpioErr_t MYKONOS_getGpioDrv(mykonosDevice_t *device, uint32_t *gpioDrv);
mykonosGpioErr_t MYKONOS_setGpioSlewRate(mykonosDevice_t *device, mykonosGpioSelect_t gpioSelect, mykonosGpioSlewRate_t slewRate);
mykonosGpioErr_t MYKONOS_getGpioSlewRate(mykonosDevice_t *device, mykonosGpioSelect_t gpioSelect, mykonosGpioSlewRate_t *slewRate);
mykonosGpioErr_t MYKONOS_setCmosDrv(mykonosDevice_t *device, mykonosCmosPadDrvStr_t spiDrv);
mykonosGpioErr_t MYKONOS_getCmosDrv(mykonosDevice_t *device, mykonosCmosPadDrvStr_t *spiDrv);
/* Monitor output Functions */
mykonosGpioErr_t MYKONOS_setGpioMonitorOut(mykonosDevice_t *device, uint8_t monitorIndex, uint8_t monitorMask);
mykonosGpioErr_t MYKONOS_getGpioMonitorOut(mykonosDevice_t *device, uint8_t *monitorIndex, uint8_t *monitorMask);
/* RX GPIO Functions */
mykonosGpioErr_t MYKONOS_setRx1GainCtrlPin(mykonosDevice_t *device, uint8_t incStep, uint8_t decStep, mykonosGpioSelect_t rx1GainIncPin, mykonosGpioSelect_t rx1GainDecPin, uint8_t enable);
mykonosGpioErr_t MYKONOS_setRx2GainCtrlPin(mykonosDevice_t *device, uint8_t incStep, uint8_t decStep, mykonosGpioSelect_t rx2GainIncPin, mykonosGpioSelect_t rx2GainDecPin, uint8_t enable);
mykonosGpioErr_t MYKONOS_getRx1GainCtrlPin(mykonosDevice_t *device, uint8_t *incStep, uint8_t *decStep, mykonosGpioSelect_t *rx1GainIncPin, mykonosGpioSelect_t *rx1GainDecPin, uint8_t *enable);
mykonosGpioErr_t MYKONOS_getRx2GainCtrlPin(mykonosDevice_t *device, uint8_t *incStep, uint8_t *decStep, mykonosGpioSelect_t *rx2GainIncPin, mykonosGpioSelect_t *rx2GainDecPin, uint8_t *enable);
mykonosGpioErr_t MYKONOS_setRxHybridGainChangePin(mykonosDevice_t *device, mykonosGpioSelect_t rx1GainChangePin, mykonosGpioSelect_t rx2GainChangePin);
mykonosGpioErr_t MYKONOS_getRxHybridGainChangePin(mykonosDevice_t *device, mykonosGpioSelect_t *rx1GainChangePin, mykonosGpioSelect_t *rx2GainChangePin);
mykonosGpioErr_t MYKONOS_setObsRxHybridGainChangePin(mykonosDevice_t *device, mykonosGpioSelect_t obsRxGainChangePin);
mykonosGpioErr_t MYKONOS_getObsRxHybridGainChangePin(mykonosDevice_t *device, mykonosGpioSelect_t *obsRxGainChangePin);
mykonosGpioErr_t MYKONOS_setRxAgcEnSyncPin(mykonosDevice_t *device, mykonosGpioSelect_t rx1AgcSyncPin, mykonosGpioSelect_t rx2AgcSyncPin);
mykonosGpioErr_t MYKONOS_getRxAgcEnSyncPin(mykonosDevice_t *device, mykonosGpioSelect_t *rx1AgcSyncPin, mykonosGpioSelect_t *rx2AgcSyncPin);
mykonosGpioErr_t MYKONOS_setObsRxAgcEnSyncPin(mykonosDevice_t *device, mykonosGpioSelect_t obsRxAgcSyncPin);
mykonosGpioErr_t MYKONOS_getObsRxAgcEnSyncPin(mykonosDevice_t *device, mykonosGpioSelect_t *obsRxAgcSyncPin);
/* TX GPIO Functions */
mykonosGpioErr_t MYKONOS_setTx1AttenCtrlPin(mykonosDevice_t *device, uint8_t stepSize, mykonosGpioSelect_t tx1AttenIncPin, mykonosGpioSelect_t tx1AttenDecPin, uint8_t enable, uint8_t useTx1ForTx2);
mykonosGpioErr_t MYKONOS_setTx2AttenCtrlPin(mykonosDevice_t *device, uint8_t stepSize, mykonosGpioSelect_t tx2AttenIncPin, mykonosGpioSelect_t tx2AttenDecPin, uint8_t enable);
mykonosGpioErr_t MYKONOS_getTx1AttenCtrlPin(mykonosDevice_t *device, uint8_t *stepSize, mykonosGpioSelect_t *tx1AttenIncPin, mykonosGpioSelect_t *tx1AttenDecPin, uint8_t *enable, uint8_t *useTx1ForTx2);
mykonosGpioErr_t MYKONOS_getTx2AttenCtrlPin(mykonosDevice_t *device, uint8_t *stepSize, mykonosGpioSelect_t *tx2AttenIncPin, mykonosGpioSelect_t *tx2AttenDecPin, uint8_t *enable, uint8_t *useTx1ForTx2);
mykonosGpioErr_t MYKONOS_spi2GpioSetup(mykonosDevice_t *device, uint8_t enable, uint8_t updateTxAttenPinSelect);
/* GPIO memory source Functions */
mykonosGpioErr_t MYKONOS_setGpioPinLevel(mykonosDevice_t *device, uint32_t gpioPinLevel);
mykonosGpioErr_t MYKONOS_getGpioPinLevel(mykonosDevice_t *device, uint32_t *gpioPinLevel);
mykonosGpioErr_t MYKONOS_getGpioSetLevel(mykonosDevice_t *device, uint32_t *gpioPinSetLevel);
/* Gain Compensation Functions */
mykonosGpioErr_t MYKONOS_setRxGainCompensation (mykonosDevice_t *device, mykonosGainComp_t *gainComp, uint8_t enable);
mykonosGpioErr_t MYKONOS_getRxGainCompensation (mykonosDevice_t *device, mykonosGainComp_t *gainComp, uint8_t *enabled);
mykonosGpioErr_t MYKONOS_setObsRxGainCompensation (mykonosDevice_t *device, mykonosObsRxGainComp_t *gainComp, uint8_t enable);
mykonosGpioErr_t MYKONOS_getObsRxGainCompensation (mykonosDevice_t *device, mykonosObsRxGainComp_t *gainComp, uint8_t *enabled);
/* SLICER Functions */
mykonosGpioErr_t MYKONOS_setRxSlicerCtrl(mykonosDevice_t *device, uint8_t slicerStep, mykonosRxSlicer_t rx1Pins, mykonosRxSlicer_t rx2Pins, uint8_t enable);
mykonosGpioErr_t MYKONOS_getRxSlicerCtrl(mykonosDevice_t *device, uint8_t *slicerStep, mykonosRxSlicer_t *rx1Pins, mykonosRxSlicer_t *rx2Pins, uint8_t *enable);
mykonosGpioErr_t MYKONOS_setObsRxSlicerCtrl(mykonosDevice_t *device, uint8_t slicerStep, mykonosObsRxSlicer_t obsRxPins, uint8_t enable);
mykonosGpioErr_t MYKONOS_getObsRxSlicerCtrl(mykonosDevice_t *device, uint8_t *slicerStep, mykonosObsRxSlicer_t *obsRxPins, uint8_t *enable);
/* Floating Point Formatter Functions */
mykonosGpioErr_t MYKONOS_setFloatPointFrmt (mykonosDevice_t *device, mykonosFloatPntFrmt_t *floatFrmt);
mykonosGpioErr_t MYKONOS_getFloatPointFrmt (mykonosDevice_t *device, mykonosFloatPntFrmt_t *floatFrmt);
mykonosGpioErr_t MYKONOS_setRxEnFloatPntFrmt (mykonosDevice_t *device, uint8_t rx1Att, uint8_t rx2Att, uint8_t enable);
mykonosGpioErr_t MYKONOS_getRxEnFloatPntFrmt (mykonosDevice_t *device, uint8_t *rx1Att, uint8_t *rx2Att, uint8_t *enable);
mykonosGpioErr_t MYKONOS_setOrxEnFloatPntFrmt (mykonosDevice_t *device, uint8_t orxAtt, uint8_t enable);
mykonosGpioErr_t MYKONOS_getOrxEnFloatPntFrmt (mykonosDevice_t *device, uint8_t *orxAtt, uint8_t *enable);
/*
*****************************************************************************
* General Purpose Interrupt functions
*****************************************************************************
*/
mykonosGpioErr_t MYKONOS_configGpInterrupt(mykonosDevice_t *device, uint16_t gpMask);
mykonosGpioErr_t MYKONOS_readGpInterruptStatus(mykonosDevice_t *device, uint16_t *status);
/*
*****************************************************************************
* ARM GPIO usage functions
*****************************************************************************
*/
mykonosGpioErr_t MYKONOS_setArmGpioPins(mykonosDevice_t *device);
/*
*****************************************************************************
* AuxADC/AuxDAC functions
*****************************************************************************
*/
mykonosGpioErr_t MYKONOS_setupAuxAdcs(mykonosDevice_t *device, uint8_t adcDecimation, uint8_t enable);
mykonosGpioErr_t MYKONOS_setAuxAdcChannel(mykonosDevice_t *device, mykonosAuxAdcChannels_t auxAdcChannel);
mykonosGpioErr_t MYKONOS_readAuxAdc(mykonosDevice_t *device, uint16_t *adcCode);
mykonosGpioErr_t MYKONOS_setupAuxDacs(mykonosDevice_t *device);
mykonosGpioErr_t MYKONOS_writeAuxDac(mykonosDevice_t *device, uint8_t auxDacIndex, uint16_t auxDacCode);
/*
*****************************************************************************
* GPIO3v3 functions
*****************************************************************************
*/
mykonosGpioErr_t MYKONOS_setupGpio3v3(mykonosDevice_t *device);
mykonosGpioErr_t MYKONOS_setGpio3v3PinLevel(mykonosDevice_t *device, uint16_t gpio3v3PinLevel);
mykonosGpioErr_t MYKONOS_getGpio3v3SetLevel(mykonosDevice_t *device, uint16_t *gpio3v3SetLevel);
mykonosGpioErr_t MYKONOS_getGpio3v3PinLevel(mykonosDevice_t *device, uint16_t *gpio3v3PinLevel);
mykonosGpioErr_t MYKONOS_setGpio3v3Oe(mykonosDevice_t *device, uint16_t gpio3v3OutEn);
mykonosGpioErr_t MYKONOS_getGpio3v3Oe(mykonosDevice_t *device, uint16_t *gpio3v3OutEn);
mykonosGpioErr_t MYKONOS_setGpio3v3SourceCtrl(mykonosDevice_t *device, uint16_t gpio3v3SrcCtrl);
mykonosGpioErr_t MYKONOS_getGpio3v3SourceCtrl(mykonosDevice_t *device, uint16_t *gpio3v3SrcCtrl);
/*
*****************************************************************************
* GPIO helper functions
*****************************************************************************
*/
mykonosGpioErr_t MYKONOS_setupGpio(mykonosDevice_t *device);
mykonosGpioErr_t MYKONOS_setGpioOe(mykonosDevice_t *device, uint32_t gpioOutEn, uint32_t gpioUsedMask);
mykonosGpioErr_t MYKONOS_getGpioOe(mykonosDevice_t *device, uint32_t *gpioOutEn);
mykonosGpioErr_t MYKONOS_setGpioSourceCtrl(mykonosDevice_t *device, uint32_t gpioSrcCtrl);
mykonosGpioErr_t MYKONOS_getGpioSourceCtrl(mykonosDevice_t *device, uint32_t *gpioSrcCtrl);
/*
*****************************************************************************
* Temperature Sensor functions
*****************************************************************************
*/
mykonosGpioErr_t MYKONOS_setupTempSensor(mykonosDevice_t *device, mykonosTempSensorConfig_t *tempSensor);
mykonosGpioErr_t MYKONOS_getTempSensorConfig(mykonosDevice_t *device, mykonosTempSensorConfig_t *tempSensor);
mykonosGpioErr_t MYKONOS_startTempMeasurement(mykonosDevice_t *device);
mykonosGpioErr_t MYKONOS_readTempSensor(mykonosDevice_t *device, mykonosTempSensorStatus_t *tempStatus);
const char* getGpioMykonosErrorMessage(mykonosGpioErr_t errorCode);
#ifdef __cplusplus
}
#endif
#endif /* MYKONOSGPIO_H_ */
+707
View File
@@ -0,0 +1,707 @@
/**
* \file mykonos_macros.h
* \brief Contains address and miscellaneous macro definitions for Mykonos API
*
* Mykonos API version: 1.5.2.3566
*/
/**
* \page Disclaimer Legal Disclaimer
* Copyright 2015-2017 Analog Devices Inc.
* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file.
*
*/
#ifndef CLEMENTE_TDD_MACROS_H
#define CLEMENTE_TDD_MACROS_H
#ifdef __cplusplus
extern "C" {
#endif
#define MYKONOS_ADDR_CONFIGURATION_CONTROL_0 0x000
#define MYKONOS_ADDR_SPI_CONFIGURATION_CONTROL_1 0x001
#define MYKONOS_ADDR_PRODUCT_ID 0x004
#define MYKONOS_GPIO_DRV_CTL_0 0x020
#define MYKONOS_GPIO_DRV_CTL_1 0x021
#define MYKONOS_GPIO_SLEW_CTL_0 0x022
#define MYKONOS_GPIO_SLEW_CTL_1 0x023
#define MYKONOS_GPIO_SLEW_CTL_2 0x024
#define MYKONOS_GPIO_SLEW_CTL_3 0x025
#define MYKONOS_ADDR_DIGITAL_IO_CONTROL 0x028
#define MYKONOS_ADDR_SYSREF_PAD_CONFIG 0x040
#define MYKONOS_ADDR_TX1_SYNC_PAD_CONFIG 0x041
#define MYKONOS_ADDR_TX2_SYNC_PAD_CONFIG 0x042
#define MYKONOS_ADDR_RX1_SYNC_CONFIG 0x043
#define MYKONOS_ADDR_RX2_SYNC_CONFIG 0x044
/* Mykonos Framer Registers */
#define MYKONOS_ADDR_FRAMER_RESET 0x059
#define MYKONOS_ADDR_FRAMER_CLK_EN 0x05A
#define MYKONOS_ADDR_FRAMER_ADDR 0x05B
#define MYKONOS_ADDR_FRAMER_DATA 0x05C
#define MYKONOS_ADDR_FRAMER_WRITE_EN 0x05D
#define MYKONOS_ADDR_FRAMER_SYSREF_FIFO_EN 0x05E
#define MYKONOS_ADDR_FRAMER_CONFIG_F 0x05F
#define MYKONOS_ADDR_FRAMER_LANE_CTL 0x060
#define MYKONOS_ADDR_FRAMER_ADC_XBAR_SEL 0x061
#define MYKONOS_ADDR_FRAMER_LANE_XBAR_SEL 0x062
#define MYKONOS_ADDR_FRAMER_CONFIG_LOOPBACK_XBAR_REV 0x063
#define MYKONOS_ADDR_FRAMER_SYNCN_FILT 0x064
#define MYKONOS_ADDR_FRAMER_LMFC_F_OFFSET 0x065
#define MYKONOS_ADDR_FRAMER_LMFC_K_OFFSET 0x066
#define MYKONOS_ADDR_FRAMER_TEST_CNTR_CTL 0x067
#define MYKONOS_ADDR_FRAMER_STATUS_STRB 0x068
#define MYKONOS_ADDR_FRAMER_STATUS 0x069
#define MYKONOS_ADDR_FRAMER_SYSREF_TO_LMFC_CNTR_STAT 0x06A
#define MYKONOS_ADDR_FRAMER_SYSREF_TO_LMFC_ERR_MARGIN 0x06B
#define MYKONOS_ADDR_FRAMER_LANE_FIFO_STRB 0x06C
#define MYKONOS_ADDR_FRAMER_LANE0_FIFO_RDWR_ADDR 0x06D
#define MYKONOS_ADDR_FRAMER_LANE1_FIFO_RDWR_ADDR 0x06E
#define MYKONOS_ADDR_FRAMER_LANE2_FIFO_RDWR_ADDR 0x06F
#define MYKONOS_ADDR_FRAMER_LANE3_FIFO_RDWR_ADDR 0x070
#define MYKONOS_ADDR_FRAMER_PRBS10_CTL 0x071
#define MYKONOS_ADDR_FRAMER_PRBS20_CTL 0x072
#define MYKONOS_ADDR_FRAMER_PATTERN_GEN_EN 0x073
#define MYKONOS_ADDR_FRAMER_PATTERN_GEN_7_TO_0 0x074
#define MYKONOS_ADDR_FRAMER_PATTERN_GEN_15_TO_8 0x075
#define MYKONOS_ADDR_FRAMER_PATTERN_GEN_19_TO_16 0x076
#define MYKONOS_ADDR_FRAMER_CONFIG_JTX_GEN 0x077
#define MYKONOS_ADDR_FRAMER_LANE_DATA_CTL 0x078
#define MYKONOS_ADDR_FRAMER_DATA_SAMPLE_CTL 0x079
/* Mykonos Deframer Sub Address Map */
#define MYKONOS_SUBADDR_DEFRAMER_LANE0_ILAS_RECVD 0x00
#define MYKONOS_SUBADDR_DEFRAMER_LANE0_ILAS_CFG 0x50
/* Mykonos Deframer Registers */
#define MYKONOS_ADDR_DEFRAMER_RESET 0x07A
#define MYKONOS_ADDR_DEFRAMER_CLK_EN 0x07B
#define MYKONOS_ADDR_DEFRAMER_ADDR 0x07C
#define MYKONOS_ADDR_DEFRAMER_DATA 0x07D
#define MYKONOS_ADDR_DEFRAMER_WR_EN 0x07E
#define MYKONOS_ADDR_DEFRAMER_SYSREF_FIFO_EN 0x07F
#define MYKONOS_ADDR_DEFRAMER_CONFIG_F 0x080
#define MYKONOS_ADDR_DEFRAMER_LANE_FIFO_CTL 0x081
#define MYKONOS_ADDR_DEFRAMER_DAC_XBAR_SEL 0x082
#define MYKONOS_ADDR_DEFRAMER_LANE_XBAR_SEL 0x083
#define MYKONOS_ADDR_DEFRAMER_LMFC_F_OFFSET 0x084
#define MYKONOS_ADDR_DEFRAMER_LMFC_K_OFFSET 0x085
#define MYKONOS_ADDR_DEFRAMER_CONFIG_SYNC_USER_DATA_CTL 0x086
#define MYKONOS_ADDR_DEFRAMER_SYNC_REQ_RETIME 0x087
#define MYKONOS_ADDR_DEFRAMER_TEST 0x088
#define MYKONOS_ADDR_DEFRAMER_DET_FIFO_WR_STRT_DAC_XBAR_REV 0x089
#define MYKONOS_ADDR_DEFRAMER_STAT_STRB 0x08A
#define MYKONOS_ADDR_DEFRAMER_STAT 0x08B
#define MYKONOS_ADDR_DEFRAMER_TEST_ERR_CNT_STAT 0x08C
#define MYKONOS_ADDR_DEFRAMER_DET_FIFO_RD_ADDR 0x08D
#define MYKONOS_ADDR_DEFRAMER_DET_FIFO_WR_ADDR 0x08E
#define MYKONOS_ADDR_DEFRAMER_QBLMFC_VS_EXTLMFC_CNTR_STAT 0x08F
#define MYKONOS_ADDR_DEFRAMER_DET_FIFO_STAT 0x090
#define MYKONOS_ADDR_DEFRAMER_STRT_RD_DEL_STOP_WR 0x091
#define MYKONOS_ADDR_DEFRAMER_FIFO_SAMPLE_SPI_ADDR_RD 0x092
#define MYKONOS_ADDR_DEFRAMER_FIFO_BYTE_SPI_ADDR_RD 0x093
#define MYKONOS_ADDR_DEFRAMER_FIFO_BYTE_SPI_DATA_RD 0x094
#define MYKONOS_ADDR_DEFRAMER_SAMPLE0_7_TO_0 0x095
#define MYKONOS_ADDR_DEFRAMER_SAMPLE0_15_TO_8 0x096
#define MYKONOS_ADDR_DEFRAMER_SAMPLE1_7_TO_0 0x097
#define MYKONOS_ADDR_DEFRAMER_SAMPLE1_15_TO_8 0x098
#define MYKONOS_ADDR_DEFRAMER_SAMPLE2_7_TO_0 0x099
#define MYKONOS_ADDR_DEFRAMER_SAMPLE2_15_TO_8 0x09A
#define MYKONOS_ADDR_DEFRAMER_SAMPLE3_7_TO_0 0x09B
#define MYKONOS_ADDR_DEFRAMER_SAMPLE3_15_TO_8 0x09C
#define MYKONOS_ADDR_DEFRAMER_LANE_FIFO_STRB 0x09D
#define MYKONOS_ADDR_DEFRAMER_LANE0_FIFO_RDWR_ADDR 0x09E
#define MYKONOS_ADDR_DEFRAMER_LANE1_FIFO_RDWR_ADDR 0x09F
#define MYKONOS_ADDR_DEFRAMER_LANE2_FIFO_RDWR_ADDR 0x0A0
#define MYKONOS_ADDR_DEFRAMER_LANE3_FIFO_RDWR_ADDR 0x0A1
#define MYKONOS_ADDR_DEFRAMER_SYSREF_TO_LMFC_CNTR_STAT 0x0A2
#define MYKONOS_ADDR_DEFRAMER_SYSREF_TO_LMFC_ERR_MARGIN 0x0A3
#define MYKONOS_ADDR_DEFRAMER_PRBS10_CTL 0x0A4
#define MYKONOS_ADDR_DEFRAMER_PRBS20_CTL 0x0A5
#define MYKONOS_ADDR_DEFRAMER_PRBS20_STRB_CHKSUM_TYPE 0x0A6
#define MYKONOS_ADDR_DEFRAMER_PRBS20_ERR_CNTR_7_TO_0 0x0A7
#define MYKONOS_ADDR_DEFRAMER_PRBS20_ERR_CNTR_15_TO_8 0x0A8
#define MYKONOS_ADDR_DEFRAMER_PRBS20_ERR_CNTR_23_TO_16 0x0A9
#define MYKONOS_ADDR_DEFRAMER_LANE_DATA_CTL 0x0AA
#define MYKONOS_ADDR_DEFRAMER_STATUS_2 0x0AB
#define MYKONOS_ADDR_DEFRAMER_DET_FIFO_PHASE 0x0AC
/* Mykonos Serializer Registers */
#define MYKONOS_ADDR_SERIALIZER_CTL_0 0x0B0
#define MYKONOS_ADDR_SERIALIZER_CTL_1 0x0B1
#define MYKONOS_ADDR_SERIALIZER_CTL_2 0x0B2
#define MYKONOS_ADDR_SERIALIZER_CTL_3 0x0B3
#define MYKONOS_ADDR_SERIALIZER_HS_DIV_TXSER_CLK_EN 0x0B4
#define MYKONOS_ADDR_SERIALIZER_SPECIAL 0x0B5
/* Mykonos Deserializer Registers */
#define MYKONOS_ADDR_DESERIALIZER_PDET_CTL 0x0BC
#define MYKONOS_ADDR_DESERIALIZER_CTL_0 0x0BD
#define MYKONOS_ADDR_DESERIALIZER_SIN_SHAPE_0 0x0BE
#define MYKONOS_ADDR_DESERIALIZER_SIN_SHAPE_1 0x0BF
#define MYKONOS_ADDR_DESERIALIZER_EQ_CTL_0 0x0C1
#define MYKONOS_ADDR_DESERIALIZER_EQ_CTL_1 0x0C2
#define MYKONOS_ADDR_DESERIALIZER_MISC_CTL 0x0C3
#define MYKONOS_ADDR_DESERIALIZER_EQ_HP_EN 0x0C4
#define MYKONOS_ADDR_DESERIALIZER_EQ_CTL_1_TO_0 0x0C5
#define MYKONOS_ADDR_DESERIALIZER_EQ_CTL_3_TO_2 0x0C6
#define MYKONOS_ADDR_DESERIALIZER_HS_DIV_RXCDR_CLK_EN 0x0CD
#define MYKONOS_ADDR_DESERIALIZER_SPECIAL 0x0CE
#define MYKONOS_ADDR_DESERIALIZER_CDR_CAL_CTL 0x0D0
#define MYKONOS_ADDR_CONFIGURATION_CONTROL_1 0x100
#define MYKONOS_ADDR_CONFIGURATION_CONTROL_2 0x101
#define MYKONOS_ADDR_CONFIGURATION_CONTROL_4 0x102
#define MYKONOS_ADDR_CONFIGURATION_CONTROL_5 0x103
#define MYKONOS_ADDR_DPD_SNIFFER_CONFIGURATION_CONTROL_1 0x104
#define MYKONOS_ADDR_DPD_SNIFFER_CONFIGURATION_CONTROL_2 0x105
#define MYKONOS_ADDR_DPD_SNIFFER_GPIO_SELECT 0x106
#define MYKONOS_ADDR_SNIFFER_CONFIGURATION_CONTROL 0x107
#define MYKONOS_ADDR_DPD_CONFIGURATION_CONTROL 0x108
#define MYKONOS_ADDR_LOOPBACK_CONFIGURATION_CONTROL 0x109
#define MYKONOS_ADDR_CLOCK_CONTROL_0 0x117
#define MYKONOS_ADDR_CLOCK_CONTROL_1 0x118
#define MYKONOS_ADDR_CLOCK_CONTROL_2 0x119
#define MYKONOS_ADDR_CLOCK_CONTROL_3 0x11A
#define MYKONOS_ADDR_CLOCK_CONTROL_4 0x11B
#define MYKONOS_ADDR_CLOCK_CONTROL_5 0x11C
#define MYKONOS_ADDR_MCS_CONTROL 0x120
#define MYKONOS_ADDR_MCS_STATUS 0x121
/* CLK PLL Registers */
#define MYKONOS_ADDR_CLK_SYNTH_DIVIDER_INT_BYTE0 0x141
#define MYKONOS_ADDR_CLK_SYNTH_DIVIDER_INT_BYTE1 0x142
#define MYKONOS_ADDR_CLK_SYNTH_DIVIDER_FRAC_BYTE0 0x143
#define MYKONOS_ADDR_CLK_SYNTH_DIVIDER_FRAC_BYTE1 0x144
#define MYKONOS_ADDR_CLK_SYNTH_DIVIDER_FRAC_BYTE2 0x145
#define MYKONOS_ADDR_CLK_SYNTH_F_VCOTN_BYTE1 0x148
#define MYKONOS_ADDR_CLK_SYNTH_BYTE1 0x149
#define MYKONOS_ADDR_CLK_SYNTH_BYTE2 0x14A
#define MYKONOS_ADDR_CLK_SYNTH_BYTE3 0x14B
#define MYKONOS_ADDR_CLK_SYNTH_BYTE5 0x14D
#define MYKONOS_ADDR_CLK_SYNTH_BYTE6 0x14E
#define MYKONOS_ADDR_CLK_SYNTH_BYTE7 0x14F
#define MYKONOS_ADDR_CLK_SYNTH_LF_R3 0x150
#define MYKONOS_ADDR_CLK_SYNTH_BYTE9 0x152
#define MYKONOS_ADDR_CLK_SYNTH_CAL_STAT 0x154
#define MYKONOS_ADDR_CLK_SYNTH_VCO_CAL_REF 0x155
#define MYKONOS_ADDR_CLK_SYNTH_VCO_BAND_BYTE1 0x157
#define MYKONOS_ADDR_CLK_SYNTH_CAL_CONTROL 0x159
#define MYKONOS_ADDR_CLK_SYNTH_VCO_VAR_CTL1 0x15E
#define MYKONOS_ADDR_CLK_SYNTH_VCO_VAR_CTL2 0x15F
/* DPD Registers */
#define MYKONOS_ADDR_TX1_DPD_MODEL_INDIRECT_PTR 0x178
#define MYKONOS_ADDR_TX2_DPD_MODEL_INDIRECT_PTR 0x17C
#define MYKONOS_ADDR_DPD_RMS_BUF_SIZE 0x180
#define MYKONOS_ADDR_TX1_DPD_MODEL_WORKING_PTR 0x188
#define MYKONOS_ADDR_TX2_DPD_MODEL_WORKING_PTR 0x18C
/* Rx NCO Control registers */
#define MYKONOS_ADDR_CALPLL_SDM_CONTROL 0x17F
#define MYKONOS_ADDR_RX_NCO_CONTROL 0x190
#define MYKONOS_ADDR_RX_NCO_CH1_FTW_BYTE_3 0x191
#define MYKONOS_ADDR_RX_NCO_CH1_FTW_BYTE_2 0x192
#define MYKONOS_ADDR_RX_NCO_CH1_FTW_BYTE_1 0x193
#define MYKONOS_ADDR_RX_NCO_CH2_FTW_BYTE_3 0x194
#define MYKONOS_ADDR_RX_NCO_CH2_FTW_BYTE_2 0x195
#define MYKONOS_ADDR_RX_NCO_CH2_FTW_BYTE_1 0x196
#define MYKONOS_ADDR_RX_NCO_DPD_SNIFFER_FTW_BYTE_3 0x197
#define MYKONOS_ADDR_RX_NCO_DPD_SNIFFER_FTW_BYTE_2 0x198
#define MYKONOS_ADDR_RX_NCO_DPD_SNIFFER_FTW_BYTE_1 0x199
#define MYKONOS_ADDR_ENSM_CONFIG_7_0 0x1B0
#define MYKONOS_ADDR_CALIBRATION_CONTROL 0x1B2
#define MYKONOS_ADDR_ENSM_MANUAL_GAIN_LOCK_GPIO_SELECT 0x1B5
#define MYKONOS_ADDR_REFERENCE_CLOCK_CYCLES 0x1C0
#define MYKONOS_ADDR_TX_PD_OVERIDE_7_0 0x209
#define MYKONOS_ADDR_RCAL_CONTROL 0x224
#define MYKONOS_ADDR_REF_PAD_CONFIG1 0x230
#define MYKONOS_ADDR_REF_PAD_CONFIG2 0x231
#define MYKONOS_ADDR_RXSYNTH_CP_CAL_STAT 0x254
#define MYKONOS_ADDR_RXSYNTH_VCO_BAND_BYTE1 0x257
#define MYKONOS_ADDR_TXSYNTH_CP_CAL_STAT 0x2C4
#define MYKONOS_ADDR_TXSYNTH_VCO_BAND_BYTE1 0x2C7
#define MYKONOS_ADDR_SNIFF_RXSYNTH_CP_CAL_STAT 0x354
#define MYKONOS_ADDR_SNIFF_RXSYNTH_VCO_BAND_BYTE1 0x357
#define MYKONOS_ADDR_SNIFF_RXLOGEN_BYTE1 0x380
#define MYKONOS_ADDR_RX_FILTER_CONFIGURATION 0x410
#define MYKONOS_ADDR_RX_FILTER_GAIN 0x411
#define MYKONOS_ADDR_DPD_SNIFFER_RX_FILTER_GAIN 0x412
/* Mykonos Temperature Gain Compensation Registers */
#define MYKONOS_ADDR_RX1_TEMP_GAIN_COMP 0x420
#define MYKONOS_ADDR_RX2_TEMP_GAIN_COMP 0x421
#define MYKONOS_ADDR_OBS_TEMP_GAIN_COMP 0x422
/* Mykonos AGC General Registers */
#define MYKONOS_ADDR_AGC_CFG_1 0x42E
#define MYKONOS_ADDR_AGC_CFG_2 0x42F
#define MYKONOS_ADDR_AGC_GAIN_CHANGE_GPIO_SEL 0x430
#define MYKONOS_ADDR_AGC_RX1_MAX_GAIN_INDEX 0x431
#define MYKONOS_ADDR_AGC_RX1_MIN_GAIN_INDEX 0x432
#define MYKONOS_ADDR_AGC_MANUAL_GAIN_CFG 0x433
#define MYKONOS_ADDR_AGC_MANUAL_GAIN_GPIO_SEL 0x434
#define MYKONOS_ADDR_AGC_MANUAL_GAIN_INDEX_CH_1 0x435
#define MYKONOS_ADDR_AGC_MANUAL_GAIN_INDEX_CH_2 0x436
#define MYKONOS_ADDR_AGC_LOCK_LEVEL 0x437
#define MYKONOS_ADDR_AGC_OVRG_GAIN_STEP_1 0x438
#define MYKONOS_ADDR_AGC_OVRG_GAIN_STEP_2 0x439
#define MYKONOS_ADDR_AGC_OVRG_GAIN_STEP_3 0x43A
#define MYKONOS_ADDR_AGC_OVRG_GAIN_STEP_4 0x43B
#define MYKONOS_ADDR_AGC_OVRG_GAIN_STEP_5 0x43C
#define MYKONOS_ADDR_AGC_OVRG_GAIN_STEP_6 0x43D
#define MYKONOS_ADDR_AGC_RX1_GAIN_LOCK_DELAY 0x43E
#define MYKONOS_ADDR_AGC_RX2_GAIN_LOCK_DELAY 0x43F
#define MYKONOS_ADDR_AGC_RX1_ATTACK_DELAY 0x440
#define MYKONOS_ADDR_AGC_RX2_ATTACK_DELAY 0x441
#define MYKONOS_ADDR_AGC_ULB_THRSH 0x442
#define MYKONOS_ADDR_AGC_LLB_THRSH 0x443
#define MYKONOS_ADDR_AGC_RX_BLOCK_DET_DECAY 0x444
#define MYKONOS_ADDR_AGC_RESET_PD_HIGH_CNT 0x445
#define MYKONOS_ADDR_AGC_RX2_MAX_GAIN_INDEX 0x446
#define MYKONOS_ADDR_AGC_RX2_MIN_GAIN_INDEX 0x447
#define MYKONOS_ADDR_AGC_ORX_SNRX_CFG_1 0x448
#define MYKONOS_ADDR_AGC_ORX_SNRX_CFG_2 0x449
#define MYKONOS_ADDR_AGC_ORX_SNRX_MAX_GAIN_INDEX 0x44A
#define MYKONOS_ADDR_AGC_ORX_SNRX_MIN_GAIN_INDEX 0x44B
#define MYKONOS_ADDR_AGC_ORX_SNRX_MANUAL_GAIN_CFG 0x44C
#define MYKONOS_ADDR_AGC_ORX_SNRX_GPIO_SEL 0x44D
#define MYKONOS_ADDR_AGC_ORX_SNRX_LOCK_LEVEL 0x44E
#define MYKONOS_ADDR_AGC_ORX_SNRX_OVRG_GAIN_STEP_1 0x44F
#define MYKONOS_ADDR_AGC_ORX_SNRX_OVRG_GAIN_STEP_2 0x450
#define MYKONOS_ADDR_AGC_ORX_SNRX_OVRG_GAIN_STEP_3 0x451
#define MYKONOS_ADDR_AGC_ORX_SNRX_OVRG_GAIN_STEP_4 0x452
#define MYKONOS_ADDR_AGC_ORX_SNRX_OVRG_GAIN_STEP_5 0x453
#define MYKONOS_ADDR_AGC_ORX_SNRX_OVRG_GAIN_STEP_6 0x454
#define MYKONOS_ADDR_AGC_ORX_SNRX_GAIN_LOCK_DELAY 0x455
#define MYKONOS_ADDR_AGC_ORX_SNRX_ATTACK_DELAY 0x456
#define MYKONOS_ADDR_AGC_ORX_SNRX_ULB_THRSH 0x457
#define MYKONOS_ADDR_AGC_ORX_SNRX_LLB_THRSH 0x458
#define MYKONOS_ADDR_AGC_ORX_SNRX_BLOCK_DET_DECAY 0x459
#define MYKONOS_ADDR_AGC_ORX_SNRX_RESET_PD_HIGH_CNT 0x45A
#define MYKONOS_ADDR_AGC_ORX1_MANUAL_GAIN_INDEX 0x45B
#define MYKONOS_ADDR_AGC_ORX2_MANUAL_GAIN_INDEX 0x45C
#define MYKONOS_ADDR_AGC_SNRX_MANUAL_GAIN_INDEX 0x45D
#define MYKONOS_ADDR_AGC_LOOPBACK1_MANUAL_GAIN_INDEX 0x45E
#define MYKONOS_ADDR_AGC_LOOPBACK2_MANUAL_GAIN_INDEX 0x45F
#define MYKONOS_ADDR_AGC_ORX_SNRX_ACTIVE 0x460
/* Mykonos Fast Attack AGC Registers */
#define MYKONOS_ADDR_AGC_FAST_CFG_1 0x468
#define MYKONOS_ADDR_AGC_FAST_CFG_2 0x469
#define MYKONOS_ADDR_AGC_FAST_ENRGY_LOST_THRSH 0x46A
#define MYKONOS_ADDR_AGC_FAST_STRONG_SIG_THRSH 0x46B
#define MYKONOS_ADDR_AGC_FAST_SETTING_DELAY 0x46C
#define MYKONOS_ADDR_AGC_FAST_OPT_MAX_GAIN 0x46D
#define MYKONOS_ADDR_AGC_FAST_ENRGY_DET_CNT 0x46E
#define MYKONOS_ADDR_AGC_FAST_AGCLL_UPPER_LIMIT 0x46F
#define MYKONOS_ADDR_AGC_FAST_GAIN_LOCK_EXIT_CNT 0x470
#define MYKONOS_ADDR_AGC_FAST_ORX_SNRX_CFG_1 0x471
#define MYKONOS_ADDR_AGC_FAST_ORX_SNRX_CFG_2 0x472
#define MYKONOS_ADDR_AGC_FAST_ORX_SNRX_ENRGY_LOST_THRSH 0x473
#define MYKONOS_ADDR_AGC_FAST_ORX_SNRX_STRONG_SIG_THRSH 0x474
#define MYKONOS_ADDR_AGC_FAST_ORX_SNRX_SET_DELAY 0x475
#define MYKONOS_ADDR_AGC_FAST_ORX_SNRX_OPT_MAX_GAIN 0x476
#define MYKONOS_ADDR_AGC_FAST_ORX_SNRX_ENRGY_DET_CNT 0x477
#define MYKONOS_ADDR_AGC_FAST_ORX_SNRX_AGCLL_UPPER_LIMIT 0x478
#define MYKONOS_ADDR_AGC_FAST_ORX_SNRX_GAIN_LOCK_EXIT_CNT 0x479
/* Mykonos Slow Loop - Hybrid AGC Registers */
#define MYKONOS_ADDR_AGC_SLOW_LOCK_LEV_THRSH 0x480
#define MYKONOS_ADDR_AGC_SLOW_ULB_CNT_THRSH 0x481
#define MYKONOS_ADDR_AGC_SLOW_LLB_CNT_THRSH 0x482
#define MYKONOS_ADDR_AGC_SLOW_HIGH_OVRG_CNT_THRSH 0x483
#define MYKONOS_ADDR_AGC_SLOW_LOW_OVRG_CNT_THRSH 0x484
#define MYKONOS_ADDR_AGC_SLOW_VERYLOW_OVRG_CNT_THRSH 0x485
#define MYKONOS_ADDR_AGC_SLOW_DIG_SAT_CNT_THRSH 0x486
#define MYKONOS_ADDR_AGC_SLOW_UPPER0_THRSH_GAIN_STEP 0x487
#define MYKONOS_ADDR_AGC_SLOW_LOWER0_THRSH_GAIN_STEP 0x488
#define MYKONOS_ADDR_AGC_SLOW_UPPER1_THRSH_GAIN_STEP 0x489
#define MYKONOS_ADDR_AGC_SLOW_LOWER1_THRSH_GAIN_STEP 0x48A
#define MYKONOS_ADDR_AGC_SLOW_GAIN_UPDATE_CNT_1 0x48B
#define MYKONOS_ADDR_AGC_SLOW_GAIN_UPDATE_CNT_2 0x48C
#define MYKONOS_ADDR_AGC_SLOW_GAIN_UPDATE_CNT_3 0x48D
#define MYKONOS_ADDR_AGC_SLOW_LOOP_CFG 0x48E
#define MYKONOS_ADDR_AGC_SLOW_POWER_THRSH 0x48F
#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_LOCK_LEV_THRSH 0x490
#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_ULB_CNT_THRSH 0x491
#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_LLB_CNT_THRSH 0x492
#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_ADC_HIGH_OVRG_CNT_THRSH 0x493
#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_ADC_LOW_OVRG_CNT_THRSH 0x494
#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_ADC_VERYLOW_OVRG_CNT_THRSH 0x495
#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_DIG_SAT_CNT_THRSH 0x496
#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_UPPER0_THRSH_GAIN_STEP 0x497
#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_LOWER0_THRSH_GAIN_STEP 0x498
#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_UPPER1_THRSH_GAIN_STEP 0x499
#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_LOWER1_THRSH_GAIN_STEP 0x49A
#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_GAIN_UPDATE_CTR_1 0x49B
#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_GAIN_UPDATE_CTR_2 0x49C
#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_GAIN_UPDATE_CTR_3 0x49D
#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_LOOP_CFG 0x49E
#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_POWER_THRSH 0x49F
#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_UL_SIG_POW_MEAS_DEL_1 0x4A0
#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_UL_SIG_POW_MEAS_DEL_2 0x4A1
#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_UL_SIG_POW_MEAS_DUR_1 0x4A2
#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_UL_SIG_POW_MEAS_DUR_2 0x4A3
/* Mykonos Gain Control Read Registers */
#define MYKONOS_ADDR_GAIN_CTL_CHANNEL_1 0x4B0
#define MYKONOS_ADDR_GAIN_CTL_FAST_ATTK_STATE 0x4B1
#define MYKONOS_ADDR_GAIN_CTL_SLOW_LOOP_STATE 0x4B2
#define MYKONOS_ADDR_GAIN_CTL_CHANNEL_2 0x4B3
#define MYKONOS_ADDR_GAIN_CTL_OVRG_SIGS_CHANNEL_1 0x4B4
#define MYKONOS_ADDR_GAIN_CTL_OVRG_SIGS_CHANNEL_2 0x4B5
#define MYKONOS_ADDR_GAIN_CTL_ORX_SNRX_GAIN 0x4B6
#define MYKONOS_ADDR_GAIN_CTL_ORX_SNRX_LOOP_STATE 0x4B7
#define MYKONOS_ADDR_GAIN_CTL_ORX_SNRX_OVRG_SIGS 0x4B8
/* Mykonos Rx Data Path Overrange Registers */
#define MYKONOS_ADDR_RX_OVRG_DATAPATH_OVRFLW 0x4B9
#define MYKONOS_ADDR_RX_OVRG_ORX_SNRX_DATAPATH_OVRFLW 0x4BA
/* Mykonos RSSI Measurement Registers and Dec Power Measurement Registers*/
#define MYKONOS_ADDR_RSSI_MEAS_DURATION_0_1 0x4C0
#define MYKONOS_ADDR_RSSI_MEAS_DURATION_2_3 0x4C1
#define MYKONOS_ADDR_RSSI_CFG 0x4C6
#define MYKONOS_DEC_POWER_CONFIG_1 0x4C7
#define MYKONOS_DEC_POWER_CONFIG_2 0x4C8
#define MYKONOS_ADDR_DPD_SNF_RSSI_CFG 0x4CF
#define MYKONOS_ADDR_DPD_RSSI_CFG 0x4D6
#define MYKONOS_SNIFFER_DEC_POWER_CONFIG_1 0x4D7
#define MYKONOS_SNIFFER_DEC_POWER_CONFIG_2 0x4D8
#define MYKONOS_CH1_DECIMATED_PWR 0x4DE
#define MYKONOS_CH2_DECIMATED_PWR 0x4DF
#define MYKONOS_SNIFFER_DECIMATED_PWR 0x4E6
#define MYKONOS_ADDR_DIGITAL_GAIN_CONFIG 0x4F0
#define MYKONOS_ADDR_DPD_SNIFFER_DIGITAL_GAIN_CONFIG 0x4F1
#define MYKONOS_ADDR_GAIN_TABLE_ADDR 0x500
#define MYKONOS_ADDR_GAIN_TABLE_RX1_FE_GAIN 0x501
#define MYKONOS_ADDR_GAIN_TABLE_RX1_EXT_CTL 0x502
#define MYKONOS_ADDR_GAIN_TABLE_RX1_DIG_GAIN 0x503
#define MYKONOS_ADDR_GAIN_TABLE_RX2_FE_GAIN 0x504
#define MYKONOS_ADDR_GAIN_TABLE_RX2_EXT_CTL 0x505
#define MYKONOS_ADDR_GAIN_TABLE_RX2_DIG_GAIN 0x506
#define MYKONOS_ADDR_GAIN_TABLE_RX3_FE_GAIN 0x507
#define MYKONOS_ADDR_GAIN_TABLE_RX3_LNA_ENAB 0x508
#define MYKONOS_ADDR_GAIN_TABLE_RX3_DIG_GAIN 0x509
#define MYKONOS_ADDR_GAIN_TABLE_CONFIGURATION 0x516
#define MYKONOS_ADDR_CH3_GAIN_TABLE_CONFIGURATION 0x517
#define MYKONOS_ADDR_RXFE1_LOCM 0x520
#define MYKONOS_ADDR_RXFE2_LOCM 0x521
#define MYKONOS_ADDR_RXLOOPBACK1_CNTRL_1 0x540
#define MYKONOS_ADDR_RXLOOPBACK2_CNTRL_1 0x541
#define MYKONOS_ADDR_RX_LOOPBACK1_CNTRL_4 0x546
#define MYKONOS_ADDR_RX_LOOPBACK2_CNTRL_4 0x547
/* Mykonos Overload/Peak Detection Registers */
#define MYKONOS_ADDR_OVRLD_ADC_OVRLD_CFG 0x580
#define MYKONOS_ADDR_OVRLD_ADC_OVRLD_UPPER_THRSH 0x581
#define MYKONOS_ADDR_OVRLD_ADC_OVRLD_LOWER_THRSH 0x582
#define MYKONOS_ADDR_OVRLD_PD_DEC_OVRLD_CFG 0x583
#define MYKONOS_ADDR_OVRLD_PD_DEC_OVRLD_UPPER_THRSH 0x584
#define MYKONOS_ADDR_OVRLD_PD_DEC_OVRLD_LOWER_THRSH 0x585
#define MYKONOS_ADDR_OVRLD_PD_DEC_VERYLOW_THRSH 0x586
#define MYKONOS_ADDR_ORX_SNRX_OVRLD_ADC_OVRLD_CFG 0x587
#define MYKONOS_ADDR_ORX_SNRX_OVRLD_PD_DEC_OVRLD_CFG 0x58A
#define MYKONOS_ADDR_ORX_SNRX_OVRLD_PD_DEC_OVRLD_UPPER_THRSH 0x58B
#define MYKONOS_ADDR_ORX_SNRX_OVRLD_PD_DEC_OVRLD_LOWER_THRSH 0x58C
#define MYKONOS_ADDR_ORX_SNRX_OVRLD_PD_DEC_OVRLD_VERYLOW_THRSH 0x58D
#define MYKONOS_ADDR_RX_ADC_FLASH_DELAY 0x5B6
#define MYKONOS_ADDR_RX_ADC_FLASH_CTRL 0x5B7
#define MYKONOS_ADDR_RX_ADC1_PRFL 0x5DD
#define MYKONOS_ADDR_RX_ADC2_PRFL 0x5DE
#define MYKONOS_ADDR_ORX_ADC_PRFL 0x5DF
#define MYKONOS_ADDR_RFDC_MEASURE_COUNT_1 0x631
#define MYKONOS_ADDR_RFDC_MEASURE_COUNT_2 0x632
#define MYKONOS_ADDR_RFDC_PROGRAM_SHIFT 0x635
#define MYKONOS_ADDR_RFDC_CONFIG2 0x636
#define MYKONOS_DPD_Sniffer_RFDC_CAL_TRACK_EN 0x642
#define MYKONOS_ADDR_RFDC_SNF_MEASURE_COUNT_1 0x644
#define MYKONOS_ADDR_RFDC_SNF_MEASURE_COUNT_2 0x645
#define MYKONOS_ADDR_RFDC_ORX_MEASURE_COUNT_1 0x650
#define MYKONOS_ADDR_RFDC_ORX_MEASURE_COUNT_2 0x651
#define MYKONOS_ADDR_DIGITAL_DC_MIN_CAL_IDX 0x63A
#define MYKONOS_ADDR_DIGITAL_DC_OFFSET_SHIFT 0x674
#define MYKONOS_ADDR_DIGITAL_DC_OFFSET_CONFIG 0x676
#define MYKONOS_DIGITAL_DC_OFFSET_CH3_TRACKING 0x67A
#define MYKONOS_ADDR_DIGITAL_DC_OFFSET_SNF 0x67C
#define MYKONOS_ADDR_DIGITAL_DC_OFFSET_CH3_DPD_M_SHIFT 0x67D
#define MYKONOS_ADDR_RX_GAIN_COMP_DELAY 0x710
#define MYKONOS_ADDR_RX1_GAIN_COMP_OFFSET 0x711
#define MYKONOS_ADDR_RX2_GAIN_COMP_OFFSET 0x712
#define MYKONOS_ADDR_RX_GAIN_COMP_CFG 0x713
#define MYKONOS_ADDR_RX_SLCR_PIN_CFG 0x714
#define MYKONOS_ADDR_DPD_SNF_RX_GAIN_COMP_DELAY 0x715
#define MYKONOS_ADDR_DPD_SNF_RX_GAIN_COMP_OFFSET 0x716
#define MYKONOS_ADDR_DPD_SNF_RX_GAIN_COMP_CFG 0x717
#define MYKONOS_ADDR_DPD_SNF_RX_SLCR_PIN_CFG 0x718
#define MYKONOS_ADDR_FLOATING_POINT_CFG 0x750
#define MYKONOS_ADDR_FLOATING_POINT_RX_CTRL 0x751
#define MYKONOS_ADDR_FLOATING_POINT_ORX_CTRL 0x752
#define MYKONOS_ADDR_SNRX_LNA_BIAS_C 0x81B
#define MYKONOS_ADDR_ORX_ADC_FLASH_DELAY 0x846
#define MYKONOS_ADDR_ORX_ADC_FLASH_CTRL 0x847
#define MYKONOS_ADDR_TX_FILTER_CONFIGURATION 0x910
#define MYKONOS_ADDR_TX1_ATTENUATION_0_READBACK 0x940
#define MYKONOS_ADDR_TX1_ATTENUATION_1_READBACK 0x941
#define MYKONOS_ADDR_TX2_ATTENUATION_0_READBACK 0x942
#define MYKONOS_ADDR_TX2_ATTENUATION_1_READBACK 0x943
#define MYKONOS_ADDR_TX_FILTER_OVERFLOW 0x950
/* Mykonos PA Protection Block Registers */
#define MYKONOS_ADDR_PA_PROTECTION_CONFIGURATION 0x955
#define MYKONOS_ADDR_PA_PROTECTION_ATTEN_CONTROL 0x956
#define MYKONOS_ADDR_PA_PROTECTION_THRESHOLD_LSB 0x957
#define MYKONOS_ADDR_PA_PROTECTION_THRESHOLD_MSB 0x958
#define MYKONOS_ADDR_PA_PROTECTION_POWER_READBACK_LSB 0x959
#define MYKONOS_ADDR_PA_PROTECTION_POWER_READBACK_MSB 0x95A
#define MYKONOS_ADDR_TX1_ATTENUATION_0 0x960
#define MYKONOS_ADDR_TX1_ATTENUATION_1 0x961
#define MYKONOS_ADDR_TX2_ATTENUATION_0 0x962
#define MYKONOS_ADDR_TX2_ATTENUATION_1 0x963
#define MYKONOS_ADDR_TX1_GAIN_0 0x967
#define MYKONOS_ADDR_TX1_GAIN_1 0x968
#define MYKONOS_ADDR_TX1_GAIN_2 0x969
#define MYKONOS_ADDR_TX2_GAIN_0 0x96A
#define MYKONOS_ADDR_TX2_GAIN_1 0x96B
#define MYKONOS_ADDR_TX2_GAIN_2 0x96C
#define MYKONOS_ADDR_TX_INCR_DECR_WORD 0x96D
#define MYKONOS_ADDR_TX_TPC_CONFIG 0x96E
#define MYKONOS_ADDR_TX_TPC_GPIO_CFG 0x96F
#define MYKONOS_ADDR_TX_ABBF_FREQ_CAL_NCO_I_MSB 0x9CB
#define MYKONOS_ADDR_TX_ABBF_FREQ_CAL_NCO_I_LSB 0x9CC
#define MYKONOS_ADDR_TX_ABBF_FREQ_CAL_NCO_Q_MSB 0x9CD
#define MYKONOS_ADDR_TX_ABBF_FREQ_CAL_NCO_Q_LSB 0x9CE
/* Mykonos GPIO Registers */
#define MYKONOS_ADDR_GPIO_3V3_DIR_CTL_7_0 0xB00
#define MYKONOS_ADDR_GPIO_3V3_DIR_CTL_15_8 0xB01
#define MYKONOS_ADDR_GPIO_3V3_SPI_SRC_7_0 0xB02
#define MYKONOS_ADDR_GPIO_3V3_SPI_SRC_15_8 0xB03
#define MYKONOS_ADDR_GPIO_3V3_SPI_READ_7_0 0xB04
#define MYKONOS_ADDR_GPIO_3V3_SPI_READ_15_8 0xB05
#define MYKONOS_ADDR_GPIO_3V3_LSB_SRC_CTL 0xB06
#define MYKONOS_ADDR_GPIO_3V3_MSB_SRC_CTL 0xB07
#define MYKONOS_ADDR_GPIO_DIR_CTL_7_0 0xB20
#define MYKONOS_ADDR_GPIO_DIR_CTL_15_8 0xB21
#define MYKONOS_ADDR_GPIO_DIR_CTL_18_16 0xB22
#define MYKONOS_ADDR_GPIO_SPI_SRC_7_0 0xB23
#define MYKONOS_ADDR_GPIO_SPI_SRC_15_8 0xB24
#define MYKONOS_ADDR_GPIO_SPI_SRC_18_16 0xB25
#define MYKONOS_ADDR_GPIO_SPI_READ_7_0 0xB26
#define MYKONOS_ADDR_GPIO_SPI_READ_15_8 0xB27
#define MYKONOS_ADDR_GPIO_SPI_READ_18_16 0xB28
#define MYKONOS_ADDR_SOURCE_CONTROL_LOWER_BYTE 0xB29
#define MYKONOS_ADDR_SOURCE_CONTROL_UPPER_BYTE 0xB2A
#define MYKONOS_ADDR_SOURCE_CONTROL_EXTRA_BITS 0xB2B
#define MYKONOS_ADDR_GPIO_MONITOR_INDEX 0xB40
#define MYKONOS_ADDR_GPIO_MONITOR_ENABLE 0xB41
#define MYKONOS_ADDR_GP_INTERRUPT_MASK_1 0xB42
#define MYKONOS_ADDR_GP_INTERRUPT_MASK_0 0xB43
#define MYKONOS_ADDR_GP_INTERRUPT_READ_1 0xB44
#define MYKONOS_ADDR_GP_INTERRUPT_READ_0 0xB45
#define MYKONOS_ADDR_PDAUXDAC_MANUAL_CONTROL_5_0 0xB73
#define MYKONOS_ADDR_PDAUXDAC_MANUAL_CONTROL_9_6 0xB74
#define MYKONOS_ADDR_PDAUXDAC_MANUAL_IN_5_0 0xB75
#define MYKONOS_ADDR_PDAUXDAC_MANUAL_IN_9_6 0xB76
#define MYKONOS_ADDR_AUX_DAC_LATCH_CONTROL 0xB9F
#define MYKONOS_ADDR_AUXDAC_0_WORD_MSB 0xBA0
#define MYKONOS_ADR_AUX_ADC_CLOCK_DIVIDE 0xBC0
#define MYKONOS_ADDR_AUX_ADC_CFG 0xBC1
#define MYKONOS_ADDR_AUX_ADC_READ_MSB 0xBC2
#define MYKONOS_ADDR_AUX_ADC_READ_LSB 0xBC3
#define MYKONOS_ADDR_AUX_ADC_SEL 0xBC4
#define MYKONOS_ADDR_AUX_ADC_BUFFER_CONFIG_0 0xBC5
#define MYKONOS_ADDR_AUX_ADC_BUFFER_CONFIG_1 0xBC6
#define MYKONOS_ADDR_TEMP_SENSOR_OFFSET 0xBE0
#define MYKONOS_ADDR_TEMP_SENSOR_CONTROL_LSB 0xBE1
#define MYKONOS_ADDR_TEMP_SENSOR_CONTROL_MSB 0xBE2
#define MYKONOS_ADDR_TEMP_SENSOR_READ 0xBE3
#define MYKONOS_ADDR_TEMP_SENSOR_CONFIG 0xBE4
#define MYKONOS_ADDR_DIGITAL_TEST_BYTE_0 0xC40
/* ARM subsystem registers */
#define MYKONOS_ADDR_ARM_CTL_1 0xD00
#define MYKONOS_ADDR_ARM_CTL_2 0xD01
#define MYKONOS_ADDR_ARM_ADDR_BYTE_0 0xD02
#define MYKONOS_ADDR_ARM_ADDR_BYTE_1 0xD03
#define MYKONOS_ADDR_ARM_DATA_BYTE_0 0xD04
#define MYKONOS_ADDR_ARM_DATA_BYTE_1 0xD05
#define MYKONOS_ADDR_ARM_DATA_BYTE_2 0xD06
#define MYKONOS_ADDR_ARM_DATA_BYTE_3 0xD07
#define MYKONOS_ADDR_ARM_CLK_CTL 0xD08
#define MYKONOS_ADDR_AHB_SPI_BRIDGE 0xD09
#define MYKONOS_ADDR_ARM_BOOT_ADDR_BYTE_0 0xD0A
#define MYKONOS_ADDR_ARM_BOOT_ADDR_BYTE_1 0xD0B
#define MYKONOS_ADDR_ARM_BOOT_ADDR_BYTE_2 0xD0C
#define MYKONOS_ADDR_ARM_BOOT_ADDR_BYTE_3 0xD0D
#define MYKONOS_ADDR_ARM_STACK_PTR_BYTE_0 0xD0E
#define MYKONOS_ADDR_ARM_STACK_PTR_BYTE_1 0xD0F
#define MYKONOS_ADDR_ARM_STACK_PTR_BYTE_2 0xD10
#define MYKONOS_ADDR_ARM_STACK_PTR_BYTE_3 0xD11
#define MYKONOS_ADDR_ARM_BRIDGE_CLK_CTL 0xD14
/* ARM mailbox registers */
#define MYKONOS_ADDR_ARM_CMD 0xD30
#define MYKONOS_ADDR_ARM_EXT_CMD_BYTE_1 0xD31
#define MYKONOS_ADDR_ARM_EXT_CMD_BYTE_2 0xD32
#define MYKONOS_ADDR_ARM_EXT_CMD_BYTE_3 0xD33
#define MYKONOS_ADDR_ARM_EXT_CMD_BYTE_4 0xD34
#define MYKONOS_ADDR_ARM_EXT_CMD_BYTE_5 0xD35
#define MYKONOS_ADDR_ARM_EXT_CMD_BYTE_6 0xD36
#define MYKONOS_ADDR_ARM_EXT_CMD_BYTE_7 0xD37
#define MYKONOS_ADDR_ARM_CMD_STATUS_0 0xD38
#define MYKONOS_ADDR_ARM_CMD_STATUS_1 0xD39
#define MYKONOS_ADDR_ARM_CMD_STATUS_2 0xD3A
#define MYKONOS_ADDR_ARM_CMD_STATUS_3 0xD3B
#define MYKONOS_ADDR_ARM_CMD_STATUS_4 0xD3C
#define MYKONOS_ADDR_ARM_CMD_STATUS_5 0xD3D
#define MYKONOS_ADDR_ARM_CMD_STATUS_6 0xD3E
#define MYKONOS_ADDR_ARM_CMD_STATUS_7 0xD3F
#define MYKONOS_ADDR_ARM_OPCODE_STATE_0 0xD40
#define MYKONOS_ADDR_ARM_OPCODE_STATE_1 0xD41
#define MYKONOS_ADDR_ARM_OPCODE_STATE_2 0xD42
#define MYKONOS_ADDR_ARM_OPCODE_STATE_3 0xD43
#define MYKONOS_ADDR_ARM_OPCODE_STATE_4 0xD44
#define MYKONOS_ADDR_ARM_OPCODE_STATE_5 0xD45
#define MYKONOS_ADDR_ARM_OPCODE_STATE_6 0xD46
#define MYKONOS_ADDR_ARM_OPCODE_STATE_7 0xD47
/* Mykonos Power-Down Override Control Registers */
#define MYKONOS_ADDR_TX_PD_OVERRIDE_CONTROL_7_0 0xD89
/* Mykonos Observation Framer Registers */
#define MYKONOS_ADDR_OBS_FRAMER_RESET 0xDC0
#define MYKONOS_ADDR_OBS_FRAMER_CLK_EN 0xDC1
#define MYKONOS_ADDR_OBS_FRAMER_ADDR 0xDC2
#define MYKONOS_ADDR_OBS_FRAMER_DATA 0xDC3
#define MYKONOS_ADDR_OBS_FRAMER_WRITE_EN 0xDC4
#define MYKONOS_ADDR_OBS_FRAMER_SYSREF_FIFO_EN 0xDC5
#define MYKONOS_ADDR_OBS_FRAMER_CONFIG_F 0xDC6
#define MYKONOS_ADDR_OBS_FRAMER_LANE_CTL 0xDC7
#define MYKONOS_ADDR_OBS_FRAMER_ADC_XBAR_SEL 0xDC8
#define MYKONOS_ADDR_OBS_FRAMER_LANE_XBAR_SEL 0xDC9
#define MYKONOS_ADDR_OBS_FRAMER_CONFIG_LOOPBACK_XBAR_REV 0xDCA
#define MYKONOS_ADDR_OBS_FRAMER_SYNCN_FILT 0xDCB
#define MYKONOS_ADDR_OBS_FRAMER_LMFC_F_OFFSET 0xDCC
#define MYKONOS_ADDR_OBS_FRAMER_LMFC_K_OFFSET 0xDCD
#define MYKONOS_ADDR_OBS_FRAMER_TEST_CNTR_CTL 0xDCE
#define MYKONOS_ADDR_OBS_FRAMER_STATUS_STRB 0xDCF
#define MYKONOS_ADDR_OBS_FRAMER_STATUS 0xDD0
#define MYKONOS_ADDR_OBS_FRAMER_SYSREF_TO_LMFC_CNTR_STAT 0xDD1
#define MYKONOS_ADDR_OBS_FRAMER_SYSREF_TO_LMFC_ERR_MARGIN 0xDD2
#define MYKONOS_ADDR_OBS_FRAMER_LANE_FIFO_STRB 0xDD3
#define MYKONOS_ADDR_OBS_FRAMER_LANE0_FIFO_RDWR_ADDR 0xDD4
#define MYKONOS_ADDR_OBS_FRAMER_LANE1_FIFO_RDWR_ADDR 0xDD5
#define MYKONOS_ADDR_OBS_FRAMER_LANE2_FIFO_RDWR_ADDR 0xDD6
#define MYKONOS_ADDR_OBS_FRAMER_LANE3_FIFO_RDWR_ADDR 0xDD7
#define MYKONOS_ADDR_OBS_FRAMER_PRBS10_CTL 0xDD8
#define MYKONOS_ADDR_OBS_FRAMER_PRBS20_CTL 0xDD9
#define MYKONOS_ADDR_OBS_FRAMER_PATTERN_GEN_EN 0xDDA
#define MYKONOS_ADDR_OBS_FRAMER_PATTERN_GEN_7_TO_0 0xDDB
#define MYKONOS_ADDR_OBS_FRAMER_PATTERN_GEN_15_TO_8 0xDDC
#define MYKONOS_ADDR_OBS_FRAMER_PATTERN_GEN_19_TO_16 0xDDD
#define MYKONOS_ADDR_OBS_FRAMER_CONFIG_JTX_GEN 0xDDE
#define MYKONOS_ADDR_OBS_FRAMER_LANE_DATA_CTL 0xDDF
#define MYKONOS_ADDR_OBS_FRAMER_DATA_SAMPLE_CTL 0xDE0
#define MYKONOS_ADDR_PFIR_COEFF_CTL 0xDFF
#define MYKONOS_ADDR_PFIR_COEFF_DATA 0xE00
#define MYKONOS_ADDR_PFIR_COEFF_ADDR 0xE01
/* ARM memory */
#define MYKONOS_ADDR_ARM_START_PROG_ADDR 0x01000000
#define MYKONOS_ADDR_ARM_END_PROG_ADDR 0x01017FFF
#define MYKONOS_ADDR_ARM_START_DATA_ADDR 0x20000000
#define MYKONOS_ADDR_ARM_END_DATA_ADDR 0x2000FFFF
#define MYKONOS_ADDR_ARM_BUILD_CHKSUM_ADDR 0x01017FE0
#define MYKONOS_ADDR_ARM_CALC_CHKSUM_ADDR 0x01017FE4
#define MYKONOS_ADDR_ARM_VERSION 0x01000128
#define MYKONOS_ARM_ABORT_OPCODE 0x00
#define MYKONOS_ARM_RUNINIT_OPCODE 0x02
#define MYKONOS_ARM_RADIOON_OPCODE 0x04
#define MYKONOS_ARM_WRITECFG_OPCODE 0x06
#define MYKONOS_ARM_READCFG_OPCODE 0x08
#define MYKONOS_ARM_SET_OPCODE 0x0A
#define MYKONOS_ARM_GET_OPCODE 0x0C
#define MYKONOS_ARM_OBJECTID_DPDINIT_CONFIG 0x0F
#define MYKONOS_ARM_OBJECTID_CLGCINIT_CONFIG 0x10
#define MYKONOS_ARM_OBJECTID_VSWRINIT_CONFIG 0x11
#define MYKONOS_ARM_OBJECTID_DPDCONFIG 0x24
#define MYKONOS_ARM_DPD_RESET 0x02
#define MYKONOS_ARM_OBJECTID_GS_TRACKCALS 0x66
#define MYKONOS_ARM_OBJECTID_RXQEC_TRACKING 0x20
#define MYKONOS_ARM_OBJECTID_ORXQEC_TRACKING 0x21
#define MYKONOS_ARM_OBJECTID_TXLOL_TRACKING 0x22
#define MYKONOS_ARM_OBJECTID_TXQEC_TRACKING 0x23
#define MYKONOS_ARM_OBJECTID_CLGCCONFIG 0x25
#define MYKONOS_ARM_OBJECTID_VSWRCONFIG 0x26
#define MYKONOS_ARM_OBJECTID_CAL_STATUS 0x42
#define MYKONOS_ARM_OBJECTID_INIT_CAL_DONE 0x43
#define MYKONOS_ARM_OBJECTID_ORX_MODE 0x61
#define MYKONOS_ARM_OBJECTID_TRACKING_CAL_SUSPEND_RESUME 0x65
#define MYKONOS_ARM_OBJECTID_TRACKING_CAL_CONTROL 0x66
#define MYKONOS_ARM_OBJECTID_TRACKING_CAL_PENDING 0x67
#define MYKONOS_ARM_OBJECTID_RADIO_CONTROL 0x81
#define MYKONOS_ARM_OBJECTID_CALSCHEDULER 0x83
#define MYKONOS_ARM_SYSTEMSTATE_POWERUP 0x00
#define MYKONOS_ARM_SYSTEMSTATE_READY 0x01
#define MYKONOS_ARM_SYSTEMSTATE_IDLE 0x02
#define MYKONOS_ARM_SYSTEMSTATE_RADIO_ON 0x03
#define ORX_TRIGGER_SIGNALID 0x00
#define ORX_MODE_0_SIGNALID 0x01
#define ORX_MODE_1_SIGNALID 0x02
#define ORX_MODE_2_SIGNALID 0x03
#define RX1_ENABLE_ACK_SIGNALID 0x04
#define RX2_ENABLE_ACK_SIGNALID 0x05
#define TX1_ENABLE_ACK_SIGNALID 0x06
#define TX2_ENABLE_ACK_SIGNALID 0x07
#define ORX1_ENABLE_ACK_SIGNALID 0x08
#define ORX2_ENABLE_ACK_SIGNALID 0x09
#define SRX_ENABLE_ACK_SIGNALID 0x0A
#define TX_OBS_SELECT_SIGNALID 0x0B
#define DISABLE_DPD_ACTUATOR 0x03
#define ENABLE_DPD_ACTUATOR 0x04
#define SET_CLGC_DESIRED_GAIN_1 0x05
#define SET_CLGC_DESIRED_GAIN_2 0x06
#define SET_PATH_DELAY 0x08
#ifdef __cplusplus
}
#endif
#endif
+176
View File
@@ -0,0 +1,176 @@
/**
* \file mykonos_user.c
* \brief Contains Mykonos default gain table values for Rx, ObsRx, and SnRx
*
* Mykonos API version: 1.5.2.3566
*/
/**
* \page Disclaimer Legal Disclaimer
* Copyright 2015-2017 Analog Devices Inc.
* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file.
*
*/
#include <stdint.h>
#include "t_mykonos.h"
#include "mykonos_user.h"
/**
* \brief Default Rx gain table settings
*/
uint8_t RxGainTable [61][4] =
{
/* Order: {FE table, External Ctl, Digital Gain/Atten, Enable Atten} */
{0, 0, 0, 0}, /* Gain index 255 */
{3, 0, 2, 1}, /* Gain index 254 */
{6, 0, 3, 1}, /* Gain index 253 */
{10, 0, 0, 0}, /* Gain index 252 */
{13, 0, 1, 1}, /* Gain index 251 */
{16, 0, 0, 0}, /* Gain index 250 */
{18, 0, 3, 1}, /* Gain index 249 */
{21, 0, 1, 1}, /* Gain index 248 */
{23, 0, 3, 1}, /* Gain index 247 */
{25, 0, 4, 1}, /* Gain index 246 */
{28, 0, 0, 0}, /* Gain index 245 */
{30, 0, 0, 0}, /* Gain index 244 */
{31, 0, 5, 1}, /* Gain index 243 */
{33, 0, 4, 1}, /* Gain index 242 */
{35, 0, 2, 1}, /* Gain index 241 */
{37, 0, 0, 0}, /* Gain index 240 */
{38, 0, 4, 1}, /* Gain index 239 */
{39, 0, 7, 1}, /* Gain index 238 */
{41, 0, 2, 1}, /* Gain index 237 */
{42, 0, 4, 1}, /* Gain index 236 */
{43, 0, 6, 1}, /* Gain index 235 */
{44, 0, 8, 1}, /* Gain index 234 */
{45, 0, 9, 1}, /* Gain index 233 */
{46, 0, 10, 1}, /* Gain index 232 */
{47, 0, 10, 1}, /* Gain index 231 */
{48, 0, 9, 1}, /* Gain index 230 */
{49, 0, 8, 1}, /* Gain index 229 */
{50, 0, 6, 1}, /* Gain index 228 */
{51, 0, 3, 1}, /* Gain index 227 */
{51, 0, 13, 1}, /* Gain index 226 */
{52, 0, 9, 1}, /* Gain index 225 */
{53, 0, 5, 1}, /* Gain index 224 */
{53, 0, 15, 1}, /* Gain index 223 */
{54, 0, 9, 1}, /* Gain index 222 */
{54, 0, 19, 1}, /* Gain index 221 */
{55, 0, 11, 1}, /* Gain index 220 */
{55, 0, 21, 1}, /* Gain index 219 */
{56, 0, 11, 1}, /* Gain index 218 */
{56, 0, 21, 1}, /* Gain index 217 */
{57, 0, 9, 1}, /* Gain index 216 */
{57, 0, 19, 1}, /* Gain index 215 */
{57, 0, 29, 1}, /* Gain index 214 */
{58, 0, 12, 1}, /* Gain index 213 */
{58, 0, 22, 1}, /* Gain index 212 */
{58, 0, 32, 1}, /* Gain index 211 */
{59, 0, 11, 1}, /* Gain index 210 */
{59, 0, 21, 1}, /* Gain index 209 */
{59, 0, 31, 1}, /* Gain index 208 */
{59, 0, 41, 1}, /* Gain index 207 */
{60, 0, 13, 1}, /* Gain index 206 */
{60, 0, 23, 1}, /* Gain index 205 */
{60, 0, 33, 1}, /* Gain index 204 */
{60, 0, 43, 1}, /* Gain index 203 */
{60, 0, 53, 1}, /* Gain index 202 */
{61, 0, 14, 1}, /* Gain index 201 */
{61, 0, 24, 1}, /* Gain index 200 */
{61, 0, 34, 1}, /* Gain index 199 */
{61, 0, 44, 1}, /* Gain index 198 */
{61, 0, 54, 1}, /* Gain index 197 */
{61, 0, 64, 1}, /* Gain index 196 */
{61, 0, 74, 1}, /* Gain index 195 */
};
/**
* \brief Default ORx gain table settings
*/
uint8_t ORxGainTable [19][4] =
{
/* Order: {FE table, External Ctl, Digital Gain/Atten, Enable Atten} */
{0, 0, 0, 0}, /* Gain index 255 */
{7, 0, 0, 0}, /* Gain index 254 */
{13, 0, 1, 1}, /* Gain index 253 */
{18, 0, 3, 1}, /* Gain index 252 */
{23, 0, 3, 1}, /* Gain index 251 */
{28, 0, 0, 0}, /* Gain index 250 */
{32, 0, 0, 0}, /* Gain index 249 */
{35, 0, 2, 1}, /* Gain index 248 */
{38, 0, 4, 1}, /* Gain index 247 */
{41, 0, 2, 1}, /* Gain index 246 */
{43, 0, 6, 1}, /* Gain index 245 */
{46, 0, 0, 0}, /* Gain index 244 */
{47, 0, 10, 1}, /* Gain index 243 */
{49, 0, 8, 1}, /* Gain index 242 */
{51, 0, 3, 1}, /* Gain index 241 */
{52, 0, 9, 1}, /* Gain index 240 */
{53, 0, 14, 1}, /* Gain index 239 */
{54, 0, 18, 1}, /* Gain index 238 */
{56, 0, 0, 0} /* Gain index 237 */
};
/**
* \brief Default SnRx gain table settings
*/
uint8_t SnRxGainTable [53][4] =
{
/* Order: {FE table, LNA Bypass, Digital Gain/Atten, Enable Atten} */
{0, 0, 0, 0}, /* Gain index 255 */
{1, 0, 7, 1}, /* Gain index 254 */
{3, 0, 1, 0}, /* Gain index 253 */
{3, 0, 15, 1}, /* Gain index 252 */
{5, 0, 0, 0}, /* Gain index 251 */
{6, 0, 2, 1}, /* Gain index 250 */
{7, 0, 2, 1}, /* Gain index 249 */
{8, 0, 12, 1}, /* Gain index 248 */
{9, 0, 7, 1}, /* Gain index 247 */
{11, 0, 1, 0}, /* Gain index 246 */
{11, 0, 15, 1},/* Gain index 245 */
{13, 0, 1, 0}, /* Gain index 244 */
{14, 0, 2, 0}, /* Gain index 243 */
{14, 0, 10, 1},/* Gain index 242 */
{15, 0, 0, 0}, /* Gain index 241 */
{15, 0, 20, 1},/* Gain index 240 */
{16, 0, 2, 1}, /* Gain index 239 */
{16, 0, 22, 1},/* Gain index 238 */
{17, 0, 1, 0}, /* Gain index 237 */
{17, 0, 15, 1},/* Gain index 236 */
{17, 0, 35, 1},/* Gain index 235 */
{17, 0, 55, 1},/* Gain index 234 */
{18, 0, 7, 1}, /* Gain index 233 */
{18, 0, 27, 1},/* Gain index 232 */
{ 6, 1, 7, 1}, /* Gain index 231 */
{ 7, 1, 7, 1}, /* Gain index 230 */
{ 8, 1, 17, 1}, /* Gain index 229 */
{ 9, 1, 12, 1}, /* Gain index 228 */
{11, 1, 0, 0}, /* Gain index 227 */
{12, 1, 3, 1}, /* Gain index 226 */
{13, 1, 0, 0}, /* Gain index 225 */
{14, 1, 1, 0}, /* Gain index 224 */
{14, 1, 15, 1},/* Gain index 223 */
{15, 1, 5, 1}, /* Gain index 222 */
{15, 1, 25, 1},/* Gain index 221 */
{16, 1, 7, 1}, /* Gain index 220 */
{16, 1, 27, 1},/* Gain index 219 */
{17, 1, 0, 0}, /* Gain index 218 */
{17, 1, 20, 1},/* Gain index 217 */
{17, 1, 40, 1},/* Gain index 216 */
{17, 1, 60, 1},/* Gain index 215 */
{18, 1, 12, 1},/* Gain index 214 */
{18, 1, 32, 1},/* Gain index 213 */
{18, 1, 52, 1},/* Gain index 212 */
{18, 1, 72, 1},/* Gain index 211 */
{18, 1, 92, 1},/* Gain index 210 */
{19, 1, 1, 0}, /* Gain index 209 */
{19, 1, 15, 1},/* Gain index 208 */
{19, 1, 35, 1},/* Gain index 207 */
{19, 1, 55, 1},/* Gain index 206 */
{19, 1, 75, 1},/* Gain index 205 */
{19, 1, 95, 1},/* Gain index 204 */
{19, 1, 115, 1}/* Gain index 203 */
};
+85
View File
@@ -0,0 +1,85 @@
/**
* \file mykonos_user.h
*
* \brief Contains macro definitions and global structure declarations for mykonos_user.c
*
* Mykonos API version: 1.5.2.3566
*/
/**
* \page Disclaimer Legal Disclaimer
* Copyright 2015-2017 Analog Devices Inc.
* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file.
*
*/
#ifndef _MYKONOSPROFILES_H_
#define _MYKONOSPROFILES_H_
#ifdef __cplusplus
extern "C" {
#endif
/* turns verbose messaging on */
#define MYKONOS_VERBOSE 1
#define MYK_ENABLE_SPIWRITEARRAY 1
/* 3 Bytes per SPI transaction * 341 transactions = ~1024 byte buffer size */
/* Minimum MYK_SPIWRITEARRAY_BUFFERSIZE = 27 */
#define MYK_SPIWRITEARRAY_BUFFERSIZE 341
/*
*****************************************
* Rx, ObsRx, and Sniffer gain tables
******************************************
*/
#define MAX_GAIN_TABLE_INDEX 255
#define START_RX_GAIN_INDEX 255
#define MAX_RX_GAIN_TABLE_NUMINDEXES (START_RX_GAIN_INDEX + 1)
#define MIN_RX_GAIN_TABLE_INDEX 0
#define START_ORX_GAIN_INDEX 47
#define MAX_ORX_GAIN_TABLE_NUMINDEXES (START_ORX_GAIN_INDEX + 1)
#define MIN_ORX_GAIN_TABLE_INDEX (MAX_GAIN_TABLE_INDEX - START_ORX_GAIN_INDEX)
#define START_SNRX_GAIN_INDEX 127
#define MAX_SNRX_GAIN_TABLE_NUMINDEXES (START_SNRX_GAIN_INDEX + 1)
#define MIN_SNRX_GAIN_TABLE_INDEX (MAX_GAIN_TABLE_INDEX - START_SNRX_GAIN_INDEX)
#define START_LOOPBACK_GAIN_INDEX 47
#define MAX_LOOPBACK_GAIN_TABLE_NUMINDEXES (START_LOOPBACK_GAIN_INDEX + 1)
#define MIN_LOOPBACK_GAIN_TABLE_INDEX (MAX_GAIN_TABLE_INDEX - START_SNRX_GAIN_INDEX)
extern uint8_t RxGainTable [61][4];
extern uint8_t ORxGainTable [19][4];
extern uint8_t SnRxGainTable [53][4];
/*
********************************************
* Rx, Sniffer, ObsRx and Tx Profiles limits
********************************************
*/
#define MIN_RX_IQRATE_KHZ 15000 /*!< Mykonos minimum IQ rate for the Rx channel, expressed in KHz */
#define MAX_RX_IQRATE_KHZ 320000 /*!< Mykonos maximum IQ rate for the Rx channel, expressed in KHz */
#define MIN_TX_IQRATE_KHZ 15000 /*!< Mykonos minimum IQ rate for the Tx channel, expressed in KHz */
#define MAX_TX_IQRATE_KHZ 492000 /*!< Mykonos maximum IQ rate for the Tx channel, expressed in KHz */
#define MIN_SNIFFER_RFBW_HZ 5000000 /*!< Mykonos minimum Sniffer channel bandwidth expressed in Hz */
#define MAX_SNIFFER_RFBW_HZ 20000000 /*!< Mykonos maximum Sniffer channel bandwidth expressed in Hz */
#define MIN_ORX_RFBW_HZ 5000000 /*!< Mykonos minimum Observation channel bandwidth expressed in Hz */
#define MAX_ORX_RFBW_HZ 250000000 /*!< Mykonos maximum Observation channel bandwidth expressed in Hz */
#define MIN_RX_RFBW_HZ 5000000 /*!< Mykonos minimum Rx channel bandwidth expressed in Hz */
#define MAX_RX_RFBW_HZ 100000000 /*!< Mykonos maximum Rx channel bandwidth expressed in Hz */
#define MIN_TX_RFBW_HZ 20000000 /*!< Mykonos minimum Tx channel bandwidth expressed in Hz */
#define MAX_TX_RFBW_HZ 250000000 /*!< Mykonos maximum Tx channel bandwidth expressed in Hz */
#ifdef __cplusplus
}
#endif
#endif
+31
View File
@@ -0,0 +1,31 @@
/**
* \file mykonos_version.h
* \brief Contains the version number for the Mykonos API
*
* Mykonos API version: 1.5.2.3566
*/
/**
* \page Disclaimer Legal Disclaimer
* Copyright 2015-2017 Analog Devices Inc.
* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in * this zip file.
*
*/
#ifndef MYKONOS_VERSION_H_
#define MYKONOS_VERSION_H_
#ifdef __cplusplus
extern "C" {
#endif
#define MYKONOS_CURRENT_SI_VERSION 1 /*!< Mykonos current silicon version */
#define MYKONOS_CURRENT_MAJOR_VERSION 5 /*!< Mykonos current ARM major version */
#define MYKONOS_CURRENT_MINOR_VERSION 2 /*!< Mykonos current ARM minor version */
#define MYKONOS_CURRENT_BUILD_VERSION 3566 /*!< Mykonos current API build version */
#ifdef __cplusplus
}
#endif
#endif /* MYKONOS_VERSION_H_ */
+194
View File
@@ -0,0 +1,194 @@
/**
* \file t_ad9528.h
* \brief Contains enum and structure data types for all AD9528 function calls
*/
/**
* \page Disclaimer Legal Disclaimer
* Copyright 2015-2017 Analog Devices Inc.
* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file.
*
*/
#ifndef _AD9528_TYPES_H_
#define _AD9528_TYPES_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "../common.h"
/* AD9528 SPI Address defines */
#define AD9528_ADDR_ADI_SPI_CONFIG_A 0x000
#define AD9528_ADDR_ADI_SPI_CONFIG_B 0x001
#define AD9528_ADDR_IO_UPDATE 0x00F
#define AD9528_ADDR_REF_A_DIVIDER_LSB 0x100
#define AD9528_ADDR_REF_A_DIVIDER_MSB 0x101
#define AD9528_ADDR_REF_B_DIVIDER_LSB 0x102
#define AD9528_ADDR_REF_B_DIVIDER_MSB 0x103
#define AD9528_ADDR_PLL1_N_DIV_LSB 0x104
#define AD9528_ADDR_PLL1_N_DIV_MSB 0x105
#define AD9528_ADDR_PLL1_CHARGEPUMP 0x106
#define AD9528_ADDR_PLL1_CP_CTRL2 0x107
#define AD9528_ADDR_INPUT_RECEIVERS1 0x108
#define AD9528_ADDR_INPUT_RECEIVERS2 0x109
#define AD9528_ADDR_INPUT_RECEIVERS3 0x10A
#define AD9528_ADDR_PLL1_FASTLOCK 0x10B
#define AD9528_ADDR_PLL2_CHARGEPUMP 0x200
#define AD9528_ADDR_PLL2_N_DIV 0x201
#define AD9528_ADDR_PLL2_CTRL 0x202
#define AD9528_ADDR_PLL2_VCO_CTRL 0x203
#define AD9528_ADDR_PLL2_VCO_DIV 0x204
#define AD9528_ADDR_PLL2_LF_CTRL1 0x205
#define AD9528_ADDR_PLL2_LF_CTRL2 0x206
#define AD9528_ADDR_PLL2_RDIV 0x207
#define AD9528_ADDR_PLL2_REPLICA_CHDIV 0x208
#define AD9528_ADDR_PLL2_REPLICA_DIV_PHASE 0x209
#define AD9528_ADDR_CH_OUT0_CTRL1 0x300
#define AD9528_ADDR_CH_OUT0_CTRL2 0x301
#define AD9528_ADDR_CH_OUT0_CHDIV 0x302
#define AD9528_ADDR_OUTPUT_SYNC 0x32A
#define AD9528_ADDR_MASK_SYNC1 0x32B
#define AD9528_ADDR_MASK_SYNC2 0x32C
#define AD9528_ADDR_EN_OUTPUT_PATH_SEL1 0x32D
#define AD9528_ADDR_EN_OUTPUT_PATH_SEL2 0x32E
#define AD9528_ADDR_SYSERF_DIV_LSB 0x400
#define AD9528_ADDR_SYSERF_DIV_MSB 0x401
#define AD9528_ADDR_SYSREF_CTRL3 0x402
#define AD9528_ADDR_SYSREF_CTRL4 0x403
#define AD9528_ADDR_SYSREF_CTRL5 0x404
#define AD9528_ADDR_POWERDOWN_CTRL 0x500
#define AD9528_ADDR_CH_POWERDOWN1 0x501
#define AD9528_ADDR_CH_POWERDOWN2 0x502
#define AD9528_ADDR_LDO_ENABLES1 0x503
#define AD9528_ADDR_LDO_ENABLES2 0x504
#define AD9528_ADDR_STATUS0_CTRL 0x505
#define AD9528_ADDR_STATUS1_CTRL 0x506
#define AD9528_ADDR_STATUS_OE 0x507
#define AD9528_ADDR_STATUS_READBACK0 0x508
#define AD9528_ADDR_STATUS_READBACK1 0x509
///Enum to select what source outputs from each AD9528 output channel
typedef enum
{
CHANNEL_DIV = 0, PLL1_OUTPUT = 1, //VCXO frequency
SYSREF = 2,
INV_PLL1_OUTPUT = 5 //VCXO inverted
} ad9528outSourceSel_t;
///Enum to select what output buffer standard is used for the clock outputs
typedef enum
{
LVDS = 0, LVDS_BOOST = 1, HSTL = 2
} ad9528outBufferControl_t;
///Enum to select the clock input buffer mode.
typedef enum
{
DISABLED = 0, SINGLE_ENDED, NEG_SINGLE_ENDED, DIFFERENTIAL
} ad9528RefBuffer_t;
/// Structure to hold AD9528 PLL1 settings
typedef struct
{
uint32_t refA_Frequency_Hz;
uint16_t refA_Divider;
ad9528RefBuffer_t refA_bufferCtrl;
uint32_t refB_Frequency_Hz;
uint16_t refB_Divider;
ad9528RefBuffer_t refB_bufferCtrl;
uint32_t vcxo_Frequency_Hz;
ad9528RefBuffer_t vcxoBufferCtrl;
uint16_t nDivider;
uint8_t bypassPll1;
} ad9528pll1Settings_t;
/// Structure to hold AD9528 PLL2 settings
typedef struct
{
uint8_t rfDivider; //VCO divider: Valid range (3,4,5)
uint8_t n2Divider; //PLL2 N2 Divider
uint8_t totalNdiv; //NDiv = 4*Bdiv + Adiv //Bdiv valid range (3 to 63), Adiv valid range (0-3)
} ad9528pll2Settings_t;
/// Structure to hold AD9528 Output Clock settings
typedef struct
{
uint16_t outPowerDown; //bit per output, if 1 power down that output.
ad9528outSourceSel_t outSource[14]; //CHANNEL_DIV, PLL1_OUTPUT, SYSREF, INV_PLL1_OUTPUT
ad9528outBufferControl_t outBufferCtrl[14]; //LVDS, LVDS_BOOST, HSTL
uint8_t outAnalogDelay[14]; //5 bits
uint8_t outDigitalDelay[14]; //6 bits, 1/2 clock resolution @ channel div input frequency
uint8_t outChannelDiv[14]; //8 bit channel divider
uint32_t outFrequency_Hz[14]; //output clock frequency per clock output
} ad9528outputSettings_t;
///Enum to select the SYSREF output source
typedef enum
{
EXTERNAL = 0, EXT_RESAMPLED = 1, INTERNAL = 2
} sysrefSourceSelection_t;
///Enum to choose the SYSREF pattern mode.
typedef enum
{
NSHOT = 0, CONTINUOUS = 1, PRBS = 2, STOP = 3
} sysrefPatternMode_t;
///Enum to select the SYSREF input pin mode.
typedef enum
{
LEVEL_ACTIVE_HIGH = 0, LEVEL_ACTIVE_LOW = 1, RISING_EDGE = 2, FALLING_EDGE = 3
} sysrefPinEdgeMode_t;
///Enum to select the SYSREF output # of pulses for NSHOT mode.
typedef enum
{
ONE_PULSE = 0, TWO_PULSES = 2, FOUR_PULSES = 3, SIX_PULSES = 4, EIGHT_PULSES = 5
} sysrefNshotMode_t;
//Enum to select how a SYSREF is requested.
typedef enum
{
SPI = 0, PIN = 1
} sysrefRequestMethod_t;
/// Structure to hold AD9528 SYSREF output settings
typedef struct
{
sysrefRequestMethod_t sysrefRequestMethod;
sysrefSourceSelection_t sysrefSource;
sysrefPinEdgeMode_t sysrefPinEdgeMode;
ad9528RefBuffer_t sysrefPinBufferMode;
sysrefPatternMode_t sysrefPatternMode;
sysrefNshotMode_t sysrefNshotMode;
uint16_t sysrefDivide;
} ad9528sysrefSettings_t;
/// Structure to hold AD9528 settings
typedef struct
{
spiSettings_t *spiSettings;
ad9528pll1Settings_t *pll1Settings;
ad9528pll2Settings_t *pll2Settings;
ad9528outputSettings_t *outputSettings;
ad9528sysrefSettings_t *sysrefSettings;
} ad9528Device_t;
#ifdef __cplusplus
}
#endif
#endif
File diff suppressed because it is too large Load Diff
+375
View File
@@ -0,0 +1,375 @@
/*!
* \file t_mykonos_gpio.h
* \brief Mykonos GPIO error handling and type defines
*
* Mykonos API version: 1.5.2.3566
*/
/**
* \page Disclaimer Legal Disclaimer
* Copyright 2015-2017 Analog Devices Inc.
* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file.
*
*/
#ifndef T_MYKONOSGPIO_H_
#define T_MYKONOSGPIO_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "../common.h"
/**
* \brief Enum of unique error codes from the Mykonos GPIO API functions.
* Each error condition in the library should get its own enum value to allow
* easy debug of errors.
*/
typedef enum
{
MYKONOS_ERR_GPIO_OK = 0,
MYKONOS_ERR_EN_MONITOR_OUT_NOT_ENABLED,
MYKONOS_ERR_EN_MONITOR_OUT_SRC_CTRL,
MYKONOS_ERR_MONITOR_OUT_INDEX_RANGE,
MYKONOS_ERR_GETGPIOMON_INDEX_NULL_PARM,
MYKONOS_ERR_GETGPIOMON_MONITORMASK_NULL_PARM,
MYKONOS_ERR_MGCRX2_GPIO_DECPIN_INV_PARAM,
MYKONOS_ERR_MGCRX2_GPIO_INCPIN_INV_PARAM,
MYKONOS_ERR_MGCRX2_SOURCE_CONFIG,
MYKONOS_ERR_MGCRX2_STEP_INV_PARAM,
MYKONOS_ERR_MGCRX1_GPIO_DECPIN_INV_PARAM,
MYKONOS_ERR_MGCRX1_GPIO_INCPIN_INV_PARAM,
MYKONOS_ERR_MGCRX1_STEP_INV_PARAM,
MYKONOS_ERR_GETRX2PIN_INCSTEP_NULL_PARM,
MYKONOS_ERR_GETRX2PIN_DECSTEP_NULL_PARM,
MYKONOS_ERR_GETRX2PIN_INCPIN_NULL_PARM,
MYKONOS_ERR_GETRX2PIN_DECPIN_NULL_PARM,
MYKONOS_ERR_GETRX2PIN_EN_NULL_PARM,
MYKONOS_ERR_GETRX1PIN_INCSTEP_NULL_PARM,
MYKONOS_ERR_GETRX1PIN_DECSTEP_NULL_PARM,
MYKONOS_ERR_GETRX1PIN_INCPIN_NULL_PARM,
MYKONOS_ERR_GETRX1PIN_DECPIN_NULL_PARM,
MYKONOS_ERR_GETRX1PIN_EN_NULL_PARM,
MYKONOS_ERR_TPCTX2_GPIO_DECPIN_INV_PARAM,
MYKONOS_ERR_TPCTX2_GPIO_INCPIN_INV_PARAM,
MYKONOS_ERR_TPCTX2_GPIO_STEP_INV_PARAM,
MYKONOS_ERR_TPCTX1_GPIO_DECPIN_INV_PARAM,
MYKONOS_ERR_TPCTX1_GPIO_INCPIN_INV_PARAM,
MYKONOS_ERR_TPCTX1_GPIO_STEP_INV_PARAM,
MYKONOS_ERR_GETTX2PIN_STEP_NULL_PARM,
MYKONOS_ERR_GETTX2PIN_INC_NULL_PARM,
MYKONOS_ERR_GETTX2PIN_DEC_NULL_PARM,
MYKONOS_ERR_GETTX2PIN_EN_NULL_PARM,
MYKONOS_ERR_GETTX2PIN_TX1TX2_NULL_PARM,
MYKONOS_ERR_GETTX1PIN_STEP_NULL_PARM,
MYKONOS_ERR_GETTX1PIN_INC_NULL_PARM,
MYKONOS_ERR_GETTX1PIN_DEC_NULL_PARM,
MYKONOS_ERR_GETTX1PIN_EN_NULL_PARM,
MYKONOS_ERR_GETTX1PIN_TX1TX2_NULL_PARM,
MYKONOS_ERR_SPI2_INV_GPIO,
MYKONOS_ERR_SPI2_INV_SETUP,
MYKONOS_ERR_SET_GPIO_1V8_INV_POINTER,
MYKONOS_ERR_GETGPIOSETLEVEL_NULL_PARM,
MYKONOS_ERR_READGPIOSPI_NULL_PARM,
MYKONOS_ERR_SET_GPIO_1V8_INV_MODE,
MYKONOS_ERR_GETGPIO_OE_NULL_PARM,
MYKONOS_ERR_GPIO_OE_INV_PARAM,
MYKONOS_ERR_GPIO_SRC_PARAM_INV,
MYKONOS_ERR_GET_GPIO_SOURCE_CONTROL_NULL_PARM,
MYKONOS_ERR_INV_GP_INT_MASK_PARM,
MYKONOS_ERR_GP_INT_STATUS_NULL_PARAM,
MYKONOS_ERR_GETGPIO3V3OUT_NULL_PARM,
MYKONOS_ERR_SET_GPIO_3V3_INV_POINTER,
MYKONOS_ERR_GETGPIO3V3SPI_NULL_PARM,
MYKONOS_ERR_GPIO3V3OUTEN_NULL_PARM,
MYKONOS_ERR_SET_GPIO_3V3_INV_MODE,
MYKONOS_ERR_SET_GPIO_3V3_INV_SRC_CTRL,
MYKONOS_ERR_SET_ARMGPIO_INV_POINTER,
MYKONOS_ERR_SET_ARMGPIO_PINS_ARMERROR,
MYKONOS_ERR_SET_ARMGPIO_PINS_INV_SIGNALID,
MYKONOS_ERR_SET_ARMGPIO_PINS_INV_GPIOPIN,
MYKONOS_ERR_SETUPAUXDAC_NULL_PARAM,
MYKONOS_ERR_WRITEAUXDAC_NULL_AUXIO,
MYKONOS_ERR_READAUXADC_NULL_PARAM,
MYKONOS_ERR_SETUPAUXDAC_INV_AUXDACCODE,
MYKONOS_ERR_WRITEAUXDAC_INV_AUXDACCODE,
MYKONOS_ERR_WRITEAUXDAC_INV_AUXDACINDEX,
MYKONOS_ERR_INV_AUX_ADC_CHAN_PARM,
MYKONOS_ERR_SETUPAUXADC_INV_VCODIV,
MYKONOS_ERR_INV_AUX_ADC_DEC_PARM,
MYKONOS_ERR_GAINCOMP_NULL_STRUCT,
MYKONOS_ERR_GAINCOMP_EN_NULL_PARM,
MYKONOS_ERR_GAINCOMP_SET_NULL_STRUCT,
MYKONOS_ERR_GAINCOMP_INV_RX1_OFFSET,
MYKONOS_ERR_GAINCOMP_INV_RX2_OFFSET,
MYKONOS_ERR_GAINCOMP_INV_STEP,
MYKONOS_ERR_GAINCOMP_INV_EN,
MYKONOS_ERR_OBS_RX_GAINCOMP_SET_NULL_STRUCT,
MYKONOS_ERR_OBS_RX_GAINCOMP_EN_NULL_PARAM,
MYKONOS_ERR_OBS_RX_GAINCOMP_INV_EN,
MYKONOS_ERR_OBS_RX_GAINCOMP_INV_OFFSET,
MYKONOS_ERR_OBS_RX_GAINCOMP_INV_STEP,
MYKONOS_ERR_OBS_RX_GAINCOMP_NULL_STRUCT,
MYKONOS_ERR_SLICER_STEP_OUT_OF_RANGE,
MYKONOS_ERR_SLICER_INV_RX1_SEL,
MYKONOS_ERR_SLICER_INV_RX2_SEL,
MYKONOS_ERR_SLICER_EN_INV,
MYKONOS_ERR_SLICER_RX1PIN_NULL_PARM,
MYKONOS_ERR_SLICER_RX2PIN_NULL_PARM,
MYKONOS_ERR_SLICER_STEP_NULL_PARM,
MYKONOS_ERR_SLICER_EN_NULL_PARM,
MYKONOS_ERR_SLICER_INV_OBS_RX_SEL,
MYKONOS_ERR_SLICER_OBS_RX_STEP_OUT_OF_RANGE,
MYKONOS_ERR_SLICER_OBS_RX_EN_INV,
MYKONOS_ERR_SLICER_OBS_RX_EN_NULL_PARM,
MYKONOS_ERR_SLICER_OBS_RX_STEP_NULL_PARM,
MYKONOS_ERR_SLICER_OBS_RXPIN_NULL_PARM,
MYKONOS_ERR_FLOATFRMT_NULL_STRUCT,
MYKONOS_ERR_FLOATFRMT_SET_NULL_STRUCT,
MYKONOS_ERR_FLOATFRMT_INV_ROUND_MODE,
MYKONOS_ERR_FLOATFRMT_INV_DATA_FORMAT,
MYKONOS_ERR_FLOATFRMT_INV_ENC_NAN,
MYKONOS_ERR_FLOATFRMT_INV_EXP_BITS,
MYKONOS_ERR_FLOATFRMT_INV_LEADING,
MYKONOS_ERR_FLOATFRMT_INV_RX1ATT,
MYKONOS_ERR_FLOATFRMT_INV_RX2ATT,
MYKONOS_ERR_FLOATFRMT_INV_EN,
MYKONOS_ERR_FLOATFRMT_NULL_RX1ATT,
MYKONOS_ERR_FLOATFRMT_NULL_RX2ATT,
MYKONOS_ERR_FLOATFRMT_NULL_ENABLE,
MYKONOS_ERR_FLOATFRMT_SET_INV_EN,
MYKONOS_ERR_FLOATFRMT_SET_INV_RX1ATT,
MYKONOS_ERR_FLOATFRMT_SET_INV_RX2ATT,
MYKONOS_ERR_FLOATFRMT_INV_ORXATT,
MYKONOS_ERR_FLOATFRMT_INV_ORXEN,
MYKONOS_ERR_FLOATFRMT_NULL_ORXATT,
MYKONOS_ERR_FLOATFRMT_NULL_ORXENABLE,
MYKONOS_ERR_SETUPTEMPSENSOR_NULL_PARAM,
MYKONOS_ERR_SETUPTEMPSENSOR_INV_TEMPDECIMATION,
MYKONOS_ERR_SETUPTEMPSENSOR_INV_OFFSET,
MYKONOS_ERR_SETUPTEMPSENSOR_INV_TEMPWINDOW,
MYKONOS_ERR_GETTEMPSENSORCFG_NULL_PARAM,
MYKONOS_ERR_READTEMPSENSOR_NULL_PARAM,
MYKONOS_ERR_READTEMPSENSOR_NOT_LOCKED,
MYKONOS_ERR_GAIN_CONTROL_NOT_HYBRID,
MYKONOS_ERR_GPIO_HYBRID_RX1_PIN,
MYKONOS_ERR_GPIO_HYBRID_RX2_PIN,
MYKONOS_ERR_GPIO_HYBRID_RX1_PIN_NULL_PARM,
MYKONOS_ERR_GPIO_HYBRID_RX2_PIN_NULL_PARM,
MYKONOS_ERR_GPIO_HYBRID_RX1_PIN_READ,
MYKONOS_ERR_GPIO_HYBRID_RX2_PIN_READ,
MYKONOS_ERR_AGC_OBS_NOT_IN_HYBRID,
MYKONOS_ERR_GPIO_HYBRID_ORX_PIN,
MYKONOS_ERR_GPIO_HYBRID_ORX_PIN_NULL_PARM,
MYKONOS_ERR_GAIN_CONTROL_NOT_AGC,
MYKONOS_ERR_GPIO_AGC_SYNC_RX1_PIN,
MYKONOS_ERR_GPIO_AGC_SYNC_RX2_PIN,
MYKONOS_ERR_GPIO_AGC_SYNC_RX1_PIN_NULL_PARM,
MYKONOS_ERR_GPIO_AGC_SYNC_RX2_PIN_NULL_PARM,
MYKONOS_ERR_OBS_GAIN_CONTROL_NOT_AGC,
MYKONOS_ERR_GPIO_AGC_SYNC_ORX_PIN,
MYKONOS_ERR_GPIO_AGC_SYNC_ORX_PIN_NULL_PARM,
MYKONOS_ERR_GETGPIODRV_NULL_PARAM,
MYKONOS_ERR_GPIO_DRV_INV_PARAM,
MYKONOS_ERR_GPIO_SLEW_RATE_INV_PARAM,
MYKONOS_ERR_GPIO_GETSLEW_NULL_PARAM,
MYKONOS_ERR_CMOS_DRV_INV_PARAM,
MYKONOS_ERR_CMOS_DRV_NULL_PARAM
} mykonosGpioErr_t;
/**
* \brief Enum of possible Rx Slicer pin combinations
*/
typedef enum
{
GPIO_0_1_2 = 0, /*!< GPIO combination for RX1 */
GPIO_5_6_7 = 1, /*!< GPIO combination for RX1 or RX2 */
GPIO_8_9_10 = 2, /*!< GPIO combination for RX1 */
GPIO_11_12_13 = 3 /*!< GPIO combination for RX2 */
} mykonosRxSlicer_t;
/**
* \brief Enum of possible observation channel Slicer pin combinations
*/
typedef enum
{
GPIO_18_17_16 = 0, /*!< GPIO combination for observation channel */
GPIO_16_15_14 = 1 /*!< GPIO combination for observation channel */
} mykonosObsRxSlicer_t;
/**
* \brief Enum of possible GPIO slew rate settings
*/
typedef enum
{
MYK_SLEWRATE_NONE = 0, /*!< Lower slew rate for the GPIO */
MYK_SLEWRATE_LOW = 1, /*!< Low slew rate for the GPIO */
MYK_SLEWRATE_MEDIUM = 2, /*!< Medium slew rate for the GPIO */
MYK_SLEWRATE_HIGH = 3 /*!< High slew rate for the GPIO */
} mykonosGpioSlewRate_t;
/**
* \brief Enumerated list of CMOS pads drive strength options
*/
typedef enum
{
MYK_CMOSPAD_DRV_1X = 0x00, /*!< 2.5pF load @ 65MHz */
MYK_CMOSPAD_DRV_2X = 0x01, /*!< 5pF load @ 65MHz */
MYK_CMOSPAD_DRV_3X = 0x03, /*!< 7.5pF load @ 65MHz */
MYK_CMOSPAD_DRV_4X = 0x07, /*!< 10pF load @ 65MHz */
MYK_CMOSPAD_DRV_5X = 0x0F /*!< 12.5pF load @ 65MHz */
} mykonosCmosPadDrvStr_t;
/**
* \brief Enumerated list for Aux ADCs
*/
typedef enum
{
MYK_AUXADC_0 = 0x00, /*!< Aux ADC channel 0 */
MYK_AUXADC_1 = 0x01, /*!< Aux ADC channel 1 */
MYK_AUXADC_2 = 0x02, /*!< Aux ADC channel 2 */
MYK_AUXADC_3 = 0x03, /*!< Aux ADC channel 3 */
MYK_AUXADC_0_DIV2 = 0x04, /*!< Aux ADC channel 0 with the divider by 2 set */
MYK_TEMPSENSOR = 0x10 /*!< Temperature sensor channel */
} mykonosAuxAdcChannels_t;
/**
* \brief Data structure to hold Gain compensation settings for the main receive channels
**/
typedef struct
{
uint8_t rx1Offset; /*!< These parameter contains the Rx1 offset word used for the gain compensation
when the gain index is at its maximum setting.
It has a range of 0 to 0x1F with a resolution is 0.5dB per LSB. */
uint8_t rx2Offset; /*!< These parameter contains the Rx2 offset word used for the gain compensation
when the gain index is at its maximum setting.
It has a range of 0 to 0x1F with a resolution is 0.5dB per LSB. */
uint8_t compStep; /*!< These bits contains the value in dB that the total Rx gain changes
when there is an LSB change in the gain index according to the following settings:
compStep | dB ramp
---------|------------
0 | 0.25dB
1 | 0.5dB
2 | 1.0dB
3 | 2.0dB
4 | 3.0dB
5 | 4.0dB
6 | 6.0dB
7 | Not valid defaulted to 0.25dB */
} mykonosGainComp_t;
/**
* \brief Data structure to hold Gain compensation settings for the observation channel
**/
typedef struct
{
uint8_t obsRxOffset; /*!< These parameter contains the Rx1 offset word used for the gain compensation
when the gain index is at its maximum setting.
It has a range of 0 to 0x1F with a resolution is 0.5dB per LSB. */
uint8_t compStep; /*!< These bits contains the value in dB that the total Rx gain changes
when there is an LSB change in the gain index according to the following settings:
compStep | dB ramp
---------|------------
0 | 0.25dB
1 | 0.5dB
2 | 1.0dB
3 | 2.0dB
4 | 3.0dB
5 | 4.0dB
6 | 6.0dB
7 | Not valid defaulted to 0.25dB */
} mykonosObsRxGainComp_t;
/**
* \brief Data structure to hold floating point formatter settings for the floating point
* number generation
**/
typedef struct
{
uint8_t roundMode; /*!<These parameter set the round modes for the significand.
The following settings are defined in the IEEE754 specification:
roundMode | Round type
----------|-----------------
0 | RoundTiesToEven
1 | RoundTowardsPositive
2 | RoundTowardsNegative
3 | RoundTowardsZero
4 | RoundTiesToAway*/
uint8_t dataFormat; /*!< These parameter sets the format of the 16-bit output on the JESD interface:
Setting this to 1 then the format is from MSB to LSB to {sign, significand, exponent}.
Clearing this bit sets the format to {sign, exponent, significand}.*/
uint8_t encNan; /*!< if this parameter is set to 1 then the floating point formatter reserves the highest value
of exponent for NaN to be compatible to the IEEE754 specification.
Clearing this parameter increases the range of the exponent by one.*/
uint8_t expBits; /*!<These parameter is used to indicate the number of exponent bits in the floating point number
according to the following settings:
expBits| Round type
--------|------------------------------------------------
0 | 2 bit exponent, 13 bit significand, 1 bit sign
1 | 3 bit exponent, 12 bit significand, 1 bit sign
2 | 4 bit exponent, 11 bit significand, 1 bit sign
3 | 5 bit exponent, 10 bit significand, 1 bit sign */
uint8_t leading; /*!< Setting this parameter hides the leading one in the the significand to be compatible to the IEEE754 specification.
Clearing this parameter causes the leading one to be at the MSB of the significand.*/
}mykonosFloatPntFrmt_t;
/**
* \brief Data structure used to configure the on-die Temperature Sensor
*/
typedef struct
{
uint8_t tempDecimation; /*!<3-bit value that controls the AuxADC decimation factor when used for temp sensor calculations;
AuxADC_decimation = 256 * 2^tempDecimation */
uint8_t offset; /*!< 8-bit offset that gets added to temp sensor code internally */
uint8_t overrideFusedOffset; /*!< This bit overrides the factory-calibrated fuse offset
and uses the value stored in the offset member */
uint8_t tempWindow; /*!< 4-bit code with a resolution of 1?C/LSB, each time a temperature measurement is performed,
the device compares the current temperature against the previous value.*/
}mykonosTempSensorConfig_t;
/**
* \brief Data structure used to store Temperature Sensor related values
*/
typedef struct
{
int16_t tempCode; /*!< 16-bit signed temperature value (in deg C) that is read back */
uint8_t windowExceeded; /*!< If the absolute value of the difference is greater than the value in temperature configuration
tempWindow, the windowExceeded flag is set.*/
uint8_t windowHiLo; /*!<when windowExceeded member gets set,
this bit is set to 1 if current value is greater than previous value, else reset */
uint8_t tempValid; /*!< When the reading is complete and a valid temperature value stored in tempCode*/
}mykonosTempSensorStatus_t;
#ifdef __cplusplus
}
#endif
#endif /* T_MYKONOSGPIO_H_ */
@@ -1,7 +1,7 @@
/***************************************************************************//** /***************************************************************************//**
* @file xilinx/xilinx_delay.c * @file ad9371/src/devices/adi_hal/parameters.h
* @brief Implementation of Xilinx Delay Functions. * @brief Platform dependent parameters.
* @author Antoniu Miclaus (antoniu.miclaus@analog.com) * @author DBogdan (dragos.bogdan@analog.com)
******************************************************************************** ********************************************************************************
* Copyright 2019(c) Analog Devices, Inc. * Copyright 2019(c) Analog Devices, Inc.
* *
@@ -36,65 +36,46 @@
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * 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. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/ *******************************************************************************/
#ifndef _PARAMETERS_H_
#define _PARAMETERS_H_
/******************************************************************************/ /******************************************************************************/
/***************************** Include Files **********************************/ /***************************** Include Files **********************************/
/******************************************************************************/ /******************************************************************************/
#include "platform_drivers.h"
#include "delay.h" #include "xparameters.h"
#include <sleep.h>
#ifdef _XPARAMETERS_PS_H_
#include "util.h"
#include "xtime_l.h"
#endif
/******************************************************************************/ /******************************************************************************/
/************************ Functions Definitions *******************************/ /********************** Macros and Constants Definitions **********************/
/******************************************************************************/ /******************************************************************************/
#define DDR_MEM_BASEADDR XPAR_DDR_MEM_BASEADDR
#define GPIO_0_DEVICE_ID XPAR_PS7_GPIO_0_DEVICE_ID
//#define FREQ_CTRL_DEVICE_ID XPAR_AXI_9731_FREQ_CTRL_DEVICE_ID
//#define GAIN_CTRL_DEVICE_ID XPAR_AXI_9731_RX_GAIN_DEVICE_ID
//#define ATTN_CTRL_DEVICE_ID XPAR_AXI_9731_TX_ATTN_DEVICE_ID
//
//#define FREQ_CTRL_INTR_ID XPAR_FABRIC_AXI_9731_FREQ_CTRL_IP2INTC_IRPT_INTR
//#define GAIN_CTRL_INTR_ID XPAR_FABRIC_AXI_9731_RX_GAIN_IP2INTC_IRPT_INTR
//#define ATTN_CTRL_INTR_ID XPAR_FABRIC_AXI_9731_TX_ATTN_IP2INTC_IRPT_INTR
#define GPIO_OFFSET 54
#define AD9528_CS 1
#define AD9371_CS 2
#define TX_FREQ_INTR_MASK XGPIO_IR_CH1_MASK
#define RX_FREQ_INTR_MASK XGPIO_IR_CH2_MASK
#define TX1_ATTN_INTR_MASK XGPIO_IR_CH1_MASK
#define TX2_ATTN_INTR_MASK XGPIO_IR_CH2_MASK
#define RX1_ATTN_INTR_MASK XGPIO_IR_CH1_MASK
#define RX2_ATTN_INTR_MASK XGPIO_IR_CH2_MASK
#define AXI_GPIO_BANK_1 1
#define AXI_GPIO_BANK_2 2
//#define DAC_GPIO_PLDDR_BYPASS GPIO_OFFSET + 60
#define AD9528_RESET_B GPIO_OFFSET + 4
#define AD9528_SYSREF_REQ GPIO_OFFSET + 3
#define AD9371_RESET_B GPIO_OFFSET + 1
/**
* @brief Generate microseconds delay.
* @param usecs - Delay in microseconds.
* @return None.
*/
void udelay(uint32_t usecs)
{
#ifdef _XPARAMETERS_PS_H_
usleep(usecs);
#else
usleep_MB(usecs);
#endif #endif
}
/**
* @brief Generate miliseconds delay.
* @param msecs - Delay in miliseconds.
* @return None.
*/
void mdelay(uint32_t msecs)
{
#ifdef _XPARAMETERS_PS_H_
usleep(msecs * 1000);
#else
usleep_MB(msecs * 1000);
#endif
}
/**
* @brief Get current time.
* @return Current time structure from system start (seconds, microseconds).
*/
struct time get_time(void)
{
struct time t = {0, 0};
#ifdef _XPARAMETERS_PS_H_
unsigned long long Xtime_Global;
uint32_t rem;
XTime_GetTime(&Xtime_Global);
t.s = div_u64_rem(Xtime_Global, COUNTS_PER_SECOND, &rem);
t.us = div_u64((uint64_t)rem * 1000000, COUNTS_PER_SECOND);
#endif
return t;
}
+395
View File
@@ -0,0 +1,395 @@
/***************************************************************************//**
* @file platform_drivers.c
* @brief Implementation of Xilinx Platform Drivers.
* @author DBogdan ([email protected])
********************************************************************************
* Copyright 2018(c) Analog Devices, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* - Neither the name of Analog Devices, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* - The use of this software may or may not infringe the patent rights
* of one or more patent holders. This license does not release you
* from the requirement that you obtain separate licenses from these
* patent holders to use this software.
* - Use of the software either in source or binary form, must be run
* on or directly connected to an Analog Devices Inc. component.
*
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <stdlib.h>
#include <sleep.h>
#include "platform_drivers.h"
/******************************************************************************/
/************************ Functions Definitions *******************************/
/******************************************************************************/
/**
* @brief Initialize the SPI communication peripheral.
* @param desc - The SPI descriptor.
* @param init_param - The structure that contains the SPI parameters.
* @return SUCCESS in case of success, FAILURE otherwise.
*/
int32_t spi_init(struct spi_desc **desc,
const struct spi_init_param *param)
{
spi_desc *descriptor;
int32_t ret;
descriptor = (struct spi_desc *) calloc(1, sizeof(*descriptor));
if (!descriptor)
return FAILURE;
descriptor->mode = param->mode;
descriptor->chip_select = param->chip_select;
descriptor->flags = param->flags;
#ifdef _XPARAMETERS_PS_H_
descriptor->config = XSpiPs_LookupConfig(param->id);
if (descriptor->config == NULL)
goto error;
ret = XSpiPs_CfgInitialize(&descriptor->instance,
descriptor->config, descriptor->config->BaseAddress);
if (ret != 0)
goto error;
XSpiPs_SetOptions(&descriptor->instance,
XSPIPS_MASTER_OPTION |
((descriptor->flags & SPI_CS_DECODE) ?
XSPIPS_DECODE_SSELECT_OPTION : 0) |
XSPIPS_FORCE_SSELECT_OPTION |
((descriptor->mode & SPI_CPOL) ?
XSPIPS_CLK_ACTIVE_LOW_OPTION : 0) |
((descriptor->mode & SPI_CPHA) ?
XSPIPS_CLK_PHASE_1_OPTION : 0));
XSpiPs_SetClkPrescaler(&descriptor->instance,
XSPIPS_CLK_PRESCALE_64);
XSpiPs_SetSlaveSelect(&descriptor->instance, 0xf);
#else
ret = XSpi_Initialize(&descriptor->instance, param->id);
if (ret != 0)
goto error;
XSpi_SetOptions(&descriptor->instance,
XSP_MASTER_OPTION |
((descriptor->mode & SPI_CPOL) ?
XSP_CLK_ACTIVE_LOW_OPTION : 0) |
((descriptor->mode & SPI_CPHA) ?
XSP_CLK_PHASE_1_OPTION : 0));
XSpi_Start(&descriptor->instance);
XSpi_IntrGlobalDisable(&descriptor->instance);
#endif
*desc = descriptor;
return SUCCESS;
error:
free(descriptor);
return FAILURE;
}
/**
* @brief Free the resources allocated by spi_init().
* @param desc - The SPI descriptor.
* @return SUCCESS in case of success, FAILURE otherwise.
*/
int32_t spi_remove(struct spi_desc *desc)
{
if (desc) {
// Unused variable - fix compiler warning
}
return SUCCESS;
}
/**
* @brief Write and read data to/from SPI.
* @param desc - The SPI descriptor.
* @param data - The buffer with the transmitted/received data.
* @param bytes_number - Number of bytes to write/read.
* @return SUCCESS in case of success, FAILURE otherwise.
*/
int32_t spi_write_and_read(struct spi_desc *desc,
uint8_t *data,
uint8_t bytes_number)
{
#ifdef _XPARAMETERS_PS_H_
XSpiPs_SetOptions(&desc->instance,
XSPIPS_MASTER_OPTION |
((desc->flags & SPI_CS_DECODE) ?
XSPIPS_DECODE_SSELECT_OPTION : 0) |
XSPIPS_FORCE_SSELECT_OPTION |
((desc->mode & SPI_CPOL) ?
XSPIPS_CLK_ACTIVE_LOW_OPTION : 0) |
((desc->mode & SPI_CPHA) ?
XSPIPS_CLK_PHASE_1_OPTION : 0));
XSpiPs_SetSlaveSelect(&desc->instance, desc->chip_select);
// 0xf & ~desc->chip_select);
XSpiPs_PolledTransfer(&desc->instance,
data, data, bytes_number);
#else
XSpi_SetOptions(&desc->instance,
XSP_MASTER_OPTION |
((desc->mode & SPI_CPOL) ?
XSP_CLK_ACTIVE_LOW_OPTION : 0) |
((desc->mode & SPI_CPHA) ?
XSP_CLK_PHASE_1_OPTION : 0));
XSpi_SetSlaveSelect(&desc->instance,
desc->chip_select);
XSpi_Transfer(&desc->instance,
data, data, bytes_number);
#endif
return 0;
}
/**
* @brief Obtain the GPIO decriptor.
* @param desc - The GPIO descriptor.
* @param gpio_number - The number of the GPIO.
* @return SUCCESS in case of success, FAILURE otherwise.
*/
int32_t gpio_get(struct gpio_desc **desc,
uint8_t gpio_number)
{
gpio_desc *descriptor;
int32_t ret;
descriptor = (struct gpio_desc *) malloc(sizeof(*descriptor));
if (!descriptor)
return FAILURE;
#ifdef _XPARAMETERS_PS_H_
descriptor->config = XGpioPs_LookupConfig(0);
if (descriptor->config == NULL)
goto error;
ret = XGpioPs_CfgInitialize(&descriptor->instance,
descriptor->config, descriptor->config->BaseAddr);
if (ret != 0)
goto error;
#else
ret = XGpio_Initialize(&descriptor->instance, 0);
if (ret != 0)
goto error;
#endif
descriptor->number = gpio_number;
*desc = descriptor;
return SUCCESS;
error:
free(descriptor);
return FAILURE;
}
/**
* @brief Free the resources allocated by gpio_get().
* @param desc - The SPI descriptor.
* @return SUCCESS in case of success, FAILURE otherwise.
*/
int32_t gpio_remove(struct gpio_desc *desc)
{
if (desc) {
// Unused variable - fix compiler warning
}
return SUCCESS;
}
/**
* @brief Enable the input direction of the specified GPIO.
* @param desc - The GPIO descriptor.
* @return SUCCESS in case of success, FAILURE otherwise.
*/
int32_t gpio_direction_input(struct gpio_desc *desc)
{
if (desc) {
// Unused variable - fix compiler warning
}
return 0;
}
/**
* @brief Enable the output direction of the specified GPIO.
* @param desc - The GPIO descriptor.
* @param value - The value.
* Example: GPIO_HIGH
* GPIO_LOW
* @return SUCCESS in case of success, FAILURE otherwise.
*/
int32_t gpio_direction_output(struct gpio_desc *desc,
uint8_t value)
{
#ifdef _XPARAMETERS_PS_H_
XGpioPs_SetDirectionPin(&desc->instance, desc->number, 1);
XGpioPs_SetOutputEnablePin(&desc->instance, desc->number, 1);
XGpioPs_WritePin(&desc->instance, desc->number, value);
#else
uint8_t pin = desc->number;
uint8_t channel;
uint32_t reg_val;
if (pin >= 32) {
channel = 2;
pin -= 32;
} else
channel = 1;
reg_val = XGpio_GetDataDirection(&desc->instance, channel);
reg_val &= ~(1 << pin);
XGpio_SetDataDirection(&desc->instance, channel, reg_val);
reg_val = XGpio_DiscreteRead(&desc->instance, channel);
if(value)
reg_val |= (1 << pin);
else
reg_val &= ~(1 << pin);
XGpio_DiscreteWrite(&desc->instance, channel, reg_val);
#endif
return SUCCESS;
}
/**
* @brief Get the direction of the specified GPIO.
* @param desc - The GPIO descriptor.
* @param direction - The direction.
* Example: GPIO_OUT
* GPIO_IN
* @return SUCCESS in case of success, FAILURE otherwise.
*/
int32_t gpio_get_direction(struct gpio_desc *desc,
uint8_t *direction)
{
if (desc) {
// Unused variable - fix compiler warning
}
if (direction) {
// Unused variable - fix compiler warning
}
return 0;
}
/**
* @brief Set the value of the specified GPIO.
* @param desc - The GPIO descriptor.
* @param value - The value.
* Example: GPIO_HIGH
* GPIO_LOW
* @return SUCCESS in case of success, FAILURE otherwise.
*/
int32_t gpio_set_value(struct gpio_desc *desc,
uint8_t value)
{
#ifdef _XPARAMETERS_PS_H_
XGpioPs_WritePin(&desc->instance, desc->number, value);
#else
uint8_t pin = desc->number;
uint8_t channel;
uint32_t reg_val;
if (pin >= 32) {
channel = 2;
pin -= 32;
} else
channel = 1;
reg_val = XGpio_DiscreteRead(&desc->instance, channel);
if(value)
reg_val |= (1 << pin);
else
reg_val &= ~(1 << pin);
XGpio_DiscreteWrite(&desc->instance, channel, reg_val);
#endif
return 0;
}
/**
* @brief Get the value of the specified GPIO.
* @param desc - The GPIO descriptor.
* @param value - The value.
* Example: GPIO_HIGH
* GPIO_LOW
* @return SUCCESS in case of success, FAILURE otherwise.
*/
int32_t gpio_get_value(struct gpio_desc *desc,
uint8_t *value)
{
if (desc) {
// Unused variable - fix compiler warning
}
if (value) {
// Unused variable - fix compiler warning
}
return 0;
}
/**
* @brief Generate microseconds delay.
* @param usecs - Delay in microseconds.
* @return None.
*/
void udelay(uint32_t usecs)
{
usleep(usecs);
}
/**
* @brief Generate miliseconds delay.
* @param msecs - Delay in miliseconds.
* @return None.
*/
void mdelay(uint32_t msecs)
{
#ifdef _XPARAMETERS_PS_H_
usleep(msecs * 1000);
#else
usleep(msecs * 50); // FIXME
#endif
}
+204
View File
@@ -0,0 +1,204 @@
/***************************************************************************//**
* @file platform_drivers.h
* @brief Header file of Xilinx Platform Drivers.
* @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 PLATFORM_DRIVERS_H_
#define PLATFORM_DRIVERS_H_
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <stdint.h>
#include <xparameters.h>
#ifdef _XPARAMETERS_PS_H_
#include <xspips.h>
#include <xgpiops.h>
#else
#include <xspi.h>
#include <xgpio.h>
#endif
/******************************************************************************/
/********************** Macros and Constants Definitions **********************/
/******************************************************************************/
#define SUCCESS 0
#define FAILURE -1
#define SPI_CPHA 0x01
#define SPI_CPOL 0x02
#define SPI_CS_DECODE 0x01
#define SPI_CS_DECODE_DISABLE 0x00
#define GPIO_OUT 0x01
#define GPIO_IN 0x00
#define GPIO_HIGH 0x01
#define GPIO_LOW 0x00
/******************************************************************************/
/*************************** Types Declarations *******************************/
/******************************************************************************/
typedef enum i2c_type {
XILINX_I2C
} i2c_type;
typedef struct i2c_init_param {
enum i2c_type type;
uint32_t id;
uint32_t max_speed_hz;
uint8_t slave_address;
} i2c_init_param;
typedef struct i2c_desc {
enum i2c_type type;
uint32_t id;
uint32_t max_speed_hz;
uint8_t slave_address;
} i2c_desc;
typedef enum spi_type {
XILINX_SPI
} spi_type;
/**
* @enum spi_mode
* @brief SPI configuration for clock phase and polarity.
*/
typedef enum spi_mode {
/** Data on rising, shift out on falling */
SPI_MODE_0 = (0 | 0),
/** Data on falling, shift out on rising */
SPI_MODE_1 = (0 | SPI_CPHA),
/** Data on falling, shift out on rising */
SPI_MODE_2 = (SPI_CPOL | 0),
/** Data on rising, shift out on falling */
SPI_MODE_3 = (SPI_CPOL | SPI_CPHA)
} spi_mode;
typedef struct spi_init_param {
enum spi_type type;
uint32_t id;
uint32_t max_speed_hz;
enum spi_mode mode;
uint8_t chip_select;
uint32_t flags;
} spi_init_param;
typedef struct spi_desc {
enum spi_type type;
uint32_t id;
uint32_t max_speed_hz;
enum spi_mode mode;
uint8_t chip_select;
uint32_t flags;
#ifdef _XPARAMETERS_PS_H_
XSpiPs_Config *config;
XSpiPs instance;
#else
XSpi instance;
#endif
} spi_desc;
typedef enum gpio_type {
XILINX_GPIO
} gpio_type;
typedef struct gpio_desc {
enum gpio_type type;
uint32_t id;
uint8_t number;
#ifdef _XPARAMETERS_PS_H_
XGpioPs_Config *config;
XGpioPs instance;
#else
XGpio instance;
#endif
} gpio_desc;
/******************************************************************************/
/************************ Functions Declarations ******************************/
/******************************************************************************/
/* Initialize the SPI communication peripheral. */
int32_t spi_init(struct spi_desc **desc,
const struct spi_init_param *param);
/* Free the resources allocated by spi_init() */
int32_t spi_remove(struct spi_desc *desc);
/* Write and read data to/from SPI. */
int32_t spi_write_and_read(struct spi_desc *desc,
uint8_t *data,
uint8_t bytes_number);
/* Obtain the GPIO decriptor. */
int32_t gpio_get(struct gpio_desc **desc,
uint8_t gpio_number);
/* Free the resources allocated by gpio_get() */
int32_t gpio_remove(struct gpio_desc *desc);
/* Enable the input direction of the specified GPIO. */
int32_t gpio_direction_input(struct gpio_desc *desc);
/* Enable the output direction of the specified GPIO. */
int32_t gpio_direction_output(struct gpio_desc *desc,
uint8_t value);
/* Get the direction of the specified GPIO. */
int32_t gpio_get_direction(struct gpio_desc *desc,
uint8_t *direction);
/* Set the value of the specified GPIO. */
int32_t gpio_set_value(struct gpio_desc *desc,
uint8_t value);
/* Get the value of the specified GPIO. */
int32_t gpio_get_value(struct gpio_desc *desc,
uint8_t *value);
/* Generate microseconds delay. */
void udelay(uint32_t usecs);
/* Generate miliseconds delay. */
void mdelay(uint32_t msecs);
#endif // PLATFORM_DRIVERS_H_
+1 -1
View File
@@ -38,7 +38,7 @@
#endif #endif
#define FAILURE -1 #define FAILURE -1
#define EPARAM -2 /*!< Data crc check failed */ #define EPARAM -2 /*!< Invalid parameters */
#define ECRC -3 /*!< Data crc check failed */ #define ECRC -3 /*!< Data crc check failed */
#define EDINVAL -4 /*!< Device is invalid (sleep or power off) */ #define EDINVAL -4 /*!< Device is invalid (sleep or power off) */
#define EDCONF -5 /*!< Device confugure error */ #define EDCONF -5 /*!< Device confugure error */
+101
View File
@@ -0,0 +1,101 @@
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
/**
* @file
* Prototypes and structures for the ring buffer module.
*/
#ifndef __RINGBUFFER_H
#define __RINGBUFFER_H
#ifdef __cplusplus
extern "C"
{
#endif
/**
* Structure which holds a ring buffer.
* The buffer contains a buffer array
* as well as metadata for the ring buffer.
*/
typedef struct RING_BUFFER {
uint8_t *buffer; ///< Buffer memory
size_t tail; ///< Index of tail
size_t head; ///< Index of head
size_t capacity; ///< Capacity of buffer
size_t size; ///< Size of data stored in buffer
} RING_BUFFER;
/**
* Initialize a ringbuffer .
* @param capacity capacity of the ringbuffer
* @return The initialized ringbuffer pointer, NULL of not enough memory
*/
RING_BUFFER *RingBuff_Create(size_t capacity);
/**
* Destroy a ringbuffer .
* @param rb The buffer to destroyed.
*/
void RingBuff_Destroy(RING_BUFFER *rb);
/**
* Flush all the data stored in ring buffer
* @param rb The buffer to be flushed.
*/
void RingBuff_Flush(RING_BUFFER *rb);
/**
* Adds an array of bytes to a ring buffer.
* @param rb The buffer in which the data should be placed.
* @param data A pointer to the array of bytes to place in the queue.
* @param size The size of the array.
*/
size_t RingBuff_Push(RING_BUFFER *rb, const uint8_t *data, size_t len);
/**
* Returns the <em>len</em> oldest bytes in a ring buffer.
* @param rb The buffer from which the data should be returned.
* @param data A pointer to the array at which the data should be placed.
* @param len The maximum number of bytes to return.
* @return The number of bytes returned.
*/
size_t RingBuff_Pop(RING_BUFFER *rb, uint8_t *data, size_t len);
/**
* Peeks a ring buffer, i.e. returns an element without removing it.
* @param rb The buffer from which the data should be returned.
* @param data A pointer to the location at which the data should be placed.
* @param len The maximum number of bytes to return.
* @return the number of bytes returned.
*/
size_t RingBuff_Peek(const RING_BUFFER *rb, uint8_t *data, size_t len);
/**
* Returns the number of items in a ring buffer.
* @param rb The buffer for which the number of items should be returned.
* @return The number of items in the ring buffer.
*/
size_t RingBuff_Size(RING_BUFFER *rb);
/**
* Returns whether a ring buffer is empty.
* @param buffer The buffer for which it should be returned whether it is empty.
* @return 1 if empty; 0 otherwise.
*/
uint8_t RingBuff_isEmpty(RING_BUFFER *rb);
/**
* Returns whether a ring buffer is full.
* @param buffer The buffer for which it should be returned whether it is full.
* @return 1 if full; 0 otherwise.
*/
uint8_t RingBuff_isFull(RING_BUFFER *rb);
#ifdef __cplusplus
}
#endif
#endif /* __RINGBUFFER_H */
-115
View File
@@ -1,115 +0,0 @@
/***************************************************************************//**
* @file trng.h
* @brief Header file of true random number generator
* @author Mihail Chindris ([email protected])
********************************************************************************
* @copyright
* Copyright 2020(c) Analog Devices, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* - Neither the name of Analog Devices, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* - The use of this software may or may not infringe the patent rights
* of one or more patent holders. This license does not release you
* from the requirement that you obtain separate licenses from these
* patent holders to use this software.
* - Use of the software either in source or binary form, must be run
* on or directly connected to an Analog Devices Inc. component.
*
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#ifndef _TRNG_H_
#define _TRNG_H_
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <stdint.h>
/******************************************************************************/
/*************************** Types Declarations *******************************/
/******************************************************************************/
/**
* @struct trng_platform_ops
* @brief Structure holding TRNG function pointers that point to the platform
* specific function
*/
struct trng_platform_ops;
/**
* @struct trng_desc
* @brief TRNG Descriptor
*/
struct trng_desc {
/** Platform ops */
const struct trng_platform_ops *platform_ops;
/** Platform specific parameters */
void *extra;
};
/**
* @struct trng_init_param
* @brief Init parameter for TRNG
*/
struct trng_init_param {
/** Device id */
uint32_t dev_id;
/** Platform specific parameter */
void *extra;
/** Platform ops */
const struct trng_platform_ops *platform_ops;
};
/**
* @struct trng_platform_ops
* @brief Structure holding TRNG function pointers that point to the platform
* specific function
*/
struct trng_platform_ops {
/** TRNG initialization function pointer */
int (*init)(struct trng_desc **,
const struct trng_init_param *);
/** Fill buffer with random numbers */
int (*fill_buffer)(struct trng_desc *, uint8_t *, uint32_t);
/** TRNG remove function pointer */
int (*remove)(struct trng_desc *);
};
/******************************************************************************/
/************************ Functions Declarations ******************************/
/******************************************************************************/
/* Initialize descriptor */
int trng_init(struct trng_desc **desc,
const struct trng_init_param *param);
/* Free resources allocated in descriptor */
int trng_remove(struct trng_desc *desc);
/* Fill buffer with random numbers */
int trng_fill_buffer(struct trng_desc *desc, uint8_t *buff,
uint32_t len);
#endif // _TRNG_H_
+702
View File
@@ -0,0 +1,702 @@
/*****************************************************************************/
/**
* Description: MPC protocol implementation file.
*
* Date: 2023-05-06 10:13
* Last Edit Time: [2023-05-06 21:45]
*
* Revisions: Rev 0.0
* History:
* [2023-05-06]: Initial version.
* [2023-09-13]: Update to 485 protocol-20220816
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Network
*
******************************************************************************/
/***************************** Include Files *********************************/
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include "mpc.h"
#include "util.h"
#include "common.h"
#include "error.h"
#include "circ_queue.h"
#include "xbram.h"
#include "xgpio.h"
#include "../system_monitor.h"
/************************** Constant Definitions *****************************/
// Common Field
// -- Command word
#define WD_CMD 0x00
// -- Production type
#define WD_PRD 0x01
#define PRD_DL_K 0xDD
#define PRD_DL_S 0xEE
#define PRD_ALL 0xFF
// Self-Test
#define CMD_SELF_TEST 0xE1
// -- Request
// -- -- --
// -- Response
// -- -- Self-Test Result
#define ST_RSP_LEN 16
#define WD_ST_RET 0x02
#define ST_RET_OK 0xAA
#define ST_RET_ERROR 0x55
#define ST_RET_INFO_LEN 13
// -- -- Signal processor PS voltage
#define WD_SP_FPGA_VOLT 0x03
// -- -- Signal processor PS AUX voltage
#define WD_SP_CLK_STATE 0x04
// -- -- Signal processor DDR voltage
#define WD_SP_AD_LOCK_STATE 0x05
// -- -- Signal processor PL voltage
#define WD_SP_AD_TEMP_0 0x06
// -- -- Signal processor PL AUX voltage
#define WD_SP_AD_TEMP_1 0x07
// -- -- Signal processor Bram voltage
#define WD_SP_FPGA_TEMP 0x08
// Config load
#define CMD_CONFIG 0xE3
// -- Request
#define WD_EN_CMD 0x02
#define EN_CMD_ON_HIGH_POWER 0x66
#define EN_CMD_ON_LOW_POWER 0x77
#define EN_CMD_SILENT 0x88
#define WD_SPEED_CMD 0x03
#define SPEED_CMD_2K 0x11
#define SPEED_CMD_128K 0x22
#define SPEED_CMD_256K 0x33
// -- Response
// -- -- none response
// Remote Test
#define RM_TEST_RESP_LEN 158
// -- Request
// Remote Test FLJ
#define CMD_FLJ_RM_TEST 0xE6
// Remote Test LJ
#define CMD_LJ_RM_TEST 0xF6
#define WD_RM_TEST 0x02
#define RM_TEST_CODE 0x99
// -- Response
#define WD_TIME_STAMP 0x02
#define WD_TIME_STAMP_LEN 8
#define WD_SYSBUS_LOG 0x0A
#define WD_SYSBUS_LOG_LEN 14
#define WD_LINK_LOG 0x18
#define WD_LINK_LOG_LEN 64
#define WD_PHY_LOG 0x58
#define WD_PHY_LOG_LEN 57
#define WD_HARDWARE_ST 0x91
#define WD_HARDWARE_ST_LEN 13
// Service Data
// -- Request
#define DATA_DLUL_LEN 510
#define CMD_DATA_DL 0x92
#define CMD_DATA_UL 0xA2
#define WD_DATA_SEQID_L 2U
#define WD_DATA_SEQID_H 3U
#define WD_DATA_PKTNUM 4U
#define WD_DATA_PKTSEQ 5U
#define WD_DATA_DLEN_L 6U
#define WD_DATA_DLEN_H 7U
#define WD_DATA_PAYLOAD 8U
#define DATA_PAYLOAD_MAX 502U
// -- Response
// -- -- none response
// My Production Type
#define MY_PRD_ID PRD_DL_K
#define MPC_SVC_MAX 1024
/************************** Function Prototypes ******************************/
static int32_t Mpc_ReceiveSvcDate(MPC *instPtr, uint8_t *msg);
/**************************** Type Definitions *******************************/
/************************** Variable Definitions *****************************/
// TODO: better approach?
#include "../networking/link_layer/link_layer.h"
#include "../networking/phy_layer/phy_layer.h"
extern L2_INST *linkInstPtr;
extern L2_CONFIG linkConfig;
inline bool Mpc_IsEnable(MPC *instPtr)
{
ASSERT(instPtr != NULL);
return (instPtr->isEnable);
}
inline bool Mpc_IsReqPending(MPC *instPtr)
{
ASSERT(instPtr != NULL);
return (!isCircQueueEmpty(instPtr->rxQueue));
}
inline bool Mpc_IsRsqPending(MPC *instPtr)
{
ASSERT(instPtr != NULL);
return (!isCircQueueEmpty(instPtr->txQueue));
}
inline bool Mpc_IsTxBusy(MPC *instPtr)
{
ASSERT(instPtr != NULL);
return (!instPtr->isTxDone);
}
inline bool Mpc_IsRxBusy(MPC *instPtr)
{
ASSERT(instPtr != NULL);
return (!instPtr->isRxDone);
}
inline bool Mpc_IsSvcUpPending(MPC *instPtr)
{
ASSERT(instPtr != NULL);
return (!isCircQueueEmpty(instPtr->rxSvcQueue));
}
inline bool Mpc_IsSvcDownPending(MPC *instPtr)
{
ASSERT(instPtr != NULL);
return (!isCircQueueEmpty(instPtr->txSvcQueue));
}
inline bool Mpc_PushSvcFrame(MPC *instPtr, void* buff) {
ASSERT(instPtr != NULL);
ASSERT(buff != NULL);
return CircQueuePush(instPtr->rxSvcQueue, buff);
}
inline bool Mpc_PopSvcFrame(MPC *instPtr, void** buff) {
ASSERT(instPtr != NULL);
ASSERT(buff != NULL);
return CircQueuePop(instPtr->txSvcQueue, buff);
}
/**
* @brief Generate System Bus SelfTest response.
*/
static int32_t Mpc_GenSelfTestRsp(MPC *instPtr)
{
ASSERT(instPtr != NULL);
MPC_HW_FRAME *mpcRsp;
uint8_t *msg;
if (Mpc_IsEnable(instPtr) == false)
{
DBG_ERROR("System is not enabled!\n");
return EIGNORE;
}
mpcRsp = malloc(sizeof(MPC_HW_FRAME));
if (mpcRsp == NULL)
{
DBG_ERROR("Failed to allocate memory for LJ REMOTE TEST Response!\n");
return ENOMEM;
}
mpcRsp->len = ST_RSP_LEN;
msg = mpcRsp->data + FRAME_PAYLOAD_POFFSET;
HWSTATE *hwStatsPtr = &(instPtr->hwState);
msg[WD_CMD] = CMD_SELF_TEST;
msg[WD_PRD] = MY_PRD_ID;
SysMonitor_GetHardwareStatus(hwStatsPtr);
if (Mpc_IsEnable(instPtr))
{
msg[WD_ST_RET] = (hwStatsPtr->isSpOk && hwStatsPtr->isAntOk) ? ST_RET_OK : ST_RET_ERROR;
}
else
{
msg[WD_ST_RET] = (hwStatsPtr->isSpOk) ? ST_RET_OK : ST_RET_ERROR;
}
// apply status and omit 2 bytes of overhead.
memcpy(msg + WD_SP_FPGA_VOLT, &(hwStatsPtr->spFpgaVolt), ST_RET_INFO_LEN);
if (CircQueuePush(instPtr->txQueue, (void *)mpcRsp) == false)
{
free(mpcRsp);
DBG_ERROR("SystemBus::TX Queue overflowed!\n");
return EQUEUE;
}
return SUCCESS;
}
/**
* @brief Apply system configuration
*/
static int32_t Mpc_SystemConfig(MPC *instPtr, uint8_t *msg)
{
PHY_INST *phyRef = linkInstPtr->config.phyInstPtr;
TMC_INST *tmcRef = linkInstPtr->config.tmcInstPtr;
switch (msg[WD_SPEED_CMD]) {
case SPEED_CMD_2K:
Linklayer_UpdateSpeedMode(linkInstPtr, L2_SPEED_2KBPS);
break;
case SPEED_CMD_128K:
Linklayer_UpdateSpeedMode(linkInstPtr, L2_SPEED_128KBPS);
break;
case SPEED_CMD_256K:
Linklayer_UpdateSpeedMode(linkInstPtr, L2_SPEED_256KBPS);
break;
default:
DBG_ERROR("Unexpected config command 0x%02X:0x%02X",
WD_SPEED_CMD, msg[WD_SPEED_CMD]);
return EIGNORE;
}
if (msg[WD_EN_CMD] == EN_CMD_ON_HIGH_POWER)
{
// high power config
Phy_AntConfigMode(phyRef, PHY_ANT_MODE_POWER_FULL);
Linklayer_Start(linkInstPtr);
instPtr->isEnable = true;
}
else if (msg[WD_EN_CMD] == EN_CMD_ON_LOW_POWER)
{
// low power config
Phy_AntConfigMode(phyRef, PHY_ANT_MODE_POWER_LOW);
Linklayer_Start(linkInstPtr);
instPtr->isEnable = true;
}
else if (msg[WD_EN_CMD] == EN_CMD_SILENT)
{
// silence config
// TODO: better approach?
instPtr->isEnable = false;
Linklayer_Halt(linkInstPtr);
Phy_AntConfigMode(phyRef, PHY_ANT_MODE_STANDBY);
TIME_WORD pullTime = {0, 0};
pullTime.int_part = TimeCtrl_GetIntCnt(tmcRef) + 1;
if (Phy_SetTimeWord(phyRef, &pullTime, PHY_TIME_WORD_POLL) != SUCCESS)
{
DBG_ERROR("Physical set pull time failed.\n");
}
Phy_SetupNextSlot(phyRef, PHY_TOR_RX, L1_10KBPS_10MS_FRAME, NULL);
}
else
{
// Ignore current command
DBG_ERROR("Unexpected config command 0x%02X:0x%02X",
WD_EN_CMD, msg[WD_EN_CMD]);
return EIGNORE;
}
instPtr->mpcLog.lastConfig[0] = msg[WD_EN_CMD];
instPtr->mpcLog.lastConfig[1] = msg[WD_SPEED_CMD];
return SUCCESS;
}
/**
* @brief Receive service data from upper layer
*/
static int32_t Mpc_ReceiveSvcDate(MPC *instPtr, uint8_t *msg)
{
ASSERT(instPtr != NULL);
ASSERT(msg != NULL);
uint8_t numPack = msg[WD_DATA_PKTNUM];
uint8_t seqNo = msg[WD_DATA_PKTSEQ];
size_t dlen = (size_t)msg[WD_DATA_DLEN_L] | ((size_t)msg[WD_DATA_DLEN_H] << 8);
if(seqNo > numPack) {
DBG_ERROR("Invalid service packet sequence number (%u/%u).\n", seqNo, numPack);
return EPARAM;
}
if(dlen > 502) {
DBG_ERROR("Invalid service data packet length %u.\n", dlen);
return EPARAM;
}
if (instPtr->currSvcBuff == NULL)
{
instPtr->currSvcBuff = RingBuff_Create(MPC_SVC_MAX);
if(instPtr->currSvcBuff == NULL) {
return ENOMEM;
}
}
size_t tmpLen = RingBuff_Push(instPtr->currSvcBuff, &(msg[WD_DATA_PAYLOAD]), dlen);
if(tmpLen < dlen) {
DBG_ERROR("Ring buffer overflowed.\n");
ASSERT(true);
}
// TODO: Check packet consistency
if(numPack == 0 || seqNo == numPack) {
if(CircQueuePush(instPtr->txSvcQueue, (void*)instPtr->currSvcBuff) == false) {
DBG_ERROR("txSvcQueue overflowed.\n");
RingBuff_Destroy(instPtr->currSvcBuff);
return EQUEUE;
}
instPtr->currSvcBuff = NULL;
}
instPtr->mpcLog.svcUpCnt++;
return SUCCESS;
}
/**
* @brief Upload service data to upper layer
*/
int32_t Mpc_UploadSvcData(MPC *instPtr)
{
ASSERT(instPtr != NULL);
RING_BUFFER *buff;
if(CircQueuePop(instPtr->rxSvcQueue, (void**)(&buff)) == false) {
DBG_ERROR("No service data need to be uploaded.\n");
return EIGNORE;
}
uint8_t numPack = RingBuff_Size(buff) / DATA_PAYLOAD_MAX;
uint8_t cntPack = 0;
MPC_HW_FRAME *mpcRsp;
uint8_t *rsp;
size_t sentLen;
while(RingBuff_Size(buff) > 0) {
mpcRsp = malloc(sizeof(MPC_HW_FRAME));
if (mpcRsp == NULL)
{
DBG_ERROR("Failed to allocate memory for LJ REMOTE TEST Response!\n");
return ENOMEM;
}
mpcRsp->len = DATA_DLUL_LEN;
rsp = mpcRsp->data + FRAME_PAYLOAD_POFFSET;
rsp[WD_CMD] = CMD_DATA_UL;
rsp[WD_PRD] = MY_PRD_ID;
rsp[WD_DATA_SEQID_L] = instPtr->mpcLog.svcUpCnt & 0xFF;
rsp[WD_DATA_SEQID_H] = (instPtr->mpcLog.svcUpCnt >> 8) & 0xFF;
rsp[WD_DATA_PKTNUM] = numPack;
rsp[WD_DATA_PKTSEQ] = cntPack;
sentLen = RingBuff_Pop(buff, &(rsp[WD_DATA_PAYLOAD]), DATA_PAYLOAD_MAX);
rsp[WD_DATA_DLEN_L] = sentLen & 0xFF;
rsp[WD_DATA_DLEN_H] = (sentLen >> 8) & 0xFF;
if (CircQueuePush(instPtr->txQueue, (void *)mpcRsp) == false)
{
RingBuff_Destroy(buff);
free(mpcRsp);
DBG_WARNING("SystemBus::TX Queue overflowed!\n");
return EQUEUE;
}
instPtr->mpcLog.svcUpCnt++;
}
RingBuff_Destroy(buff);
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Initialize MPC instance.
*
* @param InstPtr A double pointer to MPC instance.
* @param config A pointer to MPC configurations.
*
* @return Error code.
*
******************************************************************************/
int32_t Mpc_Init(MPC **instPtr, MPC_CONFIG *config)
{
ASSERT(instPtr != NULL);
ASSERT(config != NULL);
MPC_HW_CONFIG mpcHwConfig;
int32_t Status;
(*instPtr) = malloc(sizeof(MPC));
if ((*instPtr) == NULL)
{
return ENOMEM;
}
(*instPtr)->rxQueue = NULL;
(*instPtr)->txQueue = NULL;
(*instPtr)->mpchwDesc = NULL;
(*instPtr)->txSvcQueue = NULL;
(*instPtr)->rxSvcQueue = NULL;
(*instPtr)->currSvcBuff = NULL;
memcpy(&((*instPtr)->config), config, sizeof(MPC_CONFIG));
memset(&((*instPtr)->mpcLog), 0x00, sizeof(SYSBUSLOG));
memset(&((*instPtr)->linkLog), 0x00, sizeof(LINKLOG));
memset(&((*instPtr)->phyLog), 0x00, sizeof(PHYLOG));
memset(&((*instPtr)->hwState), 0x00, sizeof(HWSTATE));
XBram_Config *bramConfigPtr;
XBram mpcBram;
bramConfigPtr = XBram_LookupConfig(config->bramId);
if (bramConfigPtr == NULL)
{
Mpc_Destroy(*instPtr);
return EDCONF;
}
Status = XBram_CfgInitialize(&mpcBram, bramConfigPtr,
bramConfigPtr->CtrlBaseAddress);
if (Status != SUCCESS)
{
Mpc_Destroy(*instPtr);
return Status;
}
/*
* Execute the BRAM driver selftest.
*/
Status = XBram_SelfTest(&mpcBram, 0);
if (Status != SUCCESS)
{
Mpc_Destroy(*instPtr);
return Status;
}
mpcHwConfig.txBuffAddr = mpcBram.Config.MemBaseAddress;
mpcHwConfig.rxBuffAddr = mpcBram.Config.MemBaseAddress;
mpcHwConfig.gpioId = config->gpioId;
Status = MpcHw_Init(&((*instPtr)->mpchwDesc), &mpcHwConfig);
if (Status != SUCCESS)
{
Mpc_Destroy(*instPtr);
return ENOMEM;
}
if (CircQueueCreate(&((*instPtr)->txQueue), (*instPtr)->config.txQueueMax) == false)
{
Mpc_Destroy(*instPtr);
return ENOMEM;
}
if (CircQueueCreate(&((*instPtr)->rxQueue), (*instPtr)->config.rxQueueMax) == false)
{
Mpc_Destroy(*instPtr);
return ENOMEM;
}
if (CircQueueCreate(&((*instPtr)->txSvcQueue), (*instPtr)->config.rxQueueMax) == false)
{
Mpc_Destroy(*instPtr);
return ENOMEM;
}
if (CircQueueCreate(&((*instPtr)->rxSvcQueue), (*instPtr)->config.rxQueueMax) == false)
{
Mpc_Destroy(*instPtr);
return ENOMEM;
}
(*instPtr)->isEnable = false; // nothing received.
(*instPtr)->isRxDone = false; // nothing received.
(*instPtr)->isTxDone = true; // nothing to be sent.
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Destroy MPC instance.
*
* @param InstPtr A pointer to MPC instance.
*
* @return None.
*
******************************************************************************/
void Mpc_Destroy(MPC *instPtr)
{
if (instPtr == NULL)
{
return;
}
free(instPtr->mpchwDesc);
CircQueueFree(instPtr->txQueue);
CircQueueFree(instPtr->rxQueue);
CircQueueFree(instPtr->txSvcQueue);
CircQueueFree(instPtr->rxSvcQueue);
free(instPtr);
}
/*****************************************************************************/
/**
* @brief Generate a remote test response message.
*
* @param instPtr A pointer to MPC instance.
*
* @return SUCCESS
* error code
*
******************************************************************************/
int32_t Mpc_PendRemoteTest(MPC *instPtr)
{
MPC_HW_FRAME *mpcRsp;
uint8_t *msg;
if (!Mpc_IsEnable(instPtr))
{
DBG_ERROR("System is not enabled!\n");
return EIGNORE;
}
mpcRsp = malloc(sizeof(MPC_HW_FRAME));
if (mpcRsp == NULL)
{
DBG_ERROR("Failed to allocate memory for LJ REMOTE TEST Response!\n");
return ENOMEM;
}
msg = mpcRsp->data + FRAME_PAYLOAD_POFFSET;
mpcRsp->len = RM_TEST_RESP_LEN;
if (L2_GetNodeType(linkInstPtr) == L2_NODE_HEAD)
{
// head node config
msg[WD_CMD] = CMD_FLJ_RM_TEST;
}
else
{
msg[WD_CMD] = CMD_LJ_RM_TEST;
}
msg[WD_PRD] = MY_PRD_ID;
TIME_WORD tmWord;
uint64_t time;
TimeCtrl_GetCurrentTime(linkInstPtr->config.tmcInstPtr, &tmWord);
time = (uint64_t)tmWord.int_part * TIME_FRAC_MAX + tmWord.frac_part;
memcpy(msg + WD_TIME_STAMP, &time, WD_TIME_STAMP_LEN);
SysMonitor_GetLinklayerLog(&(instPtr->linkLog));
SysMonitor_GetPhysicalLayerLog(&(instPtr->phyLog));
SysMonitor_GetHardwareStatus(&(instPtr->hwState));
memcpy(msg + WD_SYSBUS_LOG, &(instPtr->mpcLog), WD_SYSBUS_LOG_LEN);
memcpy(msg + WD_LINK_LOG, &(instPtr->linkLog), WD_LINK_LOG_LEN);
memcpy(msg + WD_PHY_LOG, &(instPtr->phyLog), WD_PHY_LOG_LEN);
memcpy(msg + WD_HARDWARE_ST, &(instPtr->hwState.spFpgaVolt), WD_HARDWARE_ST_LEN);
if (CircQueuePush(instPtr->txQueue, (void *)mpcRsp) == false)
{
free(mpcRsp);
DBG_WARNING("SystemBus::TX Queue overflowed!\n");
return EQUEUE;
}
instPtr->mpcLog.remoteCnt++;
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief A handler function. This handler evaluate the message from system
* bus receive queue, and make appropriate response.
*
* @param instPtr A pointer to MPC instance.
*
* @return None
*
******************************************************************************/
int32_t Mpc_HandleCmd(MPC *instPtr)
{
ASSERT(instPtr != NULL);
int32_t Status;
MPC_HW_FRAME *mpcReq;
uint8_t *reqMsg;
if (CircQueuePop(instPtr->rxQueue, (void **)(&mpcReq)) == false)
{
DBG_WARNING("SystemBus::Nothing to be handled.\n");
return EIGNORE;
}
reqMsg = mpcReq->data + FRAME_PAYLOAD_POFFSET;
if (reqMsg[WD_PRD] != MY_PRD_ID && reqMsg[WD_PRD] != PRD_ALL)
{
DBG_WARNING("SystemBus::Production code mismatch!\n");
return EIGNORE;
}
switch (reqMsg[WD_CMD])
{
case CMD_CONFIG:
Status = Mpc_SystemConfig(instPtr, reqMsg);
if (Status == SUCCESS)
{
Status = Mpc_GenSelfTestRsp(instPtr);
}
break;
case CMD_DATA_DL:
Status = Mpc_ReceiveSvcDate(instPtr, reqMsg);
break;
default:
DBG_ERROR("SystemBus::Unknown command code!\n");
Status = FAILURE;
break;
}
free(mpcReq);
return Status;
}
/*****************************************************************************/
/**
* @brief This function send a repose frame from MPC tx queue.
*
* @param instPtr A pointer to MPC instance.
*
* @return None
*
******************************************************************************/
int32_t Mpc_MakeResp(MPC *instPtr)
{
ASSERT(instPtr != NULL);
int32_t Status;
MPC_HW_FRAME *mpcRsp;
if (CircQueuePop(instPtr->txQueue, (void **)(&mpcRsp)) == false)
{
DBG_WARNING("SystemBus::Nothing to be sent.\n");
return EIGNORE;
}
instPtr->isTxDone = false; // A transmission procedure is started.
Status = MpcHw_Send(instPtr->mpchwDesc, mpcRsp);
free(mpcRsp);
return Status;
}
/*****************************************************************************/
/**
* @brief This function handles the mpc tx irq events.
*
* @param instPtr A pointer to MPC instance.
*
* @return None
*
******************************************************************************/
int32_t Mpc_TxIrqHandler(MPC *instPtr)
{
ASSERT(instPtr != NULL);
// nothing special...
instPtr->isTxDone = true; // A transmission procedure finished.
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief This function handles the mpc rx irq events.
*
* @param instPtr A pointer to MPC instance.
*
* @return None
*
******************************************************************************/
int32_t Mpc_RxIrqHandler(MPC *instPtr)
{
ASSERT(instPtr != NULL);
int32_t Status;
MPC_HW_FRAME *mpcReq;
instPtr->isRxDone = true; // whether reception successes or not, receiving procedure ended.
mpcReq = malloc(sizeof(MPC_HW_FRAME));
if (mpcReq == NULL)
{
return ENOMEM;
}
Status = MpcHw_Recv(instPtr->mpchwDesc, mpcReq);
if (Status != SUCCESS)
{
DBG_ERROR("SystemBus::RX error!\n");
free(mpcReq);
return Status;
}
if (CircQueuePush(instPtr->rxQueue, (void *)mpcReq) == false)
{
DBG_ERROR("SystemBus::RX Queue overflowed!\n");
free(mpcReq);
return EQUEUE;
}
instPtr->isRxDone = false; // another reception is undergoing.
return SUCCESS;
}
+82
View File
@@ -0,0 +1,82 @@
/*****************************************************************************/
/**
* Description: MPC protocol head file.
*
* Date: 2023-05-06 10:12
* Last Edit Time: [2023-05-06 10:13]
*
* Revisions: Rev 0.0
* History:
* [2023-05-06]: Initial version.
*
* Copyright(c) 2021 Beijing Institute of Technology.
*
******************************************************************************/
#ifndef __MPC_H_
#define __MPC_H_
/***************************** Include Files *********************************/
#include <stdint.h>
#include <stdbool.h>
#include "mpc_hw.h" // MPC driver
#include "circ_queue.h"
#include "ring_buffer.h"
#include "../system_monitor.h"
/************************** Constant Definitions *****************************/
/************************** Data Type Definitions ****************************/
// Definition of MPC instance.
typedef struct
{
uint32_t bramId;
uint32_t gpioId;
uint32_t txQueueMax;
uint32_t rxQueueMax;
} MPC_CONFIG;
typedef struct
{
MPC_CONFIG config;
SYSBUSLOG mpcLog; // mpc log
LINKLOG linkLog; // Link layer log
PHYLOG phyLog; // Physical layer log
HWSTATE hwState; // Hardware status
MPC_HW *mpchwDesc;
RING_BUFFER *currSvcBuff;
CIRC_QUEUE *txQueue; ///< tx queue for systembus message
CIRC_QUEUE *rxQueue; ///< rx queue for systembus message
CIRC_QUEUE *txSvcQueue; ///< tx queue for service data
CIRC_QUEUE *rxSvcQueue; ///< rx queue for service data
bool isEnable;
bool isRxDone;
bool isTxDone;
} MPC;
/************************** Function Prototypes ******************************/
int32_t Mpc_Init(MPC **instPtr, MPC_CONFIG *config);
void Mpc_Destroy(MPC *instPtr);
int32_t Mpc_HandleCmd(MPC *instPtr);
int32_t Mpc_PendRemoteTest(MPC *instPtr);
int32_t Mpc_MakeResp(MPC *instPtr);
int32_t Mpc_UploadSvcData(MPC *instPtr);
int32_t Mpc_TxIrqHandler(MPC *instPtr);
int32_t Mpc_RxIrqHandler(MPC *instPtr);
bool Mpc_IsEnable(MPC *instPtr);
bool Mpc_IsReqPending(MPC *instPtr);
bool Mpc_IsRsqPending(MPC *instPtr);
bool Mpc_IsTxBusy(MPC *instPtr);
bool Mpc_IsRxBusy(MPC *instPtr);
bool Mpc_IsSvcUpPending(MPC *instPtr);
bool Mpc_IsSvcDownPending(MPC *instPtr);
bool Mpc_PushSvcFrame(MPC *instPtr, void* buff);
bool Mpc_PopSvcFrame(MPC *instPtr, void** buff);
#endif //__MPC_H_
+140
View File
@@ -0,0 +1,140 @@
/*****************************************************************************/
/**
* Description: MPC uart driver implementation file.
*
* Date: 2023-05-06 10:59
* LastEditTime: 2023-05-06 21:56
* Revisions: Rev 0.0
* History:
* [2023-05-06]: Initial version.
*
* Copyright(c) 2022 Beijing Institute of Technology.
*
******************************************************************************/
/***************************** Include Files *******************************/
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include "mpc_hw.h"
#include "common.h"
#include "error.h"
// Control and status register
#define MODULE_VERSION 0
#define MPC_STATUS 4
#define MPC_SEND_CMD 8
#define MPC_RECV_CNT 12
// Status code
#define MPC_STATUS_TX_BUSY 0x00010000
#define MPC_STATUS_RX_BUSY 0x01000000
// Data buffer register
#define MPC_TXBUFF_MAX 512
#define MPC_RXBUFF_MAX 512
// Frame Data offsets
#define FRAME_HEAD_LOW 0x02
#define FRAME_HEAD_HIGH 0x53
#define FRAME_TAIL_LOW 0x32
#define FRAME_TAIL_HIGH 0x20
#define FRAME_HEAD_LEN 2
#define FRAME_TAIL_LEN 2
#define FRAME_DUMMY_LEN 1 // Dummy
#define FRAME_OVERHEAD_LEN 2 // CheckSum, Dummy and
#define MPC_STATUS_CH 1
#define MPC_CONFIG_CH 2
#define MPC_CONFIG_SEND_TRIG 0x00000002
/*************************** Function Definitions ****************************/
/*****************************************************************************/
/**
* @brief Instance initial
*
* @param instPtr A pointer to frame uart instance structure.
* @param config Base address of frame uart, refer to "xparameters.h"
*
* @return None.
*
******************************************************************************/
int MpcHw_Init(MPC_HW **instPtr, MPC_HW_CONFIG *config)
{
ASSERT(instPtr != NULL);
ASSERT(config != NULL);
uint32_t Status;
(*instPtr) = malloc(sizeof(MPC_HW));
if ((*instPtr) == NULL)
{
return FAILURE;
}
(*instPtr)->config.txBuffAddr = config->txBuffAddr;
(*instPtr)->config.rxBuffAddr = config->rxBuffAddr;
Status = XGpio_Initialize(&((*instPtr)->gpioDesc), config->gpioId);
if (Status != SUCCESS) {
DBG_ERROR("MPC gpio Initialization Failed.\n");
free(*instPtr);
return FAILURE;
}
XGpio_SetDataDirection(&((*instPtr)->gpioDesc), MPC_CONFIG_CH, 0x00000000);
XGpio_SetDataDirection(&((*instPtr)->gpioDesc), MPC_STATUS_CH, 0xFFFFFFFF);
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Send a MPC frame.
*
* @param instPtr A pointer to MPC_HW instance structure.
* @param buff A pointer to send data buffer
* @param dLen A integer indicate the send data buffer length in byte.
*
* @return
*
******************************************************************************/
int MpcHw_Send(MPC_HW *instPtr, MPC_HW_FRAME *frame)
{
ASSERT(instPtr != NULL);
ASSERT(frame != NULL);
size_t sendLen;
uint8_t *sendBuff = (uint8_t*) instPtr->config.txBuffAddr;
sendLen = frame->len + FRAME_OVERHEAD_LEN;
if (sendLen > MPC_TXBUFF_MAX || frame->len == 0)
{
return FAILURE;
}
frame->data[0] = FRAME_HEAD_LOW;
frame->data[1] = FRAME_HEAD_HIGH;
memcpy(sendBuff, frame->data, sendLen);
// Start Sending
uint32_t gpioVal = XGpio_DiscreteRead(&(instPtr->gpioDesc), MPC_CONFIG_CH);
gpioVal ^= MPC_CONFIG_SEND_TRIG;
XGpio_DiscreteWrite(&(instPtr->gpioDesc), MPC_CONFIG_CH, gpioVal);
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Get last MPC frame.
*
* @param instPtr A pointer to MPC_HW instance structure.
* @param buff A pointer to receive data buffer.
*
* @return
*
******************************************************************************/
int MpcHw_Recv(MPC_HW *instPtr, MPC_HW_FRAME *frame)
{
ASSERT(instPtr != NULL);
ASSERT(frame != NULL);
uint8_t *recvBuff = (uint8_t *)(instPtr->config.rxBuffAddr);
memcpy(frame->data, recvBuff, MPC_FRAME_MAX);
frame->len = MPC_FRAME_MAX;
frame->isValid = true;
return SUCCESS;
}
+98
View File
@@ -0,0 +1,98 @@
/*****************************************************************************/
/**
* Description: MPC uart driver implementation file.
*
* Date: 2023-05-06 10:59
* LastEditTime: 2023-05-06 21:48
* Revisions: Rev 0.0
* History:
* [2023-05-06]: Initial version.
*
* Copyright(c) 2022 Beijing Institute of Technology.
*
******************************************************************************/
#ifndef __MPC_HW_H
#define __MPC_HW_H
/**************************** Include Files *****************************/
#include <stdint.h>
#include <stdbool.h>
#include "util.h"
#include "xgpio.h"
#define MPC_FRAME_MAX 512
#define FRAME_PAYLOAD_POFFSET 2 // CheckSum, Dummy and DataLen
/**************************** Type Definitions *****************************/
/**
*
* Write a value to a SYSTEMBUS_UART register. A 32 bit write is performed.
* If the component is implemented in a smaller width, only the least
* significant data is written.
*
* @param baseAddr is the base address of the SYSTEMBUS_UARTdevice.
* @param offset is the register offset from the base to write to.
* @param data is the data written to the register.
*
* @return None.
*
* @note
* C-style signature:
* void MPC_HW_mWriteReg(uint32_t BaseAddress, unsigned RegOffset, uint32_t Data)
*
*/
#define MPC_HW_mWriteReg(baseAddr, offset, data) \
IO_Out32((baseAddr) + (offset), (uint32_t)(data))
/**
*
* Read a value from a SYSTEMBUS_UART register. A 32 bit read is performed.
* If the component is implemented in a smaller width, only the least
* significant data is read from the register. The most significant data
* will be read as 0.
*
* @param baseAddr is the base address of the SYSTEMBUS_UART device.
* @param offset is the register offset from the base to write to.
*
* @return Data is the data from the register.
*
* @note
* C-style signature:
* uint32_t MPC_HW_mReadReg(uint32_t BaseAddress, unsigned RegOffset)
*
*/
#define MPC_HW_mReadReg(baseAddr, offset) \
IO_In32((baseAddr) + (offset))
typedef struct
{
uintptr_t txBuffAddr;
uintptr_t rxBuffAddr;
uint32_t gpioId;
} MPC_HW_CONFIG;
typedef struct
{
MPC_HW_CONFIG config;
XGpio gpioDesc;
} MPC_HW;
typedef struct
{
uint16_t len;
uint8_t checkSum;
uint8_t isValid;
uint8_t data[MPC_FRAME_MAX];
} MPC_HW_FRAME;
/************************** Function Prototypes ******************************/
// Instance initial
int MpcHw_Init(MPC_HW **instPtr, MPC_HW_CONFIG *config);
// Send a MPC frame.
int MpcHw_Send(MPC_HW *instPtr, MPC_HW_FRAME *frame);
// Get last MPC frame.
int MpcHw_Recv(MPC_HW *instPtr, MPC_HW_FRAME *frame);
#endif // __MPC_HW_H
+22 -3
View File
@@ -29,7 +29,6 @@
#include "link_layer.h" #include "link_layer.h"
/************************** Constant Definitions *****************************/ /************************** Constant Definitions *****************************/
/*****************************************************************************/ /*****************************************************************************/
/** /**
* @brief Insert a data chunk to a bit array. * @brief Insert a data chunk to a bit array.
@@ -42,7 +41,7 @@
* @return NONE * @return NONE
* *
******************************************************************************/ ******************************************************************************/
void L2_FrameInsertChunk(uint8_t *frame, size_t offset, size_t bytes, const void *chunk) inline void L2_FrameInsertChunk(uint8_t *frame, size_t offset, size_t bytes, const void *chunk)
{ {
ASSERT(frame != NULL); ASSERT(frame != NULL);
ASSERT(chunk != NULL); ASSERT(chunk != NULL);
@@ -61,13 +60,33 @@ void L2_FrameInsertChunk(uint8_t *frame, size_t offset, size_t bytes, const void
* @return NONE * @return NONE
* *
******************************************************************************/ ******************************************************************************/
void L2_FrameGetChunk(uint8_t *frame, size_t offset, size_t bytes, void *chunk) inline void L2_FrameGetChunk(uint8_t *frame, size_t offset, size_t bytes, void *chunk)
{ {
ASSERT(frame != NULL); ASSERT(frame != NULL);
ASSERT(chunk != NULL); ASSERT(chunk != NULL);
memcpy(chunk, frame + offset, bytes); memcpy(chunk, frame + offset, bytes);
} }
/*****************************************************************************/
/**
* @brief Insert a integer to a bit array.
*
* @param frame pointer to target bit array.
* @param offset offset of insert start position.
* @param bytes the number of bytes of integer
* @param val data value
*
* @return NONE
*
******************************************************************************/
void L2_FrameInsertInteger(uint8_t *frame, size_t offset, size_t bytes, uint64_t val)
{
ASSERT(bytes <= 4 && bytes > 0);
uint64_t _val = val;
L2_FrameInsertChunk(frame, offset, bytes, &_val);
}
/*****************************************************************************/ /*****************************************************************************/
/** /**
* @brief Generate crc of specified data. * @brief Generate crc of specified data.
+73 -22
View File
@@ -27,10 +27,7 @@
#include "common.h" #include "common.h"
#include "util.h" #include "util.h"
#include "circ_queue.h" #include "circ_queue.h"
#include "../time_ctrl/time_ctrl.h" #include "time_ctrl/time_ctrl.h"
#ifndef EMULATION
#include "../config/app_config.h"
#endif
/************************** Constant Definitions *****************************/ /************************** Constant Definitions *****************************/
#define NET_START_TIME_INFTY UINT32_MAX #define NET_START_TIME_INFTY UINT32_MAX
#define LINK_BROCK_THRESHOLD L2_SLOTS_PER_FRAME // 0.5 secods #define LINK_BROCK_THRESHOLD L2_SLOTS_PER_FRAME // 0.5 secods
@@ -159,12 +156,18 @@ static void L2_FrameStateUpdate(L2_INST *instPtr)
instPtr->log.cfmRecvCnt++; instPtr->log.cfmRecvCnt++;
instPtr->log.cfmCorrectCnt = isValid ? instPtr->log.cfmCorrectCnt + 1 : instPtr->log.cfmCorrectCnt; instPtr->log.cfmCorrectCnt = isValid ? instPtr->log.cfmCorrectCnt + 1 : instPtr->log.cfmCorrectCnt;
break; break;
case L2_SVC_FRAME: case L2_SVC_2K_FRAME:
#ifndef DATALINK_ENABLE_BERTEST isValid = L2_CrcCheck(instPtr->recvPktData, L2_SVC_PACK_2K_LEN, L2_CRC16_1021);
isValid = L2_CrcCheck(instPtr->recvPktData, L2_SVC_PACK_LEN, L2_CRC16_1021); instPtr->log.svcRecvCnt++;
#else instPtr->log.svcCorrectCnt = isValid ? instPtr->log.svcCorrectCnt + 1 : instPtr->log.svcCorrectCnt;
isValid = true; break;
#endif case L2_SVC_128K_FRAME:
isValid = L2_CrcCheck(instPtr->recvPktData, L2_SVC_PACK_128K_LEN, L2_CRC16_1021);
instPtr->log.svcRecvCnt++;
instPtr->log.svcCorrectCnt = isValid ? instPtr->log.svcCorrectCnt + 1 : instPtr->log.svcCorrectCnt;
break;
case L2_SVC_256K_FRAME:
isValid = L2_CrcCheck(instPtr->recvPktData, L2_SVC_PACK_256K_LEN, L2_CRC16_1021);
instPtr->log.svcRecvCnt++; instPtr->log.svcRecvCnt++;
instPtr->log.svcCorrectCnt = isValid ? instPtr->log.svcCorrectCnt + 1 : instPtr->log.svcCorrectCnt; instPtr->log.svcCorrectCnt = isValid ? instPtr->log.svcCorrectCnt + 1 : instPtr->log.svcCorrectCnt;
break; break;
@@ -333,6 +336,15 @@ inline L2_FRAME_TYPE L2_GetCurrentFrameType(L2_INST *instPtr)
return instPtr->frame.curr; return instPtr->frame.curr;
} }
/**
* @brief Get the current working speed mode.
*/
inline L2_SPEED_MODE L2_GetCurrentSpeedMode(L2_INST *instPtr)
{
ASSERT(instPtr != NULL);
return instPtr->speedMode;
}
/** /**
* @brief Get the tx/rx state of current slot. * @brief Get the tx/rx state of current slot.
*/ */
@@ -422,8 +434,12 @@ L1_FRAME_TYPE L2_L2frame2L1frame(L2_FRAME_TYPE l2Frame)
case L2_ADV_FRAME: case L2_ADV_FRAME:
return L1_10KBPS_20MS_FRAME; return L1_10KBPS_20MS_FRAME;
case L2_CFM_FRAME: case L2_CFM_FRAME:
case L2_SVC_FRAME: case L2_SVC_2K_FRAME:
return L1_40KBPS_20MS_FRAME; return L1_40KBPS_20MS_FRAME;
case L2_SVC_128K_FRAME:
return L1_200KBPS_5MS_FRAME;
case L2_SVC_256K_FRAME:
return L1_1M2BPS_5MS_FRAME;
default: default:
return L1_NONE_FRAME; return L1_NONE_FRAME;
} }
@@ -471,6 +487,7 @@ int32_t Linklayer_Init(L2_INST **instPtr, const L2_CONFIG *config)
// Clear random content // Clear random content
memset(*instPtr, 0x00, sizeof(L2_INST)); memset(*instPtr, 0x00, sizeof(L2_INST));
(*instPtr)->speedMode = config->speedMode;
(*instPtr)->sendPktData = NULL; (*instPtr)->sendPktData = NULL;
(*instPtr)->recvPktData = NULL; (*instPtr)->recvPktData = NULL;
(*instPtr)->schdEventPool = NULL; (*instPtr)->schdEventPool = NULL;
@@ -802,8 +819,25 @@ int32_t Linklayer_EventHandler(L2_INST *instPtr, const L2_EVENT *l2Event)
else if (instPtr->nextState == L2_NORMAL_STATE) else if (instPtr->nextState == L2_NORMAL_STATE)
{ {
UpdateMainSate(instPtr, L2_NORMAL_STATE); UpdateMainSate(instPtr, L2_NORMAL_STATE);
instPtr->rtneConfig.rtneTable = normalTable; switch(L2_GetCurrentSpeedMode(instPtr)){
instPtr->rtneConfig.rtnePrd = ARRAY_SIZE(normalTable); case L2_SPEED_NONE :
DBG_WARNING("Speed mode not configured, fallback to 2Kbps mode.\n");
case L2_SPEED_2KBPS :
instPtr->rtneConfig.rtneTable = normalTable2K;
instPtr->rtneConfig.rtnePrd = ARRAY_SIZE(normalTable2K);
break;
case L2_SPEED_128KBPS :
instPtr->rtneConfig.rtneTable = normalTable128K;
instPtr->rtneConfig.rtnePrd = ARRAY_SIZE(normalTable128K);
break;
case L2_SPEED_256KBPS :
instPtr->rtneConfig.rtneTable = normalTable256K;
instPtr->rtneConfig.rtnePrd = ARRAY_SIZE(normalTable256K);
break;
default:
DBG_ERROR("Unknown speed mode %d.\n", instPtr->speedMode);
ASSERT(true);
}
} }
else else
{ {
@@ -856,7 +890,9 @@ int32_t Linklayer_PktHandler(L2_INST *instPtr, L2_FRAME_TYPE frameType)
case L2_CFM_FRAME: case L2_CFM_FRAME:
Status = L2_Scan_PktHandler(instPtr, instPtr->recvPktData); Status = L2_Scan_PktHandler(instPtr, instPtr->recvPktData);
break; break;
case L2_SVC_FRAME: case L2_SVC_2K_FRAME:
case L2_SVC_128K_FRAME:
case L2_SVC_256K_FRAME:
Status = L2_Service_PktHandler(instPtr, instPtr->recvPktData); Status = L2_Service_PktHandler(instPtr, instPtr->recvPktData);
break; break;
default: default:
@@ -880,7 +916,6 @@ static int32_t IntcNodeTTL(NODE_ENTRY *node, const void *param)
/** /**
* @brief Utility function to check connection to node is still valid. * @brief Utility function to check connection to node is still valid.
*/ */
#ifdef DATALINK_ENABLE_AUTORECONNECT
static bool IsNodeConnected(NODE_ENTRY *node) static bool IsNodeConnected(NODE_ENTRY *node)
{ {
ASSERT(node != NULL); ASSERT(node != NULL);
@@ -895,7 +930,6 @@ static bool IsNodeConnected(NODE_ENTRY *node)
return false; return false;
} }
} }
#endif
/*****************************************************************************/ /*****************************************************************************/
/** /**
@@ -937,7 +971,9 @@ static int32_t Linklayer_Routine(L2_INST *instPtr)
case L2_SLOT_CONFIRM: case L2_SLOT_CONFIRM:
Status = L2_Scan_Routine(instPtr, &rtneEntry); Status = L2_Scan_Routine(instPtr, &rtneEntry);
break; break;
case L2_SLOT_SERVICE: case L2_SLOT_SERVICE_2K:
case L2_SLOT_SERVICE_128K:
case L2_SLOT_SERVICE_256K:
Status = L2_Service_Routine(instPtr, &rtneEntry); Status = L2_Service_Routine(instPtr, &rtneEntry);
break; break;
default: default:
@@ -956,7 +992,7 @@ static int32_t Linklayer_Routine(L2_INST *instPtr)
uint32_t increment = 1; uint32_t increment = 1;
L2_IterEditNode(instPtr->nodeList, &increment, IntcNodeTTL); L2_IterEditNode(instPtr->nodeList, &increment, IntcNodeTTL);
#ifdef DATALINK_ENABLE_AUTORECONNECT //#ifdef DATALINK_ENABLE_AUTORECONNECT
if (L2_GetMainState(instPtr) != L2_INIT_STATE) if (L2_GetMainState(instPtr) != L2_INIT_STATE)
{ {
L2_IterDeleteNode(instPtr->nodeList, IsNodeConnected); L2_IterDeleteNode(instPtr->nodeList, IsNodeConnected);
@@ -970,7 +1006,7 @@ static int32_t Linklayer_Routine(L2_INST *instPtr)
AssertL2Event(instPtr, &l2Event); AssertL2Event(instPtr, &l2Event);
} }
} }
#endif //#endif
return Status; return Status;
} }
@@ -1165,7 +1201,7 @@ int32_t L2_SetupNextSlot(L2_INST *instPtr, L2_TOR_TYPE txrxMode, L2_FRAME_TYPE f
ASSERT(instPtr != NULL); ASSERT(instPtr != NULL);
PHY_INST *phyRef = instPtr->config.phyInstPtr; PHY_INST *phyRef = instPtr->config.phyInstPtr;
int32_t Status; int32_t Status;
if (frameType < L2_SCAN_FRAME || frameType > L2_SVC_FRAME) if (frameType < L2_SCAN_FRAME || frameType > L2_SVC_256K_FRAME)
{ {
return FAILURE; return FAILURE;
} }
@@ -1182,7 +1218,9 @@ int32_t L2_SetupNextSlot(L2_INST *instPtr, L2_TOR_TYPE txrxMode, L2_FRAME_TYPE f
case L2_CFM_FRAME: case L2_CFM_FRAME:
instPtr->log.cfmTxCnt++; instPtr->log.cfmTxCnt++;
break; break;
case L2_SVC_FRAME: case L2_SVC_2K_FRAME:
case L2_SVC_128K_FRAME:
case L2_SVC_256K_FRAME:
instPtr->log.svcTxCnt++; instPtr->log.svcTxCnt++;
break; break;
default: default:
@@ -1200,7 +1238,9 @@ int32_t L2_SetupNextSlot(L2_INST *instPtr, L2_TOR_TYPE txrxMode, L2_FRAME_TYPE f
case L2_CFM_FRAME: case L2_CFM_FRAME:
instPtr->log.cfmRxCnt++; instPtr->log.cfmRxCnt++;
break; break;
case L2_SVC_FRAME: case L2_SVC_2K_FRAME:
case L2_SVC_128K_FRAME:
case L2_SVC_256K_FRAME:
instPtr->log.svcRxCnt++; instPtr->log.svcRxCnt++;
break; break;
default: default:
@@ -1284,5 +1324,16 @@ int32_t L2_SetupNextSlot(L2_INST *instPtr, L2_TOR_TYPE txrxMode, L2_FRAME_TYPE f
} }
return Status; return Status;
} }
int32_t Linklayer_UpdateSpeedMode(L2_INST *instPtr, L2_SPEED_MODE mode) {
ASSERT(instPtr != NULL);
if(mode < L2_SPEED_2KBPS || mode > L2_SPEED_256KBPS){
DBG_ERROR("Unsurpport speed mode, %d.\n", mode);
return EIGNORE;
}
instPtr->speedMode = mode;
return SUCCESS;
}
/** @} LinkLayer_Main*/ /** @} LinkLayer_Main*/
/** @} LinkLayer*/ /** @} LinkLayer*/
+13 -4
View File
@@ -25,8 +25,8 @@
#include "schdevent.h" #include "schdevent.h"
#include "node_list.h" #include "node_list.h"
#include "circ_queue.h" #include "circ_queue.h"
#include "../phy_layer/phy_layer.h" #include "networking/phy_layer/phy_layer.h"
#include "../../system_monitor.h" #include "system_monitor.h"
/************************** Constant Definitions *****************************/ /************************** Constant Definitions *****************************/
/***************** Macros (Inline Functions) Definitions *********************/ /***************** Macros (Inline Functions) Definitions *********************/
#define AssertL2Event(instPtr, event) (Linklayer_EventHandler((instPtr), (event))) #define AssertL2Event(instPtr, event) (Linklayer_EventHandler((instPtr), (event)))
@@ -45,6 +45,9 @@ typedef struct
uint8_t netScale; ///< net scale uint8_t netScale; ///< net scale
PHY_INST *phyInstPtr; ///< pointer to system physical layer instance PHY_INST *phyInstPtr; ///< pointer to system physical layer instance
TMC_INST *tmcInstPtr; ///< pointer to system timer controller layer instance TMC_INST *tmcInstPtr; ///< pointer to system timer controller layer instance
L2_SPEED_MODE speedMode;///< service speed mode
PUSHUP_HANDLE pushUpHandle;
POPUP_HANDLE popUpHandle;
} L2_CONFIG; } L2_CONFIG;
/** /**
@@ -104,6 +107,7 @@ typedef struct
L2_RTNE_CONFIG rtneConfig; ///< current routine table configuration and status. L2_RTNE_CONFIG rtneConfig; ///< current routine table configuration and status.
L2_SCAN_FSM *scanFSM; ///< FSM of scan net (link set up) L2_SCAN_FSM *scanFSM; ///< FSM of scan net (link set up)
L2_SVC_FSM *serviceFSM; ///< FSM of service net (data service) L2_SVC_FSM *serviceFSM; ///< FSM of service net (data service)
L2_SPEED_MODE speedMode;
uint8_t *sendPktData; ///< send data buffer uint8_t *sendPktData; ///< send data buffer
uint8_t *recvPktData; ///< received data buffer uint8_t *recvPktData; ///< received data buffer
L2_LOG log; ///< Linklayer operating log L2_LOG log; ///< Linklayer operating log
@@ -114,7 +118,9 @@ typedef struct
/************************** Variable Definitions *****************************/ /************************** Variable Definitions *****************************/
extern L2_RTNE_TABLE_ENTRY *initTable[L2_INIT_RTNE_PERIOD]; extern L2_RTNE_TABLE_ENTRY *initTable[L2_INIT_RTNE_PERIOD];
extern L2_RTNE_TABLE_ENTRY *normalTable[L2_NORMAL_RTNE_PERIOD]; extern L2_RTNE_TABLE_ENTRY *normalTable2K[L2_NORMAL_RTNE_PERIOD];
extern L2_RTNE_TABLE_ENTRY *normalTable128K[L2_NORMAL_RTNE_PERIOD];
extern L2_RTNE_TABLE_ENTRY *normalTable256K[L2_NORMAL_RTNE_PERIOD];
/************************** Function Prototypes ******************************/ /************************** Function Prototypes ******************************/
/** /**
* @defgroup LinkLayer_Main * @defgroup LinkLayer_Main
@@ -130,6 +136,7 @@ int32_t Linklayer_EventHandler(L2_INST *instPtr, const L2_EVENT *l2Event);
int32_t Linklayer_PktHandler(L2_INST *instPtr, L2_FRAME_TYPE frameType); int32_t Linklayer_PktHandler(L2_INST *instPtr, L2_FRAME_TYPE frameType);
int32_t L2_SteerBeam2Node(L2_INST *instPtr, uint8_t nodeId); int32_t L2_SteerBeam2Node(L2_INST *instPtr, uint8_t nodeId);
int32_t L2_SetupNextSlot(L2_INST *instPtr, L2_TOR_TYPE txrxMode, L2_FRAME_TYPE frameType); int32_t L2_SetupNextSlot(L2_INST *instPtr, L2_TOR_TYPE txrxMode, L2_FRAME_TYPE frameType);
int32_t Linklayer_UpdateSpeedMode(L2_INST *instPtr, L2_SPEED_MODE mode);
/** @} LinkLayer_Main*/ /** @} LinkLayer_Main*/
/** /**
@@ -138,6 +145,7 @@ int32_t L2_SetupNextSlot(L2_INST *instPtr, L2_TOR_TYPE txrxMode, L2_FRAME_TYPE f
*/ */
void L2_FrameInsertChunk(uint8_t *frame, size_t offset, size_t bytes, const void *chunk); void L2_FrameInsertChunk(uint8_t *frame, size_t offset, size_t bytes, const void *chunk);
void L2_FrameGetChunk(uint8_t *frame, size_t offset, size_t bytes, void *chunk); void L2_FrameGetChunk(uint8_t *frame, size_t offset, size_t bytes, void *chunk);
void L2_FrameInsertInteger(uint8_t *frame, size_t offset, size_t bytes, uint64_t val);
int32_t L2_CrcAppend(uint8_t *dataBuff, uint32_t dataLen, uint32_t crcPos, L2_CRC_TYPE crcType); int32_t L2_CrcAppend(uint8_t *dataBuff, uint32_t dataLen, uint32_t crcPos, L2_CRC_TYPE crcType);
bool L2_CrcCheck(uint8_t *dataBuff, uint32_t dataLen, L2_CRC_TYPE crcType); bool L2_CrcCheck(uint8_t *dataBuff, uint32_t dataLen, L2_CRC_TYPE crcType);
/** @} LinkLayer_Framing*/ /** @} LinkLayer_Framing*/
@@ -174,7 +182,6 @@ int32_t L2_Service_Init(L2_SVC_FSM **svcFSMPtr);
void L2_Service_Reset(L2_SVC_FSM *svcFSMPtr); void L2_Service_Reset(L2_SVC_FSM *svcFSMPtr);
void L2_Service_Destroy(L2_SVC_FSM *svcFSMPtr); void L2_Service_Destroy(L2_SVC_FSM *svcFSMPtr);
int32_t L2_Service_PktHandler(L2_INST *instPtr, uint8_t *msg); int32_t L2_Service_PktHandler(L2_INST *instPtr, uint8_t *msg);
int32_t L2_Service_Proc(L2_INST *instPtr);
int32_t L2_Service_Routine(L2_INST *instPtr, const L2_RTNE_TABLE_ENTRY *schedEntry); int32_t L2_Service_Routine(L2_INST *instPtr, const L2_RTNE_TABLE_ENTRY *schedEntry);
/** @} LinkLayer_Service*/ /** @} LinkLayer_Service*/
@@ -206,6 +213,7 @@ L2_TOR_TYPE L2_GetLastTor(L2_INST *instPtr);
uint32_t L2_GetCurrentFrameNum(L2_INST *instPtr); uint32_t L2_GetCurrentFrameNum(L2_INST *instPtr);
uint32_t L2_GetCurrentSlotNum(L2_INST *instPtr); uint32_t L2_GetCurrentSlotNum(L2_INST *instPtr);
L2_FRAME_TYPE L2_GetCurrentFrameType(L2_INST *instPtr); L2_FRAME_TYPE L2_GetCurrentFrameType(L2_INST *instPtr);
L2_SPEED_MODE L2_GetCurrentSpeedMode(L2_INST *instPtr);
L2_TOR_TYPE L2_GetCurrentTor(L2_INST *instPtr); L2_TOR_TYPE L2_GetCurrentTor(L2_INST *instPtr);
uint32_t L2_GetNextFrameNum(L2_INST *instPtr); uint32_t L2_GetNextFrameNum(L2_INST *instPtr);
uint32_t L2_GetNextSlotNum(L2_INST *instPtr); uint32_t L2_GetNextSlotNum(L2_INST *instPtr);
@@ -213,6 +221,7 @@ L2_FRAME_TYPE L2_GetNextFrameType(L2_INST *instPtr);
L2_TOR_TYPE L2_GetNextTor(L2_INST *instPtr); L2_TOR_TYPE L2_GetNextTor(L2_INST *instPtr);
L2_FRAME_TYPE L2_GetLastOptFrameType(L2_INST *instPtr); L2_FRAME_TYPE L2_GetLastOptFrameType(L2_INST *instPtr);
L1_FRAME_TYPE L2_L2frame2L1frame(L2_FRAME_TYPE l2Frame); L1_FRAME_TYPE L2_L2frame2L1frame(L2_FRAME_TYPE l2Frame);
/** @} LinkLayer_Utility*/ /** @} LinkLayer_Utility*/
#endif /* __LINK_LAYER_H_ */ #endif /* __LINK_LAYER_H_ */
+27 -12
View File
@@ -21,12 +21,10 @@
/***************************** Include Files *********************************/ /***************************** Include Files *********************************/
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "ring_buffer.h"
#include "geometry/coord.h" #include "geometry/coord.h"
#include "geometry/quaternion.h" #include "geometry/quaternion.h"
#include "../phy_layer/phy_layer.h" #include "networking/phy_layer/phy_layer.h"
#ifndef EMULATION
#include "../config/app_config.h"
#endif
/************************** Constant Definitions *****************************/ /************************** Constant Definitions *****************************/
/** /**
* @name Linklayer_Common_Constants * @name Linklayer_Common_Constants
@@ -158,7 +156,9 @@ typedef enum
L2_SLOT_SCAN = 2, L2_SLOT_SCAN = 2,
L2_SLOT_ADVERTISE = 3, L2_SLOT_ADVERTISE = 3,
L2_SLOT_CONFIRM = 4, L2_SLOT_CONFIRM = 4,
L2_SLOT_SERVICE = 5, L2_SLOT_SERVICE_2K = 5,
L2_SLOT_SERVICE_128K = 6,
L2_SLOT_SERVICE_256K = 7,
} L2_SLOT_TYPE; } L2_SLOT_TYPE;
/** /**
@@ -170,9 +170,22 @@ typedef enum
L2_SCAN_FRAME = 1, L2_SCAN_FRAME = 1,
L2_ADV_FRAME = 2, L2_ADV_FRAME = 2,
L2_CFM_FRAME = 3, L2_CFM_FRAME = 3,
L2_SVC_FRAME = 4 L2_SVC_2K_FRAME = 4,
L2_SVC_128K_FRAME = 5,
L2_SVC_256K_FRAME = 6
} L2_FRAME_TYPE; } L2_FRAME_TYPE;
/**
* @enum L2_SPEED_MODE
*/
typedef enum
{
L2_SPEED_NONE = 0,
L2_SPEED_2KBPS = 1,
L2_SPEED_128KBPS = 2,
L2_SPEED_256KBPS = 3,
} L2_SPEED_MODE;
/** /**
* @enum L2_CRC_TYPE * @enum L2_CRC_TYPE
*/ */
@@ -234,12 +247,10 @@ typedef struct
uint32_t txCnt; ///< tx frame count uint32_t txCnt; ///< tx frame count
uint32_t rxCnt; ///< rx frame count uint32_t rxCnt; ///< rx frame count
uint32_t rxdCnt; ///< received frame count uint32_t rxdCnt; ///< received frame count
#ifdef DATALINK_ENABLE_BERTEST uint8_t currTxSeq; ///< seqid of current tx frame sub-packet
uint32_t bitTotal; ///< received bits count uint8_t currRxSeq; ///< seqid of current rx frame sub-packet
uint32_t bitError; ///< error bits count RING_BUFFER *currTxBuff; ///< a ring buffer to store data to be sent
double lossRate; ///< packet loss rate RING_BUFFER *currRxBuff; ///< a ring buffer to store data received
double errorRate; ///< bit error rate
#endif
} L2_SVC_FSM; } L2_SVC_FSM;
/** /**
@@ -255,6 +266,10 @@ typedef struct
L2_RTNE_TABLE_ENTRY *next; ///< next routine entry L2_RTNE_TABLE_ENTRY *next; ///< next routine entry
} L2_RTNE_CONFIG; } L2_RTNE_CONFIG;
typedef bool (*PUSHUP_HANDLE) (RING_BUFFER *buff);
typedef bool (*POPUP_HANDLE) (RING_BUFFER **buff);
/************************** Variable Definitions *****************************/ /************************** Variable Definitions *****************************/
#endif /* __LINK_LAYER_DEF_H_ */ #endif /* __LINK_LAYER_DEF_H_ */
+32 -27
View File
@@ -1,6 +1,6 @@
/*****************************************************************************/ /*****************************************************************************/
/** /**
* @file msg_def.c * @file msg_def.h
* @author FanHao ([email protected]) * @author FanHao ([email protected])
* @brief DF Linklayer message definition constants. * @brief DF Linklayer message definition constants.
* @version 0.0 * @version 0.0
@@ -20,14 +20,34 @@
* @name LinkLayer_MSG_Constants * @name LinkLayer_MSG_Constants
* @{ * @{
*/ */
#ifndef __L2_MSG_DEF_H_ #ifndef __L2_MSG_DEF_H_
#define __L2_MSG_DEF_H_ #define __L2_MSG_DEF_H_
#include "link_layer.h"
#define L2_PACK_LEN_MAX 512 // bytes #define L2_PACK_LEN_MAX 512 // bytes
#define L2_ADV_PACK_LEN 28 // bytes #define L2_ADV_PACK_LEN 28 // bytes
#define L2_CMF_PACK_LEN 268 // bytes #define L2_CMF_PACK_LEN 268 // bytes
#define L2_SVC_PACK_LEN 268 // bytes #define L2_SVC_PACK_2K_LEN 30 // bytes: 16(128b) payload + 12 head + 2 crc
#define L2_SVC_PACK_128K_LEN 174 // bytes: 160(1280b) payload + 12 head + 2 crc
#define L2_SVC_PACK_256K_LEN 334 // bytes: 320(2560b) payload + 12 head + 2 crc
#define L2_ASSEMBLE_INTEGER(buff, offset, val) { \
L2_FrameInsertInteger(buff, offset, offset##_LEN, val); \
}
#define L2_ASSEMBLE_FLOAT(buff, offset, ptr) { \
L2_FrameInsertChunk(buff, offset, sizeof(float), ptr); \
}
#define L2_ASSEMBLE_DOUBLE(buff, offset, ptr) { \
L2_FrameInsertChunk(buff, offset, sizeof(double), ptr); \
}
#define L2_DEASSEMBLE(buff, offset, ptr) { \
L2_FrameGetChunk(buff, offset, offset##_LEN, ptr); \
}
// Common structure: // Common structure:
// [bytes] [name] // [bytes] [name]
@@ -96,31 +116,16 @@
// service payload structure: // service payload structure:
// [bytes] [name] // [bytes] [name]
// 4 position x // 1 packet flag
// 4 position y // 1 packet id
// 4 position z // 2 data length
// 4 speed x #define L2_MSG_SVC_PKTFLG 8 // 0-no subpacket, 1-subpacket 2-last subpacket
// 4 speed y #define L2_MSG_SVC_PKTFLG_LEN 1
// 4 speed z #define L2_MSG_SVC_PKTID 9
// 234 payload #define L2_MSG_SVC_PKTID_LEN 1
// 2 crc #define L2_MSG_SVC_DLEN 10
#define L2_MSG_SVC_SRC_POSX 8 #define L2_MSG_SVC_DLEN_LEN 2
#define L2_MSG_SVC_SRC_POSX_LEN 4 #define L2_MSG_SVC_PAYLOAD 12
#define L2_MSG_SVC_SRC_POSY 12
#define L2_MSG_SVC_SRC_POSY_LEN 4
#define L2_MSG_SVC_SRC_POSZ 16
#define L2_MSG_SVC_SRC_POSZ_LEN 4
#define L2_MSG_SVC_SRC_SPEEDX 20
#define L2_MSG_SVC_SRC_SPEEDX_LEN 4
#define L2_MSG_SVC_SRC_SPEEDY 24
#define L2_MSG_SVC_SRC_SPEEDY_LEN 4
#define L2_MSG_SVC_SRC_SPEEDZ 28
#define L2_MSG_SVC_SRC_SPEEDZ_LEN 4
#define L2_MSG_SVC_PAYLOAD_ID 32
#define L2_MSG_SVC_PAYLOAD_ID_LEN 4
#define L2_MSG_SVC_PAYLOAD 36
#define L2_MSG_SVC_PAYLOAD_LEN 230
#define L2_MSG_SVC_CRC 266
#define L2_MSG_SVC_CRC_LEN 2 #define L2_MSG_SVC_CRC_LEN 2
#endif //__L2_MSG_DEF_H_ #endif //__L2_MSG_DEF_H_
+318 -83
View File
@@ -137,126 +137,361 @@ L2_RTNE_TABLE_ENTRY intraScanSubT[L2_SLOTS_PER_FRAME] = {
{L2_SLOT_IDLE, 0x00, 0x00, 0x00}, {L2_SLOT_IDLE, 0x00, 0x00, 0x00},
}; };
L2_RTNE_TABLE_ENTRY normalSub[L2_SLOTS_PER_FRAME] = { L2_RTNE_TABLE_ENTRY normalSub2K[L2_SLOTS_PER_FRAME] = {
// SubFrame 0 // SubFrame 0
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00}, {L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x03, 0x02, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00}, {L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00}, {L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x03, 0x02, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00}, {L2_SLOT_IDLE, 0x00, 0x00, 0x00},
// SubFrame 1 // SubFrame 1
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00}, {L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x03, 0x02, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00}, {L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00}, {L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x03, 0x02, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00}, {L2_SLOT_IDLE, 0x00, 0x00, 0x00},
// SubFrame 2 // SubFrame 2
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00}, {L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x03, 0x02, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00}, {L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00}, {L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x03, 0x02, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00}, {L2_SLOT_IDLE, 0x00, 0x00, 0x00},
// SubFrame 3 // SubFrame 3
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00}, {L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x03, 0x02, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00}, {L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00}, {L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x03, 0x02, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00}, {L2_SLOT_IDLE, 0x00, 0x00, 0x00},
// SubFrame 4 // SubFrame 4
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00}, {L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x03, 0x02, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00}, {L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02}, {L2_SLOT_SERVICE_2K, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00}, {L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01}, {L2_SLOT_SERVICE_2K, 0x03, 0x02, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00}, {L2_SLOT_IDLE, 0x00, 0x00, 0x00},
}; };
L2_RTNE_TABLE_ENTRY normalSub128K[L2_SLOTS_PER_FRAME] = {
// SubFrame 0
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
// SubFrame 1
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
// SubFrame 2
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
// SubFrame 3
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
// SubFrame 4
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_128K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_128K, 0x00, 0x02, 0x01},
};
L2_RTNE_TABLE_ENTRY normalSub256K[L2_SLOTS_PER_FRAME] = {
// SubFrame 0
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
// SubFrame 1
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
// SubFrame 2
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
// SubFrame 3
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
// SubFrame 4
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_256K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_256K, 0x00, 0x02, 0x01},
};
L2_RTNE_TABLE_ENTRY *initTable[L2_INIT_RTNE_PERIOD] = L2_RTNE_TABLE_ENTRY *initTable[L2_INIT_RTNE_PERIOD] =
{ {
intraScanSubT intraScanSubT
}; };
L2_RTNE_TABLE_ENTRY *normalTable[L2_NORMAL_RTNE_PERIOD] = L2_RTNE_TABLE_ENTRY *normalTable2K[L2_NORMAL_RTNE_PERIOD] =
{ {
normalSub normalSub2K
};
L2_RTNE_TABLE_ENTRY *normalTable128K[L2_NORMAL_RTNE_PERIOD] =
{
normalSub128K
};
L2_RTNE_TABLE_ENTRY *normalTable256K[L2_NORMAL_RTNE_PERIOD] =
{
normalSub256K
}; };
/** @} RoutineTable*/ /** @} RoutineTable*/
+35 -79
View File
@@ -28,7 +28,7 @@
#include "node_list.h" #include "node_list.h"
#include "error.h" #include "error.h"
#include "common.h" #include "common.h"
#include "../phy_layer/phy_layer.h" #include "networking/phy_layer/phy_layer.h"
/************************** Constant Definitions *****************************/ /************************** Constant Definitions *****************************/
#define ADV_LISTEN_TIMEOUT 40 #define ADV_LISTEN_TIMEOUT 40
@@ -357,7 +357,6 @@ static int32_t ScanMsg_Packing(L2_INST *instPtr, L2_FRAME_TYPE type, uint8_t dst
{ {
ASSERT(instPtr != NULL); ASSERT(instPtr != NULL);
int32_t Status; int32_t Status;
uint32_t dataChunk;
uint8_t *buff = instPtr->sendPktData; uint8_t *buff = instPtr->sendPktData;
if ((type < L2_ADV_FRAME) || (type > L2_CFM_FRAME)) if ((type < L2_ADV_FRAME) || (type > L2_CFM_FRAME))
{ {
@@ -366,70 +365,49 @@ static int32_t ScanMsg_Packing(L2_INST *instPtr, L2_FRAME_TYPE type, uint8_t dst
} }
// Common section of link layer package // Common section of link layer package
dataChunk = L2_GetNextFrameNum(instPtr); L2_ASSEMBLE_INTEGER(buff, L2_MSG_FRAME_NUM, L2_GetNextFrameNum(instPtr));
L2_FrameInsertChunk(buff, L2_MSG_FRAME_NUM, L2_MSG_FRAME_NUM_LEN, &dataChunk); L2_ASSEMBLE_INTEGER(buff, L2_MSG_SLOT_NUM, L2_GetNextSlotNum(instPtr));
dataChunk = L2_GetNextSlotNum(instPtr); L2_ASSEMBLE_INTEGER(buff, L2_MSG_SRC_ID, L2_GetNodeId(instPtr));
L2_FrameInsertChunk(buff, L2_MSG_SLOT_NUM, L2_MSG_SLOT_NUM_LEN, &dataChunk); L2_ASSEMBLE_INTEGER(buff, L2_MSG_DST_ID, dstId);
dataChunk = L2_GetNodeId(instPtr);
L2_FrameInsertChunk(buff, L2_MSG_SRC_ID, L2_MSG_SRC_ID_LEN, &dataChunk);
dataChunk = dstId;
L2_FrameInsertChunk(buff, L2_MSG_DST_ID, L2_MSG_DST_ID_LEN, &dataChunk);
switch (type) switch (type)
{ {
case L2_ADV_FRAME: case L2_ADV_FRAME:
{ {
dataChunk = L2_ADV_FRAME; L2_ASSEMBLE_INTEGER(buff, L2_MSG_TYPE, L2_ADV_FRAME);
L2_FrameInsertChunk(buff, L2_MSG_TYPE, L2_MSG_TYPE_LEN, &dataChunk);
SysMonitor_GetSysinfo(&(instPtr->sysInfo)); SysMonitor_GetSysinfo(&(instPtr->sysInfo));
// insert position and speed info // insert position and speed info
L2_FrameInsertChunk(buff, L2_MSG_ADV_SRC_POSX, L2_MSG_ADV_SRC_POSX_LEN, &(instPtr->sysInfo.posX)); L2_ASSEMBLE_FLOAT(buff, L2_MSG_ADV_SRC_POSX, &(instPtr->sysInfo.posX));
L2_FrameInsertChunk(buff, L2_MSG_ADV_SRC_POSY, L2_MSG_ADV_SRC_POSY_LEN, &(instPtr->sysInfo.posY)); L2_ASSEMBLE_FLOAT(buff, L2_MSG_ADV_SRC_POSY, &(instPtr->sysInfo.posY));
L2_FrameInsertChunk(buff, L2_MSG_ADV_SRC_POSZ, L2_MSG_ADV_SRC_POSZ_LEN, &(instPtr->sysInfo.posZ)); L2_ASSEMBLE_FLOAT(buff, L2_MSG_ADV_SRC_POSZ, &(instPtr->sysInfo.posZ));
// Insert net start time // Insert net start time
L2_FrameInsertChunk(buff, L2_MSG_ADV_SRC_NETSTART_TIME, L2_MSG_ADV_SRC_NETSTART_TIME_LEN, &(instPtr->netStartTime)); L2_ASSEMBLE_INTEGER(buff, L2_MSG_ADV_SRC_NETSTART_TIME, instPtr->netStartTime);
// Append CRC // Append CRC
Status = L2_CrcAppend(buff, L2_ADV_PACK_LEN - L2_MSG_ADV_SVC_CRC_LEN, L2_MSG_ADV_SVC_CRC, L2_CRC16_1021); Status = L2_CrcAppend(buff, L2_ADV_PACK_LEN - L2_MSG_ADV_SVC_CRC_LEN, L2_MSG_ADV_SVC_CRC, L2_CRC16_1021);
if (Status != SUCCESS) if (Status != SUCCESS)
{ {
DBG_ERROR("Fail to append CRC, error code: %" PRId32 ".\n", Status); DBG_ERROR("Fail to append CRC, error code: %" PRId32 ".\n", Status);
return Status; ASSERT(true);
} }
break; break;
} }
case L2_CFM_FRAME: case L2_CFM_FRAME:
{ {
dataChunk = L2_CFM_FRAME; L2_ASSEMBLE_INTEGER(buff, L2_MSG_TYPE, L2_CFM_FRAME);
L2_FrameInsertChunk(buff, L2_MSG_TYPE, L2_MSG_TYPE_LEN, &dataChunk);
SysMonitor_GetSysinfo(&(instPtr->sysInfo)); SysMonitor_GetSysinfo(&(instPtr->sysInfo));
// insert position and speed info // insert position and speed info
L2_FrameInsertChunk(buff, L2_MSG_CFM_SRC_POSX, L2_MSG_CFM_SRC_POSX_LEN, &(instPtr->sysInfo.posX)); L2_ASSEMBLE_FLOAT(buff, L2_MSG_CFM_SRC_POSX, &(instPtr->sysInfo.posX));
L2_FrameInsertChunk(buff, L2_MSG_CFM_SRC_POSY, L2_MSG_CFM_SRC_POSY_LEN, &(instPtr->sysInfo.posY)); L2_ASSEMBLE_FLOAT(buff, L2_MSG_CFM_SRC_POSY, &(instPtr->sysInfo.posY));
L2_FrameInsertChunk(buff, L2_MSG_CFM_SRC_POSZ, L2_MSG_CFM_SRC_POSZ_LEN, &(instPtr->sysInfo.posZ)); L2_ASSEMBLE_FLOAT(buff, L2_MSG_CFM_SRC_POSZ, &(instPtr->sysInfo.posZ));
L2_FrameInsertChunk(buff, L2_MSG_CFM_SRC_SPEEDX, L2_MSG_CFM_SRC_SPEEDX_LEN, &(instPtr->sysInfo.vX)); L2_ASSEMBLE_FLOAT(buff, L2_MSG_CFM_SRC_SPEEDX, &(instPtr->sysInfo.vX));
L2_FrameInsertChunk(buff, L2_MSG_CFM_SRC_SPEEDY, L2_MSG_CFM_SRC_SPEEDY_LEN, &(instPtr->sysInfo.vY)); L2_ASSEMBLE_FLOAT(buff, L2_MSG_CFM_SRC_SPEEDY, &(instPtr->sysInfo.vY));
L2_FrameInsertChunk(buff, L2_MSG_CFM_SRC_SPEEDZ, L2_MSG_CFM_SRC_SPEEDZ_LEN, &(instPtr->sysInfo.vZ)); L2_ASSEMBLE_FLOAT(buff, L2_MSG_CFM_SRC_SPEEDZ, &(instPtr->sysInfo.vZ));
// Packing extra payload // Packing extra payload
uint32_t dataId;
if (L2_GetNodeType(instPtr) == L2_NODE_HEAD)
{
SysMonitor_GetSendPayload(buff + L2_MSG_CFM_PAYLOAD, &dataId, PAYLOAD_LEN_FLJ_TX);
}
else
{
SysMonitor_GetSendPayload(buff + L2_MSG_CFM_PAYLOAD, &dataId, PAYLOAD_LEN_LJ_TX);
}
L2_FrameInsertChunk(buff, L2_MSG_CFM_PAYLOAD_ID, L2_MSG_CFM_PAYLOAD_ID_LEN, &dataId);
if (dataId == DATA_ID_NONE)
{
memset(buff + L2_MSG_CFM_PAYLOAD, 0xAA, L2_MSG_CFM_PAYLOAD_LEN); memset(buff + L2_MSG_CFM_PAYLOAD, 0xAA, L2_MSG_CFM_PAYLOAD_LEN);
}
// Append CRC // Append CRC
Status = L2_CrcAppend(buff, L2_CMF_PACK_LEN - L2_MSG_CFM_CRC_LEN, L2_MSG_CFM_CRC, L2_CRC16_1021); Status = L2_CrcAppend(buff, L2_CMF_PACK_LEN - L2_MSG_CFM_CRC_LEN, L2_MSG_CFM_CRC, L2_CRC16_1021);
if (Status != SUCCESS) if (Status != SUCCESS)
@@ -437,10 +415,6 @@ static int32_t ScanMsg_Packing(L2_INST *instPtr, L2_FRAME_TYPE type, uint8_t dst
DBG_ERROR("Fail to append CRC, error code: %" PRId32 ".\n", Status); DBG_ERROR("Fail to append CRC, error code: %" PRId32 ".\n", Status);
return Status; return Status;
} }
// Logging...
memcpy(instPtr->log.txLog.data, buff, L2_CMF_PACK_LEN);
instPtr->log.txLog.dataId = dataId;
break; break;
} }
default: default:
@@ -469,7 +443,7 @@ int32_t L2_Scan_PktHandler(L2_INST *instPtr, uint8_t *msg)
int32_t Status; int32_t Status;
L2_SCAN_FSM *scanFsmPtr = instPtr->scanFSM; L2_SCAN_FSM *scanFsmPtr = instPtr->scanFSM;
L2_FRAME_TYPE frameType = L2_NONE_FRAME; L2_FRAME_TYPE frameType = L2_NONE_FRAME;
L2_FrameGetChunk(msg, L2_MSG_TYPE, L2_MSG_TYPE_LEN, &frameType); L2_DEASSEMBLE(msg, L2_MSG_TYPE, &frameType);
switch (frameType) switch (frameType)
{ {
case L2_SCAN_FRAME: case L2_SCAN_FRAME:
@@ -487,7 +461,7 @@ int32_t L2_Scan_PktHandler(L2_INST *instPtr, uint8_t *msg)
break; break;
} }
uint8_t nodeId; uint8_t nodeId;
L2_FrameGetChunk(msg, L2_MSG_SRC_ID, L2_MSG_SRC_ID_LEN, &nodeId); L2_DEASSEMBLE(msg, L2_MSG_SRC_ID, &nodeId);
NODE_ENTRY *node; NODE_ENTRY *node;
node = L2_GetNodeById(instPtr->nodeList, nodeId); node = L2_GetNodeById(instPtr->nodeList, nodeId);
if (node == NULL) if (node == NULL)
@@ -502,11 +476,11 @@ int32_t L2_Scan_PktHandler(L2_INST *instPtr, uint8_t *msg)
} }
// Update node info. // Update node info.
float nodePos; float nodePos;
L2_FrameGetChunk(msg, L2_MSG_ADV_SRC_POSX, L2_MSG_ADV_SRC_POSX_LEN, &nodePos); L2_DEASSEMBLE(msg, L2_MSG_ADV_SRC_POSX, &nodePos);
node->nodeInfo.pos.x = (double)nodePos; node->nodeInfo.pos.x = (double)nodePos;
L2_FrameGetChunk(msg, L2_MSG_ADV_SRC_POSY, L2_MSG_ADV_SRC_POSY_LEN, &nodePos); L2_DEASSEMBLE(msg, L2_MSG_ADV_SRC_POSY, &nodePos);
node->nodeInfo.pos.y = (double)nodePos; node->nodeInfo.pos.y = (double)nodePos;
L2_FrameGetChunk(msg, L2_MSG_ADV_SRC_POSZ, L2_MSG_ADV_SRC_POSZ_LEN, &nodePos); L2_DEASSEMBLE(msg, L2_MSG_ADV_SRC_POSZ, &nodePos);
node->nodeInfo.pos.z = (double)nodePos; node->nodeInfo.pos.z = (double)nodePos;
node->nodeInfo.beamNo = Phy_LastScanBeamNo(instPtr->config.phyInstPtr); node->nodeInfo.beamNo = Phy_LastScanBeamNo(instPtr->config.phyInstPtr);
@@ -515,7 +489,7 @@ int32_t L2_Scan_PktHandler(L2_INST *instPtr, uint8_t *msg)
uint32_t netstartTime; uint32_t netstartTime;
// Update net start time. // Update net start time.
L2_FrameGetChunk(msg, L2_MSG_ADV_SRC_NETSTART_TIME, L2_MSG_ADV_SRC_NETSTART_TIME_LEN, &netstartTime); L2_DEASSEMBLE(msg, L2_MSG_ADV_SRC_NETSTART_TIME, &netstartTime);
L2_EVENT netSetupDoneEvent = { L2_EVENT netSetupDoneEvent = {
.event = L2_EV_NET_ADV_UPDATE, .event = L2_EV_NET_ADV_UPDATE,
.msg = &netstartTime}; .msg = &netstartTime};
@@ -523,8 +497,8 @@ int32_t L2_Scan_PktHandler(L2_INST *instPtr, uint8_t *msg)
// Calculate time deviation // Calculate time deviation
uint32_t frameNum, slotNum = 0; uint32_t frameNum, slotNum = 0;
L2_FrameGetChunk(msg, L2_MSG_FRAME_NUM, L2_MSG_FRAME_NUM_LEN, &frameNum); L2_DEASSEMBLE(msg, L2_MSG_FRAME_NUM, &frameNum);
L2_FrameGetChunk(msg, L2_MSG_SLOT_NUM, L2_MSG_SLOT_NUM_LEN, &slotNum); L2_DEASSEMBLE(msg, L2_MSG_SLOT_NUM, &slotNum);
Status = L2_GetTimeDeviation(instPtr, frameNum, slotNum, true, &(instPtr->log.timeDev)); Status = L2_GetTimeDeviation(instPtr, frameNum, slotNum, true, &(instPtr->log.timeDev));
if (Status != SUCCESS) if (Status != SUCCESS)
{ {
@@ -543,7 +517,7 @@ int32_t L2_Scan_PktHandler(L2_INST *instPtr, uint8_t *msg)
case L2_CFM_FRAME: case L2_CFM_FRAME:
{ {
uint8_t nodeId; uint8_t nodeId;
L2_FrameGetChunk(msg, L2_MSG_SRC_ID, L2_MSG_SRC_ID_LEN, &nodeId); L2_DEASSEMBLE(msg, L2_MSG_SRC_ID, &nodeId);
NODE_ENTRY *node; NODE_ENTRY *node;
node = L2_GetNodeById(instPtr->nodeList, nodeId); node = L2_GetNodeById(instPtr->nodeList, nodeId);
if (node == NULL) if (node == NULL)
@@ -558,18 +532,18 @@ int32_t L2_Scan_PktHandler(L2_INST *instPtr, uint8_t *msg)
} }
// Update node info. // Update node info.
float nodePos; float nodePos;
L2_FrameGetChunk(msg, L2_MSG_CFM_SRC_POSX, L2_MSG_CFM_SRC_POSX_LEN, &nodePos); L2_DEASSEMBLE(msg, L2_MSG_CFM_SRC_POSX, &nodePos);
node->nodeInfo.pos.x = (double)nodePos; node->nodeInfo.pos.x = (double)nodePos;
L2_FrameGetChunk(msg, L2_MSG_CFM_SRC_POSY, L2_MSG_CFM_SRC_POSY_LEN, &nodePos); L2_DEASSEMBLE(msg, L2_MSG_CFM_SRC_POSY, &nodePos);
node->nodeInfo.pos.y = (double)nodePos; node->nodeInfo.pos.y = (double)nodePos;
L2_FrameGetChunk(msg, L2_MSG_CFM_SRC_POSZ, L2_MSG_CFM_SRC_POSZ_LEN, &nodePos); L2_DEASSEMBLE(msg, L2_MSG_CFM_SRC_POSZ, &nodePos);
node->nodeInfo.pos.z = (double)nodePos; node->nodeInfo.pos.z = (double)nodePos;
float nodeSpeed; float nodeSpeed;
L2_FrameGetChunk(msg, L2_MSG_CFM_SRC_SPEEDX, L2_MSG_CFM_SRC_SPEEDX_LEN, &nodeSpeed); L2_DEASSEMBLE(msg, L2_MSG_CFM_SRC_SPEEDX, &nodeSpeed);
node->nodeInfo.speed.x = (double)nodePos; node->nodeInfo.speed.x = (double)nodePos;
L2_FrameGetChunk(msg, L2_MSG_CFM_SRC_SPEEDY, L2_MSG_CFM_SRC_SPEEDY_LEN, &nodeSpeed); L2_DEASSEMBLE(msg, L2_MSG_CFM_SRC_SPEEDY, &nodeSpeed);
node->nodeInfo.speed.y = (double)nodePos; node->nodeInfo.speed.y = (double)nodePos;
L2_FrameGetChunk(msg, L2_MSG_CFM_SRC_SPEEDZ, L2_MSG_CFM_SRC_SPEEDZ_LEN, &nodeSpeed); L2_DEASSEMBLE(msg, L2_MSG_CFM_SRC_SPEEDZ, &nodeSpeed);
node->nodeInfo.speed.z = (double)nodePos; node->nodeInfo.speed.z = (double)nodePos;
// Reset node ttl // Reset node ttl
@@ -577,8 +551,8 @@ int32_t L2_Scan_PktHandler(L2_INST *instPtr, uint8_t *msg)
// Calculate time deviation // Calculate time deviation
uint32_t frameNum, slotNum = 0; uint32_t frameNum, slotNum = 0;
L2_FrameGetChunk(msg, L2_MSG_FRAME_NUM, L2_MSG_FRAME_NUM_LEN, &frameNum); L2_DEASSEMBLE(msg, L2_MSG_FRAME_NUM, &frameNum);
L2_FrameGetChunk(msg, L2_MSG_SLOT_NUM, L2_MSG_SLOT_NUM_LEN, &slotNum); L2_DEASSEMBLE(msg, L2_MSG_SLOT_NUM, &slotNum);
Status = L2_GetTimeDeviation(instPtr, frameNum, slotNum, true, &(instPtr->log.timeDev)); Status = L2_GetTimeDeviation(instPtr, frameNum, slotNum, true, &(instPtr->log.timeDev));
if (Status != SUCCESS) if (Status != SUCCESS)
{ {
@@ -625,24 +599,6 @@ int32_t L2_Scan_PktHandler(L2_INST *instPtr, uint8_t *msg)
(void)AssertL2Event(instPtr, &l2Event); (void)AssertL2Event(instPtr, &l2Event);
} }
} }
// Get data payload
uint32_t dataId;
L2_FrameGetChunk(msg, L2_MSG_CFM_PAYLOAD_ID, L2_MSG_CFM_PAYLOAD_ID_LEN, &dataId);
if (L2_GetNodeType(instPtr) == L2_NODE_HEAD)
{
SysMonitor_UpdateRecvPayload(msg + L2_MSG_CFM_PAYLOAD, dataId, PAYLOAD_LEN_FLJ_RX);
}
else
{
SysMonitor_UpdateRecvPayload(msg + L2_MSG_CFM_PAYLOAD, dataId, PAYLOAD_LEN_LJ_RX);
}
// Logging...
memcpy(instPtr->log.rxLog.data, msg, L2_CMF_PACK_LEN);
instPtr->log.rxLog.dataId = dataId;
Status = SUCCESS; Status = SUCCESS;
break; break;
} }
+221 -207
View File
@@ -28,51 +28,69 @@
#include "error.h" #include "error.h"
#include "common.h" #include "common.h"
#include "circ_queue.h" #include "circ_queue.h"
#ifndef EMULATION
#include "../config/app_config.h"
#endif
/************************** Constant Definitions *****************************/ /************************** Constant Definitions *****************************/
#define SERVICE_MAX 1024
#define PAYLOAD_LEN_2K (128/8) //Byte
#define PAYLOAD_LEN_128K (1280/8) //Byte
#define PAYLOAD_LEN_256K (2560/8) //Byte
#define PACKET_TYPE_NONE 0
#define PACKET_TYPE_SINGLE 1
#define PACKET_TYPE_SUBPKT 2
#define PACKET_TYPE_LASTPKT 3
/***************** Macros (Inline Functions) Definitions *********************/ /***************** Macros (Inline Functions) Definitions *********************/
/**************************** Type Definitions *******************************/ /**************************** Type Definitions *******************************/
/************************** Function Prototypes ******************************/ /************************** Function Prototypes ******************************/
static int32_t Service_Packing(L2_INST *instPtr, L2_FRAME_TYPE type, uint8_t dstId); static int32_t Service_Packing(L2_INST *instPtr, L2_FRAME_TYPE type, uint8_t dstId);
static inline bool prepareCurrRx(L2_INST *instPtr);
static inline void resetCurrRx(L2_INST *instPtr);
static inline bool uploadCurrRx(L2_INST *instPtr);
static inline bool updateCurrTx(L2_INST *instPtr);
/************************** Variable Definitions *****************************/ /************************** Variable Definitions *****************************/
static inline bool prepareCurrRx(L2_INST *instPtr) {
ASSERT(instPtr != NULL);
if(instPtr->serviceFSM->currRxBuff != NULL) {
return true;
}
instPtr->serviceFSM->currRxBuff = RingBuff_Create(SERVICE_MAX);
if(instPtr->serviceFSM->currRxBuff == NULL)
{
DBG_ERROR("Not enough space to initialize serviceFSM->currRxBuff ring buffer...\n");
return false;
}
return true;
}
static uint8_t testData[L2_PACK_LEN_MAX] = static inline void resetCurrRx(L2_INST *instPtr) {
{ ASSERT(instPtr != NULL);
0x39, 0x85, 0x02, 0xF0, 0xC7, 0x6A, 0xE8, 0xB4, 0xE7, 0xAB, 0xC9, 0xDC, 0x0B, 0x41, 0x42, 0xE0, ASSERT(instPtr->serviceFSM->currRxBuff != NULL);
0xED, 0x21, 0x07, 0x62, 0x4E, 0x80, 0xA0, 0xE1, 0xAC, 0x77, 0x9B, 0x1F, 0x48, 0x0B, 0x58, 0xB9, RingBuff_Flush(instPtr->serviceFSM->currRxBuff);
0x45, 0xA5, 0x24, 0xEF, 0xF3, 0x71, 0x2E, 0x84, 0x6C, 0x22, 0xB3, 0x05, 0xEB, 0x75, 0xF2, 0x0B, instPtr->serviceFSM->currRxSeq = 0;
0x45, 0x73, 0x01, 0xA8, 0x1E, 0x00, 0x21, 0x3E, 0x03, 0x86, 0x55, 0x59, 0x98, 0x5C, 0x61, 0xA2, }
0xE8, 0x20, 0x0E, 0x7A, 0xD5, 0x72, 0xAF, 0xF4, 0xBC, 0xB3, 0x6F, 0xFE, 0xB3, 0x78, 0x6A, 0x59,
0x73, 0xBD, 0x97, 0xBE, 0x44, 0xA4, 0x9B, 0x71, 0x11, 0x45, 0x37, 0xFE, 0xB3, 0x71, 0xEF, 0x1E, static inline bool uploadCurrRx(L2_INST *instPtr) {
0x3A, 0x2B, 0x58, 0x07, 0xF6, 0x01, 0x1C, 0x73, 0x28, 0x11, 0xA8, 0x15, 0xA2, 0x58, 0x32, 0x2E, ASSERT(instPtr != NULL);
0x7D, 0x35, 0x9C, 0xE4, 0x98, 0x7F, 0x9C, 0x81, 0x32, 0xAA, 0xC4, 0x87, 0x16, 0x26, 0x23, 0x95, ASSERT(instPtr->config.pushUpHandle != NULL);
0x57, 0xC9, 0xD4, 0x34, 0xCE, 0x63, 0x78, 0x7E, 0xD4, 0x3C, 0x16, 0x1D, 0x80, 0xC0, 0x55, 0xBF, bool ret = instPtr->config.pushUpHandle(instPtr->serviceFSM->currRxBuff);
0xB5, 0xD6, 0x0C, 0xA5, 0xB9, 0x0A, 0x14, 0x5B, 0x4D, 0x52, 0xF2, 0xA9, 0x7A, 0x08, 0x67, 0x8E, instPtr->serviceFSM->currRxBuff = NULL;
0xEB, 0x67, 0x34, 0x7F, 0x7A, 0x35, 0xAF, 0xD9, 0x07, 0x52, 0x30, 0x38, 0x70, 0xC9, 0x41, 0xF8, instPtr->serviceFSM->currRxSeq = 0;
0x36, 0x61, 0x32, 0x72, 0xA4, 0x7A, 0xEA, 0x21, 0xB4, 0xBF, 0xAA, 0xCF, 0x93, 0x4F, 0xE1, 0x5C, return ret;
0xA0, 0xFB, 0xD0, 0x2B, 0xA3, 0x82, 0x2E, 0x69, 0x7D, 0xB7, 0x76, 0x88, 0xF7, 0x5C, 0xF3, 0x82, }
0xC6, 0x6D, 0x49, 0x92, 0x64, 0x88, 0x9A, 0x43, 0xEE, 0xE9, 0x93, 0xC3, 0x70, 0x50, 0x22, 0xF1,
0xD3, 0x2B, 0xCF, 0xA9, 0xE5, 0x69, 0x22, 0xF9, 0xBF, 0x78, 0x9A, 0xA4, 0x5A, 0x3D, 0x2E, 0x2A, static inline bool updateCurrTx(L2_INST *instPtr) {
0x23, 0xE3, 0x51, 0x8F, 0x1A, 0xC1, 0xAF, 0x47, 0x9C, 0x14, 0xCE, 0xB9, 0xCD, 0xD0, 0x02, 0xB7, ASSERT(instPtr != NULL);
0xB8, 0x81, 0xCC, 0x44, 0xE7, 0xA2, 0x6F, 0x32, 0x8C, 0x78, 0x79, 0x10, 0xF3, 0xE1, 0xB0, 0x7C, ASSERT(instPtr->config.popUpHandle != NULL);
0xAB, 0x40, 0xDB, 0xF9, 0x99, 0xE7, 0x27, 0x30, 0x53, 0x67, 0x00, 0xE8, 0x33, 0x6D, 0xFC, 0x4D, if(instPtr->serviceFSM->currTxBuff == NULL) {
0xDC, 0xB0, 0xFC, 0x3D, 0xEF, 0x8D, 0x43, 0xAF, 0x7E, 0x41, 0x69, 0xDA, 0xFD, 0xDF, 0x2F, 0xF8, instPtr->serviceFSM->currTxSeq = 0;
0xEC, 0xFB, 0x6A, 0x65, 0xE7, 0xEC, 0xC7, 0x53, 0x1B, 0x14, 0xDF, 0xBD, 0x0C, 0x54, 0x57, 0xD2, return (instPtr->config.popUpHandle(&(instPtr->serviceFSM->currTxBuff)));
0x56, 0x15, 0xF4, 0x34, 0xE2, 0xFB, 0x12, 0xA0, 0xA2, 0xDE, 0x82, 0xF5, 0x04, 0x81, 0x9B, 0x08, }
0xB6, 0x8C, 0x7B, 0xE0, 0xAA, 0xDF, 0xC9, 0x92, 0x9D, 0x5F, 0x2D, 0xF7, 0x4A, 0x0B, 0xFF, 0xA5, if(RingBuff_Size(instPtr->serviceFSM->currTxBuff) == 0) {
0xAA, 0xDC, 0xD6, 0x3F, 0x56, 0xB2, 0x6A, 0x3C, 0x6F, 0xAA, 0xAC, 0x84, 0xAC, 0x3F, 0x3D, 0x05, free(instPtr->serviceFSM->currTxBuff);
0x96, 0x12, 0x44, 0x39, 0x1C, 0xD1, 0xFA, 0xBE, 0x6B, 0x1A, 0xCD, 0x31, 0x29, 0x41, 0x31, 0xA3, instPtr->serviceFSM->currTxSeq = 0;
0xA8, 0x0D, 0x87, 0xEB, 0x96, 0x21, 0x39, 0xD6, 0x3B, 0x11, 0x50, 0xB5, 0xFE, 0x44, 0x0E, 0x74, return (instPtr->config.popUpHandle(&(instPtr->serviceFSM->currTxBuff)));
0x31, 0x12, 0xA1, 0x66, 0x49, 0xFD, 0x2D, 0x75, 0x72, 0xF9, 0xC8, 0xD9, 0x6C, 0xC9, 0x11, 0x74, }
0x2E, 0xEB, 0x20, 0x33, 0x3D, 0x2C, 0x5E, 0xEA, 0x39, 0x31, 0x88, 0xC7, 0xD1, 0x93, 0x95, 0xD8, return true;
0x9E, 0x87, 0x93, 0xBC, 0x09, 0x17, 0xC9, 0xA2, 0x59, 0x18, 0x51, 0x8F, 0xBF, 0x55, 0x45, 0x81, }
0x8D, 0xFD, 0xAF, 0xB2, 0x21, 0xB7, 0xD8, 0xA8, 0x00, 0x2E, 0x70, 0x73, 0x2F, 0x74, 0xBC, 0x61,
0x0A, 0x8E, 0xE3, 0x0A, 0x92, 0x82, 0xD2, 0x82, 0xBA, 0xE4, 0x3E, 0x8E, 0xBB, 0xC7, 0xA2, 0x8F,
0x68, 0xE1, 0x29, 0x34, 0x7C, 0xB4, 0x22, 0xCF, 0x36, 0x8F, 0x9D, 0x63, 0x9D, 0x04, 0x8F, 0x4A,
0xFB, 0x84, 0xBB, 0x6B, 0x97, 0x2C, 0x15, 0xC9, 0x37, 0x4F, 0x40, 0xD7, 0x47, 0x50, 0x39, 0x97
};
/*****************************************************************************/ /*****************************************************************************/
/** /**
@@ -88,76 +106,83 @@ static uint8_t testData[L2_PACK_LEN_MAX] =
******************************************************************************/ ******************************************************************************/
static int32_t Service_Packing(L2_INST *instPtr, L2_FRAME_TYPE type, uint8_t dstId) static int32_t Service_Packing(L2_INST *instPtr, L2_FRAME_TYPE type, uint8_t dstId)
{ {
#ifndef DATALINK_ENABLE_BERTEST
ASSERT(instPtr != NULL); ASSERT(instPtr != NULL);
int32_t Status; int32_t Status;
uint32_t dataChunk; uint8_t *sendBuff = instPtr->sendPktData;
uint8_t *buff = instPtr->sendPktData; size_t payloadMax, packetLen;
// Common section of link layer package
dataChunk = L2_GetNextFrameNum(instPtr);
L2_FrameInsertChunk(buff, L2_MSG_FRAME_NUM, L2_MSG_FRAME_NUM_LEN, &dataChunk);
dataChunk = L2_GetNextSlotNum(instPtr);
L2_FrameInsertChunk(buff, L2_MSG_SLOT_NUM, L2_MSG_SLOT_NUM_LEN, &dataChunk);
dataChunk = L2_GetNodeId(instPtr);
L2_FrameInsertChunk(buff, L2_MSG_SRC_ID, L2_MSG_SRC_ID_LEN, &dataChunk);
dataChunk = dstId;
L2_FrameInsertChunk(buff, L2_MSG_DST_ID, L2_MSG_DST_ID_LEN, &dataChunk);
switch (type) switch (type)
{ {
case L2_SVC_FRAME: case L2_SVC_2K_FRAME:
{ packetLen = L2_SVC_PACK_2K_LEN;
dataChunk = L2_SVC_FRAME; payloadMax = PAYLOAD_LEN_2K;
L2_FrameInsertChunk(buff, L2_MSG_TYPE, L2_MSG_TYPE_LEN, &dataChunk); break;
case L2_SVC_128K_FRAME:
SysMonitor_GetSysinfo(&(instPtr->sysInfo)); packetLen = L2_SVC_PACK_128K_LEN;
// insert position and speed info payloadMax = PAYLOAD_LEN_128K;
L2_FrameInsertChunk(buff, L2_MSG_SVC_SRC_POSX, L2_MSG_SVC_SRC_POSX_LEN, &(instPtr->sysInfo.posX)); break;
L2_FrameInsertChunk(buff, L2_MSG_SVC_SRC_POSY, L2_MSG_SVC_SRC_POSY_LEN, &(instPtr->sysInfo.posY)); case L2_SVC_256K_FRAME:
L2_FrameInsertChunk(buff, L2_MSG_SVC_SRC_POSZ, L2_MSG_SVC_SRC_POSZ_LEN, &(instPtr->sysInfo.posZ)); packetLen = L2_SVC_PACK_256K_LEN;
L2_FrameInsertChunk(buff, L2_MSG_SVC_SRC_SPEEDX, L2_MSG_SVC_SRC_SPEEDX_LEN, &(instPtr->sysInfo.vX)); payloadMax = PAYLOAD_LEN_256K;
L2_FrameInsertChunk(buff, L2_MSG_SVC_SRC_SPEEDY, L2_MSG_SVC_SRC_SPEEDY_LEN, &(instPtr->sysInfo.vY));
L2_FrameInsertChunk(buff, L2_MSG_SVC_SRC_SPEEDZ, L2_MSG_SVC_SRC_SPEEDZ_LEN, &(instPtr->sysInfo.vZ));
uint32_t dataId;
if (L2_GetNodeType(instPtr) == L2_NODE_HEAD)
{
SysMonitor_GetSendPayload(buff + L2_MSG_SVC_PAYLOAD, &dataId, PAYLOAD_LEN_FLJ_TX);
}
else
{
SysMonitor_GetSendPayload(buff + L2_MSG_SVC_PAYLOAD, &dataId, PAYLOAD_LEN_LJ_TX);
}
L2_FrameInsertChunk(buff, L2_MSG_SVC_PAYLOAD_ID, L2_MSG_SVC_PAYLOAD_ID_LEN, &dataId);
if (dataId == DATA_ID_NONE)
{
L2_FrameInsertChunk(buff, L2_MSG_SVC_PAYLOAD, L2_MSG_SVC_PAYLOAD_LEN, testData);
}
Status = L2_CrcAppend(buff, L2_SVC_PACK_LEN - L2_MSG_SVC_CRC_LEN, L2_MSG_SVC_CRC, L2_CRC16_1021);
if (Status != SUCCESS)
{
DBG_ERROR("Fail to append CRC...\n");
return Status;
}
memcpy(instPtr->log.txLog.data, buff, L2_SVC_PACK_LEN);
instPtr->log.txLog.dataId = dataId;
break; break;
}
default: default:
{
DBG_ERROR("Unexpected frame type: %" PRIu8 ".\n", type); DBG_ERROR("Unexpected frame type: %" PRIu8 ".\n", type);
return EPARAM; return EPARAM;
break; break;
} }
// Common section of link layer package
L2_ASSEMBLE_INTEGER(sendBuff, L2_MSG_FRAME_NUM, L2_GetNextFrameNum(instPtr));
L2_ASSEMBLE_INTEGER(sendBuff, L2_MSG_SLOT_NUM, L2_GetNextSlotNum(instPtr));
L2_ASSEMBLE_INTEGER(sendBuff, L2_MSG_SRC_ID, L2_GetNodeId(instPtr));
L2_ASSEMBLE_INTEGER(sendBuff, L2_MSG_DST_ID, dstId);
L2_ASSEMBLE_INTEGER(sendBuff, L2_MSG_TYPE, type);
// TODO: check
// If no data need to be sent, send dummy data
if(updateCurrTx(instPtr) == false) {
L2_ASSEMBLE_INTEGER(sendBuff, L2_MSG_SVC_PKTFLG, PACKET_TYPE_NONE);
Status = L2_CrcAppend(sendBuff, packetLen - L2_MSG_SVC_CRC_LEN, L2_MSG_SVC_PAYLOAD + payloadMax, L2_CRC16_1021);
if (Status != SUCCESS)
{
DBG_ERROR("Fail to append CRC, error code: %" PRId32 ".\n", Status);
ASSERT(true);
} }
return EIGNORE;
}
RING_BUFFER *svcData = instPtr->serviceFSM->currTxBuff;
size_t sentLen = RingBuff_Pop(svcData, sendBuff + L2_MSG_SVC_PAYLOAD, packetLen);
L2_ASSEMBLE_INTEGER(sendBuff, L2_MSG_SVC_DLEN, sentLen);
// Packet type
uint32_t pktType = PACKET_TYPE_NONE;
if(RingBuff_Size(svcData) == 0)
{
if(instPtr->serviceFSM->currTxSeq == 0)
{
pktType = PACKET_TYPE_SINGLE;
}
else
{
pktType = PACKET_TYPE_LASTPKT;
}
}
else
{
pktType = PACKET_TYPE_SUBPKT;
}
L2_ASSEMBLE_INTEGER(sendBuff, L2_MSG_SVC_PKTFLG, pktType);
L2_ASSEMBLE_INTEGER(sendBuff, L2_MSG_SVC_PKTID, instPtr->serviceFSM->currTxSeq);
Status = L2_CrcAppend(sendBuff, packetLen - L2_MSG_SVC_CRC_LEN, L2_MSG_SVC_PAYLOAD + payloadMax, L2_CRC16_1021);
if (Status != SUCCESS)
{
DBG_ERROR("Fail to append CRC, error code: %" PRId32 ".\n", Status);
ASSERT(true);
}
instPtr->serviceFSM->currTxSeq++;
memcpy(instPtr->log.txLog.data, sendBuff, packetLen);
instPtr->log.txLog.dataId = instPtr->serviceFSM->rxdCnt;
return SUCCESS; return SUCCESS;
#else
DBG_ERROR("Unexpected call of Service_Packing in BER test mode.\n");
return EUNEXP;
#endif
} }
/*****************************************************************************/ /*****************************************************************************/
@@ -175,15 +200,32 @@ int32_t L2_Service_PktHandler(L2_INST *instPtr, uint8_t *msg)
ASSERT(instPtr != NULL); ASSERT(instPtr != NULL);
ASSERT(msg != NULL); ASSERT(msg != NULL);
int32_t Status; int32_t Status;
#ifndef DATALINK_ENABLE_BERTEST
L2_FRAME_TYPE frameType = L2_NONE_FRAME; L2_FRAME_TYPE frameType = L2_NONE_FRAME;
L2_FrameGetChunk(msg, L2_MSG_TYPE, L2_MSG_TYPE_LEN, &frameType); L2_FrameGetChunk(msg, L2_MSG_TYPE, L2_MSG_TYPE_LEN, &frameType);
size_t packetLen;
switch (frameType) switch (frameType)
{ {
case L2_SVC_FRAME: case L2_SVC_2K_FRAME:
{ packetLen = L2_SVC_PACK_2K_LEN;
break;
case L2_SVC_128K_FRAME:
packetLen = L2_SVC_PACK_128K_LEN;
break;
case L2_SVC_256K_FRAME:
packetLen = L2_SVC_PACK_256K_LEN;
break;
default:
DBG_ERROR("Unexpected frame type: %" PRIu8 ".\n", type);
return EPARAM;
break;
}
uint8_t nodeId; uint8_t nodeId;
L2_FrameGetChunk(msg, L2_MSG_SRC_ID, L2_MSG_SRC_ID_LEN, &nodeId); L2_DEASSEMBLE(msg, L2_MSG_DST_ID, &nodeId);
if(nodeId != L2_GetNodeId(instPtr)) {
DBG_ERROR("Packet not addressed to me, dropping...\n");
return EIGNORE;
}
NODE_ENTRY *node; NODE_ENTRY *node;
node = L2_GetNodeById(instPtr->nodeList, nodeId); node = L2_GetNodeById(instPtr->nodeList, nodeId);
if (node == NULL) if (node == NULL)
@@ -192,101 +234,75 @@ int32_t L2_Service_PktHandler(L2_INST *instPtr, uint8_t *msg)
if (node == NULL) if (node == NULL)
{ {
DBG_ERROR("Failed to append new node [id: %" PRIu8 "]", nodeId); DBG_ERROR("Failed to append new node [id: %" PRIu8 "]", nodeId);
Status = ENOMEM; ASSERT(true);
break;
} }
} }
// Update node info.
float nodePos;
L2_FrameGetChunk(msg, L2_MSG_SVC_SRC_POSX, L2_MSG_SVC_SRC_POSX_LEN, &nodePos);
node->nodeInfo.pos.x = (double)nodePos;
L2_FrameGetChunk(msg, L2_MSG_SVC_SRC_POSY, L2_MSG_SVC_SRC_POSY_LEN, &nodePos);
node->nodeInfo.pos.y = (double)nodePos;
L2_FrameGetChunk(msg, L2_MSG_SVC_SRC_POSZ, L2_MSG_SVC_SRC_POSZ_LEN, &nodePos);
node->nodeInfo.pos.z = (double)nodePos;
float nodeSpeed;
L2_FrameGetChunk(msg, L2_MSG_SVC_SRC_SPEEDX, L2_MSG_SVC_SRC_SPEEDX_LEN, &nodeSpeed);
node->nodeInfo.speed.x = (double)nodePos;
L2_FrameGetChunk(msg, L2_MSG_SVC_SRC_SPEEDY, L2_MSG_SVC_SRC_SPEEDY_LEN, &nodeSpeed);
node->nodeInfo.speed.y = (double)nodePos;
L2_FrameGetChunk(msg, L2_MSG_SVC_SRC_SPEEDZ, L2_MSG_SVC_SRC_SPEEDZ_LEN, &nodeSpeed);
node->nodeInfo.speed.z = (double)nodePos;
// Reset node ttl // Reset node ttl
node->ttlCnt = 0; node->ttlCnt = 0;
// Calculate time deviation // Calculate time deviation
uint32_t frameNum, slotNum = 0; uint32_t frameNum = 0;
L2_FrameGetChunk(msg, L2_MSG_FRAME_NUM, L2_MSG_FRAME_NUM_LEN, &frameNum); uint32_t slotNum = 0;
L2_FrameGetChunk(msg, L2_MSG_SLOT_NUM, L2_MSG_SLOT_NUM_LEN, &slotNum); int64_t timeDev = 0;
Status = L2_GetTimeDeviation(instPtr, frameNum, slotNum, true, &(instPtr->log.timeDev)); L2_DEASSEMBLE(msg, L2_MSG_FRAME_NUM, &frameNum);
L2_DEASSEMBLE(msg, L2_MSG_SLOT_NUM, &slotNum);
Status = L2_GetTimeDeviation(instPtr, frameNum, slotNum, true, &timeDev);
if (Status != SUCCESS) if (Status != SUCCESS)
{ {
DBG_ERROR("Failed to compute time deviation.\n") DBG_ERROR("Failed to compute time deviation.\n")
break; ASSERT(true);
} }
instPtr->log.timeDev = timeDev;
uint32_t dataId;
L2_FrameGetChunk(msg, L2_MSG_SVC_PAYLOAD_ID, L2_MSG_SVC_PAYLOAD_ID_LEN, &dataId);
if (L2_GetNodeType(instPtr) == L2_NODE_HEAD)
{
SysMonitor_UpdateRecvPayload(msg + L2_MSG_SVC_PAYLOAD, dataId, PAYLOAD_LEN_FLJ_RX);
}
else
{
SysMonitor_UpdateRecvPayload(msg + L2_MSG_SVC_PAYLOAD, dataId, PAYLOAD_LEN_LJ_RX);
}
// Logging
memcpy(instPtr->log.rxLog.data, msg, L2_SVC_PACK_LEN);
instPtr->log.rxLog.dataId = dataId;
instPtr->serviceFSM->rxdCnt++;
#ifdef DATALINK_ENABLE_AUTOTIMESYNC
// Implement a auto time sync. // Implement a auto time sync.
if (L2_GetNodeType(instPtr) != L2_NODE_HEAD) if (L2_GetNodeType(instPtr) != L2_NODE_HEAD)
{ {
// Time sync. L2_TimeAdjust(instPtr, &timeDev);
L2_TimeAdjust(instPtr, &(instPtr->log.timeDev));
}
#endif
break;
}
default:
DBG_ERROR("Unsupported frame type: %" PRIu8 ".\n", frameType);
break;
}
return Status;
#else
uint32_t errorBits = 0;
for (int i = 0; i < L2_SVC_PACK_LEN; i++)
{
errorBits += count_ones(msg[i] ^ testData[i]);
} }
instPtr->serviceFSM->bitError += errorBits; // TODO: check
instPtr->serviceFSM->bitTotal += L2_SVC_PACK_LEN * 8; uint8_t pktType, pktId;
L2_DEASSEMBLE(msg, L2_MSG_SVC_PKTFLG, &pktType);
L2_DEASSEMBLE(msg, L2_MSG_SVC_PKTID, &pktId);
// Calculate time deviation if(pktType != PACKET_TYPE_SINGLE && pktType != PACKET_TYPE_SUBPKT && pktType != PACKET_TYPE_LASTPKT)
uint32_t frameNum, slotNum = 0;
L2_FrameGetChunk(msg, L2_MSG_FRAME_NUM, L2_MSG_FRAME_NUM_LEN, &frameNum);
L2_FrameGetChunk(msg, L2_MSG_SLOT_NUM, L2_MSG_SLOT_NUM_LEN, &slotNum);
Status = L2_GetTimeDeviation(instPtr, frameNum, slotNum, true, &(instPtr->log.timeDev));
if (Status != SUCCESS)
{ {
DBG_ERROR("Failed to compute time deviation.\n") DBG_INFO("Dummy packet, discard...\n");
return Status;
}
// Implement a auto time sync.
if (L2_GetNodeType(instPtr) != L2_NODE_HEAD)
{
// Time sync.
L2_TimeAdjust(instPtr, &(instPtr->log.timeDev));
}
return SUCCESS; return SUCCESS;
#endif }
if(prepareCurrRx(instPtr) == false) {
DBG_ERROR("Failed to prepare prepareCurrRx.\n");
return ENOMEM;
}
if(pktId != instPtr->serviceFSM->currRxSeq)
{
DBG_ERROR("Packet loss occurred discard all...\n");
resetCurrRx(instPtr);
return FAILURE;
}
size_t pushLen, dlen = 0;
RING_BUFFER *svcData = instPtr->serviceFSM->currRxBuff;
L2_DEASSEMBLE(msg, L2_MSG_SVC_DLEN, &dlen);
pushLen = RingBuff_Push(svcData, msg + L2_MSG_SVC_PAYLOAD, dlen);
if(pushLen < dlen) {
DBG_ERROR("Receiving ring buffer overflowed.\n")
ASSERT(true);
}
instPtr->serviceFSM->currRxSeq++;
if(pktType == PACKET_TYPE_SINGLE || pktType == PACKET_TYPE_LASTPKT)
{
uploadCurrRx(instPtr);
}
instPtr->serviceFSM->rxdCnt++;
memcpy(instPtr->log.rxLog.data, msg, packetLen);
instPtr->log.rxLog.dataId = instPtr->serviceFSM->rxdCnt;
return Status;
} }
/*****************************************************************************/ /*****************************************************************************/
@@ -326,12 +342,10 @@ void L2_Service_Reset(L2_SVC_FSM *svcFSMPtr)
svcFSMPtr->txCnt = 0; svcFSMPtr->txCnt = 0;
svcFSMPtr->rxCnt = 0; svcFSMPtr->rxCnt = 0;
svcFSMPtr->rxdCnt = 0; svcFSMPtr->rxdCnt = 0;
#ifdef DATALINK_ENABLE_BERTEST svcFSMPtr->currTxSeq = 0;
svcFSMPtr->bitTotal = 0; svcFSMPtr->currRxSeq = 0;
svcFSMPtr->bitError = 0; svcFSMPtr->currTxBuff = NULL;
svcFSMPtr->lossRate = 0; svcFSMPtr->currRxBuff = NULL;
svcFSMPtr->errorRate = 0;
#endif
} }
/*****************************************************************************/ /*****************************************************************************/
@@ -399,38 +413,38 @@ int32_t L2_Service_Routine(L2_INST *instPtr, const L2_RTNE_TABLE_ENTRY *rtneEntr
Phy_SetBeamWidth(phyRef, PHY_ANT_BEAM_120); Phy_SetBeamWidth(phyRef, PHY_ANT_BEAM_120);
instPtr->log.lastBeamWidth = PHY_ANT_BEAM_120; instPtr->log.lastBeamWidth = PHY_ANT_BEAM_120;
} }
L2_FRAME_TYPE frameType = L2_NONE_FRAME;
switch (rtneEntry->slotType) switch (rtneEntry->slotType)
{ {
case L2_SLOT_SERVICE: case L2_SLOT_SERVICE_2K:
if (torState == L2_TOR_TX) frameType = L2_SVC_2K_FRAME;
{ break;
svcFSMPtr->txCnt++; case L2_SLOT_SERVICE_128K:
#ifndef DATALINK_ENABLE_BERTEST frameType = L2_SVC_128K_FRAME;
// Packing service data break;
Service_Packing(instPtr, L2_SVC_FRAME, rtneEntry->dst); case L2_SLOT_SERVICE_256K:
#else frameType = L2_SVC_256K_FRAME;
memcpy(instPtr->sendPktData, testData, L2_SVC_PACK_LEN);
#endif
}
else
{
svcFSMPtr->rxCnt++;
}
L2_SetupNextSlot(instPtr, torState, L2_SVC_FRAME);
break; break;
default: default:
DBG_ERROR("UNKNOWN slot type [%" PRIu8 "].\n", rtneEntry->slotType); DBG_ERROR("UNKNOWN slot type [%" PRIu8 "].\n", rtneEntry->slotType);
return FAILURE; return FAILURE;
} }
#ifdef DATALINK_ENABLE_BERTEST if (torState == L2_TOR_TX)
uint32_t pktLoss; {
pktLoss = svcFSMPtr->rxCnt - svcFSMPtr->rxdCnt; if(Service_Packing(instPtr, frameType, rtneEntry->dst) == SUCCESS)
svcFSMPtr->lossRate = (svcFSMPtr->rxCnt == 0) ? 0 : (double)pktLoss / (double)svcFSMPtr->rxCnt; {
svcFSMPtr->errorRate = (svcFSMPtr->bitTotal == 0) ? 0 : (double)svcFSMPtr->bitError / (double)svcFSMPtr->bitTotal; svcFSMPtr->txCnt++;
DBG_PRINT("Packet Loss Rate -- Total: %lu, Loss: %lu.\n", instPtr->log.svcRxCnt, pktLoss); }
DBG_PRINT("Bit Error Rate -- Total:%lu, Error:%lu.\n", svcFSMPtr->bitTotal, svcFSMPtr->bitError); else
#endif {
torState = L2_TOR_SUSPEND;
}
}
else
{
svcFSMPtr->rxCnt++;
}
L2_SetupNextSlot(instPtr, torState, frameType);
return SUCCESS; return SUCCESS;
} }
+1 -1
View File
@@ -23,7 +23,7 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include "link_layer.h" #include "link_layer.h"
#include "../phy_layer/phy_layer.h" #include "networking/phy_layer/phy_layer.h"
#include "error.h" #include "error.h"
#include "common.h" #include "common.h"
+2 -3
View File
@@ -25,10 +25,9 @@
#ifndef EMULATION #ifndef EMULATION
#include "xbram.h" #include "xbram.h"
#include "xadcps.h" #include "xadcps.h"
#include "../config/app_config.h"
#endif #endif
#include "../../system_monitor.h" #include "system_monitor.h"
#include "../../time_ctrl/time_ctrl.h" #include "time_ctrl/time_ctrl.h"
/************************** Constant Definitions *****************************/ /************************** Constant Definitions *****************************/
/** /**
* @name PhysicalLayer_Common_Constant * @name PhysicalLayer_Common_Constant
+37 -18
View File
@@ -29,18 +29,20 @@
#include "error.h" #include "error.h"
#include "timer.h" #include "timer.h"
#include "system_monitor.h" #include "system_monitor.h"
#include "config/app_config.h"
#include "dev_profile/dev_profile.h"
#include "systembus/systembus.h" #include "systembus/systembus.h"
#include "networking/phy_layer/phy_layer.h" #include "networking/phy_layer/phy_layer.h"
#include "networking/link_layer/link_layer.h" #include "networking/link_layer/link_layer.h"
#include "node_config/app_config.h"
#include "node_config/dev_profile/dev_profile.h"
/************************** Function Prototypes ******************************/ /************************** Function Prototypes ******************************/
int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr); static int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr);
void Phy_IntrHandler(void *context); static void Phy_IntrHandler(void *context);
void PeriodicPull_Handler(void *callBackRef); static void PeriodicPull_Handler(void *callBackRef);
void ScuTimer_IntrHandler(void *context); static void ScuTimer_IntrHandler(void *context);
void Systembus_IntrHandler(void *context); static void Systembus_IntrHandler(void *context);
static bool LinklayerPush2Up(RING_BUFFER *buff);
static bool LinklayerPopFromUp(RING_BUFFER **buff);
/************************** Constant Definitions *****************************/ /************************** Constant Definitions *****************************/
struct callback_desc phy_callback_desc = { struct callback_desc phy_callback_desc = {
@@ -71,7 +73,9 @@ L2_CONFIG linkConfig = {
.headId = 1U, .headId = 1U,
.netScale = 2U, .netScale = 2U,
.phyInstPtr = NULL, // physical layer reference .phyInstPtr = NULL, // physical layer reference
.tmcInstPtr = NULL .tmcInstPtr = NULL,
.pushUpHandle = LinklayerPush2Up,
.popUpHandle = LinklayerPopFromUp
}; };
// L2_CONFIG linkConfig = { // L2_CONFIG linkConfig = {
@@ -81,7 +85,9 @@ L2_CONFIG linkConfig = {
// .headId = 1U, // .headId = 1U,
// .netScale = 2U, // .netScale = 2U,
// .phyInstPtr = NULL, // physical layer reference // .phyInstPtr = NULL, // physical layer reference
// .tmcInstPtr = NULL // .tmcInstPtr = NULL,
// .pushUpHandle = LinklayerPush2Up,
// .popUpHandle = LinklayerPopFromUp
// }; // };
static PHY_CONFIG phyConfig = { static PHY_CONFIG phyConfig = {
@@ -117,14 +123,19 @@ static SYSBUS_CONFIG sysbusConfig = {
.rxQueueMax = 16U .rxQueueMax = 16U
}; };
/*********************** Driver Instance Definitions **************************/ /*********************** Driver Instance Definitions **************************/
static struct irq_ctrl_desc *intcDescPtr = NULL; // General interrupt controller descriptor static struct irq_ctrl_desc *intcDescPtr = NULL;
static struct timer_desc *logTmPtr = NULL; static struct timer_desc *logTmPtr = NULL;
static SYSBUS *sysbusDescPtr = NULL; static SYSBUS *sysbusDescPtr = NULL;
static PHY_INST *phyInstPtr = NULL; static PHY_INST *phyInstPtr = NULL;
static TMC_INST *tmcInstPtr = NULL; static TMC_INST *tmcInstPtr = NULL;
L2_INST *linkInstPtr = NULL; L2_INST *linkInstPtr = NULL;
static bool LinklayerPush2Up(RING_BUFFER *buff){
return SystemBus_PushSvcFrame(sysbusDescPtr, (void*)buff);
}
static bool LinklayerPopFromUp(RING_BUFFER **buff) {
return SystemBus_PopSvcFrame(sysbusDescPtr, (void**)buff);
}
/****************************************************************************/ /****************************************************************************/
/** /**
* This function is responsible for initializing the SCUGIC instance, looking * This function is responsible for initializing the SCUGIC instance, looking
@@ -137,7 +148,7 @@ L2_INST *linkInstPtr = NULL;
* FAILURE if initialization failed. * FAILURE if initialization failed.
* *
*****************************************************************************/ *****************************************************************************/
int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr) static int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr)
{ {
int32_t Status; int32_t Status;
struct xil_irq_desc *xil_dev; struct xil_irq_desc *xil_dev;
@@ -218,8 +229,8 @@ int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr)
} }
// Enable interrupts // Enable interrupts
// irq_enable(descPtr, PHY_INTR_ID); irq_enable(descPtr, PHY_INTR_ID);
// irq_enable(descPtr, PERIODIC_5MS_INTR_ID); irq_enable(descPtr, PERIODIC_5MS_INTR_ID);
irq_enable(descPtr, SYSBUS_INTR_ID); irq_enable(descPtr, SYSBUS_INTR_ID);
irq_enable(descPtr, SCUTIMER_INTR_ID); irq_enable(descPtr, SCUTIMER_INTR_ID);
@@ -243,7 +254,7 @@ int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr)
* @return None. * @return None.
* *
*****************************************************************************/ *****************************************************************************/
void Phy_IntrHandler(void *context) static void Phy_IntrHandler(void *context)
{ {
Phy_UpdateState(phyInstPtr); Phy_UpdateState(phyInstPtr);
} // PhyIntr_Handler } // PhyIntr_Handler
@@ -258,7 +269,7 @@ void Phy_IntrHandler(void *context)
* @return None. * @return None.
* *
*****************************************************************************/ *****************************************************************************/
void PeriodicPull_Handler(void *callBackRef) static void PeriodicPull_Handler(void *callBackRef)
{ {
int32_t Status; int32_t Status;
Status = Linklayer_Proc(linkInstPtr); Status = Linklayer_Proc(linkInstPtr);
@@ -278,7 +289,7 @@ void PeriodicPull_Handler(void *callBackRef)
* @return None. * @return None.
* *
******************************************************************************/ ******************************************************************************/
void Systembus_IntrHandler(void *context) static void Systembus_IntrHandler(void *context)
{ {
int32_t Status; int32_t Status;
Status = SystemBus_IntrHandler(sysbusDescPtr); Status = SystemBus_IntrHandler(sysbusDescPtr);
@@ -297,7 +308,7 @@ void Systembus_IntrHandler(void *context)
* @return None. * @return None.
* *
******************************************************************************/ ******************************************************************************/
void ScuTimer_IntrHandler(void *context) static void ScuTimer_IntrHandler(void *context)
{ {
int32_t Status; int32_t Status;
struct xil_timer_desc *xdesc; struct xil_timer_desc *xdesc;
@@ -441,5 +452,13 @@ int main(void)
DBG_ERROR("SystemBus_HandleCmd exit with ErrorCode: %" PRId32 ".\n", Status); DBG_ERROR("SystemBus_HandleCmd exit with ErrorCode: %" PRId32 ".\n", Status);
} }
} }
if(SystemBus_IsSvcUpPending(sysbusDescPtr))
{
Status = SystemBus_UploadSvcData(sysbusDescPtr);
if (Status != SUCCESS)
{
DBG_ERROR("SystemBus_UploadSvcData exit with ErrorCode: %" PRId32 ".\n", Status);
}
}
} }
} // main } // main
@@ -36,9 +36,6 @@
// 1 - print only errors // 1 - print only errors
// other - print nothing // other - print nothing
#define DATALINK_ENABLE_AUTORECONNECT
#define DATALINK_ENABLE_AUTOTIMESYNC
// #define DATALINK_ENABLE_BERTEST
/************ Hardware Configs ************/ /************ Hardware Configs ************/
#define CPU_CLK_HZ XPAR_CPU_CORTEXA9_0_CPU_CLK_FREQ_HZ #define CPU_CLK_HZ XPAR_CPU_CORTEXA9_0_CPU_CLK_FREQ_HZ
@@ -54,7 +51,7 @@
// Physical Layer Configs // Physical Layer Configs
#define PHY_DEVICE_ID 0X00 #define PHY_DEVICE_ID 0X00
#define PHY_BASEADDR XPAR_PHYC_BASEADDR #define PHY_BASEADDR XPAR_PHYC_BASEADDR
#define PHY_BEAM_FORMING_ENABLE
// -- Antenna Bram Configs // -- Antenna Bram Configs
#define PHY_ANTCONFIG_BRAM_DEVICE_ID XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_DEVICE_ID #define PHY_ANTCONFIG_BRAM_DEVICE_ID XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_DEVICE_ID
#define PHY_ANTINFO_BRAM_DEVICE_ID XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_DEVICE_ID #define PHY_ANTINFO_BRAM_DEVICE_ID XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_DEVICE_ID
@@ -82,17 +79,4 @@
// INTC configis // INTC configis
#define INTC_DEVICE_ID XPAR_SCUGIC_0_DEVICE_ID #define INTC_DEVICE_ID XPAR_SCUGIC_0_DEVICE_ID
// Configuration Check
#if defined(PHY_BEAM_SET_PRESET) && !defined(PHY_BEAM_FORMING_ENABLE)
#define PHY_BEAM_FORMING_ENABLE
#warning To impliment beam scan must enable beam forming...
#endif
#if defined(DATALINK_ENABLE_BERTEST)
#if !defined(DATALINK_ENABLE_AUTOTIMESYNC)
#warning To enbale bit error rate test, auto time-sync should be enabled...
#endif
#endif
#endif //__APP_CONFIG_H_ #endif //__APP_CONFIG_H_
@@ -0,0 +1,11 @@
#include "dev_profile.h"
#include "global_timer.h"
#include "../app_config.h"
struct global_timer_init_param globaltimer_init_param = {
.base_addr = GLOBAL_TIMER_BASEADDR,
.id = GLOBAL_TIMER_DEVICE_ID,
.freq_hz = GLOBAL_TIMER_CLK_HZ,
.load_value = 0x0000000000000000
};
@@ -1,7 +1,7 @@
#include "dev_profile.h" #include "dev_profile.h"
#include "irq.h" #include "irq.h"
#include "../config/app_config.h" #include "drivers/platform/xilinx_irq.h"
#include "../drivers/platform/xilinx_irq.h" #include "../app_config.h"
struct xil_irq_init_param xil_intc_init_param = { struct xil_irq_init_param xil_intc_init_param = {
.type = IRQ_PS .type = IRQ_PS
@@ -1,7 +1,7 @@
#include "dev_profile.h" #include "dev_profile.h"
#include "timer.h" #include "timer.h"
#include "../config/app_config.h" #include "drivers/platform/xilinx_timer.h"
#include "../drivers/platform/xilinx_timer.h" #include "../app_config.h"
struct xil_timer_init_param xil_scutimer_init_param = { struct xil_timer_init_param xil_scutimer_init_param = {
.active_tmr = 0, .active_tmr = 0,
+3 -3
View File
@@ -120,11 +120,11 @@ typedef struct __attribute__((packed))
{ {
// SystemBus log // SystemBus log
uint16_t lastConfig; ///< Last valid config \n uint8_t lastConfig[2]; ///< Last valid config \n
// byte 0: 0x11 FLJ, 0x00 LJ \n // byte 0: 0x11 FLJ, 0x00 LJ \n
// byte 1: 0x66 Full Power, 0x88 Low Power // byte 1: 0x66 Full Power, 0x88 Low Power
uint32_t pollCnt; ///< number of poll commands uint32_t svcDownCnt; ///< number of service packet from upper layer
uint32_t svcCnt; ///< number of service commands uint32_t svcUpCnt; ///< number of service packet to upper layer
uint32_t remoteCnt; ///< number of remote check commands uint32_t remoteCnt; ///< number of remote check commands
} SYSBUSLOG; } SYSBUSLOG;
+181 -19
View File
@@ -25,13 +25,16 @@
#include "systembus_psuart.h" #include "systembus_psuart.h"
#include "error.h" #include "error.h"
#include "circ_queue.h" #include "circ_queue.h"
#include "../system_monitor.h" #include "ring_buffer.h"
#include "system_monitor.h"
/** /**
* @addtogroup SystemBus_Protocol_Routine * @addtogroup SystemBus_Protocol_Routine
* @{ * @{
*/ */
#define SYSBUS_SVC_MAX 1024
/************************** Function Prototypes ******************************/ /************************** Function Prototypes ******************************/
static int32_t SystemBus_StartListen(SYSBUS *instPtr); static int32_t SystemBus_StartListen(SYSBUS *instPtr);
static int32_t SystemBus_GenSelfTestRsp(SYSBUS *instPtr); static int32_t SystemBus_GenSelfTestRsp(SYSBUS *instPtr);
@@ -41,8 +44,8 @@ static int32_t SystemBus_ModeSwicth(SYSBUS *instPtr, uint16_t *msg);
/**************************** Type Definitions *******************************/ /**************************** Type Definitions *******************************/
/************************** Variable Definitions *****************************/ /************************** Variable Definitions *****************************/
// TODO: better approach? // TODO: better approach?
#include "../networking/link_layer/link_layer.h" #include "networking/link_layer/link_layer.h"
#include "../networking/phy_layer/phy_layer.h" #include "networking/phy_layer/phy_layer.h"
extern L2_INST *linkInstPtr; extern L2_INST *linkInstPtr;
extern L2_CONFIG linkConfig; extern L2_CONFIG linkConfig;
@@ -58,6 +61,30 @@ inline bool SystemBus_IsRsqPending(SYSBUS *instPtr)
return (!isCircQueueEmpty(instPtr->txQueue)); return (!isCircQueueEmpty(instPtr->txQueue));
} }
inline bool SystemBus_IsSvcUpPending(SYSBUS *instPtr)
{
ASSERT(instPtr != NULL);
return (!isCircQueueEmpty(instPtr->rxSvcQueue));
}
inline bool SystemBus_IsSvcDownPending(SYSBUS *instPtr)
{
ASSERT(instPtr != NULL);
return (!isCircQueueEmpty(instPtr->txSvcQueue));
}
inline bool SystemBus_PushSvcFrame(SYSBUS *instPtr, void* buff) {
ASSERT(instPtr != NULL);
ASSERT(buff != NULL);
return CircQueuePush(instPtr->rxSvcQueue, buff);
}
inline bool SystemBus_PopSvcFrame(SYSBUS *instPtr, void** buff) {
ASSERT(instPtr != NULL);
ASSERT(buff != NULL);
return CircQueuePop(instPtr->txSvcQueue, buff);
}
inline bool SystemBus_IsTxBusy(SYSBUS *instPtr) inline bool SystemBus_IsTxBusy(SYSBUS *instPtr)
{ {
ASSERT(instPtr != NULL); ASSERT(instPtr != NULL);
@@ -139,7 +166,7 @@ static int32_t SystemBus_BindingConfig(SYSBUS *instPtr, uint16_t *msg)
} }
uint16_t* rsp = (uint16_t*)sysbusRsp->data; uint16_t* rsp = (uint16_t*)sysbusRsp->data;
rsp[WD_CMD] = RSP_CONFIG; rsp[WD_CMD] = RSP_CONFIG;
rsp[WD_RSP_STATE] = RSP_STA_OK; // TODO: rsp[WD_RSP_STATE] = RSP_STA_OK;
sysbusRsp->len = RSP_CONFIG_LEN; sysbusRsp->len = RSP_CONFIG_LEN;
if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false) if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false)
{ {
@@ -161,18 +188,26 @@ static int32_t SystemBus_PowerUp(SYSBUS *instPtr, uint16_t *msg)
return EIGNORE; return EIGNORE;
} }
// TODO: configure speed, power mode
PHY_INST *phyRef = linkInstPtr->config.phyInstPtr; PHY_INST *phyRef = linkInstPtr->config.phyInstPtr;
TMC_INST *tmcRef = linkInstPtr->config.tmcInstPtr; TMC_INST *tmcRef = linkInstPtr->config.tmcInstPtr;
bool reconfig = false;
// TODO: speed configure.
switch (msg[WD_PWUP_BACKWARD]) {
case SPEED_NEW_2KBPS:
break;
case SPEED_NEW_128KBPS:
break;
case SPEED_NEW_256KBPS:
break;
default:
DBG_ERROR("Unsurpport speed mode 0x%04X.\n", msg[WD_PWUP_BACKWARD]);
return EPARAM;
}
if (msg[WD_PWUP_SATMODE] == PWUP_SATMODE_UP) { if (msg[WD_PWUP_SATMODE] == PWUP_SATMODE_UP) {
// full power config // TODO: confirm default power config power config
Phy_AntConfigMode(phyRef, PHY_ANT_MODE_POWER_FULL); Phy_AntConfigMode(phyRef, PHY_ANT_MODE_POWER_LOW);
if (reconfig || !L2_isStarted(linkInstPtr))
{
Linklayer_Reconfig(linkInstPtr, &linkConfig);
}
Linklayer_Start(linkInstPtr); Linklayer_Start(linkInstPtr);
} }
else if (msg[WD_PWUP_SATMODE] == PWUP_SATMODE_DOWN) else if (msg[WD_PWUP_SATMODE] == PWUP_SATMODE_DOWN)
@@ -196,8 +231,10 @@ static int32_t SystemBus_PowerUp(SYSBUS *instPtr, uint16_t *msg)
WD_EN_CMD, msg[WD_EN_CMD]); WD_EN_CMD, msg[WD_EN_CMD]);
return EIGNORE; return EIGNORE;
} }
// TODO: speed configure.
instPtr->sysbusLog.lastConfig = msg[WD_PWUP_SATMODE];
instPtr->sysbusLog.lastConfig[0] = msg[WD_PWUP_SATMODE] & 0xFF;
instPtr->sysbusLog.lastConfig[1] = (msg[WD_PWUP_BACKWARD] >> 4) & 0x0F & msg[WD_PWUP_FORWARD] & 0xF0;
SYSBUS_PSUART_FRAME *sysbusRsp = malloc(sizeof(SYSBUS_PSUART_FRAME)); SYSBUS_PSUART_FRAME *sysbusRsp = malloc(sizeof(SYSBUS_PSUART_FRAME));
@@ -248,13 +285,13 @@ static int32_t SystemBus_ModeSwicth(SYSBUS *instPtr, uint16_t *msg)
WD_EN_CMD, msg[WD_EN_CMD]); WD_EN_CMD, msg[WD_EN_CMD]);
return EIGNORE; return EIGNORE;
} }
instPtr->sysbusLog.lastConfig = msg[WD_MODESW_SATMODE_0]; instPtr->sysbusLog.lastConfig[0] = msg[WD_MODESW_SATMODE_0] & 0xFF;
SYSBUS_PSUART_FRAME *sysbusRsp = malloc(sizeof(SYSBUS_PSUART_FRAME)); SYSBUS_PSUART_FRAME *sysbusRsp = malloc(sizeof(SYSBUS_PSUART_FRAME));
if (sysbusRsp == NULL) if (sysbusRsp == NULL)
{ {
DBG_ERROR("Failed to allocate memory for SELF TEST Response!\n"); DBG_ERROR("Failed to allocate memory for MODE SWITCH Response!\n");
return ENOMEM; return ENOMEM;
} }
uint16_t* rsp = (uint16_t*)sysbusRsp->data; uint16_t* rsp = (uint16_t*)sysbusRsp->data;
@@ -270,6 +307,109 @@ static int32_t SystemBus_ModeSwicth(SYSBUS *instPtr, uint16_t *msg)
return SUCCESS; return SUCCESS;
} }
/**
* @brief Receive service data from upper layer
*/
static int32_t SystemBus_ReceiveSvcDate(SYSBUS *instPtr, uint16_t *msg)
{
ASSERT(instPtr != NULL);
ASSERT(msg != NULL);
if (msg[WD_DATA_SATID] != SATID_NEW) {
return EIGNORE;
}
uint8_t numPack = msg[WD_DATA_SEQPKT] & 0x00FF;
uint8_t seqNo = (msg[WD_DATA_SEQPKT]>>8) & 0x00FF;
size_t dlen = msg[WD_DATA_DLEN];
if(seqNo > numPack) {
DBG_ERROR("Invalid service packet sequence number (%u/%u).\n", seqNo, numPack);
return EPARAM;
}
if(dlen > 500) {
DBG_ERROR("Invalid service data packet length %u.\n", dlen);
return EPARAM;
}
if (instPtr->currSvcBuff == NULL)
{
instPtr->currSvcBuff = RingBuff_Create(SYSBUS_SVC_MAX);
if(instPtr->currSvcBuff == NULL) {
return ENOMEM;
}
}
if(instPtr->currSvcSeq != seqNo) {
DBG_ERROR("Inconsistent packet seqID %u (should be %u).\n", seqNo, instPtr->currSvcSeq);
DBG_ERROR("Restart receiving process.\n");
RingBuff_Flush(instPtr->currSvcBuff);
instPtr->currSvcSeq = 0;
return FAILURE;
}
size_t tmpLen = RingBuff_Push(instPtr->currSvcBuff, (uint8_t*)&(msg[WD_DATA_PAYLOAD]), dlen);
if(tmpLen < dlen) {
DBG_ERROR("Ring buffer overflowed.\n");
ASSERT(true);
}
if(numPack == 0 || seqNo == numPack) {
if(CircQueuePush(instPtr->txSvcQueue, (void**)&(instPtr->currSvcBuff)) == false) {
DBG_ERROR("txSvcQueue overflowed.\n");
RingBuff_Destroy(instPtr->currSvcBuff);
return EQUEUE;
}
instPtr->currSvcBuff = NULL;
instPtr->currSvcSeq = 0;
}
instPtr->sysbusLog.svcUpCnt++;
return SUCCESS;
}
/**
* @brief Upload service data to upper layer
*/
int32_t SystemBus_UploadSvcData(SYSBUS *instPtr)
{
ASSERT(instPtr != NULL);
RING_BUFFER *buff;
if(CircQueuePop(instPtr->txSvcQueue, (void**)(&buff)) == false) {
DBG_ERROR("No service data need to be uploaded.\n");
return EIGNORE;
}
uint8_t numPack = RingBuff_Size(buff) / DATA_PAYLOAD_MAX;
uint8_t cntPack = 0;
while(RingBuff_Size(buff) > 0) {
size_t sentLen;
uint16_t seqId = ((uint16_t)numPack) | ((uint16_t)cntPack << 8);
SYSBUS_PSUART_FRAME *sysbusRsp = malloc(sizeof(SYSBUS_PSUART_FRAME));
if (sysbusRsp == NULL)
{
DBG_ERROR("Failed to allocate memory for LJ REMOTE TEST Response!\n");
return ENOMEM;
}
uint16_t *rsp = (uint16_t*)sysbusRsp->data;
ASSEMBLE_MSG_IMMEDIATE(rsp, WD_CMD, CMD_DATA_UL);
ASSEMBLE_MSG_IMMEDIATE(rsp, WD_DATA_SATID, SATID_NEW);
ASSEMBLE_MSG_IMMEDIATE(rsp, WD_DATA_SEQID, instPtr->sysbusLog.svcUpCnt);
ASSEMBLE_MSG_IMMEDIATE(rsp, WD_DATA_SEQPKT, seqId);
sentLen = RingBuff_Pop(buff, (uint8_t*)&(rsp[WD_DATA_PAYLOAD]), DATA_PAYLOAD_MAX);
ASSEMBLE_MSG_IMMEDIATE(rsp, WD_DATA_DLEN, sentLen);
sysbusRsp->len = DATA_DLUL_LEN;
if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false)
{
RingBuff_Destroy(buff);
free(sysbusRsp);
DBG_WARNING("SystemBus::TX Queue overflowed!\n");
// TODO: check
ASSERT(true);
// return EQUEUE;
}
instPtr->sysbusLog.svcUpCnt++;
}
RingBuff_Destroy(buff);
return SUCCESS;
}
/** /**
* @brief Generate System Bus remote check command response * @brief Generate System Bus remote check command response
*/ */
@@ -422,6 +562,9 @@ int32_t SystemBus_HandleCmd(SYSBUS *instPtr)
case CMD_MODE_SWITCH: case CMD_MODE_SWITCH:
Status = SystemBus_ModeSwicth(instPtr, msg); Status = SystemBus_ModeSwicth(instPtr, msg);
break; break;
case CMD_DATA_DL:
Status = SystemBus_ReceiveSvcDate(instPtr, msg);
break;
default: default:
DBG_ERROR("SystemBus::Unknown command code!\n"); DBG_ERROR("SystemBus::Unknown command code!\n");
Status = FAILURE; Status = FAILURE;
@@ -450,6 +593,7 @@ int32_t SystemBus_MakeResp(SYSBUS *instPtr)
return EIGNORE; return EIGNORE;
} }
Status = SysbusPSUart_Send(instPtr->uartInst, sysbusRsp); Status = SysbusPSUart_Send(instPtr->uartInst, sysbusRsp);
free(sysbusRsp);
return Status; return Status;
} }
@@ -475,9 +619,15 @@ int32_t SystemBus_Init(SYSBUS **instPtr, SYSBUS_CONFIG *config)
{ {
return ENOMEM; return ENOMEM;
} }
(*instPtr)->uartInst = NULL;
(*instPtr)->rxQueue = NULL; (*instPtr)->rxQueue = NULL;
(*instPtr)->txQueue = NULL; (*instPtr)->txQueue = NULL;
(*instPtr)->uartInst = NULL; (*instPtr)->txSvcQueue = NULL;
(*instPtr)->rxSvcQueue = NULL;
(*instPtr)->currSvcSeq = 0;
(*instPtr)->currSvcBuff = NULL;
memcpy(&((*instPtr)->config), config, sizeof(SYSBUS_CONFIG)); memcpy(&((*instPtr)->config), config, sizeof(SYSBUS_CONFIG));
memset(&((*instPtr)->sysbusLog), 0x00, sizeof(SYSBUSLOG)); memset(&((*instPtr)->sysbusLog), 0x00, sizeof(SYSBUSLOG));
memset(&((*instPtr)->linkLog), 0x00, sizeof(LINKLOG)); memset(&((*instPtr)->linkLog), 0x00, sizeof(LINKLOG));
@@ -499,6 +649,16 @@ int32_t SystemBus_Init(SYSBUS **instPtr, SYSBUS_CONFIG *config)
SystemBus_Destroy(*instPtr); SystemBus_Destroy(*instPtr);
return ENOMEM; return ENOMEM;
} }
if (CircQueueCreate(&((*instPtr)->txSvcQueue), (*instPtr)->config.rxQueueMax) == false)
{
SystemBus_Destroy(*instPtr);
return ENOMEM;
}
if (CircQueueCreate(&((*instPtr)->rxSvcQueue), (*instPtr)->config.rxQueueMax) == false)
{
SystemBus_Destroy(*instPtr);
return ENOMEM;
}
return SystemBus_StartListen(*instPtr); return SystemBus_StartListen(*instPtr);
} }
@@ -519,8 +679,10 @@ void SystemBus_Destroy(SYSBUS *instPtr)
return; return;
} }
SysbusPSUart_Destroy(instPtr->uartInst); SysbusPSUart_Destroy(instPtr->uartInst);
free(instPtr->txQueue); CircQueueFree(instPtr->txQueue);
free(instPtr->rxQueue); CircQueueFree(instPtr->rxQueue);
CircQueueFree(instPtr->txSvcQueue);
CircQueueFree(instPtr->rxSvcQueue);
free(instPtr); free(instPtr);
} }
+13 -3
View File
@@ -23,7 +23,8 @@
#include <stdbool.h> #include <stdbool.h>
#include "systembus_psuart.h" #include "systembus_psuart.h"
#include "circ_queue.h" #include "circ_queue.h"
#include "../system_monitor.h" #include "ring_buffer.h"
#include "system_monitor.h"
/************************** Constant Definitions *****************************/ /************************** Constant Definitions *****************************/
/************************** Data Type Definitions ****************************/ /************************** Data Type Definitions ****************************/
@@ -51,8 +52,12 @@ typedef struct
PHYLOG phyLog; ///< Physical layer log PHYLOG phyLog; ///< Physical layer log
HWSTATE hwState; ///< Hardware status HWSTATE hwState; ///< Hardware status
SYSBUS_PSUART *uartInst; ///< physical uart controller instance SYSBUS_PSUART *uartInst; ///< physical uart controller instance
CIRC_QUEUE *txQueue; ///< tx queue uint32_t currSvcSeq;
CIRC_QUEUE *rxQueue; ///< rx queue RING_BUFFER *currSvcBuff;
CIRC_QUEUE *txQueue; ///< tx queue for systembus message
CIRC_QUEUE *rxQueue; ///< rx queue for systembus message
CIRC_QUEUE *txSvcQueue; ///< tx queue for service data
CIRC_QUEUE *rxSvcQueue; ///< rx queue for service data
} SYSBUS; } SYSBUS;
/************************** Function Prototypes ******************************/ /************************** Function Prototypes ******************************/
@@ -67,12 +72,17 @@ void SystemBus_Destroy(SYSBUS *instPtr);
int32_t SystemBus_HandleCmd(SYSBUS *instPtr); int32_t SystemBus_HandleCmd(SYSBUS *instPtr);
int32_t SystemBus_MakeResp(SYSBUS *instPtr); int32_t SystemBus_MakeResp(SYSBUS *instPtr);
int32_t SystemBus_GenRemoteCheckRsp(SYSBUS *instPtr); int32_t SystemBus_GenRemoteCheckRsp(SYSBUS *instPtr);
int32_t SystemBus_UploadSvcData(SYSBUS *instPtr);
/** @} */ /** @} */
int32_t SystemBus_IntrHandler(SYSBUS *instPtr); int32_t SystemBus_IntrHandler(SYSBUS *instPtr);
bool SystemBus_IsReqPending(SYSBUS *instPtr); bool SystemBus_IsReqPending(SYSBUS *instPtr);
bool SystemBus_IsRsqPending(SYSBUS *instPtr); bool SystemBus_IsRsqPending(SYSBUS *instPtr);
bool SystemBus_IsSvcUpPending(SYSBUS *instPtr);
bool SystemBus_IsSvcDownPending(SYSBUS *instPtr);
bool SystemBus_PushSvcFrame(SYSBUS *instPtr, void* buff);
bool SystemBus_PopSvcFrame(SYSBUS *instPtr, void** buff);
bool SystemBus_IsTxBusy(SYSBUS *instPtr); bool SystemBus_IsTxBusy(SYSBUS *instPtr);
bool SystemBus_IsRxBusy(SYSBUS *instPtr); bool SystemBus_IsRxBusy(SYSBUS *instPtr);
+3 -1
View File
@@ -49,7 +49,7 @@
#define SPEED_TT_90K6BPS 0x008B #define SPEED_TT_90K6BPS 0x008B
#define SPEED_NEW_128KBPS 0x009B #define SPEED_NEW_128KBPS 0x009B
#define SPEED_NEW_256KBPS 0x00AB #define SPEED_NEW_256KBPS 0x00AB
#define SPEED_NEW_75BPS 0x00BB #define SPEED_NEW_2KBPS 0x00BB
// Configure load // Configure load
#define CMD_CONFIG 0x0002 #define CMD_CONFIG 0x0002
@@ -138,6 +138,7 @@
// Service Data // Service Data
// -- Request // -- Request
#define DATA_DLUL_LEN 510U
#define CMD_DATA_DL 0x0092 #define CMD_DATA_DL 0x0092
#define CMD_DATA_UL 0x00A2 #define CMD_DATA_UL 0x00A2
#define WD_DATA_SATID 1U #define WD_DATA_SATID 1U
@@ -145,6 +146,7 @@
#define WD_DATA_SEQPKT 3U #define WD_DATA_SEQPKT 3U
#define WD_DATA_DLEN 4U #define WD_DATA_DLEN 4U
#define WD_DATA_PAYLOAD 5U #define WD_DATA_PAYLOAD 5U
#define DATA_PAYLOAD_MAX 500U
// -- Response // -- Response
// -- -- none response // -- -- none response
+3
View File
@@ -148,6 +148,9 @@ int SysbusPSUart_Init(SYSBUS_PSUART **instPtr, const SYSBUS_PSUART_CONFIG *confi
void SysbusPSUart_Destroy(SYSBUS_PSUART *instPtr) { void SysbusPSUart_Destroy(SYSBUS_PSUART *instPtr) {
if(instPtr == NULL) {
return;
}
XUartPs_SetInterruptMask(&(instPtr->hwInst), 0x00000000); XUartPs_SetInterruptMask(&(instPtr->hwInst), 0x00000000);
free(instPtr->currTxMsg); free(instPtr->currTxMsg);
free(instPtr->currRxMsg); free(instPtr->currRxMsg);
+1 -1
View File
@@ -44,7 +44,7 @@
#define SYSBUS_PSUART_1_5_STOP_BIT XUARTPS_FORMAT_1_5_STOP_BIT /**< 1.5 stop bits */ #define SYSBUS_PSUART_1_5_STOP_BIT XUARTPS_FORMAT_1_5_STOP_BIT /**< 1.5 stop bits */
#define SYSBUS_PSUART_1_STOP_BIT XUARTPS_FORMAT_1_STOP_BIT /**< 1 stop bit */ #define SYSBUS_PSUART_1_STOP_BIT XUARTPS_FORMAT_1_STOP_BIT /**< 1 stop bit */
#define SYSBUS_MAX_TRANS_LEN 1024 #define SYSBUS_MAX_TRANS_LEN 512
#define SYSBUS_MIN_TRANS_LEN 4 #define SYSBUS_MIN_TRANS_LEN 4
/** /**
+2 -1
View File
@@ -40,7 +40,8 @@ inline bool isCircQueueEmpty(CIRC_QUEUE *queue)
void CircQueueFree(CIRC_QUEUE *queue) void CircQueueFree(CIRC_QUEUE *queue)
{ {
ASSERT(queue != NULL); if(queue == NULL)
return;
if (queue->data) if (queue->data)
free(queue->data); free(queue->data);
free(queue); free(queue);
+158
View File
@@ -0,0 +1,158 @@
#include "ring_buffer.h"
#include "common.h"
#include <string.h>
#include <stdlib.h>
/**
* @file
* Implementation of ring rb functions.
*/
inline size_t RingBuff_Size(RING_BUFFER *rb) {
return (rb->size);
}
inline uint8_t RingBuff_isEmpty(RING_BUFFER *rb) {
return (rb->size == 0);
}
inline uint8_t RingBuff_isFull(RING_BUFFER *rb) {
return (rb->size == rb->capacity);
}
static inline size_t Get_Available2Write(const RING_BUFFER *rb)
{
return (rb->capacity - rb->size);
}
RING_BUFFER *RingBuff_Create(size_t capacity)
{
if(capacity <= 1) {
return NULL;
}
RING_BUFFER *rb = malloc(sizeof(RING_BUFFER));
if (rb == NULL){
return rb;
}
rb->buffer = malloc(capacity);
if(rb->buffer == NULL) {
free(rb);
return NULL;
}
rb->tail = 0;
rb->head = 0;
rb->size = 0;
rb->capacity = capacity;
return rb;
}
void RingBuff_Destroy(RING_BUFFER *rb)
{
if(rb == NULL) {
return;
}
free(rb->buffer);
free(rb);
}
void RingBuff_Flush(RING_BUFFER *rb)
{
ASSERT(rb != NULL);
rb->tail = 0;
rb->head = 0;
rb->size = 0;
}
size_t RingBuff_Push(RING_BUFFER *rb, const uint8_t *data, size_t len)
{
ASSERT(rb != NULL);
ASSERT(data != NULL);
if (len == 0)
{
return 0;
}
size_t canWrite = Get_Available2Write(rb);
if (canWrite == 0)
{
return 0;
}
if (len > canWrite)
{
len = canWrite;
}
size_t endSpace = rb->capacity - rb->head;
if (len <= endSpace)
{
memcpy(&(rb->buffer[rb->head]), data, len);
rb->head = (rb->head + len) % rb->capacity;
}
else
{
size_t remain = len - endSpace;
memcpy(&(rb->buffer[rb->head]), data, endSpace);
memcpy(&(rb->buffer[0]), data + endSpace, remain);
rb->head = remain;
}
rb->size += len;
return len;
}
size_t RingBuff_Pop(RING_BUFFER *rb, uint8_t *data, size_t len)
{
ASSERT(rb != NULL);
ASSERT(data != NULL);
size_t canRead = rb->size;
if (canRead == 0 || len == 0)
return 0;
if (len > canRead)
{
len = canRead;
}
size_t endSpace = rb->capacity - rb->tail;
if (len <= endSpace)
{
memcpy(data, &rb->buffer[rb->tail], len);
rb->tail = (rb->tail + len) % rb->capacity;
}
else
{
size_t remain = len - endSpace;
memcpy(data, &(rb->buffer[rb->tail]), endSpace);
memcpy(data + endSpace, &(rb->buffer[0]), len - endSpace);
rb->tail = remain;
}
rb->size -= len;
return len;
}
size_t RingBuff_Peek(const RING_BUFFER *rb, uint8_t *data, size_t len)
{
ASSERT(rb != NULL);
ASSERT(data != NULL);
size_t canRead = rb->size;
if (canRead == 0 || len == 0){
return 0;
}
if (len > canRead)
{
len = canRead;
}
size_t endSpace = rb->capacity - rb->tail;
if (len <= endSpace)
{
memcpy(data, &rb->buffer[rb->tail], len);
}
else
{
memcpy(data, &rb->buffer[rb->tail], endSpace);
size_t remain = len - endSpace;
memcpy(data + endSpace, &rb->buffer[0], remain);
}
return len;
}