Compare commits

...
17 Commits
Author SHA1 Message Date
Gatsby Van e71cb9c1ed chore: update build scripts 2024-12-25 16:15:02 +08:00
Gatsby Van 5753a86fb8 chore: update hardware files 2024-12-25 16:14:47 +08:00
Gatsby Van 3320e35cee chore(linklayer): misc cleanup 2024-12-25 16:05:29 +08:00
Gatsby Van 2a8eb64e61 fix(linklayer): set default value for variables to prevent unexpected behavior
Some variables had size mismatches with the data size defined in the frame segment. After deframing, this could leave residual bits as random and unknown values.
2024-12-25 16:05:02 +08:00
Gatsby Van 789e7fa30f fix(linklayer): extend max packet length to prevent memory leak. 2024-12-25 15:58:17 +08:00
Gatsby Van 3765e59b10 feat(linklayer): set 128Kbsp as default fallback seed mode. 2024-12-25 15:57:36 +08:00
Gatsby Van 9c1a30f1e1 refator(mpc): reset link layer log after reconfiguring 2024-12-25 15:54:39 +08:00
Gatsby Van 047446fd9b fix(ge_app): change frequency to 720MHz to match node application 2024-12-25 15:53:07 +08:00
Gatsby Van 89ecdc476f chore: enhance code coherence
* distinct link layer parameter for GE and node application
* disable remote test for node application
* auto start link layer for node application
2024-12-25 15:52:26 +08:00
Gatsby Van c66c3fe18e chore(ge_app): remove redundant code 2024-12-25 15:48:57 +08:00
Gatsby Van deb82441c6 chore: correct build script setting 2024-12-25 15:45:49 +08:00
Gatsby Van 250190baef chore: fix compile errors, simplified code. 2024-12-24 15:12:51 +08:00
Gatsby Van 3470b6f6dc chore: merge GE program
* merge GE code
* update fold structure
* enable to build two types of projects separately
2024-12-24 13:27:22 +08:00
Gatsby Van 384a51a198 fix(systembus): correct systembus_psuart transceiver logic
* neglect radom power-up interrupts
* bound minimum and maximum transmit length
2024-12-18 15:48:34 +08:00
Gatsby Van 7f5a5bb72f chore: fix indentation 2024-12-17 15:03:52 +08:00
Gatsby Van 9e0cfa1b82 fix(systembus): add default init value. 2024-12-16 20:40:52 +08:00
Gatsby Van 902297e726 chore: remove redundant driver and hw config code. 2024-12-16 20:39:10 +08:00
109 changed files with 85152 additions and 22328 deletions
+11 -3
View File
@@ -2,7 +2,15 @@ include scripts/generic_variables.mk
PLATFORM := xilinx
TARGET_PROJ ?= node
BUILD_DIR := $(PROJECT)/build
CONFIG_FILE := $(PROJECT)/config.json
include scripts/generic.mk
ifeq ($(TARGET_PROJ), node)
BUILD_DIR := $(PROJECT)/build/node
CONFIG_FILE := $(PROJECT)/config/node.json
else ifeq ($(TARGET_PROJ), ge)
BUILD_DIR := $(PROJECT)/build/ge
CONFIG_FILE := $(PROJECT)/config/ge.json
else
$(error Unsupported target PROJECT: $(TARGET_PROJ))
endif
include scripts/generic.mk
+7
View File
@@ -11,10 +11,13 @@
### 在 Linux 上构建
1. 初始化工具链环境:
```shell
source /tools/Xilinx/SDK/2019.1/settings64.sh
```
2. 运行以下命令完成构建:
```shell
make
```
@@ -50,6 +53,10 @@
- 重写总线驱动程序,采用 **PS UART 控制器**完成总线信息的收发。
- 更新总线控制协议,基于《网控模块 GLINK 协议》实现核心交互逻辑。
- 使用折算的方式模拟新体制中的三档速率:
- 2Kbps:10Kbps模拟,Payload 128b, 占空比 40%
- 128Kbps:200Kbps模拟,Payload 1280b, 占空比 50%
- 256Kbps:1.2Mbps模拟,Payload 2560b, 占空比 50%
---
+30 -4
View File
@@ -1,9 +1,35 @@
@echo off
set "platform=xilinx"
set "tools_dir=%~dp0scripts\platform\%platform%"
set "platform_ver=2019.1"
set "work_dir=%~dp0build"
set "config=%~dp0config.json"
:menu
echo Please select the project needed to be built:
echo 1. NODE Project (SDK 2019.1)
echo 2. GE Project (SDK 2019.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 ^(SDK 2019.1^)
set "platform_ver=2019.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
cd /d "%~dp0"
@@ -32,4 +58,4 @@ if "%ERRORLEVEL%" neq "0" (
exit /b 1
)
exit /b 0
exit /b 0
+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"]
}
}
}
}
}
+15 -4
View File
@@ -1,10 +1,21 @@
{
"project_name": "ky-xtz",
"version": "0.0.0",
"hw_design": "hw/hsjl_node_v0.0.0.hdf",
"hw_design": "hw/kykk_node_hw_v0.0.hdf",
"apps": {
"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",
"os": "standalone",
"language": "C",
@@ -14,11 +25,11 @@
},
"build_config": {
"debug": {
"include-path": ["src/include"],
"include-path": ["src", "src/include"],
"libraries": ["m"]
},
"release": {
"include-path": ["src/include"],
"include-path": ["src", "src/include"],
"libraries": ["m"]
}
}
Binary file not shown.
Binary file not shown.
+21516
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+20197
View File
File diff suppressed because it is too large Load Diff
+1 -1
Submodule scripts updated: af260c1610...58ed5e4bda
-193
View File
@@ -1,193 +0,0 @@
/*****************************************************************************/
/**
* 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) 2024 Beijing Institute of Technology.
* Lab of Communication and Networking
*
******************************************************************************/
#ifndef __APP_CONFIG_H_
#define __APP_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 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 0X00
#define PHY_BASEADDR XPAR_PHYC_BASEADDR
#define PHY_BEAM_FORMING_ENABLE
// -- Antenna Bram Configs
#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
// -- 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 SYSBUS_DEV_ID XPAR_XUARTPS_0_DEVICE_ID
#define SYSBUS_INTR_ID XPAR_XUARTPS_0_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
// AD9361 Configuration
#define SPI_INTERFACE_SPI_ENGINE
#define HAVE_SPLIT_GAIN_TABLE 1 /* only set to 0 in case split_gain_table_mode_enable = 0*/
#define HAVE_TDD_SYNTH_TABLE 1 /* only set to 0 in case split_gain_table_mode_enable = 0*/
#define AD9361_DEVICE 1 /* set it 1 if AD9361 device is used, 0 otherwise */
#define AD9364_DEVICE 0 /* set it 1 if AD9364 device is used, 0 otherwise */
#define AD9363A_DEVICE 0 /* set it 1 if AD9363A device is used, 0 otherwise */
#define HAVE_VERBOSE_MESSAGES /* Recommended during development prints errors and warnings */
// #define HAVE_DEBUG_MESSAGES /* For Debug purposes only */
// -- AD9361 SPI Engine Configuration
#define AD9361_SPI_DEVICE_ID 0
#define AD9361_SPI_ENGINE_REF_CLK FCLK_CLK0_HZ
#define AD9361_SPI_ENGINE_MAX_SPEED 5000000
#define AD9361_SPI_ENGINE_BASEADDR XPAR_AXI_SPI_ENGINE_AXI_SPI_ENGINE_BASEADDR
#define AD9361_SPI_ENGINE_DATA_WIDTH 8
#define AD9361_SPI_ENGINE_CS_DELAY 3
#define AD9361_SPI_CS_AD9361_1 0x01
#define AD9361_SPI_CS_AD9361_2 0x02
#define AD9361_TIMEOUT_TH 2000
// AD9361 GPIO Configurations
#define AD9361_GPIO_DEVICE_ID 0
#define AD9361_GPIO_OFFSET 54
#define AD9361_GPIO_INPUT 0
#define AD9361_GPIO_OUTPUT 1
#define AD9361_GPIO_DISABLE 0
#define AD9361_GPIO_ENABLE 1
// -- AD9361-1
#define AD9361_1_TXNRX (AD9361_GPIO_OFFSET + 6)
#define AD9361_1_ENABLE (AD9361_GPIO_OFFSET + 7)
#define AD9361_1_EN_AGC (AD9361_GPIO_OFFSET + 8)
#define AD9361_1_RESET_B (AD9361_GPIO_OFFSET + 9)
#define AD9361_1_CTRL_OUT0 (AD9361_GPIO_OFFSET + 10)
#define AD9361_1_CTRL_OUT1 (AD9361_GPIO_OFFSET + 11)
#define AD9361_1_CTRL_OUT2 (AD9361_GPIO_OFFSET + 12)
#define AD9361_1_CTRL_OUT3 (AD9361_GPIO_OFFSET + 13)
#define AD9361_1_CTRL_OUT4 (AD9361_GPIO_OFFSET + 14)
#define AD9361_1_CTRL_OUT5 (AD9361_GPIO_OFFSET + 15)
#define AD9361_1_CTRL_OUT6 (AD9361_GPIO_OFFSET + 16)
#define AD9361_1_CTRL_OUT7 (AD9361_GPIO_OFFSET + 17)
#define AD9361_1_CTRL_IN0 (AD9361_GPIO_OFFSET + 18)
#define AD9361_1_CTRL_IN1 (AD9361_GPIO_OFFSET + 19)
#define AD9361_1_CTRL_IN2 (AD9361_GPIO_OFFSET + 20)
#define AD9361_1_CTRL_IN3 (AD9361_GPIO_OFFSET + 21)
// AD9361-2
#define AD9361_2_TXNRX (AD9361_GPIO_OFFSET + 22)
#define AD9361_2_ENABLE (AD9361_GPIO_OFFSET + 23)
#define AD9361_2_EN_AGC (AD9361_GPIO_OFFSET + 24)
#define AD9361_2_RESET_B (AD9361_GPIO_OFFSET + 25)
#define AD9361_2_CTRL_OUT0 (AD9361_GPIO_OFFSET + 26)
#define AD9361_2_CTRL_OUT1 (AD9361_GPIO_OFFSET + 27)
#define AD9361_2_CTRL_OUT2 (AD9361_GPIO_OFFSET + 28)
#define AD9361_2_CTRL_OUT3 (AD9361_GPIO_OFFSET + 29)
#define AD9361_2_CTRL_OUT4 (AD9361_GPIO_OFFSET + 30)
#define AD9361_2_CTRL_OUT5 (AD9361_GPIO_OFFSET + 31)
#define AD9361_2_CTRL_OUT6 (AD9361_GPIO_OFFSET + 32)
#define AD9361_2_CTRL_OUT7 (AD9361_GPIO_OFFSET + 33)
#define AD9361_2_CTRL_IN0 (AD9361_GPIO_OFFSET + 34)
#define AD9361_2_CTRL_IN1 (AD9361_GPIO_OFFSET + 35)
#define AD9361_2_CTRL_IN2 (AD9361_GPIO_OFFSET + 36)
#define AD9361_2_CTRL_IN3 (AD9361_GPIO_OFFSET + 37)
// AD9361-Status Code
#define AD9361_SYNC (AD9361_GPIO_OFFSET + 38)
#define AD9361_RX_FIFO_RST (AD9361_GPIO_OFFSET + 39)
#define AD9361_1_CAL_START (AD9361_GPIO_OFFSET + 40)
#define AD9361_2_CAL_START (AD9361_GPIO_OFFSET + 41)
#define AD9361_RECAL (AD9361_GPIO_OFFSET + 42)
#define AD9361_TX_SWITCH (AD9361_GPIO_OFFSET + 43)
#define AD9361_1_CAL_DONE (AD9361_GPIO_OFFSET + 44)
#define AD9361_2_CAL_DONE (AD9361_GPIO_OFFSET + 45)
#define AD9361_CAL_RESULT (AD9361_GPIO_OFFSET + 46)
typedef enum
{
TX_FREQ_125,
TX_FREQ_126,
TX_FREQ_4125
} ad9361TxFreq;
// HMC7044 Configurations
#define HMC7044_GPIO_DEVICE_ID 0
#define HMC7044_GPIO_OFFSET 54
#define HMC7044_RESET (HMC7044_GPIO_OFFSET + 0)
#define HMC7044_SYNC (HMC7044_GPIO_OFFSET + 1)
#define HMC7044_GPIO_0 (HMC7044_GPIO_OFFSET + 2)
#define HMC7044_GPIO_1 (HMC7044_GPIO_OFFSET + 3)
#define HMC7044_GPIO_2 (HMC7044_GPIO_OFFSET + 4)
#define HMC7044_GPIO_3 (HMC7044_GPIO_OFFSET + 5)
// -- HMC7044 SPI Engine Configuration
#define HMC7044_SPI_DEVICE_ID 0
#define HMC7044_SPI_ENGINE_REF_CLK FCLK_CLK0_HZ
#define HMC7044_SPI_ENGINE_MAX_SPEED 5000000
#define HMC7044_SPI_ENGINE_BASEADDR XPAR_AXI_SPI_ENGINE_AXI_SPI_ENGINE_BASEADDR
#define HMC7044_SPI_ENGINE_DATA_WIDTH 8
#define HMC7044_SPI_ENGINE_CS_DELAY 3
#define HMC7044_SPI_CS_HMC7044 0x00
// 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_
-340
View File
@@ -1,340 +0,0 @@
#include "dev_profile.h"
#include "../config/app_config.h"
#include "../drivers/rf-transceiver/ad9361/ad9361_api.h"
#include "../drivers/axi_core/spi_engine/spi_engine.h"
#include "../drivers/platform/xilinx_gpio.h"
struct spi_engine_init_param spi_engine_param = {
.ref_clk_hz = AD9361_SPI_ENGINE_REF_CLK,
.type = SPI_ENGINE,
.spi_engine_baseaddr = AD9361_SPI_ENGINE_BASEADDR,
.cs_delay = AD9361_SPI_ENGINE_CS_DELAY,
.data_width = AD9361_SPI_ENGINE_DATA_WIDTH
};
struct xil_gpio_init_param xil_gpio_param = {
.type = GPIO_PS,
.device_id = AD9361_GPIO_DEVICE_ID
};
AD9361_InitParam ad9361_default_init_param = {
/* Device selection */
ID_AD9361, // dev_sel
/* Reference Clock */
48000000UL, //reference_clk_rate
/* Base Configuration */
1, //two_rx_two_tx_mode_enable *** adi,2rx-2tx-mode-enable
1, //one_rx_one_tx_mode_use_rx_num *** adi,1rx-1tx-mode-use-rx-num
1, //one_rx_one_tx_mode_use_tx_num *** adi,1rx-1tx-mode-use-tx-num
1, //frequency_division_duplex_mode_enable *** adi,frequency-division-duplex-mode-enable
0, //frequency_division_duplex_independent_mode_enable *** adi,frequency-division-duplex-independent-mode-enable
0, //tdd_use_dual_synth_mode_enable *** adi,tdd-use-dual-synth-mode-enable
0, //tdd_skip_vco_cal_enable *** adi,tdd-skip-vco-cal-enable
0, //tx_fastlock_delay_ns *** adi,tx-fastlock-delay-ns
0, //rx_fastlock_delay_ns *** adi,rx-fastlock-delay-ns
0, //rx_fastlock_pincontrol_enable *** adi,rx-fastlock-pincontrol-enable
0, //tx_fastlock_pincontrol_enable *** adi,tx-fastlock-pincontrol-enable
0, //external_rx_lo_enable *** adi,external-rx-lo-enable
0, //external_tx_lo_enable *** adi,external-tx-lo-enable
5, //dc_offset_tracking_update_event_mask *** adi,dc-offset-tracking-update-event-mask
6, //dc_offset_attenuation_high_range *** adi,dc-offset-attenuation-high-range
5, //dc_offset_attenuation_low_range *** adi,dc-offset-attenuation-low-range
0x28, //dc_offset_count_high_range *** adi,dc-offset-count-high-range
0x32, //dc_offset_count_low_range *** adi,dc-offset-count-low-range
0, //split_gain_table_mode_enable *** adi,split-gain-table-mode-enable
MAX_SYNTH_FREF, //trx_synthesizer_target_fref_overwrite_hz *** adi,trx-synthesizer-target-fref-overwrite-hz
0, // qec_tracking_slow_mode_enable *** adi,qec-tracking-slow-mode-enable
/* ENSM Control */
0, //ensm_enable_pin_pulse_mode_enable *** adi,ensm-enable-pin-pulse-mode-enable
0, //ensm_enable_txnrx_control_enable *** adi,ensm-enable-txnrx-control-enable
/* LO Control */
4125000000UL, //rx_synthesizer_frequency_hz *** adi,rx-synthesizer-frequency-hz
4126000000UL, //tx_synthesizer_frequency_hz *** adi,tx-synthesizer-frequency-hz
1, //tx_lo_powerdown_managed_enable *** adi,tx-lo-powerdown-managed-enable
/* Rate & BW Control */
{768000000, 192000000, 96000000, 48000000, 24000000, 24000000},// rx_path_clock_frequencies[6] *** adi,rx-path-clock-frequencies
{768000000, 192000000, 96000000, 48000000, 24000000, 24000000},// tx_path_clock_frequencies[6] *** adi,tx-path-clock-frequencies
18000000,//rf_rx_bandwidth_hz *** adi,rf-rx-bandwidth-hz
18000000,//rf_tx_bandwidth_hz *** adi,rf-tx-bandwidth-hz
/* RF Port Control */
0, //rx_rf_port_input_select *** adi,rx-rf-port-input-select
0, //tx_rf_port_input_select *** adi,tx-rf-port-input-select
/* TX Attenuation Control */
10000, //tx_attenuation_mdB *** adi,tx-attenuation-mdB
0, //update_tx_gain_in_alert_enable *** adi,update-tx-gain-in-alert-enable
/* Reference Clock Control */
0, //xo_disable_use_ext_refclk_enable *** adi,xo-disable-use-ext-refclk-enable
{8, 5920}, //dcxo_coarse_and_fine_tune[2] *** adi,dcxo-coarse-and-fine-tune
CLKOUT_DISABLE, //clk_output_mode_select *** adi,clk-output-mode-select
/* Gain Control */
2, //gc_rx1_mode *** adi,gc-rx1-mode
2, //gc_rx2_mode *** adi,gc-rx2-mode
58, //gc_adc_large_overload_thresh *** adi,gc-adc-large-overload-thresh
4, //gc_adc_ovr_sample_size *** adi,gc-adc-ovr-sample-size
47, //gc_adc_small_overload_thresh *** adi,gc-adc-small-overload-thresh
8192, //gc_dec_pow_measurement_duration *** adi,gc-dec-pow-measurement-duration
0, //gc_dig_gain_enable *** adi,gc-dig-gain-enable
800, //gc_lmt_overload_high_thresh *** adi,gc-lmt-overload-high-thresh
704, //gc_lmt_overload_low_thresh *** adi,gc-lmt-overload-low-thresh
24, //gc_low_power_thresh *** adi,gc-low-power-thresh
15, //gc_max_dig_gain *** adi,gc-max-dig-gain
0, //gc_use_rx_fir_out_for_dec_pwr_meas_enable *** adi,gc-use-rx-fir-out-for-dec-pwr-meas-enable
/* Gain MGC Control */
2, //mgc_dec_gain_step *** adi,mgc-dec-gain-step
2, //mgc_inc_gain_step *** adi,mgc-inc-gain-step
0, //mgc_rx1_ctrl_inp_enable *** adi,mgc-rx1-ctrl-inp-enable
0, //mgc_rx2_ctrl_inp_enable *** adi,mgc-rx2-ctrl-inp-enable
0, //mgc_split_table_ctrl_inp_gain_mode *** adi,mgc-split-table-ctrl-inp-gain-mode
/* Gain AGC Control */
10, //agc_adc_large_overload_exceed_counter *** adi,agc-adc-large-overload-exceed-counter
2, //agc_adc_large_overload_inc_steps *** adi,agc-adc-large-overload-inc-steps
0, //agc_adc_lmt_small_overload_prevent_gain_inc_enable *** adi,agc-adc-lmt-small-overload-prevent-gain-inc-enable
10, //agc_adc_small_overload_exceed_counter *** adi,agc-adc-small-overload-exceed-counter
4, //agc_dig_gain_step_size *** adi,agc-dig-gain-step-size
3, //agc_dig_saturation_exceed_counter *** adi,agc-dig-saturation-exceed-counter
1000, // agc_gain_update_interval_us *** adi,agc-gain-update-interval-us
0, //agc_immed_gain_change_if_large_adc_overload_enable *** adi,agc-immed-gain-change-if-large-adc-overload-enable
0, //agc_immed_gain_change_if_large_lmt_overload_enable *** adi,agc-immed-gain-change-if-large-lmt-overload-enable
10, //agc_inner_thresh_high *** adi,agc-inner-thresh-high
1, //agc_inner_thresh_high_dec_steps *** adi,agc-inner-thresh-high-dec-steps
12, //agc_inner_thresh_low *** adi,agc-inner-thresh-low
1, //agc_inner_thresh_low_inc_steps *** adi,agc-inner-thresh-low-inc-steps
10, //agc_lmt_overload_large_exceed_counter *** adi,agc-lmt-overload-large-exceed-counter
2, //agc_lmt_overload_large_inc_steps *** adi,agc-lmt-overload-large-inc-steps
10, //agc_lmt_overload_small_exceed_counter *** adi,agc-lmt-overload-small-exceed-counter
5, //agc_outer_thresh_high *** adi,agc-outer-thresh-high
2, //agc_outer_thresh_high_dec_steps *** adi,agc-outer-thresh-high-dec-steps
18, //agc_outer_thresh_low *** adi,agc-outer-thresh-low
2, //agc_outer_thresh_low_inc_steps *** adi,agc-outer-thresh-low-inc-steps
1, //agc_attack_delay_extra_margin_us; *** adi,agc-attack-delay-extra-margin-us
0, //agc_sync_for_gain_counter_enable *** adi,agc-sync-for-gain-counter-enable
/* Fast AGC */
64, //fagc_dec_pow_measuremnt_duration *** adi,fagc-dec-pow-measurement-duration
260, //fagc_state_wait_time_ns *** adi,fagc-state-wait-time-ns
/* Fast AGC - Low Power */
0, //fagc_allow_agc_gain_increase *** adi,fagc-allow-agc-gain-increase-enable
5, //fagc_lp_thresh_increment_time *** adi,fagc-lp-thresh-increment-time
1, //fagc_lp_thresh_increment_steps *** adi,fagc-lp-thresh-increment-steps
/* Fast AGC - Lock Level (Lock Level is set via slow AGC inner high threshold) */
1, //fagc_lock_level_lmt_gain_increase_en *** adi,fagc-lock-level-lmt-gain-increase-enable
5, //fagc_lock_level_gain_increase_upper_limit *** adi,fagc-lock-level-gain-increase-upper-limit
/* Fast AGC - Peak Detectors and Final Settling */
1, //fagc_lpf_final_settling_steps *** adi,fagc-lpf-final-settling-steps
1, //fagc_lmt_final_settling_steps *** adi,fagc-lmt-final-settling-steps
3, //fagc_final_overrange_count *** adi,fagc-final-overrange-count
/* Fast AGC - Final Power Test */
0, //fagc_gain_increase_after_gain_lock_en *** adi,fagc-gain-increase-after-gain-lock-enable
/* Fast AGC - Unlocking the Gain */
0, //fagc_gain_index_type_after_exit_rx_mode *** adi,fagc-gain-index-type-after-exit-rx-mode
1, //fagc_use_last_lock_level_for_set_gain_en *** adi,fagc-use-last-lock-level-for-set-gain-enable
1, //fagc_rst_gla_stronger_sig_thresh_exceeded_en *** adi,fagc-rst-gla-stronger-sig-thresh-exceeded-enable
5, //fagc_optimized_gain_offset *** adi,fagc-optimized-gain-offset
10, //fagc_rst_gla_stronger_sig_thresh_above_ll *** adi,fagc-rst-gla-stronger-sig-thresh-above-ll
1, //fagc_rst_gla_engergy_lost_sig_thresh_exceeded_en *** adi,fagc-rst-gla-engergy-lost-sig-thresh-exceeded-enable
1, //fagc_rst_gla_engergy_lost_goto_optim_gain_en *** adi,fagc-rst-gla-engergy-lost-goto-optim-gain-enable
10, //fagc_rst_gla_engergy_lost_sig_thresh_below_ll *** adi,fagc-rst-gla-engergy-lost-sig-thresh-below-ll
8, //fagc_energy_lost_stronger_sig_gain_lock_exit_cnt *** adi,fagc-energy-lost-stronger-sig-gain-lock-exit-cnt
1, //fagc_rst_gla_large_adc_overload_en *** adi,fagc-rst-gla-large-adc-overload-enable
1, //fagc_rst_gla_large_lmt_overload_en *** adi,fagc-rst-gla-large-lmt-overload-enable
0, //fagc_rst_gla_en_agc_pulled_high_en *** adi,fagc-rst-gla-en-agc-pulled-high-enable
0, //fagc_rst_gla_if_en_agc_pulled_high_mode *** adi,fagc-rst-gla-if-en-agc-pulled-high-mode
64, //fagc_power_measurement_duration_in_state5 *** adi,fagc-power-measurement-duration-in-state5
2, //fagc_large_overload_inc_steps *** adi,fagc-adc-large-overload-inc-steps
/* RSSI Control */
1, //rssi_delay *** adi,rssi-delay
1000, //rssi_duration *** adi,rssi-duration
3, //rssi_restart_mode *** adi,rssi-restart-mode
0, //rssi_unit_is_rx_samples_enable *** adi,rssi-unit-is-rx-samples-enable
1, //rssi_wait *** adi,rssi-wait
/* Aux ADC Control */
256, //aux_adc_decimation *** adi,aux-adc-decimation
48000000UL, //aux_adc_rate *** adi,aux-adc-rate
/* AuxDAC Control */
1, //aux_dac_manual_mode_enable *** adi,aux-dac-manual-mode-enable
0, //aux_dac1_default_value_mV *** adi,aux-dac1-default-value-mV
0, //aux_dac1_active_in_rx_enable *** adi,aux-dac1-active-in-rx-enable
0, //aux_dac1_active_in_tx_enable *** adi,aux-dac1-active-in-tx-enable
0, //aux_dac1_active_in_alert_enable *** adi,aux-dac1-active-in-alert-enable
0, //aux_dac1_rx_delay_us *** adi,aux-dac1-rx-delay-us
0, //aux_dac1_tx_delay_us *** adi,aux-dac1-tx-delay-us
0, //aux_dac2_default_value_mV *** adi,aux-dac2-default-value-mV
0, //aux_dac2_active_in_rx_enable *** adi,aux-dac2-active-in-rx-enable
0, //aux_dac2_active_in_tx_enable *** adi,aux-dac2-active-in-tx-enable
0, //aux_dac2_active_in_alert_enable *** adi,aux-dac2-active-in-alert-enable
0, //aux_dac2_rx_delay_us *** adi,aux-dac2-rx-delay-us
0, //aux_dac2_tx_delay_us *** adi,aux-dac2-tx-delay-us
/* Temperature Sensor Control */
256, //temp_sense_decimation *** adi,temp-sense-decimation
1000, //temp_sense_measurement_interval_ms *** adi,temp-sense-measurement-interval-ms
0xCE, //temp_sense_offset_signed *** adi,temp-sense-offset-signed
1, //temp_sense_periodic_measurement_enable *** adi,temp-sense-periodic-measurement-enable
/* Control Out Setup */
0xFF, //ctrl_outs_enable_mask *** adi,ctrl-outs-enable-mask
0, //ctrl_outs_index *** adi,ctrl-outs-index
/* External LNA Control */
0, //elna_settling_delay_ns *** adi,elna-settling-delay-ns
0, //elna_gain_mdB *** adi,elna-gain-mdB
0, //elna_bypass_loss_mdB *** adi,elna-bypass-loss-mdB
0, //elna_rx1_gpo0_control_enable *** adi,elna-rx1-gpo0-control-enable
0, //elna_rx2_gpo1_control_enable *** adi,elna-rx2-gpo1-control-enable
0, //elna_gaintable_all_index_enable *** adi,elna-gaintable-all-index-enable
/* Digital Interface Control */
0, //digital_interface_tune_skip_mode *** adi,digital-interface-tune-skip-mode
0, //digital_interface_tune_fir_disable *** adi,digital-interface-tune-fir-disable
1, //pp_tx_swap_enable *** adi,pp-tx-swap-enable
1, //pp_rx_swap_enable *** adi,pp-rx-swap-enable
0, //tx_channel_swap_enable *** adi,tx-channel-swap-enable
0, //rx_channel_swap_enable *** adi,rx-channel-swap-enable
1, //rx_frame_pulse_mode_enable *** adi,rx-frame-pulse-mode-enable
0, //two_t_two_r_timing_enable *** adi,2t2r-timing-enable
0, //invert_data_bus_enable *** adi,invert-data-bus-enable
0, //invert_data_clk_enable *** adi,invert-data-clk-enable
0, //fdd_alt_word_order_enable *** adi,fdd-alt-word-order-enable
0, //invert_rx_frame_enable *** adi,invert-rx-frame-enable
0, //fdd_rx_rate_2tx_enable *** adi,fdd-rx-rate-2tx-enable
0, //swap_ports_enable *** adi,swap-ports-enable
0, //single_data_rate_enable *** adi,single-data-rate-enable
1, //lvds_mode_enable *** adi,lvds-mode-enable
0, //half_duplex_mode_enable *** adi,half-duplex-mode-enable
0, //single_port_mode_enable *** adi,single-port-mode-enable
0, //full_port_enable *** adi,full-port-enable
0, //full_duplex_swap_bits_enable *** adi,full-duplex-swap-bits-enable
0, //delay_rx_data *** adi,delay-rx-data
0, //rx_data_clock_delay *** adi,rx-data-clock-delay
4, //rx_data_delay *** adi,rx-data-delay
7, //tx_fb_clock_delay *** adi,tx-fb-clock-delay
0, //tx_data_delay *** adi,tx-data-delay
150, //lvds_bias_mV *** adi,lvds-bias-mV
1, //lvds_rx_onchip_termination_enable *** adi,lvds-rx-onchip-termination-enable
0, //rx1rx2_phase_inversion_en *** adi,rx1-rx2-phase-inversion-enable
0xFF, //lvds_invert1_control *** adi,lvds-invert1-control
0x0F, //lvds_invert2_control *** adi,lvds-invert2-control
/* GPO Control */
0, //gpo_manual_mode_enable *** adi,gpo-manual-mode-enable
0, //gpo_manual_mode_enable_mask *** adi,gpo-manual-mode-enable-mask
0, //gpo0_inactive_state_high_enable *** adi,gpo0-inactive-state-high-enable
0, //gpo1_inactive_state_high_enable *** adi,gpo1-inactive-state-high-enable
0, //gpo2_inactive_state_high_enable *** adi,gpo2-inactive-state-high-enable
0, //gpo3_inactive_state_high_enable *** adi,gpo3-inactive-state-high-enable
0, //gpo0_slave_rx_enable *** adi,gpo0-slave-rx-enable
0, //gpo0_slave_tx_enable *** adi,gpo0-slave-tx-enable
0, //gpo1_slave_rx_enable *** adi,gpo1-slave-rx-enable
0, //gpo1_slave_tx_enable *** adi,gpo1-slave-tx-enable
0, //gpo2_slave_rx_enable *** adi,gpo2-slave-rx-enable
0, //gpo2_slave_tx_enable *** adi,gpo2-slave-tx-enable
0, //gpo3_slave_rx_enable *** adi,gpo3-slave-rx-enable
0, //gpo3_slave_tx_enable *** adi,gpo3-slave-tx-enable
0, //gpo0_rx_delay_us *** adi,gpo0-rx-delay-us
0, //gpo0_tx_delay_us *** adi,gpo0-tx-delay-us
0, //gpo1_rx_delay_us *** adi,gpo1-rx-delay-us
0, //gpo1_tx_delay_us *** adi,gpo1-tx-delay-us
0, //gpo2_rx_delay_us *** adi,gpo2-rx-delay-us
0, //gpo2_tx_delay_us *** adi,gpo2-tx-delay-us
0, //gpo3_rx_delay_us *** adi,gpo3-rx-delay-us
0, //gpo3_tx_delay_us *** adi,gpo3-tx-delay-us
/* Tx Monitor Control */
37000, //low_high_gain_threshold_mdB *** adi,txmon-low-high-thresh
0, //low_gain_dB *** adi,txmon-low-gain
24, //high_gain_dB *** adi,txmon-high-gain
0, //tx_mon_track_en *** adi,txmon-dc-tracking-enable
0, //one_shot_mode_en *** adi,txmon-one-shot-mode-enable
511, //tx_mon_delay *** adi,txmon-delay
8192, //tx_mon_duration *** adi,txmon-duration
2, //tx1_mon_front_end_gain *** adi,txmon-1-front-end-gain
2, //tx2_mon_front_end_gain *** adi,txmon-2-front-end-gain
48, //tx1_mon_lo_cm *** adi,txmon-1-lo-cm
48, //tx2_mon_lo_cm *** adi,txmon-2-lo-cm
/* GPIO definitions */
/* Reset_b */
{
.number = AD9361_1_RESET_B,
.platform_ops = &xil_gpio_ops,
.extra = &xil_gpio_param
}, //gpio_resetb *** reset-gpios
/* MCS Sync */
{
.number = -1,
.platform_ops = &xil_gpio_ops,
.extra = &xil_gpio_param
}, //gpio_sync *** sync-gpios
/* Cal-SW1 */
{
.number = -1,
.platform_ops = &xil_gpio_ops,
.extra = &xil_gpio_param
}, //gpio_cal_sw1 *** cal-sw1-gpios
/* Cal-SW2 */
{
.number = -1,
.platform_ops = &xil_gpio_ops,
.extra = &xil_gpio_param
}, //gpio_cal_sw2 *** cal-sw2-gpios
{
.device_id = AD9361_SPI_DEVICE_ID,
.mode = SPI_MODE_1,
.chip_select = AD9361_SPI_CS_AD9361_1,
.platform_ops = &spi_eng_platform_ops,
.extra = &spi_engine_param
},
/* External LO clocks */
NULL, //(*ad9361_rfpll_ext_recalc_rate)()
NULL, //(*ad9361_rfpll_ext_round_rate)()
NULL, //(*ad9361_rfpll_ext_set_rate)()
};
AD9361_RXFIRConfig rx_fir_config = { // BPF PASSBAND 3/20 fs to 1/4 fs
3, // rx
0, // rx_gain
1, // rx_dec
{
-4, -6, -37, 35, 186, 86, -284, -315,
107, 219, -4, 271, 558, -307, -1182, -356,
658, 157, 207, 1648, 790, -2525, -2553, 748,
865, -476, 3737, 6560, -3583, -14731, -5278, 14819,
14819, -5278, -14731, -3583, 6560, 3737, -476, 865,
748, -2553, -2525, 790, 1648, 207, 157, 658,
-356, -1182, -307, 558, 271, -4, 219, 107,
-315, -284, 86, 186, 35, -37, -6, -4,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
}, // rx_coef[128]
64, // rx_coef_size
{0, 0, 0, 0, 0, 0}, //rx_path_clks[6]
0 // rx_bandwidth
};
AD9361_TXFIRConfig tx_fir_config = { // BPF PASSBAND 3/20 fs to 1/4 fs
3, // tx
-6, // tx_gain
1, // tx_int
{
-4, -6, -37, 35, 186, 86, -284, -315,
107, 219, -4, 271, 558, -307, -1182, -356,
658, 157, 207, 1648, 790, -2525, -2553, 748,
865, -476, 3737, 6560, -3583, -14731, -5278, 14819,
14819, -5278, -14731, -3583, 6560, 3737, -476, 865,
748, -2553, -2525, 790, 1648, 207, 157, 658,
-356, -1182, -307, 558, 271, -4, 219, 107,
-315, -284, 86, 186, 35, -37, -6, -4,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
}, // tx_coef[128]
64, // tx_coef_size
{0, 0, 0, 0, 0, 0}, // tx_path_clks[6]
0 // tx_bandwidth
};
File diff suppressed because it is too large Load Diff
-27
View File
@@ -1,27 +0,0 @@
#ifndef _DEV_PROFILE_H_
#define _DEV_PROFILE_H_
#include "irq.h"
#include "error.h"
#include "../drivers/rf-transceiver/ad9361/ad9361_api.h"
#include "../drivers/rf-transceiver/ad9361_reg/ad9361_reg.h"
#include "../drivers/frequency/hmc7044/hmc7044.h"
#include "../drivers/adc/ad9694/ad9694.h"
#include "../config/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;
// HMC7044
extern struct hmc7044_init_param hmc7044_default_init_param;
// AD9361
extern AD9361_InitParam ad9361_default_init_param;
extern AD9361_RXFIRConfig rx_fir_config;
extern AD9361_TXFIRConfig tx_fir_config;
extern struct ad9361_reg_init_param ad9361_1_reg_default_init_param;
extern struct ad9361_reg_init_param ad9361_2_reg_default_init_param;
uint32_t ad9361_reg_config(struct ad9361_reg_dev *dev);
#endif /* SRC_DEV_PROFILE_H_ */
-132
View File
@@ -1,132 +0,0 @@
#include "dev_profile.h"
#include "../config/app_config.h"
#include "../drivers/platform/xilinx_gpio.h"
#include "../drivers/axi_core/spi_engine/spi_engine.h"
#include "../drivers/frequency/hmc7044/hmc7044.h"
static struct spi_engine_init_param spi_engine_param = {
.ref_clk_hz = HMC7044_SPI_ENGINE_REF_CLK,
.type = SPI_ENGINE,
.spi_engine_baseaddr = HMC7044_SPI_ENGINE_BASEADDR,
.cs_delay = HMC7044_SPI_ENGINE_CS_DELAY,
.data_width = HMC7044_SPI_ENGINE_DATA_WIDTH
};
//static struct xil_gpio_init_param xil_gpio_param = {
// .type = GPIO_PS,
// .device_id = AD9361_GPIO_DEVICE_ID
//};
// hmc7044 spi settings
static struct spi_init_param hmc7044_spi_init_param = {
.device_id = HMC7044_SPI_DEVICE_ID,
.max_speed_hz = HMC7044_SPI_ENGINE_MAX_SPEED,
.mode = SPI_MODE_4,
.chip_select = HMC7044_SPI_CS_HMC7044,
.platform_ops = &spi_eng_platform_ops,
.extra = &spi_engine_param
};
// hmc7044 channel specifications
struct hmc7044_chan_spec hmc7044_chan_spec[4] = {
/* AD9361_XTAL */
{
.disable = 0,
.num = 3,
.divider = 100,
.coarse_delay = 0,
.fine_delay = 0,
.high_performance_mode_dis = true,
.start_up_mode_dynamic_enable = false,
.dynamic_driver_enable = false,
.output_control0_rb4_enable = true,
.force_mute_enable = false,
.driver_mode = CML,
.driver_impedance = INTERNAL_100OHM_PER_PIN,
.out_mux_mode = CHANNEL_DIV
},
/* FPGA_DAC_LOGIC_CLK */
{
.disable = 0,
.num = 4,
.divider = 10,
.coarse_delay = 0,
.fine_delay = 0,
.high_performance_mode_dis = true,
.start_up_mode_dynamic_enable = false,
.dynamic_driver_enable = false,
.output_control0_rb4_enable = true,
.force_mute_enable = false,
.driver_mode = CML,
.driver_impedance = INTERNAL_100OHM_PER_PIN,
.out_mux_mode = CHANNEL_DIV
},
/* B_AD9361_XTAL */
{
.disable = 0,
.num = 12,
.divider = 100,
.coarse_delay = 0,
.fine_delay = 0,
.high_performance_mode_dis = false,
.start_up_mode_dynamic_enable = false,
.dynamic_driver_enable = false,
.output_control0_rb4_enable = true,
.force_mute_enable = false,
.driver_mode = CML,
.driver_impedance = INTERNAL_100OHM_PER_PIN,
.out_mux_mode = CHANNEL_DIV
},
/* AD9361_RX_EXT_LO */
{
.disable = 0,
.num = 13,
.divider = 10,
.coarse_delay = 0,
.fine_delay = 0,
.high_performance_mode_dis = false,
.start_up_mode_dynamic_enable = false,
.dynamic_driver_enable = false,
.output_control0_rb4_enable = true,
.force_mute_enable = false,
.driver_mode = CML,
.driver_impedance = INTERNAL_100OHM_PER_PIN,
.out_mux_mode = CHANNEL_DIV
},
};
// hmc7044 default configurations
struct hmc7044_init_param hmc7044_default_init_param = {
.spi_init = &hmc7044_spi_init_param,
.clkin_freq = {0, 100000000, 0, 0},
.vcxo_freq = 100000000,
.pll2_freq = 2500000000,
.pll1_loop_bw = 200,
.sysref_timer_div = 1536,
.in_buf_mode = {
BUFFER_DISABLE,
ENABLE_AC_COUPLE | ENABLE_INTERNAL_TERM | BUFFER_ENABLE,
BUFFER_DISABLE,
BUFFER_DISABLE,
ENABLE_AC_COUPLE | ENABLE_INTERNAL_TERM | BUFFER_ENABLE
},
.gpi_ctrl = {
GPI_DISABLE,
GPI_DISABLE,
CHIP_SLEEP_MODE,
PULSE_GEN_REQUSET
},
.gpo_ctrl = {
PLL1_LOCK_DETECT | GPO_CMOS_MODE,
PLL2_LOCK_DETECT | GPO_CMOS_MODE,
GPO_DISABLE,
GPO_DISABLE
},
.num_channels = 4,
.pll1_ref_prio_ctrl = 0xE4,
.sync_pin_mode = SYNC_MULTICHIP,
.high_performance_mode_clock_dist_en = false,
.pulse_gen_mode = PULSE_ONE,
.channels = hmc7044_chan_spec
};
-128
View File
@@ -1,128 +0,0 @@
/***************************************************************************//**
* @file ad9694.c
* @brief Implementation of AD9680 Driver.
* @author DBogdan ([email protected])
********************************************************************************
* Copyright 2014-2016(c) Analog Devices, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* - Neither the name of Analog Devices, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* - The use of this software may or may not infringe the patent rights
* of one or more patent holders. This license does not release you
* from the requirement that you obtain separate licenses from these
* patent holders to use this software.
* - Use of the software either in source or binary form, must be run
* on or directly connected to an Analog Devices Inc. component.
*
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include "ad9694.h"
#include "../../../include/error.h"
/***************************************************************************//**
* @brief ad9694_read
*******************************************************************************/
int32_t ad9694_read(struct ad9694_dev *dev,
uint16_t reg_addr,
uint8_t *reg_data)
{
uint8_t tx_buf[2];
uint8_t rx_buf[1];
int32_t ret;
tx_buf[0] = 0x80 | (reg_addr >> 8);
tx_buf[1] = reg_addr & 0xFF;
ret = spi_write_and_read_3wire(dev->spi_desc,
tx_buf, rx_buf, 2, 1);
*reg_data = rx_buf[0];
return ret;
}
/***************************************************************************//**
* @brief ad9694_write
*******************************************************************************/
int32_t ad9694_write(struct ad9694_dev *dev,
uint16_t reg_addr,
uint8_t reg_data)
{
uint8_t buf[3];
int32_t ret;
buf[0] = reg_addr >> 8;
buf[1] = reg_addr & 0xFF;
buf[2] = reg_data;
ret = spi_write_and_read_3wire(dev->spi_desc,
buf, NULL, 3, 0);
return ret;
}
/***************************************************************************//**
* @brief ad9694_init
*******************************************************************************/
int32_t ad9694_init(struct ad9694_dev **device,
const struct ad9694_init_param *init_param)
{
int ret = SUCCESS;
struct ad9694_dev *dev;
dev = (struct ad9694_dev *)malloc(sizeof(*dev));
if (!dev)
return FAILURE;
/* SPI */
ret = spi_init(&dev->spi_desc, init_param->spi_init);
*device = dev;
return ret;
}
/***************************************************************************//**
* @brief Free the resources allocated by ad9694_setup().
*
* @param dev - The device structure.
*
* @return SUCCESS in case of success, negative error code otherwise.
*******************************************************************************/
int32_t ad9694_remove(struct ad9694_dev *dev)
{
int32_t ret;
ret = spi_remove(dev->spi_desc);
free(dev);
return ret;
}
-231
View File
@@ -1,231 +0,0 @@
/***************************************************************************//**
* @file ad9694.h
* @brief Header file of AD9694 Driver.
* @author DBogdan ([email protected])
********************************************************************************
* Copyright 2014-2016(c) Analog Devices, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* - Neither the name of Analog Devices, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* - The use of this software may or may not infringe the patent rights
* of one or more patent holders. This license does not release you
* from the requirement that you obtain separate licenses from these
* patent holders to use this software.
* - Use of the software either in source or binary form, must be run
* on or directly connected to an Analog Devices Inc. component.
*
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#ifndef AD9694_H_
#define AD9694_H_
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <stdint.h>
#include "delay.h"
#include "spi.h"
/******************************************************************************/
/********************** Macros and Constants Definitions **********************/
/******************************************************************************/
#define AD9694_REG_GLOBAL_MAP_SPI_CONF_A 0x0000
#define AD9694_REG_GLOBAL_MAP_SPI_CONF_B 0x0001
#define AD9694_REG_CH_MAP_CHIP_CONF 0x0002
#define AD9694_REG_PAIR_MAP_CHIP_TYPE 0x0003
#define AD9694_REG_PAIR_MAP_CHIP_ID_LSB 0x0004
#define AD9694_REG_PAIR_MAP_CHIP_GRADE 0x0006
#define AD9694_REG_PAIR_MAP_DEV_INDEX 0x0008
#define AD9694_REG_GLOBAL_MAP_PAIR_INDEX 0x0009
#define AD9694_REG_PAIR_MAP_SCRATCH_PAD 0x000A
#define AD9694_REG_PAIR_MAP_SPI_REVISION 0x000B
#define AD9694_REG_PAIR_MAP_VENDOR_ID_LSB 0x000C
#define AD9694_REG_PAIR_MAP_VENDOR_ID_MSB 0x000D
#define AD9694_REG_CH_MAP_CHIP_PD_PIN 0x003F
#define AD9694_REG_PAIR_MAP_CHIP_PIN_CTRL_1 0x0040
#define AD9694_REG_PAIR_MAP_CLK_DIV_CTRL 0x0108
#define AD9694_REG_CH_MAP_CLK_DIV_PHASE 0x0109
#define AD9694_REG_PAIR_MAP_CLK_DIV_SYSREF_CTRL 0x010A
#define AD9694_REG_PAIR_MAP_CLK_DELAY_CTRL 0x0110
#define AD9694_REG_CH_MAP_CLK_SUPER_FINE_DELAY 0x0111
#define AD9694_REG_CH_MAP_CLK_FINE_DELAY 0x0112
#define AD9694_REG_CLK_DETN_CTRL 0x011A
#define AD9694_REG_PAIR_MAP_CLK_STAT 0x011B
#define AD9694_REG_CLK_DCS_CTRL_1 0x011C
#define AD9694_REG_CLK_DCS_CTRL_2 0x011E
#define AD9694_REG_CLK_DCS_CTRL_3 0x011F
#define AD9694_REG_PAIR_MAP_SYSREF_CTRL_1 0x0120
#define AD9694_REG_PAIR_MAP_SYSREF_CTRL_2 0x0121
#define AD9694_REG_PAIR_MAP_SYSREF_CTRL_4 0x0123
#define AD9694_REG_PAIR_MAP_SYSREF_STAT_1 0x0128
#define AD9694_REG_PAIR_MAP_SYSREF_STAT_2 0x0129
#define AD9694_REG_PAIR_MAP_SYSREF_STAT_3 0x012A
#define AD9694_REG_PAIR_MAP_CHIP_SYNC 0x01FF
#define AD9694_REG_PAIR_MAP_CHIP_MODE 0x0200
#define AD9694_REG_PAIR_MAP_CHIP_DEC_RATIO 0x0201
#define AD9694_REG_CH_MAP_CUSTOM_OFFSET 0x0228
#define AD9694_REG_CH_MAP_FD_CTRL 0x0245
#define AD9694_REG_CH_MAP_FD_UT_LSB 0x0247
#define AD9694_REG_CH_MAP_FD_UT_MSB 0x0248
#define AD9694_REG_CH_MAP_FD_LT_LSB 0x0249
#define AD9694_REG_CH_MAP_FD_LT_MSB 0x024A
#define AD9694_REG_CH_MAP_FD_DWELL_TIME_LSB 0x024B
#define AD9694_REG_CH_MAP_FD_DWELL_TIME_MSB 0x024C
#define AD9694_REG_PAIR_MAP_SIG_MON_SYNC_CTRL 0x026F
#define AD9694_REG_CH_MAP_SIG_MON_CTRL 0x0270
#define AD9694_REG_CH_MAP_SIG_MON_PERIOD_0 0x0271
#define AD9694_REG_CH_MAP_SIG_MON_PERIOD_1 0x0272
#define AD9694_REG_CH_MAP_SIG_MON_PERIOD_2 0x0273
#define AD9694_REG_CH_MAP_SIG_MON_STAT_CTRL 0x0274
#define AD9694_REG_CH_MAP_SIG_MON_STAT_0 0x0275
#define AD9694_REG_CH_MAP_SIG_MON_STAT_1 0x0276
#define AD9694_REG_CH_MAP_SIG_MON_STAT_2 0x0277
#define AD9694_REG_CH_MAP_SIG_MON_STAT_FRAME_CNT 0x0278
#define AD9694_REG_CH_MAP_SIG_MON_SERIAL_FRAMER_CTRL 0x0279
#define AD9694_REG_SPORT_OVER_JESD204B_INPUT_SEL 0x027A
#define AD9694_REG_PAIR_MAP_DDC_SYNC_CTRL 0x0300
#define AD9694_REG_PAIR_MAP_DDC_0_CTRL 0x0310
#define AD9694_REG_PAIR_MAP_DDC_0_INPUT_SEL 0x0311
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_INC_0 0x0314
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_INC_1 0x0315
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_INC_2 0x0316
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_INC_3 0x0317
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_INC_4 0x0318
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_INC_5 0x031A
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_OFFSET_0 0x031D
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_OFFSET_1 0x031E
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_OFFSET_2 0x031F
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_OFFSET_3 0x0320
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_OFFSET_4 0x0321
#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_OFFSET_5 0x0322
#define AD9694_REG_PAIR_MAP_DDC_0_TEST_ENABLE 0x0327
#define AD9694_REG_PAIR_MAP_DDC_1_CTRL 0x0330
#define AD9694_REG_PAIR_MAP_DDC_1_INPUT_SEL 0x0331
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_INC_0 0x0334
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_INC_1 0x0335
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_INC_2 0x0336
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_INC_3 0x0337
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_INC_4 0x0338
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_INC_5 0x033A
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_OFFSET_0 0x033D
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_OFFSET_1 0x033E
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_OFFSET_2 0x033F
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_OFFSET_3 0x0340
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_OFFSET_4 0x0341
#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_OFFSET_5 0x0342
#define AD9694_REG_PAIR_MAP_DDC_1_TEST_ENABLE 0x0347
#define AD9694_REG_CH_MAP_TEST_MODE_CTRL 0x0550
#define AD9694_REG_PAIR_MAP_USER_PATTERN_1_LSB 0x0551
#define AD9694_REG_PAIR_MAP_USER_PATTERN_1_MSB 0x0552
#define AD9694_REG_PAIR_MAP_USER_PATTERN_2_LSB 0x0553
#define AD9694_REG_PAIR_MAP_USER_PATTERN_2_MSB 0x0554
#define AD9694_REG_PAIR_MAP_USER_PATTERN_3_LSB 0x0555
#define AD9694_REG_PAIR_MAP_USER_PATTERN_3_MSB 0x0556
#define AD9694_REG_PAIR_MAP_USER_PATTERN_4_LSB 0x0557
#define AD9694_REG_PAIR_MAP_USER_PATTERN_4_MSB 0x0558
#define AD9694_REG_PAIR_MAP_OUTPUT_CTRL_MODE_0 0x0559
#define AD9694_REG_PAIR_MAP_OUTPUT_CTRL_MODE_1 0x055A
#define AD9694_REG_PAIR_MAP_OUTPUT_SAMPLE_MODE 0x0561
#define AD9694_REG_PAIR_MAP_OUTPUT_CH_SEL 0x0564
#define AD9694_REG_JESD204B_MAP_PLL_CTRL 0x056E
#define AD9694_REG_JESD204B_MAP_PLL_STAT 0x056F
#define AD9694_REG_JESD204B_MAP_JTX_QUICK_CONF 0x0570
#define AD9694_REG_JESD204B_MAP_JTX_LINK_CTRL_1 0x0571
#define AD9694_REG_JESD204B_MAP_JTX_LINK_CTRL_2 0x0572
#define AD9694_REG_JESD204B_MAP_JTX_LINK_CTRL_3 0x0573
#define AD9694_REG_JESD204B_MAP_JTX_LINK_CTRL_4 0x0574
#define AD9694_REG_JESD204B_MAP_JTX_LMFC_OFFSET 0x0578
#define AD9694_REG_JESD204B_MAP_JTX_DID_CONF 0x0580
#define AD9694_REG_JESD204B_MAP_JTX_BID_CONF 0x0581
#define AD9694_REG_JESD204B_MAP_JTX_LID_0_CONF 0x0583
#define AD9694_REG_JESD204B_MAP_JTX_LID_1_CONF 0x0585
#define AD9694_REG_JESD204B_MAP_JTX_SCR_L_CONF 0x058B
#define AD9694_REG_JESD204B_MAP_JTX_F_CONF 0x058C
#define AD9694_REG_JESD204B_MAP_JTX_K_CONF 0x058D
#define AD9694_REG_JESD204B_MAP_JTX_M_CONF 0x058E
#define AD9694_REG_JESD204B_MAP_JTX_CS_N_CONF 0x058F
#define AD9694_REG_JESD204B_MAP_JTX_SUBCLASS_CONF 0x0590
#define AD9694_REG_JESD204B_MAP_JTX_S_CONF 0x0591
#define AD9694_REG_JESD204B_MAP_JTX_HD_CF_CONF 0x0592
#define AD9694_REG_JESD204B_MAP_JTX_CHECKSUM_0_CONF 0x05A0
#define AD9694_REG_JESD204B_MAP_JTX_CHECKSUM_1_CONF 0x05A1
#define AD9694_REG_SERDOUTX0_SERDOUTX1_LANE_PD 0x05B0
#define AD9694_REG_JESD204B_MAP_JTX_LANE_ASSIGN_1 0x05B2
#define AD9694_REG_JESD204B_MAP_JTX_LANE_ASSIGN_2 0x05B3
#define AD9694_REG_JESD204B_MAP_SERD_ADJUST_0 0x05C0
#define AD9694_REG_JESD204B_MAP_SERD_ADJUST_1 0x05C1
#define AD9694_REG_JESD204B_SER_PE_SEL_LANE_0 0x05C4
#define AD9694_REG_JESD204B_SER_PE_SEL_LANE_1 0x05C6
#define AD9694_REG_LARGE_DITHER_CTRL 0x0922
#define AD9694_REG_PLL_CAL 0x1222
#define AD9694_REG_JESD204B_STARTUP_CIRCUIT_RST 0x1228
#define AD9694_REG_PLL_LOSS_OF_LOCK_CTRL 0x1262
#define AD9694_REG_DC_OFFSET_CAL_CTRL 0x0701
#define AD9694_REG_DC_OFFSET_CAL_CTRL_2 0x073B
#define AD9694_REG_PAIR_MAP_VREF_CTRL 0x18A6
#define AD9694_REG_EXT_VCM_BUF_CTRL_1 0x18E0
#define AD9694_REG_EXT_VCM_BUF_CTRL_2 0x18E1
#define AD9694_REG_EXT_VCM_BUF_CTRL_3 0x18E2
#define AD9694_REG_EXT_VCM_BUF_CTRL 0x18E3
#define AD9694_REG_TEMP_DIODE_EXPORT 0x18E6
#define AD9694_REG_CH_MAP_ANALOG_INPUT_CTRL 0x1908
#define AD9694_REG_CH_MAP_INPUT_FULLSCALE_RANGE 0x1910
#define AD9694_REG_CH_MAP_BUF_CTRL_1 0x1A4C
#define AD9694_REG_CH_MAP_BUF_CTRL_2 0x1A4D
/******************************************************************************/
/*************************** Types Declarations *******************************/
/******************************************************************************/
struct ad9694_dev {
/* SPI */
struct spi_desc *spi_desc;
};
struct ad9694_init_param {
/* SPI */
struct spi_init_param *spi_init;
};
struct ad9694_config {
uint16_t addr;
uint8_t value;
};
/******************************************************************************/
/************************ Functions Declarations ******************************/
/******************************************************************************/
int32_t ad9694_read(struct ad9694_dev *dev,
uint16_t reg_addr,
uint8_t *reg_data);
int32_t ad9694_write(struct ad9694_dev *dev,
uint16_t reg_addr,
uint8_t reg_data);
int32_t ad9694_init(struct ad9694_dev **device,
const struct ad9694_init_param *init_param);
int32_t ad9694_remove(struct ad9694_dev *dev);
#endif
-241
View File
@@ -1,241 +0,0 @@
/***************************************************************************//**
* @file gpio.c
* @brief Implementation of the GPIO Interface
* @author Antoniu Miclaus ([email protected])
********************************************************************************
* Copyright 2020(c) Analog Devices, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* - Neither the name of Analog Devices, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* - The use of this software may or may not infringe the patent rights
* of one or more patent holders. This license does not release you
* from the requirement that you obtain separate licenses from these
* patent holders to use this software.
* - Use of the software either in source or binary form, must be run
* on or directly connected to an Analog Devices Inc. component.
*
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#include <inttypes.h>
#include "gpio.h"
#include <stdlib.h>
#include "error.h"
/******************************************************************************/
/************************ Functions Definitions *******************************/
/******************************************************************************/
/**
* @brief Obtain the GPIO decriptor.
* @param desc - The GPIO descriptor.
* @param param - GPIO Initialization parameters.
* @return 0 in case of success, -1 otherwise.
*/
int32_t gpio_get(struct gpio_desc **desc,
const struct gpio_init_param *param)
{
int32_t ret;
if (!param || !param->platform_ops)
return -EINVAL;
if (!param->platform_ops->gpio_ops_get)
return -ENOSYS;
ret = param->platform_ops->gpio_ops_get(desc, param);
if (ret)
return ret;
(*desc)->platform_ops = param->platform_ops;
return 0;
}
/**
* @brief Get the value of an optional GPIO.
* @param desc - The GPIO descriptor.
* @param param - GPIO Initialization parameters.
* @return 0 in case of success, -1 otherwise.
*/
int32_t gpio_get_optional(struct gpio_desc **desc,
const struct gpio_init_param *param)
{
int32_t ret;
if (!param || (param->number == -1)) {
*desc = NULL;
return 0;
}
if (!param->platform_ops)
return -EINVAL;
if (!param->platform_ops->gpio_ops_get_optional)
return -ENOSYS;
ret = param->platform_ops->gpio_ops_get_optional(desc, param);
if (ret)
return ret;
(*desc)->platform_ops = param->platform_ops;
return 0;
}
/**
* @brief Free the resources allocated by gpio_get().
* @param desc - The GPIO descriptor.
* @return 0 in case of success, -1 otherwise.
*/
int32_t gpio_remove(struct gpio_desc *desc)
{
if (desc) {
if (!desc->platform_ops)
return -EINVAL;
if (!desc->platform_ops->gpio_ops_remove)
return -ENOSYS;
return desc->platform_ops->gpio_ops_remove(desc);
}
return 0;
}
/**
* @brief Enable the input direction of the specified GPIO.
* @param desc - The GPIO descriptor.
* @return 0 in case of success, -1 otherwise.
*/
int32_t gpio_direction_input(struct gpio_desc *desc)
{
if (desc) {
if (!desc->platform_ops)
return -EINVAL;
if (!desc->platform_ops->gpio_ops_direction_input)
return -ENOSYS;
return desc->platform_ops->gpio_ops_direction_input(desc);
}
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 0 in case of success, -1 otherwise.
*/
int32_t gpio_direction_output(struct gpio_desc *desc,
uint8_t value)
{
if (desc) {
if (!desc->platform_ops)
return -EINVAL;
if (!desc->platform_ops->gpio_ops_direction_output)
return -ENOSYS;
return desc->platform_ops->
gpio_ops_direction_output(desc, value);
}
return 0;
}
/**
* @brief Get the direction of the specified GPIO.
* @param desc - The GPIO descriptor.
* @param direction - The direction.
* Example: GPIO_OUT
* GPIO_IN
* @return 0 in case of success, -1 otherwise.
*/
int32_t gpio_get_direction(struct gpio_desc *desc,
uint8_t *direction)
{
if (desc) {
if (!desc->platform_ops)
return -EINVAL;
if (!desc->platform_ops->gpio_ops_get_direction)
return -ENOSYS;
return desc->platform_ops->
gpio_ops_get_direction(desc, direction);
}
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 0 in case of success, -1 otherwise.
*/
int32_t gpio_set_value(struct gpio_desc *desc,
uint8_t value)
{
if (desc) {
if (!desc->platform_ops)
return -EINVAL;
if (!desc->platform_ops->gpio_ops_set_value)
return -ENOSYS;
return desc->platform_ops->gpio_ops_set_value(desc, value);
}
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 0 in case of success, -1 otherwise.
*/
int32_t gpio_get_value(struct gpio_desc *desc,
uint8_t *value)
{
if (desc) {
if (!desc->platform_ops)
return -EINVAL;
if (!desc->platform_ops->gpio_ops_set_value)
return -ENOSYS;
return desc->platform_ops->gpio_ops_get_value(desc, value);
}
return 0;
}
-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 "spi_engine_private.h"
#include "../axi_dmac/axi_dmac.h"
#include "../../platform/xilinx_spi.h"
#include "drivers/axi_core/axi_dmac/axi_dmac.h"
#include "drivers/platform/xilinx_spi.h"
/******************************************************************************/
/********************** Macros and Constants Definitions **********************/
-927
View File
@@ -1,927 +0,0 @@
/***************************************************************************//**
* @file hmc7044.c
* @brief Implementation of HMC7044, HMC7043 Driver.
* @author DBogdan ([email protected])
********************************************************************************
* Copyright 2018-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 Files **********************************/
/******************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include "hmc7044.h"
#include "../../../include/error.h"
#include "../../../include/util.h"
/******************************************************************************/
/********************** Macros and Constants Definitions **********************/
/******************************************************************************/
#define HMC7044_WRITE (0 << 15)
#define HMC7044_READ (1 << 15)
#define HMC7044_CNT(x) (((x) - 1) << 13)
#define HMC7044_ADDR(x) ((x) & 0xFFF)
/* Global Control */
#define HMC7044_REG_SOFT_RESET 0x0000
#define HMC7044_SOFT_RESET BIT(0)
#define HMC7044_REG_REQ_MODE_0 0x0001
#define HMC7044_RESEED_REQ BIT(7)
#define HMC7044_HIGH_PERF_DISTRIB_PATH BIT(6)
#define HMC7044_HIGH_PERF_PLL_VCO BIT(5)
#define HMC7044_FORCE_HOLDOVER BIT(4)
#define HMC7044_MUTE_OUT_DIV BIT(3)
#define HMC7044_PULSE_GEN_REQ BIT(2)
#define HMC7044_RESTART_DIV_FSM BIT(1)
#define HMC7044_SLEEP_MODE BIT(0)
#define HMC7044_REG_REQ_MODE_1 0x0002
#define HMC7044_PLL2_AUTOTUNE_TRIG BIT(2)
#define HMC7044_SLIP_REQ BIT(1)
#define HMC7044_REG_EN_CTRL_0 0x0003
#define HMC7044_RF_RESEEDER_EN BIT(5)
#define HMC7044_VCO_SEL(x) (((x) & 0x3) << 3)
#define HMC7044_VCO_EXT 0
#define HMC7044_VCO_HIGH 1
#define HMC7044_VCO_LOW 2
#define HMC7044_SYSREF_TIMER_EN BIT(2)
#define HMC7044_PLL2_EN BIT(1)
#define HMC7044_PLL1_EN BIT(0)
#define HMC7044_REG_EN_CTRL_1 0x0004
#define HMC7044_SEVEN_PAIRS(x) ((x) & 0x7f)
#define HMC7044_REG_GLOB_MODE 0x0005
#define HMC7044_REF_PATH_EN(x) ((x) & 0xf)
#define HMC7044_RFSYNC_EN BIT(4)
#define HMC7044_VCOIN_MODE_EN BIT(5)
#define HMC7044_SYNC_PIN_MODE(x) (((x) & 0x3) << 6)
/* PLL1 */
#define HMC7044_REG_CLKIN0_BUF_CTRL 0x000A
#define HMC7044_REG_CLKIN1_BUF_CTRL 0x000B
#define HMC7044_REG_CLKIN2_BUF_CTRL 0x000C
#define HMC7044_REG_CLKIN3_BUF_CTRL 0x000D
#define HMC7044_REG_OSCIN_BUF_CTRL 0x000E
#define HMC7044_REG_PLL1_REF_PRIO_CTRL 0x0014
#define HMC7044_HIGH_Z_EN BIT(4)
#define HMC7044_LVPECL_EN BIT(3)
#define HMC7044_AC_COUPLING_EN BIT(2)
#define HMC7044_100_OHM_EN BIT(1)
#define HMC7044_BUF_EN BIT(0)
#define HMC7044_REG_CLKIN_PRESCALER(x) (0x001C + (x))
#define HMC7044_REG_OSCIN_PRESCALER 0x0020
#define HMC7044_REG_PLL1_R_LSB 0x0021
#define HMC7044_R1_LSB(x) ((x) & 0xff)
#define HMC7044_REG_PLL1_R_MSB 0x0022
#define HMC7044_R1_MSB(x) (((x) & 0xff00) >> 8)
#define HMC7044_REG_PLL1_N_LSB 0x0026
#define HMC7044_N1_LSB(x) ((x) & 0xff)
#define HMC7044_REG_PLL1_N_MSB 0x0027
#define HMC7044_N1_MSB(x) (((x) & 0xff00) >> 8)
#define HMC7044_REG_PLL1_LOCK_DETECT 0x0028
#define HMC7044_LOCK_DETECT_SLIP BIT(5)
#define HMC7044_LOCK_DETECT_TIMER(x) ((x) & 0x1f)
/* PLL2 */
#define HMC7044_REG_PLL2_FREQ_DOUBLER 0x0032
#define HMC7044_PLL2_FREQ_DOUBLER_DIS BIT(0)
#define HMC7044_REG_PLL2_R_LSB 0x0033
#define HMC7044_R2_LSB(x) ((x) & 0xff)
#define HMC7044_REG_PLL2_R_MSB 0x0034
#define HMC7044_R2_MSB(x) (((x) & 0xf00) >> 8)
#define HMC7044_REG_PLL2_N_LSB 0x0035
#define HMC7044_N2_LSB(x) ((x) & 0xff)
#define HMC7044_REG_PLL2_N_MSB 0x0036
#define HMC7044_N2_MSB(x) (((x) & 0xff00) >> 8)
#define HMC7044_REG_OSCOUT_PATH 0x0039
#define HMC7044_REG_OSCOUT_DRIVER_0 0x003A
#define HMC7044_REG_OSCOUT_DRIVER_1 0x003B
/* GPIO/SDATA Control */
#define HMC7044_REG_GPI_CTRL(x) (0x0046 + (x))
#define HMC7044_REG_GPI_SEL(x) ((x) & 0xf)
#define HMC7044_REG_GPO_CTRL(x) (0x0050 + (x))
#define HMC7044_GPO_SEL(x) (((x) & 0x3f) << 2)
#define HMC7044_GPO_MODE BIT(1)
#define HMC7044_GPO_EN BIT(0)
/* SYSREF/SYNC Control */
#define HMC7044_REG_PULSE_GEN 0x005A
#define HMC7044_PULSE_GEN_MODE(x) ((x) & 0x7)
#define HMC7044_REG_SYNC 0x005B
#define HMC7044_SYNC_RETIME BIT(2)
#define HMC7044_SYNC_THROUGH_PLL2 BIT(1)
#define HMC7044_SYNC_POLARITY BIT(0)
#define HMC7044_REG_SYSREF_TIMER_LSB 0x005C
#define HMC7044_SYSREF_TIMER_LSB(x) ((x) & 0xff)
#define HMC7044_REG_SYSREF_TIMER_MSB 0x005D
#define HMC7044_SYSREF_TIMER_MSB(x) (((x) & 0xf00) >> 8)
#define HMC7044_CLK_INPUT_CTRL 0x0064
#define HMC7044_LOW_FREQ_INPUT_MODE BIT(0)
#define HMC7044_DIV_2_INPUT_MODE BIT(1)
/* Status and Alarm readback */
#define HMC7044_REG_ALARM_READBACK 0x007D
#define HMC7044_REG_PLL1_STATUS 0x0082
#define HMC7044_PLL1_FSM_STATE(x) ((x) & 0x7)
#define HMC7044_PLL1_ACTIVE_CLKIN(x) (((x) >> 3) & 0x3)
#define HMC7044_PLL2_LOCK_DETECT(x) ((x) & 0x1)
#define HMC7044_SYSREF_SYNC_STAT(x) ((x) & 0x2)
#define HMC7044_CLK_OUT_PH_STATUS(x) ((x) & 0x4)
#define HMC7044_PLL1_PLL2_LOCK_STAT(x) ((x) & 0x8)
#define HMC7044_SYNC_REQ_STATUS(x) ((x) & 0x10)
/* Other Controls */
#define HMC7044_REG_CLK_OUT_DRV_LOW_PW 0x009F
#define HMC7044_REG_CLK_OUT_DRV_HIGH_PW 0x00A0
#define HMC7044_REG_PLL1_DELAY 0x00A5
#define HMC7044_REG_PLL1_HOLDOVER 0x00A8
#define HMC7044_REG_VTUNE_PRESET 0x00B0
/* Clock Distribution */
#define HMC7044_REG_CH_OUT_CRTL_0(ch) (0x00C8 + 0xA * (ch))
#define HMC7044_HI_PERF_MODE BIT(7)
#define HMC7044_SYNC_EN BIT(6)
#define HMC7044_CH_EN BIT(0)
#define HMC7044_START_UP_MODE_DYN_EN (BIT(3) | BIT(2))
#define HMC7044_REG_CH_OUT_CRTL_1(ch) (0x00C9 + 0xA * (ch))
#define HMC7044_DIV_LSB(x) ((x) & 0xFF)
#define HMC7044_REG_CH_OUT_CRTL_2(ch) (0x00CA + 0xA * (ch))
#define HMC7044_DIV_MSB(x) (((x) >> 8) & 0xFF)
#define HMC7044_REG_CH_OUT_CRTL_3(ch) (0x00CB + 0xA * (ch))
#define HMC7044_REG_CH_OUT_CRTL_4(ch) (0x00CC + 0xA * (ch))
#define HMC7044_REG_CH_OUT_CRTL_5(ch) (0x00CD + 0xA * (ch))
#define HMC7044_REG_CH_OUT_CRTL_6(ch) (0x00CE + 0xA * (ch))
#define HMC7044_REG_CH_OUT_CRTL_7(ch) (0x00CF + 0xA * (ch))
#define HMC7044_REG_CH_OUT_CRTL_8(ch) (0x00D0 + 0xA * (ch))
#define HMC7044_DRIVER_MODE(x) (((x) & 0x3) << 3)
#define HMC7044_DRIVER_Z_MODE(x) (((x) & 0x3) << 0)
#define HMC7044_DYN_DRIVER_EN BIT(5)
#define HMC7044_FORCE_MUTE_EN BIT(7)
#define HMC7044_NUM_CHAN 14
#define HMC7044_LOW_VCO_MIN 2150000
#define HMC7044_LOW_VCO_MAX 2880000
#define HMC7044_HIGH_VCO_MIN 2650000
#define HMC7044_HIGH_VCO_MAX 3200000
#define HMC7044_RECOMM_LCM_MIN 30000
#define HMC7044_RECOMM_LCM_MAX 70000
#define HMC7044_RECOMM_FPD1 10000
#define HMC7044_R1_MAX 65535
#define HMC7044_N1_MAX 65535
#define HMC7044_R2_MIN 1
#define HMC7044_R2_MAX 4095
#define HMC7044_N2_MIN 8
#define HMC7044_N2_MAX 65535
#define HMC7044_OUT_DIV_MIN 1
#define HMC7044_OUT_DIV_MAX 4094
/******************************************************************************/
/************************** Functions Implementation **************************/
/******************************************************************************/
/**
* SPI register write to device.
* @param dev - The device structure.
* @param reg - The register address.
* @param val - The register data.
* @return SUCCESS in case of success, negative error code otherwise.
*/
int32_t hmc7044_write(struct hmc7044_dev *dev,
uint16_t reg,
uint8_t val)
{
uint8_t buf[3];
uint16_t cmd;
cmd = HMC7044_WRITE | HMC7044_CNT(1) | HMC7044_ADDR(reg);
buf[0] = cmd >> 8;
buf[1] = cmd & 0xFF;
buf[2] = val;
return spi_write_and_read_3wire(dev->spi_desc, buf, NULL,
ARRAY_SIZE(buf), 0);
}
/**
* SPI register read from device.
* @param dev - The device structure.
* @param reg - The register address.
* @param val - The register data.
* @return SUCCESS in case of success, negative error code otherwise.
*/
int32_t hmc7044_read(struct hmc7044_dev *dev, uint16_t reg, uint8_t *val)
{
uint8_t wr_buf[2];
uint8_t rd_data[1];
uint16_t cmd;
int ret;
cmd = HMC7044_READ | HMC7044_CNT(1) | HMC7044_ADDR(reg);
wr_buf[0] = cmd >> 8;
wr_buf[1] = cmd & 0xFF;
ret = spi_write_and_read_3wire(dev->spi_desc, wr_buf, rd_data,
ARRAY_SIZE(wr_buf), ARRAY_SIZE(rd_data));
if (ret != SUCCESS)
return ret;
*val = rd_data[0];
return SUCCESS;
}
/**
* Calculate the output channel divider.
* @param rate - The desired rate.
* @param parent_rate - The parent rate.
* @return The output divider.
*/
uint32_t hmc7044_calc_out_div(uint32_t rate,
uint32_t parent_rate)
{
uint32_t div;
div = DIV_ROUND_CLOSEST(parent_rate, rate);
/* Supported odd divide ratios are 1, 3, and 5 */
if ((div != 1) && (div != 3) && (div != 5) && (div % 2))
div = DIV_ROUND_CLOSEST(parent_rate, rate * 2) * 2;
div = clamp_t(unsigned int,
div,
HMC7044_OUT_DIV_MIN,
HMC7044_OUT_DIV_MAX);
return div;
}
/**
* Recalculate rate corresponding to a channel.
* @param dev - The device structure.
* @param chan_num - Channel number.
* @param rate - Channel rate.
* @return SUCCESS in case of success, negative error code otherwise.
*/
int32_t hmc7044_clk_recalc_rate(struct hmc7044_dev *dev, uint32_t chan_num,
uint64_t *rate)
{
int i;
struct hmc7044_chan_spec *chan = NULL;
/* Find the reqested channel number */
for (i = 0; i < dev->num_channels; i++) {
if (dev->channels[i].num == chan_num) {
chan = &dev->channels[i];
break;
}
}
if (chan == NULL )
return FAILURE;
*rate = dev->pll2_freq / chan->divider;
return SUCCESS;
}
/**
* Calculate closest possible rate
* @param dev - The device structure
* @param rate - The desired rate.
* @param rounded_rate - The closest possible rate of desired rate.
* @return SUCCESS in case of success, negative error code otherwise.
*/
int32_t hmc7044_clk_round_rate(struct hmc7044_dev *dev, uint32_t rate,
uint64_t *rounded_rate)
{
uint32_t div = hmc7044_calc_out_div(rate, dev->pll2_freq);
*rounded_rate = DIV_ROUND_CLOSEST(dev->pll2_freq, div);
return SUCCESS;
}
/**
* Set channel rate.
* @param dev - The device structure.
* @param chan_num - Channel number.
* @param rate - Channel rate.
* @return SUCCESS in case of success, negative error code otherwise.
*/
int32_t hmc7044_clk_set_rate(struct hmc7044_dev *dev, uint32_t chan_num,
uint64_t rate)
{
uint32_t div;
int32_t ret;
int i;
struct hmc7044_chan_spec *chan = NULL;
/* Find the reqested channel number */
for (i = 0; i < dev->num_channels; i++) {
if (dev->channels[i].num == chan_num) {
chan = &dev->channels[i];
break;
}
}
if (chan == NULL )
return FAILURE;
div = hmc7044_calc_out_div(rate, dev->pll2_freq);
chan->divider = div;
ret = hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_1(chan->num),
HMC7044_DIV_LSB(div));
if(ret < 0)
return ret;
return hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_2(chan->num),
HMC7044_DIV_MSB(div));
}
/**
* Setup the device.
* @param dev - The device structure.
* @return SUCCESS in case of success, negative error code otherwise.
*/
static int32_t hmc7044_setup(struct hmc7044_dev *dev)
{
struct hmc7044_chan_spec *chan;
bool high_vco_en;
bool pll2_freq_doubler_en;
uint32_t vcxo_freq, pll2_freq;
uint32_t clkin_freq[4];
uint32_t lcm_freq;
uint32_t in_prescaler[5];
uint32_t pll1_lock_detect;
uint32_t n1, r1;
uint32_t pfd1_freq;
uint32_t vco_limit;
uint32_t n2[2], r2[2];
uint32_t i, ref_en = 0;
vcxo_freq = dev->vcxo_freq / 1000;
pll2_freq = dev->pll2_freq / 1000;
lcm_freq = vcxo_freq;
for (i = 0; i < ARRAY_SIZE(clkin_freq); i++) {
if (dev->clkin_freq_ccf[i])
clkin_freq[i] = dev->clkin_freq_ccf[i] / 1000;
else
clkin_freq[i] = dev->clkin_freq[i] / 1000;
if (clkin_freq[i]) {
lcm_freq = greatest_common_divisor(clkin_freq[i], lcm_freq);
ref_en |= BIT(i);
}
}
while (lcm_freq > HMC7044_RECOMM_LCM_MAX)
lcm_freq /= 2;
for (i = 0; i < ARRAY_SIZE(clkin_freq); i++) {
if (clkin_freq[i])
in_prescaler[i] = clkin_freq[i] / lcm_freq;
else
in_prescaler[i] = 1;
}
in_prescaler[4] = vcxo_freq / lcm_freq;
pll1_lock_detect = log_base_2((lcm_freq * 4000) / dev->pll1_loop_bw);
/* fVCXO / N1 = fLCM / R1 */
rational_best_approximation(vcxo_freq, lcm_freq,
HMC7044_N1_MAX, HMC7044_R1_MAX,
&n1, &r1);
pfd1_freq = vcxo_freq / n1;
while ((pfd1_freq > HMC7044_RECOMM_FPD1) &&
(n1 <= HMC7044_N1_MAX / 2) &&
(r1 <= HMC7044_R1_MAX / 2)) {
pfd1_freq /= 2;
n1 *= 2;
r1 *= 2;
}
dev->pll1_pfd = pfd1_freq;
if (pll2_freq < HMC7044_LOW_VCO_MIN ||
pll2_freq > HMC7044_HIGH_VCO_MAX)
return FAILURE;
vco_limit = (HMC7044_LOW_VCO_MAX + HMC7044_HIGH_VCO_MIN) / 2;
if (pll2_freq >= vco_limit)
high_vco_en = true;
else
high_vco_en = false;
/* fVCO / N2 = fVCXO * doubler / R2 */
pll2_freq_doubler_en = true;
rational_best_approximation(pll2_freq, vcxo_freq * 2,
HMC7044_N2_MAX, HMC7044_R2_MAX,
&n2[0], &r2[0]);
if (pll2_freq != vcxo_freq * n2[0] / r2[0]) {
rational_best_approximation(pll2_freq, vcxo_freq,
HMC7044_N2_MAX, HMC7044_R2_MAX,
&n2[1], &r2[1]);
if (abs((int)pll2_freq - (int)(vcxo_freq * 2 * n2[0] / r2[0])) >
abs((int)pll2_freq - (int)(vcxo_freq * n2[1] / r2[1]))) {
n2[0] = n2[1];
r2[0] = r2[1];
pll2_freq_doubler_en = false;
}
}
while ((n2[0] < HMC7044_N2_MIN) && (r2[0] <= HMC7044_R2_MAX / 2)) {
n2[0] *= 2;
r2[0] *= 2;
}
if (n2[0] < HMC7044_N2_MIN)
return -FAILURE;
/* Resets all registers to default values */
hmc7044_write(dev, HMC7044_REG_SOFT_RESET, HMC7044_SOFT_RESET);
mdelay(10);
hmc7044_write(dev, HMC7044_REG_SOFT_RESET, 0);
mdelay(10);
/* Disable all channels */
for (i = 0; i < HMC7044_NUM_CHAN; i++)
hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_0(i), 0);
/* Load the configuration updates (provided by Analog Devices) */
hmc7044_write(dev, HMC7044_REG_CLK_OUT_DRV_LOW_PW, 0x4d);
hmc7044_write(dev, HMC7044_REG_CLK_OUT_DRV_HIGH_PW, 0xdf);
hmc7044_write(dev, HMC7044_REG_PLL1_DELAY, 0x06);
hmc7044_write(dev, HMC7044_REG_PLL1_HOLDOVER, 0x06);
hmc7044_write(dev, HMC7044_REG_VTUNE_PRESET, 0x04);
uint8_t rd_back;
hmc7044_read(dev, HMC7044_REG_CLK_OUT_DRV_LOW_PW, &rd_back);
hmc7044_read(dev, HMC7044_REG_CLK_OUT_DRV_HIGH_PW, &rd_back);
hmc7044_read(dev, HMC7044_REG_PLL1_DELAY, &rd_back);
hmc7044_read(dev, HMC7044_REG_PLL1_HOLDOVER, &rd_back);
hmc7044_read(dev, HMC7044_REG_VTUNE_PRESET, &rd_back);
hmc7044_write(dev, HMC7044_REG_GLOB_MODE,
HMC7044_SYNC_PIN_MODE(dev->sync_pin_mode) |
(dev->clkin0_rfsync_en ? HMC7044_RFSYNC_EN : 0) |
(dev->clkin1_vcoin_en ? HMC7044_VCOIN_MODE_EN : 0) |
HMC7044_REF_PATH_EN(ref_en));
/* Program PLL2 */
/* Select the VCO range */
hmc7044_write(dev, HMC7044_REG_EN_CTRL_0,
(dev->rf_reseeder_en ? HMC7044_RF_RESEEDER_EN : 0) |
HMC7044_VCO_SEL(high_vco_en ?
HMC7044_VCO_HIGH :
HMC7044_VCO_LOW) |
HMC7044_SYSREF_TIMER_EN | HMC7044_PLL2_EN |
HMC7044_PLL1_EN);
/* Program the dividers */
hmc7044_write(dev, HMC7044_REG_PLL2_R_LSB,
HMC7044_R2_LSB(r2[0]));
hmc7044_write(dev, HMC7044_REG_PLL2_R_MSB,
HMC7044_R2_MSB(r2[0]));
hmc7044_write(dev, HMC7044_REG_PLL2_N_LSB,
HMC7044_N2_LSB(n2[0]));
hmc7044_write(dev, HMC7044_REG_PLL2_N_MSB,
HMC7044_N2_MSB(n2[0]));
/* Program the reference doubler */
hmc7044_write(dev, HMC7044_REG_PLL2_FREQ_DOUBLER,
pll2_freq_doubler_en ? 0 : HMC7044_PLL2_FREQ_DOUBLER_DIS);
/* Program PLL1 */
/* Set the lock detect timer threshold */
hmc7044_write(dev, HMC7044_REG_PLL1_LOCK_DETECT,
HMC7044_LOCK_DETECT_TIMER(pll1_lock_detect));
/* Set the LCM */
for (i = 0; i < ARRAY_SIZE(clkin_freq); i++) {
hmc7044_write(dev, HMC7044_REG_CLKIN_PRESCALER(i),
in_prescaler[i]);
}
hmc7044_write(dev, HMC7044_REG_OSCIN_PRESCALER,
in_prescaler[4]);
/* Program the dividers */
hmc7044_write(dev, HMC7044_REG_PLL1_R_LSB,
HMC7044_R2_LSB(r1));
hmc7044_write(dev, HMC7044_REG_PLL1_R_MSB,
HMC7044_R2_MSB(r1));
hmc7044_write(dev, HMC7044_REG_PLL1_N_LSB,
HMC7044_N2_LSB(n1));
hmc7044_write(dev, HMC7044_REG_PLL1_N_MSB,
HMC7044_N2_MSB(n1));
hmc7044_write(dev, HMC7044_REG_PLL1_REF_PRIO_CTRL,
dev->pll1_ref_prio_ctrl);
/* Program the SYSREF timer */
/* Set the divide ratio */
hmc7044_write(dev, HMC7044_REG_SYSREF_TIMER_LSB,
HMC7044_SYSREF_TIMER_LSB(dev->sysref_timer_div));
hmc7044_write(dev, HMC7044_REG_SYSREF_TIMER_MSB,
HMC7044_SYSREF_TIMER_MSB(dev->sysref_timer_div));
/* Set the pulse generator mode configuration */
hmc7044_write(dev, HMC7044_REG_PULSE_GEN,
HMC7044_PULSE_GEN_MODE(dev->pulse_gen_mode));
/* Enable the input buffers */
hmc7044_write(dev, HMC7044_REG_CLKIN0_BUF_CTRL,
dev->in_buf_mode[0]);
hmc7044_write(dev, HMC7044_REG_CLKIN1_BUF_CTRL,
dev->in_buf_mode[1]);
hmc7044_write(dev, HMC7044_REG_CLKIN2_BUF_CTRL,
dev->in_buf_mode[2]);
hmc7044_write(dev, HMC7044_REG_CLKIN3_BUF_CTRL,
dev->in_buf_mode[3]);
hmc7044_write(dev, HMC7044_REG_OSCIN_BUF_CTRL,
dev->in_buf_mode[4]);
/* Set GPIOs */
for (i = 0; i < ARRAY_SIZE(dev->gpi_ctrl); i++) {
hmc7044_write(dev, HMC7044_REG_GPI_CTRL(i),
dev->gpi_ctrl[i]);
}
for (i = 0; i < ARRAY_SIZE(dev->gpo_ctrl); i++) {
hmc7044_write(dev, HMC7044_REG_GPO_CTRL(i),
dev->gpo_ctrl[i]);
}
mdelay(10);
/* Program the output channels */
for (i = 0; i < dev->num_channels; i++) {
chan = &dev->channels[i];
if (chan->num >= HMC7044_NUM_CHAN || chan->disable)
continue;
hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_1(chan->num),
HMC7044_DIV_LSB(chan->divider));
hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_2(chan->num),
HMC7044_DIV_MSB(chan->divider));
hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_8(chan->num),
HMC7044_DRIVER_MODE(chan->driver_mode) |
HMC7044_DRIVER_Z_MODE(chan->driver_impedance) |
(chan->dynamic_driver_enable ?
HMC7044_DYN_DRIVER_EN : 0) |
(chan->force_mute_enable ?
HMC7044_FORCE_MUTE_EN : 0));
hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_3(chan->num),
chan->fine_delay & 0x1F);
hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_4(chan->num),
chan->coarse_delay & 0x1F);
hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_7(chan->num),
chan->out_mux_mode & 0x3);
hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_0(chan->num),
(chan->start_up_mode_dynamic_enable ?
HMC7044_START_UP_MODE_DYN_EN : 0) |
(chan->output_control0_rb4_enable ? BIT(4) : 0) |
(chan->high_performance_mode_dis ?
0 : HMC7044_HI_PERF_MODE) | HMC7044_SYNC_EN |
HMC7044_CH_EN);
}
mdelay(10);
/* Do a restart to reset the system and initiate calibration */
hmc7044_write(dev, HMC7044_REG_REQ_MODE_0,
HMC7044_RESTART_DIV_FSM);
mdelay(1);
hmc7044_write(dev, HMC7044_REG_REQ_MODE_0,
(dev->high_performance_mode_clock_dist_en ?
HMC7044_HIGH_PERF_DISTRIB_PATH : 0));
mdelay(1);
return SUCCESS;
}
/**
* Setup the device.
* @param dev - The device structure.
* @return SUCCESS in case of success, negative error code otherwise.
*/
static int32_t hmc7043_setup(struct hmc7044_dev *dev)
{
struct hmc7044_chan_spec *chan;
uint32_t i;
if (dev->clkin_freq_ccf[0])
dev->pll2_freq = dev->clkin_freq_ccf[0];
else
dev->pll2_freq = dev->clkin_freq[0];
if (!dev->pll2_freq) {
printf("%s: Failed to get valid parent rate\n", __func__);
return FAILURE;
}
/* Resets all registers to default values */
hmc7044_write(dev, HMC7044_REG_SOFT_RESET, HMC7044_SOFT_RESET);
mdelay(10);
hmc7044_write(dev, HMC7044_REG_SOFT_RESET, 0);
mdelay(10);
/* Load the configuration updates (provided by Analog Devices) */
hmc7044_write(dev, HMC7044_REG_CLK_OUT_DRV_LOW_PW, 0x4d);
hmc7044_write(dev, HMC7044_REG_CLK_OUT_DRV_HIGH_PW, 0xdf);
/* Disable all channels */
for (i = 0; i < HMC7044_NUM_CHAN; i++)
hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_0(i), 0);
if (dev->pll2_freq < 1000000000U)
hmc7044_write(dev, HMC7044_CLK_INPUT_CTRL,
HMC7044_LOW_FREQ_INPUT_MODE);
hmc7044_write(dev, HMC7044_REG_EN_CTRL_0,
(dev->rf_reseeder_en ? HMC7044_RF_RESEEDER_EN : 0) |
HMC7044_SYSREF_TIMER_EN);
/* Program the SYSREF timer */
/* Set the divide ratio */
hmc7044_write(dev, HMC7044_REG_SYSREF_TIMER_LSB,
HMC7044_SYSREF_TIMER_LSB(dev->sysref_timer_div));
hmc7044_write(dev, HMC7044_REG_SYSREF_TIMER_MSB,
HMC7044_SYSREF_TIMER_MSB(dev->sysref_timer_div));
/* Set the pulse generator mode configuration */
hmc7044_write(dev, HMC7044_REG_PULSE_GEN,
HMC7044_PULSE_GEN_MODE(dev->pulse_gen_mode));
/* Enable the input buffers */
hmc7044_write(dev, HMC7044_REG_CLKIN0_BUF_CTRL,
dev->in_buf_mode[0]);
hmc7044_write(dev, HMC7044_REG_CLKIN1_BUF_CTRL,
dev->in_buf_mode[1]);
/* Set GPIOs */
hmc7044_write(dev, HMC7044_REG_GPI_CTRL(0),
dev->gpi_ctrl[0]);
hmc7044_write(dev, HMC7044_REG_GPO_CTRL(0),
dev->gpo_ctrl[0]);
/* Program the output channels */
for (i = 0; i < dev->num_channels; i++) {
chan = &dev->channels[i];
if (chan->num >= HMC7044_NUM_CHAN || chan->disable)
continue;
hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_1(chan->num),
HMC7044_DIV_LSB(chan->divider));
hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_2(chan->num),
HMC7044_DIV_MSB(chan->divider));
hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_8(chan->num),
HMC7044_DRIVER_MODE(chan->driver_mode) |
HMC7044_DRIVER_Z_MODE(chan->driver_impedance) |
(chan->dynamic_driver_enable ?
HMC7044_DYN_DRIVER_EN : 0) |
(chan->force_mute_enable ?
HMC7044_FORCE_MUTE_EN : 0));
hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_3(chan->num),
chan->fine_delay & 0x1F);
hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_4(chan->num),
chan->coarse_delay & 0x1F);
hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_7(chan->num),
chan->out_mux_mode & 0x3);
hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_0(chan->num),
(chan->start_up_mode_dynamic_enable ?
HMC7044_START_UP_MODE_DYN_EN : 0) |
(chan->output_control0_rb4_enable ? BIT(4) : 0) |
(chan->high_performance_mode_dis ?
0 : HMC7044_HI_PERF_MODE) | HMC7044_SYNC_EN |
HMC7044_CH_EN);
}
mdelay(10);
/* Do a restart to reset the system and initiate calibration */
hmc7044_write(dev, HMC7044_REG_REQ_MODE_0,
HMC7044_RESTART_DIV_FSM);
mdelay(1);
hmc7044_write(dev, HMC7044_REG_REQ_MODE_0,
(dev->high_performance_mode_clock_dist_en ?
HMC7044_HIGH_PERF_DISTRIB_PATH : 0));
mdelay(1);
return SUCCESS;
}
/***************************************************************************//**
* @brief hmc7044_reg_init
*******************************************************************************/
int32_t hmc7044_reg_init(struct hmc7044_dev **device,
const struct hmc7044_init_param *init_param)
{
int ret = SUCCESS;
struct hmc7044_dev *dev;
dev = (struct hmc7044_dev *)malloc(sizeof(*dev));
if (!dev)
return FAILURE;
/* SPI */
ret = spi_init(&dev->spi_desc, init_param->spi_init);
*device = dev;
return ret;
}
/**
* Initialize the device.
* @param device - The device structure.
* @param init_param - The structure that contains the device initial
* parameters.
* @return SUCCESS in case of success, negative error code otherwise.
*/
int32_t hmc7044_init(struct hmc7044_dev **device,
const struct hmc7044_init_param *init_param)
{
struct hmc7044_dev *dev;
int32_t ret;
unsigned int i;
dev = (struct hmc7044_dev *)malloc(sizeof(*dev));
if (!dev)
return FAILURE;
ret = spi_init(&dev->spi_desc, init_param->spi_init);
if (ret < 0)
return ret;
dev->is_hmc7043 = init_param->is_hmc7043;
dev->clkin_freq[0] = init_param->clkin_freq[0];
dev->clkin_freq[1] = init_param->clkin_freq[1];
dev->clkin_freq[2] = init_param->clkin_freq[2];
dev->clkin_freq[3] = init_param->clkin_freq[3];
dev->clkin_freq_ccf[0] = init_param->clkin_freq_ccf[0];
dev->clkin_freq_ccf[1] = init_param->clkin_freq_ccf[1];
dev->clkin_freq_ccf[2] = init_param->clkin_freq_ccf[2];
dev->clkin_freq_ccf[3] = init_param->clkin_freq_ccf[3];
dev->vcxo_freq = init_param->vcxo_freq;
dev->pll1_pfd = init_param->pll1_pfd;
dev->pll2_freq = init_param->pll2_freq;
dev->pll1_loop_bw = init_param->pll1_loop_bw;
dev->sysref_timer_div = init_param->sysref_timer_div;
dev->pll1_ref_prio_ctrl = init_param->pll1_ref_prio_ctrl;
dev->clkin0_rfsync_en = init_param->clkin0_rfsync_en;
dev->clkin1_vcoin_en = init_param->clkin1_vcoin_en;
dev->high_performance_mode_clock_dist_en =
init_param->high_performance_mode_clock_dist_en;
dev->rf_reseeder_en = !init_param->rf_reseeder_disable;
dev->sync_pin_mode = init_param->sync_pin_mode;
dev->pulse_gen_mode = init_param->pulse_gen_mode;
dev->in_buf_mode[0] = init_param->in_buf_mode[0];
dev->in_buf_mode[1] = init_param->in_buf_mode[1];
dev->in_buf_mode[2] = init_param->in_buf_mode[2];
dev->in_buf_mode[3] = init_param->in_buf_mode[3];
dev->in_buf_mode[4] = init_param->in_buf_mode[4];
dev->gpi_ctrl[0] = init_param->gpi_ctrl[0];
dev->gpi_ctrl[1] = init_param->gpi_ctrl[1];
dev->gpi_ctrl[2] = init_param->gpi_ctrl[2];
dev->gpi_ctrl[3] = init_param->gpi_ctrl[3];
dev->gpo_ctrl[0] = init_param->gpo_ctrl[0];
dev->gpo_ctrl[1] = init_param->gpo_ctrl[1];
dev->gpo_ctrl[2] = init_param->gpo_ctrl[2];
dev->gpo_ctrl[3] = init_param->gpo_ctrl[3];
dev->num_channels = init_param->num_channels;
dev->channels = (struct hmc7044_chan_spec *)
malloc(sizeof(*dev->channels) * dev->num_channels);
for (i = 0; i < dev->num_channels; i++) {
dev->channels[i].num = init_param->channels[i].num;
dev->channels[i].disable = init_param->channels[i].disable;
dev->channels[i].divider = init_param->channels[i].divider;
dev->channels[i].driver_mode =
init_param->channels[i].driver_mode;
dev->channels[i].high_performance_mode_dis =
init_param->channels[i].high_performance_mode_dis;
dev->channels[i].start_up_mode_dynamic_enable =
init_param->channels[i].start_up_mode_dynamic_enable;
dev->channels[i].dynamic_driver_enable =
init_param->channels[i].dynamic_driver_enable;
dev->channels[i].output_control0_rb4_enable =
init_param->channels[i].output_control0_rb4_enable;
dev->channels[i].force_mute_enable =
init_param->channels[i].force_mute_enable;
dev->channels[i].driver_impedance =
init_param->channels[i].driver_impedance;
dev->channels[i].coarse_delay =
init_param->channels[i].coarse_delay;
dev->channels[i].fine_delay =
init_param->channels[i].fine_delay;
dev->channels[i].out_mux_mode =
init_param->channels[i].out_mux_mode;
}
*device = dev;
if (!dev->is_hmc7043)
return hmc7044_setup(dev);
else
return hmc7043_setup(dev);
}
/**
* Remove the device - release resources.
* @param device - The device structure.
* @return SUCCESS in case of success, negative error code otherwise.
*/
int32_t hmc7044_remove(struct hmc7044_dev *device)
{
int32_t ret;
ret = spi_remove(device->spi_desc);
free(device->channels);
free(device);
return ret;
}
-276
View File
@@ -1,276 +0,0 @@
/***************************************************************************//**
* @file hmc7044.h
* @brief Header file of HMC7044, HMC7043 Driver.
* @author DBogdan ([email protected])
********************************************************************************
* Copyright 2018-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 HMC7044_H_
#define HMC7044_H_
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <stdbool.h>
#include <stdint.h>
#include "delay.h"
#include "spi.h"
/******************************************************************************/
/*************************** Types Declarations *******************************/
/******************************************************************************/
// Enum to select SYNC pin configuration with respect to PLL2 (0x0005)
typedef enum
{
SYNC_DISABLED = 0,
SYNC_MULTICHIP = 1,
SYNC_PULSE_GEN = 2,
SYNC_ALARM = 3
} hmc7044SyncPinModeSelect_t;
// Enum to select input buffer mode (0x000A, 0x000B, 0x000C, 0x000D, 0x000E)
typedef enum
{
BUFFER_ENABLE = (1) << 0,
BUFFER_DISABLE = (0) << 0,
ENABLE_INTERNAL_TERM = (1) << 1,
ENABLE_AC_COUPLE = (1) << 2,
ENABLE_LVPECL = (1) << 3,
ENABLE_HIGH_Z = (1) << 4
} hmc7044InputBufferMode_t;
// Enum to select output driver mode (0x003A, 0x003B, 0x00D0, 0x00DA, 0x00E4,
// 0x00EE, 0x00F8, 0x0102, 0x010C, 0x0116, 0x0120, 0x012A, 0x0134, 0x013E,
// 0x0148, 0x0152)
typedef enum
{
CML = 0,
LVPECL = 1,
LVDS = 2,
CMOS = 3
} hmc7044DriverMode_t;
// Enum to select the GPIx functionality. (0x0046, 0x0047, 0x0048, 0x0049)
typedef enum
{
GPI_ENABLE = (1) << 0,
GPI_DISABLE = (0) << 0,
FORCE_PLL1_HOLDOVER = (0x01) << 1 | GPI_ENABLE,
SELECT_PLL1_REF_BIT1 = (0x02) << 1 | GPI_ENABLE,
SELECT_PLL1_REF_BIT2 = (0x03) << 1 | GPI_ENABLE,
CHIP_SLEEP_MODE = (0x04) << 1 | GPI_ENABLE,
MUTE_REQUSET = (0x05) << 1 | GPI_ENABLE,
SELECT_INTERNAL_VCO_TYPE = (0x06) << 1 | GPI_ENABLE,
SELECT_HI_PERF_MODE = (0x07) << 1 | GPI_ENABLE,
PULSE_GEN_REQUSET = (0x08) << 1 | GPI_ENABLE,
RESEED_REQUEST = (0x09) << 1 | GPI_ENABLE,
RESTART_REQUSET = (0x0A) << 1 | GPI_ENABLE,
FORCE_FANOUT_MODE = (0x0B) << 1 | GPI_ENABLE,
SLIP_REQUEST = (0x0D) << 1 | GPI_ENABLE,
} hmc7044GPIControl_t;
// Enum to select the GPOx functionality. (0x0050, 0x0051, 0x0052, 0x0053)
typedef enum
{
GPO_ENABLE = (1) << 0,
GPO_DISABLE = (0) << 0,
GPO_CMOS_MODE = (1) << 1,
GPO_OPEN_DRAIN_MODE = (0) << 1,
ALARM_SIGNAL = (0x00) << 3 | GPO_ENABLE,
SPI_SDATA = (0x01) << 3 | GPO_ENABLE,
CLKIN3_SIGNAL_LOSS = (0x02) << 3 | GPO_ENABLE,
CLKIN2_SIGNAL_LOSS = (0x03) << 3 | GPO_ENABLE,
CLKIN1_SIGNAL_LOSS = (0x04) << 3 | GPO_ENABLE,
CLKIN0_SIGNAL_LOSS = (0x05) << 3 | GPO_ENABLE,
PLL1_HOLDOVER_ENABLE = (0x06) << 3 | GPO_ENABLE,
PLL1_LOCK_DETECT = (0x07) << 3 | GPO_ENABLE,
PLL1_ACQUIRING_LOCK = (0x08) << 3 | GPO_ENABLE,
PLL1_NEAR_CLOCK_ACQ_STAT = (0x09) << 3 | GPO_ENABLE,
PLL2_LOCK_DETECT = (0x0A) << 3 | GPO_ENABLE,
PLL2_SYSREF_SYNC = (0x0B) << 3 | GPO_ENABLE,
CLOCK_OUTPUT_PHASE_STAT = (0x0C) << 3 | GPO_ENABLE,
PLL1_PLL2_LOCKED = (0x0D) << 3 | GPO_ENABLE,
SYNC_REQUSRT_STAT = (0x0E) << 3 | GPO_ENABLE,
PLL1_ACTIVE_CLKIN0 = (0x0F) << 3 | GPO_ENABLE,
PLL1_ACTIVE_CLKIN1 = (0x10) << 3 | GPO_ENABLE,
PLL1_HOLDOVER_IN_RANGE_STAT = (0x11) << 3 | GPO_ENABLE,
PLL1_HOLDOVER_IN_STAT = (0x12) << 3 | GPO_ENABLE,
PLL1_VCXO_STAT = (0x13) << 3 | GPO_ENABLE,
PLL1_ACTIVE_CLKINx_STAT = (0x14) << 3 | GPO_ENABLE,
PLL1_FSM_BIT0 = (0x15) << 3 | GPO_ENABLE,
PLL1_FSM_BIT1 = (0x16) << 3 | GPO_ENABLE,
PLL1_FSM_BIT2 = (0x17) << 3 | GPO_ENABLE,
PLL1_HOLDOVER_EXIT_PHASE_BIT0 = (0x18) << 3 | GPO_ENABLE,
PLL1_HOLDOVER_EXIT_PHASE_BIT1 = (0x19) << 3 | GPO_ENABLE,
CHANNEL_OUTPUT_FSM_BUSY = (0x1A) << 3 | GPO_ENABLE,
SYSREF_FSM_STAT_BIT0 = (0x1B) << 3 | GPO_ENABLE,
SYSREF_FSM_STAT_BIT1 = (0x1C) << 3 | GPO_ENABLE,
SYSREF_FSM_STAT_BIT2 = (0x1D) << 3 | GPO_ENABLE,
SYSREF_FSM_STAT_BIT3 = (0x1E) << 3 | GPO_ENABLE,
FORCE_LOGIC_1 = (0x1F) << 3 | GPO_ENABLE,
FORCE_LOGIC_0 = (0x20) << 3 | GPO_ENABLE,
PLL1_HOLDOVER_AVG_VALUE_BIT0 = (0x27) << 3 | GPO_ENABLE,
PLL1_HOLDOVER_AVG_VALUE_BIT1 = (0x28) << 3 | GPO_ENABLE,
PLL1_HOLDOVER_AVG_VALUE_BIT2 = (0x29) << 3 | GPO_ENABLE,
PLL1_HOLDOVER_AVG_VALUE_BIT3 = (0x2A) << 3 | GPO_ENABLE,
PLL1_HOLDOVER_CURR_VALUE_BIT0 = (0x2B) << 3 | GPO_ENABLE,
PLL1_HOLDOVER_CURR_VALUE_BIT1 = (0x2C) << 3 | GPO_ENABLE,
PLL1_HOLDOVER_CURR_VALUE_BIT2 = (0x2D) << 3 | GPO_ENABLE,
PLL1_HOLDOVER_CURR_VALUE_BIT3 = (0x2E) << 3 | GPO_ENABLE
} hmc7044GPOControl_t;
// Enum to select output channel (0x00CF, 0x00D9, 0x00E3, 0x00ED, 0x00F7,
// 0x0101, 0x010B, 0x0115, 0x011F, 0x0129, 0x0133, 0x013D, 0x0147, 0x0151
typedef enum
{
CHANNEL_DIV = 0,
ANALOG_DELAY = 1,
OTHER_CHANNEL = 2,
VCO_CLOCK = 3
} hmc7044OutputMuxSelect_t;
// Enum to select output driver impedance selection for CML mode (0x00D0,
// 0x00DA, 0x00E4, 0x00EE, 0x00F8, 0x0102, 0x010C, 0x0116, 0x0120, 0x012A,
// 0x0134, 0x013E, 0x0148, 0x0152)
typedef enum
{
INTERNAL_RES_DISABLE = 0,
INTERNAL_100OHM_PER_PIN = 1,
// INTERNAL_RES_RESERVED = 2,
INTERNAL_50OHM_PER_PIN = 3
} hmc7044DriverImpedance_t;
// Enum to select pulse generator mode (0x005A)
typedef enum
{
PULSE_LEVEL_SENSITIVE = 0,
PULSE_ONE = 1,
PULSE_TWO = 2,
PULSE_FOUR = 3,
PULSE_EIGHT = 4,
PULSE_SIXTEEN = 5,
// PULSE_SIXTEEN = 6,
PULSE_CONTINOUS = 7
} hmc7044SyncPulseGenControl_t;
struct hmc7044_chan_spec {
unsigned int num;
bool disable;
bool high_performance_mode_dis;
bool start_up_mode_dynamic_enable;
bool dynamic_driver_enable;
bool output_control0_rb4_enable;
bool force_mute_enable;
unsigned int divider;
unsigned int coarse_delay;
unsigned int fine_delay;
hmc7044DriverMode_t driver_mode;
hmc7044DriverImpedance_t driver_impedance;
hmc7044OutputMuxSelect_t out_mux_mode;
};
struct hmc7044_config {
uint16_t addr;
uint8_t value;
};
struct hmc7044_dev {
struct spi_desc *spi_desc;
bool is_hmc7043;
uint32_t clkin_freq[4];
uint32_t clkin_freq_ccf[4];
uint32_t vcxo_freq;
uint32_t pll1_pfd;
uint32_t pll2_freq;
uint32_t pll1_loop_bw;
uint32_t sysref_timer_div;
unsigned int pll1_ref_prio_ctrl;
bool clkin0_rfsync_en;
bool clkin1_vcoin_en;
bool high_performance_mode_clock_dist_en;
bool rf_reseeder_en;
hmc7044SyncPinModeSelect_t sync_pin_mode;
hmc7044SyncPulseGenControl_t pulse_gen_mode;
uint32_t in_buf_mode[5];
uint32_t gpi_ctrl[4];
uint32_t gpo_ctrl[4];
uint32_t num_channels;
struct hmc7044_chan_spec *channels;
};
struct hmc7044_init_param {
struct spi_init_param *spi_init;
bool is_hmc7043;
uint32_t clkin_freq[4];
uint32_t clkin_freq_ccf[4];
uint32_t vcxo_freq;
uint32_t pll1_pfd;
uint32_t pll2_freq;
uint32_t pll1_loop_bw;
uint32_t sysref_timer_div;
unsigned int pll1_ref_prio_ctrl;
bool clkin0_rfsync_en;
bool clkin1_vcoin_en;
bool high_performance_mode_clock_dist_en;
bool rf_reseeder_disable;
hmc7044SyncPinModeSelect_t sync_pin_mode;
hmc7044SyncPulseGenControl_t pulse_gen_mode;
uint32_t in_buf_mode[5];
uint32_t gpi_ctrl[4];
uint32_t gpo_ctrl[4];
uint32_t num_channels;
struct hmc7044_chan_spec *channels;
};
/******************************************************************************/
/************************ Functions Declarations ******************************/
/******************************************************************************/
/* Initialize the device. */
int32_t hmc7044_reg_init(struct hmc7044_dev **device,
const struct hmc7044_init_param *init_param);
int32_t hmc7044_init(struct hmc7044_dev **device,
const struct hmc7044_init_param *init_param);
/* Remove the device. */
int32_t hmc7044_remove(struct hmc7044_dev *device);
int32_t hmc7044_write(struct hmc7044_dev *dev,
uint16_t reg, uint8_t val);
int32_t hmc7044_read(struct hmc7044_dev *dev, uint16_t reg, uint8_t *val);
int32_t hmc7044_clk_recalc_rate(struct hmc7044_dev *dev, uint32_t chan_num,
uint64_t *rate);
int32_t hmc7044_clk_round_rate(struct hmc7044_dev *dev, uint32_t rate,
uint64_t *rounded_rate);
int32_t hmc7044_clk_set_rate(struct hmc7044_dev *dev, uint32_t chan_num,
uint64_t rate);
#endif // HMC7044_H_
-464
View File
@@ -1,464 +0,0 @@
/***************************************************************************//**
* @file xilinx/xilinx_gpio.c
* @brief Implementation of Xilinx GPIO Generic Driver.
* @author Antoniu Miclaus ([email protected])
********************************************************************************
* Copyright 2019(c) Analog Devices, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* - Neither the name of Analog Devices, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* - The use of this software may or may not infringe the patent rights
* of one or more patent holders. This license does not release you
* from the requirement that you obtain separate licenses from these
* patent holders to use this software.
* - Use of the software either in source or binary form, must be run
* on or directly connected to an Analog Devices Inc. component.
*
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <stdlib.h>
#include <xparameters.h>
#ifdef XPAR_XGPIO_NUM_INSTANCES
#include <xgpio.h>
#endif
#ifdef XPAR_XGPIOPS_NUM_INSTANCES
#include <xgpiops.h>
#endif
#include "error.h"
#include "gpio.h"
#include "xilinx_gpio.h"
/******************************************************************************/
/************************ Functions Definitions *******************************/
/******************************************************************************/
/**
* @brief Prepare the GPIO decriptor.
* @param desc - The GPIO descriptor.
* @param param - The structure that contains the GPIO parameters.
* @return 0 in case of success, -1 otherwise.
*/
int32_t _gpio_init(struct gpio_desc *desc,
const struct gpio_init_param *param)
{
int32_t ret;
struct xil_gpio_desc *xdesc;
struct xil_gpio_init_param *xinit;
ret = -1;
xdesc = desc->extra;
xinit = param->extra;
xdesc->type = xinit->type;
desc->number = param->number;
switch (xinit->type) {
case GPIO_PL:
#ifdef XGPIO_H
xdesc->instance = (XGpio *)malloc(sizeof(XGpio));
if(!xdesc->instance)
goto pl_error;
xdesc->config = XGpio_LookupConfig(xinit->device_id);
if(xdesc->config == NULL)
goto pl_error;
ret = XGpio_CfgInitialize(xdesc->instance,
xdesc->config,
((XGpio_Config*)xdesc->config)
->BaseAddress);
if(ret < 0)
goto pl_error;
break;
pl_error:
free(xdesc->instance);
#endif
goto error;
case GPIO_PS:
#ifdef XGPIOPS_H
xdesc->instance = (XGpioPs *)malloc(sizeof(XGpioPs));
if(!xdesc->instance)
goto ps_error;
xdesc->config = XGpioPs_LookupConfig(xinit->device_id);
if(xdesc->config == NULL)
goto ps_error;
ret = XGpioPs_CfgInitialize(xdesc->instance,
xdesc->config,
((XGpioPs_Config*)xdesc->config)->BaseAddr);
if(ret < 0)
goto ps_error;
break;
ps_error:
free(xdesc->instance);
#endif
goto error;
error:
default:
return -1;
}
return 0;
}
/**
* @brief Obtain the GPIO decriptor.
* @param desc - The GPIO descriptor.
* @param param - GPIO initialization parameters
* @return 0 in case of success, -1 otherwise.
*/
int32_t xil_gpio_get(struct gpio_desc **desc,
const struct gpio_init_param *param)
{
struct gpio_desc *descriptor;
struct xil_gpio_desc *extra;
int32_t ret;
descriptor = (struct gpio_desc *)malloc(sizeof(*descriptor));
extra = (struct xil_gpio_desc*)malloc(sizeof(*extra));
if (!descriptor || !extra)
return -1;
descriptor->extra = extra;
ret = _gpio_init(descriptor, param);
if(ret != 0)
goto error;
*desc = descriptor;
return 0;
error:
free(extra);
free(descriptor);
return -1;
}
/**
* @brief Get the value of an optional GPIO.
* @param desc - The GPIO descriptor.
* @param param - GPIO Initialization parameters.
* @return 0 in case of success, -1 otherwise.
*/
int32_t xil_gpio_get_optional(struct gpio_desc **desc,
const struct gpio_init_param *param)
{
if(param == NULL) {
*desc = NULL;
return 0;
}
return xil_gpio_get(desc, param);
}
/**
* @brief Free the resources allocated by gpio_get().
* @param desc - The GPIO descriptor.
* @return 0 in case of success, -1 otherwise.
*/
int32_t xil_gpio_remove(struct gpio_desc *desc)
{
if (desc != NULL) {
free(((struct xil_gpio_desc *)(desc->extra))->instance);
free(desc->extra);
free(desc);
}
return 0;
}
/**
* @brief Enable the input direction of the specified GPIO.
* @param desc - The GPIO descriptor.
* @return 0 in case of success, -1 otherwise.
*/
int32_t xil_gpio_direction_input(struct gpio_desc *desc)
{
struct xil_gpio_desc *extra;
#ifdef XGPIO_H
uint8_t pin = desc->number;
uint32_t channel = 1;
uint32_t config = 0;
#endif
extra = desc->extra;
switch (extra->type) {
case GPIO_PL:
#ifdef XGPIO_H
/* We assume that pin 32 is the first pin from channel 2 */
if (pin >= 32) {
channel = 2;
pin -= 32;
}
config = XGpio_GetDataDirection((XGpio *)extra->instance,
channel);
config |= (1 << pin);
XGpio_SetDataDirection((XGpio *)extra->instance,
channel,
config);
#endif
break;
case GPIO_PS:
#ifdef XGPIOPS_H
XGpioPs_SetDirectionPin(extra->instance,
desc->number,
GPIO_IN);
#endif
break;
default:
return -1;
}
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 0 in case of success, -1 otherwise.
*/
int32_t xil_gpio_direction_output(struct gpio_desc *desc,
uint8_t value)
{
struct xil_gpio_desc *extra;
#ifdef XGPIO_H
uint8_t pin = desc->number;
uint8_t channel;
uint32_t reg_val;
#endif
extra = desc->extra;
switch (extra->type) {
case GPIO_PL:
#ifdef XGPIO_H
if (pin >= 32) {
channel = 2;
pin -= 32;
} else
channel = 1;
reg_val = XGpio_GetDataDirection(extra->instance,
channel);
reg_val &= ~(1 << pin);
XGpio_SetDataDirection(extra->instance,
channel,
reg_val);
reg_val = XGpio_DiscreteRead(extra->instance,
channel);
if(value)
reg_val |= (1 << pin);
else
reg_val &= ~(1 << pin);
XGpio_DiscreteWrite(extra->instance,
channel,
reg_val);
#endif
break;
case GPIO_PS:
#ifdef XGPIOPS_H
XGpioPs_SetDirectionPin(extra->instance,
desc->number,
GPIO_OUT);
XGpioPs_SetOutputEnablePin(extra->instance,
desc->number,
GPIO_OUT);
XGpioPs_WritePin(extra->instance,
desc->number,
value);
#endif
break;
default:
return -1;
}
return 0;
}
/**
* @brief Get the direction of the specified GPIO.
* @param desc - The GPIO descriptor.
* @param direction - The direction.
* Example: GPIO_OUT
* GPIO_IN
* @return 0 in case of success, -1 otherwise.
*/
int32_t xil_gpio_get_direction(struct gpio_desc *desc,
uint8_t *direction)
{
if (!desc)
return -1;
struct xil_gpio_desc *extra;
uint8_t pin = desc->number;
#ifdef XGPIO_H
uint8_t channel;
#endif
extra = desc->extra;
switch (extra->type) {
case GPIO_PL:
#ifdef XGPIO_H
if (pin >= 32) {
channel = 2;
pin -= 32;
} else
channel = 1;
*direction = ((XGpio_GetDataDirection(extra->instance,
channel) >> pin) & 0x1) ^ 0x1;
#endif
break;
case GPIO_PS:
#ifdef XGPIOPS_H
*direction = XGpioPs_GetDirectionPin(extra->instance, pin);
#endif
break;
default:
return -1;
}
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 0 in case of success, -1 otherwise.
*/
int32_t xil_gpio_set_value(struct gpio_desc *desc,
uint8_t value)
{
struct xil_gpio_desc *extra;
#ifdef XGPIO_H
uint8_t pin = desc->number;
uint8_t channel;
uint32_t reg_val;
#endif
extra = desc->extra;
switch (extra->type) {
case GPIO_PL:
#ifdef XGPIO_H
if (pin >= 32) {
channel = 2;
pin -= 32;
} else
channel = 1;
reg_val = XGpio_DiscreteRead(extra->instance, channel);
if(value)
reg_val |= (1 << pin);
else
reg_val &= ~(1 << pin);
XGpio_DiscreteWrite(extra->instance, channel, reg_val);
#endif
break;
case GPIO_PS:
#ifdef XGPIOPS_H
XGpioPs_WritePin(extra->instance, desc->number, value);
#endif
break;
default:
return -1;
}
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 0 in case of success, -1 otherwise.
*/
int32_t xil_gpio_get_value(struct gpio_desc *desc,
uint8_t *value)
{
if (!desc)
return -1;
struct xil_gpio_desc *extra;
uint8_t pin = desc->number;
#ifdef XGPIO_H
uint8_t channel;
#endif
extra = desc->extra;
switch (extra->type) {
case GPIO_PL:
#ifdef XGPIO_H
if (pin >= 32) {
channel = 2;
pin -= 32;
} else
channel = 1;
*value = (XGpio_DiscreteRead(extra->instance, channel) >> pin) & 0x01;
#endif
break;
case GPIO_PS:
#ifdef XGPIOPS_H
*value = XGpioPs_ReadPin(extra->instance, pin);
#endif
break;
default:
return -1;
}
return 0;
}
/**
* @brief Xilinx platform specific GPIO platform ops structure
*/
const struct gpio_platform_ops xil_gpio_ops = {
.gpio_ops_get = &xil_gpio_get,
.gpio_ops_get_optional = &xil_gpio_get_optional,
.gpio_ops_remove = &xil_gpio_remove,
.gpio_ops_direction_input = &xil_gpio_direction_input,
.gpio_ops_direction_output = &xil_gpio_direction_output,
.gpio_ops_get_direction = &xil_gpio_get_direction,
.gpio_ops_set_value = &xil_gpio_set_value,
.gpio_ops_get_value = &xil_gpio_get_value,
};
-95
View File
@@ -1,95 +0,0 @@
/*******************************************************************************
* @file xilinx/xilinx_gpio.h
* @brief Header containing extra types used in the gpio driver
* @author scuciurean ([email protected])
********************************************************************************
* Copyright 2019(c) Analog Devices, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* - Neither the name of Analog Devices, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* - The use of this software may or may not infringe the patent rights
* of one or more patent holders. This license does not release you
* from the requirement that you obtain separate licenses from these
* patent holders to use this software.
* - Use of the software either in source or binary form, must be run
* on or directly connected to an Analog Devices Inc. component.
*
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#ifndef XILINX_GPIO_H_
#define XILINX_GPIO_H_
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <stdint.h>
#include <stdbool.h>
/******************************************************************************/
/*************************** Types Declarations *******************************/
/******************************************************************************/
/**
* @enum xil_gpio_type
* @brief Xilinx platform architecture sections
*/
enum xil_gpio_type {
/** Programmable Logic */
GPIO_PL,
/** Processing System */
GPIO_PS
};
/**
* @struct xil_gpio_init_param
* @brief Structure holding the initialization parameters for Xilinx platform
* specific GPIO parameters.
*/
struct xil_gpio_init_param {
/** Xilinx architecture */
enum xil_gpio_type type;
/** Device ID */
uint32_t device_id;
};
/**
* @struct xil_gpio_desc
* @brief Xilinx platform specific GPIO descriptor
*/
struct xil_gpio_desc {
/** Xilinx architecture */
enum xil_gpio_type type;
/** Xilinx GPIO configuration */
void *config;
/** Xilinx GPIO Instance */
void *instance;
};
/**
* @brief Xilinx platform specific gpio platform ops structure
*/
extern const struct gpio_platform_ops xil_gpio_ops;
#endif
-360
View File
@@ -1,360 +0,0 @@
/***************************************************************************//**
* @file xilinx/xilinx_gpio_irq.c
* @brief Implementation of Xilinx GPIO IRQ Generic Driver.
* @author Porumb Andrei ([email protected])
********************************************************************************
* Copyright 2021(c) Analog Devices, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* - Neither the name of Analog Devices, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* - The use of this software may or may not infringe the patent rights
* of one or more patent holders. This license does not release you
* from the requirement that you obtain separate licenses from these
* patent holders to use this software.
* - Use of the software either in source or binary form, must be run
* on or directly connected to an Analog Devices Inc. component.
*
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <stdlib.h>
#include "xparameters.h"
#include "error.h"
#include "xilinx_gpio_irq.h"
#include "util.h"
#include "list.h"
#include "irq.h"
/******************************************************************************/
/************************ Functions Definitions *******************************/
/******************************************************************************/
/**
* @brief Comparing function used by list.
* @param desc_a - Compared item
* @param desc_b - Reference item
* @return - 0 if items match
*/
static int32_t call_cmp(struct xil_callback_desc *desc_a,
struct xil_callback_desc *desc_b)
{
return desc_a->pin_nb - desc_b->pin_nb;
}
/**
* @brief Function called when GPIO IRQ occurs.
* @param param - GPIO IRQ desc's extra field
* @return - None.
*/
static void xil_gpio_irq_handler(struct xil_gpio_irq_desc *param)
{
int32_t status = 0;
int32_t pin_nb;
struct xil_callback_desc *callback_desc;
status = iterator_move_to_idx(param->it, 0);
while(!status) {
iterator_read(param->it, &callback_desc);
status = iterator_move(param->it, 1);
if(XGpioPs_IntrGetStatusPin(&param->my_Gpio, callback_desc->pin_nb))
callback_desc->triggered = true;
}
status = iterator_move_to_idx(param->it, 0);
while(!status) {
iterator_read(param->it, &callback_desc);
status = iterator_move(param->it, 1);
if(callback_desc->triggered == true) {
callback_desc->triggered = false;
XGpioPs_IntrDisablePin(&param->my_Gpio, callback_desc->pin_nb);
XGpioPs_IntrClearPin(&param->my_Gpio, callback_desc->pin_nb);
callback_desc->callback.legacy_callback(callback_desc->callback.ctx, 0U, NULL);
if(callback_desc->enabled)
XGpioPs_IntrEnablePin(&param->my_Gpio, callback_desc->pin_nb);
}
}
}
/**
* @brief Disable specific GPIO IRQ pin.
* @param desc - The GPIO IRQ controller descriptor.
* @param irq_id - Pin number.
* @return 0 in case of success, -1 otherwise.
*/
int32_t xil_gpio_irq_disable(struct irq_ctrl_desc *desc, uint32_t irq_id)
{
int32_t status;
struct xil_gpio_irq_desc *extra;
struct xil_callback_desc *callback_desc;
extra = desc->extra;
status = iterator_move_to_idx(extra->it, 0);
while(!status) {
iterator_read(extra->it, &callback_desc);
status = iterator_move(extra->it, 1);
if(callback_desc->pin_nb == irq_id) {
callback_desc->enabled = false;
break;
}
}
XGpioPs_IntrDisablePin(&extra->my_Gpio, irq_id);
return 0;
}
/**
* @brief Initialize the GPIO IRQ controller.
* @param desc - The GPIO IRQ controller descriptor.
* @param param - The GPIO IRQ controller initial parameters.
* irq_ctrl_id from irq_init_param is the interrupt id for the parent controller
* @return 0 in case of success, -1 otherwise.
*/
int32_t xil_gpio_irq_ctrl_init(struct irq_ctrl_desc **desc,
const struct irq_init_param *param)
{
int32_t i;
int32_t status;
struct irq_ctrl_desc *ldesc;
static XGpioPs_Config *GPIO_Config;
struct xil_gpio_irq_desc *xil_desc;
struct xil_gpio_irq_init_param *xil_ip;
struct callback_desc callback;
xil_desc = (struct xil_gpio_irq_desc *)calloc(1, sizeof(*xil_desc));
if(!xil_desc)
return -ENOMEM;
ldesc = (struct irq_ctrl_desc *)calloc(1, sizeof(*ldesc));
if(!ldesc) {
free(xil_desc);
return -ENOMEM;
}
xil_ip = param->extra;
GPIO_Config = XGpioPs_LookupConfig(xil_ip->gpio_device_id);
status = XGpioPs_CfgInitialize(&xil_desc->my_Gpio, GPIO_Config,
GPIO_Config->BaseAddr);
if(status)
goto error_desc;
ldesc->extra = xil_desc;
xil_desc->parent_desc = xil_ip->parent_desc;
status = list_init(&xil_desc->callback_list, LIST_DEFAULT,
call_cmp);
if(status)
goto error_list;
status = iterator_init(&xil_desc->it, xil_desc->callback_list, 0);
if(status) {
iterator_remove(xil_desc->it);
goto error_list;
}
ldesc->irq_ctrl_id = param->irq_ctrl_id;
status = irq_trigger_level_set(xil_desc->parent_desc, ldesc->irq_ctrl_id,
IRQ_EDGE_RISING);
if(status)
goto error_op;
status = irq_enable(xil_desc->parent_desc, ldesc->irq_ctrl_id);
if(status)
goto error_op;
callback.legacy_callback = &xil_gpio_irq_handler;
callback.ctx = ldesc->extra;
status = irq_register_callback(xil_desc->parent_desc, ldesc->irq_ctrl_id,
&callback);
if(status)
goto error_op;
*desc = ldesc;
return 0;
error_op:
iterator_remove(xil_desc->it);
error_list:
list_remove(xil_desc->callback_list);
error_desc:
free(xil_desc);
free(ldesc);
return status;
}
/**
* @brief Set GPIO interrupt trigger level.
* @param desc - The GPIO IRQ controller descriptor.
* @param irq_id - Pin number.
* @param trig - New trigger level for the GPIO interrupt.
* @return 0 in case of success, -1 otherwise.
*/
int32_t xil_gpio_irq_trigger_level_set(struct irq_ctrl_desc *desc,
uint32_t irq_id,
enum irq_trig_level trig)
{
static const int32_t trig_level[5] = {XGPIOPS_IRQ_TYPE_LEVEL_LOW,
XGPIOPS_IRQ_TYPE_LEVEL_HIGH,
XGPIOPS_IRQ_TYPE_EDGE_FALLING,
XGPIOPS_IRQ_TYPE_EDGE_RISING,
XGPIOPS_IRQ_TYPE_EDGE_BOTH
};
struct xil_gpio_irq_desc *extra;
extra = desc->extra;
XGpioPs_SetIntrTypePin(&extra->my_Gpio, irq_id, trig_level[trig]);
return 0;
}
/**
* @brief Register pin specific GPIO interrupt.
* @param desc - The GPIO IRQ controller descriptor.
* @param irq_id - Pin number.
* @param callback_desc - Callback.
* @return 0 in case of success, -1 otherwise.
*/
int32_t xil_gpio_irq_register_callback(struct irq_ctrl_desc *desc,
uint32_t irq_id,
struct callback_desc *callback_desc)
{
struct xil_callback_desc *dev_callback;
struct xil_gpio_irq_desc *extra;
dev_callback = (struct xil_callback_desc *)calloc(1,
sizeof(*dev_callback));
if(!dev_callback)
return -1;
dev_callback->pin_nb = irq_id;
dev_callback->callback.legacy_callback = callback_desc->legacy_callback;
dev_callback->callback.ctx = callback_desc->ctx;
dev_callback->triggered = false;
extra = desc->extra;
XGpioPs_SetDirectionPin(&extra->my_Gpio, irq_id, 0);
list_add_last(extra->callback_list, dev_callback);
return 0;
}
/**
* @brief Unregister pin specific GPIO interrupt.
* @param desc - The GPIO IRQ controller descriptor.
* @param irq_id - Pin number.
* @param cb - Callback descriptor.
* @return 0 in case of success, -1 otherwise.
*/
int32_t xil_gpio_irq_unregister_callback(struct irq_ctrl_desc *desc,
uint32_t irq_id, struct callback_desc *cb)
{
int32_t status;
struct xil_gpio_irq_desc *extra;
struct xil_callback_desc *dev_callback;
struct xil_callback_desc search_callback;
extra = desc->extra;
search_callback.pin_nb = irq_id;
status = list_get_find(extra->callback_list, &dev_callback,
&search_callback);
if(status)
return -ENXIO;
free(dev_callback);
return 0;
}
/**
* @brief Enable specific GPIO IRQ pin.
* @param desc - The GPIO IRQ controller descriptor.
* @param irq_id - Pin number.
* @return 0 in case of success, -1 otherwise.
*/
int32_t xil_gpio_irq_enable(struct irq_ctrl_desc *desc, uint32_t irq_id)
{
int32_t status;
struct xil_gpio_irq_desc *extra;
struct xil_callback_desc *callback_desc;
extra = desc->extra;
status = iterator_move_to_idx(extra->it, 0);
while(!status) {
iterator_read(extra->it, &callback_desc);
status = iterator_move(extra->it, 1);
if(callback_desc->pin_nb == irq_id) {
callback_desc->enabled = true;
XGpioPs_IntrClearPin(&extra->my_Gpio, irq_id);
break;
}
}
XGpioPs_IntrEnablePin(&extra->my_Gpio, irq_id);
return 0;
}
/**
* @brief Remove the GPIO IRQ controller.
* @param desc - The GPIO IRQ controller descriptor.
* @return 0 in case of success, -1 otherwise.
*/
int32_t xil_gpio_irq_ctrl_remove(struct irq_ctrl_desc *desc)
{
struct xil_gpio_irq_desc *extra;
struct xil_callback_desc *callback_desc;
if (!desc)
return -EINVAL;
extra = desc->extra;
while (0 == list_get_first(extra->callback_list, &callback_desc))
free(callback_desc);
iterator_remove(extra->it);
list_remove(extra->callback_list);
free(extra);
free(desc);
return 0;
}
/**
* @brief Xilinx platform specific GPIO IRQ platform ops structure
*/
const struct irq_platform_ops xil_gpio_irq_ops = {
.init = &xil_gpio_irq_ctrl_init,
.enable = &xil_gpio_irq_enable,
.disable = &xil_gpio_irq_disable,
.trigger_level_set = &xil_gpio_irq_trigger_level_set,
.register_callback = &xil_gpio_irq_register_callback,
.unregister_callback = xil_gpio_irq_unregister_callback,
.remove = &xil_gpio_irq_ctrl_remove
};
-92
View File
@@ -1,92 +0,0 @@
/***************************************************************************//**
* @file xilinx_gpio_irq.h
* @brief Implementation of Xilinx GPIO IRQ Generic Driver.
* @author Porumb Andrei ([email protected])
********************************************************************************
* Copyright 2021(c) Analog Devices, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* - Neither the name of Analog Devices, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* - The use of this software may or may not infringe the patent rights
* of one or more patent holders. This license does not release you
* from the requirement that you obtain separate licenses from these
* patent holders to use this software.
* - Use of the software either in source or binary form, must be run
* on or directly connected to an Analog Devices Inc. component.
*
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#ifndef XILINX_GPIO_IRQ_H_
#define XILINX_GPIO_IRQ_H_
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include "stdbool.h"
#include "list.h"
#include "xgpiops.h"
#include "irq.h"
/******************************************************************************/
/*************************** Types Declarations *******************************/
/******************************************************************************/
/**
* @struct xil_callback_desc
* @brief Structure holding callback parameters for each pin
*/
struct xil_callback_desc {
int32_t pin_nb;
struct callback_desc callback;
bool triggered;
bool enabled;
};
/**
* @struct xil_gpio_irq_init_param
* @brief Structure holding the initialization parameters for Xilinx platform
* specific GPIO IRQ parameters.
*/
struct xil_gpio_irq_init_param {
struct irq_ctrl_desc *parent_desc;
int32_t gpio_device_id;
};
/**
* @struct xil_gpio_irq_desc
* @brief Xilinx platform specific GPIO IRQ descriptor
*/
struct xil_gpio_irq_desc {
struct irq_ctrl_desc *parent_desc;
XGpioPs my_Gpio;
struct list_desc *callback_list;
struct iterator *it;
};
/**
* @brief Xilinx specific GPIO IRQ platform ops structure
*/
extern const struct irq_platform_ops xil_gpio_irq_ops;
#endif
-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_
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,552 +0,0 @@
/***************************************************************************//**
* @file ad9361_api.h
* @brief Header file of AD9361 API Driver.
* @author DBogdan (dragos.bogdan@analog.com)
********************************************************************************
* Copyright 2013(c) Analog Devices, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* - Neither the name of Analog Devices, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* - The use of this software may or may not infringe the patent rights
* of one or more patent holders. This license does not release you
* from the requirement that you obtain separate licenses from these
* patent holders to use this software.
* - Use of the software either in source or binary form, must be run
* on or directly connected to an Analog Devices Inc. component.
*
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#ifndef AD9361_API_H_
#define AD9361_API_H_
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include "ad9361_util.h"
#include "gpio.h"
#include "spi.h"
/******************************************************************************/
/*************************** Types Declarations *******************************/
/******************************************************************************/
typedef struct {
/* Device selection */
enum dev_id dev_sel;
/* Reference Clock */
uint32_t reference_clk_rate;
/* Base Configuration */
uint8_t two_rx_two_tx_mode_enable; /* adi,2rx-2tx-mode-enable */
uint8_t one_rx_one_tx_mode_use_rx_num; /* adi,1rx-1tx-mode-use-rx-num */
uint8_t one_rx_one_tx_mode_use_tx_num; /* adi,1rx-1tx-mode-use-tx-num */
uint8_t frequency_division_duplex_mode_enable; /* adi,frequency-division-duplex-mode-enable */
uint8_t frequency_division_duplex_independent_mode_enable; /* adi,frequency-division-duplex-independent-mode-enable */
uint8_t tdd_use_dual_synth_mode_enable; /* adi,tdd-use-dual-synth-mode-enable */
uint8_t tdd_skip_vco_cal_enable; /* adi,tdd-skip-vco-cal-enable */
uint32_t tx_fastlock_delay_ns; /* adi,tx-fastlock-delay-ns */
uint32_t rx_fastlock_delay_ns; /* adi,rx-fastlock-delay-ns */
uint8_t rx_fastlock_pincontrol_enable; /* adi,rx-fastlock-pincontrol-enable */
uint8_t tx_fastlock_pincontrol_enable; /* adi,tx-fastlock-pincontrol-enable */
uint8_t external_rx_lo_enable; /* adi,external-rx-lo-enable */
uint8_t external_tx_lo_enable; /* adi,external-tx-lo-enable */
uint8_t dc_offset_tracking_update_event_mask; /* adi,dc-offset-tracking-update-event-mask */
uint8_t dc_offset_attenuation_high_range; /* adi,dc-offset-attenuation-high-range */
uint8_t dc_offset_attenuation_low_range; /* adi,dc-offset-attenuation-low-range */
uint8_t dc_offset_count_high_range; /* adi,dc-offset-count-high-range */
uint8_t dc_offset_count_low_range; /* adi,dc-offset-count-low-range */
uint8_t split_gain_table_mode_enable; /* adi,split-gain-table-mode-enable */
uint32_t trx_synthesizer_target_fref_overwrite_hz; /* adi,trx-synthesizer-target-fref-overwrite-hz */
uint8_t qec_tracking_slow_mode_enable; /* adi,qec-tracking-slow-mode-enable */
/* ENSM Control */
uint8_t ensm_enable_pin_pulse_mode_enable; /* adi,ensm-enable-pin-pulse-mode-enable */
uint8_t ensm_enable_txnrx_control_enable; /* adi,ensm-enable-txnrx-control-enable */
/* LO Control */
uint64_t rx_synthesizer_frequency_hz; /* adi,rx-synthesizer-frequency-hz */
uint64_t tx_synthesizer_frequency_hz; /* adi,tx-synthesizer-frequency-hz */
uint8_t tx_lo_powerdown_managed_enable; /* adi,tx-lo-powerdown-managed-enable */
/* Rate & BW Control */
uint32_t rx_path_clock_frequencies[6]; /* adi,rx-path-clock-frequencies */
uint32_t tx_path_clock_frequencies[6]; /* adi,tx-path-clock-frequencies */
uint32_t rf_rx_bandwidth_hz; /* adi,rf-rx-bandwidth-hz */
uint32_t rf_tx_bandwidth_hz; /* adi,rf-tx-bandwidth-hz */
/* RF Port Control */
uint32_t rx_rf_port_input_select; /* adi,rx-rf-port-input-select */
uint32_t tx_rf_port_input_select; /* adi,tx-rf-port-input-select */
/* TX Attenuation Control */
int32_t tx_attenuation_mdB; /* adi,tx-attenuation-mdB */
uint8_t update_tx_gain_in_alert_enable; /* adi,update-tx-gain-in-alert-enable */
/* Reference Clock Control */
uint8_t xo_disable_use_ext_refclk_enable; /* adi,xo-disable-use-ext-refclk-enable */
uint32_t dcxo_coarse_and_fine_tune[2]; /* adi,dcxo-coarse-and-fine-tune */
uint32_t clk_output_mode_select; /* adi,clk-output-mode-select */
/* Gain Control */
uint8_t gc_rx1_mode; /* adi,gc-rx1-mode */
uint8_t gc_rx2_mode; /* adi,gc-rx2-mode */
uint8_t gc_adc_large_overload_thresh; /* adi,gc-adc-large-overload-thresh */
uint8_t gc_adc_ovr_sample_size; /* adi,gc-adc-ovr-sample-size */
uint8_t gc_adc_small_overload_thresh; /* adi,gc-adc-small-overload-thresh */
uint16_t gc_dec_pow_measurement_duration; /* adi,gc-dec-pow-measurement-duration */
uint8_t gc_dig_gain_enable; /* adi,gc-dig-gain-enable */
uint16_t gc_lmt_overload_high_thresh; /* adi,gc-lmt-overload-high-thresh */
uint16_t gc_lmt_overload_low_thresh; /* adi,gc-lmt-overload-low-thresh */
uint8_t gc_low_power_thresh; /* adi,gc-low-power-thresh */
uint8_t gc_max_dig_gain; /* adi,gc-max-dig-gain */
uint8_t gc_use_rx_fir_out_for_dec_pwr_meas_enable; /* adi,gc-use-rx-fir-out-for-dec-pwr-meas-enable */
/* Gain MGC Control */
uint8_t mgc_dec_gain_step; /* adi,mgc-dec-gain-step */
uint8_t mgc_inc_gain_step; /* adi,mgc-inc-gain-step */
uint8_t mgc_rx1_ctrl_inp_enable; /* adi,mgc-rx1-ctrl-inp-enable */
uint8_t mgc_rx2_ctrl_inp_enable; /* adi,mgc-rx2-ctrl-inp-enable */
uint8_t mgc_split_table_ctrl_inp_gain_mode; /* adi,mgc-split-table-ctrl-inp-gain-mode */
/* Gain AGC Control */
uint8_t agc_adc_large_overload_exceed_counter; /* adi,agc-adc-large-overload-exceed-counter */
uint8_t agc_adc_large_overload_inc_steps; /* adi,agc-adc-large-overload-inc-steps - Name is misleading should be dec-steps*/
uint8_t agc_adc_lmt_small_overload_prevent_gain_inc_enable; /* adi,agc-adc-lmt-small-overload-prevent-gain-inc-enable */
uint8_t agc_adc_small_overload_exceed_counter; /* adi,agc-adc-small-overload-exceed-counter */
uint8_t agc_dig_gain_step_size; /* adi,agc-dig-gain-step-size */
uint8_t agc_dig_saturation_exceed_counter; /* adi,agc-dig-saturation-exceed-counter */
uint32_t agc_gain_update_interval_us; /* adi,agc-gain-update-interval-us */
uint8_t agc_immed_gain_change_if_large_adc_overload_enable; /* adi,agc-immed-gain-change-if-large-adc-overload-enable */
uint8_t agc_immed_gain_change_if_large_lmt_overload_enable; /* adi,agc-immed-gain-change-if-large-lmt-overload-enable */
uint8_t agc_inner_thresh_high; /* adi,agc-inner-thresh-high */
uint8_t agc_inner_thresh_high_dec_steps; /* adi,agc-inner-thresh-high-dec-steps */
uint8_t agc_inner_thresh_low; /* adi,agc-inner-thresh-low */
uint8_t agc_inner_thresh_low_inc_steps; /* adi,agc-inner-thresh-low-inc-steps */
uint8_t agc_lmt_overload_large_exceed_counter; /* adi,agc-lmt-overload-large-exceed-counter */
uint8_t agc_lmt_overload_large_inc_steps; /* adi,agc-lmt-overload-large-inc-steps */
uint8_t agc_lmt_overload_small_exceed_counter; /* adi,agc-lmt-overload-small-exceed-counter */
uint8_t agc_outer_thresh_high; /* adi,agc-outer-thresh-high */
uint8_t agc_outer_thresh_high_dec_steps; /* adi,agc-outer-thresh-high-dec-steps */
uint8_t agc_outer_thresh_low; /* adi,agc-outer-thresh-low */
uint8_t agc_outer_thresh_low_inc_steps; /* adi,agc-outer-thresh-low-inc-steps */
uint32_t agc_attack_delay_extra_margin_us; /* adi,agc-attack-delay-extra-margin-us */
uint8_t agc_sync_for_gain_counter_enable; /* adi,agc-sync-for-gain-counter-enable */
/* Fast AGC */
uint32_t fagc_dec_pow_measuremnt_duration; /* adi,fagc-dec-pow-measurement-duration */
uint32_t fagc_state_wait_time_ns; /* adi,fagc-state-wait-time-ns */
/* Fast AGC - Low Power */
uint8_t fagc_allow_agc_gain_increase; /* adi,fagc-allow-agc-gain-increase-enable */
uint32_t fagc_lp_thresh_increment_time; /* adi,fagc-lp-thresh-increment-time */
uint32_t fagc_lp_thresh_increment_steps; /* adi,fagc-lp-thresh-increment-steps */
/* Fast AGC - Lock Level (Lock Level is set via slow AGC inner high threshold) */
uint8_t fagc_lock_level_lmt_gain_increase_en; /* adi,fagc-lock-level-lmt-gain-increase-enable */
uint32_t fagc_lock_level_gain_increase_upper_limit; /* adi,fagc-lock-level-gain-increase-upper-limit */
/* Fast AGC - Peak Detectors and Final Settling */
uint32_t fagc_lpf_final_settling_steps; /* adi,fagc-lpf-final-settling-steps */
uint32_t fagc_lmt_final_settling_steps; /* adi,fagc-lmt-final-settling-steps */
uint32_t fagc_final_overrange_count; /* adi,fagc-final-overrange-count */
/* Fast AGC - Final Power Test */
uint8_t fagc_gain_increase_after_gain_lock_en; /* adi,fagc-gain-increase-after-gain-lock-enable */
/* Fast AGC - Unlocking the Gain */
uint32_t fagc_gain_index_type_after_exit_rx_mode; /* adi,fagc-gain-index-type-after-exit-rx-mode */
uint8_t fagc_use_last_lock_level_for_set_gain_en; /* adi,fagc-use-last-lock-level-for-set-gain-enable */
uint8_t fagc_rst_gla_stronger_sig_thresh_exceeded_en; /* adi,fagc-rst-gla-stronger-sig-thresh-exceeded-enable */
uint32_t fagc_optimized_gain_offset; /* adi,fagc-optimized-gain-offset */
uint32_t fagc_rst_gla_stronger_sig_thresh_above_ll; /* adi,fagc-rst-gla-stronger-sig-thresh-above-ll */
uint8_t fagc_rst_gla_engergy_lost_sig_thresh_exceeded_en; /* adi,fagc-rst-gla-engergy-lost-sig-thresh-exceeded-enable */
uint8_t fagc_rst_gla_engergy_lost_goto_optim_gain_en; /* adi,fagc-rst-gla-engergy-lost-goto-optim-gain-enable */
uint32_t fagc_rst_gla_engergy_lost_sig_thresh_below_ll; /* adi,fagc-rst-gla-engergy-lost-sig-thresh-below-ll */
uint32_t fagc_energy_lost_stronger_sig_gain_lock_exit_cnt; /* adi,fagc-energy-lost-stronger-sig-gain-lock-exit-cnt */
uint8_t fagc_rst_gla_large_adc_overload_en; /* adi,fagc-rst-gla-large-adc-overload-enable */
uint8_t fagc_rst_gla_large_lmt_overload_en; /* adi,fagc-rst-gla-large-lmt-overload-enable */
uint8_t fagc_rst_gla_en_agc_pulled_high_en; /* adi,fagc-rst-gla-en-agc-pulled-high-enable */
uint32_t fagc_rst_gla_if_en_agc_pulled_high_mode; /* adi,fagc-rst-gla-if-en-agc-pulled-high-mode */
uint32_t fagc_power_measurement_duration_in_state5; /* adi,fagc-power-measurement-duration-in-state5 */
uint32_t fagc_large_overload_inc_steps; /* adi,fagc-adc-large-overload-inc-steps - Name is misleading should be dec-steps */
/* RSSI Control */
uint32_t rssi_delay; /* adi,rssi-delay */
uint32_t rssi_duration; /* adi,rssi-duration */
uint8_t rssi_restart_mode; /* adi,rssi-restart-mode */
uint8_t rssi_unit_is_rx_samples_enable; /* adi,rssi-unit-is-rx-samples-enable */
uint32_t rssi_wait; /* adi,rssi-wait */
/* Aux ADC Control */
uint32_t aux_adc_decimation; /* adi,aux-adc-decimation */
uint32_t aux_adc_rate; /* adi,aux-adc-rate */
/* AuxDAC Control */
uint8_t aux_dac_manual_mode_enable; /* adi,aux-dac-manual-mode-enable */
uint32_t aux_dac1_default_value_mV; /* adi,aux-dac1-default-value-mV */
uint8_t aux_dac1_active_in_rx_enable; /* adi,aux-dac1-active-in-rx-enable */
uint8_t aux_dac1_active_in_tx_enable; /* adi,aux-dac1-active-in-tx-enable */
uint8_t aux_dac1_active_in_alert_enable; /* adi,aux-dac1-active-in-alert-enable */
uint32_t aux_dac1_rx_delay_us; /* adi,aux-dac1-rx-delay-us */
uint32_t aux_dac1_tx_delay_us; /* adi,aux-dac1-tx-delay-us */
uint32_t aux_dac2_default_value_mV; /* adi,aux-dac2-default-value-mV */
uint8_t aux_dac2_active_in_rx_enable; /* adi,aux-dac2-active-in-rx-enable */
uint8_t aux_dac2_active_in_tx_enable; /* adi,aux-dac2-active-in-tx-enable */
uint8_t aux_dac2_active_in_alert_enable; /* adi,aux-dac2-active-in-alert-enable */
uint32_t aux_dac2_rx_delay_us; /* adi,aux-dac2-rx-delay-us */
uint32_t aux_dac2_tx_delay_us; /* adi,aux-dac2-tx-delay-us */
/* Temperature Sensor Control */
uint32_t temp_sense_decimation; /* adi,temp-sense-decimation */
uint16_t temp_sense_measurement_interval_ms; /* adi,temp-sense-measurement-interval-ms */
int8_t temp_sense_offset_signed; /* adi,temp-sense-offset-signed */
uint8_t temp_sense_periodic_measurement_enable; /* adi,temp-sense-periodic-measurement-enable */
/* Control Out Setup */
uint8_t ctrl_outs_enable_mask; /* adi,ctrl-outs-enable-mask */
uint8_t ctrl_outs_index; /* adi,ctrl-outs-index */
/* External LNA Control */
uint32_t elna_settling_delay_ns; /* adi,elna-settling-delay-ns */
uint32_t elna_gain_mdB; /* adi,elna-gain-mdB */
uint32_t elna_bypass_loss_mdB; /* adi,elna-bypass-loss-mdB */
uint8_t elna_rx1_gpo0_control_enable; /* adi,elna-rx1-gpo0-control-enable */
uint8_t elna_rx2_gpo1_control_enable; /* adi,elna-rx2-gpo1-control-enable */
uint8_t elna_gaintable_all_index_enable; /* adi,elna-gaintable-all-index-enable */
/* Digital Interface Control */
uint8_t digital_interface_tune_skip_mode; /* adi,digital-interface-tune-skip-mode */
uint8_t digital_interface_tune_fir_disable; /* adi,digital-interface-tune-fir-disable */
uint8_t pp_tx_swap_enable; /* adi,pp-tx-swap-enable */
uint8_t pp_rx_swap_enable; /* adi,pp-rx-swap-enable */
uint8_t tx_channel_swap_enable; /* adi,tx-channel-swap-enable */
uint8_t rx_channel_swap_enable; /* adi,rx-channel-swap-enable */
uint8_t rx_frame_pulse_mode_enable; /* adi,rx-frame-pulse-mode-enable */
uint8_t two_t_two_r_timing_enable; /* adi,2t2r-timing-enable */
uint8_t invert_data_bus_enable; /* adi,invert-data-bus-enable */
uint8_t invert_data_clk_enable; /* adi,invert-data-clk-enable */
uint8_t fdd_alt_word_order_enable; /* adi,fdd-alt-word-order-enable */
uint8_t invert_rx_frame_enable; /* adi,invert-rx-frame-enable */
uint8_t fdd_rx_rate_2tx_enable; /* adi,fdd-rx-rate-2tx-enable */
uint8_t swap_ports_enable; /* adi,swap-ports-enable */
uint8_t single_data_rate_enable; /* adi,single-data-rate-enable */
uint8_t lvds_mode_enable; /* adi,lvds-mode-enable */
uint8_t half_duplex_mode_enable; /* adi,half-duplex-mode-enable */
uint8_t single_port_mode_enable; /* adi,single-port-mode-enable */
uint8_t full_port_enable; /* adi,full-port-enable */
uint8_t full_duplex_swap_bits_enable; /* adi,full-duplex-swap-bits-enable */
uint32_t delay_rx_data; /* adi,delay-rx-data */
uint32_t rx_data_clock_delay; /* adi,rx-data-clock-delay */
uint32_t rx_data_delay; /* adi,rx-data-delay */
uint32_t tx_fb_clock_delay; /* adi,tx-fb-clock-delay */
uint32_t tx_data_delay; /* adi,tx-data-delay */
uint32_t lvds_bias_mV; /* adi,lvds-bias-mV */
uint8_t lvds_rx_onchip_termination_enable; /* adi,lvds-rx-onchip-termination-enable */
uint8_t rx1rx2_phase_inversion_en; /* adi,rx1-rx2-phase-inversion-enable */
uint8_t lvds_invert1_control; /* adi,lvds-invert1-control */
uint8_t lvds_invert2_control; /* adi,lvds-invert2-control */
/* GPO Control */
uint8_t gpo_manual_mode_enable; /* adi,gpo-manual-mode-enable */
uint32_t gpo_manual_mode_enable_mask; /* adi,gpo-manual-mode-enable-mask */
uint8_t gpo0_inactive_state_high_enable; /* adi,gpo0-inactive-state-high-enable */
uint8_t gpo1_inactive_state_high_enable; /* adi,gpo1-inactive-state-high-enable */
uint8_t gpo2_inactive_state_high_enable; /* adi,gpo2-inactive-state-high-enable */
uint8_t gpo3_inactive_state_high_enable; /* adi,gpo3-inactive-state-high-enable */
uint8_t gpo0_slave_rx_enable; /* adi,gpo0-slave-rx-enable */
uint8_t gpo0_slave_tx_enable; /* adi,gpo0-slave-tx-enable */
uint8_t gpo1_slave_rx_enable; /* adi,gpo1-slave-rx-enable */
uint8_t gpo1_slave_tx_enable; /* adi,gpo1-slave-tx-enable */
uint8_t gpo2_slave_rx_enable; /* adi,gpo2-slave-rx-enable */
uint8_t gpo2_slave_tx_enable; /* adi,gpo2-slave-tx-enable */
uint8_t gpo3_slave_rx_enable; /* adi,gpo3-slave-rx-enable */
uint8_t gpo3_slave_tx_enable; /* adi,gpo3-slave-tx-enable */
uint8_t gpo0_rx_delay_us; /* adi,gpo0-rx-delay-us */
uint8_t gpo0_tx_delay_us; /* adi,gpo0-tx-delay-us */
uint8_t gpo1_rx_delay_us; /* adi,gpo1-rx-delay-us */
uint8_t gpo1_tx_delay_us; /* adi,gpo1-tx-delay-us */
uint8_t gpo2_rx_delay_us; /* adi,gpo2-rx-delay-us */
uint8_t gpo2_tx_delay_us; /* adi,gpo2-tx-delay-us */
uint8_t gpo3_rx_delay_us; /* adi,gpo3-rx-delay-us */
uint8_t gpo3_tx_delay_us; /* adi,gpo3-tx-delay-us */
/* Tx Monitor Control */
uint32_t low_high_gain_threshold_mdB; /* adi,txmon-low-high-thresh */
uint32_t low_gain_dB; /* adi,txmon-low-gain */
uint32_t high_gain_dB; /* adi,txmon-high-gain */
uint8_t tx_mon_track_en; /* adi,txmon-dc-tracking-enable */
uint8_t one_shot_mode_en; /* adi,txmon-one-shot-mode-enable */
uint32_t tx_mon_delay; /* adi,txmon-delay */
uint32_t tx_mon_duration; /* adi,txmon-duration */
uint32_t tx1_mon_front_end_gain; /* adi,txmon-1-front-end-gain */
uint32_t tx2_mon_front_end_gain; /* adi,txmon-2-front-end-gain */
uint32_t tx1_mon_lo_cm; /* adi,txmon-1-lo-cm */
uint32_t tx2_mon_lo_cm; /* adi,txmon-2-lo-cm */
/* GPIO definitions */
struct gpio_init_param gpio_resetb; /* reset-gpios */
/* MCS Sync */
struct gpio_init_param gpio_sync; /* sync-gpios */
struct gpio_init_param gpio_cal_sw1; /* cal-sw1-gpios */
struct gpio_init_param gpio_cal_sw2; /* cal-sw2-gpios */
struct spi_init_param spi_param;
/* External LO clocks */
uint32_t (*ad9361_rfpll_ext_recalc_rate)(struct refclk_scale *clk_priv);
int32_t (*ad9361_rfpll_ext_round_rate)(struct refclk_scale *clk_priv,
uint32_t rate);
int32_t (*ad9361_rfpll_ext_set_rate)(struct refclk_scale *clk_priv,
uint32_t rate);
} AD9361_InitParam;
typedef struct {
uint32_t rx; /* 1, 2, 3(both) */
int32_t rx_gain; /* -12, -6, 0, 6 */
uint32_t rx_dec; /* 1, 2, 4 */
int16_t rx_coef[128];
uint8_t rx_coef_size;
uint32_t rx_path_clks[6];
uint32_t rx_bandwidth;
} AD9361_RXFIRConfig;
typedef struct {
uint32_t tx; /* 1, 2, 3(both) */
int32_t tx_gain; /* -6, 0 */
uint32_t tx_int; /* 1, 2, 4 */
int16_t tx_coef[128];
uint8_t tx_coef_size;
uint32_t tx_path_clks[6];
uint32_t tx_bandwidth;
} AD9361_TXFIRConfig;
enum ad9361_ensm_mode {
ENSM_MODE_TX,
ENSM_MODE_RX,
ENSM_MODE_ALERT,
ENSM_MODE_FDD,
ENSM_MODE_WAIT,
ENSM_MODE_SLEEP,
ENSM_MODE_PINCTRL,
ENSM_MODE_PINCTRL_FDD_INDEP,
};
#define ENABLE 1
#define DISABLE 0
#define RX1 0
#define RX2 1
#define TX1 0
#define TX2 1
#define A_BALANCED 0
#define B_BALANCED 1
#define C_BALANCED 2
#define A_N 3
#define A_P 4
#define B_N 5
#define B_P 6
#define C_N 7
#define C_P 8
#define TX_MON1 9
#define TX_MON2 10
#define TX_MON1_2 11
#define TXA 0
#define TXB 1
#define MODE_1x1 1
#define MODE_2x2 2
#define HIGHEST_OSR 0
#define NOMINAL_OSR 1
#define INT_LO 0
#define EXT_LO 1
#define ON 0
#define OFF 1
/******************************************************************************/
/************************ Functions Declarations ******************************/
/******************************************************************************/
/* Initialize the AD9361 part. */
int32_t ad9361_init (struct ad9361_rf_phy **ad9361_phy,
AD9361_InitParam *init_param);
/* Free the allocated resources. */
int32_t ad9361_remove(struct ad9361_rf_phy *phy);
/* Set the Enable State Machine (ENSM) mode. */
int32_t ad9361_set_en_state_machine_mode (struct ad9361_rf_phy *phy,
uint32_t mode);
/* Get the Enable State Machine (ENSM) mode. */
int32_t ad9361_get_en_state_machine_mode (struct ad9361_rf_phy *phy,
uint32_t *mode);
/* Set the receive RF gain for the selected channel. */
int32_t ad9361_set_rx_rf_gain (struct ad9361_rf_phy *phy, uint8_t ch,
int32_t gain_db);
/* Get current receive RF gain for the selected channel. */
int32_t ad9361_get_rx_rf_gain (struct ad9361_rf_phy *phy, uint8_t ch,
int32_t *gain_db);
/* Set the RX RF bandwidth. */
int32_t ad9361_set_rx_rf_bandwidth (struct ad9361_rf_phy *phy,
uint32_t bandwidth_hz);
/* Get the RX RF bandwidth. */
int32_t ad9361_get_rx_rf_bandwidth (struct ad9361_rf_phy *phy,
uint32_t *bandwidth_hz);
/* Set the RX sampling frequency. */
int32_t ad9361_set_rx_sampling_freq (struct ad9361_rf_phy *phy,
uint32_t sampling_freq_hz);
/* Get current RX sampling frequency. */
int32_t ad9361_get_rx_sampling_freq (struct ad9361_rf_phy *phy,
uint32_t *sampling_freq_hz);
/* Set the RX LO frequency. */
int32_t ad9361_set_rx_lo_freq (struct ad9361_rf_phy *phy, uint64_t lo_freq_hz);
/* Get current RX LO frequency. */
int32_t ad9361_get_rx_lo_freq (struct ad9361_rf_phy *phy, uint64_t *lo_freq_hz);
/* Switch between internal and external LO. */
int32_t ad9361_set_rx_lo_int_ext(struct ad9361_rf_phy *phy, uint8_t int_ext);
/* Get the RSSI for the selected channel. */
int32_t ad9361_get_rx_rssi (struct ad9361_rf_phy *phy, uint8_t ch,
struct rf_rssi *rssi);
/* Set the gain control mode for the selected channel. */
int32_t ad9361_set_rx_gain_control_mode (struct ad9361_rf_phy *phy, uint8_t ch,
uint8_t gc_mode);
/* Get the gain control mode for the selected channel. */
int32_t ad9361_get_rx_gain_control_mode (struct ad9361_rf_phy *phy, uint8_t ch,
uint8_t *gc_mode);
/* Set the RX FIR filter configuration. */
int32_t ad9361_set_rx_fir_config (struct ad9361_rf_phy *phy,
AD9361_RXFIRConfig fir_cfg);
/* Get the RX FIR filter configuration. */
int32_t ad9361_get_rx_fir_config(struct ad9361_rf_phy *phy, uint8_t rx_ch,
AD9361_RXFIRConfig *fir_cfg);
/* Enable/disable the RX FIR filter. */
int32_t ad9361_set_rx_fir_en_dis (struct ad9361_rf_phy *phy, uint8_t en_dis);
/* Get the status of the RX FIR filter. */
int32_t ad9361_get_rx_fir_en_dis (struct ad9361_rf_phy *phy, uint8_t *en_dis);
/* Enable/disable the RX RFDC Tracking. */
int32_t ad9361_set_rx_rfdc_track_en_dis (struct ad9361_rf_phy *phy,
uint8_t en_dis);
/* Get the status of the RX RFDC Tracking. */
int32_t ad9361_get_rx_rfdc_track_en_dis (struct ad9361_rf_phy *phy,
uint8_t *en_dis);
/* Enable/disable the RX BasebandDC Tracking. */
int32_t ad9361_set_rx_bbdc_track_en_dis (struct ad9361_rf_phy *phy,
uint8_t en_dis);
/* Get the status of the RX BasebandDC Tracking. */
int32_t ad9361_get_rx_bbdc_track_en_dis (struct ad9361_rf_phy *phy,
uint8_t *en_dis);
/* Enable/disable the RX Quadrature Tracking. */
int32_t ad9361_set_rx_quad_track_en_dis (struct ad9361_rf_phy *phy,
uint8_t en_dis);
/* Get the status of the RX Quadrature Tracking. */
int32_t ad9361_get_rx_quad_track_en_dis (struct ad9361_rf_phy *phy,
uint8_t *en_dis);
/* Set the RX RF input port. */
int32_t ad9361_set_rx_rf_port_input (struct ad9361_rf_phy *phy, uint32_t mode);
/* Get the selected RX RF input port. */
int32_t ad9361_get_rx_rf_port_input (struct ad9361_rf_phy *phy, uint32_t *mode);
/* Store RX fastlock profile. */
int32_t ad9361_rx_fastlock_store(struct ad9361_rf_phy *phy, uint32_t profile);
/* Recall RX fastlock profile. */
int32_t ad9361_rx_fastlock_recall(struct ad9361_rf_phy *phy, uint32_t profile);
/* Load RX fastlock profile. */
int32_t ad9361_rx_fastlock_load(struct ad9361_rf_phy *phy, uint32_t profile,
uint8_t *values);
/* Save RX fastlock profile. */
int32_t ad9361_rx_fastlock_save(struct ad9361_rf_phy *phy, uint32_t profile,
uint8_t *values);
/* Power down the RX Local Oscillator. */
int32_t ad9361_rx_lo_powerdown(struct ad9361_rf_phy *phy, uint8_t option);
/* Get the RX Local Oscillator power status. */
int32_t ad9361_get_rx_lo_power(struct ad9361_rf_phy *phy, uint8_t *option);
/* Set the transmit attenuation for the selected channel. */
int32_t ad9361_set_tx_attenuation (struct ad9361_rf_phy *phy, uint8_t ch,
uint32_t attenuation_mdb);
/* Get current transmit attenuation for the selected channel. */
int32_t ad9361_get_tx_attenuation (struct ad9361_rf_phy *phy, uint8_t ch,
uint32_t *attenuation_mdb);
/* Set the TX RF bandwidth. */
int32_t ad9361_set_tx_rf_bandwidth (struct ad9361_rf_phy *phy,
uint32_t bandwidth_hz);
/* Get the TX RF bandwidth. */
int32_t ad9361_get_tx_rf_bandwidth (struct ad9361_rf_phy *phy,
uint32_t *bandwidth_hz);
/* Set the TX sampling frequency. */
int32_t ad9361_set_tx_sampling_freq (struct ad9361_rf_phy *phy,
uint32_t sampling_freq_hz);
/* Get current TX sampling frequency. */
int32_t ad9361_get_tx_sampling_freq (struct ad9361_rf_phy *phy,
uint32_t *sampling_freq_hz);
/* Set the TX LO frequency. */
int32_t ad9361_set_tx_lo_freq (struct ad9361_rf_phy *phy, uint64_t lo_freq_hz);
/* Get current TX LO frequency. */
int32_t ad9361_get_tx_lo_freq (struct ad9361_rf_phy *phy, uint64_t *lo_freq_hz);
/* Switch between internal and external LO. */
int32_t ad9361_set_tx_lo_int_ext(struct ad9361_rf_phy *phy, uint8_t int_ext);
/* Set the TX FIR filter configuration. */
int32_t ad9361_set_tx_fir_config (struct ad9361_rf_phy *phy,
AD9361_TXFIRConfig fir_cfg);
/* Get the TX FIR filter configuration. */
int32_t ad9361_get_tx_fir_config(struct ad9361_rf_phy *phy, uint8_t tx_ch,
AD9361_TXFIRConfig *fir_cfg);
/* Enable/disable the TX FIR filter. */
int32_t ad9361_set_tx_fir_en_dis (struct ad9361_rf_phy *phy, uint8_t en_dis);
/* Get the status of the TX FIR filter. */
int32_t ad9361_get_tx_fir_en_dis (struct ad9361_rf_phy *phy, uint8_t *en_dis);
/* Get the TX RSSI for the selected channel. */
int32_t ad9361_get_tx_rssi (struct ad9361_rf_phy *phy, uint8_t ch,
uint32_t *rssi_db_x_1000);
/* Set the TX RF output port. */
int32_t ad9361_set_tx_rf_port_output (struct ad9361_rf_phy *phy, uint32_t mode);
/* Get the selected TX RF output port. */
int32_t ad9361_get_tx_rf_port_output (struct ad9361_rf_phy *phy,
uint32_t *mode);
/* Enable/disable the auto calibration. */
int32_t ad9361_set_tx_auto_cal_en_dis (struct ad9361_rf_phy *phy,
uint8_t en_dis);
/* Get the status of the auto calibration flag. */
int32_t ad9361_get_tx_auto_cal_en_dis (struct ad9361_rf_phy *phy,
uint8_t *en_dis);
/* Store TX fastlock profile. */
int32_t ad9361_tx_fastlock_store(struct ad9361_rf_phy *phy, uint32_t profile);
/* Recall TX fastlock profile. */
int32_t ad9361_tx_fastlock_recall(struct ad9361_rf_phy *phy, uint32_t profile);
/* Load TX fastlock profile. */
int32_t ad9361_tx_fastlock_load(struct ad9361_rf_phy *phy, uint32_t profile,
uint8_t *values);
/* Save TX fastlock profile. */
int32_t ad9361_tx_fastlock_save(struct ad9361_rf_phy *phy, uint32_t profile,
uint8_t *values);
/* Power down the TX Local Oscillator. */
int32_t ad9361_tx_lo_powerdown(struct ad9361_rf_phy *phy, uint8_t option);
/* Get the TX Local Oscillator power status. */
int32_t ad9361_get_tx_lo_power(struct ad9361_rf_phy *phy, uint8_t *option);
/* Set the RX and TX path rates. */
int32_t ad9361_set_trx_path_clks(struct ad9361_rf_phy *phy,
uint32_t *rx_path_clks, uint32_t *tx_path_clks);
/* Get the RX and TX path rates. */
int32_t ad9361_get_trx_path_clks(struct ad9361_rf_phy *phy,
uint32_t *rx_path_clks, uint32_t *tx_path_clks);
/* Set the number of channels mode. */
int32_t ad9361_set_no_ch_mode(struct ad9361_rf_phy *phy, uint8_t no_ch_mode);
/* Do multi chip synchronization. */
int32_t ad9361_do_mcs(struct ad9361_rf_phy *phy_master,
struct ad9361_rf_phy *phy_slave);
/* Enable/disable the TRX FIR filters. */
int32_t ad9361_set_trx_fir_en_dis (struct ad9361_rf_phy *phy, uint8_t en_dis);
/* Set the OSR rate governor. */
int32_t ad9361_set_trx_rate_gov (struct ad9361_rf_phy *phy, uint32_t rate_gov);
/* Get the OSR rate governor. */
int32_t ad9361_get_trx_rate_gov (struct ad9361_rf_phy *phy, uint32_t *rate_gov);
/* Perform the selected calibration. */
int32_t ad9361_do_calib(struct ad9361_rf_phy *phy, uint32_t cal, int32_t arg);
/* Load and enable TRX FIR filters configurations. */
int32_t ad9361_trx_load_enable_fir(struct ad9361_rf_phy *phy,
AD9361_RXFIRConfig rx_fir_cfg,
AD9361_TXFIRConfig tx_fir_cfg);
/* Do DCXO coarse tuning. */
int32_t ad9361_do_dcxo_tune_coarse(struct ad9361_rf_phy *phy,
uint32_t coarse);
/* Do DCXO fine tuning. */
int32_t ad9361_do_dcxo_tune_fine(struct ad9361_rf_phy *phy,
uint32_t fine);
/* Get the temperature. */
int32_t ad9361_get_temperature(struct ad9361_rf_phy *phy,
int32_t *temp);
#endif
@@ -1,335 +0,0 @@
/***************************************************************************//**
* @file ad9361_util.c
* @brief AD9361 Implementation of Util Driver.
* @author DBogdan (dragos.bogdan@analog.com)
********************************************************************************
* Copyright 2013(c) Analog Devices, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* - Neither the name of Analog Devices, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* - The use of this software may or may not infringe the patent rights
* of one or more patent holders. This license does not release you
* from the requirement that you obtain separate licenses from these
* patent holders to use this software.
* - Use of the software either in source or binary form, must be run
* on or directly connected to an Analog Devices Inc. component.
*
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <string.h>
#include "ad9361_util.h"
#include "../../../include/delay.h"
/******************************************************************************/
/*************************** Macros Definitions *******************************/
/******************************************************************************/
#define BITS_PER_LONG 32
/***************************************************************************//**
* @brief clk_prepare_enable
*******************************************************************************/
int32_t clk_prepare_enable(struct clk *clk)
{
if (clk) {
// Unused variable - fix compiler warning
}
return 0;
}
/***************************************************************************//**
* @brief clk_get_rate
*******************************************************************************/
uint32_t clk_get_rate(struct ad9361_rf_phy *phy,
struct refclk_scale *clk_priv)
{
uint32_t rate = 0;
uint32_t source;
source = clk_priv->source;
switch (source) {
case TX_REFCLK:
case RX_REFCLK:
case BB_REFCLK:
rate = ad9361_clk_factor_recalc_rate(clk_priv,
phy->clk_refin->rate);
break;
case TX_RFPLL_INT:
case RX_RFPLL_INT:
rate = ad9361_rfpll_int_recalc_rate(clk_priv,
phy->clks[clk_priv->parent_source]->rate);
break;
case RX_RFPLL_DUMMY:
case TX_RFPLL_DUMMY:
rate = ad9361_rfpll_dummy_recalc_rate(clk_priv);
break;
case TX_RFPLL:
case RX_RFPLL:
rate = ad9361_rfpll_recalc_rate(clk_priv);
break;
case BBPLL_CLK:
rate = ad9361_bbpll_recalc_rate(clk_priv,
phy->clks[clk_priv->parent_source]->rate);
break;
case ADC_CLK:
case R2_CLK:
case R1_CLK:
case CLKRF_CLK:
case RX_SAMPL_CLK:
case DAC_CLK:
case T2_CLK:
case T1_CLK:
case CLKTF_CLK:
case TX_SAMPL_CLK:
rate = ad9361_clk_factor_recalc_rate(clk_priv,
phy->clks[clk_priv->parent_source]->rate);
break;
default:
break;
}
return rate;
}
/***************************************************************************//**
* @brief clk_set_rate
*******************************************************************************/
int32_t clk_set_rate(struct ad9361_rf_phy *phy,
struct refclk_scale *clk_priv,
uint32_t rate)
{
uint32_t source;
int32_t i;
uint32_t round_rate;
source = clk_priv->source;
if(phy->clks[source]->rate != rate)
{
switch (source) {
case TX_REFCLK:
case RX_REFCLK:
case BB_REFCLK:
round_rate = ad9361_clk_factor_round_rate(clk_priv, rate,
&phy->clk_refin->rate);
ad9361_clk_factor_set_rate(clk_priv, round_rate,
phy->clk_refin->rate);
phy->clks[source]->rate = ad9361_clk_factor_recalc_rate(clk_priv,
phy->clk_refin->rate);
break;
case TX_RFPLL_INT:
case RX_RFPLL_INT:
round_rate = ad9361_rfpll_int_round_rate(clk_priv, rate,
&phy->clks[clk_priv->parent_source]->rate);
ad9361_rfpll_int_set_rate(clk_priv, round_rate,
phy->clks[clk_priv->parent_source]->rate);
phy->clks[source]->rate = ad9361_rfpll_int_recalc_rate(clk_priv,
phy->clks[clk_priv->parent_source]->rate);
break;
case RX_RFPLL_DUMMY:
case TX_RFPLL_DUMMY:
ad9361_rfpll_dummy_set_rate(clk_priv, rate);
break;
case TX_RFPLL:
case RX_RFPLL:
round_rate = ad9361_rfpll_round_rate(clk_priv, rate);
ad9361_rfpll_set_rate(clk_priv, round_rate);
phy->clks[source]->rate = ad9361_rfpll_recalc_rate(clk_priv);
break;
case BBPLL_CLK:
round_rate = ad9361_bbpll_round_rate(clk_priv, rate,
&phy->clks[clk_priv->parent_source]->rate);
ad9361_bbpll_set_rate(clk_priv, round_rate,
phy->clks[clk_priv->parent_source]->rate);
phy->clks[source]->rate = ad9361_bbpll_recalc_rate(clk_priv,
phy->clks[clk_priv->parent_source]->rate);
phy->bbpll_initialized = true;
break;
case ADC_CLK:
case R2_CLK:
case R1_CLK:
case CLKRF_CLK:
case RX_SAMPL_CLK:
case DAC_CLK:
case T2_CLK:
case T1_CLK:
case CLKTF_CLK:
case TX_SAMPL_CLK:
round_rate = ad9361_clk_factor_round_rate(clk_priv, rate,
&phy->clks[clk_priv->parent_source]->rate);
ad9361_clk_factor_set_rate(clk_priv, round_rate,
phy->clks[clk_priv->parent_source]->rate);
phy->clks[source]->rate = ad9361_clk_factor_recalc_rate(clk_priv,
phy->clks[clk_priv->parent_source]->rate);
break;
default:
break;
}
for(i = BB_REFCLK; i < BBPLL_CLK; i++)
{
phy->clks[i]->rate = ad9361_clk_factor_recalc_rate(phy->ref_clk_scale[i],
phy->clk_refin->rate);
}
phy->clks[BBPLL_CLK]->rate = ad9361_bbpll_recalc_rate(phy->ref_clk_scale[BBPLL_CLK],
phy->clks[phy->ref_clk_scale[BBPLL_CLK]->parent_source]->rate);
for(i = ADC_CLK; i < RX_RFPLL_INT; i++)
{
phy->clks[i]->rate = ad9361_clk_factor_recalc_rate(phy->ref_clk_scale[i],
phy->clks[phy->ref_clk_scale[i]->parent_source]->rate);
}
for(i = RX_RFPLL_INT; i < RX_RFPLL_DUMMY; i++)
{
phy->clks[i]->rate = ad9361_rfpll_int_recalc_rate(phy->ref_clk_scale[i],
phy->clks[phy->ref_clk_scale[i]->parent_source]->rate);
}
for(i = RX_RFPLL_DUMMY; i < RX_RFPLL; i++)
{
phy->clks[i]->rate = ad9361_rfpll_dummy_recalc_rate(phy->ref_clk_scale[i]);
}
for(i = RX_RFPLL; i < NUM_AD9361_CLKS; i++)
{
phy->clks[i]->rate = ad9361_rfpll_recalc_rate(phy->ref_clk_scale[i]);
}
} else {
if ((source == BBPLL_CLK) && !phy->bbpll_initialized) {
round_rate = ad9361_bbpll_round_rate(clk_priv, rate,
&phy->clks[clk_priv->parent_source]->rate);
ad9361_bbpll_set_rate(clk_priv, round_rate,
phy->clks[clk_priv->parent_source]->rate);
phy->clks[source]->rate = ad9361_bbpll_recalc_rate(clk_priv,
phy->clks[clk_priv->parent_source]->rate);
phy->bbpll_initialized = true;
}
}
return 0;
}
/***************************************************************************//**
* @brief int_sqrt
*******************************************************************************/
uint32_t int_sqrt(uint32_t x)
{
uint32_t b, m, y = 0;
if (x <= 1)
return x;
m = 1UL << (BITS_PER_LONG - 2);
while (m != 0) {
b = y + m;
y >>= 1;
if (x >= b) {
x -= b;
y += m;
}
m >>= 2;
}
return y;
}
/***************************************************************************//**
* @brief ilog2
*******************************************************************************/
int32_t ilog2(int32_t x)
{
int32_t A = !(!(x >> 16));
int32_t count = 0;
int32_t x_copy = x;
count = count + (A << 4);
x_copy = (((~A + 1) & (x >> 16)) + (~(~A + 1) & x));
A = !(!(x_copy >> 8));
count = count + (A << 3);
x_copy = (((~A + 1) & (x_copy >> 8)) + (~(~A + 1) & x_copy));
A = !(!(x_copy >> 4));
count = count + (A << 2);
x_copy = (((~A + 1) & (x_copy >> 4)) + (~(~A + 1) & x_copy));
A = !(!(x_copy >> 2));
count = count + (A << 1);
x_copy = (((~A + 1) & (x_copy >> 2)) + (~(~A + 1) & x_copy));
A = !(!(x_copy >> 1));
count = count + A;
return count;
}
/***************************************************************************//**
* @brief find_first_bit
*******************************************************************************/
uint32_t find_first_bit(uint32_t word)
{
int32_t num = 0;
if ((word & 0xffff) == 0) {
num += 16;
word >>= 16;
}
if ((word & 0xff) == 0) {
num += 8;
word >>= 8;
}
if ((word & 0xf) == 0) {
num += 4;
word >>= 4;
}
if ((word & 0x3) == 0) {
num += 2;
word >>= 2;
}
if ((word & 0x1) == 0)
num += 1;
return num;
}
/***************************************************************************//**
* @brief ERR_PTR
*******************************************************************************/
void * ERR_PTR(long error)
{
return (void *) error;
}
/***************************************************************************//**
* @brief zmalloc
*******************************************************************************/
void *zmalloc(size_t size)
{
void *ptr = malloc(size);
if (ptr)
memset(ptr, 0, size);
mdelay(1);
return ptr;
}
@@ -1,120 +0,0 @@
/***************************************************************************//**
* @file ad9361_util.h
* @brief AD9361 Header file of Util driver.
* @author DBogdan (dragos.bogdan@analog.com)
********************************************************************************
* Copyright 2013(c) Analog Devices, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* - Neither the name of Analog Devices, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* - The use of this software may or may not infringe the patent rights
* of one or more patent holders. This license does not release you
* from the requirement that you obtain separate licenses from these
* patent holders to use this software.
* - Use of the software either in source or binary form, must be run
* on or directly connected to an Analog Devices Inc. component.
*
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#ifndef __AD9361_UTIL_H__
#define __AD9361_UTIL_H__
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "ad9361.h"
#include "common.h"
/******************************************************************************/
/********************** Macros and Constants Definitions **********************/
/******************************************************************************/
#define CLK_IGNORE_UNUSED BIT(3)
#define CLK_GET_RATE_NOCACHE BIT(6)
#if defined(HAVE_VERBOSE_MESSAGES)
#define dev_err(dev, format, ...) ({printf(format, ## __VA_ARGS__);printf("\n"); })
#define dev_warn(dev, format, ...) ({printf(format, ## __VA_ARGS__);printf("\n"); })
#if defined(HAVE_DEBUG_MESSAGES)
#define dev_dbg(dev, format, ...) ({printf(format, ## __VA_ARGS__);printf("\n"); })
#else
#define dev_dbg(dev, format, ...) ({ if (0) printf(format, ## __VA_ARGS__); })
#endif
#define printk(format, ...) printf(format, ## __VA_ARGS__)
#else
#define dev_err(dev, format, ...) ({ if (0) printf(format, ## __VA_ARGS__); })
#define dev_warn(dev, format, ...) ({ if (0) printf(format, ## __VA_ARGS__); })
#define dev_dbg(dev, format, ...) ({ if (0) printf(format, ## __VA_ARGS__); })
#define printk(format, ...) ({ if (0) printf(format, ## __VA_ARGS__); })
#endif
struct device {
};
struct spi_device {
struct device dev;
uint8_t id_no;
};
struct axiadc_state {
struct ad9361_rf_phy *phy;
uint32_t pcore_version;
};
struct axiadc_chip_info {
char *name;
int32_t num_channels;
};
struct axiadc_converter {
struct axiadc_chip_info *chip_info;
uint32_t scratch_reg[16];
};
#ifdef WIN32
#include "basetsd.h"
typedef SSIZE_T ssize_t;
#define strsep(s, ct) 0
#define snprintf(s, n, format, ...) 0
#define __func__ __FUNCTION__
#endif
/******************************************************************************/
/************************ Functions Declarations ******************************/
/******************************************************************************/
int32_t clk_prepare_enable(struct clk *clk);
uint32_t clk_get_rate(struct ad9361_rf_phy *phy,
struct refclk_scale *clk_priv);
int32_t clk_set_rate(struct ad9361_rf_phy *phy,
struct refclk_scale *clk_priv,
uint32_t rate);
uint32_t int_sqrt(uint32_t x);
int32_t ilog2(int32_t x);
uint32_t find_first_bit(uint32_t word);
void * ERR_PTR(long error);
void *zmalloc(size_t size);
#endif
@@ -1,66 +0,0 @@
/***************************************************************************//**
* @file common.h
* @brief Header file of Common Driver.
* @author DBogdan (dragos.bogdan@analog.com)
********************************************************************************
* Copyright 2013(c) Analog Devices, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* - Neither the name of Analog Devices, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* - The use of this software may or may not infringe the patent rights
* of one or more patent holders. This license does not release you
* from the requirement that you obtain separate licenses from these
* patent holders to use this software.
* - Use of the software either in source or binary form, must be run
* on or directly connected to an Analog Devices Inc. component.
*
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#ifndef __AD9361_COMMON_H_
#define __AD9361_COMMON_H_
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <stdint.h>
#include "../../../include/error.h"
/******************************************************************************/
/*************************** Types Declarations *******************************/
/******************************************************************************/
#if defined (__STDC__) && (__STDC_VERSION__ >= 199901L)
#include <stdbool.h>
#else
typedef enum { false, true } bool;
#endif
struct clk {
const char *name;
uint32_t rate;
};
struct clk_hw {
struct clk *clk;
};
#endif // __AD9361_COMMON_H_
@@ -1,151 +0,0 @@
/***************************************************************************//**
* @file ad9361_reg.c
* @brief Implementation of AD9680 Driver.
* @author DBogdan (dragos.bogdan@analog.com)
********************************************************************************
* Copyright 2014-2016(c) Analog Devices, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* - Neither the name of Analog Devices, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* - The use of this software may or may not infringe the patent rights
* of one or more patent holders. This license does not release you
* from the requirement that you obtain separate licenses from these
* patent holders to use this software.
* - Use of the software either in source or binary form, must be run
* on or directly connected to an Analog Devices Inc. component.
*
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include "ad9361_reg.h"
#include <stdlib.h>
#include <stdio.h>
#include "../../../include/error.h"
/***************************************************************************//**
* @brief ad9361_reg_read
*******************************************************************************/
int32_t ad9361_reg_read(struct ad9361_reg_dev *dev,
uint16_t reg_addr,
uint8_t *reg_data)
{
uint8_t tx_buf[2];
uint8_t rx_buf[1];
int32_t ret;
tx_buf[0] = reg_addr >> 8;
tx_buf[1] = reg_addr & 0xFF;
ret = spi_write_and_read_3wire(dev->spi_desc,
tx_buf, rx_buf, 2, 1);
*reg_data = rx_buf[0];
return ret;
}
/***************************************************************************//**
* @brief ad9361_reg_write
*******************************************************************************/
int32_t ad9361_reg_write(struct ad9361_reg_dev *dev,
uint16_t reg_addr,
uint8_t reg_data)
{
uint8_t buf[3];
int32_t ret;
buf[0] = 0x80 | reg_addr >> 8;
buf[1] = reg_addr & 0xFF;
buf[2] = reg_data;
ret = spi_write_and_read_3wire(dev->spi_desc,
buf, NULL, 3, 0);
return ret;
}
/***************************************************************************//**
* @brief ad9361_reg_init
*******************************************************************************/
int32_t ad9361_reg_init(struct ad9361_reg_dev **device,
const struct ad9361_reg_init_param *init_param)
{
int ret = SUCCESS;
struct ad9361_reg_dev *dev;
dev = (struct ad9361_reg_dev *)malloc(sizeof(*dev));
if (!dev)
return FAILURE;
/* SPI */
ret = spi_init(&dev->spi_desc, init_param->spi_init);
ret |= gpio_get(&dev->gpio_desc_resetb, init_param->gpio_resetb);
gpio_direction_output(dev->gpio_desc_resetb, 0);
ad9361_reg_reset(dev);
*device = dev;
return ret;
}
/**
* AD9361 Device Reset
* @param phy The AD9361 state structure.
* @return 0 in case of success, negative error code otherwise.
*/
int32_t ad9361_reg_reset(struct ad9361_reg_dev *dev)
{
if (dev->gpio_desc_resetb) {
gpio_set_value(dev->gpio_desc_resetb, 0);
mdelay(10);
gpio_set_value(dev->gpio_desc_resetb, 1);
mdelay(10);
return 0;
}
return 0;
}
/***************************************************************************//**
* @brief Free the resources allocated by ad9361_reg_setup().
*
* @param dev - The device structure.
*
* @return SUCCESS in case of success, negative error code otherwise.
*******************************************************************************/
int32_t ad9361_reg_remove(struct ad9361_reg_dev *dev)
{
int32_t ret;
ret = spi_remove(dev->spi_desc);
free(dev);
return ret;
}
@@ -1,104 +0,0 @@
/***************************************************************************//**
* @file ad9361_reg.h
* @brief Header file of ad9361_reg Driver.
* @author DBogdan (dragos.bogdan@analog.com)
********************************************************************************
* Copyright 2014-2016(c) Analog Devices, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* - Neither the name of Analog Devices, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* - The use of this software may or may not infringe the patent rights
* of one or more patent holders. This license does not release you
* from the requirement that you obtain separate licenses from these
* patent holders to use this software.
* - Use of the software either in source or binary form, must be run
* on or directly connected to an Analog Devices Inc. component.
*
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#ifndef ad9361_reg_H_
#define ad9361_reg_H_
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <stdint.h>
#include "delay.h"
#include "spi.h"
#include "gpio.h"
/******************************************************************************/
/********************** Macros and Constants Definitions **********************/
/******************************************************************************/
/******************************************************************************/
/*************************** Types Declarations *******************************/
/******************************************************************************/
struct ad9361_reg_dev {
/* SPI */
struct spi_desc *spi_desc;
struct gpio_desc *gpio_desc_resetb;
};
struct ad9361_reg_init_param {
/* SPI */
struct spi_init_param *spi_init;
struct gpio_init_param *gpio_resetb;
};
enum Operation_Type{
AD9361_WRITE,
AD9361_READ,
AD9361_WAIT,
AD9361_WHEN
};
struct ad9361_reg_config {
int operation;
uint16_t val1;
uint16_t val2;
};
/******************************************************************************/
/************************ Functions Declarations ******************************/
/******************************************************************************/
int32_t ad9361_reg_read(struct ad9361_reg_dev *dev,
uint16_t reg_addr,
uint8_t *reg_data);
int32_t ad9361_reg_write(struct ad9361_reg_dev *dev,
uint16_t reg_addr,
uint8_t reg_data);
int32_t ad9361_reg_init(struct ad9361_reg_dev **device,
const struct ad9361_reg_init_param *init_param);
int32_t ad9361_reg_reset(struct ad9361_reg_dev *dev);
int32_t ad9361_reg_remove(struct ad9361_reg_dev *dev);
#endif
+542
View File
@@ -0,0 +1,542 @@
/*****************************************************************************/
/**
* 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
};
#ifdef _GE_APP_
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
};
#else
#error No application type is specified.
#endif
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
};
/************************** 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");
}
}
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);
}
}
}
} // main
+85
View File
@@ -0,0 +1,85 @@
/*****************************************************************************/
/**
* 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)
#define _GE_APP_
/*********** Debug Info Level ************/
// #define _DEBUG_LEVEL 1
// 3 - print all debug info
// 2 - print warnings and errors
// 1 - print only errors
// other - print nothing
/************ 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
#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 "global_timer.h"
#include "../config/app_config.h"
#include "../app_config.h"
struct global_timer_init_param globaltimer_init_param = {
.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
};
+276
View File
@@ -0,0 +1,276 @@
/**
* \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 "delay.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,9 +1,9 @@
/***************************************************************************//**
* @file ad9361_conv.c
* @brief Implementation of AD9361 Conv Driver.
* @file ad9371/src/devices/adi_hal/parameters.h
* @brief Platform dependent parameters.
* @author DBogdan (dragos.bogdan@analog.com)
********************************************************************************
* Copyright 2014-2015(c) Analog Devices, Inc.
* Copyright 2019(c) Analog Devices, Inc.
*
* All rights reserved.
*
@@ -36,51 +36,46 @@
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#ifndef _PARAMETERS_H_
#define _PARAMETERS_H_
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <inttypes.h>
#include <string.h>
#include "ad9361.h"
#include "ad9361_util.h"
#include "delay.h"
#include "../../../config/app_config.h"
#include "platform_drivers.h"
#include "xparameters.h"
/******************************************************************************/
/********************** Macros and Constants Definitions **********************/
/******************************************************************************/
#define DDR_MEM_BASEADDR XPAR_DDR_MEM_BASEADDR
#define GPIO_0_DEVICE_ID XPAR_PS7_GPIO_0_DEVICE_ID
/**
* HDL loopback enable/disable.
* @param phy The AD9361 state structure.
* @param enable Enable/disable option.
* @return 0 in case of success, negative error code otherwise.
*/
int32_t ad9361_hdl_loopback(struct ad9361_rf_phy *phy, bool enable)
{
return -ENODEV;
}
//#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
/**
* Digital tune.
* @param phy The AD9361 state structure.
* @param max_freq Maximum frequency.
* @param flags Flags: BE_VERBOSE, BE_MOREVERBOSE, DO_IDELAY, DO_ODELAY.
* @return 0 in case of success, negative error code otherwise.
*/
int32_t ad9361_dig_tune(struct ad9361_rf_phy *phy, uint32_t max_freq,
enum dig_tune_flags flags)
{
return 0;
}
#define GPIO_OFFSET 54
#define AD9528_CS 1
#define AD9371_CS 2
/**
* Setup the AD9361 device.
* @param phy The AD9361 state structure.
* @return 0 in case of success, negative error code otherwise.
*/
int32_t ad9361_post_setup(struct ad9361_rf_phy *phy)
{
return 0;
}
#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
#endif
+371
View File
@@ -0,0 +1,371 @@
/***************************************************************************//**
* @file platform_drivers.c
* @brief Implementation of Xilinx Platform Drivers.
* @author DBogdan (dragos.bogdan@analog.com)
********************************************************************************
* 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;
}
@@ -1,9 +1,9 @@
/***************************************************************************//**
* @file gpio.h
* @brief Header file of GPIO Interface
* @file platform_drivers.h
* @brief Header file of Xilinx Platform Drivers.
* @author DBogdan (dragos.bogdan@analog.com)
********************************************************************************
* Copyright 2019(c) Analog Devices, Inc.
* Copyright 2018(c) Analog Devices, Inc.
*
* All rights reserved.
*
@@ -37,133 +37,124 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#ifndef _GPIO_H_
#define _GPIO_H_
#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 spi_type {
XILINX_SPI
} spi_type;
/**
* @struct gpio_platform_ops
* @brief Structure holding gpio function pointers that point to the platform
* specific function
* @enum spi_mode
* @brief SPI configuration for clock phase and polarity.
*/
struct gpio_platform_ops ;
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;
/**
* @enum gpio_pull_up
* @brief Enum that holds the possible pull up/ pull down resistor configuration.
*/
enum gpio_pull_up {
PULL_NONE,
/** Strong pull up */
PULL_UP,
/** Strong pull down */
PULL_DOWN,
PULL_UP_WEAK,
PULL_DOWN_WEAK
};
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;
/**
* @struct gpio_init_param
* @brief Structure holding the parameters for GPIO initialization.
*/
struct gpio_init_param {
/** Port number */
int32_t port;
/** GPIO number */
int32_t number;
/** Pull up/down resistor configuration */
enum gpio_pull_up pull;
/** GPIO platform specific functions */
const struct gpio_platform_ops *platform_ops;
/** GPIO extra parameters (device specific) */
void *extra;
};
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;
/**
* @struct gpio_desc
* @brief Structure holding the GPIO descriptor.
*/
struct gpio_desc {
/** Port number */
int32_t port;
/** GPIO number */
int32_t number;
/** Pull up/down resistor configuration */
enum gpio_pull_up pull;
/** GPIO platform specific functions */
const struct gpio_platform_ops *platform_ops;
/** GPIO extra parameters (device specific) */
void *extra;
};
typedef enum gpio_type {
XILINX_GPIO
} gpio_type;
/**
* @enum gpio_values
* @brief Enum that holds the possible output states of a GPIO.
*/
enum gpio_values {
/** GPIO logic low */
GPIO_LOW,
/** GPIO logic high */
GPIO_HIGH,
/** GPIO high impedance */
GPIO_HIGH_Z
};
/**
* @struct gpio_platform_ops
* @brief Structure holding gpio function pointers that point to the platform
* specific function
*/
struct gpio_platform_ops {
/** gpio initialization function pointer */
int32_t (*gpio_ops_get)(struct gpio_desc **,
const struct gpio_init_param *);
/** gpio optional descriptor function pointer */
int32_t (*gpio_ops_get_optional)(struct gpio_desc **,
const struct gpio_init_param *);
/** gpio remove function pointer */
int32_t (*gpio_ops_remove)(struct gpio_desc *);
/** gpio direction input function pointer */
int32_t (*gpio_ops_direction_input)(struct gpio_desc *);
/** gpio direction output function pointer */
int32_t (*gpio_ops_direction_output)(struct gpio_desc *, uint8_t);
/** gpio get direction function pointer */
int32_t (*gpio_ops_get_direction)(struct gpio_desc *, uint8_t *);
/** gpio set value function pointer */
int32_t (*gpio_ops_set_value)(struct gpio_desc *, uint8_t);
/** gpio get value function pointer */
int32_t (*gpio_ops_get_value)(struct gpio_desc *, uint8_t *);
};
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,
const struct gpio_init_param *param);
uint8_t gpio_number);
/* Obtain optional GPIO descriptor. */
int32_t gpio_get_optional(struct gpio_desc **desc,
const struct gpio_init_param *param);
/* Free the resources allocated by gpio_get(). */
/* Free the resources allocated by gpio_get() */
int32_t gpio_remove(struct gpio_desc *desc);
/* Enable the input direction of the specified GPIO. */
@@ -171,18 +162,18 @@ 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);
uint8_t value);
/* Get the direction of the specified GPIO. */
int32_t gpio_get_direction(struct gpio_desc *desc,
uint8_t *direction);
uint8_t *direction);
/* Set the value of the specified GPIO. */
int32_t gpio_set_value(struct gpio_desc *desc,
uint8_t value);
uint8_t value);
/* Get the value of the specified GPIO. */
int32_t gpio_get_value(struct gpio_desc *desc,
uint8_t *value);
uint8_t *value);
#endif // _GPIO_H_
#endif // PLATFORM_DRIVERS_H_
-474
View File
@@ -1,474 +0,0 @@
/*****************************************************************************/
/**
* Description: hwconfig.h
*
* Date: 2024-02-20 13:19
* Last Edit Time: [2024-02-20 13:19]
*
* Revisions: Rev 0.0
* History:
* [2023-05-07]: Initial edition.
*
* Copyright(c) 2024 Beijing Institute of Technology.
*
******************************************************************************/
/***************************** Include Files *********************************/
// Standard
#include <stdint.h>
#include <stdbool.h>
// Xilinx
#include "xgpiops.h"
#include "drivers/rf-transceiver/ad9361_reg/ad9361_reg.h"
#include "drivers/rf-transceiver/ad9361/ad9361_api.h"
#include "drivers/axi_core/spi_engine/spi_engine.h"
// App
#include "common.h"
#include "error.h"
#include "delay.h"
#include "system_monitor.h"
#include "hwconfig.h"
#include "config/app_config.h"
#include "dev_profile/dev_profile.h"
/************************** Function Prototypes ******************************/
/*********************** Driver Instance Definitions **************************/
static struct hmc7044_dev *hmc7044_inst = NULL;
static struct ad9361_reg_dev *ad9361_1_reg_inst = NULL;
static struct ad9361_reg_dev *ad9361_2_reg_inst = NULL;
// static struct ad9361_rf_phy *ad9361_phy;
// static struct ad9361_rf_phy *ad9361_2_phy;
/*****************************************************************************/
/**
* @brief Hardware_Init
*
* @param none.
*
* @return None.
*
******************************************************************************/
int32_t Hardware_Init(void)
{
int32_t Status;
XGpioPs Gpio;
XGpioPs_Config *ConfigPtr;
ConfigPtr = XGpioPs_LookupConfig(AD9361_GPIO_DEVICE_ID);
Status = XGpioPs_CfgInitialize(&Gpio, ConfigPtr, ConfigPtr->BaseAddr);
if (Status != SUCCESS)
{
return FAILURE;
}
/**********************************************************/
/****************** HMC7044 Configuration *****************/
/**********************************************************/
Status = hmc7044_init(&hmc7044_inst, &hmc7044_default_init_param);
if (Status != SUCCESS)
{
DBG_ERROR("hmc7044_init() error: %" PRId32 "\n", Status);
return FAILURE;
}
/**********************************************************/
/***************** AD9361-1 Configuration *****************/
/**********************************************************/
XGpioPs_SetDirectionPin(&Gpio, AD9361_1_TXNRX, AD9361_GPIO_OUTPUT);
XGpioPs_SetDirectionPin(&Gpio, AD9361_1_ENABLE, AD9361_GPIO_OUTPUT);
XGpioPs_SetDirectionPin(&Gpio, AD9361_1_EN_AGC, AD9361_GPIO_OUTPUT);
XGpioPs_SetDirectionPin(&Gpio, AD9361_1_RESET_B, AD9361_GPIO_OUTPUT);
ad9361_reg_init(&ad9361_1_reg_inst, &ad9361_1_reg_default_init_param);
XGpioPs_WritePin(&Gpio, AD9361_1_ENABLE, 0);
ad9361_reg_config(ad9361_1_reg_inst);
XGpioPs_WritePin(&Gpio, AD9361_1_ENABLE, 1);
// Status = ad9361_init(&ad9361_phy, &ad9361_default_init_param);
// if (Status != XST_SUCCESS){
// return XST_FAILURE;
// }else{
// printf("Configurate AD9361 Completely!\n");
// }
// ad9361_set_tx_fir_config(ad9361_phy, tx_fir_config);
// ad9361_set_rx_fir_config(ad9361_phy, rx_fir_config);
/**********************************************************/
/***************** AD9361-2 Configuration *****************/
/**********************************************************/
XGpioPs_SetDirectionPin(&Gpio, AD9361_2_TXNRX, AD9361_GPIO_OUTPUT);
XGpioPs_SetDirectionPin(&Gpio, AD9361_2_ENABLE, AD9361_GPIO_OUTPUT);
XGpioPs_SetDirectionPin(&Gpio, AD9361_2_EN_AGC, AD9361_GPIO_OUTPUT);
XGpioPs_SetDirectionPin(&Gpio, AD9361_2_RESET_B, AD9361_GPIO_OUTPUT);
ad9361_reg_init(&ad9361_2_reg_inst, &ad9361_2_reg_default_init_param);
XGpioPs_WritePin(&Gpio, AD9361_2_ENABLE, 0);
ad9361_reg_config(ad9361_2_reg_inst);
XGpioPs_WritePin(&Gpio, AD9361_2_ENABLE, 1);
// uint8_t rd_back;
// Status = ad9361_reg_read(ad9361_1_reg_inst, 0x0002, &rd_back);
// Status = ad9361_reg_read(ad9361_2_reg_inst, 0x0002, &rd_back);
/**********************************************************/
/******* AD9361 Baseband Multichip Synchronization ********/
/**********************************************************/
XGpioPs_SetDirectionPin(&Gpio, AD9361_SYNC, AD9361_GPIO_OUTPUT);
XGpioPs_SetDirectionPin(&Gpio, AD9361_RX_FIFO_RST, AD9361_GPIO_OUTPUT);
// SYNC BBPLL and DIGITAL SAMPLING CLOCKS
ad9361_reg_write(ad9361_1_reg_inst, 0x0001, 0x0D); // MCS RF Enable; MCS BBPLL Enable; MCS BB Enable
ad9361_reg_write(ad9361_2_reg_inst, 0x0001, 0x0D);
ad9361_reg_write(ad9361_1_reg_inst, 0x0047, 0x80); // MCS refclk Scale Enable
ad9361_reg_write(ad9361_2_reg_inst, 0x0047, 0x80);
XGpioPs_WritePin(&Gpio, AD9361_SYNC, 0);
mdelay(20);
XGpioPs_WritePin(&Gpio, AD9361_SYNC, 1); // Input a rising-edge pulse to the SYNC_IN pin
mdelay(500);
XGpioPs_WritePin(&Gpio, AD9361_SYNC, 0);
mdelay(2000);
ad9361_reg_write(ad9361_1_reg_inst, 0x0001, 0x0B); // MCS RF Enable; MCS Digital CLK Enable ; MCS BB Enable
ad9361_reg_write(ad9361_2_reg_inst, 0x0001, 0x0B);
XGpioPs_WritePin(&Gpio, AD9361_SYNC, 1); // Input another rising-edge pulse to the SYNC_IN pin
mdelay(500);
XGpioPs_WritePin(&Gpio, AD9361_SYNC, 0);
ad9361_reg_write(ad9361_1_reg_inst, 0x0001, 0x08); // clear MCS bits
ad9361_reg_write(ad9361_2_reg_inst, 0x0001, 0x08);
XGpioPs_WritePin(&Gpio, AD9361_RX_FIFO_RST, 0);
mdelay(20);
XGpioPs_WritePin(&Gpio, AD9361_RX_FIFO_RST, 1);
mdelay(20);
XGpioPs_WritePin(&Gpio, AD9361_RX_FIFO_RST, 0);
/**********************************************************/
/********* AD9361 Multichip Rx Phase Calibration **********/
/**********************************************************/
XGpioPs_SetDirectionPin(&Gpio, AD9361_TX_SWITCH, AD9361_GPIO_OUTPUT);
XGpioPs_SetDirectionPin(&Gpio, AD9361_1_CAL_START, AD9361_GPIO_OUTPUT);
XGpioPs_SetDirectionPin(&Gpio, AD9361_1_CAL_DONE, AD9361_GPIO_INPUT);
XGpioPs_SetDirectionPin(&Gpio, AD9361_2_CAL_START, AD9361_GPIO_OUTPUT);
XGpioPs_SetDirectionPin(&Gpio, AD9361_2_CAL_DONE, AD9361_GPIO_INPUT);
// switch to lower frequency
Status = Hardware_SwitchFreq(ad9361_1_reg_inst, TX_FREQ_126);
XGpioPs_WritePin(&Gpio, AD9361_TX_SWITCH, 1);
mdelay(20);
// switch rx channel
Status = ad9361_reg_write(ad9361_1_reg_inst, 0x0004, 0x30);
Status = ad9361_reg_write(ad9361_2_reg_inst, 0x0004, 0x30);
// enable dual ad9361 tx channels
Status = ad9361_reg_write(ad9361_1_reg_inst, 0x0002, 0xE4); // Setup Tx Digital Filters/ Channels
// switch ad9361 tx channel
Status = ad9361_reg_write(ad9361_1_reg_inst, 0x0004, 0x70); // Select Rx input pin(A,B,C)/ Tx out pin (A,B)
mdelay(20);
// begin to calibrate the 1st ad9361
XGpioPs_WritePin(&Gpio, AD9361_1_CAL_START, 0);
XGpioPs_WritePin(&Gpio, AD9361_1_CAL_START, 1);
mdelay(1);
XGpioPs_WritePin(&Gpio, AD9361_1_CAL_START, 0);
// read calibration status
int32_t time_out_cnt = 0;
do
{
mdelay(1); // Wait 1ms
time_out_cnt++;
} while (((XGpioPs_ReadPin(&Gpio, AD9361_1_CAL_DONE) == 0) && time_out_cnt <= AD9361_TIMEOUT_TH));
if (time_out_cnt == AD9361_TIMEOUT_TH)
{
return FAILURE;
}
// begin to calibrate the 2nd ad9361
XGpioPs_WritePin(&Gpio, AD9361_2_CAL_START, 1);
mdelay(1);
XGpioPs_WritePin(&Gpio, AD9361_2_CAL_START, 0);
// read calibration status
time_out_cnt = 0;
do
{
mdelay(1); // Wait 1ms
time_out_cnt++;
} while (((XGpioPs_ReadPin(&Gpio, AD9361_2_CAL_DONE) == 0) && time_out_cnt <= AD9361_TIMEOUT_TH));
if (time_out_cnt == AD9361_TIMEOUT_TH)
{
return FAILURE;
}
// enable single ad9361 tx channels
Status = ad9361_reg_write(ad9361_1_reg_inst, 0x0002, 0xA4); // Setup Tx Digital Filters/ Channels
// switch ad9361 tx & rx channel
Status = ad9361_reg_write(ad9361_1_reg_inst, 0x0004, 0x03);
Status = ad9361_reg_write(ad9361_2_reg_inst, 0x0004, 0x03);
// switch to higher frequency
Status = Hardware_SwitchFreq(ad9361_1_reg_inst, TX_FREQ_4125);
XGpioPs_WritePin(&Gpio, AD9361_TX_SWITCH, 0);
Status = ad9361_reg_write(ad9361_1_reg_inst, 0x0109, 0x00); // Rx Gain
Status = ad9361_reg_write(ad9361_1_reg_inst, 0x010C, 0x00); // Rx Gain
Status = ad9361_reg_write(ad9361_2_reg_inst, 0x0109, 0x00); // Rx Gain
Status = ad9361_reg_write(ad9361_2_reg_inst, 0x010C, 0x00); // Rx Gain
DBG_PRINT("Done.\n");
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Hardware_SwitchFreq
*
* @param devSysMonitor_UpdateHardwareStatus(newHwState);
* @param freq
*
* @return None.
*
******************************************************************************/
int32_t Hardware_SwitchFreq(struct ad9361_reg_dev *dev, ad9361TxFreq freq)
{
int32_t status = 0;
uint8_t value = 0;
int32_t time_out_cnt = 0;
switch (freq)
{
case TX_FREQ_125:
{
//************************************************************
// Setup Tx Frequency-Dependent Syntheisizer Registers
//************************************************************
status = ad9361_reg_write(dev, 0x027A, 0x4A); // Set VCO Output level[3:0]
status = ad9361_reg_write(dev, 0x0279, 0xC1); // Set Init ALC Value[3:0] and VCO Varactor[3:0]
status = ad9361_reg_write(dev, 0x0282, 0x0E); // Set VCO Bias Tcf[1:0] and VCO Bias Ref[2:0]
status = ad9361_reg_write(dev, 0x0278, 0x78); // Set VCO Cal Offset[3:0]
status = ad9361_reg_write(dev, 0x0285, 0x00); // Set VCO Cal Ref Tcf[2:0]
status = ad9361_reg_write(dev, 0x0291, 0x0B); // Set VCO Varactor Reference[3:0]
status = ad9361_reg_write(dev, 0x0290, 0x70); // Set VCO Varactor Ref Tcf[2:0] and VCO Varactor Offset[3:0]
status = ad9361_reg_write(dev, 0x027B, 0x94); // Set Synth Loop Filter charge pump current (Icp)
status = ad9361_reg_write(dev, 0x027E, 0xF4); // Set Synth Loop Filter C2 and C1
status = ad9361_reg_write(dev, 0x027F, 0xDF); // Set Synth Loop Filter R1 and C3
status = ad9361_reg_write(dev, 0x0280, 0x0A); // Set Synth Loop Filter R3
//************************************************************
// Write Tx Frequency Words
//************************************************************
status = ad9361_reg_write(dev, 0x0273, 0x00); // Write Tx Synth Fractional Freq Word[7:0]
status = ad9361_reg_write(dev, 0x0274, 0x00); // Write Tx Synth Fractional Freq Word[15:8]
status = ad9361_reg_write(dev, 0x0275, 0x00); // Write Tx Synth Fractional Freq Word[22:16]
status = ad9361_reg_write(dev, 0x0272, 0x00); // Write Tx Synth Integer Freq Word[10:8]
status = ad9361_reg_write(dev, 0x0271, 0xA0); // Write Tx Synth Integer Freq Word[7:0] (starts VCO cal)
status = ad9361_reg_write(dev, 0x0005, 0x57); // Set LO divider setting
//************************************************************
// Tx Quadrature Calibration Settings
//************************************************************
status = ad9361_reg_write(dev, 0x00A0, 0x75); // Set TxQuadcal NCO frequency
status = ad9361_reg_write(dev, 0x00A3, 0xC0); // Set TxQuadcal NCO frequency (Only update bits [7:6])
status = ad9361_reg_write(dev, 0x00A1, 0x7B); // Tx Quad Cal Configuration, Phase and Gain Cal Enable
status = ad9361_reg_write(dev, 0x00A9, 0xFF); // Set Tx Quad Cal Count
status = ad9361_reg_write(dev, 0x00A2, 0x7F); // Set Tx Quad Cal Kexp
status = ad9361_reg_write(dev, 0x00A5, 0x01); // Set Tx Quad Cal Magnitude Threshhold
status = ad9361_reg_write(dev, 0x00A6, 0x01); // Set Tx Quad Cal Magnitude Threshhold
status = ad9361_reg_write(dev, 0x00AA, 0x22); // Set Tx Quad Cal Gain Table index
status = ad9361_reg_write(dev, 0x00A4, 0xF0); // Set Tx Quad Cal Settle Count
status = ad9361_reg_write(dev, 0x00AE, 0x00); // Set Tx Quad Cal LPF Gain index incase Split table mode used
status = ad9361_reg_write(dev, 0x0169, 0xC0); // Disable Rx Quadrature Calibration before Running Tx Quadrature Calibration
status = ad9361_reg_write(dev, 0x0016, 0x10); // Start Tx Quad cal
break;
}
case TX_FREQ_126:
{
//************************************************************
// Setup Tx Frequency-Dependent Syntheisizer Registers
//************************************************************
status = ad9361_reg_write(dev, 0x027A, 0x4A); // Set VCO Output level[3:0]
status = ad9361_reg_write(dev, 0x0279, 0xC1); // Set Init ALC Value[3:0] and VCO Varactor[3:0]
status = ad9361_reg_write(dev, 0x0282, 0x0E); // Set VCO Bias Tcf[1:0] and VCO Bias Ref[2:0]
status = ad9361_reg_write(dev, 0x0278, 0x78); // Set VCO Cal Offset[3:0]
status = ad9361_reg_write(dev, 0x0285, 0x00); // Set VCO Cal Ref Tcf[2:0]
status = ad9361_reg_write(dev, 0x0291, 0x0B); // Set VCO Varactor Reference[3:0]
status = ad9361_reg_write(dev, 0x0290, 0x70); // Set VCO Varactor Ref Tcf[2:0] and VCO Varactor Offset[3:0]
status = ad9361_reg_write(dev, 0x027B, 0x93); // Set Synth Loop Filter charge pump current (Icp)
status = ad9361_reg_write(dev, 0x027E, 0xF4); // Set Synth Loop Filter C2 and C1
status = ad9361_reg_write(dev, 0x027F, 0xDF); // Set Synth Loop Filter R1 and C3
status = ad9361_reg_write(dev, 0x0280, 0x0A); // Set Synth Loop Filter R3
//************************************************************
// Write Tx Frequency Words
//************************************************************
status = ad9361_reg_write(dev, 0x0273, 0x06); // Write Tx Synth Fractional Freq Word[7:0]
status = ad9361_reg_write(dev, 0x0274, 0xD7); // Write Tx Synth Fractional Freq Word[15:8]
status = ad9361_reg_write(dev, 0x0275, 0x23); // Write Tx Synth Fractional Freq Word[22:16]
status = ad9361_reg_write(dev, 0x0272, 0x00); // Write Tx Synth Integer Freq Word[10:8]
status = ad9361_reg_write(dev, 0x0271, 0xA1); // Write Tx Synth Integer Freq Word[7:0] (starts VCO cal)
status = ad9361_reg_write(dev, 0x0005, 0x57); // Set LO divider setting
//************************************************************
// Tx Quadrature Calibration Settings
//************************************************************
status = ad9361_reg_write(dev, 0x00A0, 0x75); // Set TxQuadcal NCO frequency
status = ad9361_reg_write(dev, 0x00A3, 0xC0); // Set TxQuadcal NCO frequency (Only update bits [7:6])
status = ad9361_reg_write(dev, 0x00A1, 0x7B); // Tx Quad Cal Configuration, Phase and Gain Cal Enable
status = ad9361_reg_write(dev, 0x00A9, 0xFF); // Set Tx Quad Cal Count
status = ad9361_reg_write(dev, 0x00A2, 0x7F); // Set Tx Quad Cal Kexp
status = ad9361_reg_write(dev, 0x00A5, 0x01); // Set Tx Quad Cal Magnitude Threshhold
status = ad9361_reg_write(dev, 0x00A6, 0x01); // Set Tx Quad Cal Magnitude Threshhold
status = ad9361_reg_write(dev, 0x00AA, 0x22); // Set Tx Quad Cal Gain Table index
status = ad9361_reg_write(dev, 0x00A4, 0xF0); // Set Tx Quad Cal Settle Count
status = ad9361_reg_write(dev, 0x00AE, 0x00); // Set Tx Quad Cal LPF Gain index incase Split table mode used
status = ad9361_reg_write(dev, 0x0169, 0xC0); // Disable Rx Quadrature Calibration before Running Tx Quadrature Calibration
status = ad9361_reg_write(dev, 0x0016, 0x10); // Start Tx Quad cal
break;
}
case TX_FREQ_4125:
{
//************************************************************
// Setup Tx Frequency-Dependent Syntheisizer Registers
//************************************************************
status = ad9361_reg_write(dev, 0x027A, 0x4A); // Set VCO Output level[3:0]
status = ad9361_reg_write(dev, 0x0279, 0xC1); // Set Init ALC Value[3:0] and VCO Varactor[3:0]
status = ad9361_reg_write(dev, 0x0282, 0x0E); // Set VCO Bias Tcf[1:0] and VCO Bias Ref[2:0]
status = ad9361_reg_write(dev, 0x0278, 0x78); // Set VCO Cal Offset[3:0]
status = ad9361_reg_write(dev, 0x0285, 0x00); // Set VCO Cal Ref Tcf[2:0]
status = ad9361_reg_write(dev, 0x0291, 0x0B); // Set VCO Varactor Reference[3:0]
status = ad9361_reg_write(dev, 0x0290, 0x70); // Set VCO Varactor Ref Tcf[2:0] and VCO Varactor Offset[3:0]
status = ad9361_reg_write(dev, 0x027B, 0x93); // Set Synth Loop Filter charge pump current (Icp)
status = ad9361_reg_write(dev, 0x027E, 0xF4); // Set Synth Loop Filter C2 and C1
status = ad9361_reg_write(dev, 0x027F, 0xDF); // Set Synth Loop Filter R1 and C3
status = ad9361_reg_write(dev, 0x0280, 0x0A); // Set Synth Loop Filter R3
//************************************************************
// Write Rx Frequency Words
//************************************************************
status = ad9361_reg_write(dev, 0x0273, 0x00); // Write Tx Synth Fractional Freq Word[7:0]
status = ad9361_reg_write(dev, 0x0274, 0x00); // Write Tx Synth Fractional Freq Word[15:8]
status = ad9361_reg_write(dev, 0x0275, 0x00); // Write Tx Synth Fractional Freq Word[22:16]
status = ad9361_reg_write(dev, 0x0272, 0x00); // Write Tx Synth Integer Freq Word[10:8]
status = ad9361_reg_write(dev, 0x0271, 0xA5); // Write Tx Synth Integer Freq Word[7:0] (starts VCO cal)
status = ad9361_reg_write(dev, 0x0005, 0x07); // Set LO divider setting
//************************************************************
// Tx Quadrature Calibration Settings
//************************************************************
status = ad9361_reg_write(dev, 0x00A0, 0x75); // Set TxQuadcal NCO frequency
status = ad9361_reg_write(dev, 0x00A3, 0xC0); // Set TxQuadcal NCO frequency (Only update bits [7:6])
status = ad9361_reg_write(dev, 0x00A1, 0x7B); // Tx Quad Cal Configuration, Phase and Gain Cal Enable
status = ad9361_reg_write(dev, 0x00A9, 0xFF); // Set Tx Quad Cal Count
status = ad9361_reg_write(dev, 0x00A2, 0x7F); // Set Tx Quad Cal Kexp
status = ad9361_reg_write(dev, 0x00A5, 0x01); // Set Tx Quad Cal Magnitude Threshhold
status = ad9361_reg_write(dev, 0x00A6, 0x01); // Set Tx Quad Cal Magnitude Threshhold
status = ad9361_reg_write(dev, 0x00AA, 0x28); // Set Tx Quad Cal Gain Table index
status = ad9361_reg_write(dev, 0x00A4, 0xF0); // Set Tx Quad Cal Settle Count
status = ad9361_reg_write(dev, 0x00AE, 0x04); // Set Tx Quad Cal LPF Gain index incase Split table mode used
status = ad9361_reg_write(dev, 0x0169, 0xC0); // Disable Rx Quadrature Calibration before Running Tx Quadrature Calibration
status = ad9361_reg_write(dev, 0x0016, 0x10); // Start Tx Quad cal
break;
}
// Wait for cal to complete (Done when 0x016[4]==0)
time_out_cnt = 0;
do
{
status |= ad9361_reg_read(dev, 0x0016, &value);
mdelay(1); // Wait 1ms
time_out_cnt++;
} while ((value & 0x10) != 0x00 && time_out_cnt <= AD9361_TIMEOUT_TH);
}
return status;
}
// @ Get AD9361 - 1 temperature (Celsius Degree)
/**
* Read corresponding register to get AD9361 - 1 current temperature.
*/
int8_t Hardware_GetAD9361Temp_1(void)
{
int8_t scaleTemp;
double temp;
ad9361_reg_write(ad9361_1_reg_inst, 0x000B, -64);
ad9361_reg_write(ad9361_1_reg_inst, 0x001D, 0x01); // disable aux adc
ad9361_reg_read(ad9361_1_reg_inst, 0x000E, (uint8_t*)&scaleTemp);
ad9361_reg_write(ad9361_1_reg_inst, 0x001D, 0x00); // enable aux adc
temp = ((double)scaleTemp + 64)/1.16;
return ((temp > INT8_MAX) ? INT8_MAX : (int8_t)temp);
}
// @ Get AD9361 - 2 temperature (Celsius Degree)
/**
* Read corresponding register to get AD9361 - 2 current temperature.
*/
int8_t Hardware_GetAD9361Temp_2(void)
{
int8_t scaleTemp;
double temp;
ad9361_reg_write(ad9361_2_reg_inst, 0x000B, -64);
ad9361_reg_write(ad9361_2_reg_inst, 0x001D, 0x01); // disable aux adc
ad9361_reg_read(ad9361_2_reg_inst, 0x000E, (uint8_t*)&scaleTemp);
ad9361_reg_write(ad9361_2_reg_inst, 0x001D, 0x00); // enable aux adc
temp = ((double)scaleTemp + 64)/1.16;
return ((temp > INT8_MAX) ? INT8_MAX : (int8_t)temp);
}
// @ Determine AD9361 lock state
/**
* Read corresponding register to determine AD9361(both) lock state.
*/
uint8_t Hardware_GetAD9361LockStatus(void)
{
uint8_t ret = 0;
uint8_t regVal;
// bbpll
ad9361_reg_read(ad9361_1_reg_inst, 0x005E, &regVal); // [D7] is lock indicator
ret |= ((regVal & 0x80) == 0x80) ? CLK_AD0_BBPLL_LOCK : 0;
ad9361_reg_read(ad9361_2_reg_inst, 0x005E, &regVal); // [D7] is lock indicator
ret |= ((regVal & 0x80) == 0x80) ? CLK_AD1_BBPLL_LOCK : 0;
// rfpll
ad9361_reg_read(ad9361_1_reg_inst, 0x0287, &regVal); // [D1] is lock indicator
ret |= ((regVal & 0x02) == 0x02) ? CLK_AD0_RFPLL_LOCK : 0;
ad9361_reg_read(ad9361_2_reg_inst, 0x0287, &regVal); // [D1] is lock indicator
ret |= ((regVal & 0x02) == 0x02) ? CLK_AD1_RFPLL_LOCK : 0;
return ret;
}
// @ Determine HMC7044 lock state
/**
* Read corresponding register to determine clock lock state.
*/
uint8_t Hardware_GetHMC7044LockStatus(void)
{
uint8_t ret = 0;
uint8_t regVal;
// pll1
hmc7044_read(hmc7044_inst, 0x007C, &regVal); // [D5] is lock indicator
ret |= ((regVal & 0xE0) != 0x00) ? CLK_SP_PLL0_LOCK : 0;
// pll2
hmc7044_read(hmc7044_inst, 0x007D, &regVal); // [D0] is lock indicator
ret |= ((regVal & 0x01) == 0x01) ? CLK_SP_PLL1_LOCK : 0;
return ret;
}
-33
View File
@@ -1,33 +0,0 @@
/*****************************************************************************/
/**
* Description: hwconfig.h
*
* Date: 2024-02-20 13:19
* Last Edit Time: [2024-02-20 13:19]
*
* Revisions: Rev 0.0
* History:
* [2023-05-07]: Initial edition.
*
* Copyright(c) 2024 Beijing Institute of Technology.
*
******************************************************************************/
#ifndef HWCONFIG_H_
#define HWCONFIG_H_
/***************************** Include Files *********************************/
// Standard
#include <stdint.h>
#include "config/app_config.h"
#include "drivers/rf-transceiver/ad9361_reg/ad9361_reg.h"
#include "drivers/rf-transceiver/ad9361/ad9361_api.h"
/************************** Function Prototypes ******************************/
int32_t Hardware_Init(void);
int32_t Hardware_SwitchFreq(struct ad9361_reg_dev *dev, ad9361TxFreq freq);
int8_t Hardware_GetAD9361Temp_1(void);
int8_t Hardware_GetAD9361Temp_2(void);
uint8_t Hardware_GetAD9361LockStatus(void);
uint8_t Hardware_GetHMC7044LockStatus(void);
#endif // HWCONFIG_H_
+2 -2
View File
@@ -38,7 +38,7 @@
#endif
#define FAILURE -1
#define EPARAM -2 /*!< Data crc check failed */
#define EPARAM -2 /*!< Invalid parameters */
#define ECRC -3 /*!< Data crc check failed */
#define EDINVAL -4 /*!< Device is invalid (sleep or power off) */
#define EDCONF -5 /*!< Device confugure error */
@@ -53,4 +53,4 @@
/** @} ERRORNO*/
/** @} COMMON_MACRO*/
/** @} COMMON_MACRO*/
-134
View File
@@ -1,134 +0,0 @@
/***************************************************************************//**
* @file i2c.h
* @brief Header file of I2C Interface
* @author DBogdan (dragos.bogdan@analog.com)
********************************************************************************
* 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 _I2C_H_
#define _I2C_H_
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include <stdint.h>
/******************************************************************************/
/*************************** Types Declarations *******************************/
/******************************************************************************/
/**
* @struct i2c_platform_ops
* @brief Structure holding I2C function pointers that point to the platform
* specific function
*/
struct i2c_platform_ops ;
/**
* @struct i2c_init_param
* @brief Structure holding the parameters for I2C initialization.
*/
struct i2c_init_param {
/** Device ID */
uint32_t device_id;
/** I2C maximum transfer speed supported */
uint32_t max_speed_hz;
/** Slave address */
uint8_t slave_address;
/** I2C platform specific functions */
const struct i2c_platform_ops *platform_ops;
/** I2C extra parameters (device specific parameters) */
void *extra;
};
/**
* @struct i2c_desc
* @brief Structure holding I2C descriptor
*/
struct i2c_desc {
/** Device ID */
uint32_t device_id;
/** I2C maximum transfer speed supported */
uint32_t max_speed_hz;
/** Slave address */
uint8_t slave_address;
/** I2C platform specific functions */
const struct i2c_platform_ops *platform_ops;
/** I2C extra parameters (device specific parameters) */
void *extra;
};
/**
* @struct i2c_platform_ops
* @brief Structure holding i2c function pointers that point to the platform
* specific function
*/
struct i2c_platform_ops {
/** i2c initialization function pointer */
int32_t (*i2c_ops_init)(struct i2c_desc **,
const struct i2c_init_param *);
/** i2c write function pointer */
int32_t (*i2c_ops_write)(struct i2c_desc *, uint8_t *, uint8_t, uint8_t);
/** i2c write function pointer */
int32_t (*i2c_ops_read)(struct i2c_desc *, uint8_t *, uint8_t, uint8_t);
/** i2c remove function pointer */
int32_t (*i2c_ops_remove)(struct i2c_desc *);
};
/******************************************************************************/
/************************ Functions Declarations ******************************/
/******************************************************************************/
/* Initialize the I2C communication peripheral. */
int32_t i2c_init(struct i2c_desc **desc,
const struct i2c_init_param *param);
/* Free the resources allocated by i2c_init(). */
int32_t i2c_remove(struct i2c_desc *desc);
/* Write data to a slave device. */
int32_t i2c_write(struct i2c_desc *desc,
uint8_t *data,
uint8_t bytes_number,
uint8_t stop_bit);
/* Read data from a slave device. */
int32_t i2c_read(struct i2c_desc *desc,
uint8_t *data,
uint8_t bytes_number,
uint8_t stop_bit);
#endif // _I2C_H_
+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 (mihail.chindris@analog.com)
********************************************************************************
* @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_
+703
View File
@@ -0,0 +1,703 @@
/*****************************************************************************/
/**
* 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;
}
//NOTE: Clear previous log.
memset(&(linkInstPtr->log), 0x00, sizeof(L2_LOG));
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"
/************************** Constant Definitions *****************************/
/*****************************************************************************/
/**
* @brief Insert a data chunk to a bit array.
@@ -42,7 +41,7 @@
* @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(chunk != NULL);
@@ -61,13 +60,33 @@ void L2_FrameInsertChunk(uint8_t *frame, size_t offset, size_t bytes, const void
* @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(chunk != NULL);
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.
+73 -22
View File
@@ -27,10 +27,7 @@
#include "common.h"
#include "util.h"
#include "circ_queue.h"
#include "../time_ctrl/time_ctrl.h"
#ifndef EMULATION
#include "../config/app_config.h"
#endif
#include "time_ctrl/time_ctrl.h"
/************************** Constant Definitions *****************************/
#define NET_START_TIME_INFTY UINT32_MAX
#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.cfmCorrectCnt = isValid ? instPtr->log.cfmCorrectCnt + 1 : instPtr->log.cfmCorrectCnt;
break;
case L2_SVC_FRAME:
#ifndef DATALINK_ENABLE_BERTEST
isValid = L2_CrcCheck(instPtr->recvPktData, L2_SVC_PACK_LEN, L2_CRC16_1021);
#else
isValid = true;
#endif
case L2_SVC_2K_FRAME:
isValid = L2_CrcCheck(instPtr->recvPktData, L2_SVC_PACK_2K_LEN, L2_CRC16_1021);
instPtr->log.svcRecvCnt++;
instPtr->log.svcCorrectCnt = isValid ? instPtr->log.svcCorrectCnt + 1 : instPtr->log.svcCorrectCnt;
break;
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.svcCorrectCnt = isValid ? instPtr->log.svcCorrectCnt + 1 : instPtr->log.svcCorrectCnt;
break;
@@ -333,6 +336,15 @@ inline L2_FRAME_TYPE L2_GetCurrentFrameType(L2_INST *instPtr)
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.
*/
@@ -422,8 +434,12 @@ L1_FRAME_TYPE L2_L2frame2L1frame(L2_FRAME_TYPE l2Frame)
case L2_ADV_FRAME:
return L1_10KBPS_20MS_FRAME;
case L2_CFM_FRAME:
case L2_SVC_FRAME:
case L2_SVC_2K_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:
return L1_NONE_FRAME;
}
@@ -471,6 +487,7 @@ int32_t Linklayer_Init(L2_INST **instPtr, const L2_CONFIG *config)
// Clear random content
memset(*instPtr, 0x00, sizeof(L2_INST));
(*instPtr)->speedMode = config->speedMode;
(*instPtr)->sendPktData = NULL;
(*instPtr)->recvPktData = 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)
{
UpdateMainSate(instPtr, L2_NORMAL_STATE);
instPtr->rtneConfig.rtneTable = normalTable;
instPtr->rtneConfig.rtnePrd = ARRAY_SIZE(normalTable);
switch(L2_GetCurrentSpeedMode(instPtr)){
case L2_SPEED_NONE :
DBG_WARNING("Speed mode not configured, fallback to 128Kbps mode.\n");
case L2_SPEED_128KBPS :
instPtr->rtneConfig.rtneTable = normalTable128K;
instPtr->rtneConfig.rtnePrd = ARRAY_SIZE(normalTable128K);
break;
case L2_SPEED_2KBPS :
instPtr->rtneConfig.rtneTable = normalTable2K;
instPtr->rtneConfig.rtnePrd = ARRAY_SIZE(normalTable2K);
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
{
@@ -856,7 +890,9 @@ int32_t Linklayer_PktHandler(L2_INST *instPtr, L2_FRAME_TYPE frameType)
case L2_CFM_FRAME:
Status = L2_Scan_PktHandler(instPtr, instPtr->recvPktData);
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);
break;
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.
*/
#ifdef DATALINK_ENABLE_AUTORECONNECT
static bool IsNodeConnected(NODE_ENTRY *node)
{
ASSERT(node != NULL);
@@ -895,7 +930,6 @@ static bool IsNodeConnected(NODE_ENTRY *node)
return false;
}
}
#endif
/*****************************************************************************/
/**
@@ -937,7 +971,9 @@ static int32_t Linklayer_Routine(L2_INST *instPtr)
case L2_SLOT_CONFIRM:
Status = L2_Scan_Routine(instPtr, &rtneEntry);
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);
break;
default:
@@ -956,7 +992,7 @@ static int32_t Linklayer_Routine(L2_INST *instPtr)
uint32_t increment = 1;
L2_IterEditNode(instPtr->nodeList, &increment, IntcNodeTTL);
#ifdef DATALINK_ENABLE_AUTORECONNECT
//#ifdef DATALINK_ENABLE_AUTORECONNECT
if (L2_GetMainState(instPtr) != L2_INIT_STATE)
{
L2_IterDeleteNode(instPtr->nodeList, IsNodeConnected);
@@ -970,7 +1006,7 @@ static int32_t Linklayer_Routine(L2_INST *instPtr)
AssertL2Event(instPtr, &l2Event);
}
}
#endif
//#endif
return Status;
}
@@ -1165,7 +1201,7 @@ int32_t L2_SetupNextSlot(L2_INST *instPtr, L2_TOR_TYPE txrxMode, L2_FRAME_TYPE f
ASSERT(instPtr != NULL);
PHY_INST *phyRef = instPtr->config.phyInstPtr;
int32_t Status;
if (frameType < L2_SCAN_FRAME || frameType > L2_SVC_FRAME)
if (frameType < L2_SCAN_FRAME || frameType > L2_SVC_256K_FRAME)
{
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:
instPtr->log.cfmTxCnt++;
break;
case L2_SVC_FRAME:
case L2_SVC_2K_FRAME:
case L2_SVC_128K_FRAME:
case L2_SVC_256K_FRAME:
instPtr->log.svcTxCnt++;
break;
default:
@@ -1200,7 +1238,9 @@ int32_t L2_SetupNextSlot(L2_INST *instPtr, L2_TOR_TYPE txrxMode, L2_FRAME_TYPE f
case L2_CFM_FRAME:
instPtr->log.cfmRxCnt++;
break;
case L2_SVC_FRAME:
case L2_SVC_2K_FRAME:
case L2_SVC_128K_FRAME:
case L2_SVC_256K_FRAME:
instPtr->log.svcRxCnt++;
break;
default:
@@ -1284,5 +1324,16 @@ int32_t L2_SetupNextSlot(L2_INST *instPtr, L2_TOR_TYPE txrxMode, L2_FRAME_TYPE f
}
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*/
+14 -5
View File
@@ -25,8 +25,8 @@
#include "schdevent.h"
#include "node_list.h"
#include "circ_queue.h"
#include "../phy_layer/phy_layer.h"
#include "../../system_monitor.h"
#include "networking/phy_layer/phy_layer.h"
#include "system_monitor.h"
/************************** Constant Definitions *****************************/
/***************** Macros (Inline Functions) Definitions *********************/
#define AssertL2Event(instPtr, event) (Linklayer_EventHandler((instPtr), (event)))
@@ -45,6 +45,9 @@ typedef struct
uint8_t netScale; ///< net scale
PHY_INST *phyInstPtr; ///< pointer to system physical 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;
/**
@@ -104,6 +107,7 @@ typedef struct
L2_RTNE_CONFIG rtneConfig; ///< current routine table configuration and status.
L2_SCAN_FSM *scanFSM; ///< FSM of scan net (link set up)
L2_SVC_FSM *serviceFSM; ///< FSM of service net (data service)
L2_SPEED_MODE speedMode;
uint8_t *sendPktData; ///< send data buffer
uint8_t *recvPktData; ///< received data buffer
L2_LOG log; ///< Linklayer operating log
@@ -114,7 +118,9 @@ typedef struct
/************************** Variable Definitions *****************************/
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 ******************************/
/**
* @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 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 Linklayer_UpdateSpeedMode(L2_INST *instPtr, L2_SPEED_MODE mode);
/** @} 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_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);
bool L2_CrcCheck(uint8_t *dataBuff, uint32_t dataLen, L2_CRC_TYPE crcType);
/** @} 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_Destroy(L2_SVC_FSM *svcFSMPtr);
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);
/** @} LinkLayer_Service*/
@@ -206,6 +213,7 @@ L2_TOR_TYPE L2_GetLastTor(L2_INST *instPtr);
uint32_t L2_GetCurrentFrameNum(L2_INST *instPtr);
uint32_t L2_GetCurrentSlotNum(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);
uint32_t L2_GetNextFrameNum(L2_INST *instPtr);
uint32_t L2_GetNextSlotNum(L2_INST *instPtr);
@@ -213,8 +221,9 @@ L2_FRAME_TYPE L2_GetNextFrameType(L2_INST *instPtr);
L2_TOR_TYPE L2_GetNextTor(L2_INST *instPtr);
L2_FRAME_TYPE L2_GetLastOptFrameType(L2_INST *instPtr);
L1_FRAME_TYPE L2_L2frame2L1frame(L2_FRAME_TYPE l2Frame);
/** @} LinkLayer_Utility*/
#endif /* __LINK_LAYER_H_ */
/** @} LinkLayer*/
/** @} LinkLayer*/
+28 -13
View File
@@ -21,12 +21,10 @@
/***************************** Include Files *********************************/
#include <stdbool.h>
#include <stdint.h>
#include "ring_buffer.h"
#include "geometry/coord.h"
#include "geometry/quaternion.h"
#include "../phy_layer/phy_layer.h"
#ifndef EMULATION
#include "../config/app_config.h"
#endif
#include "networking/phy_layer/phy_layer.h"
/************************** Constant Definitions *****************************/
/**
* @name Linklayer_Common_Constants
@@ -158,7 +156,9 @@ typedef enum
L2_SLOT_SCAN = 2,
L2_SLOT_ADVERTISE = 3,
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;
/**
@@ -170,9 +170,22 @@ typedef enum
L2_SCAN_FRAME = 1,
L2_ADV_FRAME = 2,
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;
/**
* @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
*/
@@ -234,12 +247,10 @@ typedef struct
uint32_t txCnt; ///< tx frame count
uint32_t rxCnt; ///< rx frame count
uint32_t rxdCnt; ///< received frame count
#ifdef DATALINK_ENABLE_BERTEST
uint32_t bitTotal; ///< received bits count
uint32_t bitError; ///< error bits count
double lossRate; ///< packet loss rate
double errorRate; ///< bit error rate
#endif
uint8_t currTxSeq; ///< seqid of current tx frame sub-packet
uint8_t currRxSeq; ///< seqid of current rx frame sub-packet
RING_BUFFER *currTxBuff; ///< a ring buffer to store data to be sent
RING_BUFFER *currRxBuff; ///< a ring buffer to store data received
} L2_SVC_FSM;
/**
@@ -255,8 +266,12 @@ typedef struct
L2_RTNE_TABLE_ENTRY *next; ///< next routine entry
} L2_RTNE_CONFIG;
typedef bool (*PUSHUP_HANDLE) (RING_BUFFER *buff);
typedef bool (*POPUP_HANDLE) (RING_BUFFER **buff);
/************************** Variable Definitions *****************************/
#endif /* __LINK_LAYER_DEF_H_ */
/** @} LinkLayer*/
/** @} LinkLayer*/
+34 -29
View File
@@ -1,6 +1,6 @@
/*****************************************************************************/
/**
* @file msg_def.c
* @file msg_def.h
* @author FanHao (hao_fan_bit_ee@163.com)
* @brief DF Linklayer message definition constants.
* @version 0.0
@@ -20,14 +20,34 @@
* @name LinkLayer_MSG_Constants
* @{
*/
#ifndef __L2_MSG_DEF_H_
#define __L2_MSG_DEF_H_
#define L2_PACK_LEN_MAX 512 // bytes
#include "link_layer.h"
#define L2_PACK_LEN_MAX 1024 // bytes
#define L2_ADV_PACK_LEN 28 // 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:
// [bytes] [name]
@@ -96,35 +116,20 @@
// service payload structure:
// [bytes] [name]
// 4 position x
// 4 position y
// 4 position z
// 4 speed x
// 4 speed y
// 4 speed z
// 234 payload
// 2 crc
#define L2_MSG_SVC_SRC_POSX 8
#define L2_MSG_SVC_SRC_POSX_LEN 4
#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
// 1 packet flag
// 1 packet id
// 2 data length
#define L2_MSG_SVC_PKTFLG 8 // 0-no subpacket, 1-subpacket 2-last subpacket
#define L2_MSG_SVC_PKTFLG_LEN 1
#define L2_MSG_SVC_PKTID 9
#define L2_MSG_SVC_PKTID_LEN 1
#define L2_MSG_SVC_DLEN 10
#define L2_MSG_SVC_DLEN_LEN 2
#define L2_MSG_SVC_PAYLOAD 12
#define L2_MSG_SVC_CRC_LEN 2
#endif //__L2_MSG_DEF_H_
/** @} LinkLayer_MSG_Constants*/
/** @} LinkLayer*/
/** @} LinkLayer*/
+319 -84
View File
@@ -137,127 +137,362 @@ L2_RTNE_TABLE_ENTRY intraScanSubT[L2_SLOTS_PER_FRAME] = {
{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
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x03, 0x02, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x03, 0x02, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
// SubFrame 1
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x03, 0x02, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x03, 0x02, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
// SubFrame 2
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x03, 0x02, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x03, 0x02, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
// SubFrame 3
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x03, 0x02, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x03, 0x02, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
// SubFrame 4
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x03, 0x02, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE_2K, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE_2K, 0x03, 0x02, 0x01},
{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] =
{
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*/
/** @} LinkLayer*/
/** @} LinkLayer*/
+48 -86
View File
@@ -28,7 +28,7 @@
#include "node_list.h"
#include "error.h"
#include "common.h"
#include "../phy_layer/phy_layer.h"
#include "networking/phy_layer/phy_layer.h"
/************************** Constant Definitions *****************************/
#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);
int32_t Status;
uint32_t dataChunk;
uint8_t *buff = instPtr->sendPktData;
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
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);
L2_ASSEMBLE_INTEGER(buff, L2_MSG_FRAME_NUM, L2_GetNextFrameNum(instPtr));
L2_ASSEMBLE_INTEGER(buff, L2_MSG_SLOT_NUM, L2_GetNextSlotNum(instPtr));
L2_ASSEMBLE_INTEGER(buff, L2_MSG_SRC_ID, L2_GetNodeId(instPtr));
L2_ASSEMBLE_INTEGER(buff, L2_MSG_DST_ID, dstId);
switch (type)
{
case L2_ADV_FRAME:
{
dataChunk = L2_ADV_FRAME;
L2_FrameInsertChunk(buff, L2_MSG_TYPE, L2_MSG_TYPE_LEN, &dataChunk);
L2_ASSEMBLE_INTEGER(buff, L2_MSG_TYPE, L2_ADV_FRAME);
SysMonitor_GetSysinfo(&(instPtr->sysInfo));
// insert position and speed info
L2_FrameInsertChunk(buff, L2_MSG_ADV_SRC_POSX, L2_MSG_ADV_SRC_POSX_LEN, &(instPtr->sysInfo.posX));
L2_FrameInsertChunk(buff, L2_MSG_ADV_SRC_POSY, L2_MSG_ADV_SRC_POSY_LEN, &(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_POSX, &(instPtr->sysInfo.posX));
L2_ASSEMBLE_FLOAT(buff, L2_MSG_ADV_SRC_POSY, &(instPtr->sysInfo.posY));
L2_ASSEMBLE_FLOAT(buff, L2_MSG_ADV_SRC_POSZ, &(instPtr->sysInfo.posZ));
// 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
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)
{
DBG_ERROR("Fail to append CRC, error code: %" PRId32 ".\n", Status);
return Status;
ASSERT(true);
}
break;
}
case L2_CFM_FRAME:
{
dataChunk = L2_CFM_FRAME;
L2_FrameInsertChunk(buff, L2_MSG_TYPE, L2_MSG_TYPE_LEN, &dataChunk);
L2_ASSEMBLE_INTEGER(buff, L2_MSG_TYPE, L2_CFM_FRAME);
SysMonitor_GetSysinfo(&(instPtr->sysInfo));
// insert position and speed info
L2_FrameInsertChunk(buff, L2_MSG_CFM_SRC_POSX, L2_MSG_CFM_SRC_POSX_LEN, &(instPtr->sysInfo.posX));
L2_FrameInsertChunk(buff, L2_MSG_CFM_SRC_POSY, L2_MSG_CFM_SRC_POSY_LEN, &(instPtr->sysInfo.posY));
L2_FrameInsertChunk(buff, L2_MSG_CFM_SRC_POSZ, L2_MSG_CFM_SRC_POSZ_LEN, &(instPtr->sysInfo.posZ));
L2_FrameInsertChunk(buff, L2_MSG_CFM_SRC_SPEEDX, L2_MSG_CFM_SRC_SPEEDX_LEN, &(instPtr->sysInfo.vX));
L2_FrameInsertChunk(buff, L2_MSG_CFM_SRC_SPEEDY, L2_MSG_CFM_SRC_SPEEDY_LEN, &(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_POSX, &(instPtr->sysInfo.posX));
L2_ASSEMBLE_FLOAT(buff, L2_MSG_CFM_SRC_POSY, &(instPtr->sysInfo.posY));
L2_ASSEMBLE_FLOAT(buff, L2_MSG_CFM_SRC_POSZ, &(instPtr->sysInfo.posZ));
L2_ASSEMBLE_FLOAT(buff, L2_MSG_CFM_SRC_SPEEDX, &(instPtr->sysInfo.vX));
L2_ASSEMBLE_FLOAT(buff, L2_MSG_CFM_SRC_SPEEDY, &(instPtr->sysInfo.vY));
L2_ASSEMBLE_FLOAT(buff, L2_MSG_CFM_SRC_SPEEDZ, &(instPtr->sysInfo.vZ));
// 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
Status = L2_CrcAppend(buff, L2_CMF_PACK_LEN - L2_MSG_CFM_CRC_LEN, L2_MSG_CFM_CRC, L2_CRC16_1021);
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);
return Status;
}
// Logging...
memcpy(instPtr->log.txLog.data, buff, L2_CMF_PACK_LEN);
instPtr->log.txLog.dataId = dataId;
break;
}
default:
@@ -469,7 +443,7 @@ int32_t L2_Scan_PktHandler(L2_INST *instPtr, uint8_t *msg)
int32_t Status;
L2_SCAN_FSM *scanFsmPtr = instPtr->scanFSM;
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)
{
case L2_SCAN_FRAME:
@@ -487,7 +461,7 @@ int32_t L2_Scan_PktHandler(L2_INST *instPtr, uint8_t *msg)
break;
}
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 = L2_GetNodeById(instPtr->nodeList, nodeId);
if (node == NULL)
@@ -502,30 +476,32 @@ int32_t L2_Scan_PktHandler(L2_INST *instPtr, uint8_t *msg)
}
// Update node info.
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;
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;
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.beamNo = Phy_LastScanBeamNo(instPtr->config.phyInstPtr);
// Reset node ttl
node->ttlCnt = 0;
uint32_t netstartTime;
uint32_t netstartTime = 0;
// 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 = {
.event = L2_EV_NET_ADV_UPDATE,
.msg = &netstartTime};
AssertL2Event(instPtr, &netSetupDoneEvent);
// Calculate time deviation
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));
uint32_t frameNum = 0;
uint32_t slotNum = 0;
int64_t timeDev = 0;
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)
{
DBG_ERROR("Failed to compute time deviation.\n")
@@ -533,7 +509,8 @@ int32_t L2_Scan_PktHandler(L2_INST *instPtr, uint8_t *msg)
}
// Time sync.
L2_TimeAdjust(instPtr, &(instPtr->log.timeDev));
L2_TimeAdjust(instPtr, &timeDev);
instPtr->log.timeDev = timeDev;
// trigger flag
AdvRecvStateUpdate(scanFsmPtr, true);
@@ -543,7 +520,7 @@ int32_t L2_Scan_PktHandler(L2_INST *instPtr, uint8_t *msg)
case L2_CFM_FRAME:
{
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 = L2_GetNodeById(instPtr->nodeList, nodeId);
if (node == NULL)
@@ -558,33 +535,36 @@ int32_t L2_Scan_PktHandler(L2_INST *instPtr, uint8_t *msg)
}
// Update node info.
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;
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;
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;
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;
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;
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;
// Reset node ttl
node->ttlCnt = 0;
// Calculate time deviation
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));
uint32_t frameNum = 0;
uint32_t slotNum = 0;
int64_t timeDev = 0;
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)
{
DBG_ERROR("Failed to compute time deviation.\n")
break;
}
instPtr->log.timeDev = timeDev;
if (L2_GetNodeType(instPtr) != L2_NODE_HEAD)
{
@@ -625,24 +605,6 @@ int32_t L2_Scan_PktHandler(L2_INST *instPtr, uint8_t *msg)
(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;
break;
}
+235 -221
View File
@@ -28,51 +28,69 @@
#include "error.h"
#include "common.h"
#include "circ_queue.h"
#ifndef EMULATION
#include "../config/app_config.h"
#endif
/************************** 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 *********************/
/**************************** Type Definitions *******************************/
/************************** Function Prototypes ******************************/
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 *****************************/
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] =
{
0x39, 0x85, 0x02, 0xF0, 0xC7, 0x6A, 0xE8, 0xB4, 0xE7, 0xAB, 0xC9, 0xDC, 0x0B, 0x41, 0x42, 0xE0,
0xED, 0x21, 0x07, 0x62, 0x4E, 0x80, 0xA0, 0xE1, 0xAC, 0x77, 0x9B, 0x1F, 0x48, 0x0B, 0x58, 0xB9,
0x45, 0xA5, 0x24, 0xEF, 0xF3, 0x71, 0x2E, 0x84, 0x6C, 0x22, 0xB3, 0x05, 0xEB, 0x75, 0xF2, 0x0B,
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,
0x3A, 0x2B, 0x58, 0x07, 0xF6, 0x01, 0x1C, 0x73, 0x28, 0x11, 0xA8, 0x15, 0xA2, 0x58, 0x32, 0x2E,
0x7D, 0x35, 0x9C, 0xE4, 0x98, 0x7F, 0x9C, 0x81, 0x32, 0xAA, 0xC4, 0x87, 0x16, 0x26, 0x23, 0x95,
0x57, 0xC9, 0xD4, 0x34, 0xCE, 0x63, 0x78, 0x7E, 0xD4, 0x3C, 0x16, 0x1D, 0x80, 0xC0, 0x55, 0xBF,
0xB5, 0xD6, 0x0C, 0xA5, 0xB9, 0x0A, 0x14, 0x5B, 0x4D, 0x52, 0xF2, 0xA9, 0x7A, 0x08, 0x67, 0x8E,
0xEB, 0x67, 0x34, 0x7F, 0x7A, 0x35, 0xAF, 0xD9, 0x07, 0x52, 0x30, 0x38, 0x70, 0xC9, 0x41, 0xF8,
0x36, 0x61, 0x32, 0x72, 0xA4, 0x7A, 0xEA, 0x21, 0xB4, 0xBF, 0xAA, 0xCF, 0x93, 0x4F, 0xE1, 0x5C,
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,
0x23, 0xE3, 0x51, 0x8F, 0x1A, 0xC1, 0xAF, 0x47, 0x9C, 0x14, 0xCE, 0xB9, 0xCD, 0xD0, 0x02, 0xB7,
0xB8, 0x81, 0xCC, 0x44, 0xE7, 0xA2, 0x6F, 0x32, 0x8C, 0x78, 0x79, 0x10, 0xF3, 0xE1, 0xB0, 0x7C,
0xAB, 0x40, 0xDB, 0xF9, 0x99, 0xE7, 0x27, 0x30, 0x53, 0x67, 0x00, 0xE8, 0x33, 0x6D, 0xFC, 0x4D,
0xDC, 0xB0, 0xFC, 0x3D, 0xEF, 0x8D, 0x43, 0xAF, 0x7E, 0x41, 0x69, 0xDA, 0xFD, 0xDF, 0x2F, 0xF8,
0xEC, 0xFB, 0x6A, 0x65, 0xE7, 0xEC, 0xC7, 0x53, 0x1B, 0x14, 0xDF, 0xBD, 0x0C, 0x54, 0x57, 0xD2,
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,
0xAA, 0xDC, 0xD6, 0x3F, 0x56, 0xB2, 0x6A, 0x3C, 0x6F, 0xAA, 0xAC, 0x84, 0xAC, 0x3F, 0x3D, 0x05,
0x96, 0x12, 0x44, 0x39, 0x1C, 0xD1, 0xFA, 0xBE, 0x6B, 0x1A, 0xCD, 0x31, 0x29, 0x41, 0x31, 0xA3,
0xA8, 0x0D, 0x87, 0xEB, 0x96, 0x21, 0x39, 0xD6, 0x3B, 0x11, 0x50, 0xB5, 0xFE, 0x44, 0x0E, 0x74,
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,
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
};
static inline void resetCurrRx(L2_INST *instPtr) {
ASSERT(instPtr != NULL);
ASSERT(instPtr->serviceFSM->currRxBuff != NULL);
RingBuff_Flush(instPtr->serviceFSM->currRxBuff);
instPtr->serviceFSM->currRxSeq = 0;
}
static inline bool uploadCurrRx(L2_INST *instPtr) {
ASSERT(instPtr != NULL);
ASSERT(instPtr->config.pushUpHandle != NULL);
bool ret = instPtr->config.pushUpHandle(instPtr->serviceFSM->currRxBuff);
instPtr->serviceFSM->currRxBuff = NULL;
instPtr->serviceFSM->currRxSeq = 0;
return ret;
}
static inline bool updateCurrTx(L2_INST *instPtr) {
ASSERT(instPtr != NULL);
ASSERT(instPtr->config.popUpHandle != NULL);
if(instPtr->serviceFSM->currTxBuff == NULL) {
instPtr->serviceFSM->currTxSeq = 0;
return (instPtr->config.popUpHandle(&(instPtr->serviceFSM->currTxBuff)));
}
if(RingBuff_Size(instPtr->serviceFSM->currTxBuff) == 0) {
free(instPtr->serviceFSM->currTxBuff);
instPtr->serviceFSM->currTxSeq = 0;
return (instPtr->config.popUpHandle(&(instPtr->serviceFSM->currTxBuff)));
}
return true;
}
/*****************************************************************************/
/**
@@ -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)
{
#ifndef DATALINK_ENABLE_BERTEST
ASSERT(instPtr != NULL);
int32_t Status;
uint32_t dataChunk;
uint8_t *buff = instPtr->sendPktData;
// 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);
uint8_t *sendBuff = instPtr->sendPktData;
size_t payloadMax, packetLen;
switch (type)
{
case L2_SVC_FRAME:
{
dataChunk = L2_SVC_FRAME;
L2_FrameInsertChunk(buff, L2_MSG_TYPE, L2_MSG_TYPE_LEN, &dataChunk);
SysMonitor_GetSysinfo(&(instPtr->sysInfo));
// insert position and speed info
L2_FrameInsertChunk(buff, L2_MSG_SVC_SRC_POSX, L2_MSG_SVC_SRC_POSX_LEN, &(instPtr->sysInfo.posX));
L2_FrameInsertChunk(buff, L2_MSG_SVC_SRC_POSY, L2_MSG_SVC_SRC_POSY_LEN, &(instPtr->sysInfo.posY));
L2_FrameInsertChunk(buff, L2_MSG_SVC_SRC_POSZ, L2_MSG_SVC_SRC_POSZ_LEN, &(instPtr->sysInfo.posZ));
L2_FrameInsertChunk(buff, L2_MSG_SVC_SRC_SPEEDX, L2_MSG_SVC_SRC_SPEEDX_LEN, &(instPtr->sysInfo.vX));
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;
case L2_SVC_2K_FRAME:
packetLen = L2_SVC_PACK_2K_LEN;
payloadMax = PAYLOAD_LEN_2K;
break;
case L2_SVC_128K_FRAME:
packetLen = L2_SVC_PACK_128K_LEN;
payloadMax = PAYLOAD_LEN_128K;
break;
case L2_SVC_256K_FRAME:
packetLen = L2_SVC_PACK_256K_LEN;
payloadMax = PAYLOAD_LEN_256K;
break;
}
default:
{
DBG_ERROR("Unexpected frame type: %" PRIu8 ".\n", type);
return EPARAM;
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 SUCCESS;
}
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;
#else
DBG_ERROR("Unexpected call of Service_Packing in BER test mode.\n");
return EUNEXP;
#endif
}
/*****************************************************************************/
@@ -175,118 +200,109 @@ int32_t L2_Service_PktHandler(L2_INST *instPtr, uint8_t *msg)
ASSERT(instPtr != NULL);
ASSERT(msg != NULL);
int32_t Status;
#ifndef DATALINK_ENABLE_BERTEST
L2_FRAME_TYPE frameType = L2_NONE_FRAME;
L2_FrameGetChunk(msg, L2_MSG_TYPE, L2_MSG_TYPE_LEN, &frameType);
size_t packetLen;
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;
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 = L2_GetNodeById(instPtr->nodeList, nodeId);
if (node == NULL)
{
uint8_t nodeId;
L2_FrameGetChunk(msg, L2_MSG_SRC_ID, L2_MSG_SRC_ID_LEN, &nodeId);
NODE_ENTRY *node;
node = L2_GetNodeById(instPtr->nodeList, nodeId);
node = L2_AppendNode(instPtr->nodeList, nodeId, L2_NODE_MEMBER);
if (node == NULL)
{
node = L2_AppendNode(instPtr->nodeList, nodeId, L2_NODE_MEMBER);
if (node == NULL)
{
DBG_ERROR("Failed to append new node [id: %" PRIu8 "]", nodeId);
Status = ENOMEM;
break;
}
DBG_ERROR("Failed to append new node [id: %" PRIu8 "]", nodeId);
ASSERT(true);
}
// 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
node->ttlCnt = 0;
// Calculate time deviation
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")
break;
}
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.
if (L2_GetNodeType(instPtr) != L2_NODE_HEAD)
{
// Time sync.
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;
instPtr->serviceFSM->bitTotal += L2_SVC_PACK_LEN * 8;
// Reset node ttl
node->ttlCnt = 0;
// Calculate time deviation
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));
uint32_t frameNum = 0;
uint32_t slotNum = 0;
int64_t timeDev = 0;
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)
{
DBG_ERROR("Failed to compute time deviation.\n")
return Status;
ASSERT(true);
}
instPtr->log.timeDev = timeDev;
// Implement a auto time sync.
if (L2_GetNodeType(instPtr) != L2_NODE_HEAD)
{
// Time sync.
L2_TimeAdjust(instPtr, &(instPtr->log.timeDev));
L2_TimeAdjust(instPtr, &timeDev);
}
return SUCCESS;
#endif
// TODO: check
uint8_t pktType, pktId;
L2_DEASSEMBLE(msg, L2_MSG_SVC_PKTFLG, &pktType);
L2_DEASSEMBLE(msg, L2_MSG_SVC_PKTID, &pktId);
if(pktType != PACKET_TYPE_SINGLE && pktType != PACKET_TYPE_SUBPKT && pktType != PACKET_TYPE_LASTPKT)
{
DBG_INFO("Dummy packet, discard...\n");
return SUCCESS;
}
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->rxCnt = 0;
svcFSMPtr->rxdCnt = 0;
#ifdef DATALINK_ENABLE_BERTEST
svcFSMPtr->bitTotal = 0;
svcFSMPtr->bitError = 0;
svcFSMPtr->lossRate = 0;
svcFSMPtr->errorRate = 0;
#endif
svcFSMPtr->currTxSeq = 0;
svcFSMPtr->currRxSeq = 0;
svcFSMPtr->currTxBuff = NULL;
svcFSMPtr->currRxBuff = NULL;
}
/*****************************************************************************/
@@ -399,40 +413,40 @@ int32_t L2_Service_Routine(L2_INST *instPtr, const L2_RTNE_TABLE_ENTRY *rtneEntr
Phy_SetBeamWidth(phyRef, PHY_ANT_BEAM_120);
instPtr->log.lastBeamWidth = PHY_ANT_BEAM_120;
}
L2_FRAME_TYPE frameType = L2_NONE_FRAME;
switch (rtneEntry->slotType)
{
case L2_SLOT_SERVICE:
if (torState == L2_TOR_TX)
{
svcFSMPtr->txCnt++;
#ifndef DATALINK_ENABLE_BERTEST
// Packing service data
Service_Packing(instPtr, L2_SVC_FRAME, rtneEntry->dst);
#else
memcpy(instPtr->sendPktData, testData, L2_SVC_PACK_LEN);
#endif
}
else
{
svcFSMPtr->rxCnt++;
}
L2_SetupNextSlot(instPtr, torState, L2_SVC_FRAME);
case L2_SLOT_SERVICE_2K:
frameType = L2_SVC_2K_FRAME;
break;
case L2_SLOT_SERVICE_128K:
frameType = L2_SVC_128K_FRAME;
break;
case L2_SLOT_SERVICE_256K:
frameType = L2_SVC_256K_FRAME;
break;
default:
DBG_ERROR("UNKNOWN slot type [%" PRIu8 "].\n", rtneEntry->slotType);
return FAILURE;
}
#ifdef DATALINK_ENABLE_BERTEST
uint32_t pktLoss;
pktLoss = svcFSMPtr->rxCnt - svcFSMPtr->rxdCnt;
svcFSMPtr->lossRate = (svcFSMPtr->rxCnt == 0) ? 0 : (double)pktLoss / (double)svcFSMPtr->rxCnt;
svcFSMPtr->errorRate = (svcFSMPtr->bitTotal == 0) ? 0 : (double)svcFSMPtr->bitError / (double)svcFSMPtr->bitTotal;
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);
#endif
if (torState == L2_TOR_TX)
{
if(Service_Packing(instPtr, frameType, rtneEntry->dst) == SUCCESS)
{
svcFSMPtr->txCnt++;
}
else
{
torState = L2_TOR_SUSPEND;
}
}
else
{
svcFSMPtr->rxCnt++;
}
L2_SetupNextSlot(instPtr, torState, frameType);
return SUCCESS;
}
/** @} LinkLayer_Service*/
/** @} LinkLayer*/
/** @} LinkLayer*/
+2 -2
View File
@@ -23,7 +23,7 @@
#include <string.h>
#include <stdlib.h>
#include "link_layer.h"
#include "../phy_layer/phy_layer.h"
#include "networking/phy_layer/phy_layer.h"
#include "error.h"
#include "common.h"
@@ -102,4 +102,4 @@ void L2_TimeAdjust(L2_INST *instPtr, const int64_t *timeDev)
/** @} LinkLayer_TimeSync*/
/** @} LinkLayer*/
/** @} LinkLayer*/
+2 -2
View File
@@ -321,7 +321,7 @@ uint32_t Phy_GetTimeComp(L1_FRAME_TYPE frameType)
/*****************************************************************************/
/**
* @brief Get frame type of the frame in receive data buffer (Base on PL Record).
* @brief Get frame type of the frame in receive data buffer (Base on PL Record).
*
* @param instPtr A pointer to physical layer control instance.
*
@@ -1390,4 +1390,4 @@ void Phy_GetLastReceivedSlotStartTimeStamp(PHY_INST *instPtr, TIME_WORD *slotSta
/** @} PhysicalLayer_Receive_Estimations*/
/** @} PhysicalLayer*/
/** @} PhysicalLayer*/
+3 -4
View File
@@ -25,10 +25,9 @@
#ifndef EMULATION
#include "xbram.h"
#include "xadcps.h"
#include "../config/app_config.h"
#endif
#include "../../system_monitor.h"
#include "../../time_ctrl/time_ctrl.h"
#include "system_monitor.h"
#include "time_ctrl/time_ctrl.h"
/************************** Constant Definitions *****************************/
/**
* @name PhysicalLayer_Common_Constant
@@ -312,4 +311,4 @@ int32_t Phy_SetBeamAngle(PHY_INST *phyInstPtr, double offAx, double rndAx);
#endif // PHY_CTRL_H_
/** @} PhysicalLayer*/
/** @} PhysicalLayer*/
+46 -68
View File
@@ -20,6 +20,7 @@
#include <stdint.h>
#include <stdbool.h>
// Xilinx
#include "sleep.h"
#include "xscugic.h"
#include "drivers/platform/xilinx_irq.h"
#include "drivers/platform/xilinx_timer.h"
@@ -27,20 +28,21 @@
#include "common.h"
#include "error.h"
#include "timer.h"
#include "hwconfig.h"
#include "system_monitor.h"
#include "config/app_config.h"
#include "dev_profile/dev_profile.h"
#include "systembus/systembus.h"
#include "networking/phy_layer/phy_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 ******************************/
int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr);
void Phy_IntrHandler(void *context);
void PeriodicPull_Handler(void *callBackRef);
void ScuTimer_IntrHandler(void *context);
void Systembus_IntrHandler(void *context);
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 Systembus_IntrHandler(void *context);
static bool LinklayerPush2Up(RING_BUFFER *buff);
static bool LinklayerPopFromUp(RING_BUFFER **buff);
/************************** Constant Definitions *****************************/
struct callback_desc phy_callback_desc = {
@@ -64,25 +66,21 @@ struct callback_desc scutm_callback_desc = {
.ctx = NULL
};
#ifdef _NODE_APP_
L2_CONFIG linkConfig = {
.myType = L2_NODE_HEAD,
.myType = L2_NODE_MEMBER,
.clustId = 1U,
.myId = 1U,
.myId = 2U,
.headId = 1U,
.netScale = 2U,
.phyInstPtr = NULL, // physical layer reference
.tmcInstPtr = NULL
.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
// };
#else
#error No application type is specified.
#endif
static PHY_CONFIG phyConfig = {
.devId = PHY_DEVICE_ID,
@@ -92,10 +90,10 @@ static PHY_CONFIG phyConfig = {
.txBramId = PHY_TXBUFF_BRAM_DEVICE_ID,
.rxBramId = PHY_RXBUFF_BRAM_DEVICE_ID,
.hwXadcId = PHY_HW_XADC_DEVICE_ID,
.get_clk_state = Hardware_GetHMC7044LockStatus,
.get_ad_lock_state = Hardware_GetAD9361LockStatus,
.get_ad0_temp = Hardware_GetAD9361Temp_1,
.get_ad1_temp = Hardware_GetAD9361Temp_2
.get_clk_state = NULL,
.get_ad_lock_state = NULL,
.get_ad0_temp = NULL,
.get_ad1_temp = NULL
};
TMC_CONFIG tmcConfig = {
@@ -117,14 +115,19 @@ static SYSBUS_CONFIG sysbusConfig = {
.rxQueueMax = 16U
};
/*********************** 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 SYSBUS *sysbusDescPtr = NULL;
static PHY_INST *phyInstPtr = NULL;
static TMC_INST *tmcInstPtr = 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
@@ -137,7 +140,7 @@ L2_INST *linkInstPtr = NULL;
* FAILURE if initialization failed.
*
*****************************************************************************/
int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr)
static int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr)
{
int32_t Status;
struct xil_irq_desc *xil_dev;
@@ -200,20 +203,6 @@ int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr)
}
/* Initialize system bus interrupt. */
Status = irq_trigger_level_set(descPtr, SYSBUS_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, SYSBUS_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, SYSBUS_INTR_ID, &sysbus_callback_desc);
if (Status != SUCCESS)
@@ -235,7 +224,7 @@ int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr)
irq_enable(descPtr, PHY_INTR_ID);
irq_enable(descPtr, PERIODIC_5MS_INTR_ID);
irq_enable(descPtr, SYSBUS_INTR_ID);
irq_enable(descPtr, SCUTIMER_INTR_ID);
// irq_enable(descPtr, SCUTIMER_INTR_ID);
// Enable Exceptions
Status = irq_global_enable(descPtr);
@@ -257,7 +246,7 @@ int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr)
* @return None.
*
*****************************************************************************/
void Phy_IntrHandler(void *context)
static void Phy_IntrHandler(void *context)
{
Phy_UpdateState(phyInstPtr);
} // PhyIntr_Handler
@@ -272,7 +261,7 @@ void Phy_IntrHandler(void *context)
* @return None.
*
*****************************************************************************/
void PeriodicPull_Handler(void *callBackRef)
static void PeriodicPull_Handler(void *callBackRef)
{
int32_t Status;
Status = Linklayer_Proc(linkInstPtr);
@@ -292,7 +281,7 @@ void PeriodicPull_Handler(void *callBackRef)
* @return None.
*
******************************************************************************/
void Systembus_IntrHandler(void *context)
static void Systembus_IntrHandler(void *context)
{
int32_t Status;
Status = SystemBus_IntrHandler(sysbusDescPtr);
@@ -311,7 +300,7 @@ void Systembus_IntrHandler(void *context)
* @return None.
*
******************************************************************************/
void ScuTimer_IntrHandler(void *context)
static void ScuTimer_IntrHandler(void *context)
{
int32_t Status;
struct xil_timer_desc *xdesc;
@@ -325,11 +314,6 @@ void ScuTimer_IntrHandler(void *context)
if(Status != SUCCESS) {
DBG_ERROR("Failed to generate remote check.\n");
}
// if (TimeCtrl_GetIntCnt(tmcInstPtr) - phyInstPtr->lastLogTime >= PHY_LOG_EXPIRE)
// {
// Phy_UpdateLogging(phyInstPtr);
// }
XScuTimer_ClearInterruptStatus((XScuTimer *)xdesc->instance);
}
else
@@ -365,18 +349,6 @@ int main(void)
return Status;
}
/* Hardware Initialize */
Status = Hardware_Init();
if (Status == SUCCESS)
{
DBG_PRINT("Hardware Init SUCCESS! \n");
}
else
{
DBG_PRINT("Hardware Init FAILED! \n");
return Status;
}
/* Time controller Initialize */
Status = TimeCtrl_Init(&tmcInstPtr, &tmcConfig);
if (Status == SUCCESS)
@@ -448,8 +420,7 @@ int main(void)
DBG_PRINT("Physical started...\n");
Phy_Start(phyInstPtr);
// Linklayer_Start(linkInstPtr);
Linklayer_Start(linkInstPtr);
while (true)
{
@@ -464,13 +435,20 @@ int main(void)
}
if (SystemBus_IsRsqPending(sysbusDescPtr) && (!SystemBus_IsTxBusy(sysbusDescPtr)))
{
// FIXME: Required by 12 (CASC)
udelay(4000);
usleep(4000);
Status = SystemBus_MakeResp(sysbusDescPtr);
if (Status != SUCCESS)
{
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
+84
View File
@@ -0,0 +1,84 @@
/*****************************************************************************/
/**
* 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) 2024 Beijing Institute of Technology.
* Lab of Communication and Networking
*
******************************************************************************/
#ifndef __APP_CONFIG_H_
#define __APP_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)
#define _NODE_APP_
/*********** Debug Info Level ************/
// #define _DEBUG_LEVEL 1
// 3 - print all debug info
// 2 - print warnings and errors
// 1 - print only errors
// other - print nothing
/************ 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 0X00
#define PHY_BASEADDR XPAR_PHYC_BASEADDR
// -- Antenna Bram Configs
#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
// -- 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 SYSBUS_DEV_ID XPAR_XUARTPS_0_DEVICE_ID
#define SYSBUS_INTR_ID XPAR_XUARTPS_0_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
#endif //__APP_CONFIG_H_
+11
View File
@@ -0,0 +1,11 @@
#ifndef _DEV_PROFILE_H_
#define _DEV_PROFILE_H_
#include "irq.h"
#include "error.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_ */
@@ -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 "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 = {
.type = IRQ_PS

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