Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
14621223ef |
+20
@@ -0,0 +1,20 @@
|
||||
# System generated files
|
||||
# -- macOS
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
._*
|
||||
|
||||
# -- Windows
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
Desktop.ini
|
||||
|
||||
# -- Linux
|
||||
*~
|
||||
|
||||
# IDEs and editors' files
|
||||
*.idea
|
||||
*.vscode
|
||||
*.sublime-workspace
|
||||
*.sublime-project
|
||||
@@ -0,0 +1,35 @@
|
||||
# keep compiled libs
|
||||
!*.a
|
||||
|
||||
# Buid folder
|
||||
build/
|
||||
|
||||
# Xilinx tools generated files
|
||||
.metadata/
|
||||
.settings/
|
||||
.wsdata/
|
||||
.Xil/
|
||||
logs/
|
||||
Packages/
|
||||
*.log*
|
||||
|
||||
# System generated files
|
||||
# -- macOS
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
._*
|
||||
|
||||
# -- Windows
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
Desktop.ini
|
||||
|
||||
# -- Linux
|
||||
*~
|
||||
|
||||
# IDEs and editors' files
|
||||
*.idea
|
||||
*.vscode
|
||||
*.sublime-workspace
|
||||
*.sublime-project
|
||||
@@ -0,0 +1,8 @@
|
||||
include ../../scripts/generic_variables.mk
|
||||
|
||||
PLATFORM := xilinx
|
||||
CONFIG_FILE := $(PROJECT)/config.json
|
||||
XILINX_VITIS_CLASSIC = y
|
||||
SCRIPT_DIR = ../../scripts
|
||||
|
||||
include ../../scripts/generic.mk
|
||||
@@ -0,0 +1,84 @@
|
||||
{
|
||||
"project_name": "cx9261a_demo_cmos_20240513",
|
||||
"version": "20240513",
|
||||
"hw_design": "../CX9261A_ZC706.xsa",
|
||||
"hw_version": "20241031",
|
||||
"apps": {
|
||||
"cx9261a_api_app": {
|
||||
"sources": ["source_cx9261a_api_1_9_0/"],
|
||||
"target_cpu": "ps7_cortexa9_0",
|
||||
"os": "standalone",
|
||||
"language": "C++",
|
||||
"mem_layout" : {
|
||||
"heap_size": "0x80000",
|
||||
"stack_size": "0x4000"
|
||||
}
|
||||
},
|
||||
"cx9261a_api_lib_app": {
|
||||
"sources": ["source_cx9261a_api_lib_c/"],
|
||||
"target_cpu": "ps7_cortexa9_0",
|
||||
"os": "standalone",
|
||||
"language": "C",
|
||||
"mem_layout" : {
|
||||
"heap_size": "0x80000",
|
||||
"stack_size": "0x4000"
|
||||
},
|
||||
"build_config": {
|
||||
"debug": {
|
||||
"include-path": ["source_cx9261a_api_lib_c/include"],
|
||||
"libraries": ["cx9261a_c_dbg", "stdc++", "m"],
|
||||
"library-search-path": ["source_cx9261a_api_lib_c/drivers/rf-transceiver/cx9261a/lib"]
|
||||
},
|
||||
"release": {
|
||||
"include-path": ["source_cx9261a_api_lib_c/include"],
|
||||
"libraries": ["cx9261a_c", "stdc++", "m"],
|
||||
"library-search-path": ["source_cx9261a_api_lib_c/drivers/rf-transceiver/cx9261a/lib"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"CX9261A_DEMO": {
|
||||
"sources": ["source_CX9261A_DEMO/"],
|
||||
"target_cpu": "ps7_cortexa9_0",
|
||||
"os": "freertos10_xilinx",
|
||||
"language": "C",
|
||||
"mem_layout" : {
|
||||
"heap_size": "0x80000",
|
||||
"stack_size": "0x4000"
|
||||
},
|
||||
"bsp_lib": {
|
||||
"lwip220": {
|
||||
"version": "1.0",
|
||||
"config": {
|
||||
"api_mode": "SOCKET_API",
|
||||
"pbuf_pool_size": 2048
|
||||
}
|
||||
},
|
||||
"xilffs": {
|
||||
"version": "5.2"
|
||||
}
|
||||
}
|
||||
},
|
||||
"CX9261A_HOP": {
|
||||
"sources": ["source_CX9261A_HOP/"],
|
||||
"target_cpu": "ps7_cortexa9_0",
|
||||
"os": "freertos10_xilinx",
|
||||
"language": "C",
|
||||
"mem_layout" : {
|
||||
"heap_size": "0x80000",
|
||||
"stack_size": "0x4000"
|
||||
},
|
||||
"bsp_lib": {
|
||||
"lwip220": {
|
||||
"version": "1.0",
|
||||
"config": {
|
||||
"api_mode": "SOCKET_API",
|
||||
"pbuf_pool_size": 2048
|
||||
}
|
||||
},
|
||||
"xilffs": {
|
||||
"version": "5.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+342
@@ -0,0 +1,342 @@
|
||||
/*
|
||||
* cx9261a_076_config.c
|
||||
*
|
||||
* Created on: 2023年11月30日
|
||||
* Author: cxlab
|
||||
*/
|
||||
|
||||
|
||||
#include "xilinx_io.h"
|
||||
#include "sleep.h"
|
||||
void cx9261a_076_config(void){
|
||||
u8 rx_data;
|
||||
int temp;
|
||||
|
||||
//setPin(pin,value)
|
||||
GpioSetPinDir(0,0x01);
|
||||
GpioWritePin(0,1);
|
||||
GpioSetPinDir(32,0x01);
|
||||
GpioWritePin(32,1);
|
||||
GpioSetPinDir(33,0x01);
|
||||
GpioWritePin(33,1);
|
||||
GpioSetPinDir(34,0x01);
|
||||
GpioWritePin(34,0);
|
||||
GpioSetPinDir(35,0x01); //tx:0-rx:1
|
||||
GpioWritePin(35,1); //tx:0-rx:1
|
||||
GpioSetPinDir(36,0x01); //fdd:0-tdd:1
|
||||
GpioWritePin(36,1); //fdd:0-tdd:1
|
||||
GpioSetPinDir(37,0x01); //1r1t:0-2r2t:1
|
||||
GpioWritePin(37,0); //1r1t:0-2r2t:1
|
||||
GpioSetPinDir(38,0x01); //dualport:0-singleport:1
|
||||
GpioWritePin(38,1); //dualport:0-singleport:1
|
||||
GpioSetPinDir(39,0x01);
|
||||
GpioWritePin(39,1);
|
||||
GpioSetPinDir(40,0x01);
|
||||
GpioWritePin(40,1);
|
||||
//三个通道共同控制
|
||||
SpiPs_write_read1(0x000,0x02,&rx_data);
|
||||
//电源管理自定义
|
||||
//断电模式
|
||||
SpiPs_write_read1(0x031,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x032,0x7F,&rx_data);
|
||||
SpiPs_write_read1(0x033,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x034,0xFF,&rx_data);
|
||||
//休眠模式
|
||||
SpiPs_write_read1(0x035,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x036,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x037,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x038,0xEB,&rx_data);
|
||||
//警戒模式
|
||||
SpiPs_write_read1(0x039,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x03A,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x03B,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x03C,0xE0,&rx_data);
|
||||
//校准模式
|
||||
SpiPs_write_read1(0x03D,0x1B,&rx_data);
|
||||
SpiPs_write_read1(0x03E,0x39,&rx_data);
|
||||
SpiPs_write_read1(0x03F,0x27,&rx_data);
|
||||
SpiPs_write_read1(0x040,0xE0,&rx_data);
|
||||
//接收模式
|
||||
SpiPs_write_read1(0x041,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x042,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x043,0xE7,&rx_data);
|
||||
SpiPs_write_read1(0x044,0xF8,&rx_data);
|
||||
//发射模式
|
||||
SpiPs_write_read1(0x045,0x1B,&rx_data);
|
||||
SpiPs_write_read1(0x046,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x047,0x26,&rx_data);
|
||||
SpiPs_write_read1(0x048,0x7E,&rx_data);
|
||||
//FDD模式
|
||||
SpiPs_write_read1(0x049,0x1B,&rx_data);
|
||||
SpiPs_write_read1(0x04A,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x04B,0x27,&rx_data);
|
||||
SpiPs_write_read1(0x04C,0xE0,&rx_data);
|
||||
//观测模式
|
||||
SpiPs_write_read1(0x04D,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x04E,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x04F,0xD9,&rx_data);
|
||||
SpiPs_write_read1(0x050,0xFE,&rx_data);
|
||||
//带隙基准
|
||||
SpiPs_write_read1(0x773,0x53,&rx_data);
|
||||
SpiPs_write_read1(0x774,0x86,&rx_data);
|
||||
//参考时钟设置
|
||||
SpiPs_write_read1(0x789,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x785,0x49,&rx_data);
|
||||
SpiPs_write_read1(0x788,0x24,&rx_data);
|
||||
usleep(10000);
|
||||
SpiPs_write_read1(0x788,0xA4,&rx_data);
|
||||
//BBPLL
|
||||
SpiPs_write_read1(0x0C0,0x50,&rx_data);
|
||||
SpiPs_write_read1(0x0C1,0x50,&rx_data);
|
||||
SpiPs_write_read1(0x0C2,0x50,&rx_data);
|
||||
SpiPs_write_read1(0x601,0x0F,&rx_data);
|
||||
SpiPs_write_read1(0x602,0x21,&rx_data);
|
||||
SpiPs_write_read1(0x60D,0x0C,&rx_data);
|
||||
SpiPs_write_read1(0x60E,0x66,&rx_data);
|
||||
SpiPs_write_read1(0x60F,0x66,&rx_data);
|
||||
SpiPs_write_read1(0x610,0x66,&rx_data);
|
||||
SpiPs_write_read1(0x611,0x13,&rx_data);
|
||||
SpiPs_write_read1(0x612,0x00,&rx_data);
|
||||
//ADC
|
||||
SpiPs_write_read1(0x70B,0x0E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x0E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x0E,&rx_data);
|
||||
SpiPs_write_read1(0x70D,0x3F,&rx_data);
|
||||
SpiPs_write_read1(0x729,0x3F,&rx_data);
|
||||
SpiPs_write_read1(0x745,0x3F,&rx_data);
|
||||
SpiPs_write_read1(0x70E,0x48,&rx_data);
|
||||
SpiPs_write_read1(0x72A,0x48,&rx_data);
|
||||
SpiPs_write_read1(0x746,0x48,&rx_data);
|
||||
SpiPs_write_read1(0x70F,0xA0,&rx_data);
|
||||
SpiPs_write_read1(0x72B,0xA0,&rx_data);
|
||||
SpiPs_write_read1(0x747,0xA0,&rx_data);
|
||||
//通道时钟来源
|
||||
SpiPs_write_read1(0x77D,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0x775,0x24,&rx_data);
|
||||
SpiPs_write_read1(0x6C3,0x00,&rx_data);
|
||||
//PLL1
|
||||
SpiPs_write_read1(0x620,0x81,&rx_data);
|
||||
SpiPs_write_read1(0x61D,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB06,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB07,0x64,&rx_data);
|
||||
SpiPs_write_read1(0xB08,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB09,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB0A,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x61A,0x0B,&rx_data);
|
||||
SpiPs_write_read1(0x61B,0x20,&rx_data);
|
||||
SpiPs_write_read1(0x61C,0x13,&rx_data);
|
||||
SpiPs_write_read1(0x624,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x625,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x62A,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x61E,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x61F,0x08,&rx_data);
|
||||
SpiPs_write_read1(0x621,0x4D,&rx_data);
|
||||
SpiPs_write_read1(0x622,0x19,&rx_data);
|
||||
SpiPs_write_read1(0x627,0x10,&rx_data);
|
||||
//Rx通道设置
|
||||
SpiPs_write_read1(0x700,0x56,&rx_data);
|
||||
SpiPs_write_read1(0x71C,0x56,&rx_data);
|
||||
SpiPs_write_read1(0x738,0x56,&rx_data);
|
||||
SpiPs_write_read1(0x701,0x02,&rx_data);
|
||||
SpiPs_write_read1(0x702,0x35,&rx_data);
|
||||
SpiPs_write_read1(0x71D,0x02,&rx_data);
|
||||
SpiPs_write_read1(0x71E,0x35,&rx_data);
|
||||
SpiPs_write_read1(0x739,0x02,&rx_data);
|
||||
SpiPs_write_read1(0x73A,0x35,&rx_data);
|
||||
SpiPs_write_read1(0x703,0xF6,&rx_data);
|
||||
SpiPs_write_read1(0x71F,0xF6,&rx_data);
|
||||
SpiPs_write_read1(0x73B,0xF6,&rx_data);
|
||||
SpiPs_write_read1(0x704,0xC8,&rx_data);
|
||||
SpiPs_write_read1(0x720,0xC8,&rx_data);
|
||||
SpiPs_write_read1(0x73C,0xC8,&rx_data);
|
||||
SpiPs_write_read1(0x907,0x1F,&rx_data);
|
||||
SpiPs_write_read1(0x705,0xFC,&rx_data);
|
||||
SpiPs_write_read1(0x721,0xFC,&rx_data);
|
||||
SpiPs_write_read1(0x73D,0xFC,&rx_data);
|
||||
SpiPs_write_read1(0x706,0x65,&rx_data);
|
||||
SpiPs_write_read1(0x722,0x65,&rx_data);
|
||||
SpiPs_write_read1(0x73E,0x65,&rx_data);
|
||||
SpiPs_write_read1(0x707,0x91,&rx_data);
|
||||
SpiPs_write_read1(0x723,0x91,&rx_data);
|
||||
SpiPs_write_read1(0x73F,0x91,&rx_data);
|
||||
SpiPs_write_read1(0x708,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x724,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x740,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x709,0x94,&rx_data);
|
||||
SpiPs_write_read1(0x725,0x94,&rx_data);
|
||||
SpiPs_write_read1(0x741,0x94,&rx_data);
|
||||
SpiPs_write_read1(0x70A,0xFC,&rx_data);
|
||||
SpiPs_write_read1(0x726,0xFC,&rx_data);
|
||||
SpiPs_write_read1(0x742,0xFC,&rx_data);
|
||||
SpiPs_write_read1(0x75A,0x83,&rx_data);
|
||||
SpiPs_write_read1(0x75B,0xDA,&rx_data);
|
||||
usleep(10000);
|
||||
SpiPs_write_read1(0x75B,0x9A,&rx_data);
|
||||
SpiPs_write_read1(0x75C,0x81,&rx_data);
|
||||
SpiPs_write_read1(0x75D,0xF8,&rx_data);
|
||||
SpiPs_write_read1(0x75E,0xA7,&rx_data);
|
||||
SpiPs_write_read1(0x75F,0x51,&rx_data);
|
||||
SpiPs_write_read1(0x760,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x761,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x762,0x70,&rx_data);
|
||||
SpiPs_write_read1(0x763,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x764,0x83,&rx_data);
|
||||
SpiPs_write_read1(0x765,0xDA,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x765,0x9A,&rx_data);
|
||||
SpiPs_write_read1(0x766,0x81,&rx_data);
|
||||
SpiPs_write_read1(0x767,0xF8,&rx_data);
|
||||
SpiPs_write_read1(0x768,0xA7,&rx_data);
|
||||
SpiPs_write_read1(0x769,0x51,&rx_data);
|
||||
SpiPs_write_read1(0x76A,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x76B,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x76C,0x70,&rx_data);
|
||||
SpiPs_write_read1(0x76D,0x04,&rx_data);
|
||||
//Rx滤波器
|
||||
SpiPs_write_read1(0x106,0x02,&rx_data);
|
||||
//Tx滤波器
|
||||
SpiPs_write_read1(0x107,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x108,0xD0,&rx_data);
|
||||
//Rx NCO
|
||||
SpiPs_write_read1(0x11C,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA07,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA08,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA16,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA17,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA18,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA19,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1A,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1B,0x00,&rx_data);
|
||||
//Tx NCO
|
||||
SpiPs_write_read1(0x128,0x10,&rx_data);
|
||||
SpiPs_write_read1(0x11B,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x11E,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x161,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x162,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x164,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x165,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x166,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x167,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x168,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x169,0x00,&rx_data);
|
||||
//AGC配置
|
||||
SpiPs_write_read1(0x900,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x901,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x903,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x908,0x77,&rx_data);
|
||||
SpiPs_write_read1(0x909,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x90A,0x32,&rx_data);
|
||||
SpiPs_write_read1(0x90D,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x90E,0x0F,&rx_data);
|
||||
SpiPs_write_read1(0x90F,0x65,&rx_data);
|
||||
SpiPs_write_read1(0x910,0x32,&rx_data);
|
||||
SpiPs_write_read1(0x911,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x912,0x0F,&rx_data);
|
||||
SpiPs_write_read1(0x913,0x3A,&rx_data);
|
||||
SpiPs_write_read1(0x914,0x37,&rx_data);
|
||||
SpiPs_write_read1(0x915,0x34,&rx_data);
|
||||
SpiPs_write_read1(0x916,0x31,&rx_data);
|
||||
//进入休眠模式
|
||||
SpiPs_write_read1(0x02E,0x01,&rx_data);
|
||||
usleep(1000000);
|
||||
//进入校准模式
|
||||
SpiPs_write_read1(0x02E,0x03,&rx_data);
|
||||
//BBPLL AFC
|
||||
SpiPs_write_read1(0x600,0x00,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x600,0x11,&rx_data);
|
||||
//PLL1 AFC
|
||||
SpiPs_write_read1(0x617,0x00,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x617,0x03,&rx_data);
|
||||
//接口配置
|
||||
SpiPs_write_read1(0x02E,0x06,&rx_data);
|
||||
SpiPs_write_read1(0x003,0x33,&rx_data);
|
||||
SpiPs_write_read1(0x200,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x201,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x202,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x209,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x780,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x781,0x6F,&rx_data);
|
||||
SpiPs_write_read1(0x782,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x783,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x784,0x01,&rx_data);
|
||||
//ADC校准
|
||||
SpiPs_write_read1(0x70B,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x70F,0xA0,&rx_data);
|
||||
SpiPs_write_read1(0x710,0x83,&rx_data);
|
||||
SpiPs_write_read1(0x711,0xF0,&rx_data);
|
||||
SpiPs_write_read1(0x72B,0xA0,&rx_data);
|
||||
SpiPs_write_read1(0x72C,0x83,&rx_data);
|
||||
SpiPs_write_read1(0x72D,0xF0,&rx_data);
|
||||
SpiPs_write_read1(0x747,0xA0,&rx_data);
|
||||
SpiPs_write_read1(0x748,0x83,&rx_data);
|
||||
SpiPs_write_read1(0x749,0xF0,&rx_data);
|
||||
SpiPs_write_read1(0x713,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x72F,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x74B,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x70B,0x9E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x9E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x9E,&rx_data);
|
||||
SpiPs_write_read1(0x70B,0x9A,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x9A,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x9A,&rx_data);
|
||||
SpiPs_write_read1(0x70B,0x9E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x9E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x9E,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x70B,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x713,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0x72F,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0x74B,0xC0,&rx_data);
|
||||
//Flash校准
|
||||
SpiPs_write_read1(0x70B,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x715,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x731,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x74D,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x715,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0x731,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0x74D,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0x716,0x40,&rx_data);
|
||||
SpiPs_write_read1(0x732,0x40,&rx_data);
|
||||
SpiPs_write_read1(0x74E,0x40,&rx_data);
|
||||
SpiPs_write_read1(0x70B,0x16,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x16,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x16,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x70B,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x715,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x731,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x74D,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x716,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x732,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x74E,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x109,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x10A,0x70,&rx_data);
|
||||
SpiPs_write_read1(0x11F,0x33,&rx_data);
|
||||
usleep(1000);
|
||||
SpiPs_write_read2(0x615,0x00,&rx_data);
|
||||
temp=rx_data;
|
||||
SpiPs_write_read2(0x635,0x00,&rx_data);
|
||||
temp=rx_data;
|
||||
////配置Tx NCO BIST ON
|
||||
//SpiPs_write_read1(0x11B,0x01,&rx_data);
|
||||
//SpiPs_write_read1(0x11E,0x01,&rx_data);
|
||||
//SpiPs_write_read1(0x161,0x01,&rx_data);
|
||||
//SpiPs_write_read1(0x162,0x01,&rx_data);
|
||||
////配置Tx NCO频率 1MHz
|
||||
//SpiPs_write_read1(0x164,0x05,&rx_data);
|
||||
//SpiPs_write_read1(0x165,0x55,&rx_data);
|
||||
//SpiPs_write_read1(0x166,0x55,&rx_data);
|
||||
//SpiPs_write_read1(0x167,0x55,&rx_data);
|
||||
//SpiPs_write_read1(0x168,0x55,&rx_data);
|
||||
//SpiPs_write_read1(0x169,0x55,&rx_data);
|
||||
}
|
||||
+708
@@ -0,0 +1,708 @@
|
||||
/*
|
||||
* cx9261_config.c
|
||||
*
|
||||
* Created on: 2023年10月16日
|
||||
* Author: cxlab
|
||||
*/
|
||||
|
||||
#include "xilinx_io.h"
|
||||
#include "sleep.h"
|
||||
void cx9261a_151_config(void){
|
||||
u8 rx_data;
|
||||
int temp;
|
||||
|
||||
//setPin(pin,value)
|
||||
GpioSetPinDir(0,0x01);
|
||||
GpioWritePin(0,1);
|
||||
GpioSetPinDir(32,0x01);
|
||||
GpioWritePin(32,1);
|
||||
GpioSetPinDir(33,0x01);
|
||||
GpioWritePin(33,1);
|
||||
GpioSetPinDir(34,0x01);
|
||||
GpioWritePin(34,0);
|
||||
GpioSetPinDir(35,0x01); //tx:0-rx:1
|
||||
GpioWritePin(35,1); //tx:0-rx:1
|
||||
GpioSetPinDir(36,0x01); //fdd:0-tdd:1
|
||||
GpioWritePin(36,1); //fdd:0-tdd:1
|
||||
GpioSetPinDir(37,0x01); //1r1t:0-2r2t:1
|
||||
GpioWritePin(37,0); //1r1t:0-2r2t:1
|
||||
GpioSetPinDir(38,0x01); //dualport:0-singleport:1
|
||||
GpioWritePin(38,1); //dualport:0-singleport:1
|
||||
GpioSetPinDir(39,0x01);
|
||||
GpioWritePin(39,1);
|
||||
GpioSetPinDir(40,0x01);
|
||||
GpioWritePin(40,1);
|
||||
//三个通道共同控制
|
||||
SpiPs_write_read1(0x000,0x02,&rx_data);
|
||||
//电源管理自定义
|
||||
//断电模式
|
||||
SpiPs_write_read1(0x031,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x032,0x7F,&rx_data);
|
||||
SpiPs_write_read1(0x033,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x034,0xFF,&rx_data);
|
||||
//休眠模式
|
||||
SpiPs_write_read1(0x035,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x036,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x037,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x038,0xEB,&rx_data);
|
||||
//警戒模式
|
||||
SpiPs_write_read1(0x039,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x03A,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x03B,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x03C,0xE0,&rx_data);
|
||||
//校准模式
|
||||
SpiPs_write_read1(0x03D,0x1B,&rx_data);
|
||||
SpiPs_write_read1(0x03E,0x39,&rx_data);
|
||||
SpiPs_write_read1(0x03F,0x27,&rx_data);
|
||||
SpiPs_write_read1(0x040,0xE0,&rx_data);
|
||||
//接收模式
|
||||
SpiPs_write_read1(0x041,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x042,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x043,0xE7,&rx_data);
|
||||
SpiPs_write_read1(0x044,0xF8,&rx_data);
|
||||
//发射模式
|
||||
SpiPs_write_read1(0x045,0x18,&rx_data);
|
||||
SpiPs_write_read1(0x046,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x047,0x3F,&rx_data);
|
||||
SpiPs_write_read1(0x048,0xF8,&rx_data);
|
||||
//FDD模式
|
||||
SpiPs_write_read1(0x049,0x1B,&rx_data);
|
||||
SpiPs_write_read1(0x04A,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x04B,0x27,&rx_data);
|
||||
SpiPs_write_read1(0x04C,0xE0,&rx_data);
|
||||
//观测模式
|
||||
SpiPs_write_read1(0x04D,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x04E,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x04F,0xD9,&rx_data);
|
||||
SpiPs_write_read1(0x050,0xFE,&rx_data);
|
||||
//带隙基准
|
||||
SpiPs_write_read1(0x773,0x53,&rx_data);
|
||||
SpiPs_write_read1(0x774,0x86,&rx_data);
|
||||
//参考时钟设置
|
||||
SpiPs_write_read1(0x789,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x785,0x49,&rx_data);
|
||||
SpiPs_write_read1(0x788,0x24,&rx_data);
|
||||
usleep(10000);
|
||||
SpiPs_write_read1(0x788,0xA4,&rx_data);
|
||||
//BBPLL
|
||||
SpiPs_write_read1(0x0C0,0x50,&rx_data);
|
||||
SpiPs_write_read1(0x0C1,0x50,&rx_data);
|
||||
SpiPs_write_read1(0x0C2,0x50,&rx_data);
|
||||
SpiPs_write_read1(0x601,0x0F,&rx_data);
|
||||
SpiPs_write_read1(0x602,0x21,&rx_data);
|
||||
SpiPs_write_read1(0x60D,0x0C,&rx_data);
|
||||
SpiPs_write_read1(0x60E,0x66,&rx_data);
|
||||
SpiPs_write_read1(0x60F,0x66,&rx_data);
|
||||
SpiPs_write_read1(0x610,0x66,&rx_data);
|
||||
SpiPs_write_read1(0x611,0x13,&rx_data);
|
||||
SpiPs_write_read1(0x612,0x00,&rx_data);
|
||||
//ADC
|
||||
SpiPs_write_read1(0x70B,0x0E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x0E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x0E,&rx_data);
|
||||
SpiPs_write_read1(0x70D,0x3F,&rx_data);
|
||||
SpiPs_write_read1(0x729,0x3F,&rx_data);
|
||||
SpiPs_write_read1(0x745,0x3F,&rx_data);
|
||||
SpiPs_write_read1(0x70E,0x48,&rx_data);
|
||||
SpiPs_write_read1(0x72A,0x48,&rx_data);
|
||||
SpiPs_write_read1(0x746,0x48,&rx_data);
|
||||
SpiPs_write_read1(0x70F,0xA0,&rx_data);
|
||||
SpiPs_write_read1(0x72B,0xA0,&rx_data);
|
||||
SpiPs_write_read1(0x747,0xA0,&rx_data);
|
||||
//通道时钟来源
|
||||
SpiPs_write_read1(0x77D,0xCF,&rx_data);
|
||||
SpiPs_write_read1(0x775,0x24,&rx_data);
|
||||
SpiPs_write_read1(0x6C3,0x00,&rx_data);
|
||||
//PLL1
|
||||
SpiPs_write_read1(0x620,0x81,&rx_data);
|
||||
SpiPs_write_read1(0x61D,0x07,&rx_data);
|
||||
SpiPs_write_read1(0xB06,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB07,0x64,&rx_data);
|
||||
SpiPs_write_read1(0xB08,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB09,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB0A,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x61A,0x0B,&rx_data);
|
||||
SpiPs_write_read1(0x61B,0x20,&rx_data);
|
||||
SpiPs_write_read1(0x61C,0x13,&rx_data);
|
||||
SpiPs_write_read1(0x624,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x625,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x62A,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x61E,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x61F,0x08,&rx_data);
|
||||
SpiPs_write_read1(0x621,0x4D,&rx_data);
|
||||
SpiPs_write_read1(0x622,0x19,&rx_data);
|
||||
SpiPs_write_read1(0x627,0x10,&rx_data);
|
||||
//PLL2
|
||||
SpiPs_write_read1(0x642,0x91,&rx_data);
|
||||
SpiPs_write_read1(0x63F,0x36,&rx_data);
|
||||
SpiPs_write_read1(0xB14,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB15,0x70,&rx_data);
|
||||
SpiPs_write_read1(0xB16,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB17,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB18,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x63C,0x0C,&rx_data);
|
||||
SpiPs_write_read1(0x63D,0x20,&rx_data);
|
||||
SpiPs_write_read1(0x63E,0x0C,&rx_data);
|
||||
SpiPs_write_read1(0x646,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x647,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x64C,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x640,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x641,0x08,&rx_data);
|
||||
SpiPs_write_read1(0x643,0x4D,&rx_data);
|
||||
SpiPs_write_read1(0x644,0x19,&rx_data);
|
||||
SpiPs_write_read1(0x649,0x10,&rx_data);
|
||||
//PLL3
|
||||
SpiPs_write_read1(0x664,0x91,&rx_data);
|
||||
SpiPs_write_read1(0x661,0x36,&rx_data);
|
||||
SpiPs_write_read1(0xB22,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB23,0x80,&rx_data);
|
||||
SpiPs_write_read1(0xB24,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB25,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB26,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x65E,0x0D,&rx_data);
|
||||
SpiPs_write_read1(0x65F,0x20,&rx_data);
|
||||
SpiPs_write_read1(0x660,0x0F,&rx_data);
|
||||
SpiPs_write_read1(0x668,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x669,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x66E,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x662,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x663,0x08,&rx_data);
|
||||
SpiPs_write_read1(0x665,0x4D,&rx_data);
|
||||
SpiPs_write_read1(0x666,0x19,&rx_data);
|
||||
SpiPs_write_read1(0x66B,0x10,&rx_data);
|
||||
//PLL4
|
||||
SpiPs_write_read1(0x686,0x81,&rx_data);
|
||||
SpiPs_write_read1(0x683,0x37,&rx_data);
|
||||
SpiPs_write_read1(0xB30,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB31,0x48,&rx_data);
|
||||
SpiPs_write_read1(0xB32,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB33,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB34,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x680,0x0C,&rx_data);
|
||||
SpiPs_write_read1(0x681,0x20,&rx_data);
|
||||
SpiPs_write_read1(0x682,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x68A,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x68B,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x690,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x684,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x685,0x08,&rx_data);
|
||||
SpiPs_write_read1(0x687,0x4D,&rx_data);
|
||||
SpiPs_write_read1(0x688,0x19,&rx_data);
|
||||
SpiPs_write_read1(0x68D,0x10,&rx_data);
|
||||
//PLL5
|
||||
SpiPs_write_read1(0x6A8,0x81,&rx_data);
|
||||
SpiPs_write_read1(0x6A5,0x37,&rx_data);
|
||||
SpiPs_write_read1(0xB3E,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB3F,0x50,&rx_data);
|
||||
SpiPs_write_read1(0xB40,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB41,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB42,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x6A2,0x0C,&rx_data);
|
||||
SpiPs_write_read1(0x6A3,0x20,&rx_data);
|
||||
SpiPs_write_read1(0x6A4,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x6AC,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x6AD,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x6B2,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x6A6,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x6A7,0x08,&rx_data);
|
||||
SpiPs_write_read1(0x6A9,0x4D,&rx_data);
|
||||
SpiPs_write_read1(0x6AA,0x19,&rx_data);
|
||||
SpiPs_write_read1(0x6AF,0x10,&rx_data);
|
||||
//Rx通道设置
|
||||
SpiPs_write_read1(0x700,0x56,&rx_data);
|
||||
SpiPs_write_read1(0x71C,0x56,&rx_data);
|
||||
SpiPs_write_read1(0x738,0x56,&rx_data);
|
||||
SpiPs_write_read1(0x701,0x02,&rx_data);
|
||||
SpiPs_write_read1(0x702,0x35,&rx_data);
|
||||
SpiPs_write_read1(0x71D,0x02,&rx_data);
|
||||
SpiPs_write_read1(0x71E,0x35,&rx_data);
|
||||
SpiPs_write_read1(0x739,0x02,&rx_data);
|
||||
SpiPs_write_read1(0x73A,0x35,&rx_data);
|
||||
SpiPs_write_read1(0x703,0xF6,&rx_data);
|
||||
SpiPs_write_read1(0x71F,0xF6,&rx_data);
|
||||
SpiPs_write_read1(0x73B,0xF6,&rx_data);
|
||||
SpiPs_write_read1(0x704,0xC8,&rx_data);
|
||||
SpiPs_write_read1(0x720,0xC8,&rx_data);
|
||||
SpiPs_write_read1(0x73C,0xC8,&rx_data);
|
||||
SpiPs_write_read1(0x907,0x1F,&rx_data);
|
||||
SpiPs_write_read1(0x705,0xFC,&rx_data);
|
||||
SpiPs_write_read1(0x721,0xFC,&rx_data);
|
||||
SpiPs_write_read1(0x73D,0xFC,&rx_data);
|
||||
SpiPs_write_read1(0x706,0x65,&rx_data);
|
||||
SpiPs_write_read1(0x722,0x65,&rx_data);
|
||||
SpiPs_write_read1(0x73E,0x65,&rx_data);
|
||||
SpiPs_write_read1(0x707,0x91,&rx_data);
|
||||
SpiPs_write_read1(0x723,0x91,&rx_data);
|
||||
SpiPs_write_read1(0x73F,0x91,&rx_data);
|
||||
SpiPs_write_read1(0x708,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x724,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x740,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x709,0x94,&rx_data);
|
||||
SpiPs_write_read1(0x725,0x94,&rx_data);
|
||||
SpiPs_write_read1(0x741,0x94,&rx_data);
|
||||
SpiPs_write_read1(0x70A,0xFC,&rx_data);
|
||||
SpiPs_write_read1(0x726,0xFC,&rx_data);
|
||||
SpiPs_write_read1(0x742,0xFC,&rx_data);
|
||||
SpiPs_write_read1(0x75A,0x83,&rx_data);
|
||||
SpiPs_write_read1(0x75B,0xDA,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x75B,0x9A,&rx_data);
|
||||
SpiPs_write_read1(0x75C,0x81,&rx_data);
|
||||
SpiPs_write_read1(0x75D,0xF8,&rx_data);
|
||||
SpiPs_write_read1(0x75E,0xA7,&rx_data);
|
||||
SpiPs_write_read1(0x75F,0x50,&rx_data);
|
||||
SpiPs_write_read1(0x760,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x761,0x07,&rx_data);
|
||||
SpiPs_write_read1(0x762,0x6C,&rx_data);
|
||||
SpiPs_write_read1(0x763,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x764,0x83,&rx_data);
|
||||
SpiPs_write_read1(0x765,0xDA,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x765,0x9A,&rx_data);
|
||||
SpiPs_write_read1(0x766,0x81,&rx_data);
|
||||
SpiPs_write_read1(0x767,0xF8,&rx_data);
|
||||
SpiPs_write_read1(0x768,0xA7,&rx_data);
|
||||
SpiPs_write_read1(0x769,0x50,&rx_data);
|
||||
SpiPs_write_read1(0x76A,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x76B,0x07,&rx_data);
|
||||
SpiPs_write_read1(0x76C,0x6C,&rx_data);
|
||||
SpiPs_write_read1(0x76D,0x04,&rx_data);
|
||||
//Rx滤波器
|
||||
SpiPs_write_read1(0x106,0x02,&rx_data);
|
||||
//Tx滤波器
|
||||
SpiPs_write_read1(0x107,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x108,0xD0,&rx_data);
|
||||
//Rx NCO
|
||||
SpiPs_write_read1(0x11C,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA07,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA08,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA16,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA17,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA18,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA19,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1A,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1B,0x00,&rx_data);
|
||||
//Tx NCO
|
||||
SpiPs_write_read1(0x128,0x10,&rx_data);
|
||||
SpiPs_write_read1(0x11B,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x11E,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x161,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x162,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x164,0x05,&rx_data);
|
||||
SpiPs_write_read1(0x165,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x166,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x167,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x168,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x169,0x55,&rx_data);
|
||||
//AGC配置
|
||||
SpiPs_write_read1(0x900,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x901,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x903,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x908,0x77,&rx_data);
|
||||
SpiPs_write_read1(0x909,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x90A,0x32,&rx_data);
|
||||
SpiPs_write_read1(0x90D,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x90E,0x0F,&rx_data);
|
||||
SpiPs_write_read1(0x90F,0x65,&rx_data);
|
||||
SpiPs_write_read1(0x910,0x32,&rx_data);
|
||||
SpiPs_write_read1(0x911,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x912,0x0F,&rx_data);
|
||||
SpiPs_write_read1(0x913,0x3A,&rx_data);
|
||||
SpiPs_write_read1(0x914,0x37,&rx_data);
|
||||
SpiPs_write_read1(0x915,0x34,&rx_data);
|
||||
SpiPs_write_read1(0x916,0x31,&rx_data);
|
||||
//进入休眠模式
|
||||
SpiPs_write_read1(0x02E,0x01,&rx_data);
|
||||
usleep(1000000);
|
||||
//进入校准模式
|
||||
SpiPs_write_read1(0x02E,0x03,&rx_data);
|
||||
usleep(100000);
|
||||
//BBPLL AFC
|
||||
SpiPs_write_read1(0x600,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x600,0x11,&rx_data);
|
||||
usleep(50);
|
||||
//PLL1 AFC
|
||||
while(temp != 48)
|
||||
{
|
||||
SpiPs_write_read1(0x617,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x617,0x03,&rx_data);
|
||||
usleep(100);
|
||||
SpiPs_write_read2(0x635,0x00,&rx_data);
|
||||
temp=rx_data;
|
||||
}
|
||||
//接口配置
|
||||
SpiPs_write_read1(0x02E,0x06,&rx_data);
|
||||
SpiPs_write_read1(0x003,0x33,&rx_data);
|
||||
SpiPs_write_read1(0x200,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x201,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x202,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x208,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x209,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x780,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x781,0x6F,&rx_data);
|
||||
SpiPs_write_read1(0x782,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x783,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x784,0x01,&rx_data);
|
||||
//ADC校准
|
||||
SpiPs_write_read1(0x70B,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x70F,0xA0,&rx_data);
|
||||
SpiPs_write_read1(0x710,0x83,&rx_data);
|
||||
SpiPs_write_read1(0x711,0xF0,&rx_data);
|
||||
SpiPs_write_read1(0x72B,0xA0,&rx_data);
|
||||
SpiPs_write_read1(0x72C,0x83,&rx_data);
|
||||
SpiPs_write_read1(0x72D,0xF0,&rx_data);
|
||||
SpiPs_write_read1(0x747,0xA0,&rx_data);
|
||||
SpiPs_write_read1(0x748,0x83,&rx_data);
|
||||
SpiPs_write_read1(0x749,0xF0,&rx_data);
|
||||
SpiPs_write_read1(0x713,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x72F,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x74B,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x70B,0x9E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x9E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x9E,&rx_data);
|
||||
SpiPs_write_read1(0x70B,0x9A,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x9A,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x9A,&rx_data);
|
||||
SpiPs_write_read1(0x70B,0x9E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x9E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x9E,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x70B,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x713,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0x72F,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0x74B,0xC0,&rx_data);
|
||||
//Flash校准
|
||||
SpiPs_write_read1(0x70B,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x715,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x731,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x74D,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x715,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0x731,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0x74D,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0x716,0x40,&rx_data);
|
||||
SpiPs_write_read1(0x732,0x40,&rx_data);
|
||||
SpiPs_write_read1(0x74E,0x40,&rx_data);
|
||||
SpiPs_write_read1(0x70B,0x16,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x16,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x16,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x70B,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x715,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x731,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x74D,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x716,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x732,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x74E,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x109,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x10A,0x70,&rx_data);
|
||||
SpiPs_write_read1(0x11F,0x33,&rx_data);
|
||||
//QEC校准
|
||||
//Rx TST Calibration
|
||||
SpiPs_write_read1(0x000,0x12,&rx_data);
|
||||
SpiPs_write_read1(0x109,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x77E,0x50,&rx_data);
|
||||
SpiPs_write_read1(0x14E,0x00,&rx_data);
|
||||
// 修改校准模式电源管理
|
||||
SpiPs_write_read1(0x03D,0x09,&rx_data);
|
||||
SpiPs_write_read1(0x03E,0x39,&rx_data);
|
||||
SpiPs_write_read1(0x03F,0xB6,&rx_data);
|
||||
SpiPs_write_read1(0x040,0x78,&rx_data);
|
||||
//修改电源模式
|
||||
SpiPs_write_read1(0x02E,0x03,&rx_data);
|
||||
//Calibration PLL Source
|
||||
// 修改Pll来源
|
||||
SpiPs_write_read1(0x77D,0x90,&rx_data);
|
||||
SpiPs_write_read1(0x6C3,0x05,&rx_data);
|
||||
SpiPs_write_read1(0x775,0x24,&rx_data);
|
||||
//修改Pll4频率
|
||||
//PLL4
|
||||
SpiPs_write_read1(0x686,0x81,&rx_data);
|
||||
SpiPs_write_read1(0x683,0x07,&rx_data);
|
||||
SpiPs_write_read1(0xB30,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB31,0x63,&rx_data);
|
||||
SpiPs_write_read1(0xB32,0xEB,&rx_data);
|
||||
SpiPs_write_read1(0xB33,0x85,&rx_data);
|
||||
SpiPs_write_read1(0xB34,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x680,0x0B,&rx_data);
|
||||
SpiPs_write_read1(0x681,0x20,&rx_data);
|
||||
SpiPs_write_read1(0x682,0x13,&rx_data);
|
||||
SpiPs_write_read1(0x68A,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x68B,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x690,0x0B,&rx_data);
|
||||
SpiPs_write_read1(0x684,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x685,0x08,&rx_data);
|
||||
SpiPs_write_read1(0x687,0x4D,&rx_data);
|
||||
SpiPs_write_read1(0x688,0x19,&rx_data);
|
||||
SpiPs_write_read1(0x68D,0x10,&rx_data);
|
||||
//PLL4 AFC
|
||||
while(temp != 48)
|
||||
{
|
||||
SpiPs_write_read1(0x67D,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x67D,0x03,&rx_data);
|
||||
usleep(100);
|
||||
SpiPs_write_read2(0x69B,0x00,&rx_data);
|
||||
temp=rx_data;
|
||||
}
|
||||
SpiPs_write_read1(0x02A,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x121,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x11F,0x73,&rx_data);
|
||||
SpiPs_write_read1(0x124,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x120,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x122,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x126,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x02A,0x12,&rx_data);
|
||||
|
||||
SpiPs_write_read2(0x14D,0x00,&rx_data);
|
||||
temp=rx_data & 0x10;
|
||||
while(temp != 16){
|
||||
SpiPs_write_read2(0x14D,0x00,&rx_data);
|
||||
temp=rx_data & 0x10;
|
||||
usleep(100000);
|
||||
}
|
||||
|
||||
SpiPs_write_read1(0x77E,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x775,0x24,&rx_data);
|
||||
SpiPs_write_read1(0x77D,0xCF,&rx_data);
|
||||
SpiPs_write_read1(0x6C3,0x00,&rx_data);
|
||||
//Rx TST Calibration
|
||||
SpiPs_write_read1(0x000,0x22,&rx_data);
|
||||
SpiPs_write_read1(0x109,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x77E,0x0A,&rx_data);
|
||||
SpiPs_write_read1(0x14E,0x00,&rx_data);
|
||||
// 修改校准模式电源管理
|
||||
SpiPs_write_read1(0x03D,0x12,&rx_data);
|
||||
SpiPs_write_read1(0x03E,0x39,&rx_data);
|
||||
SpiPs_write_read1(0x03F,0x6E,&rx_data);
|
||||
SpiPs_write_read1(0x040,0x78,&rx_data);
|
||||
//修改电源模式
|
||||
SpiPs_write_read1(0x02E,0x03,&rx_data);
|
||||
//Calibration PLL Source
|
||||
// 修改Pll来源
|
||||
SpiPs_write_read1(0x77D,0x60,&rx_data);
|
||||
SpiPs_write_read1(0x6C3,0x0A,&rx_data);
|
||||
SpiPs_write_read1(0x775,0x24,&rx_data);
|
||||
//修改Pll4频率
|
||||
//PLL4
|
||||
SpiPs_write_read1(0x686,0x81,&rx_data);
|
||||
SpiPs_write_read1(0x683,0x07,&rx_data);
|
||||
SpiPs_write_read1(0xB30,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB31,0x63,&rx_data);
|
||||
SpiPs_write_read1(0xB32,0xEB,&rx_data);
|
||||
SpiPs_write_read1(0xB33,0x85,&rx_data);
|
||||
SpiPs_write_read1(0xB34,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x680,0x0B,&rx_data);
|
||||
SpiPs_write_read1(0x681,0x20,&rx_data);
|
||||
SpiPs_write_read1(0x682,0x13,&rx_data);
|
||||
SpiPs_write_read1(0x68A,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x68B,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x690,0x0B,&rx_data);
|
||||
SpiPs_write_read1(0x684,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x685,0x08,&rx_data);
|
||||
SpiPs_write_read1(0x687,0x4D,&rx_data);
|
||||
SpiPs_write_read1(0x688,0x19,&rx_data);
|
||||
SpiPs_write_read1(0x68D,0x10,&rx_data);
|
||||
//PLL4 AFC
|
||||
while(temp != 48)
|
||||
{
|
||||
SpiPs_write_read1(0x67D,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x67D,0x03,&rx_data);
|
||||
usleep(100);
|
||||
SpiPs_write_read2(0x69B,0x00,&rx_data);
|
||||
temp=rx_data;
|
||||
}
|
||||
SpiPs_write_read1(0x02B,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x121,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x11F,0x73,&rx_data);
|
||||
SpiPs_write_read1(0x124,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x120,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x122,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x126,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x02B,0x12,&rx_data);
|
||||
|
||||
SpiPs_write_read2(0x14D,0x00,&rx_data);
|
||||
temp=rx_data & 0x10;
|
||||
while(temp != 16){
|
||||
SpiPs_write_read2(0x14D,0x00,&rx_data);
|
||||
temp=rx_data & 0x10;
|
||||
usleep(100000);
|
||||
}
|
||||
|
||||
SpiPs_write_read1(0x77E,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x775,0x24,&rx_data);
|
||||
SpiPs_write_read1(0x77D,0xCF,&rx_data);
|
||||
SpiPs_write_read1(0x6C3,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x02C,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x02B,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x02A,0x00,&rx_data);
|
||||
//恢复校准前设置
|
||||
SpiPs_write_read1(0x000,0x02,&rx_data);
|
||||
SpiPs_write_read1(0x02E,0x06,&rx_data);
|
||||
SpiPs_write_read1(0x03D,0x1B,&rx_data);
|
||||
SpiPs_write_read1(0x03E,0x39,&rx_data);
|
||||
SpiPs_write_read1(0x03F,0x27,&rx_data);
|
||||
SpiPs_write_read1(0x040,0xF8,&rx_data);
|
||||
SpiPs_write_read1(0x109,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x10A,0x70,&rx_data);
|
||||
SpiPs_write_read1(0x11B,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x11E,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x11F,0x33,&rx_data);
|
||||
SpiPs_write_read1(0x128,0x10,&rx_data);
|
||||
SpiPs_write_read1(0x161,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x162,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x164,0x05,&rx_data);
|
||||
SpiPs_write_read1(0x165,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x166,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x167,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x168,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x169,0x55,&rx_data);
|
||||
SpiPs_write_read1(0xA07,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA08,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA16,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA17,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA18,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA19,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1A,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1B,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1C,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA2D,0x00,&rx_data);
|
||||
// TX二分法校准
|
||||
// 修改校准模式电源管理
|
||||
SpiPs_write_read1(0x03D,0x1B,&rx_data);
|
||||
SpiPs_write_read1(0x03E,0x39,&rx_data);
|
||||
SpiPs_write_read1(0x03F,0x27,&rx_data);
|
||||
SpiPs_write_read1(0x040,0xF8,&rx_data);
|
||||
//修改电源模式
|
||||
SpiPs_write_read1(0x02E,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x128,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x11E,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x77E,0x24,&rx_data);
|
||||
SpiPs_write_read1(0x11F,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x121,0x02,&rx_data);
|
||||
SpiPs_write_read1(0x11B,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x161,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x162,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x163,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x164,0x05,&rx_data);
|
||||
SpiPs_write_read1(0x165,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x166,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x167,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x168,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x169,0x55,&rx_data);
|
||||
SpiPs_write_read1(0xA2D,0x02,&rx_data);
|
||||
SpiPs_write_read1(0xA07,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA08,0x0F,&rx_data);
|
||||
SpiPs_write_read1(0xA1C,0x01,&rx_data);
|
||||
SpiPs_write_read1(0xA16,0x2A,&rx_data);
|
||||
SpiPs_write_read1(0xA17,0xAA,&rx_data);
|
||||
SpiPs_write_read1(0xA18,0xAA,&rx_data);
|
||||
SpiPs_write_read1(0xA19,0xAA,&rx_data);
|
||||
SpiPs_write_read1(0xA1A,0xAA,&rx_data);
|
||||
SpiPs_write_read1(0xA1B,0xAA,&rx_data);
|
||||
SpiPs_write_read1(0x186,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x763,0x34,&rx_data);
|
||||
SpiPs_write_read1(0x76D,0x34,&rx_data);
|
||||
SpiPs_write_read1(0x101,0xEF,&rx_data);
|
||||
SpiPs_write_read1(0x101,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x800,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x81A,0xF7,&rx_data);
|
||||
SpiPs_write_read1(0x81B,0x34,&rx_data);
|
||||
SpiPs_write_read1(0x81C,0x33,&rx_data);
|
||||
SpiPs_write_read1(0x81D,0x12,&rx_data);
|
||||
SpiPs_write_read1(0x81E,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x81F,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x820,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x821,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x800,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x800,0x81,&rx_data);
|
||||
//最少0.1s
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x77E,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x77E,0x24,&rx_data);
|
||||
SpiPs_write_read1(0x11F,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x121,0x02,&rx_data);
|
||||
SpiPs_write_read1(0x11B,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x11E,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x161,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x162,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x164,0x05,&rx_data);
|
||||
SpiPs_write_read1(0x165,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x166,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x167,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x168,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x169,0x55,&rx_data);
|
||||
SpiPs_write_read1(0xA2D,0x02,&rx_data);
|
||||
SpiPs_write_read1(0xA07,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA08,0x0F,&rx_data);
|
||||
SpiPs_write_read1(0xA1C,0x01,&rx_data);
|
||||
SpiPs_write_read1(0xA16,0x15,&rx_data);
|
||||
SpiPs_write_read1(0xA17,0x55,&rx_data);
|
||||
SpiPs_write_read1(0xA18,0x55,&rx_data);
|
||||
SpiPs_write_read1(0xA19,0x55,&rx_data);
|
||||
SpiPs_write_read1(0xA1A,0x55,&rx_data);
|
||||
SpiPs_write_read1(0xA1B,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x81A,0xF7,&rx_data);
|
||||
SpiPs_write_read1(0x81B,0x44,&rx_data);
|
||||
SpiPs_write_read1(0x81C,0x33,&rx_data);
|
||||
SpiPs_write_read1(0x81D,0x14,&rx_data);
|
||||
SpiPs_write_read1(0x800,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x800,0x82,&rx_data);
|
||||
//最少0.1s
|
||||
usleep(500000);
|
||||
SpiPs_write_read1(0x77E,0x00,&rx_data);
|
||||
//恢复校准前设置
|
||||
SpiPs_write_read1(0x000,0x02,&rx_data);
|
||||
SpiPs_write_read1(0x02E,0x06,&rx_data);
|
||||
SpiPs_write_read1(0x03D,0x1B,&rx_data);
|
||||
SpiPs_write_read1(0x03E,0x39,&rx_data);
|
||||
SpiPs_write_read1(0x03F,0x27,&rx_data);
|
||||
SpiPs_write_read1(0x040,0xF8,&rx_data);
|
||||
SpiPs_write_read1(0x109,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x10A,0x70,&rx_data);
|
||||
SpiPs_write_read1(0x11B,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x11E,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x11F,0x33,&rx_data);
|
||||
SpiPs_write_read1(0x128,0x10,&rx_data);
|
||||
SpiPs_write_read1(0x161,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x162,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x164,0x05,&rx_data);
|
||||
SpiPs_write_read1(0x165,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x166,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x167,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x168,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x169,0x55,&rx_data);
|
||||
SpiPs_write_read1(0xA07,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA08,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA16,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA17,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA18,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA19,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1A,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1B,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1C,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA2D,0x00,&rx_data);
|
||||
usleep(1000);
|
||||
SpiPs_write_read2(0x615,0x00,&rx_data);
|
||||
temp=rx_data;
|
||||
SpiPs_write_read2(0x635,0x00,&rx_data);
|
||||
temp=rx_data;
|
||||
////配置Tx NCO BIST ON
|
||||
//SpiPs_write_read1(0x11B,0x01,&rx_data);
|
||||
//SpiPs_write_read1(0x11E,0x01,&rx_data);
|
||||
//SpiPs_write_read1(0x161,0x01,&rx_data);
|
||||
//SpiPs_write_read1(0x162,0x01,&rx_data);
|
||||
////配置Tx NCO频率 1MHz
|
||||
//SpiPs_write_read1(0x164,0x05,&rx_data);
|
||||
//SpiPs_write_read1(0x165,0x55,&rx_data);
|
||||
//SpiPs_write_read1(0x166,0x55,&rx_data);
|
||||
//SpiPs_write_read1(0x167,0x55,&rx_data);
|
||||
//SpiPs_write_read1(0x168,0x55,&rx_data);
|
||||
//SpiPs_write_read1(0x169,0x55,&rx_data);
|
||||
}
|
||||
+835
@@ -0,0 +1,835 @@
|
||||
/*
|
||||
* cx9261a_710_config.c
|
||||
*
|
||||
* Created on: 2024年3月21日
|
||||
* Author: cxlab
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* cx9261a_076_config.c
|
||||
*
|
||||
* Created on: 2023年11月30日
|
||||
* Author: cxlab
|
||||
*/
|
||||
|
||||
|
||||
#include "xilinx_io.h"
|
||||
#include "sleep.h"
|
||||
void cx9261a_710_config(void){
|
||||
u8 rx_data;
|
||||
u8 temp,r13D,r13E;
|
||||
|
||||
//setPin(pin,value)
|
||||
GpioSetPinDir(0,0x01);
|
||||
GpioWritePin(0,1);
|
||||
GpioSetPinDir(32,0x01);
|
||||
GpioWritePin(32,1);
|
||||
GpioSetPinDir(33,0x01);
|
||||
GpioWritePin(33,1);
|
||||
GpioSetPinDir(34,0x01);
|
||||
GpioWritePin(34,0);
|
||||
GpioSetPinDir(35,0x01); //tx:0-rx:1
|
||||
GpioWritePin(35,1); //tx:0-rx:1
|
||||
GpioSetPinDir(36,0x01); //fdd:0-tdd:1
|
||||
GpioWritePin(36,1); //fdd:0-tdd:1
|
||||
GpioSetPinDir(37,0x01); //1r1t:0-2r2t:1
|
||||
GpioWritePin(37,1); //1r1t:0-2r2t:1
|
||||
GpioSetPinDir(38,0x01); //dualport:0-singleport:1
|
||||
GpioWritePin(38,1); //dualport:0-singleport:1
|
||||
GpioSetPinDir(39,0x01);
|
||||
GpioWritePin(39,1);
|
||||
GpioSetPinDir(40,0x01);
|
||||
GpioWritePin(40,1);
|
||||
//配置芯片
|
||||
//初始化芯片
|
||||
SpiPs_write_read1(0x000,0x02,&rx_data);
|
||||
SpiPs_write_read1(0x773,0x53,&rx_data);
|
||||
SpiPs_write_read1(0x774,0x86,&rx_data);
|
||||
SpiPs_write_read1(0x781,0x6F,&rx_data);
|
||||
SpiPs_write_read1(0x70B,0x0E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x0E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x0E,&rx_data);
|
||||
SpiPs_write_read1(0x624,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x625,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x61E,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x61F,0x08,&rx_data);
|
||||
SpiPs_write_read1(0x621,0x4D,&rx_data);
|
||||
SpiPs_write_read1(0x622,0x19,&rx_data);
|
||||
SpiPs_write_read1(0x627,0x10,&rx_data);
|
||||
SpiPs_write_read1(0x646,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x647,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x640,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x641,0x08,&rx_data);
|
||||
SpiPs_write_read1(0x643,0x4D,&rx_data);
|
||||
SpiPs_write_read1(0x644,0x19,&rx_data);
|
||||
SpiPs_write_read1(0x649,0x10,&rx_data);
|
||||
SpiPs_write_read1(0x668,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x669,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x662,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x663,0x08,&rx_data);
|
||||
SpiPs_write_read1(0x665,0x4D,&rx_data);
|
||||
SpiPs_write_read1(0x666,0x19,&rx_data);
|
||||
SpiPs_write_read1(0x66B,0x10,&rx_data);
|
||||
SpiPs_write_read1(0x68A,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x68B,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x684,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x685,0x08,&rx_data);
|
||||
SpiPs_write_read1(0x687,0x4D,&rx_data);
|
||||
SpiPs_write_read1(0x688,0x19,&rx_data);
|
||||
SpiPs_write_read1(0x68D,0x10,&rx_data);
|
||||
SpiPs_write_read1(0x6AC,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x6AD,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x6A6,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x6A7,0x08,&rx_data);
|
||||
SpiPs_write_read1(0x6A9,0x4D,&rx_data);
|
||||
SpiPs_write_read1(0x6AA,0x19,&rx_data);
|
||||
SpiPs_write_read1(0x6AF,0x10,&rx_data);
|
||||
SpiPs_write_read1(0x705,0xFC,&rx_data);
|
||||
SpiPs_write_read1(0x706,0x6D,&rx_data);
|
||||
SpiPs_write_read1(0x707,0x91,&rx_data);
|
||||
SpiPs_write_read1(0x708,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x709,0x94,&rx_data);
|
||||
SpiPs_write_read1(0x70A,0xFC,&rx_data);
|
||||
SpiPs_write_read1(0x70C,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0x721,0xFC,&rx_data);
|
||||
SpiPs_write_read1(0x722,0x6D,&rx_data);
|
||||
SpiPs_write_read1(0x723,0x91,&rx_data);
|
||||
SpiPs_write_read1(0x724,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x725,0x94,&rx_data);
|
||||
SpiPs_write_read1(0x726,0xFC,&rx_data);
|
||||
SpiPs_write_read1(0x728,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0x73D,0xFC,&rx_data);
|
||||
SpiPs_write_read1(0x73E,0x6D,&rx_data);
|
||||
SpiPs_write_read1(0x73F,0x91,&rx_data);
|
||||
SpiPs_write_read1(0x740,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x741,0x94,&rx_data);
|
||||
SpiPs_write_read1(0x742,0xFC,&rx_data);
|
||||
SpiPs_write_read1(0x744,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0x75A,0x83,&rx_data);
|
||||
SpiPs_write_read1(0x75B,0xDA,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x75B,0x9A,&rx_data);
|
||||
SpiPs_write_read1(0x75C,0x81,&rx_data);
|
||||
SpiPs_write_read1(0x763,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x764,0x83,&rx_data);
|
||||
SpiPs_write_read1(0x765,0xDA,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x765,0x9A,&rx_data);
|
||||
SpiPs_write_read1(0x766,0x81,&rx_data);
|
||||
SpiPs_write_read1(0x76D,0x04,&rx_data);
|
||||
//初始化电源
|
||||
SpiPs_write_read1(0x031,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x032,0x7F,&rx_data);
|
||||
SpiPs_write_read1(0x033,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x034,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x035,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x036,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x037,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x038,0xFB,&rx_data);
|
||||
SpiPs_write_read1(0x039,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x03A,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x03B,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x03C,0xF8,&rx_data);
|
||||
SpiPs_write_read1(0x03D,0x1B,&rx_data);
|
||||
SpiPs_write_read1(0x03E,0x39,&rx_data);
|
||||
SpiPs_write_read1(0x03F,0x26,&rx_data);
|
||||
SpiPs_write_read1(0x040,0x78,&rx_data);
|
||||
SpiPs_write_read1(0x041,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x042,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x043,0xE7,&rx_data);
|
||||
SpiPs_write_read1(0x044,0xF8,&rx_data);
|
||||
SpiPs_write_read1(0x045,0x18,&rx_data);
|
||||
SpiPs_write_read1(0x046,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x047,0x3F,&rx_data);
|
||||
SpiPs_write_read1(0x048,0xF8,&rx_data);
|
||||
SpiPs_write_read1(0x049,0x1F,&rx_data);
|
||||
SpiPs_write_read1(0x04A,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x04B,0x07,&rx_data);
|
||||
SpiPs_write_read1(0x04C,0xF8,&rx_data);
|
||||
SpiPs_write_read1(0x04D,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x04E,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x04F,0xD9,&rx_data);
|
||||
SpiPs_write_read1(0x050,0xFE,&rx_data);
|
||||
//自定义接收模式
|
||||
SpiPs_write_read1(0x041,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x042,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x043,0xE7,&rx_data);
|
||||
SpiPs_write_read1(0x044,0xF8,&rx_data);
|
||||
//自定义发射模式
|
||||
SpiPs_write_read1(0x045,0x18,&rx_data);
|
||||
SpiPs_write_read1(0x046,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x047,0x3F,&rx_data);
|
||||
SpiPs_write_read1(0x048,0xF8,&rx_data);
|
||||
//自定义FDD模式
|
||||
SpiPs_write_read1(0x049,0x1B,&rx_data);
|
||||
SpiPs_write_read1(0x04A,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x04B,0x27,&rx_data);
|
||||
SpiPs_write_read1(0x04C,0xF8,&rx_data);
|
||||
//配置BBPLL
|
||||
SpiPs_write_read1(0x789,0x10,&rx_data);
|
||||
SpiPs_write_read1(0x785,0x49,&rx_data);
|
||||
SpiPs_write_read1(0x788,0x24,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x788,0xA4,&rx_data);
|
||||
SpiPs_write_read1(0x0C0,0x50,&rx_data);
|
||||
SpiPs_write_read1(0x0C1,0x50,&rx_data);
|
||||
SpiPs_write_read1(0x0C2,0x50,&rx_data);
|
||||
SpiPs_write_read1(0x601,0x0F,&rx_data);
|
||||
SpiPs_write_read1(0x602,0x21,&rx_data);
|
||||
SpiPs_write_read1(0x60D,0x0D,&rx_data);
|
||||
SpiPs_write_read1(0x60E,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x60F,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x610,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x611,0x2F,&rx_data);
|
||||
SpiPs_write_read1(0x612,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x70E,0x6B,&rx_data);
|
||||
SpiPs_write_read1(0x72A,0x6B,&rx_data);
|
||||
SpiPs_write_read1(0x746,0x6B,&rx_data);
|
||||
SpiPs_write_read1(0x70F,0xE0,&rx_data);
|
||||
SpiPs_write_read1(0x72B,0xE0,&rx_data);
|
||||
SpiPs_write_read1(0x747,0xE0,&rx_data);
|
||||
SpiPs_write_read1(0x70D,0x43,&rx_data);
|
||||
SpiPs_write_read1(0x729,0x43,&rx_data);
|
||||
SpiPs_write_read1(0x745,0x43,&rx_data);
|
||||
SpiPs_write_read1(0x782,0x76,&rx_data);
|
||||
SpiPs_write_read1(0x783,0x76,&rx_data);
|
||||
SpiPs_write_read1(0x784,0x06,&rx_data);
|
||||
//配置PLL来源
|
||||
SpiPs_write_read1(0x77D,0xCF,&rx_data);
|
||||
SpiPs_write_read1(0x775,0x24,&rx_data);
|
||||
SpiPs_write_read1(0x6C3,0x00,&rx_data);
|
||||
//配置PLL1
|
||||
SpiPs_write_read1(0x620,0x91,&rx_data);
|
||||
SpiPs_write_read1(0x61D,0x37,&rx_data);
|
||||
SpiPs_write_read1(0xB06,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB07,0xCB,&rx_data);
|
||||
SpiPs_write_read1(0xB08,0x20,&rx_data);
|
||||
SpiPs_write_read1(0xB09,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB0A,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x61A,0x0C,&rx_data);
|
||||
SpiPs_write_read1(0x61B,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x61C,0x08,&rx_data);
|
||||
SpiPs_write_read1(0x62A,0x0B,&rx_data);
|
||||
//配置PLL2
|
||||
SpiPs_write_read1(0x642,0x91,&rx_data);
|
||||
SpiPs_write_read1(0x63F,0x35,&rx_data);
|
||||
SpiPs_write_read1(0xB14,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB15,0xFA,&rx_data);
|
||||
SpiPs_write_read1(0xB16,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB17,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB18,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x63C,0x0D,&rx_data);
|
||||
SpiPs_write_read1(0x63D,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x63E,0x0B,&rx_data);
|
||||
SpiPs_write_read1(0x64C,0x00,&rx_data);
|
||||
//配置PLL3
|
||||
SpiPs_write_read1(0x664,0x81,&rx_data);
|
||||
SpiPs_write_read1(0x661,0x36,&rx_data);
|
||||
SpiPs_write_read1(0xB22,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB23,0xBB,&rx_data);
|
||||
SpiPs_write_read1(0xB24,0x80,&rx_data);
|
||||
SpiPs_write_read1(0xB25,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB26,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x65E,0x0B,&rx_data);
|
||||
SpiPs_write_read1(0x65F,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x660,0x0E,&rx_data);
|
||||
SpiPs_write_read1(0x66E,0x0B,&rx_data);
|
||||
//配置PLL4
|
||||
SpiPs_write_read1(0x686,0x91,&rx_data);
|
||||
SpiPs_write_read1(0x683,0x36,&rx_data);
|
||||
SpiPs_write_read1(0xB30,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB31,0xDA,&rx_data);
|
||||
SpiPs_write_read1(0xB32,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0xB33,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB34,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x680,0x0C,&rx_data);
|
||||
SpiPs_write_read1(0x681,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x682,0x08,&rx_data);
|
||||
SpiPs_write_read1(0x690,0x0B,&rx_data);
|
||||
//配置PLL5
|
||||
SpiPs_write_read1(0x6A8,0x81,&rx_data);
|
||||
SpiPs_write_read1(0x6A5,0x36,&rx_data);
|
||||
SpiPs_write_read1(0xB3E,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB3F,0x9C,&rx_data);
|
||||
SpiPs_write_read1(0xB40,0x40,&rx_data);
|
||||
SpiPs_write_read1(0xB41,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB42,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x6A2,0x0C,&rx_data);
|
||||
SpiPs_write_read1(0x6A3,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x6A4,0x0C,&rx_data);
|
||||
SpiPs_write_read1(0x6B2,0x0B,&rx_data);
|
||||
//配置Tx1通道频率相关寄存器
|
||||
SpiPs_write_read1(0x75F,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x761,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x762,0x70,&rx_data);
|
||||
//配置Tx1通道频率相关寄存器
|
||||
SpiPs_write_read1(0x769,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x76B,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x76C,0x70,&rx_data);
|
||||
//配置Rx1通道
|
||||
SpiPs_write_read1(0x700,0x56,&rx_data);
|
||||
SpiPs_write_read1(0x701,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x702,0xDB,&rx_data);
|
||||
SpiPs_write_read1(0x703,0x45,&rx_data);
|
||||
SpiPs_write_read1(0x704,0xF8,&rx_data);
|
||||
SpiPs_write_read1(0x907,0x1F,&rx_data);
|
||||
//配置Rx2通道
|
||||
SpiPs_write_read1(0x71C,0x56,&rx_data);
|
||||
SpiPs_write_read1(0x71D,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x71E,0xDB,&rx_data);
|
||||
SpiPs_write_read1(0x71F,0x45,&rx_data);
|
||||
SpiPs_write_read1(0x720,0xF8,&rx_data);
|
||||
SpiPs_write_read1(0x907,0x1F,&rx_data);
|
||||
//配置Rx3通道
|
||||
SpiPs_write_read1(0x738,0x56,&rx_data);
|
||||
SpiPs_write_read1(0x739,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x73A,0xDB,&rx_data);
|
||||
SpiPs_write_read1(0x73B,0x45,&rx_data);
|
||||
SpiPs_write_read1(0x73C,0xF8,&rx_data);
|
||||
SpiPs_write_read1(0x907,0x1F,&rx_data);
|
||||
//配置Tx1通道
|
||||
SpiPs_write_read1(0x75E,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x75D,0x4A,&rx_data);
|
||||
SpiPs_write_read1(0x75F,0x7D,&rx_data);
|
||||
SpiPs_write_read1(0x760,0xFF,&rx_data);
|
||||
//配置Tx2通道
|
||||
SpiPs_write_read1(0x768,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x767,0x4A,&rx_data);
|
||||
SpiPs_write_read1(0x769,0x7D,&rx_data);
|
||||
SpiPs_write_read1(0x76A,0xFF,&rx_data);
|
||||
//配置Rx滤波器
|
||||
SpiPs_write_read1(0x106,0x02,&rx_data);
|
||||
//配置Tx滤波器
|
||||
SpiPs_write_read1(0x107,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x108,0xD0,&rx_data);
|
||||
//配置Rx混频器
|
||||
SpiPs_write_read1(0x11C,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA07,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA08,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA09,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA16,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA17,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA18,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA19,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1A,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1B,0x00,&rx_data);
|
||||
//配置Tx混频器
|
||||
SpiPs_write_read1(0x128,0x10,&rx_data);
|
||||
SpiPs_write_read1(0x11B,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x11E,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x161,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x162,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x164,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x165,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x166,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x167,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x168,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x169,0x00,&rx_data);
|
||||
//配置AGC
|
||||
SpiPs_write_read1(0x903,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x900,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x901,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x908,0x77,&rx_data);
|
||||
SpiPs_write_read1(0x909,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x90A,0x32,&rx_data);
|
||||
SpiPs_write_read1(0x90D,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x90E,0x0F,&rx_data);
|
||||
SpiPs_write_read1(0x90F,0x65,&rx_data);
|
||||
SpiPs_write_read1(0x910,0x32,&rx_data);
|
||||
SpiPs_write_read1(0x911,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x912,0x0F,&rx_data);
|
||||
SpiPs_write_read1(0x913,0x3A,&rx_data);
|
||||
SpiPs_write_read1(0x914,0x37,&rx_data);
|
||||
SpiPs_write_read1(0x915,0x34,&rx_data);
|
||||
SpiPs_write_read1(0x916,0x31,&rx_data);
|
||||
//切换到休眠模式
|
||||
SpiPs_write_read1(0x02E,0x01,&rx_data);
|
||||
usleep(1000000);
|
||||
//切换到校准模式
|
||||
SpiPs_write_read1(0x02E,0x03,&rx_data);
|
||||
usleep(100000);
|
||||
//BBPll锁定
|
||||
SpiPs_write_read1(0x600,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x600,0x11,&rx_data);
|
||||
usleep(100000);
|
||||
//BBPll锁定 成功
|
||||
//ADC校准
|
||||
SpiPs_write_read1(0x70B,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x70F,0xE0,&rx_data);
|
||||
SpiPs_write_read1(0x710,0x83,&rx_data);
|
||||
SpiPs_write_read1(0x711,0xF0,&rx_data);
|
||||
SpiPs_write_read1(0x72B,0xE0,&rx_data);
|
||||
SpiPs_write_read1(0x72C,0x83,&rx_data);
|
||||
SpiPs_write_read1(0x72D,0xF0,&rx_data);
|
||||
SpiPs_write_read1(0x747,0xE0,&rx_data);
|
||||
SpiPs_write_read1(0x748,0x83,&rx_data);
|
||||
SpiPs_write_read1(0x749,0xF0,&rx_data);
|
||||
SpiPs_write_read1(0x713,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x72F,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x74B,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x70B,0x9E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x9E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x9E,&rx_data);
|
||||
SpiPs_write_read1(0x70B,0x9A,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x9A,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x9A,&rx_data);
|
||||
SpiPs_write_read1(0x70B,0x9E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x9E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x9E,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x70B,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x713,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0x72F,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0x74B,0xC0,&rx_data);
|
||||
//flash校准
|
||||
SpiPs_write_read1(0x70B,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x715,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x731,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x74D,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x715,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0x731,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0x74D,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0x716,0x40,&rx_data);
|
||||
SpiPs_write_read1(0x732,0x40,&rx_data);
|
||||
SpiPs_write_read1(0x74E,0x40,&rx_data);
|
||||
SpiPs_write_read1(0x70B,0x16,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x16,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x16,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x70B,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x715,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x731,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x74D,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x716,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x732,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x74E,0x00,&rx_data);
|
||||
//DC Tracking
|
||||
SpiPs_write_read1(0x109,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x10A,0x70,&rx_data);
|
||||
SpiPs_write_read1(0x11F,0x33,&rx_data);
|
||||
//Rx1 QEC校准
|
||||
SpiPs_write_read1(0x02E,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x03F,0x26,&rx_data);
|
||||
SpiPs_write_read1(0x040,0x78,&rx_data);
|
||||
SpiPs_write_read1(0x77D,0x90,&rx_data);
|
||||
SpiPs_write_read1(0x775,0x24,&rx_data);
|
||||
SpiPs_write_read1(0x6C3,0x05,&rx_data);
|
||||
SpiPs_write_read1(0x61D,0x27,&rx_data);
|
||||
SpiPs_write_read1(0x617,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x617,0x03,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x61D,0x37,&rx_data);
|
||||
SpiPs_write_read1(0x686,0x81,&rx_data);
|
||||
SpiPs_write_read1(0x683,0x36,&rx_data);
|
||||
SpiPs_write_read1(0xB30,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB31,0x87,&rx_data);
|
||||
SpiPs_write_read1(0xB32,0x04,&rx_data);
|
||||
SpiPs_write_read1(0xB33,0x44,&rx_data);
|
||||
SpiPs_write_read1(0xB34,0x44,&rx_data);
|
||||
SpiPs_write_read1(0x680,0x0C,&rx_data);
|
||||
SpiPs_write_read1(0x681,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x682,0x0C,&rx_data);
|
||||
SpiPs_write_read1(0x690,0x0B,&rx_data);
|
||||
SpiPs_write_read1(0x683,0x26,&rx_data);
|
||||
SpiPs_write_read1(0x67D,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x67D,0x03,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x683,0x36,&rx_data);
|
||||
SpiPs_write_read1(0x000,0x12,&rx_data);
|
||||
SpiPs_write_read1(0x77E,0x50,&rx_data);
|
||||
SpiPs_write_read1(0x11B,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x11E,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x164,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x165,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x166,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x167,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x168,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x169,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x161,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x162,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x162,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x161,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x706,0x65,&rx_data);
|
||||
SpiPs_write_read1(0x6C3,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x75F,0x7D,&rx_data);
|
||||
SpiPs_write_read1(0x11F,0x73,&rx_data);
|
||||
SpiPs_write_read1(0x153,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x708,0x24,&rx_data);
|
||||
SpiPs_write_read1(0x196,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x02A,0x12,&rx_data);
|
||||
|
||||
do{
|
||||
usleep(100);
|
||||
SpiPs_write_read2(0x14D,0x00,&rx_data);
|
||||
temp=rx_data&0x10;
|
||||
}while (temp != 16);
|
||||
|
||||
SpiPs_write_read1(0x02A,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x196,0x11,&rx_data);
|
||||
SpiPs_write_read2(0x13D,0x00,&rx_data);
|
||||
r13D = rx_data;
|
||||
SpiPs_write_read2(0x13E,0x00,&rx_data);
|
||||
r13E = rx_data;
|
||||
|
||||
unsigned long B = r13D * 256 + r13E;
|
||||
signed long B_s = B - (B >= 32768) * 65536;
|
||||
unsigned long B_abs = abs(B_s);
|
||||
unsigned short B_b = (unsigned short)B_abs;
|
||||
unsigned short B_delay = (B_b>>6) & 0x1ff;
|
||||
|
||||
if(B_s > 0)
|
||||
{
|
||||
SpiPs_write_read1(0x199, ((B_delay>>8)&0x1),&rx_data);
|
||||
SpiPs_write_read1(0x19A, B_delay&0xff,&rx_data);
|
||||
SpiPs_write_read1(0x19B, 0,&rx_data);
|
||||
SpiPs_write_read1(0x19C, 0,&rx_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
SpiPs_write_read1(0x199, 0,&rx_data);
|
||||
SpiPs_write_read1(0x19A, 0,&rx_data);
|
||||
SpiPs_write_read1(0x19B, ((B_delay>>8)&0x1),&rx_data);
|
||||
SpiPs_write_read1(0x19C, B_delay&0xff,&rx_data);
|
||||
}
|
||||
|
||||
SpiPs_write_read1(0x196,0x10,&rx_data);
|
||||
SpiPs_write_read1(0x153,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x02A,0x12,&rx_data);
|
||||
|
||||
do{
|
||||
usleep(100);
|
||||
SpiPs_write_read2(0x14D,0x00,&rx_data);
|
||||
temp=rx_data&0x10;
|
||||
}while (temp != 16);
|
||||
|
||||
SpiPs_write_read1(0x02A,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x77E,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x000,0x02,&rx_data);
|
||||
//Rx2 QEC校准
|
||||
SpiPs_write_read1(0x02E,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x03F,0x26,&rx_data);
|
||||
SpiPs_write_read1(0x040,0x78,&rx_data);
|
||||
SpiPs_write_read1(0x77D,0x60,&rx_data);
|
||||
SpiPs_write_read1(0x775,0x24,&rx_data);
|
||||
SpiPs_write_read1(0x6C3,0x0A,&rx_data);
|
||||
SpiPs_write_read1(0x61D,0x27,&rx_data);
|
||||
SpiPs_write_read1(0x617,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x617,0x03,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x61D,0x37,&rx_data);
|
||||
SpiPs_write_read1(0x686,0x81,&rx_data);
|
||||
SpiPs_write_read1(0x683,0x36,&rx_data);
|
||||
SpiPs_write_read1(0xB30,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB31,0x87,&rx_data);
|
||||
SpiPs_write_read1(0xB32,0x04,&rx_data);
|
||||
SpiPs_write_read1(0xB33,0x44,&rx_data);
|
||||
SpiPs_write_read1(0xB34,0x44,&rx_data);
|
||||
SpiPs_write_read1(0x680,0x0C,&rx_data);
|
||||
SpiPs_write_read1(0x681,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x682,0x0C,&rx_data);
|
||||
SpiPs_write_read1(0x690,0x0B,&rx_data);
|
||||
SpiPs_write_read1(0x683,0x26,&rx_data);
|
||||
SpiPs_write_read1(0x67D,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x67D,0x03,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x683,0x36,&rx_data);
|
||||
SpiPs_write_read1(0x000,0x22,&rx_data);
|
||||
SpiPs_write_read1(0x77E,0x0A,&rx_data);
|
||||
SpiPs_write_read1(0x11B,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x11E,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x164,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x165,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x166,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x167,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x168,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x169,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x161,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x162,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x162,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x161,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x706,0x65,&rx_data);
|
||||
SpiPs_write_read1(0x6C3,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x75F,0x7D,&rx_data);
|
||||
SpiPs_write_read1(0x11F,0x73,&rx_data);
|
||||
SpiPs_write_read1(0x153,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x724,0x24,&rx_data);
|
||||
SpiPs_write_read1(0x196,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x02B,0x12,&rx_data);
|
||||
|
||||
do{
|
||||
usleep(100);
|
||||
SpiPs_write_read2(0x14D,0x00,&rx_data);
|
||||
temp=rx_data&0x10;
|
||||
}while (temp != 16);
|
||||
|
||||
SpiPs_write_read1(0x02B,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x196,0x11,&rx_data);
|
||||
SpiPs_write_read2(0x13D,0x00,&rx_data);
|
||||
r13D = rx_data;
|
||||
SpiPs_write_read2(0x13E,0x00,&rx_data);
|
||||
r13E = rx_data;
|
||||
|
||||
B = r13D * 256 + r13E;
|
||||
B_s = B - (B >= 32768) * 65536;
|
||||
B_abs = abs(B_s);
|
||||
B_b = (unsigned short)B_abs;
|
||||
B_delay = (B_b>>6) & 0x1ff;
|
||||
|
||||
if(B_s > 0)
|
||||
{
|
||||
SpiPs_write_read1(0x199, ((B_delay>>8)&0x1),&rx_data);
|
||||
SpiPs_write_read1(0x19A, B_delay&0xff,&rx_data);
|
||||
SpiPs_write_read1(0x19B, 0,&rx_data);
|
||||
SpiPs_write_read1(0x19C, 0,&rx_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
SpiPs_write_read1(0x199, 0,&rx_data);
|
||||
SpiPs_write_read1(0x19A, 0,&rx_data);
|
||||
SpiPs_write_read1(0x19B, ((B_delay>>8)&0x1),&rx_data);
|
||||
SpiPs_write_read1(0x19C, B_delay&0xff,&rx_data);
|
||||
}
|
||||
|
||||
SpiPs_write_read1(0x196,0x10,&rx_data);
|
||||
SpiPs_write_read1(0x153,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x02B,0x12,&rx_data);
|
||||
|
||||
do{
|
||||
usleep(100);
|
||||
SpiPs_write_read2(0x14D,0x00,&rx_data);
|
||||
temp=rx_data&0x10;
|
||||
}while (temp != 16);
|
||||
|
||||
SpiPs_write_read1(0x02B,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x77E,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x000,0x02,&rx_data);
|
||||
//恢复校准中被改变的配置
|
||||
SpiPs_write_read1(0x000,0x02,&rx_data);
|
||||
SpiPs_write_read1(0x02E,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x109,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x10A,0x70,&rx_data);
|
||||
SpiPs_write_read1(0x11B,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x11E,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x11F,0x33,&rx_data);
|
||||
SpiPs_write_read1(0x128,0x10,&rx_data);
|
||||
SpiPs_write_read1(0x161,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x162,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x164,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x165,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x166,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x167,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x168,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x169,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x6C3,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x775,0x24,&rx_data);
|
||||
SpiPs_write_read1(0x77D,0xCF,&rx_data);
|
||||
SpiPs_write_read1(0xA07,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA08,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA16,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA17,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA18,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA19,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1A,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1B,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x686,0x91,&rx_data);
|
||||
SpiPs_write_read1(0x683,0x36,&rx_data);
|
||||
SpiPs_write_read1(0xB30,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB31,0xDA,&rx_data);
|
||||
SpiPs_write_read1(0xB32,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0xB33,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB34,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x680,0x0C,&rx_data);
|
||||
SpiPs_write_read1(0x681,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x682,0x08,&rx_data);
|
||||
SpiPs_write_read1(0x690,0x0B,&rx_data);
|
||||
//TX校准
|
||||
SpiPs_write_read1(0x03F,0x27,&rx_data);
|
||||
SpiPs_write_read1(0x040,0xF8,&rx_data);
|
||||
SpiPs_write_read1(0x61D,0x27,&rx_data);
|
||||
SpiPs_write_read1(0x617,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x617,0x03,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x61D,0x37,&rx_data);
|
||||
SpiPs_write_read1(0x02E,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x128,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x11E,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x77E,0x24,&rx_data);
|
||||
SpiPs_write_read1(0x11F,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x121,0x02,&rx_data);
|
||||
SpiPs_write_read1(0x11B,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x161,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x162,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x163,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x164,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x165,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x166,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x167,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x168,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x169,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA2D,0x02,&rx_data);
|
||||
SpiPs_write_read1(0xA07,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA08,0x0F,&rx_data);
|
||||
SpiPs_write_read1(0xA1C,0x01,&rx_data);
|
||||
SpiPs_write_read1(0xA16,0x20,&rx_data);
|
||||
SpiPs_write_read1(0xA17,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA18,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA19,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1A,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1B,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x102,0x0F,&rx_data);
|
||||
SpiPs_write_read1(0x102,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x186,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x186,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x763,0x34,&rx_data);
|
||||
SpiPs_write_read1(0x76D,0x34,&rx_data);
|
||||
SpiPs_write_read1(0x101,0xEF,&rx_data);
|
||||
SpiPs_write_read1(0x101,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x800,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x81A,0xF7,&rx_data);
|
||||
SpiPs_write_read1(0x81B,0x34,&rx_data);
|
||||
SpiPs_write_read1(0x81C,0x33,&rx_data);
|
||||
SpiPs_write_read1(0x81D,0x12,&rx_data);
|
||||
SpiPs_write_read1(0x81E,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x81F,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x820,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x821,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x800,0x80,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x800,0x81,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x77E,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x77E,0x24,&rx_data);
|
||||
SpiPs_write_read1(0x11F,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x121,0x02,&rx_data);
|
||||
SpiPs_write_read1(0x11B,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x11E,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x161,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x162,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x164,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x165,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x166,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x167,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x168,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x169,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA2D,0x02,&rx_data);
|
||||
SpiPs_write_read1(0xA07,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA08,0x0F,&rx_data);
|
||||
SpiPs_write_read1(0xA1C,0x01,&rx_data);
|
||||
SpiPs_write_read1(0xA16,0x10,&rx_data);
|
||||
SpiPs_write_read1(0xA17,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA18,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA19,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1A,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1B,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x81A,0xF7,&rx_data);
|
||||
SpiPs_write_read1(0x81B,0x44,&rx_data);
|
||||
SpiPs_write_read1(0x81C,0x33,&rx_data);
|
||||
SpiPs_write_read1(0x81D,0x14,&rx_data);
|
||||
SpiPs_write_read1(0x800,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x800,0x82,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x77E,0x00,&rx_data);
|
||||
//恢复校准中被改变的配置
|
||||
SpiPs_write_read1(0x000,0x02,&rx_data);
|
||||
SpiPs_write_read1(0x02E,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x109,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x10A,0x70,&rx_data);
|
||||
SpiPs_write_read1(0x11B,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x11E,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x11F,0x33,&rx_data);
|
||||
SpiPs_write_read1(0x128,0x10,&rx_data);
|
||||
SpiPs_write_read1(0x161,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x162,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x164,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x165,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x166,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x167,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x168,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x169,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x6C3,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x775,0x24,&rx_data);
|
||||
SpiPs_write_read1(0x77D,0xCF,&rx_data);
|
||||
SpiPs_write_read1(0xA07,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA08,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA16,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA17,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA18,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA19,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1A,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1B,0x00,&rx_data);
|
||||
//Pll1锁定
|
||||
SpiPs_write_read1(0x61D,0x27,&rx_data);
|
||||
SpiPs_write_read1(0x617,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x617,0x03,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x61D,0x37,&rx_data);
|
||||
//Pll1锁定 成功
|
||||
//Pll2锁定
|
||||
SpiPs_write_read1(0x63F,0x25,&rx_data);
|
||||
SpiPs_write_read1(0x639,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x639,0x03,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x63F,0x35,&rx_data);
|
||||
//Pll2锁定 成功
|
||||
//Pll3锁定
|
||||
SpiPs_write_read1(0x661,0x26,&rx_data);
|
||||
SpiPs_write_read1(0x65B,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x65B,0x03,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x661,0x36,&rx_data);
|
||||
//Pll3锁定 成功
|
||||
//Pll4锁定
|
||||
SpiPs_write_read1(0x683,0x26,&rx_data);
|
||||
SpiPs_write_read1(0x67D,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x67D,0x03,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x683,0x36,&rx_data);
|
||||
//Pll4锁定 成功
|
||||
//Pll5锁定
|
||||
SpiPs_write_read1(0x6A5,0x26,&rx_data);
|
||||
SpiPs_write_read1(0x69F,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x69F,0x03,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x6A5,0x36,&rx_data);
|
||||
//Pll5锁定 成功
|
||||
//配置接口
|
||||
SpiPs_write_read1(0x02E,0x05,&rx_data);
|
||||
SpiPs_write_read1(0x003,0x33,&rx_data);
|
||||
SpiPs_write_read1(0x200,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x201,0x3F,&rx_data);
|
||||
SpiPs_write_read1(0x202,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x206,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x208,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x209,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x77F,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x780,0x33,&rx_data);
|
||||
SpiPs_write_read1(0x781,0x6F,&rx_data);
|
||||
//配置结束
|
||||
|
||||
SpiPs_write_read1(0x02E,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x780,0x00,&rx_data);
|
||||
|
||||
SpiPs_write_read1(0x11F,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x11F,0x33,&rx_data);
|
||||
////配置Tx NCO BIST ON
|
||||
//SpiPs_write_read1(0x11B,0x01,&rx_data);
|
||||
//SpiPs_write_read1(0x11E,0x01,&rx_data);
|
||||
//SpiPs_write_read1(0x161,0x01,&rx_data);
|
||||
//SpiPs_write_read1(0x162,0x01,&rx_data);
|
||||
////配置Tx NCO频率 1MHz
|
||||
//SpiPs_write_read1(0x164,0x05,&rx_data);
|
||||
//SpiPs_write_read1(0x165,0x55,&rx_data);
|
||||
//SpiPs_write_read1(0x166,0x55,&rx_data);
|
||||
//SpiPs_write_read1(0x167,0x55,&rx_data);
|
||||
//SpiPs_write_read1(0x168,0x55,&rx_data);
|
||||
//SpiPs_write_read1(0x169,0x55,&rx_data);
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* download_bin.c
|
||||
*
|
||||
* Created on: 2023Äê11ÔÂ23ÈÕ
|
||||
* Author: cxlab
|
||||
*/
|
||||
|
||||
#include "xilinx_io.h"
|
||||
#include "sleep.h"
|
||||
void download_bin(void){
|
||||
|
||||
// int temp;
|
||||
u8 rx_data;
|
||||
u8 data[4];
|
||||
u32 buf;
|
||||
u8 addr[2];
|
||||
int on = 1;
|
||||
if (on) {
|
||||
SpiPs_write_read1(0x071,0x26,&rx_data);
|
||||
SpiPs_write_read1(0x236,0x0F,&rx_data);
|
||||
SpiPs_write_read1(0x20A,0x01,&rx_data);
|
||||
for(int i=0;i<15448;i++){
|
||||
addr[0]=(i>>8)&0xff;
|
||||
addr[1]= i&0xff;
|
||||
buf=rom_read((u8 *)&addr);
|
||||
data[0]=buf>>24;
|
||||
data[1]=(buf>>16)&0xff;
|
||||
data[2]=(buf>>8)&0xff;
|
||||
data[3]=buf&0xff;
|
||||
for(int j=0;j<4;j++){
|
||||
SpiPs_write_read1(0x070,data[j],&rx_data);
|
||||
// SpiPs_write_read2(0x070,0x00,&rx_data);
|
||||
// temp=rx_data;
|
||||
}
|
||||
if(i==15447){
|
||||
xil_printf("bin download completely");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
SpiPs_write_read1(0x071,0x00,&rx_data);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,461 @@
|
||||
/*
|
||||
* Copyright (C) 2016 - 2018 Xilinx, 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:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 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 <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lwip/sockets.h"
|
||||
#include "netif/xadapter.h"
|
||||
#include "lwipopts.h"
|
||||
#include "xil_printf.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "xilinx_io.h"
|
||||
|
||||
#define THREAD_STACKSIZE 1024
|
||||
#define ACK 0x01
|
||||
u16_t echo_port = 7;
|
||||
//#define RECV_BUF_SIZE 65536*16*8
|
||||
#define RECV_BUF_SIZE 1024
|
||||
//char recv_buf[RECV_BUF_SIZE];
|
||||
char recv_buf[1024];
|
||||
char recv_buf_temp[3];
|
||||
char trans_buf[8192*5];
|
||||
struct spi_stack spistack;
|
||||
|
||||
|
||||
u16 hop_cnt = 0;
|
||||
|
||||
void print_echo_app_header()
|
||||
{
|
||||
xil_printf("%20s %6d %s\r\n", "echo server",
|
||||
echo_port,
|
||||
"$ telnet <board_ip> 7");
|
||||
|
||||
}
|
||||
|
||||
|
||||
enum {
|
||||
CMD_VER = 0,
|
||||
CMD_RST = 1,
|
||||
CMD_SPI_WRI = 2 ,
|
||||
CMD_SPI_READ = 3,
|
||||
CMD_DATA_CAPTURE0 = 4,
|
||||
CMD_WAVE_DOWNLOAD = 5,
|
||||
CMD_PIN_SET = 6,
|
||||
CMD_DATA_CAPTURE1 = 8,
|
||||
CMD_DATA_CAPTURE2 = 9,
|
||||
CMD_STACK_OUT = 10,
|
||||
CMD_hopping = 11,
|
||||
CMD_qecbin = 12,
|
||||
CMD_cx9261a_config = 13,
|
||||
CMD_cx3e04_config = 14,
|
||||
CMD_cx3e04_SPI_WRI = 15 ,
|
||||
CMD_cx3e04_SPI_READ = 16,
|
||||
CMD_IMAGE_UPDATE = 22,
|
||||
};
|
||||
/* thread spawned for each connection */
|
||||
void process_echo_request(void *p)
|
||||
{
|
||||
int sd = (int)p;
|
||||
int status;
|
||||
int n, nwrote,send_n,total_send;
|
||||
u8 rx_data;
|
||||
u32 capture_length;
|
||||
u8 pin;
|
||||
u8 pin_value;
|
||||
char FPGA_SDK_IP[]="FPGA:20240315-SDK:20231122";
|
||||
spistack.spi_write_num = 0;
|
||||
while (1) {
|
||||
/* read a max of RECV_BUF_SIZE bytes from socket */
|
||||
if ((n = read(sd, recv_buf, 5)) < 0) {
|
||||
xil_printf("%s: error reading from socket %d, closing socket\r\n", __FUNCTION__, sd);
|
||||
break;
|
||||
}
|
||||
|
||||
/* break if the recved message = "quit" */
|
||||
if (!strncmp(recv_buf, "quit", 4))
|
||||
break;
|
||||
|
||||
/* break if client closed connection */
|
||||
if (n <= 0)
|
||||
break;
|
||||
|
||||
else{/* excute cmd if recved message = "cmd"*/
|
||||
n=0;
|
||||
if (!strncmp(recv_buf, "cmd ", 4)){
|
||||
// xil_printf("%d %d %d %d.\r\n", recv_buf[0],recv_buf[1],recv_buf[2],recv_buf[4]);
|
||||
dbg_printf("Rece %d bytes.\r\n",n);
|
||||
switch(recv_buf[4]){
|
||||
case CMD_IMAGE_UPDATE:
|
||||
{
|
||||
|
||||
u32 offset;
|
||||
u32 image_size;
|
||||
recv_buf[0] = ACK;
|
||||
nwrote = write(sd, recv_buf, 1);
|
||||
n = read(sd, recv_buf, RECV_BUF_SIZE);
|
||||
|
||||
offset = *(u32 *)recv_buf;
|
||||
image_size = *(u32 *)(recv_buf + 4);
|
||||
xil_printf("offset is 0x%x image_size is 0x%x.\n", offset, image_size);
|
||||
|
||||
void *image_ptr = (void *)0x30000000;
|
||||
u32 LengthBytes;
|
||||
write(sd, recv_buf, 1); // ask for image data
|
||||
//// receive flash image to ddr
|
||||
LengthBytes = 0;
|
||||
while (LengthBytes < image_size)
|
||||
{
|
||||
n = read(sd, image_ptr + LengthBytes, RECV_BUF_SIZE);
|
||||
// xil_printf("read %d bytes.\n",n);
|
||||
LengthBytes = LengthBytes + n;
|
||||
}
|
||||
|
||||
// image data sumcheck
|
||||
|
||||
// program image data into flash
|
||||
//QspiStore( (u32) image_ptr, offset, image_size);
|
||||
//xil_printf("flash program done.\n", n);
|
||||
status = FfsSdWrite(image_ptr, image_size);
|
||||
write(sd, recv_buf, 1); // send done
|
||||
xil_printf("sd program done.\n", n);
|
||||
n = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case CMD_VER:
|
||||
dbg_printf("Version:FPGA_20240315;SDK_20231122;IP_192.168.1.99.\r\n");
|
||||
n=26;
|
||||
for(int i=0;i<26;i++){
|
||||
recv_buf[i] = FPGA_SDK_IP[i];
|
||||
}
|
||||
break;
|
||||
case CMD_RST:
|
||||
dbg_printf("Rece cmd excute rst.\r\n");
|
||||
GpioSetPinDir(NRST,GPIO_DIR_OUTPUT);
|
||||
DeviceRst();
|
||||
break;
|
||||
|
||||
case CMD_STACK_OUT:
|
||||
dbg_printf("Rece cmd STACK OUT.\r\n");
|
||||
spi_stack_out(&spistack);
|
||||
n=1;
|
||||
recv_buf[0] = 0x55;
|
||||
break;
|
||||
case CMD_SPI_WRI:
|
||||
read(sd, &recv_buf[5], 3);
|
||||
dbg_printf("Rece cmd excute spi write.\r\n");
|
||||
dbg_printf("ADDR 0x%x DATA 0x%x.\r\n",recv_buf[5]*256+recv_buf[6]-32768,recv_buf[7]);
|
||||
// SpiPs_write_read((u8 *)&recv_buf[5],&rx_data);
|
||||
status = spi_stack_in((u8 *)&recv_buf[5],&spistack);
|
||||
if(status){//when memory is near full,start spi write
|
||||
spi_stack_out(&spistack);
|
||||
}
|
||||
// n=1;
|
||||
// recv_buf[0] = rx_data;
|
||||
break;
|
||||
case CMD_SPI_READ:
|
||||
read(sd, &recv_buf[5], 3);
|
||||
dbg_printf("Rece cmd excute spi read.\r\n");
|
||||
dbg_printf("ADDR 0x%x DATA 0x%x.\r\n",recv_buf[5]*256+recv_buf[6],recv_buf[7]);
|
||||
SpiPs_write_read((u8 *)&recv_buf[5],&rx_data);
|
||||
n=1;
|
||||
recv_buf[0] = rx_data;
|
||||
break;
|
||||
case CMD_DATA_CAPTURE0:
|
||||
read(sd, &recv_buf[5], 4);
|
||||
capture_length = *((u32 *) &recv_buf[5]);//num of sample
|
||||
dbg_printf("Rece cmd excute %d sample data capture.\r\n",capture_length);
|
||||
XAxiDmaCapture(xAxiDma0Get(),capture_length);
|
||||
n = capture_length*8;
|
||||
total_send = 0;
|
||||
/* handle request */
|
||||
while(n>0){
|
||||
if(n>1024)
|
||||
send_n = 1024;
|
||||
else
|
||||
send_n = n;
|
||||
n= n-send_n;
|
||||
memcpy(recv_buf,TX_BUFFER_BASE + total_send,send_n);
|
||||
total_send = total_send + send_n;
|
||||
if ((nwrote = write(sd, &recv_buf, send_n)) < 0) {
|
||||
xil_printf("%s: ERROR responding to client echo request. received = %d, written = %d\r\n",__FUNCTION__, n, nwrote);
|
||||
xil_printf("Closing socket %d\r\n", sd);
|
||||
break;
|
||||
}
|
||||
else{
|
||||
if(send_n!=nwrote){
|
||||
xil_printf("%d Bytes Send %d.\r\n", send_n,nwrote);
|
||||
}
|
||||
}
|
||||
}
|
||||
dbg_printf("Send %d bytes.\r\n",n);
|
||||
break;
|
||||
case CMD_DATA_CAPTURE1:
|
||||
read(sd, &recv_buf[5], 4);
|
||||
capture_length = *((u32 *) &recv_buf[5]);//num of sample
|
||||
dbg_printf("Rece cmd excute %d sample data capture.\r\n",capture_length);
|
||||
XAxiDmaCapture(xAxiDma1Get(),capture_length);
|
||||
n = capture_length*8;
|
||||
total_send = 0;
|
||||
/* handle request */
|
||||
while(n>0){
|
||||
if(n>1024)
|
||||
send_n = 1024;
|
||||
else
|
||||
send_n = n;
|
||||
n= n-send_n;
|
||||
|
||||
memcpy(recv_buf,TX_BUFFER_BASE + total_send,send_n);
|
||||
total_send = total_send + send_n;
|
||||
if ((nwrote = write(sd, &recv_buf, send_n)) < 0) {
|
||||
xil_printf("%s: ERROR responding to client echo request. received = %d, written = %d\r\n",__FUNCTION__, n, nwrote);
|
||||
xil_printf("Closing socket %d\r\n", sd);
|
||||
break;
|
||||
}
|
||||
else{
|
||||
if(send_n!=nwrote){
|
||||
xil_printf("%d Bytes Send %d.\r\n", send_n,nwrote);
|
||||
}
|
||||
}
|
||||
}
|
||||
dbg_printf("Send %d bytes.\r\n",n);
|
||||
break;
|
||||
case CMD_DATA_CAPTURE2:
|
||||
read(sd, &recv_buf[5], 4);
|
||||
capture_length = *((u32 *) &recv_buf[5]);//num of sample
|
||||
dbg_printf("Rece cmd excute %d sample data capture.\r\n",capture_length);
|
||||
XAxiDmaCapture(xAxiDma2Get(),capture_length);
|
||||
n = capture_length*8;
|
||||
total_send = 0;
|
||||
/* handle request */
|
||||
while(n>0){
|
||||
if(n>1024)
|
||||
send_n = 1024;
|
||||
else
|
||||
send_n = n;
|
||||
n= n-send_n;
|
||||
memcpy(recv_buf,TX_BUFFER_BASE + total_send,send_n);
|
||||
total_send = total_send + send_n;
|
||||
if ((nwrote = write(sd, &recv_buf, send_n)) < 0) {
|
||||
xil_printf("%s: ERROR responding to client echo request. received = %d, written = %d\r\n",__FUNCTION__, n, nwrote);
|
||||
xil_printf("Closing socket %d\r\n", sd);
|
||||
break;
|
||||
}
|
||||
else{
|
||||
if(send_n!=nwrote){
|
||||
xil_printf("%d Bytes Send %d.\r\n", send_n,nwrote);
|
||||
}
|
||||
}
|
||||
}
|
||||
dbg_printf("Send %d bytes.\r\n",n);
|
||||
break;
|
||||
case CMD_WAVE_DOWNLOAD:
|
||||
dbg_printf("Rece cmd excute wave download.\r\n");
|
||||
while(n<WAVE_LENGTH){
|
||||
dbg_printf("Rece data num in recv_buf is %d.\r\n",n);
|
||||
n =n + read(sd, &trans_buf[n], 512);//
|
||||
}
|
||||
dbg_printf("Rece data num in recv_buf is %d.\r\n",n);
|
||||
DownloadWave((u8 *)&trans_buf[0]);
|
||||
n=0;
|
||||
break;
|
||||
case CMD_PIN_SET:
|
||||
read(sd, &recv_buf[5], 2);
|
||||
pin = (u8) recv_buf[5];
|
||||
pin_value = (u8) recv_buf[6];
|
||||
dbg_printf("Rece cmd excute pin %d set %d.\r\n",pin,pin_value);
|
||||
GpioSetPinDir(pin,GPIO_DIR_OUTPUT);
|
||||
GpioWritePin(pin,pin_value&0x01);//dma_axis_rx_rstn
|
||||
// recv_buf_temp[0]= 0x80;
|
||||
// recv_buf_temp[1]= 0x43;
|
||||
// recv_buf_temp[2]= 0xe7;
|
||||
// if((pin==0x20)&&(pin_value==0x01)){
|
||||
// SpiPs_write_read((u8 *)&recv_buf_temp,&rx_data);
|
||||
// }
|
||||
break;
|
||||
|
||||
case CMD_hopping:
|
||||
read(sd, &recv_buf[5], 4);
|
||||
int hop_flag=recv_buf[5]&0x01;
|
||||
frqhop_flag(hop_flag);
|
||||
if(hop_flag==1){
|
||||
xil_printf("hopping freqence start.\r\n");
|
||||
}else{
|
||||
xil_printf("hopping freqence end.\r\n");
|
||||
}
|
||||
break;
|
||||
case CMD_qecbin:
|
||||
download_bin();
|
||||
break;
|
||||
case CMD_cx9261a_config:
|
||||
read(sd, &recv_buf[5], 1);
|
||||
int lo = 5000;
|
||||
int f0 = 4;
|
||||
int fs = 80;
|
||||
int ref= 100;
|
||||
int dcCalibEnable = 1;
|
||||
int dcCalibLength = 7;
|
||||
if(recv_buf[5] == 0){
|
||||
cx9261a_151_config();
|
||||
}else if(recv_buf[5] == 1){
|
||||
cx9261a_076_config();
|
||||
configDcCalib(dcCalibEnable,dcCalibLength);
|
||||
rxFFTCalib(lo,fs,ref,8,1);
|
||||
rxFFTCalib(lo,fs,ref,8,2);
|
||||
rxFFTCalib(lo,fs,ref,8,3);
|
||||
txBisectionQecCalib(f0, fs);
|
||||
txBisectionDcCalib(f0, fs);
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_cx3e04_config:
|
||||
cx3e04_config();
|
||||
break;
|
||||
|
||||
case CMD_cx3e04_SPI_WRI:
|
||||
read(sd, &recv_buf[5], 3);
|
||||
dbg_printf("Rece cmd excute cx3e04_spi write.\r\n");
|
||||
dbg_printf("ADDR 0x%x DATA 0x%x.\r\n",recv_buf[5]*256+recv_buf[6]-32768,recv_buf[7]);
|
||||
int addr = recv_buf[5]*256+recv_buf[6];
|
||||
int value= recv_buf[7];
|
||||
cx3e04_write(addr,value);
|
||||
break;
|
||||
case CMD_cx3e04_SPI_READ:
|
||||
read(sd, &recv_buf[5], 2);
|
||||
dbg_printf("Rece cmd excute cx3e04_spi read.\r\n");
|
||||
dbg_printf("ADDR 0x%x.\r\n",recv_buf[5]*256+recv_buf[6]);
|
||||
addr = recv_buf[5]*256+recv_buf[6];
|
||||
n=1;
|
||||
recv_buf[0] = cx3e04_read(addr);
|
||||
break;
|
||||
default :
|
||||
xil_printf("cmd error 0x%x",recv_buf[4]);
|
||||
break;
|
||||
}
|
||||
|
||||
/*if(recv_buf[4] == 7){
|
||||
read(sd, &recv_buf[5], 4);
|
||||
capture_length = *((u32 *) &recv_buf[5]);//num of sample
|
||||
dbg_printf("Rece cmd excute %d sample data capture.\r\n",capture_length);
|
||||
XAxiDmaCapture2(capture_length);
|
||||
// memcpy(recv_buf,TX_BUFFER_BASE,capture_length*8);
|
||||
n = capture_length*8;
|
||||
total_send = 0;
|
||||
// handle request
|
||||
while(n>0){
|
||||
if(n>1024)
|
||||
send_n = 1024;
|
||||
else
|
||||
send_n = n;
|
||||
n= n-send_n;
|
||||
total_send = total_send + send_n;
|
||||
memcpy(recv_buf,TX_BUFFER_BASE + total_send,send_n);
|
||||
if ((nwrote = write(sd, &recv_buf, send_n)) < 0) {
|
||||
xil_printf("%s: ERROR responding to client echo request. received = %d, written = %d\r\n",
|
||||
__FUNCTION__, n, nwrote);
|
||||
xil_printf("Closing socket %d\r\n", sd);
|
||||
break;
|
||||
}
|
||||
else{
|
||||
if(send_n!=nwrote){
|
||||
xil_printf("%d Bytes Send %d.\r\n", send_n,nwrote);
|
||||
}
|
||||
}
|
||||
}
|
||||
dbg_printf("Send %d bytes.\r\n",n);
|
||||
}*/
|
||||
|
||||
}
|
||||
}
|
||||
/* handle request */
|
||||
if ((nwrote = write(sd, recv_buf, n)) < 0) {
|
||||
xil_printf("%s: ERROR responding to client echo request. received = %d, written = %d\r\n",
|
||||
__FUNCTION__, n, nwrote);
|
||||
xil_printf("Closing socket %d\r\n", sd);
|
||||
break;
|
||||
}
|
||||
else{
|
||||
if(n!=nwrote){
|
||||
xil_printf("%d Bytes Send %d.\r\n", n,nwrote);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* close connection */
|
||||
close(sd);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
void echo_application_thread()
|
||||
{
|
||||
int sock, new_sd;
|
||||
int size;
|
||||
#if LWIP_IPV6==0
|
||||
struct sockaddr_in address, remote;
|
||||
|
||||
memset(&address, 0, sizeof(address));
|
||||
|
||||
if ((sock = lwip_socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
||||
return;
|
||||
|
||||
address.sin_family = AF_INET;
|
||||
address.sin_port = htons(echo_port);
|
||||
address.sin_addr.s_addr = INADDR_ANY;
|
||||
#else
|
||||
struct sockaddr_in6 address, remote;
|
||||
|
||||
memset(&address, 0, sizeof(address));
|
||||
|
||||
address.sin6_len = sizeof(address);
|
||||
address.sin6_family = AF_INET6;
|
||||
address.sin6_port = htons(echo_port);
|
||||
|
||||
memset(&(address.sin6_addr), 0, sizeof(address.sin6_addr));
|
||||
|
||||
if ((sock = lwip_socket(AF_INET6, SOCK_STREAM, 0)) < 0)
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (lwip_bind(sock, (struct sockaddr *)&address, sizeof (address)) < 0)
|
||||
return;
|
||||
|
||||
lwip_listen(sock, 0);
|
||||
|
||||
size = sizeof(remote);
|
||||
|
||||
while (1) {
|
||||
if ((new_sd = lwip_accept(sock, (struct sockaddr *)&remote, (socklen_t *)&size)) > 0) {
|
||||
sys_thread_new("echos", process_echo_request,
|
||||
(void*)new_sd,
|
||||
THREAD_STACKSIZE,
|
||||
DEFAULT_THREAD_PRIO);
|
||||
}
|
||||
}
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* frqhop_config.c
|
||||
*
|
||||
* Created on: 2023年11月24日
|
||||
* Author: cxlab
|
||||
*/
|
||||
|
||||
#include "xilinx_io.h"
|
||||
#include "sleep.h"
|
||||
#include "time.h"
|
||||
#include "xtime_l.h"
|
||||
#include "math.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
void frqhop_config(int hop_flag){
|
||||
XTime tCur;
|
||||
XTime_GetTime(&tCur);
|
||||
srand(tCur);
|
||||
double hop_freq = (rand()%(800-30))+30+(rand()%(101))/(double)100;//随机产生[30,800)double类型的数
|
||||
// double hop_freq = 400.52;
|
||||
double hop_freq1 = 800.25;
|
||||
static int pll_index=1;
|
||||
static int unlock_pll1_cnt=0,unlock_pll2_cnt=0;
|
||||
if(hop_freq == hop_freq1){
|
||||
if(pll_index == 2){
|
||||
pll_index = 4;
|
||||
}
|
||||
else if(pll_index == 1){
|
||||
pll_index = 3;
|
||||
}
|
||||
}
|
||||
if(hop_flag == 1){
|
||||
if(pll_index == 1 || pll_index == 3){
|
||||
//切换至pll2来源
|
||||
GpioSetPinDir(hop,GPIO_DIR_OUTPUT);
|
||||
GpioWritePin(hop,0x01);
|
||||
trx_ch_pll_config(2);
|
||||
GpioWritePin(hop,0x00);
|
||||
//配置pll1参数
|
||||
unlock_pll1_cnt=PLL_config(1,hop_freq)-1;
|
||||
pll_index = 2;
|
||||
}
|
||||
else if(pll_index == 2 || pll_index == 4){
|
||||
//切换至pll1来源
|
||||
GpioSetPinDir(hop,GPIO_DIR_OUTPUT);
|
||||
GpioWritePin(hop,0x01);
|
||||
trx_ch_pll_config(1);
|
||||
GpioWritePin(hop,0x00);
|
||||
//配置pll2参数
|
||||
unlock_pll2_cnt=PLL_config(2,hop_freq)-1;
|
||||
pll_index = 1;
|
||||
}
|
||||
}
|
||||
hop_freq1 = hop_freq;
|
||||
if(unlock_pll2_cnt!=0 || unlock_pll1_cnt !=0){
|
||||
xil_printf("pll1 unlock num: %d; pll2 unlock num: %d;.\n", unlock_pll1_cnt, unlock_pll2_cnt);
|
||||
}
|
||||
}
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (C) 2016 - 2018 Xilinx, 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:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 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 <stdio.h>
|
||||
|
||||
#include "xparameters.h"
|
||||
#if defined (__arm__) || defined(__aarch64__)
|
||||
#include "xil_printf.h"
|
||||
#endif
|
||||
|
||||
#ifdef XPS_BOARD_ZCU102
|
||||
#ifdef XPAR_XIICPS_0_DEVICE_ID
|
||||
#include "xiicps.h"
|
||||
|
||||
#define BUF_LEN 10U
|
||||
|
||||
#define IOEXPANDER1_ADDR 0x20U
|
||||
|
||||
#define IIC_SCLK_RATE_IOEXP 400000
|
||||
|
||||
#define CMD_CFG_0_REG 0x06U
|
||||
#define CMD_OUTPUT_0_REG 0x02U
|
||||
#define DATA_OUTPUT 0x0U
|
||||
|
||||
#define DATA_COMMON_CFG 0xE0U
|
||||
#define DATA_GT_0000_CFG 0x00U
|
||||
|
||||
XIicPs I2c0InstancePtr;
|
||||
|
||||
int IicPhyReset(void)
|
||||
{
|
||||
|
||||
u8 WriteBuffer[BUF_LEN] = {0};
|
||||
XIicPs_Config *I2c0CfgPtr;
|
||||
int Status = XST_SUCCESS;
|
||||
|
||||
/* Initialize the IIC0 driver so that it is ready to use */
|
||||
I2c0CfgPtr = XIicPs_LookupConfig(XPAR_XIICPS_0_DEVICE_ID);
|
||||
if (I2c0CfgPtr == NULL) {
|
||||
Status = XST_FAILURE;
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = XIicPs_CfgInitialize(&I2c0InstancePtr, I2c0CfgPtr,
|
||||
I2c0CfgPtr->BaseAddress);
|
||||
if (Status != XST_SUCCESS) {
|
||||
Status = XST_FAILURE;
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Set the IIC serial clock rate */
|
||||
XIicPs_SetSClk(&I2c0InstancePtr, IIC_SCLK_RATE_IOEXP);
|
||||
|
||||
/* Configure I/O pins as Output */
|
||||
WriteBuffer[0] = CMD_CFG_0_REG;
|
||||
WriteBuffer[1] = DATA_OUTPUT;
|
||||
Status = XIicPs_MasterSendPolled(&I2c0InstancePtr,
|
||||
WriteBuffer, 2, IOEXPANDER1_ADDR);
|
||||
if (Status != XST_SUCCESS) {
|
||||
Status = XST_FAILURE;
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Wait until bus is idle to start another transfer */
|
||||
while (XIicPs_BusIsBusy(&I2c0InstancePtr));
|
||||
|
||||
/*
|
||||
* Deasserting I2C_MUX_RESETB
|
||||
* And GEM3 Resetb
|
||||
* Selecting lanes based on configuration
|
||||
*/
|
||||
WriteBuffer[0] = CMD_OUTPUT_0_REG;
|
||||
/* gt0000 or no GT configuration */
|
||||
WriteBuffer[1] = DATA_COMMON_CFG | DATA_GT_0000_CFG;
|
||||
|
||||
/* Send the Data */
|
||||
Status = XIicPs_MasterSendPolled(&I2c0InstancePtr,
|
||||
WriteBuffer, 2, IOEXPANDER1_ADDR);
|
||||
if (Status != XST_SUCCESS) {
|
||||
Status = XST_FAILURE;
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Wait until bus is idle */
|
||||
while (XIicPs_BusIsBusy(&I2c0InstancePtr));
|
||||
|
||||
xil_printf("IIC PHY reset on ZCU102 successful \n\r");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,300 @@
|
||||
/*
|
||||
* Copyright (C) 2016 - 2018 Xilinx, 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:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 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 <stdio.h>
|
||||
#include "xparameters.h"
|
||||
#include "netif/xadapter.h"
|
||||
#include "platform_config.h"
|
||||
#include "xil_printf.h"
|
||||
#include "xilinx_io.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "queue.h"
|
||||
#include "semphr.h"
|
||||
#include "math.h"
|
||||
|
||||
#if LWIP_IPV6==1
|
||||
#include "lwip/ip.h"
|
||||
#else
|
||||
#if LWIP_DHCP==1
|
||||
#include "lwip/dhcp.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef XPS_BOARD_ZCU102
|
||||
#ifdef XPAR_XIICPS_0_DEVICE_ID
|
||||
int IicPhyReset(void);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int main_thread();
|
||||
void print_echo_app_header();
|
||||
void echo_application_thread(void *);
|
||||
|
||||
void lwip_init();
|
||||
|
||||
#if LWIP_IPV6==0
|
||||
#if LWIP_DHCP==1
|
||||
extern volatile int dhcp_timoutcntr;
|
||||
err_t dhcp_start(struct netif *netif);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define THREAD_STACKSIZE 1024
|
||||
|
||||
static struct netif server_netif;
|
||||
struct netif *echo_netif;
|
||||
|
||||
#if LWIP_IPV6==1
|
||||
void print_ip6(char *msg, ip_addr_t *ip)
|
||||
{
|
||||
print(msg);
|
||||
xil_printf(" %x:%x:%x:%x:%x:%x:%x:%x\n\r",
|
||||
IP6_ADDR_BLOCK1(&ip->u_addr.ip6),
|
||||
IP6_ADDR_BLOCK2(&ip->u_addr.ip6),
|
||||
IP6_ADDR_BLOCK3(&ip->u_addr.ip6),
|
||||
IP6_ADDR_BLOCK4(&ip->u_addr.ip6),
|
||||
IP6_ADDR_BLOCK5(&ip->u_addr.ip6),
|
||||
IP6_ADDR_BLOCK6(&ip->u_addr.ip6),
|
||||
IP6_ADDR_BLOCK7(&ip->u_addr.ip6),
|
||||
IP6_ADDR_BLOCK8(&ip->u_addr.ip6));
|
||||
}
|
||||
|
||||
#else
|
||||
void
|
||||
print_ip(char *msg, ip_addr_t *ip)
|
||||
{
|
||||
xil_printf(msg);
|
||||
xil_printf("%d.%d.%d.%d\n\r", ip4_addr1(ip), ip4_addr2(ip),
|
||||
ip4_addr3(ip), ip4_addr4(ip));
|
||||
}
|
||||
|
||||
void
|
||||
print_ip_settings(ip_addr_t *ip, ip_addr_t *mask, ip_addr_t *gw)
|
||||
{
|
||||
|
||||
print_ip("Board IP: ", ip);
|
||||
print_ip("Netmask : ", mask);
|
||||
print_ip("Gateway : ", gw);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
xil_printf("start");
|
||||
|
||||
sys_thread_new("main_thrd", (void(*)(void*))main_thread, 0,
|
||||
THREAD_STACKSIZE,
|
||||
DEFAULT_THREAD_PRIO);
|
||||
vTaskStartScheduler();
|
||||
|
||||
while(1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void network_thread(void *p)
|
||||
{
|
||||
struct netif *netif;
|
||||
/* the mac address of the board. this should be unique per board */
|
||||
unsigned char mac_ethernet_address[] = { 0x00, 0x0a, 0x35, 0x00, 0x01, 0x02 };
|
||||
#if LWIP_IPV6==0
|
||||
ip_addr_t ipaddr, netmask, gw;
|
||||
#if LWIP_DHCP==1
|
||||
int mscnt = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
netif = &server_netif;
|
||||
|
||||
xil_printf("\r\n\r\n");
|
||||
xil_printf("-----lwIP Socket Mode CX9261 TEST server Application Version 2022.05.31------\r\n");
|
||||
|
||||
#if LWIP_IPV6==0
|
||||
#if LWIP_DHCP==0
|
||||
/* initliaze IP addresses to be used */
|
||||
IP4_ADDR(&ipaddr, 192, 168, 1, 99);
|
||||
IP4_ADDR(&netmask, 255, 255, 255, 0);
|
||||
IP4_ADDR(&gw, 192, 168, 1, 1);
|
||||
#endif
|
||||
|
||||
/* print out IP settings of the board */
|
||||
|
||||
#if LWIP_DHCP==0
|
||||
print_ip_settings(&ipaddr, &netmask, &gw);
|
||||
/* print all application headers */
|
||||
#endif
|
||||
|
||||
#if LWIP_DHCP==1
|
||||
ipaddr.addr = 0;
|
||||
gw.addr = 0;
|
||||
netmask.addr = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if LWIP_IPV6==0
|
||||
/* Add network interface to the netif_list, and set it as default */
|
||||
if (!xemac_add(netif, &ipaddr, &netmask, &gw, mac_ethernet_address, PLATFORM_EMAC_BASEADDR)) {
|
||||
xil_printf("Error adding N/W interface\r\n");
|
||||
return;
|
||||
}
|
||||
#else
|
||||
/* Add network interface to the netif_list, and set it as default */
|
||||
if (!xemac_add(netif, NULL, NULL, NULL, mac_ethernet_address, PLATFORM_EMAC_BASEADDR)) {
|
||||
xil_printf("Error adding N/W interface\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
netif->ip6_autoconfig_enabled = 1;
|
||||
|
||||
netif_create_ip6_linklocal_address(netif, 1);
|
||||
netif_ip6_addr_set_state(netif, 0, IP6_ADDR_VALID);
|
||||
|
||||
print_ip6("\n\rBoard IPv6 address ", &netif->ip6_addr[0].u_addr.ip6);
|
||||
#endif
|
||||
|
||||
netif_set_default(netif);
|
||||
|
||||
/* specify that the network if is up */
|
||||
netif_set_up(netif);
|
||||
|
||||
/* start packet receive thread - required for lwIP operation */
|
||||
sys_thread_new("xemacif_input_thread", (void(*)(void*))xemacif_input_thread, netif,
|
||||
THREAD_STACKSIZE,
|
||||
DEFAULT_THREAD_PRIO);
|
||||
|
||||
#if LWIP_IPV6==0
|
||||
#if LWIP_DHCP==1
|
||||
dhcp_start(netif);
|
||||
while (1) {
|
||||
vTaskDelay(DHCP_FINE_TIMER_MSECS / portTICK_RATE_MS);
|
||||
dhcp_fine_tmr();
|
||||
mscnt += DHCP_FINE_TIMER_MSECS;
|
||||
if (mscnt >= DHCP_COARSE_TIMER_SECS*1000) {
|
||||
dhcp_coarse_tmr();
|
||||
mscnt = 0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
xil_printf("\r\n");
|
||||
xil_printf("%20s %6s %s\r\n", "Server", "Port", "Connect With..");
|
||||
xil_printf("%20s %6s %s\r\n", "--------------------", "------", "--------------------");
|
||||
|
||||
print_echo_app_header();
|
||||
xil_printf("\r\n");
|
||||
sys_thread_new("echod", echo_application_thread, 0,
|
||||
THREAD_STACKSIZE,
|
||||
DEFAULT_THREAD_PRIO);
|
||||
vTaskDelete(NULL);
|
||||
#endif
|
||||
#else
|
||||
print_echo_app_header();
|
||||
xil_printf("\r\n");
|
||||
sys_thread_new("echod",echo_application_thread, 0,
|
||||
THREAD_STACKSIZE,
|
||||
DEFAULT_THREAD_PRIO);
|
||||
vTaskDelete(NULL);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
int main_thread()
|
||||
{
|
||||
#if LWIP_DHCP==1
|
||||
int mscnt = 0;
|
||||
#endif
|
||||
|
||||
#ifdef XPS_BOARD_ZCU102
|
||||
IicPhyReset();
|
||||
#endif
|
||||
|
||||
/* initialize lwIP before calling sys_thread_new */
|
||||
lwip_init();
|
||||
SpiPsInit(SPI_DEVICE_ID);
|
||||
GpioInit(GPIO_DEVICE_ID);
|
||||
AXIGpioInit();
|
||||
XScuGicInit();
|
||||
ConfigAXIGPIOIntr();
|
||||
ExceptionInit();
|
||||
|
||||
XAxiDma_Init(xAxiDma0Get(),AXI_DMA_DEVCIE_ID0);
|
||||
XAxiDma_Init(xAxiDma1Get(),AXI_DMA_DEVCIE_ID1);
|
||||
XAxiDma_Init(xAxiDma2Get(),AXI_DMA_DEVCIE_ID2);
|
||||
PackerRst();
|
||||
|
||||
/* cx9261a configuration */
|
||||
peripheral_test();
|
||||
cx3e04_config();
|
||||
// cx9261a_710_config();
|
||||
// frqhop_config(1);
|
||||
int temp = cx3e04_read(0x03A);
|
||||
/* any thread using lwIP should be created using sys_thread_new */
|
||||
sys_thread_new("NW_THRD", network_thread, NULL,
|
||||
THREAD_STACKSIZE,
|
||||
DEFAULT_THREAD_PRIO);
|
||||
|
||||
#if LWIP_IPV6==0
|
||||
#if LWIP_DHCP==1
|
||||
while (1) {
|
||||
vTaskDelay(DHCP_FINE_TIMER_MSECS / portTICK_RATE_MS);
|
||||
if (server_netif.ip_addr.addr) {
|
||||
xil_printf("DHCP request success\r\n");
|
||||
print_ip_settings(&(server_netif.ip_addr), &(server_netif.netmask), &(server_netif.gw));
|
||||
print_echo_app_header();
|
||||
xil_printf("\r\n");
|
||||
sys_thread_new("echod", echo_application_thread, 0,
|
||||
THREAD_STACKSIZE,
|
||||
DEFAULT_THREAD_PRIO);
|
||||
break;
|
||||
}
|
||||
mscnt += DHCP_FINE_TIMER_MSECS;
|
||||
if (mscnt >= 10000) {
|
||||
xil_printf("ERROR: DHCP request timed out\r\n");
|
||||
xil_printf("Configuring default IP of 192.168.1.100\r\n");
|
||||
IP4_ADDR(&(server_netif.ip_addr), 192, 168, 1, 100);
|
||||
IP4_ADDR(&(server_netif.netmask), 255, 255, 255, 0);
|
||||
IP4_ADDR(&(server_netif.gw), 192, 168, 1, 1);
|
||||
print_ip_settings(&(server_netif.ip_addr), &(server_netif.netmask), &(server_netif.gw));
|
||||
/* print all application headers */
|
||||
xil_printf("\r\n");
|
||||
xil_printf("%20s %6s %s\r\n", "Server", "Port", "Connect With..");
|
||||
xil_printf("%20s %6s %s\r\n", "--------------------", "------", "--------------------");
|
||||
|
||||
print_echo_app_header();
|
||||
xil_printf("\r\n");
|
||||
sys_thread_new("echod", echo_application_thread, 0,
|
||||
THREAD_STACKSIZE,
|
||||
DEFAULT_THREAD_PRIO);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
vTaskDelete(NULL);
|
||||
return 0;
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
#ifndef __PLATFORM_CONFIG_H_
|
||||
#define __PLATFORM_CONFIG_H_
|
||||
|
||||
|
||||
#define PLATFORM_EMAC_BASEADDR XPAR_XEMACPS_0_BASEADDR
|
||||
|
||||
#define PLATFORM_ZYNQ
|
||||
|
||||
|
||||
#endif
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* wideband_qec.c
|
||||
*
|
||||
* Created on: 2023Äê11ÔÂ30ÈÕ
|
||||
* Author: cxlab
|
||||
*/
|
||||
|
||||
#include "xilinx_io.h"
|
||||
#include "sleep.h"
|
||||
#include "math.h"
|
||||
void rxFFTCalib(int lo, int fs,int ref, int firLength, int chan) {
|
||||
u8 rx_data;
|
||||
SpiPs_write_read1(0x000, chan == 1 ? 0x12 : 0x22,&rx_data);
|
||||
SpiPs_write_read1(0x128, 0x00,&rx_data);
|
||||
SpiPs_write_read1(0x11B, 0x01,&rx_data);
|
||||
SpiPs_write_read1(0x11E, 0x01,&rx_data);
|
||||
configTxNcoFreq(0, fs);
|
||||
SpiPs_write_read1(0x161, 0x00,&rx_data);
|
||||
SpiPs_write_read1(0x162, 0x00,&rx_data);
|
||||
SpiPs_write_read1(0x162, 0x01,&rx_data);
|
||||
SpiPs_write_read1(0x161, 0x01,&rx_data);
|
||||
SpiPs_write_read1(0x000, chan == 1 ? 0x12 : chan == 2 ? 0x22 : 0x32,&rx_data);
|
||||
SpiPs_write_read1(0x102, 0x03,&rx_data);
|
||||
SpiPs_write_read1(0x102, 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x15C, 0x00,&rx_data);
|
||||
SpiPs_write_read1(0x160, 0x01,&rx_data);
|
||||
SpiPs_write_read1(0x77E, chan == 1 ? 0x50 : chan == 2 ? 0x0A : 0x03,&rx_data);
|
||||
SpiPs_write_read1(0x09B, 0x01,&rx_data); // TXPLL4
|
||||
SpiPs_write_read1(0x09D, firLength,&rx_data);
|
||||
SpiPs_write_read1(0x096, ((u32)round(lo) >> 8) & 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x097, (u32)round(lo) & 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x098, ((u32)round(ref * 10) >> 8) & 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x099, (u32)round(ref * 10) & 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x09E, ((u32)round(fs * 100) >> 8) & 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x09F, (u32)round(fs * 100) & 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x09C, chan,&rx_data);
|
||||
while (1) {
|
||||
if (SpiPs_write_read2(0x0B3,0x00,&rx_data) == 5)
|
||||
break;
|
||||
usleep(10000);
|
||||
}
|
||||
SpiPs_write_read1(0x09C, 0x00,&rx_data);
|
||||
SpiPs_write_read1(0x15C, 0x01,&rx_data);
|
||||
SpiPs_write_read1(0x77E, 0x00,&rx_data);
|
||||
|
||||
//ͨµÀʱÖÓÀ´Ô´
|
||||
u8 r77D=0xC0;
|
||||
u8 r775=0x24;
|
||||
u8 r6C3=0x00;
|
||||
SpiPs_write_read1(0x77D, r77D,&rx_data);
|
||||
SpiPs_write_read1(0x775, r775,&rx_data);
|
||||
SpiPs_write_read1(0x6C3, r6C3,&rx_data);
|
||||
}
|
||||
|
||||
|
||||
void configDcCalib(int dcCalibEnable,int dcCalibLength) {
|
||||
u8 rx_data;
|
||||
SpiPs_write_read1(0x109, dcCalibEnable ? 0x11 : 0x00,&rx_data);
|
||||
SpiPs_write_read1(0x10A, (dcCalibLength) << 4,&rx_data);
|
||||
SpiPs_write_read1(0x11F, dcCalibEnable ? 0x33 : 0x73,&rx_data);
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
#include "sd.h"
|
||||
/************************** Variable Definitions *****************************/
|
||||
static FIL fil; /* File object */
|
||||
static FATFS fatfs;
|
||||
/*
|
||||
* To test logical drive 0, FileName should be "0:/<File name>" or
|
||||
* "<file_name>". For logical drive 1, FileName should be "1:/<file_name>"
|
||||
*/
|
||||
static char FileName[32] = "BOOT.bin";
|
||||
static char *SD_File;
|
||||
|
||||
|
||||
//#define BUFF_SIZE sizeof(image_data)
|
||||
#define BUFF_SIZE 0x2000000
|
||||
#ifdef __ICCARM__
|
||||
#pragma data_alignment = 32
|
||||
u8 DestinationAddress[10*1024];
|
||||
#pragma data_alignment = 32
|
||||
u8 SourceAddress[10*1024];
|
||||
#else
|
||||
//u8 DestinationAddress[10*1024] __attribute__ ((aligned(32)));
|
||||
//u8 SourceAddress[10*1024] __attribute__ ((aligned(32)));
|
||||
|
||||
u8 DestinationAddress[BUFF_SIZE] __attribute__ ((aligned(32)));
|
||||
u8 SourceAddress[BUFF_SIZE] __attribute__ ((aligned(32)));
|
||||
#endif
|
||||
|
||||
#define TEST 7
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* File system example using SD driver to write to and read from an SD card
|
||||
* in polled mode. This example creates a new file on an
|
||||
* SD card (which is previously formatted with FATFS), write data to the file
|
||||
* and reads the same data back to verify.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
|
||||
*
|
||||
* @note None
|
||||
*
|
||||
******************************************************************************/
|
||||
int FfsSdWrite(u8*image_data, u32 FileSize)
|
||||
{
|
||||
int error_flag = 0;
|
||||
FRESULT Res;
|
||||
UINT NumBytesRead;
|
||||
UINT NumBytesWritten;
|
||||
u32 BuffCnt;
|
||||
BYTE work[FF_MAX_SS];
|
||||
// u32 FileSize = (8*1024);
|
||||
// u32 FileSize = sizeof(image_data);
|
||||
/*
|
||||
* To test logical drive 0, Path should be "0:/"
|
||||
* For logical drive 1, Path should be "1:/"
|
||||
*/
|
||||
TCHAR *Path = "0:/";
|
||||
u8 checksum = 0;
|
||||
|
||||
for(BuffCnt = 0; BuffCnt < FileSize; BuffCnt++){
|
||||
// SourceAddress[BuffCnt] = TEST + BuffCnt;
|
||||
SourceAddress[BuffCnt] = image_data[BuffCnt];
|
||||
checksum = checksum + image_data[BuffCnt];
|
||||
}
|
||||
xil_printf("checksum is 0x%x.",checksum);
|
||||
|
||||
|
||||
/*
|
||||
* Register volume work area, initialize device
|
||||
*/
|
||||
Res = f_mount(&fatfs, Path, 0);
|
||||
|
||||
if (Res != FR_OK) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Path - Path to logical driver, 0 - FDISK format.
|
||||
* 0 - Cluster size is automatically determined based on Vol size.
|
||||
*/
|
||||
Res = f_mkfs(Path, FM_FAT32, 0, work, sizeof work);
|
||||
if (Res != FR_OK) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Open file with required permissions.
|
||||
* Here - Creating new file with read/write permissions. .
|
||||
* To open file with write permissions, file system should not
|
||||
* be in Read Only mode.
|
||||
*/
|
||||
SD_File = (char *)FileName;
|
||||
|
||||
Res = f_open(&fil, SD_File, FA_CREATE_ALWAYS | FA_WRITE | FA_READ);
|
||||
if (Res) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Pointer to beginning of file .
|
||||
*/
|
||||
Res = f_lseek(&fil, 0);
|
||||
if (Res) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write data to file.
|
||||
*/
|
||||
Res = f_write(&fil, (const void*)SourceAddress, FileSize,
|
||||
&NumBytesWritten);
|
||||
if (Res) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
/*
|
||||
* Close file.
|
||||
*/
|
||||
Res = f_close(&fil);
|
||||
if (Res) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
Res = f_open(&fil, SD_File, FA_READ);
|
||||
if (Res) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
/*
|
||||
* Pointer to beginning of file .
|
||||
*/
|
||||
Res = f_lseek(&fil, 0);
|
||||
if (Res) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read data from file.
|
||||
*/
|
||||
Res = f_read(&fil, (void*)DestinationAddress, FileSize,
|
||||
&NumBytesRead);
|
||||
if (Res) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Data verification
|
||||
*/
|
||||
for(BuffCnt = 0; BuffCnt < FileSize; BuffCnt++){
|
||||
if(SourceAddress[BuffCnt] != DestinationAddress[BuffCnt]){
|
||||
// return XST_FAILURE;
|
||||
error_flag = 1;
|
||||
xil_printf('Data check error.');
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Close file.
|
||||
*/
|
||||
Res = f_close(&fil);
|
||||
if (Res) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
if(error_flag){
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
// Res = f_unmount(Path);
|
||||
// if (Res) {
|
||||
// return XST_FAILURE;
|
||||
// }
|
||||
//
|
||||
// sleep(5);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
/***************************** Include Files *********************************/
|
||||
#include "xparameters.h" /* SDK generated parameters */
|
||||
#include "xsdps.h" /* SD device driver */
|
||||
#include "xil_printf.h"
|
||||
#include "ff.h"
|
||||
#include "xil_cache.h"
|
||||
#include "xplatform_info.h"
|
||||
/************************** Function Prototypes ******************************/
|
||||
int FfsSdWrite(u8*image_data, u32 FileSize);
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* tx_bisection.c
|
||||
*
|
||||
* Created on: 2023Äê12ÔÂ1ÈÕ
|
||||
* Author: cxlab
|
||||
*/
|
||||
|
||||
|
||||
#include "xilinx_io.h"
|
||||
#include "sleep.h"
|
||||
#include "math.h"
|
||||
|
||||
void txBisectionQecCalib(int f0, int fs) {
|
||||
u8 rx_data;
|
||||
SpiPs_write_read1(0x02E, 0x03,&rx_data);
|
||||
SpiPs_write_read1(0x128, 0x11,&rx_data);
|
||||
SpiPs_write_read1(0x11E, 0x01,&rx_data);
|
||||
SpiPs_write_read1(0x77E, 0x24,&rx_data);
|
||||
SpiPs_write_read1(0x11F, 0x01,&rx_data);
|
||||
SpiPs_write_read1(0x121, 0x02,&rx_data);
|
||||
SpiPs_write_read1(0x11B, 0x01,&rx_data);
|
||||
SpiPs_write_read1(0x161, 0x01,&rx_data);
|
||||
SpiPs_write_read1(0x162, 0x01,&rx_data);
|
||||
SpiPs_write_read1(0x163, 0x00,&rx_data);
|
||||
configTxNcoFreq(f0, fs * 4);
|
||||
SpiPs_write_read1(0xA2D, 0x02,&rx_data);
|
||||
SpiPs_write_read1(0xA07, 0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA08, 0x0F,&rx_data);
|
||||
SpiPs_write_read1(0xA1C, 0x01,&rx_data);
|
||||
configRxNcoFreq(f0 * 2, fs);
|
||||
SpiPs_write_read1(0x186, 0x01,&rx_data);
|
||||
SpiPs_write_read1(0x763, 0x34,&rx_data);
|
||||
SpiPs_write_read1(0x76D, 0x34,&rx_data);
|
||||
SpiPs_write_read1(0x101, 0xEF,&rx_data);
|
||||
SpiPs_write_read1(0x101, 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x800, 0x00,&rx_data);
|
||||
SpiPs_write_read1(0x81A, 0xF7,&rx_data);
|
||||
SpiPs_write_read1(0x81B, 0x34,&rx_data);
|
||||
SpiPs_write_read1(0x81C, 0x33,&rx_data);
|
||||
SpiPs_write_read1(0x81D, 0x12,&rx_data);
|
||||
SpiPs_write_read1(0x81E, 0x00,&rx_data);
|
||||
SpiPs_write_read1(0x81F, 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x820, 0x00,&rx_data);
|
||||
SpiPs_write_read1(0x821, 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x800, 0x80,&rx_data);
|
||||
SpiPs_write_read1(0x800, 0x81,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x77E, 0x00,&rx_data);
|
||||
}
|
||||
|
||||
void txBisectionDcCalib(int f0, int fs) {
|
||||
u8 rx_data;
|
||||
SpiPs_write_read1(0x77E, 0x24,&rx_data);
|
||||
SpiPs_write_read1(0x11F, 0x03,&rx_data);
|
||||
SpiPs_write_read1(0x121, 0x02,&rx_data);
|
||||
SpiPs_write_read1(0x11B, 0x01,&rx_data);
|
||||
SpiPs_write_read1(0x11E, 0x01,&rx_data);
|
||||
SpiPs_write_read1(0x161, 0x01,&rx_data);
|
||||
SpiPs_write_read1(0x162, 0x01,&rx_data);
|
||||
configTxNcoFreq(f0, fs * 4);
|
||||
SpiPs_write_read1(0xA2D, 0x02,&rx_data);
|
||||
SpiPs_write_read1(0xA07, 0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA08, 0x0F,&rx_data);
|
||||
SpiPs_write_read1(0xA1C, 0x01,&rx_data);
|
||||
configRxNcoFreq(f0, fs);
|
||||
SpiPs_write_read1(0x81A, 0xF7,&rx_data);
|
||||
SpiPs_write_read1(0x81B, 0x44,&rx_data);
|
||||
SpiPs_write_read1(0x81C, 0x33,&rx_data);
|
||||
SpiPs_write_read1(0x81D, 0x14,&rx_data);
|
||||
SpiPs_write_read1(0x800, 0x80,&rx_data);
|
||||
SpiPs_write_read1(0x800, 0x82,&rx_data);
|
||||
usleep(500000);
|
||||
SpiPs_write_read1(0x77E, 0x00,&rx_data);
|
||||
}
|
||||
@@ -0,0 +1,861 @@
|
||||
/*
|
||||
* xilinx_io.c
|
||||
*
|
||||
* Created on: 2021年9月6日
|
||||
* Author: cxlab
|
||||
*/
|
||||
|
||||
|
||||
#include "sleep.h"
|
||||
#include "math.h"
|
||||
#include "xilinx_io.h" /* SPI device driver */
|
||||
|
||||
static XSpiPs SpiInstance;
|
||||
XGpioPs Gpio; /* The driver instance for GPIO Device. */
|
||||
XGpio axi_gpio_inst; //PL 端 AXI GPIO 驱动实例
|
||||
XScuGic scugic_inst; //中断控制器 驱动实例
|
||||
XScuGic_Config * scugic_cfg_ptr; //中断控制器 配置信息
|
||||
int hop_flag,hop_intr_flag;
|
||||
|
||||
XAxiDma AxiDma0,AxiDma1,AxiDma2;
|
||||
|
||||
XAxiDma* xAxiDma0Get(void){
|
||||
return &AxiDma0;
|
||||
}
|
||||
|
||||
XAxiDma* xAxiDma1Get(void){
|
||||
return &AxiDma1;
|
||||
}
|
||||
|
||||
XAxiDma* xAxiDma2Get(void){
|
||||
return &AxiDma2;
|
||||
}
|
||||
void AXIGpioInit(void){
|
||||
XGpio_Initialize(&axi_gpio_inst, AXI_GPIO_ID);
|
||||
//配置 PL AXI GPIO
|
||||
XGpio_SetDataDirection(&axi_gpio_inst, 1, 1); //设置 AXI GPIO 通道 1 为输入
|
||||
XGpio_InterruptEnable(&axi_gpio_inst, KEY_MASK); //使能通道 1 中断
|
||||
XGpio_InterruptGlobalEnable(&axi_gpio_inst); //使能 AXI GPIO 全局中断
|
||||
}
|
||||
|
||||
void ConfigAXIGPIOIntr(void){
|
||||
//设置中断优先级和触发类型(高电平触发)
|
||||
XScuGic_SetPriorityTriggerType(&scugic_inst, GPIO_INT_ID, 0xA0, 0x1);
|
||||
//关联中断 ID 和中断处理函数
|
||||
XScuGic_Connect(&scugic_inst, GPIO_INT_ID, axi_gpio_handler, &axi_gpio_inst);
|
||||
//使能 AXI GPIO 中断
|
||||
XScuGic_Enable(&scugic_inst, GPIO_INT_ID);
|
||||
}
|
||||
void axi_gpio_handler(void *CallbackRef){
|
||||
XGpio *GpioPtr = (XGpio *)CallbackRef;
|
||||
print("Interrupt Detected!\n");
|
||||
XGpio_InterruptDisable(GpioPtr, KEY_MASK); //关闭 AXI GPIO 中断使能
|
||||
frqhop_config(hop_flag);
|
||||
XGpio_InterruptClear(GpioPtr, KEY_MASK); //清除中断
|
||||
XGpio_InterruptEnable(GpioPtr, KEY_MASK); //使能 AXI GPIO 中断
|
||||
}
|
||||
void frqhop_flag(int frqhop_flag){
|
||||
u8 rx_data;
|
||||
hop_flag = frqhop_flag;
|
||||
GpioSetPinDir(hop,GPIO_DIR_OUTPUT);
|
||||
GpioWritePin(hop,0x01);
|
||||
SpiPs_write_read2(0x615,0x00,&rx_data);
|
||||
}
|
||||
|
||||
void ExceptionInit(void){
|
||||
//设置并打开中断异常处理功能
|
||||
Xil_ExceptionInit();
|
||||
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler)XScuGic_InterruptHandler, &scugic_inst);
|
||||
Xil_ExceptionEnable();
|
||||
}
|
||||
void XScuGicInit(void){
|
||||
scugic_cfg_ptr = XScuGic_LookupConfig(SCUGIC_ID);
|
||||
XScuGic_CfgInitialize(&scugic_inst, scugic_cfg_ptr, scugic_cfg_ptr->CpuBaseAddress);
|
||||
}
|
||||
|
||||
int SpiPsInit(u16 SpiDeviceId){
|
||||
int Status;
|
||||
XSpiPs_Config *SpiConfig;
|
||||
/*
|
||||
* Initialize the SPI driver so that it's ready to use
|
||||
*/
|
||||
SpiConfig = XSpiPs_LookupConfig(SpiDeviceId);
|
||||
if (NULL == SpiConfig) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
Status = XSpiPs_CfgInitialize((&SpiInstance), SpiConfig,
|
||||
SpiConfig->BaseAddress);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform a self-test to check hardware build
|
||||
*/
|
||||
Status = XSpiPs_SelfTest((&SpiInstance));
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
/*
|
||||
* The SPI device is a slave by default and the clock phase
|
||||
* have to be set according to its master. In this example, CPOL is set
|
||||
* to quiescent high and CPHA is set to 1.
|
||||
*/
|
||||
|
||||
XSpiPs_SetOptions((&SpiInstance), (XSPIPS_CR_CPHA_MASK) |
|
||||
XSPIPS_MASTER_OPTION |
|
||||
XSPIPS_FORCE_SSELECT_OPTION);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
XSpiPs_SetClkPrescaler((&SpiInstance), XSPIPS_CLK_PRESCALE_8);
|
||||
/*
|
||||
* Set the Rx FIFO Threshold to the Max Data
|
||||
*/
|
||||
// XSpiPs_SetRXWatermark((&SpiInstance),MAX_DATA);
|
||||
/*
|
||||
* Enable the device.
|
||||
*/
|
||||
XSpiPs_Enable((&SpiInstance));
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
int cx3e04_write(int addr , int value)
|
||||
{
|
||||
Xil_Out32(AXI4_LITE_SPI_BASEADDR+addr*4,value);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cx3e04_read(int addr)
|
||||
{
|
||||
return Xil_In32(AXI4_LITE_SPI_BASEADDR+addr*4);
|
||||
}
|
||||
|
||||
void cx3e04_config(void)
|
||||
{
|
||||
//城芯科技CX3E04
|
||||
//Common
|
||||
cx3e04_write(0x000,0x12);
|
||||
cx3e04_write(0x002,0x38);
|
||||
cx3e04_write(0x038,0x01);
|
||||
cx3e04_write(0x003,0x30);
|
||||
cx3e04_write(0x039,0x00);
|
||||
//CLK
|
||||
//clk lvds en
|
||||
cx3e04_write(0x011,0x7F);
|
||||
cx3e04_write(0x012,0x34);
|
||||
cx3e04_write(0x036,0x7F);
|
||||
cx3e04_write(0x01A,0x4B);
|
||||
cx3e04_write(0x013,0x04);
|
||||
cx3e04_write(0x014,0x04);
|
||||
cx3e04_write(0x004,0x00);
|
||||
cx3e04_write(0x008,0x00);
|
||||
cx3e04_write(0x009,0x00);
|
||||
cx3e04_write(0x015,0x04);
|
||||
cx3e04_write(0x016,0x04);
|
||||
cx3e04_write(0x005,0x00);
|
||||
cx3e04_write(0x00A,0x00);
|
||||
cx3e04_write(0x00B,0x00);
|
||||
cx3e04_write(0x017,0x04);
|
||||
cx3e04_write(0x018,0x04);
|
||||
cx3e04_write(0x006,0x00);
|
||||
cx3e04_write(0x00C,0x00);
|
||||
cx3e04_write(0x00D,0x00);
|
||||
cx3e04_write(0x019,0x04);
|
||||
cx3e04_write(0x007,0x00);
|
||||
cx3e04_write(0x00E,0x00);
|
||||
cx3e04_write(0x00F,0x00);
|
||||
cx3e04_write(0x010,0x00);
|
||||
cx3e04_write(0x029,0x00);
|
||||
cx3e04_write(0x02A,0x00);
|
||||
//SYNC
|
||||
//sync lvds en
|
||||
cx3e04_write(0x033,0x7F);
|
||||
cx3e04_write(0x034,0x34);
|
||||
cx3e04_write(0x035,0x7F);
|
||||
cx3e04_write(0x032,0x03);
|
||||
//sync inner div
|
||||
cx3e04_write(0x03A,0x00);
|
||||
cx3e04_write(0x03B,0x00);
|
||||
cx3e04_write(0x03A,0x01);
|
||||
cx3e04_write(0x03B,0xFF);//512分频
|
||||
cx3e04_write(0x03C,0x21);
|
||||
cx3e04_write(0x03D,0x80);
|
||||
cx3e04_write(0x02B,0x04);
|
||||
cx3e04_write(0x02C,0x04);
|
||||
cx3e04_write(0x01B,0x00);
|
||||
cx3e04_write(0x01C,0x00);
|
||||
cx3e04_write(0x022,0x00);
|
||||
cx3e04_write(0x023,0x00);
|
||||
cx3e04_write(0x02D,0x04);
|
||||
cx3e04_write(0x02E,0x04);
|
||||
cx3e04_write(0x01D,0x00);
|
||||
cx3e04_write(0x01E,0x00);
|
||||
cx3e04_write(0x024,0x00);
|
||||
cx3e04_write(0x025,0x00);
|
||||
cx3e04_write(0x02F,0x04);
|
||||
cx3e04_write(0x030,0x04);
|
||||
cx3e04_write(0x01F,0x00);
|
||||
cx3e04_write(0x020,0x00);
|
||||
cx3e04_write(0x026,0x00);
|
||||
cx3e04_write(0x027,0x00);
|
||||
cx3e04_write(0x031,0x04);
|
||||
cx3e04_write(0x021,0x00);
|
||||
cx3e04_write(0x028,0x00);
|
||||
//偏置电流
|
||||
cx3e04_write(0x040,0xFF);
|
||||
cx3e04_write(0x041,0xFF);
|
||||
cx3e04_write(0x042,0xFF);
|
||||
cx3e04_write(0x043,0xF0);
|
||||
cx3e04_write(0x044,0xFF);
|
||||
cx3e04_write(0x045,0xFF);
|
||||
cx3e04_write(0x046,0xFF);
|
||||
cx3e04_write(0x047,0xF0);
|
||||
//Others
|
||||
cx3e04_write(0x037,0x07);
|
||||
}
|
||||
|
||||
//int SpiPs_write_read(u8 cmd, u16 addr,u8 data,u8 * rx_data){
|
||||
int SpiPs_write_read(u8 * data,u8 * rx_data){
|
||||
int Status;
|
||||
|
||||
u8 rx_buffer[3];
|
||||
|
||||
XSpiPs_SetSlaveSelect((&SpiInstance),0x00);
|
||||
|
||||
|
||||
Status = XSpiPs_PolledTransfer((&SpiInstance),data,rx_buffer,3);
|
||||
|
||||
*rx_data = rx_buffer[2];
|
||||
return 0;
|
||||
}
|
||||
int SpiPs_write_read1(u16 addr,u8 data,u8 * rx_data){
|
||||
u8 rx_data1;
|
||||
u16 temp;
|
||||
u8 rx_buffer[3];
|
||||
|
||||
temp= addr&0xff00;
|
||||
rx_buffer[0]= temp/256+128;
|
||||
rx_buffer[1]= addr&0x00ff;
|
||||
rx_buffer[2]= data;
|
||||
|
||||
SpiPs_write_read((u8 *)&rx_buffer,&rx_data1);
|
||||
|
||||
*rx_data = rx_data1;
|
||||
return 0;
|
||||
}
|
||||
int SpiPs_write_read2(u16 addr,u8 data,u8 * rx_data){
|
||||
u8 rx_data1;
|
||||
u16 temp;
|
||||
u8 rx_buffer[3];
|
||||
|
||||
temp= addr&0xff00;
|
||||
rx_buffer[0]= temp/256;
|
||||
rx_buffer[1]= addr&0x00ff;
|
||||
rx_buffer[2]= data;
|
||||
|
||||
SpiPs_write_read((u8 *)&rx_buffer,&rx_data1);
|
||||
|
||||
*rx_data = rx_data1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GpioInit(u16 DeviceId)
|
||||
{
|
||||
int Status;
|
||||
XGpioPs_Config *ConfigPtr;
|
||||
/* Initialize the GPIO driver. */
|
||||
ConfigPtr = XGpioPs_LookupConfig(DeviceId);
|
||||
Status = XGpioPs_CfgInitialize(&Gpio, ConfigPtr,
|
||||
ConfigPtr->BaseAddr);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
int GpioSetPinDir(u32 Pin,u32 Direction){
|
||||
XGpioPs_SetDirectionPin((&Gpio),GPIO_EMIO_OFFSET + Pin,Direction);
|
||||
return 0;
|
||||
}
|
||||
int GpioWritePin(u32 Pin,u32 data){
|
||||
XGpioPs_SetOutputEnablePin(&Gpio, GPIO_EMIO_OFFSET + Pin, 1);
|
||||
XGpioPs_WritePin((&Gpio),GPIO_EMIO_OFFSET + Pin,data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GpioReadPin(u32 Pin){
|
||||
return XGpioPs_ReadPin((&Gpio),GPIO_EMIO_OFFSET + Pin);
|
||||
}
|
||||
|
||||
void DeviceRst(void){
|
||||
GpioWritePin(NRST,0);
|
||||
GpioWritePin(NRST,1);
|
||||
}
|
||||
|
||||
int XAxiDma_Init(XAxiDma* AxiDma,u16 DeviceId){
|
||||
|
||||
XAxiDma_Config *CfgPtr;
|
||||
int Status;
|
||||
/* Initialize the XAxiDma device.
|
||||
*/
|
||||
CfgPtr = XAxiDma_LookupConfig(DeviceId);
|
||||
if (!CfgPtr) {
|
||||
xil_printf("No config found for %d\r\n", DeviceId);
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
Status = XAxiDma_CfgInitialize(AxiDma, CfgPtr);
|
||||
if (Status != XST_SUCCESS) {
|
||||
xil_printf("Initialization failed %d\r\n", Status);
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
if(XAxiDma_HasSg(AxiDma)){
|
||||
xil_printf("Device configured as SG mode \r\n");
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/* Disable interrupts, we use polling mode
|
||||
*/
|
||||
XAxiDma_IntrDisable(AxiDma, XAXIDMA_IRQ_ALL_MASK,
|
||||
XAXIDMA_DEVICE_TO_DMA);
|
||||
XAxiDma_IntrDisable(AxiDma, XAXIDMA_IRQ_ALL_MASK,
|
||||
XAXIDMA_DMA_TO_DEVICE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int XAxiDmaCapture(XAxiDma* AxiDma,u32 data_length){
|
||||
int Status;
|
||||
u8 *TxBufferPtr;
|
||||
u32 MAX_PKT_LEN;
|
||||
MAX_PKT_LEN = data_length;
|
||||
TxBufferPtr = (u8 *)TX_BUFFER_BASE;
|
||||
Xil_DCacheFlushRange((UINTPTR)TxBufferPtr, MAX_PKT_LEN);
|
||||
Status = XAxiDma_Busy(AxiDma,XAXIDMA_DEVICE_TO_DMA);
|
||||
Status = XAxiDma_Busy(AxiDma,XAXIDMA_DMA_TO_DEVICE);
|
||||
XAxiDma_Reset(AxiDma);
|
||||
Status = XAxiDma_ResetIsDone(AxiDma);
|
||||
Status = XAxiDma_Busy(AxiDma,XAXIDMA_DEVICE_TO_DMA);
|
||||
Status = XAxiDma_Busy(AxiDma,XAXIDMA_DMA_TO_DEVICE);
|
||||
|
||||
Status = XAxiDma_SimpleTransfer(AxiDma,(UINTPTR) TxBufferPtr,MAX_PKT_LEN*8, XAXIDMA_DEVICE_TO_DMA);
|
||||
SetPacketSize(AxiDma,MAX_PKT_LEN);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
u32 start_TickCount,current_TickCount=0;
|
||||
start_TickCount = sys_now();
|
||||
u32 offset= 0;
|
||||
//never come out ,reason is stream does't have tlast.Need a module to pack excatly the same length defined in para.
|
||||
while ((offset< 500)&&(XAxiDma_Busy(AxiDma,XAXIDMA_DEVICE_TO_DMA))) {
|
||||
Status = XAxiDma_Busy(AxiDma,XAXIDMA_DEVICE_TO_DMA);
|
||||
|
||||
current_TickCount =sys_now();
|
||||
offset = current_TickCount-start_TickCount;
|
||||
// xil_printf("offset: %d\r\n", offset);
|
||||
}
|
||||
/*
|
||||
u64 offset= 0;
|
||||
//never come out ,reason is stream does't have tlast.Need a module to pack excatly the same length defined in para.
|
||||
while ((offset> 100000)||(XAxiDma_Busy(AxiDma,XAXIDMA_DEVICE_TO_DMA))) {
|
||||
Status = XAxiDma_Busy(AxiDma,XAXIDMA_DEVICE_TO_DMA);
|
||||
}*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int SetPacketSize(XAxiDma* AxiDma,u32 length){
|
||||
|
||||
UINTPTR Addr;
|
||||
if(AxiDma == xAxiDma0Get())
|
||||
Addr = PACKER_BASEADDR0;
|
||||
else if(AxiDma == xAxiDma1Get())
|
||||
Addr = PACKER_BASEADDR1;
|
||||
else
|
||||
Addr = PACKER_BASEADDR2;
|
||||
xil_printf("addr %x .\n",Addr);
|
||||
Xil_Out32(Addr,0);
|
||||
xil_printf("PACKER_BASEADDR DATA %d .\n",Xil_In32(Addr));
|
||||
Xil_Out32(Addr+4,length);
|
||||
xil_printf("PACKER_BASEADDR +4 DATA %d .\n",Xil_In32(Addr + 4));
|
||||
Xil_Out32(Addr,1);
|
||||
xil_printf("PACKER_BASEADDR DATA %d .\n",Xil_In32(Addr));
|
||||
return 0;
|
||||
}
|
||||
int DownloadWave(u8 * data){
|
||||
u32 * buffer;
|
||||
u64 addr;
|
||||
int i;
|
||||
buffer = (u32 *) data;
|
||||
addr = BRAM_BASEADDR;
|
||||
for(i=0;i<WAVELENGTH;i++){
|
||||
Xil_Out32(addr+i*4,* (buffer +i));
|
||||
// Xil_Out32(addr+i*4,0x11223344);
|
||||
// xil_printf("ADDR 0x%x DATA 0x%x.\r\n",(buffer +i), * (buffer +i));
|
||||
}
|
||||
addr = BRAM_BASEADDR_1;
|
||||
for(i=0;i<WAVELENGTH;i++){
|
||||
Xil_Out32(addr+i*4,* (buffer +i));
|
||||
// Xil_Out32(addr+i*4,0x11223344);
|
||||
// xil_printf("ADDR 0x%x DATA 0x%x.\r\n",(buffer +i), * (buffer +i));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
void dbg_printf( const char8 *ctrl1, ...){
|
||||
#ifdef DBGLOG
|
||||
xil_printf( ctrl1 );
|
||||
#endif
|
||||
}
|
||||
void PackerRst(void){
|
||||
GpioSetPinDir(0x03,GPIO_DIR_OUTPUT);
|
||||
GpioWritePin(3,0x0);//dma_axis_rx_rstn
|
||||
GpioWritePin(3,0x01);//dma_axis_rx_rstn
|
||||
GpioSetPinDir(0x09,GPIO_DIR_OUTPUT);
|
||||
GpioWritePin(9,0x01);//data_valid
|
||||
}
|
||||
int peripheral_test(void){
|
||||
u8 spi_test;
|
||||
u8 Gpio_test;
|
||||
u8 BRAM_test;
|
||||
u8 DDR_test;
|
||||
// SPI TEST
|
||||
u8 rx_data;
|
||||
xil_printf("start spi test.\r\n");
|
||||
u8 spi_wr_buff[3]={0x87,0x82,0x5A};
|
||||
u8 spi_rd_buff[3]={0x07,0x82,0x00};
|
||||
SpiPs_write_read(spi_wr_buff,&rx_data);
|
||||
SpiPs_write_read(spi_rd_buff,&rx_data);
|
||||
if(rx_data==spi_wr_buff[2])
|
||||
{
|
||||
xil_printf("spi test successful.\r\n");
|
||||
spi_test = 1;
|
||||
}else
|
||||
{
|
||||
xil_printf("spi test unsuccessful.\r\n");
|
||||
spi_test = 0;
|
||||
}
|
||||
|
||||
|
||||
//BRAM TEST
|
||||
xil_printf("start bram test.\r\n");
|
||||
BRAM_test = 1;
|
||||
//for (int i=0;i<8192;i++){
|
||||
// Xil_Out32(XPAR_BRAM_0_BASEADDR + 4*i,i);
|
||||
// if(i != Xil_In32(XPAR_BRAM_0_BASEADDR + 4*i)){
|
||||
//// xil_printf("BRAM ERROR,ADDR %x DATA %d read back is %d.\r\n",XPAR_BRAM_0_BASEADDR + 4*i,i,Xil_In32(XPAR_BRAM_0_BASEADDR + 4*i));
|
||||
// BRAM_test = 0;
|
||||
// }
|
||||
//// else{
|
||||
//// xil_printf("BRAM PASS,ADDR %x DATA %d read back is %d.\r\n",XPAR_BRAM_0_BASEADDR + 4*i,i,Xil_In32(XPAR_BRAM_0_BASEADDR + 4*i));
|
||||
//// }
|
||||
//}
|
||||
|
||||
//MIG TEST
|
||||
xil_printf("start mig test.\r\n");
|
||||
DDR_test = 1;
|
||||
for (int i=0;i<2048;i++){
|
||||
Xil_Out32(TX_BUFFER_BASE + 4*i,i);
|
||||
if(i != Xil_In32(TX_BUFFER_BASE + 4*i)){
|
||||
// xil_printf("MIG ERROR,ADDR %x DATA %d read back is %d.\r\n",TX_BUFFER_BASE + 4*i,i,Xil_In32(TX_BUFFER_BASE + 4*i));
|
||||
DDR_test = 0;
|
||||
}
|
||||
// else{
|
||||
// xil_printf("BRAM11 PASS,ADDR %x DATA %d read back is %d.\r\n",TX_BUFFER_BASE + 4*i,i,Xil_In32(TX_BUFFER_BASE + 4*i));
|
||||
// }
|
||||
}
|
||||
|
||||
// GPIO TEST
|
||||
int Gpio_data;
|
||||
xil_printf("start gpio test.\r\n");
|
||||
GpioSetPinDir(NRST,GPIO_DIR_OUTPUT);
|
||||
GpioWritePin(NRST,0x00);
|
||||
GpioWritePin(NRST,0x01);
|
||||
GpioSetPinDir(rst,GPIO_DIR_OUTPUT);
|
||||
GpioWritePin(rst,0x01);
|
||||
GpioWritePin(rst,0x00);
|
||||
GpioSetPinDir(aresetn_0,GPIO_DIR_OUTPUT);
|
||||
GpioWritePin(aresetn_0,0x00);
|
||||
GpioWritePin(aresetn_0,0x01);
|
||||
GpioSetPinDir(aresetn_1,GPIO_DIR_OUTPUT);
|
||||
GpioWritePin(aresetn_1,0x00);
|
||||
GpioWritePin(aresetn_1,0x01);
|
||||
GpioSetPinDir(aresetn_2,GPIO_DIR_OUTPUT);
|
||||
GpioWritePin(aresetn_2,0x00);
|
||||
GpioWritePin(aresetn_2,0x01);
|
||||
GpioSetPinDir(debug_mode,GPIO_DIR_OUTPUT);
|
||||
GpioWritePin(debug_mode,0x00);
|
||||
GpioSetPinDir(cx3e04_rstn,GPIO_DIR_OUTPUT);
|
||||
GpioWritePin(cx3e04_rstn,0x01);
|
||||
//GpioSetPinDir(test_temp,GPIO_DIR_INPUT);
|
||||
Gpio_data=GpioReadPin(aresetn_1);
|
||||
if(Gpio_data==1)
|
||||
{
|
||||
xil_printf("GPIO test successful.\r\n");
|
||||
Gpio_test = 1;
|
||||
}else
|
||||
{
|
||||
xil_printf("GPIO test unsuccessful.\r\n");
|
||||
Gpio_test = 0;
|
||||
}
|
||||
//GpioSetPinDir(test_temp,GPIO_DIR_OUTPUT);
|
||||
//GpioWritePin(test_temp,0x01);
|
||||
|
||||
if((spi_test==1)&&(Gpio_test==1)&&(BRAM_test==1)&&(DDR_test==1))
|
||||
{
|
||||
xil_printf("peripheral test successful.\r\n");
|
||||
return 1;
|
||||
}else
|
||||
{
|
||||
xil_printf("peripheral test unsuccessful.\r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int spi_stack_in(u8 * data,struct spi_stack * spistack){
|
||||
spistack->recv_buf[spistack->spi_write_num * 3 + 0] = *(data + 0);
|
||||
spistack->recv_buf[spistack->spi_write_num * 3 + 1] = *(data + 1);
|
||||
spistack->recv_buf[spistack->spi_write_num * 3 + 2] = *(data + 2);
|
||||
spistack->spi_write_num = spistack->spi_write_num + 1;
|
||||
if(spistack->spi_write_num >= SPI_STACK_LENGTH-1){
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void spi_stack_out(struct spi_stack * spistack){
|
||||
|
||||
int i;
|
||||
u8 rx_data;
|
||||
for(i=0;i<spistack->spi_write_num;i++ ){
|
||||
SpiPs_write_read((u8 *)&(spistack->recv_buf[i * 3]),&rx_data);
|
||||
}
|
||||
spistack->spi_write_num = 0;
|
||||
}
|
||||
|
||||
int rom_read(u8 * data)
|
||||
{
|
||||
int addr ;
|
||||
addr = *(data + 0)*256+ *(data + 1);
|
||||
return Xil_In32(BROM_BASEADDR+addr*4);
|
||||
}
|
||||
|
||||
void trx_ch_pll_config(u8 pll_index)
|
||||
{
|
||||
u8 rx_data;
|
||||
u8 recv_buf[3]={0};
|
||||
u32 trx_ch_pll_data;
|
||||
|
||||
if(pll_index==1){
|
||||
trx_ch_pll_data = 0x00077DCF;
|
||||
}else if(pll_index==2){
|
||||
trx_ch_pll_data = 0x00077D0C;
|
||||
}
|
||||
|
||||
recv_buf[0] =(trx_ch_pll_data>>16 & 0xff)|0x80 ;
|
||||
recv_buf[1] = trx_ch_pll_data>>8 & 0xff;
|
||||
recv_buf[2] = trx_ch_pll_data & 0xff;
|
||||
SpiPs_write_read(recv_buf,&rx_data);
|
||||
}
|
||||
|
||||
u16 pll1_config_addr[] ={0x0620,0x061D,0x0B06,0x0B07,0x0B08,0x0B09,0x0B0A,0x061A,0x061B,0x061C,0x062A};
|
||||
u16 pll2_config_addr[] ={0x0642,0x063F,0x0B14,0x0B15,0x0B16,0x0B17,0x0B18,0x063C,0x063D,0x063E,0x064C};
|
||||
u16 pll3_config_addr[] ={0x0664,0x0661,0x0B22,0x0B23,0x0B24,0x0B25,0x0B26,0x065E,0x065F,0x0660,0x066E};
|
||||
u16 pll4_config_addr[] ={0x0686,0x0683,0x0B30,0x0B31,0x0B32,0x0B33,0x0B34,0x0680,0x0681,0x0682,0x0690};
|
||||
|
||||
int PLL_config(u8 pll_index,double pll_frq)
|
||||
{
|
||||
|
||||
int i = 0,afc_cnt=0;
|
||||
u16 pll_config_addr[11];
|
||||
u16 afc_addr,lock_addr;
|
||||
double ref=200;
|
||||
u8 pllreg_buf[11];
|
||||
u8 recv_buf[3];
|
||||
u8 rx_data,pll_div;
|
||||
u16 div_addr;
|
||||
|
||||
switch(pll_index){
|
||||
case 1:for (i = 0; i < 11; i++){pll_config_addr[i] = pll1_config_addr[i];} afc_addr=0x0617;lock_addr=0x0635;break;
|
||||
case 2:for (i = 0; i < 11; i++){pll_config_addr[i] = pll2_config_addr[i];} afc_addr=0x0639;lock_addr=0x0657;break;
|
||||
case 3:for (i = 0; i < 11; i++){pll_config_addr[i] = pll3_config_addr[i];} afc_addr=0x065B;lock_addr=0x0679;break;
|
||||
case 4:for (i = 0; i < 11; i++){pll_config_addr[i] = pll4_config_addr[i];} afc_addr=0x067D;lock_addr=0x069B;break;
|
||||
default :;
|
||||
}
|
||||
//caculate pll frequence word
|
||||
pll_frq_caculation_new(ref,pll_frq,(u8 *)&pllreg_buf);
|
||||
for (i = 0; i < 11; i++)
|
||||
{
|
||||
recv_buf[0] = (pll_config_addr[i]>>8 & 0xff)|0x80 ;
|
||||
recv_buf[1] = pll_config_addr[i] & 0xff;
|
||||
recv_buf[2] = pllreg_buf[i] & 0xff;
|
||||
SpiPs_write_read((u8 *)&recv_buf[0],&rx_data);
|
||||
}
|
||||
//afc pll
|
||||
pll_div = pllreg_buf[1];
|
||||
div_addr = pll_config_addr[1];
|
||||
recv_buf[0] = lock_addr>>8 & 0xff ;
|
||||
recv_buf[1] = lock_addr & 0xff;
|
||||
recv_buf[2] = 0x00;
|
||||
while(rx_data!=48){
|
||||
PLL_afc(afc_addr,div_addr,pll_div);
|
||||
SpiPs_write_read((u8 *)&recv_buf[0],&rx_data);
|
||||
afc_cnt++;
|
||||
}
|
||||
return afc_cnt;
|
||||
//xil_printf("afc lock count: %d.\r\n",afc_cnt);
|
||||
|
||||
}
|
||||
|
||||
void PLL_afc(u16 afc_addr,u16 div_addr,u8 pll_div){
|
||||
|
||||
u8 recv_buf[3];
|
||||
u8 rx_data;
|
||||
if(pll_div>=48){
|
||||
recv_buf[0] = (div_addr>>8 & 0xff)|0x80 ;
|
||||
recv_buf[1] = div_addr & 0xff;
|
||||
recv_buf[2] = pll_div & 0x2f;
|
||||
SpiPs_write_read((u8 *)&recv_buf[0],&rx_data);
|
||||
}
|
||||
recv_buf[0] = (afc_addr>>8 & 0xff)|0x80 ;
|
||||
recv_buf[1] = afc_addr & 0xff;
|
||||
recv_buf[2] = 0x00;
|
||||
SpiPs_write_read((u8 *)&recv_buf[0],&rx_data);
|
||||
recv_buf[2] = 0x03;
|
||||
SpiPs_write_read((u8 *)&recv_buf[0],&rx_data);
|
||||
usleep(30);
|
||||
if(pll_div>=48){
|
||||
recv_buf[0] = (div_addr>>8 & 0xff)|0x80 ;
|
||||
recv_buf[1] = div_addr & 0xff;
|
||||
recv_buf[2] = pll_div & 0xff;
|
||||
SpiPs_write_read((u8 *)&recv_buf[0],&rx_data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int pll_frq_caculation(double ref,double pll_frq,u8 *reg_data){
|
||||
|
||||
u8 row,column;
|
||||
int vco = pll_frq;
|
||||
int div = 1;
|
||||
while(vco < 7001){
|
||||
vco = vco*2;
|
||||
div = div*2;
|
||||
}
|
||||
char coreTable[7][4][3] = {{{0x0C,0x30,0x08},{0x0B,0x30,0x09},{0x0C,0x30,0x05},{0x0D,0x30,0x08}},
|
||||
{{0x0C,0x30,0x0C},{0x0B,0x30,0x0E},{0x0C,0x30,0x08},{0x0D,0x30,0x0B}},
|
||||
{{0x0C,0x20,0x10},{0x0B,0x20,0x10},{0x0C,0x20,0x0A},{0x0D,0x20,0x0D}},
|
||||
{{0x0C,0x20,0x11},{0x0B,0x20,0x13},{0x0C,0x20,0x0C},{0x0D,0x20,0x0F}},
|
||||
{{0x0D,0x30,0x14},{0x0D,0x22,0x14},{0x0D,0x20,0x0D},{0x0D,0x15,0x0C}},
|
||||
{{0x0E,0x30,0x18},{0x0E,0x25,0x16},{0x0E,0x25,0x0F},{0x0E,0x18,0x0F}},
|
||||
{{0x0F,0x38,0x1A},{0x0F,0x32,0x1C},{0x0F,0x18,0x12},{0x0F,0x18,0x12}}};
|
||||
|
||||
if (ref >= 28 && ref < 40){
|
||||
row = 0;
|
||||
}else if (ref >= 40 && ref < 60){
|
||||
row = 1;
|
||||
}else if (ref >= 60 && ref < 90){
|
||||
row = 2;
|
||||
}else if (ref >= 90 && ref < 110){
|
||||
row = 3;
|
||||
}else if (ref >= 110 && ref < 140){
|
||||
row = 4;
|
||||
}else if (ref >= 140 && ref < 180){
|
||||
row = 5;
|
||||
}else if (ref >= 180 && ref <= 240){
|
||||
row = 6;
|
||||
}
|
||||
|
||||
if (vco >= 7001 && vco < 8400){
|
||||
column = 0;
|
||||
}else if (vco >= 8400 && vco < 10500){
|
||||
column = 1;
|
||||
}else if (vco >= 10500 && vco < 12000){
|
||||
column = 2;
|
||||
}else if (vco >= 12000 && vco <= 14000){
|
||||
column = 3;
|
||||
}
|
||||
|
||||
char cp = coreTable[row][column][0];
|
||||
char c1r3 = coreTable[row][column][1];
|
||||
char r1 = coreTable[row][column][2];
|
||||
|
||||
char dither,nHigh,nLow,fHigh,fMiddle,fLow,outputDiv,core = 0x81;
|
||||
if(vco > 10500){
|
||||
core = core + 0x10;
|
||||
}
|
||||
if (div == 2){
|
||||
outputDiv = 0+7;
|
||||
}else if (div == 4){
|
||||
outputDiv = 32+7;
|
||||
}else{
|
||||
outputDiv = 48 + divBin(div);
|
||||
}
|
||||
|
||||
double nf = 1.0*vco / ref;
|
||||
int n = nf;
|
||||
double f = nf - n;
|
||||
if(f > 1e-10){
|
||||
dither = 11;
|
||||
}else{
|
||||
dither = 0;
|
||||
}
|
||||
if(n >= 256){
|
||||
nHigh = 1;
|
||||
}else{
|
||||
nHigh = 0;
|
||||
}
|
||||
nLow = n & 0xff;
|
||||
int f1 = f * pow(2,24);
|
||||
fHigh = f1>>16 & 0xff;
|
||||
fMiddle = f1>>8 & 0xff;
|
||||
fLow = f1 & 0xff;
|
||||
reg_data[0]=core;
|
||||
reg_data[1]=outputDiv;
|
||||
reg_data[2]=nHigh;
|
||||
reg_data[3]=nLow;
|
||||
reg_data[4]=fHigh;
|
||||
reg_data[5]=fMiddle;
|
||||
reg_data[6]=fLow;
|
||||
reg_data[7]=cp;
|
||||
reg_data[8]=c1r3;
|
||||
reg_data[9]=r1;
|
||||
reg_data[10]=dither;
|
||||
return 0;
|
||||
}
|
||||
int pll_frq_caculation_new(double ref,double pll_frq,u8 *reg_data){
|
||||
|
||||
u8 row,column;
|
||||
double vco = pll_frq;
|
||||
int div = 1;
|
||||
while(vco < 6701){
|
||||
vco = vco*2;
|
||||
div = div*2;
|
||||
}
|
||||
char coreTable[7][4][3] = {{{0x0C,0x30,0x08},{0x0B,0x30,0x09},{0x0C,0x30,0x05},{0x0D,0x30,0x08}},
|
||||
{{0x0C,0x30,0x0C},{0x0B,0x30,0x0E},{0x0C,0x30,0x08},{0x0D,0x30,0x0B}},
|
||||
{{0x0C,0x20,0x10},{0x0B,0x20,0x10},{0x0C,0x20,0x0A},{0x0D,0x20,0x0D}},
|
||||
{{0x0C,0x20,0x11},{0x0B,0x20,0x13},{0x0C,0x20,0x0C},{0x0D,0x20,0x0F}},
|
||||
{{0x0D,0x30,0x14},{0x0D,0x22,0x14},{0x0D,0x20,0x0D},{0x0D,0x15,0x0C}},
|
||||
{{0x0E,0x30,0x18},{0x0E,0x25,0x16},{0x0E,0x25,0x0F},{0x0E,0x18,0x0F}},
|
||||
{{0x0F,0x38,0x1A},{0x0F,0x32,0x1C},{0x0F,0x18,0x12},{0x0F,0x18,0x12}}};
|
||||
|
||||
if (ref >= 28 && ref < 40){
|
||||
row = 0;
|
||||
}else if (ref >= 40 && ref < 60){
|
||||
row = 1;
|
||||
}else if (ref >= 60 && ref < 90){
|
||||
row = 2;
|
||||
}else if (ref >= 90 && ref < 110){
|
||||
row = 3;
|
||||
}else if (ref >= 110 && ref < 140){
|
||||
row = 4;
|
||||
}else if (ref >= 140 && ref < 180){
|
||||
row = 5;
|
||||
}else if (ref >= 180 && ref <= 240){
|
||||
row = 6;
|
||||
}
|
||||
|
||||
if (vco < 8400){
|
||||
column = 0;
|
||||
}else if (vco >= 8400 && vco < 10150){
|
||||
column = 1;
|
||||
}else if (vco >= 10150 && vco < 12000){
|
||||
column = 2;
|
||||
}else if (vco >= 12000 ){
|
||||
column = 3;
|
||||
}
|
||||
|
||||
char cp = coreTable[row][column][0];
|
||||
char c1r3 = coreTable[row][column][1];
|
||||
char r1 = coreTable[row][column][2];
|
||||
|
||||
char dither,nHigh,nLow,fHigh,fMiddle,fLow,outputDiv,core = 0x81;
|
||||
if(vco > 10150){
|
||||
core = core + 0x10;
|
||||
}
|
||||
if (div == 2){
|
||||
outputDiv = 0+7;
|
||||
}else if (div == 4){
|
||||
outputDiv = 32+7;
|
||||
}else{
|
||||
outputDiv = 48 + divBin(div);
|
||||
}
|
||||
|
||||
double nf = 1.0*vco / ref;
|
||||
int n = nf;
|
||||
double f = nf - n;
|
||||
if(f > 1e-10){
|
||||
dither = 11;
|
||||
}else{
|
||||
dither = 0;
|
||||
}
|
||||
if(n >= 256){
|
||||
nHigh = 1;
|
||||
}else{
|
||||
nHigh = 0;
|
||||
}
|
||||
nLow = n & 0xff;
|
||||
int f1 = f * pow(2,24);
|
||||
fHigh = f1>>16 & 0xff;
|
||||
fMiddle = f1>>8 & 0xff;
|
||||
fLow = f1 & 0xff;
|
||||
reg_data[0]=core;
|
||||
reg_data[1]=outputDiv;
|
||||
reg_data[2]=nHigh;
|
||||
reg_data[3]=nLow;
|
||||
reg_data[4]=fHigh;
|
||||
reg_data[5]=fMiddle;
|
||||
reg_data[6]=fLow;
|
||||
reg_data[7]=cp;
|
||||
reg_data[8]=c1r3;
|
||||
reg_data[9]=r1;
|
||||
reg_data[10]=dither;
|
||||
return 0;
|
||||
}
|
||||
char divBin(u16 div){
|
||||
|
||||
switch(div){
|
||||
case 8:return 7;break;
|
||||
case 16:return 6;break;
|
||||
case 32:return 5;break;
|
||||
case 64:return 4;break;
|
||||
case 128:return 3;break;
|
||||
case 256:return 2;break;
|
||||
default :return 2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void configTxNcoFreq(int freq, int fs) {
|
||||
u8 rx_data;
|
||||
double ratio = (double) freq < 0 ? (freq + fs) / fs : freq / fs;
|
||||
double bin = ratio * pow(2,48);
|
||||
int bin_low = (u32) bin & 0xFFFFFF;
|
||||
int bin_high = (u32)(bin / pow(2,24)) & 0xFFFFFF;
|
||||
SpiPs_write_read1(0x164, (bin_high >> 16) & 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x165, (bin_high >> 8) & 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x166, bin_high & 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x167, (bin_low >> 16) & 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x168, (bin_low >> 8) & 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x169, bin_low & 0xFF,&rx_data);
|
||||
}
|
||||
void configRxNcoFreq(int freq, int fs) {
|
||||
u8 rx_data;
|
||||
double ratio = (double) freq < 0 ? (freq + fs) / fs : freq / fs;
|
||||
double bin = ratio * pow(2,48);
|
||||
int bin_low = (u32) bin & 0xFFFFFF;
|
||||
int bin_high = (u32)(bin / pow(2,24)) & 0xFFFFFF;
|
||||
SpiPs_write_read1(0xA16, (bin_high >> 16) & 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0xA17, (bin_high >> 8) & 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0xA18, bin_high & 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0xA19, (bin_low >> 16) & 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0xA1A, (bin_low >> 8) & 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0xA1B, bin_low & 0xFF,&rx_data);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* xilinx_io.h
|
||||
*
|
||||
* Created on: 2021年9月6日
|
||||
* Author: cxlab
|
||||
*/
|
||||
|
||||
#ifndef SRC_XILINX_IO_H_
|
||||
#define SRC_XILINX_IO_H_
|
||||
|
||||
|
||||
|
||||
#endif /* SRC_XILINX_IO_H_ */
|
||||
#include "xspips.h" /* SPI device driver */
|
||||
#include "xgpiops.h"
|
||||
#include "xgpio.h"
|
||||
#include "xaxidma.h"
|
||||
#include "xparameters.h"
|
||||
#include "xscugic.h"
|
||||
#include "xil_exception.h"
|
||||
|
||||
//#define DBGLOG
|
||||
#define MAX_DATA 100
|
||||
#define SPI_WRITE 0x80
|
||||
#define SPI_READ 0x00
|
||||
#define GPIO_DIR_INPUT 0x00
|
||||
#define GPIO_DIR_OUTPUT 0x01
|
||||
#define GPIO_EMIO_OFFSET 54
|
||||
|
||||
#define TX_EN 0x08
|
||||
#define RX_EN 0x07
|
||||
#define GPIO_1 0x06
|
||||
#define GPIO_0 0x05
|
||||
|
||||
#define NRST 0
|
||||
#define ENABLE_TRX1 1
|
||||
#define ENABLE_TRX2 2
|
||||
#define ENABLE_TRX3 3
|
||||
#define TXNRX_TRX1 4
|
||||
#define TXNRX_TRX2 5
|
||||
#define TXNRX_RX3 6
|
||||
|
||||
#define aresetn_0 33
|
||||
#define rst 34
|
||||
#define tr_sel 35
|
||||
#define tdd_fdd_sel 36
|
||||
#define r1t1_r2t2_sel 37
|
||||
#define sp_dp_sel 38
|
||||
#define aresetn_1 39
|
||||
#define aresetn_2 40
|
||||
#define hop 41
|
||||
#define cx3e04_rstn 42
|
||||
#define debug_mode 63
|
||||
|
||||
#define INTER_SIG3 0x03//dma_axis_rx_rstn
|
||||
#define INTER_SIG2 0x02//frame_pattern
|
||||
#define INTER_SIG1 0x01//mode_sel_async
|
||||
#define INTER_SIG0 0x00//rst_async
|
||||
|
||||
#define SPI_DEVICE_ID XPAR_XSPIPS_0_DEVICE_ID
|
||||
#define GPIO_DEVICE_ID XPAR_PS7_GPIO_0_DEVICE_ID
|
||||
|
||||
#define AXI_DMA_DEVCIE_ID0 XPAR_AXI_DMA_0_DEVICE_ID
|
||||
#define AXI_DMA_DEVCIE_ID1 XPAR_AXI_DMA_1_DEVICE_ID
|
||||
#define AXI_DMA_DEVCIE_ID2 XPAR_AXI_DMA_2_DEVICE_ID
|
||||
|
||||
#define BROM_BASEADDR XPAR_M08_AXI_0_BASEADDR
|
||||
|
||||
#define AXI4_LITE_SPI_BASEADDR XPAR_AXI4_LITE_SPI_0_BASEADDR
|
||||
#define BRAM_BASEADDR XPAR_AXI_BRAM_CTRL_0_S_AXI_BASEADDR
|
||||
#define BRAM_BASEADDR_1 XPAR_AXI_BRAM_CTRL_1_S_AXI_BASEADDR
|
||||
#define PACKER_BASEADDR0 XPAR_AXIS_ADC_DATA_PACKER_0_S00_AXI_BASEADDR
|
||||
#define PACKER_BASEADDR1 XPAR_AXIS_ADC_DATA_PACKER_1_S00_AXI_BASEADDR
|
||||
#define PACKER_BASEADDR2 XPAR_AXIS_ADC_DATA_PACKER_2_S00_AXI_BASEADDR
|
||||
#define WAVELENGTH 8192
|
||||
#define TX_BUFFER_BASE XPAR_MIG_7SERIES_0_BASEADDR +0x2000
|
||||
#define WAVE_LENGTH 8192*4
|
||||
|
||||
#define GPIO_INT_ID XPAR_FABRIC_GPIO_0_VEC_ID //PL 端 AXI GPIO 中断 ID
|
||||
#define AXI_GPIO_ID XPAR_AXI_GPIO_0_DEVICE_ID //PL 端 AXI GPIO 器件 ID
|
||||
#define SCUGIC_ID XPAR_SCUGIC_0_DEVICE_ID //中断控制器 ID
|
||||
|
||||
#define KEY_MASK XGPIO_IR_CH1_MASK //通道 1 的位定义
|
||||
|
||||
int cx3e04_write(int addr , int value);
|
||||
int cx3e04_read(int addr);
|
||||
void cx3e04_config(void);
|
||||
void cx9261a_710_config(void);
|
||||
|
||||
void AXIGpioInit(void);
|
||||
void ConfigAXIGPIOIntr(void);
|
||||
void axi_gpio_handler(void *CallbackRef);
|
||||
void XScuGicInit(void);
|
||||
void ExceptionInit(void);
|
||||
|
||||
int SpiPsInit(u16 SpiDeviceId);
|
||||
//int SpiPs_write_read(u8 cmd, u16 addr,u8 data,u8 * rx_data);
|
||||
int SpiPs_write_read(u8 * data,u8 * rx_data);
|
||||
int SpiPs_write_read1(u16 addr,u8 data,u8 * rx_data);
|
||||
int SpiPs_write_read2(u16 addr,u8 data,u8 * rx_data);
|
||||
int GpioInit(u16 DeviceId);
|
||||
int GpioSetPinDir(u32 Pin,u32 Direction);
|
||||
int GpioWritePin(u32 Pin,u32 data);
|
||||
int GpioReadPin(u32 Pin);
|
||||
void DeviceRst(void);
|
||||
|
||||
//校准
|
||||
void cx9261a_151_config(void);
|
||||
void cx9261a_076_config(void);
|
||||
void rxFFTCalib(int lo, int fs,int ref, int firLength,int chan);
|
||||
void configTxNcoFreq(int freq, int fs);
|
||||
void configRxNcoFreq(int freq, int fs);
|
||||
void configDcCalib(int dcCalibEnable,int dcCalibLength);
|
||||
void txBisectionQecCalib(int f0, int fs);
|
||||
void txBisectionDcCalib(int f0, int fs);
|
||||
|
||||
extern XAxiDma* xAxiDma0Get(void);
|
||||
extern XAxiDma* xAxiDma1Get(void);
|
||||
extern XAxiDma* xAxiDma2Get(void);
|
||||
int XAxiDma_Init(XAxiDma* AxiDma,u16 DeviceId);
|
||||
int XAxiDmaCapture(XAxiDma* AxiDma,u32 data_length);
|
||||
int XAxiDmaCapture2(XAxiDma* AxiDma,u32 data_length);
|
||||
|
||||
int DownloadWave(u8 * data);
|
||||
int SetPacketSize(XAxiDma* AxiDma,u32 length);
|
||||
void dbg_printf( const char8 *ctrl1, ...);
|
||||
void PackerRst(void);
|
||||
int peripheral_test(void);
|
||||
|
||||
#define SPI_STACK_LENGTH 65536
|
||||
struct spi_stack {
|
||||
int spi_write_num;
|
||||
u8 recv_buf[SPI_STACK_LENGTH*3];
|
||||
};
|
||||
int spi_stack_in(u8 * data,struct spi_stack * spistack);
|
||||
|
||||
void spi_stack_out(struct spi_stack * spistack);
|
||||
|
||||
int rom_read(u8 * data);
|
||||
void download_bin(void);
|
||||
//跳频
|
||||
void frqhop_config(int hop_flag);
|
||||
void frqhop_flag(int frqhop_flag);
|
||||
int PLL_config(u8 pll_index,double pll_frq);
|
||||
void trx_ch_pll_config(u8 pll_index);
|
||||
int pll_frq_caculation(double ref,double pll_frq,u8 *reg_data);
|
||||
int pll_frq_caculation_new(double ref,double pll_frq,u8 *reg_data);
|
||||
void PLL_afc(u16 afc_addr,u16 div_addr,u8 pll_div);
|
||||
char divBin(u16 div);
|
||||
+342
@@ -0,0 +1,342 @@
|
||||
/*
|
||||
* cx9261a_076_config.c
|
||||
*
|
||||
* Created on: 2023年11月30日
|
||||
* Author: cxlab
|
||||
*/
|
||||
|
||||
|
||||
#include "xilinx_io.h"
|
||||
#include "sleep.h"
|
||||
void cx9261a_076_config(void){
|
||||
u8 rx_data;
|
||||
int temp;
|
||||
|
||||
//setPin(pin,value)
|
||||
GpioSetPinDir(0,0x01);
|
||||
GpioWritePin(0,1);
|
||||
GpioSetPinDir(32,0x01);
|
||||
GpioWritePin(32,1);
|
||||
GpioSetPinDir(33,0x01);
|
||||
GpioWritePin(33,1);
|
||||
GpioSetPinDir(34,0x01);
|
||||
GpioWritePin(34,0);
|
||||
GpioSetPinDir(35,0x01); //tx:0-rx:1
|
||||
GpioWritePin(35,1); //tx:0-rx:1
|
||||
GpioSetPinDir(36,0x01); //fdd:0-tdd:1
|
||||
GpioWritePin(36,1); //fdd:0-tdd:1
|
||||
GpioSetPinDir(37,0x01); //1r1t:0-2r2t:1
|
||||
GpioWritePin(37,0); //1r1t:0-2r2t:1
|
||||
GpioSetPinDir(38,0x01); //dualport:0-singleport:1
|
||||
GpioWritePin(38,1); //dualport:0-singleport:1
|
||||
GpioSetPinDir(39,0x01);
|
||||
GpioWritePin(39,1);
|
||||
GpioSetPinDir(40,0x01);
|
||||
GpioWritePin(40,1);
|
||||
//三个通道共同控制
|
||||
SpiPs_write_read1(0x000,0x02,&rx_data);
|
||||
//电源管理自定义
|
||||
//断电模式
|
||||
SpiPs_write_read1(0x031,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x032,0x7F,&rx_data);
|
||||
SpiPs_write_read1(0x033,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x034,0xFF,&rx_data);
|
||||
//休眠模式
|
||||
SpiPs_write_read1(0x035,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x036,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x037,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x038,0xEB,&rx_data);
|
||||
//警戒模式
|
||||
SpiPs_write_read1(0x039,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x03A,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x03B,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x03C,0xE0,&rx_data);
|
||||
//校准模式
|
||||
SpiPs_write_read1(0x03D,0x1B,&rx_data);
|
||||
SpiPs_write_read1(0x03E,0x39,&rx_data);
|
||||
SpiPs_write_read1(0x03F,0x27,&rx_data);
|
||||
SpiPs_write_read1(0x040,0xE0,&rx_data);
|
||||
//接收模式
|
||||
SpiPs_write_read1(0x041,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x042,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x043,0xE7,&rx_data);
|
||||
SpiPs_write_read1(0x044,0xF8,&rx_data);
|
||||
//发射模式
|
||||
SpiPs_write_read1(0x045,0x1B,&rx_data);
|
||||
SpiPs_write_read1(0x046,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x047,0x26,&rx_data);
|
||||
SpiPs_write_read1(0x048,0x7E,&rx_data);
|
||||
//FDD模式
|
||||
SpiPs_write_read1(0x049,0x1B,&rx_data);
|
||||
SpiPs_write_read1(0x04A,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x04B,0x27,&rx_data);
|
||||
SpiPs_write_read1(0x04C,0xE0,&rx_data);
|
||||
//观测模式
|
||||
SpiPs_write_read1(0x04D,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x04E,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x04F,0xD9,&rx_data);
|
||||
SpiPs_write_read1(0x050,0xFE,&rx_data);
|
||||
//带隙基准
|
||||
SpiPs_write_read1(0x773,0x53,&rx_data);
|
||||
SpiPs_write_read1(0x774,0x86,&rx_data);
|
||||
//参考时钟设置
|
||||
SpiPs_write_read1(0x789,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x785,0x49,&rx_data);
|
||||
SpiPs_write_read1(0x788,0x24,&rx_data);
|
||||
usleep(10000);
|
||||
SpiPs_write_read1(0x788,0xA4,&rx_data);
|
||||
//BBPLL
|
||||
SpiPs_write_read1(0x0C0,0x50,&rx_data);
|
||||
SpiPs_write_read1(0x0C1,0x50,&rx_data);
|
||||
SpiPs_write_read1(0x0C2,0x50,&rx_data);
|
||||
SpiPs_write_read1(0x601,0x0F,&rx_data);
|
||||
SpiPs_write_read1(0x602,0x21,&rx_data);
|
||||
SpiPs_write_read1(0x60D,0x0C,&rx_data);
|
||||
SpiPs_write_read1(0x60E,0x66,&rx_data);
|
||||
SpiPs_write_read1(0x60F,0x66,&rx_data);
|
||||
SpiPs_write_read1(0x610,0x66,&rx_data);
|
||||
SpiPs_write_read1(0x611,0x13,&rx_data);
|
||||
SpiPs_write_read1(0x612,0x00,&rx_data);
|
||||
//ADC
|
||||
SpiPs_write_read1(0x70B,0x0E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x0E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x0E,&rx_data);
|
||||
SpiPs_write_read1(0x70D,0x3F,&rx_data);
|
||||
SpiPs_write_read1(0x729,0x3F,&rx_data);
|
||||
SpiPs_write_read1(0x745,0x3F,&rx_data);
|
||||
SpiPs_write_read1(0x70E,0x48,&rx_data);
|
||||
SpiPs_write_read1(0x72A,0x48,&rx_data);
|
||||
SpiPs_write_read1(0x746,0x48,&rx_data);
|
||||
SpiPs_write_read1(0x70F,0xA0,&rx_data);
|
||||
SpiPs_write_read1(0x72B,0xA0,&rx_data);
|
||||
SpiPs_write_read1(0x747,0xA0,&rx_data);
|
||||
//通道时钟来源
|
||||
SpiPs_write_read1(0x77D,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0x775,0x24,&rx_data);
|
||||
SpiPs_write_read1(0x6C3,0x00,&rx_data);
|
||||
//PLL1
|
||||
SpiPs_write_read1(0x620,0x81,&rx_data);
|
||||
SpiPs_write_read1(0x61D,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB06,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB07,0x64,&rx_data);
|
||||
SpiPs_write_read1(0xB08,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB09,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB0A,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x61A,0x0B,&rx_data);
|
||||
SpiPs_write_read1(0x61B,0x20,&rx_data);
|
||||
SpiPs_write_read1(0x61C,0x13,&rx_data);
|
||||
SpiPs_write_read1(0x624,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x625,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x62A,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x61E,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x61F,0x08,&rx_data);
|
||||
SpiPs_write_read1(0x621,0x4D,&rx_data);
|
||||
SpiPs_write_read1(0x622,0x19,&rx_data);
|
||||
SpiPs_write_read1(0x627,0x10,&rx_data);
|
||||
//Rx通道设置
|
||||
SpiPs_write_read1(0x700,0x56,&rx_data);
|
||||
SpiPs_write_read1(0x71C,0x56,&rx_data);
|
||||
SpiPs_write_read1(0x738,0x56,&rx_data);
|
||||
SpiPs_write_read1(0x701,0x02,&rx_data);
|
||||
SpiPs_write_read1(0x702,0x35,&rx_data);
|
||||
SpiPs_write_read1(0x71D,0x02,&rx_data);
|
||||
SpiPs_write_read1(0x71E,0x35,&rx_data);
|
||||
SpiPs_write_read1(0x739,0x02,&rx_data);
|
||||
SpiPs_write_read1(0x73A,0x35,&rx_data);
|
||||
SpiPs_write_read1(0x703,0xF6,&rx_data);
|
||||
SpiPs_write_read1(0x71F,0xF6,&rx_data);
|
||||
SpiPs_write_read1(0x73B,0xF6,&rx_data);
|
||||
SpiPs_write_read1(0x704,0xC8,&rx_data);
|
||||
SpiPs_write_read1(0x720,0xC8,&rx_data);
|
||||
SpiPs_write_read1(0x73C,0xC8,&rx_data);
|
||||
SpiPs_write_read1(0x907,0x1F,&rx_data);
|
||||
SpiPs_write_read1(0x705,0xFC,&rx_data);
|
||||
SpiPs_write_read1(0x721,0xFC,&rx_data);
|
||||
SpiPs_write_read1(0x73D,0xFC,&rx_data);
|
||||
SpiPs_write_read1(0x706,0x65,&rx_data);
|
||||
SpiPs_write_read1(0x722,0x65,&rx_data);
|
||||
SpiPs_write_read1(0x73E,0x65,&rx_data);
|
||||
SpiPs_write_read1(0x707,0x91,&rx_data);
|
||||
SpiPs_write_read1(0x723,0x91,&rx_data);
|
||||
SpiPs_write_read1(0x73F,0x91,&rx_data);
|
||||
SpiPs_write_read1(0x708,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x724,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x740,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x709,0x94,&rx_data);
|
||||
SpiPs_write_read1(0x725,0x94,&rx_data);
|
||||
SpiPs_write_read1(0x741,0x94,&rx_data);
|
||||
SpiPs_write_read1(0x70A,0xFC,&rx_data);
|
||||
SpiPs_write_read1(0x726,0xFC,&rx_data);
|
||||
SpiPs_write_read1(0x742,0xFC,&rx_data);
|
||||
SpiPs_write_read1(0x75A,0x83,&rx_data);
|
||||
SpiPs_write_read1(0x75B,0xDA,&rx_data);
|
||||
usleep(10000);
|
||||
SpiPs_write_read1(0x75B,0x9A,&rx_data);
|
||||
SpiPs_write_read1(0x75C,0x81,&rx_data);
|
||||
SpiPs_write_read1(0x75D,0xF8,&rx_data);
|
||||
SpiPs_write_read1(0x75E,0xA7,&rx_data);
|
||||
SpiPs_write_read1(0x75F,0x51,&rx_data);
|
||||
SpiPs_write_read1(0x760,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x761,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x762,0x70,&rx_data);
|
||||
SpiPs_write_read1(0x763,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x764,0x83,&rx_data);
|
||||
SpiPs_write_read1(0x765,0xDA,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x765,0x9A,&rx_data);
|
||||
SpiPs_write_read1(0x766,0x81,&rx_data);
|
||||
SpiPs_write_read1(0x767,0xF8,&rx_data);
|
||||
SpiPs_write_read1(0x768,0xA7,&rx_data);
|
||||
SpiPs_write_read1(0x769,0x51,&rx_data);
|
||||
SpiPs_write_read1(0x76A,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x76B,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x76C,0x70,&rx_data);
|
||||
SpiPs_write_read1(0x76D,0x04,&rx_data);
|
||||
//Rx滤波器
|
||||
SpiPs_write_read1(0x106,0x02,&rx_data);
|
||||
//Tx滤波器
|
||||
SpiPs_write_read1(0x107,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x108,0xD0,&rx_data);
|
||||
//Rx NCO
|
||||
SpiPs_write_read1(0x11C,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA07,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA08,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA16,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA17,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA18,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA19,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1A,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1B,0x00,&rx_data);
|
||||
//Tx NCO
|
||||
SpiPs_write_read1(0x128,0x10,&rx_data);
|
||||
SpiPs_write_read1(0x11B,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x11E,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x161,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x162,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x164,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x165,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x166,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x167,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x168,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x169,0x00,&rx_data);
|
||||
//AGC配置
|
||||
SpiPs_write_read1(0x900,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x901,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x903,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x908,0x77,&rx_data);
|
||||
SpiPs_write_read1(0x909,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x90A,0x32,&rx_data);
|
||||
SpiPs_write_read1(0x90D,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x90E,0x0F,&rx_data);
|
||||
SpiPs_write_read1(0x90F,0x65,&rx_data);
|
||||
SpiPs_write_read1(0x910,0x32,&rx_data);
|
||||
SpiPs_write_read1(0x911,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x912,0x0F,&rx_data);
|
||||
SpiPs_write_read1(0x913,0x3A,&rx_data);
|
||||
SpiPs_write_read1(0x914,0x37,&rx_data);
|
||||
SpiPs_write_read1(0x915,0x34,&rx_data);
|
||||
SpiPs_write_read1(0x916,0x31,&rx_data);
|
||||
//进入休眠模式
|
||||
SpiPs_write_read1(0x02E,0x01,&rx_data);
|
||||
usleep(1000000);
|
||||
//进入校准模式
|
||||
SpiPs_write_read1(0x02E,0x03,&rx_data);
|
||||
//BBPLL AFC
|
||||
SpiPs_write_read1(0x600,0x00,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x600,0x11,&rx_data);
|
||||
//PLL1 AFC
|
||||
SpiPs_write_read1(0x617,0x00,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x617,0x03,&rx_data);
|
||||
//接口配置
|
||||
SpiPs_write_read1(0x02E,0x06,&rx_data);
|
||||
SpiPs_write_read1(0x003,0x33,&rx_data);
|
||||
SpiPs_write_read1(0x200,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x201,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x202,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x209,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x780,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x781,0x6F,&rx_data);
|
||||
SpiPs_write_read1(0x782,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x783,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x784,0x01,&rx_data);
|
||||
//ADC校准
|
||||
SpiPs_write_read1(0x70B,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x70F,0xA0,&rx_data);
|
||||
SpiPs_write_read1(0x710,0x83,&rx_data);
|
||||
SpiPs_write_read1(0x711,0xF0,&rx_data);
|
||||
SpiPs_write_read1(0x72B,0xA0,&rx_data);
|
||||
SpiPs_write_read1(0x72C,0x83,&rx_data);
|
||||
SpiPs_write_read1(0x72D,0xF0,&rx_data);
|
||||
SpiPs_write_read1(0x747,0xA0,&rx_data);
|
||||
SpiPs_write_read1(0x748,0x83,&rx_data);
|
||||
SpiPs_write_read1(0x749,0xF0,&rx_data);
|
||||
SpiPs_write_read1(0x713,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x72F,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x74B,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x70B,0x9E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x9E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x9E,&rx_data);
|
||||
SpiPs_write_read1(0x70B,0x9A,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x9A,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x9A,&rx_data);
|
||||
SpiPs_write_read1(0x70B,0x9E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x9E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x9E,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x70B,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x713,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0x72F,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0x74B,0xC0,&rx_data);
|
||||
//Flash校准
|
||||
SpiPs_write_read1(0x70B,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x715,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x731,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x74D,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x715,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0x731,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0x74D,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0x716,0x40,&rx_data);
|
||||
SpiPs_write_read1(0x732,0x40,&rx_data);
|
||||
SpiPs_write_read1(0x74E,0x40,&rx_data);
|
||||
SpiPs_write_read1(0x70B,0x16,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x16,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x16,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x70B,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x715,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x731,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x74D,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x716,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x732,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x74E,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x109,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x10A,0x70,&rx_data);
|
||||
SpiPs_write_read1(0x11F,0x33,&rx_data);
|
||||
usleep(1000);
|
||||
SpiPs_write_read2(0x615,0x00,&rx_data);
|
||||
temp=rx_data;
|
||||
SpiPs_write_read2(0x635,0x00,&rx_data);
|
||||
temp=rx_data;
|
||||
////配置Tx NCO BIST ON
|
||||
//SpiPs_write_read1(0x11B,0x01,&rx_data);
|
||||
//SpiPs_write_read1(0x11E,0x01,&rx_data);
|
||||
//SpiPs_write_read1(0x161,0x01,&rx_data);
|
||||
//SpiPs_write_read1(0x162,0x01,&rx_data);
|
||||
////配置Tx NCO频率 1MHz
|
||||
//SpiPs_write_read1(0x164,0x05,&rx_data);
|
||||
//SpiPs_write_read1(0x165,0x55,&rx_data);
|
||||
//SpiPs_write_read1(0x166,0x55,&rx_data);
|
||||
//SpiPs_write_read1(0x167,0x55,&rx_data);
|
||||
//SpiPs_write_read1(0x168,0x55,&rx_data);
|
||||
//SpiPs_write_read1(0x169,0x55,&rx_data);
|
||||
}
|
||||
+708
@@ -0,0 +1,708 @@
|
||||
/*
|
||||
* cx9261_config.c
|
||||
*
|
||||
* Created on: 2023年10月16日
|
||||
* Author: cxlab
|
||||
*/
|
||||
|
||||
#include "xilinx_io.h"
|
||||
#include "sleep.h"
|
||||
void cx9261a_151_config(void){
|
||||
u8 rx_data;
|
||||
int temp;
|
||||
|
||||
//setPin(pin,value)
|
||||
GpioSetPinDir(0,0x01);
|
||||
GpioWritePin(0,1);
|
||||
GpioSetPinDir(32,0x01);
|
||||
GpioWritePin(32,1);
|
||||
GpioSetPinDir(33,0x01);
|
||||
GpioWritePin(33,1);
|
||||
GpioSetPinDir(34,0x01);
|
||||
GpioWritePin(34,0);
|
||||
GpioSetPinDir(35,0x01); //tx:0-rx:1
|
||||
GpioWritePin(35,1); //tx:0-rx:1
|
||||
GpioSetPinDir(36,0x01); //fdd:0-tdd:1
|
||||
GpioWritePin(36,1); //fdd:0-tdd:1
|
||||
GpioSetPinDir(37,0x01); //1r1t:0-2r2t:1
|
||||
GpioWritePin(37,0); //1r1t:0-2r2t:1
|
||||
GpioSetPinDir(38,0x01); //dualport:0-singleport:1
|
||||
GpioWritePin(38,1); //dualport:0-singleport:1
|
||||
GpioSetPinDir(39,0x01);
|
||||
GpioWritePin(39,1);
|
||||
GpioSetPinDir(40,0x01);
|
||||
GpioWritePin(40,1);
|
||||
//三个通道共同控制
|
||||
SpiPs_write_read1(0x000,0x02,&rx_data);
|
||||
//电源管理自定义
|
||||
//断电模式
|
||||
SpiPs_write_read1(0x031,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x032,0x7F,&rx_data);
|
||||
SpiPs_write_read1(0x033,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x034,0xFF,&rx_data);
|
||||
//休眠模式
|
||||
SpiPs_write_read1(0x035,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x036,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x037,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x038,0xEB,&rx_data);
|
||||
//警戒模式
|
||||
SpiPs_write_read1(0x039,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x03A,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x03B,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x03C,0xE0,&rx_data);
|
||||
//校准模式
|
||||
SpiPs_write_read1(0x03D,0x1B,&rx_data);
|
||||
SpiPs_write_read1(0x03E,0x39,&rx_data);
|
||||
SpiPs_write_read1(0x03F,0x27,&rx_data);
|
||||
SpiPs_write_read1(0x040,0xE0,&rx_data);
|
||||
//接收模式
|
||||
SpiPs_write_read1(0x041,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x042,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x043,0xE7,&rx_data);
|
||||
SpiPs_write_read1(0x044,0xF8,&rx_data);
|
||||
//发射模式
|
||||
SpiPs_write_read1(0x045,0x18,&rx_data);
|
||||
SpiPs_write_read1(0x046,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x047,0x3F,&rx_data);
|
||||
SpiPs_write_read1(0x048,0xF8,&rx_data);
|
||||
//FDD模式
|
||||
SpiPs_write_read1(0x049,0x1B,&rx_data);
|
||||
SpiPs_write_read1(0x04A,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x04B,0x27,&rx_data);
|
||||
SpiPs_write_read1(0x04C,0xE0,&rx_data);
|
||||
//观测模式
|
||||
SpiPs_write_read1(0x04D,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x04E,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x04F,0xD9,&rx_data);
|
||||
SpiPs_write_read1(0x050,0xFE,&rx_data);
|
||||
//带隙基准
|
||||
SpiPs_write_read1(0x773,0x53,&rx_data);
|
||||
SpiPs_write_read1(0x774,0x86,&rx_data);
|
||||
//参考时钟设置
|
||||
SpiPs_write_read1(0x789,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x785,0x49,&rx_data);
|
||||
SpiPs_write_read1(0x788,0x24,&rx_data);
|
||||
usleep(10000);
|
||||
SpiPs_write_read1(0x788,0xA4,&rx_data);
|
||||
//BBPLL
|
||||
SpiPs_write_read1(0x0C0,0x50,&rx_data);
|
||||
SpiPs_write_read1(0x0C1,0x50,&rx_data);
|
||||
SpiPs_write_read1(0x0C2,0x50,&rx_data);
|
||||
SpiPs_write_read1(0x601,0x0F,&rx_data);
|
||||
SpiPs_write_read1(0x602,0x21,&rx_data);
|
||||
SpiPs_write_read1(0x60D,0x0C,&rx_data);
|
||||
SpiPs_write_read1(0x60E,0x66,&rx_data);
|
||||
SpiPs_write_read1(0x60F,0x66,&rx_data);
|
||||
SpiPs_write_read1(0x610,0x66,&rx_data);
|
||||
SpiPs_write_read1(0x611,0x13,&rx_data);
|
||||
SpiPs_write_read1(0x612,0x00,&rx_data);
|
||||
//ADC
|
||||
SpiPs_write_read1(0x70B,0x0E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x0E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x0E,&rx_data);
|
||||
SpiPs_write_read1(0x70D,0x3F,&rx_data);
|
||||
SpiPs_write_read1(0x729,0x3F,&rx_data);
|
||||
SpiPs_write_read1(0x745,0x3F,&rx_data);
|
||||
SpiPs_write_read1(0x70E,0x48,&rx_data);
|
||||
SpiPs_write_read1(0x72A,0x48,&rx_data);
|
||||
SpiPs_write_read1(0x746,0x48,&rx_data);
|
||||
SpiPs_write_read1(0x70F,0xA0,&rx_data);
|
||||
SpiPs_write_read1(0x72B,0xA0,&rx_data);
|
||||
SpiPs_write_read1(0x747,0xA0,&rx_data);
|
||||
//通道时钟来源
|
||||
SpiPs_write_read1(0x77D,0xCF,&rx_data);
|
||||
SpiPs_write_read1(0x775,0x24,&rx_data);
|
||||
SpiPs_write_read1(0x6C3,0x00,&rx_data);
|
||||
//PLL1
|
||||
SpiPs_write_read1(0x620,0x81,&rx_data);
|
||||
SpiPs_write_read1(0x61D,0x07,&rx_data);
|
||||
SpiPs_write_read1(0xB06,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB07,0x64,&rx_data);
|
||||
SpiPs_write_read1(0xB08,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB09,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB0A,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x61A,0x0B,&rx_data);
|
||||
SpiPs_write_read1(0x61B,0x20,&rx_data);
|
||||
SpiPs_write_read1(0x61C,0x13,&rx_data);
|
||||
SpiPs_write_read1(0x624,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x625,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x62A,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x61E,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x61F,0x08,&rx_data);
|
||||
SpiPs_write_read1(0x621,0x4D,&rx_data);
|
||||
SpiPs_write_read1(0x622,0x19,&rx_data);
|
||||
SpiPs_write_read1(0x627,0x10,&rx_data);
|
||||
//PLL2
|
||||
SpiPs_write_read1(0x642,0x91,&rx_data);
|
||||
SpiPs_write_read1(0x63F,0x36,&rx_data);
|
||||
SpiPs_write_read1(0xB14,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB15,0x70,&rx_data);
|
||||
SpiPs_write_read1(0xB16,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB17,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB18,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x63C,0x0C,&rx_data);
|
||||
SpiPs_write_read1(0x63D,0x20,&rx_data);
|
||||
SpiPs_write_read1(0x63E,0x0C,&rx_data);
|
||||
SpiPs_write_read1(0x646,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x647,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x64C,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x640,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x641,0x08,&rx_data);
|
||||
SpiPs_write_read1(0x643,0x4D,&rx_data);
|
||||
SpiPs_write_read1(0x644,0x19,&rx_data);
|
||||
SpiPs_write_read1(0x649,0x10,&rx_data);
|
||||
//PLL3
|
||||
SpiPs_write_read1(0x664,0x91,&rx_data);
|
||||
SpiPs_write_read1(0x661,0x36,&rx_data);
|
||||
SpiPs_write_read1(0xB22,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB23,0x80,&rx_data);
|
||||
SpiPs_write_read1(0xB24,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB25,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB26,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x65E,0x0D,&rx_data);
|
||||
SpiPs_write_read1(0x65F,0x20,&rx_data);
|
||||
SpiPs_write_read1(0x660,0x0F,&rx_data);
|
||||
SpiPs_write_read1(0x668,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x669,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x66E,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x662,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x663,0x08,&rx_data);
|
||||
SpiPs_write_read1(0x665,0x4D,&rx_data);
|
||||
SpiPs_write_read1(0x666,0x19,&rx_data);
|
||||
SpiPs_write_read1(0x66B,0x10,&rx_data);
|
||||
//PLL4
|
||||
SpiPs_write_read1(0x686,0x81,&rx_data);
|
||||
SpiPs_write_read1(0x683,0x37,&rx_data);
|
||||
SpiPs_write_read1(0xB30,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB31,0x48,&rx_data);
|
||||
SpiPs_write_read1(0xB32,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB33,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB34,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x680,0x0C,&rx_data);
|
||||
SpiPs_write_read1(0x681,0x20,&rx_data);
|
||||
SpiPs_write_read1(0x682,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x68A,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x68B,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x690,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x684,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x685,0x08,&rx_data);
|
||||
SpiPs_write_read1(0x687,0x4D,&rx_data);
|
||||
SpiPs_write_read1(0x688,0x19,&rx_data);
|
||||
SpiPs_write_read1(0x68D,0x10,&rx_data);
|
||||
//PLL5
|
||||
SpiPs_write_read1(0x6A8,0x81,&rx_data);
|
||||
SpiPs_write_read1(0x6A5,0x37,&rx_data);
|
||||
SpiPs_write_read1(0xB3E,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB3F,0x50,&rx_data);
|
||||
SpiPs_write_read1(0xB40,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB41,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB42,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x6A2,0x0C,&rx_data);
|
||||
SpiPs_write_read1(0x6A3,0x20,&rx_data);
|
||||
SpiPs_write_read1(0x6A4,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x6AC,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x6AD,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x6B2,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x6A6,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x6A7,0x08,&rx_data);
|
||||
SpiPs_write_read1(0x6A9,0x4D,&rx_data);
|
||||
SpiPs_write_read1(0x6AA,0x19,&rx_data);
|
||||
SpiPs_write_read1(0x6AF,0x10,&rx_data);
|
||||
//Rx通道设置
|
||||
SpiPs_write_read1(0x700,0x56,&rx_data);
|
||||
SpiPs_write_read1(0x71C,0x56,&rx_data);
|
||||
SpiPs_write_read1(0x738,0x56,&rx_data);
|
||||
SpiPs_write_read1(0x701,0x02,&rx_data);
|
||||
SpiPs_write_read1(0x702,0x35,&rx_data);
|
||||
SpiPs_write_read1(0x71D,0x02,&rx_data);
|
||||
SpiPs_write_read1(0x71E,0x35,&rx_data);
|
||||
SpiPs_write_read1(0x739,0x02,&rx_data);
|
||||
SpiPs_write_read1(0x73A,0x35,&rx_data);
|
||||
SpiPs_write_read1(0x703,0xF6,&rx_data);
|
||||
SpiPs_write_read1(0x71F,0xF6,&rx_data);
|
||||
SpiPs_write_read1(0x73B,0xF6,&rx_data);
|
||||
SpiPs_write_read1(0x704,0xC8,&rx_data);
|
||||
SpiPs_write_read1(0x720,0xC8,&rx_data);
|
||||
SpiPs_write_read1(0x73C,0xC8,&rx_data);
|
||||
SpiPs_write_read1(0x907,0x1F,&rx_data);
|
||||
SpiPs_write_read1(0x705,0xFC,&rx_data);
|
||||
SpiPs_write_read1(0x721,0xFC,&rx_data);
|
||||
SpiPs_write_read1(0x73D,0xFC,&rx_data);
|
||||
SpiPs_write_read1(0x706,0x65,&rx_data);
|
||||
SpiPs_write_read1(0x722,0x65,&rx_data);
|
||||
SpiPs_write_read1(0x73E,0x65,&rx_data);
|
||||
SpiPs_write_read1(0x707,0x91,&rx_data);
|
||||
SpiPs_write_read1(0x723,0x91,&rx_data);
|
||||
SpiPs_write_read1(0x73F,0x91,&rx_data);
|
||||
SpiPs_write_read1(0x708,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x724,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x740,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x709,0x94,&rx_data);
|
||||
SpiPs_write_read1(0x725,0x94,&rx_data);
|
||||
SpiPs_write_read1(0x741,0x94,&rx_data);
|
||||
SpiPs_write_read1(0x70A,0xFC,&rx_data);
|
||||
SpiPs_write_read1(0x726,0xFC,&rx_data);
|
||||
SpiPs_write_read1(0x742,0xFC,&rx_data);
|
||||
SpiPs_write_read1(0x75A,0x83,&rx_data);
|
||||
SpiPs_write_read1(0x75B,0xDA,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x75B,0x9A,&rx_data);
|
||||
SpiPs_write_read1(0x75C,0x81,&rx_data);
|
||||
SpiPs_write_read1(0x75D,0xF8,&rx_data);
|
||||
SpiPs_write_read1(0x75E,0xA7,&rx_data);
|
||||
SpiPs_write_read1(0x75F,0x50,&rx_data);
|
||||
SpiPs_write_read1(0x760,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x761,0x07,&rx_data);
|
||||
SpiPs_write_read1(0x762,0x6C,&rx_data);
|
||||
SpiPs_write_read1(0x763,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x764,0x83,&rx_data);
|
||||
SpiPs_write_read1(0x765,0xDA,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x765,0x9A,&rx_data);
|
||||
SpiPs_write_read1(0x766,0x81,&rx_data);
|
||||
SpiPs_write_read1(0x767,0xF8,&rx_data);
|
||||
SpiPs_write_read1(0x768,0xA7,&rx_data);
|
||||
SpiPs_write_read1(0x769,0x50,&rx_data);
|
||||
SpiPs_write_read1(0x76A,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x76B,0x07,&rx_data);
|
||||
SpiPs_write_read1(0x76C,0x6C,&rx_data);
|
||||
SpiPs_write_read1(0x76D,0x04,&rx_data);
|
||||
//Rx滤波器
|
||||
SpiPs_write_read1(0x106,0x02,&rx_data);
|
||||
//Tx滤波器
|
||||
SpiPs_write_read1(0x107,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x108,0xD0,&rx_data);
|
||||
//Rx NCO
|
||||
SpiPs_write_read1(0x11C,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA07,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA08,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA16,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA17,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA18,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA19,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1A,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1B,0x00,&rx_data);
|
||||
//Tx NCO
|
||||
SpiPs_write_read1(0x128,0x10,&rx_data);
|
||||
SpiPs_write_read1(0x11B,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x11E,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x161,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x162,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x164,0x05,&rx_data);
|
||||
SpiPs_write_read1(0x165,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x166,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x167,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x168,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x169,0x55,&rx_data);
|
||||
//AGC配置
|
||||
SpiPs_write_read1(0x900,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x901,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x903,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x908,0x77,&rx_data);
|
||||
SpiPs_write_read1(0x909,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x90A,0x32,&rx_data);
|
||||
SpiPs_write_read1(0x90D,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x90E,0x0F,&rx_data);
|
||||
SpiPs_write_read1(0x90F,0x65,&rx_data);
|
||||
SpiPs_write_read1(0x910,0x32,&rx_data);
|
||||
SpiPs_write_read1(0x911,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x912,0x0F,&rx_data);
|
||||
SpiPs_write_read1(0x913,0x3A,&rx_data);
|
||||
SpiPs_write_read1(0x914,0x37,&rx_data);
|
||||
SpiPs_write_read1(0x915,0x34,&rx_data);
|
||||
SpiPs_write_read1(0x916,0x31,&rx_data);
|
||||
//进入休眠模式
|
||||
SpiPs_write_read1(0x02E,0x01,&rx_data);
|
||||
usleep(1000000);
|
||||
//进入校准模式
|
||||
SpiPs_write_read1(0x02E,0x03,&rx_data);
|
||||
usleep(100000);
|
||||
//BBPLL AFC
|
||||
SpiPs_write_read1(0x600,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x600,0x11,&rx_data);
|
||||
usleep(50);
|
||||
//PLL1 AFC
|
||||
while(temp != 48)
|
||||
{
|
||||
SpiPs_write_read1(0x617,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x617,0x03,&rx_data);
|
||||
usleep(100);
|
||||
SpiPs_write_read2(0x635,0x00,&rx_data);
|
||||
temp=rx_data;
|
||||
}
|
||||
//接口配置
|
||||
SpiPs_write_read1(0x02E,0x06,&rx_data);
|
||||
SpiPs_write_read1(0x003,0x33,&rx_data);
|
||||
SpiPs_write_read1(0x200,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x201,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x202,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x208,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x209,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x780,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x781,0x6F,&rx_data);
|
||||
SpiPs_write_read1(0x782,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x783,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x784,0x01,&rx_data);
|
||||
//ADC校准
|
||||
SpiPs_write_read1(0x70B,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x70F,0xA0,&rx_data);
|
||||
SpiPs_write_read1(0x710,0x83,&rx_data);
|
||||
SpiPs_write_read1(0x711,0xF0,&rx_data);
|
||||
SpiPs_write_read1(0x72B,0xA0,&rx_data);
|
||||
SpiPs_write_read1(0x72C,0x83,&rx_data);
|
||||
SpiPs_write_read1(0x72D,0xF0,&rx_data);
|
||||
SpiPs_write_read1(0x747,0xA0,&rx_data);
|
||||
SpiPs_write_read1(0x748,0x83,&rx_data);
|
||||
SpiPs_write_read1(0x749,0xF0,&rx_data);
|
||||
SpiPs_write_read1(0x713,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x72F,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x74B,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x70B,0x9E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x9E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x9E,&rx_data);
|
||||
SpiPs_write_read1(0x70B,0x9A,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x9A,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x9A,&rx_data);
|
||||
SpiPs_write_read1(0x70B,0x9E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x9E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x9E,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x70B,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x713,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0x72F,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0x74B,0xC0,&rx_data);
|
||||
//Flash校准
|
||||
SpiPs_write_read1(0x70B,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x715,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x731,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x74D,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x715,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0x731,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0x74D,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0x716,0x40,&rx_data);
|
||||
SpiPs_write_read1(0x732,0x40,&rx_data);
|
||||
SpiPs_write_read1(0x74E,0x40,&rx_data);
|
||||
SpiPs_write_read1(0x70B,0x16,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x16,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x16,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x70B,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x715,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x731,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x74D,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x716,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x732,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x74E,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x109,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x10A,0x70,&rx_data);
|
||||
SpiPs_write_read1(0x11F,0x33,&rx_data);
|
||||
//QEC校准
|
||||
//Rx TST Calibration
|
||||
SpiPs_write_read1(0x000,0x12,&rx_data);
|
||||
SpiPs_write_read1(0x109,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x77E,0x50,&rx_data);
|
||||
SpiPs_write_read1(0x14E,0x00,&rx_data);
|
||||
// 修改校准模式电源管理
|
||||
SpiPs_write_read1(0x03D,0x09,&rx_data);
|
||||
SpiPs_write_read1(0x03E,0x39,&rx_data);
|
||||
SpiPs_write_read1(0x03F,0xB6,&rx_data);
|
||||
SpiPs_write_read1(0x040,0x78,&rx_data);
|
||||
//修改电源模式
|
||||
SpiPs_write_read1(0x02E,0x03,&rx_data);
|
||||
//Calibration PLL Source
|
||||
// 修改Pll来源
|
||||
SpiPs_write_read1(0x77D,0x90,&rx_data);
|
||||
SpiPs_write_read1(0x6C3,0x05,&rx_data);
|
||||
SpiPs_write_read1(0x775,0x24,&rx_data);
|
||||
//修改Pll4频率
|
||||
//PLL4
|
||||
SpiPs_write_read1(0x686,0x81,&rx_data);
|
||||
SpiPs_write_read1(0x683,0x07,&rx_data);
|
||||
SpiPs_write_read1(0xB30,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB31,0x63,&rx_data);
|
||||
SpiPs_write_read1(0xB32,0xEB,&rx_data);
|
||||
SpiPs_write_read1(0xB33,0x85,&rx_data);
|
||||
SpiPs_write_read1(0xB34,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x680,0x0B,&rx_data);
|
||||
SpiPs_write_read1(0x681,0x20,&rx_data);
|
||||
SpiPs_write_read1(0x682,0x13,&rx_data);
|
||||
SpiPs_write_read1(0x68A,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x68B,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x690,0x0B,&rx_data);
|
||||
SpiPs_write_read1(0x684,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x685,0x08,&rx_data);
|
||||
SpiPs_write_read1(0x687,0x4D,&rx_data);
|
||||
SpiPs_write_read1(0x688,0x19,&rx_data);
|
||||
SpiPs_write_read1(0x68D,0x10,&rx_data);
|
||||
//PLL4 AFC
|
||||
while(temp != 48)
|
||||
{
|
||||
SpiPs_write_read1(0x67D,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x67D,0x03,&rx_data);
|
||||
usleep(100);
|
||||
SpiPs_write_read2(0x69B,0x00,&rx_data);
|
||||
temp=rx_data;
|
||||
}
|
||||
SpiPs_write_read1(0x02A,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x121,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x11F,0x73,&rx_data);
|
||||
SpiPs_write_read1(0x124,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x120,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x122,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x126,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x02A,0x12,&rx_data);
|
||||
|
||||
SpiPs_write_read2(0x14D,0x00,&rx_data);
|
||||
temp=rx_data & 0x10;
|
||||
while(temp != 16){
|
||||
SpiPs_write_read2(0x14D,0x00,&rx_data);
|
||||
temp=rx_data & 0x10;
|
||||
usleep(100000);
|
||||
}
|
||||
|
||||
SpiPs_write_read1(0x77E,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x775,0x24,&rx_data);
|
||||
SpiPs_write_read1(0x77D,0xCF,&rx_data);
|
||||
SpiPs_write_read1(0x6C3,0x00,&rx_data);
|
||||
//Rx TST Calibration
|
||||
SpiPs_write_read1(0x000,0x22,&rx_data);
|
||||
SpiPs_write_read1(0x109,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x77E,0x0A,&rx_data);
|
||||
SpiPs_write_read1(0x14E,0x00,&rx_data);
|
||||
// 修改校准模式电源管理
|
||||
SpiPs_write_read1(0x03D,0x12,&rx_data);
|
||||
SpiPs_write_read1(0x03E,0x39,&rx_data);
|
||||
SpiPs_write_read1(0x03F,0x6E,&rx_data);
|
||||
SpiPs_write_read1(0x040,0x78,&rx_data);
|
||||
//修改电源模式
|
||||
SpiPs_write_read1(0x02E,0x03,&rx_data);
|
||||
//Calibration PLL Source
|
||||
// 修改Pll来源
|
||||
SpiPs_write_read1(0x77D,0x60,&rx_data);
|
||||
SpiPs_write_read1(0x6C3,0x0A,&rx_data);
|
||||
SpiPs_write_read1(0x775,0x24,&rx_data);
|
||||
//修改Pll4频率
|
||||
//PLL4
|
||||
SpiPs_write_read1(0x686,0x81,&rx_data);
|
||||
SpiPs_write_read1(0x683,0x07,&rx_data);
|
||||
SpiPs_write_read1(0xB30,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB31,0x63,&rx_data);
|
||||
SpiPs_write_read1(0xB32,0xEB,&rx_data);
|
||||
SpiPs_write_read1(0xB33,0x85,&rx_data);
|
||||
SpiPs_write_read1(0xB34,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x680,0x0B,&rx_data);
|
||||
SpiPs_write_read1(0x681,0x20,&rx_data);
|
||||
SpiPs_write_read1(0x682,0x13,&rx_data);
|
||||
SpiPs_write_read1(0x68A,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x68B,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x690,0x0B,&rx_data);
|
||||
SpiPs_write_read1(0x684,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x685,0x08,&rx_data);
|
||||
SpiPs_write_read1(0x687,0x4D,&rx_data);
|
||||
SpiPs_write_read1(0x688,0x19,&rx_data);
|
||||
SpiPs_write_read1(0x68D,0x10,&rx_data);
|
||||
//PLL4 AFC
|
||||
while(temp != 48)
|
||||
{
|
||||
SpiPs_write_read1(0x67D,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x67D,0x03,&rx_data);
|
||||
usleep(100);
|
||||
SpiPs_write_read2(0x69B,0x00,&rx_data);
|
||||
temp=rx_data;
|
||||
}
|
||||
SpiPs_write_read1(0x02B,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x121,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x11F,0x73,&rx_data);
|
||||
SpiPs_write_read1(0x124,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x120,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x122,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x126,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x02B,0x12,&rx_data);
|
||||
|
||||
SpiPs_write_read2(0x14D,0x00,&rx_data);
|
||||
temp=rx_data & 0x10;
|
||||
while(temp != 16){
|
||||
SpiPs_write_read2(0x14D,0x00,&rx_data);
|
||||
temp=rx_data & 0x10;
|
||||
usleep(100000);
|
||||
}
|
||||
|
||||
SpiPs_write_read1(0x77E,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x775,0x24,&rx_data);
|
||||
SpiPs_write_read1(0x77D,0xCF,&rx_data);
|
||||
SpiPs_write_read1(0x6C3,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x02C,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x02B,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x02A,0x00,&rx_data);
|
||||
//恢复校准前设置
|
||||
SpiPs_write_read1(0x000,0x02,&rx_data);
|
||||
SpiPs_write_read1(0x02E,0x06,&rx_data);
|
||||
SpiPs_write_read1(0x03D,0x1B,&rx_data);
|
||||
SpiPs_write_read1(0x03E,0x39,&rx_data);
|
||||
SpiPs_write_read1(0x03F,0x27,&rx_data);
|
||||
SpiPs_write_read1(0x040,0xF8,&rx_data);
|
||||
SpiPs_write_read1(0x109,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x10A,0x70,&rx_data);
|
||||
SpiPs_write_read1(0x11B,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x11E,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x11F,0x33,&rx_data);
|
||||
SpiPs_write_read1(0x128,0x10,&rx_data);
|
||||
SpiPs_write_read1(0x161,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x162,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x164,0x05,&rx_data);
|
||||
SpiPs_write_read1(0x165,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x166,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x167,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x168,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x169,0x55,&rx_data);
|
||||
SpiPs_write_read1(0xA07,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA08,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA16,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA17,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA18,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA19,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1A,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1B,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1C,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA2D,0x00,&rx_data);
|
||||
// TX二分法校准
|
||||
// 修改校准模式电源管理
|
||||
SpiPs_write_read1(0x03D,0x1B,&rx_data);
|
||||
SpiPs_write_read1(0x03E,0x39,&rx_data);
|
||||
SpiPs_write_read1(0x03F,0x27,&rx_data);
|
||||
SpiPs_write_read1(0x040,0xF8,&rx_data);
|
||||
//修改电源模式
|
||||
SpiPs_write_read1(0x02E,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x128,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x11E,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x77E,0x24,&rx_data);
|
||||
SpiPs_write_read1(0x11F,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x121,0x02,&rx_data);
|
||||
SpiPs_write_read1(0x11B,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x161,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x162,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x163,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x164,0x05,&rx_data);
|
||||
SpiPs_write_read1(0x165,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x166,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x167,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x168,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x169,0x55,&rx_data);
|
||||
SpiPs_write_read1(0xA2D,0x02,&rx_data);
|
||||
SpiPs_write_read1(0xA07,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA08,0x0F,&rx_data);
|
||||
SpiPs_write_read1(0xA1C,0x01,&rx_data);
|
||||
SpiPs_write_read1(0xA16,0x2A,&rx_data);
|
||||
SpiPs_write_read1(0xA17,0xAA,&rx_data);
|
||||
SpiPs_write_read1(0xA18,0xAA,&rx_data);
|
||||
SpiPs_write_read1(0xA19,0xAA,&rx_data);
|
||||
SpiPs_write_read1(0xA1A,0xAA,&rx_data);
|
||||
SpiPs_write_read1(0xA1B,0xAA,&rx_data);
|
||||
SpiPs_write_read1(0x186,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x763,0x34,&rx_data);
|
||||
SpiPs_write_read1(0x76D,0x34,&rx_data);
|
||||
SpiPs_write_read1(0x101,0xEF,&rx_data);
|
||||
SpiPs_write_read1(0x101,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x800,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x81A,0xF7,&rx_data);
|
||||
SpiPs_write_read1(0x81B,0x34,&rx_data);
|
||||
SpiPs_write_read1(0x81C,0x33,&rx_data);
|
||||
SpiPs_write_read1(0x81D,0x12,&rx_data);
|
||||
SpiPs_write_read1(0x81E,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x81F,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x820,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x821,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x800,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x800,0x81,&rx_data);
|
||||
//最少0.1s
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x77E,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x77E,0x24,&rx_data);
|
||||
SpiPs_write_read1(0x11F,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x121,0x02,&rx_data);
|
||||
SpiPs_write_read1(0x11B,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x11E,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x161,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x162,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x164,0x05,&rx_data);
|
||||
SpiPs_write_read1(0x165,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x166,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x167,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x168,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x169,0x55,&rx_data);
|
||||
SpiPs_write_read1(0xA2D,0x02,&rx_data);
|
||||
SpiPs_write_read1(0xA07,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA08,0x0F,&rx_data);
|
||||
SpiPs_write_read1(0xA1C,0x01,&rx_data);
|
||||
SpiPs_write_read1(0xA16,0x15,&rx_data);
|
||||
SpiPs_write_read1(0xA17,0x55,&rx_data);
|
||||
SpiPs_write_read1(0xA18,0x55,&rx_data);
|
||||
SpiPs_write_read1(0xA19,0x55,&rx_data);
|
||||
SpiPs_write_read1(0xA1A,0x55,&rx_data);
|
||||
SpiPs_write_read1(0xA1B,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x81A,0xF7,&rx_data);
|
||||
SpiPs_write_read1(0x81B,0x44,&rx_data);
|
||||
SpiPs_write_read1(0x81C,0x33,&rx_data);
|
||||
SpiPs_write_read1(0x81D,0x14,&rx_data);
|
||||
SpiPs_write_read1(0x800,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x800,0x82,&rx_data);
|
||||
//最少0.1s
|
||||
usleep(500000);
|
||||
SpiPs_write_read1(0x77E,0x00,&rx_data);
|
||||
//恢复校准前设置
|
||||
SpiPs_write_read1(0x000,0x02,&rx_data);
|
||||
SpiPs_write_read1(0x02E,0x06,&rx_data);
|
||||
SpiPs_write_read1(0x03D,0x1B,&rx_data);
|
||||
SpiPs_write_read1(0x03E,0x39,&rx_data);
|
||||
SpiPs_write_read1(0x03F,0x27,&rx_data);
|
||||
SpiPs_write_read1(0x040,0xF8,&rx_data);
|
||||
SpiPs_write_read1(0x109,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x10A,0x70,&rx_data);
|
||||
SpiPs_write_read1(0x11B,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x11E,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x11F,0x33,&rx_data);
|
||||
SpiPs_write_read1(0x128,0x10,&rx_data);
|
||||
SpiPs_write_read1(0x161,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x162,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x164,0x05,&rx_data);
|
||||
SpiPs_write_read1(0x165,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x166,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x167,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x168,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x169,0x55,&rx_data);
|
||||
SpiPs_write_read1(0xA07,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA08,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA16,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA17,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA18,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA19,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1A,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1B,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1C,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA2D,0x00,&rx_data);
|
||||
usleep(1000);
|
||||
SpiPs_write_read2(0x615,0x00,&rx_data);
|
||||
temp=rx_data;
|
||||
SpiPs_write_read2(0x635,0x00,&rx_data);
|
||||
temp=rx_data;
|
||||
////配置Tx NCO BIST ON
|
||||
//SpiPs_write_read1(0x11B,0x01,&rx_data);
|
||||
//SpiPs_write_read1(0x11E,0x01,&rx_data);
|
||||
//SpiPs_write_read1(0x161,0x01,&rx_data);
|
||||
//SpiPs_write_read1(0x162,0x01,&rx_data);
|
||||
////配置Tx NCO频率 1MHz
|
||||
//SpiPs_write_read1(0x164,0x05,&rx_data);
|
||||
//SpiPs_write_read1(0x165,0x55,&rx_data);
|
||||
//SpiPs_write_read1(0x166,0x55,&rx_data);
|
||||
//SpiPs_write_read1(0x167,0x55,&rx_data);
|
||||
//SpiPs_write_read1(0x168,0x55,&rx_data);
|
||||
//SpiPs_write_read1(0x169,0x55,&rx_data);
|
||||
}
|
||||
+835
@@ -0,0 +1,835 @@
|
||||
/*
|
||||
* cx9261a_710_config.c
|
||||
*
|
||||
* Created on: 2024年3月21日
|
||||
* Author: cxlab
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* cx9261a_076_config.c
|
||||
*
|
||||
* Created on: 2023年11月30日
|
||||
* Author: cxlab
|
||||
*/
|
||||
|
||||
|
||||
#include "xilinx_io.h"
|
||||
#include "sleep.h"
|
||||
void cx9261a_710_config(void){
|
||||
u8 rx_data;
|
||||
u8 temp,r13D,r13E;
|
||||
|
||||
//setPin(pin,value)
|
||||
GpioSetPinDir(0,0x01);
|
||||
GpioWritePin(0,1);
|
||||
GpioSetPinDir(32,0x01);
|
||||
GpioWritePin(32,1);
|
||||
GpioSetPinDir(33,0x01);
|
||||
GpioWritePin(33,1);
|
||||
GpioSetPinDir(34,0x01);
|
||||
GpioWritePin(34,0);
|
||||
GpioSetPinDir(35,0x01); //tx:0-rx:1
|
||||
GpioWritePin(35,1); //tx:0-rx:1
|
||||
GpioSetPinDir(36,0x01); //fdd:0-tdd:1
|
||||
GpioWritePin(36,1); //fdd:0-tdd:1
|
||||
GpioSetPinDir(37,0x01); //1r1t:0-2r2t:1
|
||||
GpioWritePin(37,1); //1r1t:0-2r2t:1
|
||||
GpioSetPinDir(38,0x01); //dualport:0-singleport:1
|
||||
GpioWritePin(38,1); //dualport:0-singleport:1
|
||||
GpioSetPinDir(39,0x01);
|
||||
GpioWritePin(39,1);
|
||||
GpioSetPinDir(40,0x01);
|
||||
GpioWritePin(40,1);
|
||||
//配置芯片
|
||||
//初始化芯片
|
||||
SpiPs_write_read1(0x000,0x02,&rx_data);
|
||||
SpiPs_write_read1(0x773,0x53,&rx_data);
|
||||
SpiPs_write_read1(0x774,0x86,&rx_data);
|
||||
SpiPs_write_read1(0x781,0x6F,&rx_data);
|
||||
SpiPs_write_read1(0x70B,0x0E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x0E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x0E,&rx_data);
|
||||
SpiPs_write_read1(0x624,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x625,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x61E,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x61F,0x08,&rx_data);
|
||||
SpiPs_write_read1(0x621,0x4D,&rx_data);
|
||||
SpiPs_write_read1(0x622,0x19,&rx_data);
|
||||
SpiPs_write_read1(0x627,0x10,&rx_data);
|
||||
SpiPs_write_read1(0x646,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x647,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x640,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x641,0x08,&rx_data);
|
||||
SpiPs_write_read1(0x643,0x4D,&rx_data);
|
||||
SpiPs_write_read1(0x644,0x19,&rx_data);
|
||||
SpiPs_write_read1(0x649,0x10,&rx_data);
|
||||
SpiPs_write_read1(0x668,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x669,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x662,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x663,0x08,&rx_data);
|
||||
SpiPs_write_read1(0x665,0x4D,&rx_data);
|
||||
SpiPs_write_read1(0x666,0x19,&rx_data);
|
||||
SpiPs_write_read1(0x66B,0x10,&rx_data);
|
||||
SpiPs_write_read1(0x68A,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x68B,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x684,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x685,0x08,&rx_data);
|
||||
SpiPs_write_read1(0x687,0x4D,&rx_data);
|
||||
SpiPs_write_read1(0x688,0x19,&rx_data);
|
||||
SpiPs_write_read1(0x68D,0x10,&rx_data);
|
||||
SpiPs_write_read1(0x6AC,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x6AD,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x6A6,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x6A7,0x08,&rx_data);
|
||||
SpiPs_write_read1(0x6A9,0x4D,&rx_data);
|
||||
SpiPs_write_read1(0x6AA,0x19,&rx_data);
|
||||
SpiPs_write_read1(0x6AF,0x10,&rx_data);
|
||||
SpiPs_write_read1(0x705,0xFC,&rx_data);
|
||||
SpiPs_write_read1(0x706,0x6D,&rx_data);
|
||||
SpiPs_write_read1(0x707,0x91,&rx_data);
|
||||
SpiPs_write_read1(0x708,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x709,0x94,&rx_data);
|
||||
SpiPs_write_read1(0x70A,0xFC,&rx_data);
|
||||
SpiPs_write_read1(0x70C,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0x721,0xFC,&rx_data);
|
||||
SpiPs_write_read1(0x722,0x6D,&rx_data);
|
||||
SpiPs_write_read1(0x723,0x91,&rx_data);
|
||||
SpiPs_write_read1(0x724,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x725,0x94,&rx_data);
|
||||
SpiPs_write_read1(0x726,0xFC,&rx_data);
|
||||
SpiPs_write_read1(0x728,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0x73D,0xFC,&rx_data);
|
||||
SpiPs_write_read1(0x73E,0x6D,&rx_data);
|
||||
SpiPs_write_read1(0x73F,0x91,&rx_data);
|
||||
SpiPs_write_read1(0x740,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x741,0x94,&rx_data);
|
||||
SpiPs_write_read1(0x742,0xFC,&rx_data);
|
||||
SpiPs_write_read1(0x744,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0x75A,0x83,&rx_data);
|
||||
SpiPs_write_read1(0x75B,0xDA,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x75B,0x9A,&rx_data);
|
||||
SpiPs_write_read1(0x75C,0x81,&rx_data);
|
||||
SpiPs_write_read1(0x763,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x764,0x83,&rx_data);
|
||||
SpiPs_write_read1(0x765,0xDA,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x765,0x9A,&rx_data);
|
||||
SpiPs_write_read1(0x766,0x81,&rx_data);
|
||||
SpiPs_write_read1(0x76D,0x04,&rx_data);
|
||||
//初始化电源
|
||||
SpiPs_write_read1(0x031,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x032,0x7F,&rx_data);
|
||||
SpiPs_write_read1(0x033,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x034,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x035,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x036,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x037,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x038,0xFB,&rx_data);
|
||||
SpiPs_write_read1(0x039,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x03A,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x03B,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x03C,0xF8,&rx_data);
|
||||
SpiPs_write_read1(0x03D,0x1B,&rx_data);
|
||||
SpiPs_write_read1(0x03E,0x39,&rx_data);
|
||||
SpiPs_write_read1(0x03F,0x26,&rx_data);
|
||||
SpiPs_write_read1(0x040,0x78,&rx_data);
|
||||
SpiPs_write_read1(0x041,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x042,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x043,0xE7,&rx_data);
|
||||
SpiPs_write_read1(0x044,0xF8,&rx_data);
|
||||
SpiPs_write_read1(0x045,0x18,&rx_data);
|
||||
SpiPs_write_read1(0x046,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x047,0x3F,&rx_data);
|
||||
SpiPs_write_read1(0x048,0xF8,&rx_data);
|
||||
SpiPs_write_read1(0x049,0x1F,&rx_data);
|
||||
SpiPs_write_read1(0x04A,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x04B,0x07,&rx_data);
|
||||
SpiPs_write_read1(0x04C,0xF8,&rx_data);
|
||||
SpiPs_write_read1(0x04D,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x04E,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x04F,0xD9,&rx_data);
|
||||
SpiPs_write_read1(0x050,0xFE,&rx_data);
|
||||
//自定义接收模式
|
||||
SpiPs_write_read1(0x041,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x042,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x043,0xE7,&rx_data);
|
||||
SpiPs_write_read1(0x044,0xF8,&rx_data);
|
||||
//自定义发射模式
|
||||
SpiPs_write_read1(0x045,0x18,&rx_data);
|
||||
SpiPs_write_read1(0x046,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x047,0x3F,&rx_data);
|
||||
SpiPs_write_read1(0x048,0xF8,&rx_data);
|
||||
//自定义FDD模式
|
||||
SpiPs_write_read1(0x049,0x1B,&rx_data);
|
||||
SpiPs_write_read1(0x04A,0x3D,&rx_data);
|
||||
SpiPs_write_read1(0x04B,0x27,&rx_data);
|
||||
SpiPs_write_read1(0x04C,0xF8,&rx_data);
|
||||
//配置BBPLL
|
||||
SpiPs_write_read1(0x789,0x10,&rx_data);
|
||||
SpiPs_write_read1(0x785,0x49,&rx_data);
|
||||
SpiPs_write_read1(0x788,0x24,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x788,0xA4,&rx_data);
|
||||
SpiPs_write_read1(0x0C0,0x50,&rx_data);
|
||||
SpiPs_write_read1(0x0C1,0x50,&rx_data);
|
||||
SpiPs_write_read1(0x0C2,0x50,&rx_data);
|
||||
SpiPs_write_read1(0x601,0x0F,&rx_data);
|
||||
SpiPs_write_read1(0x602,0x21,&rx_data);
|
||||
SpiPs_write_read1(0x60D,0x0D,&rx_data);
|
||||
SpiPs_write_read1(0x60E,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x60F,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x610,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x611,0x2F,&rx_data);
|
||||
SpiPs_write_read1(0x612,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x70E,0x6B,&rx_data);
|
||||
SpiPs_write_read1(0x72A,0x6B,&rx_data);
|
||||
SpiPs_write_read1(0x746,0x6B,&rx_data);
|
||||
SpiPs_write_read1(0x70F,0xE0,&rx_data);
|
||||
SpiPs_write_read1(0x72B,0xE0,&rx_data);
|
||||
SpiPs_write_read1(0x747,0xE0,&rx_data);
|
||||
SpiPs_write_read1(0x70D,0x43,&rx_data);
|
||||
SpiPs_write_read1(0x729,0x43,&rx_data);
|
||||
SpiPs_write_read1(0x745,0x43,&rx_data);
|
||||
SpiPs_write_read1(0x782,0x76,&rx_data);
|
||||
SpiPs_write_read1(0x783,0x76,&rx_data);
|
||||
SpiPs_write_read1(0x784,0x06,&rx_data);
|
||||
//配置PLL来源
|
||||
SpiPs_write_read1(0x77D,0xCF,&rx_data);
|
||||
SpiPs_write_read1(0x775,0x24,&rx_data);
|
||||
SpiPs_write_read1(0x6C3,0x00,&rx_data);
|
||||
//配置PLL1
|
||||
SpiPs_write_read1(0x620,0x91,&rx_data);
|
||||
SpiPs_write_read1(0x61D,0x37,&rx_data);
|
||||
SpiPs_write_read1(0xB06,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB07,0xCB,&rx_data);
|
||||
SpiPs_write_read1(0xB08,0x20,&rx_data);
|
||||
SpiPs_write_read1(0xB09,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB0A,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x61A,0x0C,&rx_data);
|
||||
SpiPs_write_read1(0x61B,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x61C,0x08,&rx_data);
|
||||
SpiPs_write_read1(0x62A,0x0B,&rx_data);
|
||||
//配置PLL2
|
||||
SpiPs_write_read1(0x642,0x91,&rx_data);
|
||||
SpiPs_write_read1(0x63F,0x35,&rx_data);
|
||||
SpiPs_write_read1(0xB14,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB15,0xFA,&rx_data);
|
||||
SpiPs_write_read1(0xB16,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB17,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB18,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x63C,0x0D,&rx_data);
|
||||
SpiPs_write_read1(0x63D,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x63E,0x0B,&rx_data);
|
||||
SpiPs_write_read1(0x64C,0x00,&rx_data);
|
||||
//配置PLL3
|
||||
SpiPs_write_read1(0x664,0x81,&rx_data);
|
||||
SpiPs_write_read1(0x661,0x36,&rx_data);
|
||||
SpiPs_write_read1(0xB22,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB23,0xBB,&rx_data);
|
||||
SpiPs_write_read1(0xB24,0x80,&rx_data);
|
||||
SpiPs_write_read1(0xB25,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB26,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x65E,0x0B,&rx_data);
|
||||
SpiPs_write_read1(0x65F,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x660,0x0E,&rx_data);
|
||||
SpiPs_write_read1(0x66E,0x0B,&rx_data);
|
||||
//配置PLL4
|
||||
SpiPs_write_read1(0x686,0x91,&rx_data);
|
||||
SpiPs_write_read1(0x683,0x36,&rx_data);
|
||||
SpiPs_write_read1(0xB30,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB31,0xDA,&rx_data);
|
||||
SpiPs_write_read1(0xB32,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0xB33,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB34,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x680,0x0C,&rx_data);
|
||||
SpiPs_write_read1(0x681,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x682,0x08,&rx_data);
|
||||
SpiPs_write_read1(0x690,0x0B,&rx_data);
|
||||
//配置PLL5
|
||||
SpiPs_write_read1(0x6A8,0x81,&rx_data);
|
||||
SpiPs_write_read1(0x6A5,0x36,&rx_data);
|
||||
SpiPs_write_read1(0xB3E,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB3F,0x9C,&rx_data);
|
||||
SpiPs_write_read1(0xB40,0x40,&rx_data);
|
||||
SpiPs_write_read1(0xB41,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB42,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x6A2,0x0C,&rx_data);
|
||||
SpiPs_write_read1(0x6A3,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x6A4,0x0C,&rx_data);
|
||||
SpiPs_write_read1(0x6B2,0x0B,&rx_data);
|
||||
//配置Tx1通道频率相关寄存器
|
||||
SpiPs_write_read1(0x75F,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x761,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x762,0x70,&rx_data);
|
||||
//配置Tx1通道频率相关寄存器
|
||||
SpiPs_write_read1(0x769,0x55,&rx_data);
|
||||
SpiPs_write_read1(0x76B,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x76C,0x70,&rx_data);
|
||||
//配置Rx1通道
|
||||
SpiPs_write_read1(0x700,0x56,&rx_data);
|
||||
SpiPs_write_read1(0x701,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x702,0xDB,&rx_data);
|
||||
SpiPs_write_read1(0x703,0x45,&rx_data);
|
||||
SpiPs_write_read1(0x704,0xF8,&rx_data);
|
||||
SpiPs_write_read1(0x907,0x1F,&rx_data);
|
||||
//配置Rx2通道
|
||||
SpiPs_write_read1(0x71C,0x56,&rx_data);
|
||||
SpiPs_write_read1(0x71D,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x71E,0xDB,&rx_data);
|
||||
SpiPs_write_read1(0x71F,0x45,&rx_data);
|
||||
SpiPs_write_read1(0x720,0xF8,&rx_data);
|
||||
SpiPs_write_read1(0x907,0x1F,&rx_data);
|
||||
//配置Rx3通道
|
||||
SpiPs_write_read1(0x738,0x56,&rx_data);
|
||||
SpiPs_write_read1(0x739,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x73A,0xDB,&rx_data);
|
||||
SpiPs_write_read1(0x73B,0x45,&rx_data);
|
||||
SpiPs_write_read1(0x73C,0xF8,&rx_data);
|
||||
SpiPs_write_read1(0x907,0x1F,&rx_data);
|
||||
//配置Tx1通道
|
||||
SpiPs_write_read1(0x75E,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x75D,0x4A,&rx_data);
|
||||
SpiPs_write_read1(0x75F,0x7D,&rx_data);
|
||||
SpiPs_write_read1(0x760,0xFF,&rx_data);
|
||||
//配置Tx2通道
|
||||
SpiPs_write_read1(0x768,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x767,0x4A,&rx_data);
|
||||
SpiPs_write_read1(0x769,0x7D,&rx_data);
|
||||
SpiPs_write_read1(0x76A,0xFF,&rx_data);
|
||||
//配置Rx滤波器
|
||||
SpiPs_write_read1(0x106,0x02,&rx_data);
|
||||
//配置Tx滤波器
|
||||
SpiPs_write_read1(0x107,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x108,0xD0,&rx_data);
|
||||
//配置Rx混频器
|
||||
SpiPs_write_read1(0x11C,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA07,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA08,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA09,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA16,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA17,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA18,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA19,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1A,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1B,0x00,&rx_data);
|
||||
//配置Tx混频器
|
||||
SpiPs_write_read1(0x128,0x10,&rx_data);
|
||||
SpiPs_write_read1(0x11B,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x11E,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x161,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x162,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x164,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x165,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x166,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x167,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x168,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x169,0x00,&rx_data);
|
||||
//配置AGC
|
||||
SpiPs_write_read1(0x903,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x900,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x901,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x908,0x77,&rx_data);
|
||||
SpiPs_write_read1(0x909,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x90A,0x32,&rx_data);
|
||||
SpiPs_write_read1(0x90D,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x90E,0x0F,&rx_data);
|
||||
SpiPs_write_read1(0x90F,0x65,&rx_data);
|
||||
SpiPs_write_read1(0x910,0x32,&rx_data);
|
||||
SpiPs_write_read1(0x911,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x912,0x0F,&rx_data);
|
||||
SpiPs_write_read1(0x913,0x3A,&rx_data);
|
||||
SpiPs_write_read1(0x914,0x37,&rx_data);
|
||||
SpiPs_write_read1(0x915,0x34,&rx_data);
|
||||
SpiPs_write_read1(0x916,0x31,&rx_data);
|
||||
//切换到休眠模式
|
||||
SpiPs_write_read1(0x02E,0x01,&rx_data);
|
||||
usleep(1000000);
|
||||
//切换到校准模式
|
||||
SpiPs_write_read1(0x02E,0x03,&rx_data);
|
||||
usleep(100000);
|
||||
//BBPll锁定
|
||||
SpiPs_write_read1(0x600,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x600,0x11,&rx_data);
|
||||
usleep(100000);
|
||||
//BBPll锁定 成功
|
||||
//ADC校准
|
||||
SpiPs_write_read1(0x70B,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x70F,0xE0,&rx_data);
|
||||
SpiPs_write_read1(0x710,0x83,&rx_data);
|
||||
SpiPs_write_read1(0x711,0xF0,&rx_data);
|
||||
SpiPs_write_read1(0x72B,0xE0,&rx_data);
|
||||
SpiPs_write_read1(0x72C,0x83,&rx_data);
|
||||
SpiPs_write_read1(0x72D,0xF0,&rx_data);
|
||||
SpiPs_write_read1(0x747,0xE0,&rx_data);
|
||||
SpiPs_write_read1(0x748,0x83,&rx_data);
|
||||
SpiPs_write_read1(0x749,0xF0,&rx_data);
|
||||
SpiPs_write_read1(0x713,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x72F,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x74B,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x70B,0x9E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x9E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x9E,&rx_data);
|
||||
SpiPs_write_read1(0x70B,0x9A,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x9A,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x9A,&rx_data);
|
||||
SpiPs_write_read1(0x70B,0x9E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x9E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x9E,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x70B,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x713,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0x72F,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0x74B,0xC0,&rx_data);
|
||||
//flash校准
|
||||
SpiPs_write_read1(0x70B,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x715,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x731,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x74D,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x715,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0x731,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0x74D,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0x716,0x40,&rx_data);
|
||||
SpiPs_write_read1(0x732,0x40,&rx_data);
|
||||
SpiPs_write_read1(0x74E,0x40,&rx_data);
|
||||
SpiPs_write_read1(0x70B,0x16,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x16,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x16,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x70B,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x727,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x743,0x1E,&rx_data);
|
||||
SpiPs_write_read1(0x715,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x731,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x74D,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x716,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x732,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x74E,0x00,&rx_data);
|
||||
//DC Tracking
|
||||
SpiPs_write_read1(0x109,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x10A,0x70,&rx_data);
|
||||
SpiPs_write_read1(0x11F,0x33,&rx_data);
|
||||
//Rx1 QEC校准
|
||||
SpiPs_write_read1(0x02E,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x03F,0x26,&rx_data);
|
||||
SpiPs_write_read1(0x040,0x78,&rx_data);
|
||||
SpiPs_write_read1(0x77D,0x90,&rx_data);
|
||||
SpiPs_write_read1(0x775,0x24,&rx_data);
|
||||
SpiPs_write_read1(0x6C3,0x05,&rx_data);
|
||||
SpiPs_write_read1(0x61D,0x27,&rx_data);
|
||||
SpiPs_write_read1(0x617,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x617,0x03,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x61D,0x37,&rx_data);
|
||||
SpiPs_write_read1(0x686,0x81,&rx_data);
|
||||
SpiPs_write_read1(0x683,0x36,&rx_data);
|
||||
SpiPs_write_read1(0xB30,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB31,0x87,&rx_data);
|
||||
SpiPs_write_read1(0xB32,0x04,&rx_data);
|
||||
SpiPs_write_read1(0xB33,0x44,&rx_data);
|
||||
SpiPs_write_read1(0xB34,0x44,&rx_data);
|
||||
SpiPs_write_read1(0x680,0x0C,&rx_data);
|
||||
SpiPs_write_read1(0x681,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x682,0x0C,&rx_data);
|
||||
SpiPs_write_read1(0x690,0x0B,&rx_data);
|
||||
SpiPs_write_read1(0x683,0x26,&rx_data);
|
||||
SpiPs_write_read1(0x67D,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x67D,0x03,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x683,0x36,&rx_data);
|
||||
SpiPs_write_read1(0x000,0x12,&rx_data);
|
||||
SpiPs_write_read1(0x77E,0x50,&rx_data);
|
||||
SpiPs_write_read1(0x11B,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x11E,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x164,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x165,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x166,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x167,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x168,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x169,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x161,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x162,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x162,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x161,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x706,0x65,&rx_data);
|
||||
SpiPs_write_read1(0x6C3,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x75F,0x7D,&rx_data);
|
||||
SpiPs_write_read1(0x11F,0x73,&rx_data);
|
||||
SpiPs_write_read1(0x153,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x708,0x24,&rx_data);
|
||||
SpiPs_write_read1(0x196,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x02A,0x12,&rx_data);
|
||||
|
||||
do{
|
||||
usleep(100);
|
||||
SpiPs_write_read2(0x14D,0x00,&rx_data);
|
||||
temp=rx_data&0x10;
|
||||
}while (temp != 16);
|
||||
|
||||
SpiPs_write_read1(0x02A,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x196,0x11,&rx_data);
|
||||
SpiPs_write_read2(0x13D,0x00,&rx_data);
|
||||
r13D = rx_data;
|
||||
SpiPs_write_read2(0x13E,0x00,&rx_data);
|
||||
r13E = rx_data;
|
||||
|
||||
unsigned long B = r13D * 256 + r13E;
|
||||
signed long B_s = B - (B >= 32768) * 65536;
|
||||
unsigned long B_abs = abs(B_s);
|
||||
unsigned short B_b = (unsigned short)B_abs;
|
||||
unsigned short B_delay = (B_b>>6) & 0x1ff;
|
||||
|
||||
if(B_s > 0)
|
||||
{
|
||||
SpiPs_write_read1(0x199, ((B_delay>>8)&0x1),&rx_data);
|
||||
SpiPs_write_read1(0x19A, B_delay&0xff,&rx_data);
|
||||
SpiPs_write_read1(0x19B, 0,&rx_data);
|
||||
SpiPs_write_read1(0x19C, 0,&rx_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
SpiPs_write_read1(0x199, 0,&rx_data);
|
||||
SpiPs_write_read1(0x19A, 0,&rx_data);
|
||||
SpiPs_write_read1(0x19B, ((B_delay>>8)&0x1),&rx_data);
|
||||
SpiPs_write_read1(0x19C, B_delay&0xff,&rx_data);
|
||||
}
|
||||
|
||||
SpiPs_write_read1(0x196,0x10,&rx_data);
|
||||
SpiPs_write_read1(0x153,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x02A,0x12,&rx_data);
|
||||
|
||||
do{
|
||||
usleep(100);
|
||||
SpiPs_write_read2(0x14D,0x00,&rx_data);
|
||||
temp=rx_data&0x10;
|
||||
}while (temp != 16);
|
||||
|
||||
SpiPs_write_read1(0x02A,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x77E,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x000,0x02,&rx_data);
|
||||
//Rx2 QEC校准
|
||||
SpiPs_write_read1(0x02E,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x03F,0x26,&rx_data);
|
||||
SpiPs_write_read1(0x040,0x78,&rx_data);
|
||||
SpiPs_write_read1(0x77D,0x60,&rx_data);
|
||||
SpiPs_write_read1(0x775,0x24,&rx_data);
|
||||
SpiPs_write_read1(0x6C3,0x0A,&rx_data);
|
||||
SpiPs_write_read1(0x61D,0x27,&rx_data);
|
||||
SpiPs_write_read1(0x617,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x617,0x03,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x61D,0x37,&rx_data);
|
||||
SpiPs_write_read1(0x686,0x81,&rx_data);
|
||||
SpiPs_write_read1(0x683,0x36,&rx_data);
|
||||
SpiPs_write_read1(0xB30,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB31,0x87,&rx_data);
|
||||
SpiPs_write_read1(0xB32,0x04,&rx_data);
|
||||
SpiPs_write_read1(0xB33,0x44,&rx_data);
|
||||
SpiPs_write_read1(0xB34,0x44,&rx_data);
|
||||
SpiPs_write_read1(0x680,0x0C,&rx_data);
|
||||
SpiPs_write_read1(0x681,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x682,0x0C,&rx_data);
|
||||
SpiPs_write_read1(0x690,0x0B,&rx_data);
|
||||
SpiPs_write_read1(0x683,0x26,&rx_data);
|
||||
SpiPs_write_read1(0x67D,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x67D,0x03,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x683,0x36,&rx_data);
|
||||
SpiPs_write_read1(0x000,0x22,&rx_data);
|
||||
SpiPs_write_read1(0x77E,0x0A,&rx_data);
|
||||
SpiPs_write_read1(0x11B,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x11E,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x164,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x165,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x166,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x167,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x168,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x169,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x161,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x162,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x162,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x161,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x706,0x65,&rx_data);
|
||||
SpiPs_write_read1(0x6C3,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x75F,0x7D,&rx_data);
|
||||
SpiPs_write_read1(0x11F,0x73,&rx_data);
|
||||
SpiPs_write_read1(0x153,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x724,0x24,&rx_data);
|
||||
SpiPs_write_read1(0x196,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x02B,0x12,&rx_data);
|
||||
|
||||
do{
|
||||
usleep(100);
|
||||
SpiPs_write_read2(0x14D,0x00,&rx_data);
|
||||
temp=rx_data&0x10;
|
||||
}while (temp != 16);
|
||||
|
||||
SpiPs_write_read1(0x02B,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x196,0x11,&rx_data);
|
||||
SpiPs_write_read2(0x13D,0x00,&rx_data);
|
||||
r13D = rx_data;
|
||||
SpiPs_write_read2(0x13E,0x00,&rx_data);
|
||||
r13E = rx_data;
|
||||
|
||||
B = r13D * 256 + r13E;
|
||||
B_s = B - (B >= 32768) * 65536;
|
||||
B_abs = abs(B_s);
|
||||
B_b = (unsigned short)B_abs;
|
||||
B_delay = (B_b>>6) & 0x1ff;
|
||||
|
||||
if(B_s > 0)
|
||||
{
|
||||
SpiPs_write_read1(0x199, ((B_delay>>8)&0x1),&rx_data);
|
||||
SpiPs_write_read1(0x19A, B_delay&0xff,&rx_data);
|
||||
SpiPs_write_read1(0x19B, 0,&rx_data);
|
||||
SpiPs_write_read1(0x19C, 0,&rx_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
SpiPs_write_read1(0x199, 0,&rx_data);
|
||||
SpiPs_write_read1(0x19A, 0,&rx_data);
|
||||
SpiPs_write_read1(0x19B, ((B_delay>>8)&0x1),&rx_data);
|
||||
SpiPs_write_read1(0x19C, B_delay&0xff,&rx_data);
|
||||
}
|
||||
|
||||
SpiPs_write_read1(0x196,0x10,&rx_data);
|
||||
SpiPs_write_read1(0x153,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x02B,0x12,&rx_data);
|
||||
|
||||
do{
|
||||
usleep(100);
|
||||
SpiPs_write_read2(0x14D,0x00,&rx_data);
|
||||
temp=rx_data&0x10;
|
||||
}while (temp != 16);
|
||||
|
||||
SpiPs_write_read1(0x02B,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x77E,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x000,0x02,&rx_data);
|
||||
//恢复校准中被改变的配置
|
||||
SpiPs_write_read1(0x000,0x02,&rx_data);
|
||||
SpiPs_write_read1(0x02E,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x109,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x10A,0x70,&rx_data);
|
||||
SpiPs_write_read1(0x11B,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x11E,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x11F,0x33,&rx_data);
|
||||
SpiPs_write_read1(0x128,0x10,&rx_data);
|
||||
SpiPs_write_read1(0x161,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x162,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x164,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x165,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x166,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x167,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x168,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x169,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x6C3,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x775,0x24,&rx_data);
|
||||
SpiPs_write_read1(0x77D,0xCF,&rx_data);
|
||||
SpiPs_write_read1(0xA07,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA08,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA16,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA17,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA18,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA19,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1A,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1B,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x686,0x91,&rx_data);
|
||||
SpiPs_write_read1(0x683,0x36,&rx_data);
|
||||
SpiPs_write_read1(0xB30,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB31,0xDA,&rx_data);
|
||||
SpiPs_write_read1(0xB32,0xC0,&rx_data);
|
||||
SpiPs_write_read1(0xB33,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xB34,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x680,0x0C,&rx_data);
|
||||
SpiPs_write_read1(0x681,0x30,&rx_data);
|
||||
SpiPs_write_read1(0x682,0x08,&rx_data);
|
||||
SpiPs_write_read1(0x690,0x0B,&rx_data);
|
||||
//TX校准
|
||||
SpiPs_write_read1(0x03F,0x27,&rx_data);
|
||||
SpiPs_write_read1(0x040,0xF8,&rx_data);
|
||||
SpiPs_write_read1(0x61D,0x27,&rx_data);
|
||||
SpiPs_write_read1(0x617,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x617,0x03,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x61D,0x37,&rx_data);
|
||||
SpiPs_write_read1(0x02E,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x128,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x11E,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x77E,0x24,&rx_data);
|
||||
SpiPs_write_read1(0x11F,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x121,0x02,&rx_data);
|
||||
SpiPs_write_read1(0x11B,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x161,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x162,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x163,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x164,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x165,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x166,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x167,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x168,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x169,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA2D,0x02,&rx_data);
|
||||
SpiPs_write_read1(0xA07,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA08,0x0F,&rx_data);
|
||||
SpiPs_write_read1(0xA1C,0x01,&rx_data);
|
||||
SpiPs_write_read1(0xA16,0x20,&rx_data);
|
||||
SpiPs_write_read1(0xA17,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA18,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA19,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1A,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1B,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x102,0x0F,&rx_data);
|
||||
SpiPs_write_read1(0x102,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x186,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x186,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x763,0x34,&rx_data);
|
||||
SpiPs_write_read1(0x76D,0x34,&rx_data);
|
||||
SpiPs_write_read1(0x101,0xEF,&rx_data);
|
||||
SpiPs_write_read1(0x101,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x800,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x81A,0xF7,&rx_data);
|
||||
SpiPs_write_read1(0x81B,0x34,&rx_data);
|
||||
SpiPs_write_read1(0x81C,0x33,&rx_data);
|
||||
SpiPs_write_read1(0x81D,0x12,&rx_data);
|
||||
SpiPs_write_read1(0x81E,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x81F,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x820,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x821,0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x800,0x80,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x800,0x81,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x77E,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x77E,0x24,&rx_data);
|
||||
SpiPs_write_read1(0x11F,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x121,0x02,&rx_data);
|
||||
SpiPs_write_read1(0x11B,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x11E,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x161,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x162,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x164,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x165,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x166,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x167,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x168,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x169,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA2D,0x02,&rx_data);
|
||||
SpiPs_write_read1(0xA07,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA08,0x0F,&rx_data);
|
||||
SpiPs_write_read1(0xA1C,0x01,&rx_data);
|
||||
SpiPs_write_read1(0xA16,0x10,&rx_data);
|
||||
SpiPs_write_read1(0xA17,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA18,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA19,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1A,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1B,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x81A,0xF7,&rx_data);
|
||||
SpiPs_write_read1(0x81B,0x44,&rx_data);
|
||||
SpiPs_write_read1(0x81C,0x33,&rx_data);
|
||||
SpiPs_write_read1(0x81D,0x14,&rx_data);
|
||||
SpiPs_write_read1(0x800,0x80,&rx_data);
|
||||
SpiPs_write_read1(0x800,0x82,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x77E,0x00,&rx_data);
|
||||
//恢复校准中被改变的配置
|
||||
SpiPs_write_read1(0x000,0x02,&rx_data);
|
||||
SpiPs_write_read1(0x02E,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x109,0x11,&rx_data);
|
||||
SpiPs_write_read1(0x10A,0x70,&rx_data);
|
||||
SpiPs_write_read1(0x11B,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x11E,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x11F,0x33,&rx_data);
|
||||
SpiPs_write_read1(0x128,0x10,&rx_data);
|
||||
SpiPs_write_read1(0x161,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x162,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x164,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x165,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x166,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x167,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x168,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x169,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x6C3,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x775,0x24,&rx_data);
|
||||
SpiPs_write_read1(0x77D,0xCF,&rx_data);
|
||||
SpiPs_write_read1(0xA07,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA08,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA16,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA17,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA18,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA19,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1A,0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA1B,0x00,&rx_data);
|
||||
//Pll1锁定
|
||||
SpiPs_write_read1(0x61D,0x27,&rx_data);
|
||||
SpiPs_write_read1(0x617,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x617,0x03,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x61D,0x37,&rx_data);
|
||||
//Pll1锁定 成功
|
||||
//Pll2锁定
|
||||
SpiPs_write_read1(0x63F,0x25,&rx_data);
|
||||
SpiPs_write_read1(0x639,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x639,0x03,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x63F,0x35,&rx_data);
|
||||
//Pll2锁定 成功
|
||||
//Pll3锁定
|
||||
SpiPs_write_read1(0x661,0x26,&rx_data);
|
||||
SpiPs_write_read1(0x65B,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x65B,0x03,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x661,0x36,&rx_data);
|
||||
//Pll3锁定 成功
|
||||
//Pll4锁定
|
||||
SpiPs_write_read1(0x683,0x26,&rx_data);
|
||||
SpiPs_write_read1(0x67D,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x67D,0x03,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x683,0x36,&rx_data);
|
||||
//Pll4锁定 成功
|
||||
//Pll5锁定
|
||||
SpiPs_write_read1(0x6A5,0x26,&rx_data);
|
||||
SpiPs_write_read1(0x69F,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x69F,0x03,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x6A5,0x36,&rx_data);
|
||||
//Pll5锁定 成功
|
||||
//配置接口
|
||||
SpiPs_write_read1(0x02E,0x05,&rx_data);
|
||||
SpiPs_write_read1(0x003,0x33,&rx_data);
|
||||
SpiPs_write_read1(0x200,0x01,&rx_data);
|
||||
SpiPs_write_read1(0x201,0x3F,&rx_data);
|
||||
SpiPs_write_read1(0x202,0x03,&rx_data);
|
||||
SpiPs_write_read1(0x206,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x208,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x209,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x77F,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x780,0x33,&rx_data);
|
||||
SpiPs_write_read1(0x781,0x6F,&rx_data);
|
||||
//配置结束
|
||||
|
||||
SpiPs_write_read1(0x02E,0x04,&rx_data);
|
||||
SpiPs_write_read1(0x780,0x00,&rx_data);
|
||||
|
||||
SpiPs_write_read1(0x11F,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x11F,0x33,&rx_data);
|
||||
////配置Tx NCO BIST ON
|
||||
//SpiPs_write_read1(0x11B,0x01,&rx_data);
|
||||
//SpiPs_write_read1(0x11E,0x01,&rx_data);
|
||||
//SpiPs_write_read1(0x161,0x01,&rx_data);
|
||||
//SpiPs_write_read1(0x162,0x01,&rx_data);
|
||||
////配置Tx NCO频率 1MHz
|
||||
//SpiPs_write_read1(0x164,0x05,&rx_data);
|
||||
//SpiPs_write_read1(0x165,0x55,&rx_data);
|
||||
//SpiPs_write_read1(0x166,0x55,&rx_data);
|
||||
//SpiPs_write_read1(0x167,0x55,&rx_data);
|
||||
//SpiPs_write_read1(0x168,0x55,&rx_data);
|
||||
//SpiPs_write_read1(0x169,0x55,&rx_data);
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* download_bin.c
|
||||
*
|
||||
* Created on: 2023年11月23日
|
||||
* Author: cxlab
|
||||
*/
|
||||
|
||||
#include "xilinx_io.h"
|
||||
#include "sleep.h"
|
||||
void download_bin(void){
|
||||
|
||||
int temp;
|
||||
u8 rx_data;
|
||||
u8 data[4];
|
||||
u32 buf;
|
||||
u8 addr[2];
|
||||
int on = 1;
|
||||
if (on) {
|
||||
SpiPs_write_read1(0x079,0x00,&rx_data);//关闭CRC校验
|
||||
SpiPs_write_read1(0x071,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x071,0x09,&rx_data);
|
||||
// SpiPs_write_read1(0x236,0x0F,&rx_data);
|
||||
// SpiPs_write_read1(0x20A,0x01,&rx_data);
|
||||
for(int i=0;i<5507;i++){
|
||||
addr[0]=(i>>8)&0xff;
|
||||
addr[1]= i&0xff;
|
||||
buf=rom_read((u8 *)&addr);
|
||||
data[0]=buf>>24;
|
||||
data[1]=(buf>>16)&0xff;
|
||||
data[2]=(buf>>8)&0xff;
|
||||
data[3]=buf&0xff;
|
||||
for(int j=0;j<4;j++){
|
||||
SpiPs_write_read1(0x070,data[j],&rx_data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SpiPs_write_read1(0x071,0x1A,&rx_data);//开启CRC校验
|
||||
SpiPs_write_read1(0x079,0x08,&rx_data);//开启CRC校验
|
||||
usleep(1000);
|
||||
SpiPs_write_read2(0x078,0x00,&rx_data);
|
||||
temp=rx_data;
|
||||
|
||||
if (temp == 0x01) {
|
||||
xil_printf("CRC successful");
|
||||
}
|
||||
else {
|
||||
xil_printf("CRC unsuccessful");
|
||||
}
|
||||
SpiPs_write_read1(0x071,0x06,&rx_data);//处理器门控时钟使能
|
||||
usleep(10000);
|
||||
SpiPs_write_read2(0x0A7,0x00,&rx_data);//处理器运行成果标志
|
||||
temp=rx_data;
|
||||
|
||||
if (temp == 0x11) {
|
||||
xil_printf("core run successful");
|
||||
}
|
||||
else {
|
||||
xil_printf("core run unsuccessful");
|
||||
}
|
||||
////////////////////dpd系数加载////////////////////
|
||||
SpiPs_write_read1(0x302,0xDF,&rx_data);
|
||||
SpiPs_write_read1(0x0A3,0x52,&rx_data);
|
||||
usleep(200000);
|
||||
SpiPs_write_read2(0x0A7,0x00,&rx_data);//dpd系数加载完成标志
|
||||
temp=rx_data;
|
||||
|
||||
if (temp == 0x61) {
|
||||
xil_printf("dpd index load successful");
|
||||
}
|
||||
else {
|
||||
xil_printf("dpd index load unsuccessful");
|
||||
}
|
||||
}
|
||||
else {
|
||||
SpiPs_write_read1(0x071,0x00,&rx_data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,461 @@
|
||||
/*
|
||||
* Copyright (C) 2016 - 2018 Xilinx, 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:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 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 <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lwip/sockets.h"
|
||||
#include "netif/xadapter.h"
|
||||
#include "lwipopts.h"
|
||||
#include "xil_printf.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "xilinx_io.h"
|
||||
|
||||
#define THREAD_STACKSIZE 1024
|
||||
#define ACK 0x01
|
||||
u16_t echo_port = 7;
|
||||
//#define RECV_BUF_SIZE 65536*16*8
|
||||
#define RECV_BUF_SIZE 1024
|
||||
//char recv_buf[RECV_BUF_SIZE];
|
||||
char recv_buf[1024];
|
||||
char recv_buf_temp[3];
|
||||
char trans_buf[8192*5];
|
||||
struct spi_stack spistack;
|
||||
|
||||
|
||||
u16 hop_cnt = 0;
|
||||
|
||||
void print_echo_app_header()
|
||||
{
|
||||
xil_printf("%20s %6d %s\r\n", "echo server",
|
||||
echo_port,
|
||||
"$ telnet <board_ip> 7");
|
||||
|
||||
}
|
||||
|
||||
|
||||
enum {
|
||||
CMD_VER = 0,
|
||||
CMD_RST = 1,
|
||||
CMD_SPI_WRI = 2 ,
|
||||
CMD_SPI_READ = 3,
|
||||
CMD_DATA_CAPTURE0 = 4,
|
||||
CMD_WAVE_DOWNLOAD = 5,
|
||||
CMD_PIN_SET = 6,
|
||||
CMD_DATA_CAPTURE1 = 8,
|
||||
CMD_DATA_CAPTURE2 = 9,
|
||||
CMD_STACK_OUT = 10,
|
||||
CMD_hopping = 11,
|
||||
CMD_qecbin = 12,
|
||||
CMD_cx9261a_config = 13,
|
||||
CMD_cx3e04_config = 14,
|
||||
CMD_cx3e04_SPI_WRI = 15 ,
|
||||
CMD_cx3e04_SPI_READ = 16,
|
||||
CMD_IMAGE_UPDATE = 22,
|
||||
};
|
||||
/* thread spawned for each connection */
|
||||
void process_echo_request(void *p)
|
||||
{
|
||||
int sd = (int)p;
|
||||
int status;
|
||||
int n, nwrote,send_n,total_send;
|
||||
u8 rx_data;
|
||||
u32 capture_length;
|
||||
u8 pin;
|
||||
u8 pin_value;
|
||||
char FPGA_SDK_IP[]="FPGA:20240513-SDK:20240514";
|
||||
spistack.spi_write_num = 0;
|
||||
while (1) {
|
||||
/* read a max of RECV_BUF_SIZE bytes from socket */
|
||||
if ((n = read(sd, recv_buf, 5)) < 0) {
|
||||
xil_printf("%s: error reading from socket %d, closing socket\r\n", __FUNCTION__, sd);
|
||||
break;
|
||||
}
|
||||
|
||||
/* break if the recved message = "quit" */
|
||||
if (!strncmp(recv_buf, "quit", 4))
|
||||
break;
|
||||
|
||||
/* break if client closed connection */
|
||||
if (n <= 0)
|
||||
break;
|
||||
|
||||
else{/* excute cmd if recved message = "cmd"*/
|
||||
n=0;
|
||||
if (!strncmp(recv_buf, "cmd ", 4)){
|
||||
// xil_printf("%d %d %d %d.\r\n", recv_buf[0],recv_buf[1],recv_buf[2],recv_buf[4]);
|
||||
dbg_printf("Rece %d bytes.\r\n",n);
|
||||
switch(recv_buf[4]){
|
||||
case CMD_IMAGE_UPDATE:
|
||||
{
|
||||
|
||||
u32 offset;
|
||||
u32 image_size;
|
||||
recv_buf[0] = ACK;
|
||||
nwrote = write(sd, recv_buf, 1);
|
||||
n = read(sd, recv_buf, RECV_BUF_SIZE);
|
||||
|
||||
offset = *(u32 *)recv_buf;
|
||||
image_size = *(u32 *)(recv_buf + 4);
|
||||
xil_printf("offset is 0x%x image_size is 0x%x.\n", offset, image_size);
|
||||
|
||||
void *image_ptr = (void *)0x30000000;
|
||||
u32 LengthBytes;
|
||||
write(sd, recv_buf, 1); // ask for image data
|
||||
//// receive flash image to ddr
|
||||
LengthBytes = 0;
|
||||
while (LengthBytes < image_size)
|
||||
{
|
||||
n = read(sd, image_ptr + LengthBytes, RECV_BUF_SIZE);
|
||||
// xil_printf("read %d bytes.\n",n);
|
||||
LengthBytes = LengthBytes + n;
|
||||
}
|
||||
|
||||
// image data sumcheck
|
||||
|
||||
// program image data into flash
|
||||
//QspiStore( (u32) image_ptr, offset, image_size);
|
||||
//xil_printf("flash program done.\n", n);
|
||||
status = FfsSdWrite(image_ptr, image_size);
|
||||
write(sd, recv_buf, 1); // send done
|
||||
xil_printf("sd program done.\n", n);
|
||||
n = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case CMD_VER:
|
||||
dbg_printf("Version:FPGA_20240513;SDK_20240514;IP_192.168.1.99.\r\n");
|
||||
n=26;
|
||||
for(int i=0;i<26;i++){
|
||||
recv_buf[i] = FPGA_SDK_IP[i];
|
||||
}
|
||||
break;
|
||||
case CMD_RST:
|
||||
dbg_printf("Rece cmd excute rst.\r\n");
|
||||
GpioSetPinDir(NRST,GPIO_DIR_OUTPUT);
|
||||
DeviceRst();
|
||||
break;
|
||||
|
||||
case CMD_STACK_OUT:
|
||||
dbg_printf("Rece cmd STACK OUT.\r\n");
|
||||
spi_stack_out(&spistack);
|
||||
n=1;
|
||||
recv_buf[0] = 0x55;
|
||||
break;
|
||||
case CMD_SPI_WRI:
|
||||
read(sd, &recv_buf[5], 3);
|
||||
dbg_printf("Rece cmd excute spi write.\r\n");
|
||||
dbg_printf("ADDR 0x%x DATA 0x%x.\r\n",recv_buf[5]*256+recv_buf[6]-32768,recv_buf[7]);
|
||||
// SpiPs_write_read((u8 *)&recv_buf[5],&rx_data);
|
||||
status = spi_stack_in((u8 *)&recv_buf[5],&spistack);
|
||||
if(status){//when memory is near full,start spi write
|
||||
spi_stack_out(&spistack);
|
||||
}
|
||||
// n=1;
|
||||
// recv_buf[0] = rx_data;
|
||||
break;
|
||||
case CMD_SPI_READ:
|
||||
read(sd, &recv_buf[5], 3);
|
||||
dbg_printf("Rece cmd excute spi read.\r\n");
|
||||
dbg_printf("ADDR 0x%x DATA 0x%x.\r\n",recv_buf[5]*256+recv_buf[6],recv_buf[7]);
|
||||
SpiPs_write_read((u8 *)&recv_buf[5],&rx_data);
|
||||
n=1;
|
||||
recv_buf[0] = rx_data;
|
||||
break;
|
||||
case CMD_DATA_CAPTURE0:
|
||||
read(sd, &recv_buf[5], 4);
|
||||
capture_length = *((u32 *) &recv_buf[5]);//num of sample
|
||||
dbg_printf("Rece cmd excute %d sample data capture.\r\n",capture_length);
|
||||
XAxiDmaCapture(xAxiDma0Get(),capture_length);
|
||||
n = capture_length*8;
|
||||
total_send = 0;
|
||||
/* handle request */
|
||||
while(n>0){
|
||||
if(n>1024)
|
||||
send_n = 1024;
|
||||
else
|
||||
send_n = n;
|
||||
n= n-send_n;
|
||||
memcpy(recv_buf,TX_BUFFER_BASE + total_send,send_n);
|
||||
total_send = total_send + send_n;
|
||||
if ((nwrote = write(sd, &recv_buf, send_n)) < 0) {
|
||||
xil_printf("%s: ERROR responding to client echo request. received = %d, written = %d\r\n",__FUNCTION__, n, nwrote);
|
||||
xil_printf("Closing socket %d\r\n", sd);
|
||||
break;
|
||||
}
|
||||
else{
|
||||
if(send_n!=nwrote){
|
||||
xil_printf("%d Bytes Send %d.\r\n", send_n,nwrote);
|
||||
}
|
||||
}
|
||||
}
|
||||
dbg_printf("Send %d bytes.\r\n",n);
|
||||
break;
|
||||
case CMD_DATA_CAPTURE1:
|
||||
read(sd, &recv_buf[5], 4);
|
||||
capture_length = *((u32 *) &recv_buf[5]);//num of sample
|
||||
dbg_printf("Rece cmd excute %d sample data capture.\r\n",capture_length);
|
||||
XAxiDmaCapture(xAxiDma1Get(),capture_length);
|
||||
n = capture_length*8;
|
||||
total_send = 0;
|
||||
/* handle request */
|
||||
while(n>0){
|
||||
if(n>1024)
|
||||
send_n = 1024;
|
||||
else
|
||||
send_n = n;
|
||||
n= n-send_n;
|
||||
|
||||
memcpy(recv_buf,TX_BUFFER_BASE + total_send,send_n);
|
||||
total_send = total_send + send_n;
|
||||
if ((nwrote = write(sd, &recv_buf, send_n)) < 0) {
|
||||
xil_printf("%s: ERROR responding to client echo request. received = %d, written = %d\r\n",__FUNCTION__, n, nwrote);
|
||||
xil_printf("Closing socket %d\r\n", sd);
|
||||
break;
|
||||
}
|
||||
else{
|
||||
if(send_n!=nwrote){
|
||||
xil_printf("%d Bytes Send %d.\r\n", send_n,nwrote);
|
||||
}
|
||||
}
|
||||
}
|
||||
dbg_printf("Send %d bytes.\r\n",n);
|
||||
break;
|
||||
case CMD_DATA_CAPTURE2:
|
||||
read(sd, &recv_buf[5], 4);
|
||||
capture_length = *((u32 *) &recv_buf[5]);//num of sample
|
||||
dbg_printf("Rece cmd excute %d sample data capture.\r\n",capture_length);
|
||||
XAxiDmaCapture(xAxiDma2Get(),capture_length);
|
||||
n = capture_length*8;
|
||||
total_send = 0;
|
||||
/* handle request */
|
||||
while(n>0){
|
||||
if(n>1024)
|
||||
send_n = 1024;
|
||||
else
|
||||
send_n = n;
|
||||
n= n-send_n;
|
||||
memcpy(recv_buf,TX_BUFFER_BASE + total_send,send_n);
|
||||
total_send = total_send + send_n;
|
||||
if ((nwrote = write(sd, &recv_buf, send_n)) < 0) {
|
||||
xil_printf("%s: ERROR responding to client echo request. received = %d, written = %d\r\n",__FUNCTION__, n, nwrote);
|
||||
xil_printf("Closing socket %d\r\n", sd);
|
||||
break;
|
||||
}
|
||||
else{
|
||||
if(send_n!=nwrote){
|
||||
xil_printf("%d Bytes Send %d.\r\n", send_n,nwrote);
|
||||
}
|
||||
}
|
||||
}
|
||||
dbg_printf("Send %d bytes.\r\n",n);
|
||||
break;
|
||||
case CMD_WAVE_DOWNLOAD:
|
||||
dbg_printf("Rece cmd excute wave download.\r\n");
|
||||
while(n<WAVE_LENGTH){
|
||||
dbg_printf("Rece data num in recv_buf is %d.\r\n",n);
|
||||
n =n + read(sd, &trans_buf[n], 512);//
|
||||
}
|
||||
dbg_printf("Rece data num in recv_buf is %d.\r\n",n);
|
||||
DownloadWave((u8 *)&trans_buf[0]);
|
||||
n=0;
|
||||
break;
|
||||
case CMD_PIN_SET:
|
||||
read(sd, &recv_buf[5], 2);
|
||||
pin = (u8) recv_buf[5];
|
||||
pin_value = (u8) recv_buf[6];
|
||||
dbg_printf("Rece cmd excute pin %d set %d.\r\n",pin,pin_value);
|
||||
GpioSetPinDir(pin,GPIO_DIR_OUTPUT);
|
||||
GpioWritePin(pin,pin_value&0x01);//dma_axis_rx_rstn
|
||||
// recv_buf_temp[0]= 0x80;
|
||||
// recv_buf_temp[1]= 0x43;
|
||||
// recv_buf_temp[2]= 0xe7;
|
||||
// if((pin==0x20)&&(pin_value==0x01)){
|
||||
// SpiPs_write_read((u8 *)&recv_buf_temp,&rx_data);
|
||||
// }
|
||||
break;
|
||||
|
||||
case CMD_hopping:
|
||||
read(sd, &recv_buf[5], 4);
|
||||
int hop_flag=recv_buf[5]&0x01;
|
||||
frqhop_flag(hop_flag);
|
||||
if(hop_flag==1){
|
||||
xil_printf("hopping freqence start.\r\n");
|
||||
}else{
|
||||
xil_printf("hopping freqence end.\r\n");
|
||||
}
|
||||
break;
|
||||
case CMD_qecbin:
|
||||
download_bin();
|
||||
break;
|
||||
case CMD_cx9261a_config:
|
||||
read(sd, &recv_buf[5], 1);
|
||||
int lo = 5000;
|
||||
int f0 = 4;
|
||||
int fs = 80;
|
||||
int ref= 100;
|
||||
int dcCalibEnable = 1;
|
||||
int dcCalibLength = 7;
|
||||
if(recv_buf[5] == 0){
|
||||
cx9261a_151_config();
|
||||
}else if(recv_buf[5] == 1){
|
||||
cx9261a_076_config();
|
||||
configDcCalib(dcCalibEnable,dcCalibLength);
|
||||
rxFFTCalib(lo,fs,ref,8,1);
|
||||
rxFFTCalib(lo,fs,ref,8,2);
|
||||
rxFFTCalib(lo,fs,ref,8,3);
|
||||
txBisectionQecCalib(f0, fs);
|
||||
txBisectionDcCalib(f0, fs);
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_cx3e04_config:
|
||||
cx3e04_config();
|
||||
break;
|
||||
|
||||
case CMD_cx3e04_SPI_WRI:
|
||||
read(sd, &recv_buf[5], 3);
|
||||
dbg_printf("Rece cmd excute cx3e04_spi write.\r\n");
|
||||
dbg_printf("ADDR 0x%x DATA 0x%x.\r\n",recv_buf[5]*256+recv_buf[6]-32768,recv_buf[7]);
|
||||
int addr = recv_buf[5]*256+recv_buf[6];
|
||||
int value= recv_buf[7];
|
||||
cx3e04_write(addr,value);
|
||||
break;
|
||||
case CMD_cx3e04_SPI_READ:
|
||||
read(sd, &recv_buf[5], 2);
|
||||
dbg_printf("Rece cmd excute cx3e04_spi read.\r\n");
|
||||
dbg_printf("ADDR 0x%x.\r\n",recv_buf[5]*256+recv_buf[6]);
|
||||
addr = recv_buf[5]*256+recv_buf[6];
|
||||
n=1;
|
||||
recv_buf[0] = cx3e04_read(addr);
|
||||
break;
|
||||
default :
|
||||
xil_printf("cmd error 0x%x",recv_buf[4]);
|
||||
break;
|
||||
}
|
||||
|
||||
/*if(recv_buf[4] == 7){
|
||||
read(sd, &recv_buf[5], 4);
|
||||
capture_length = *((u32 *) &recv_buf[5]);//num of sample
|
||||
dbg_printf("Rece cmd excute %d sample data capture.\r\n",capture_length);
|
||||
XAxiDmaCapture2(capture_length);
|
||||
// memcpy(recv_buf,TX_BUFFER_BASE,capture_length*8);
|
||||
n = capture_length*8;
|
||||
total_send = 0;
|
||||
// handle request
|
||||
while(n>0){
|
||||
if(n>1024)
|
||||
send_n = 1024;
|
||||
else
|
||||
send_n = n;
|
||||
n= n-send_n;
|
||||
total_send = total_send + send_n;
|
||||
memcpy(recv_buf,TX_BUFFER_BASE + total_send,send_n);
|
||||
if ((nwrote = write(sd, &recv_buf, send_n)) < 0) {
|
||||
xil_printf("%s: ERROR responding to client echo request. received = %d, written = %d\r\n",
|
||||
__FUNCTION__, n, nwrote);
|
||||
xil_printf("Closing socket %d\r\n", sd);
|
||||
break;
|
||||
}
|
||||
else{
|
||||
if(send_n!=nwrote){
|
||||
xil_printf("%d Bytes Send %d.\r\n", send_n,nwrote);
|
||||
}
|
||||
}
|
||||
}
|
||||
dbg_printf("Send %d bytes.\r\n",n);
|
||||
}*/
|
||||
|
||||
}
|
||||
}
|
||||
/* handle request */
|
||||
if ((nwrote = write(sd, recv_buf, n)) < 0) {
|
||||
xil_printf("%s: ERROR responding to client echo request. received = %d, written = %d\r\n",
|
||||
__FUNCTION__, n, nwrote);
|
||||
xil_printf("Closing socket %d\r\n", sd);
|
||||
break;
|
||||
}
|
||||
else{
|
||||
if(n!=nwrote){
|
||||
xil_printf("%d Bytes Send %d.\r\n", n,nwrote);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* close connection */
|
||||
close(sd);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
void echo_application_thread()
|
||||
{
|
||||
int sock, new_sd;
|
||||
int size;
|
||||
#if LWIP_IPV6==0
|
||||
struct sockaddr_in address, remote;
|
||||
|
||||
memset(&address, 0, sizeof(address));
|
||||
|
||||
if ((sock = lwip_socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
||||
return;
|
||||
|
||||
address.sin_family = AF_INET;
|
||||
address.sin_port = htons(echo_port);
|
||||
address.sin_addr.s_addr = INADDR_ANY;
|
||||
#else
|
||||
struct sockaddr_in6 address, remote;
|
||||
|
||||
memset(&address, 0, sizeof(address));
|
||||
|
||||
address.sin6_len = sizeof(address);
|
||||
address.sin6_family = AF_INET6;
|
||||
address.sin6_port = htons(echo_port);
|
||||
|
||||
memset(&(address.sin6_addr), 0, sizeof(address.sin6_addr));
|
||||
|
||||
if ((sock = lwip_socket(AF_INET6, SOCK_STREAM, 0)) < 0)
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (lwip_bind(sock, (struct sockaddr *)&address, sizeof (address)) < 0)
|
||||
return;
|
||||
|
||||
lwip_listen(sock, 0);
|
||||
|
||||
size = sizeof(remote);
|
||||
|
||||
while (1) {
|
||||
if ((new_sd = lwip_accept(sock, (struct sockaddr *)&remote, (socklen_t *)&size)) > 0) {
|
||||
sys_thread_new("echos", process_echo_request,
|
||||
(void*)new_sd,
|
||||
THREAD_STACKSIZE,
|
||||
DEFAULT_THREAD_PRIO);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* frqhop_config.c
|
||||
*
|
||||
* Created on: 2023年11月24日
|
||||
* Author: cxlab
|
||||
*/
|
||||
|
||||
#include "xilinx_io.h"
|
||||
#include "sleep.h"
|
||||
#include "time.h"
|
||||
#include "xtime_l.h"
|
||||
#include "math.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
void frqhop_config(int hop_flag){
|
||||
XTime tCur;
|
||||
XTime_GetTime(&tCur);
|
||||
srand(tCur);
|
||||
double hop_freq = (rand()%(800-30))+30+(rand()%(101))/(double)100;//随机产生[30,800)double类型的数
|
||||
// double hop_freq = 400.52;
|
||||
double hop_freq1 = 800.25;
|
||||
static int pll_index=1;
|
||||
static int unlock_pll1_cnt=0,unlock_pll2_cnt=0;
|
||||
if(hop_freq == hop_freq1){
|
||||
if(pll_index == 2){
|
||||
pll_index = 4;
|
||||
}
|
||||
else if(pll_index == 1){
|
||||
pll_index = 3;
|
||||
}
|
||||
}
|
||||
if(hop_flag == 1){
|
||||
if(pll_index == 1 || pll_index == 3){
|
||||
//切换至pll2来源
|
||||
trx_ch_pll_config(2);
|
||||
//配置pll1参数
|
||||
unlock_pll1_cnt=PLL_config(1,hop_freq)-1;
|
||||
pll_index = 2;
|
||||
}
|
||||
else if(pll_index == 2 || pll_index == 4){
|
||||
//切换至pll1来源
|
||||
trx_ch_pll_config(1);
|
||||
//配置pll2参数
|
||||
unlock_pll2_cnt=PLL_config(2,hop_freq)-1;
|
||||
pll_index = 1;
|
||||
}
|
||||
}
|
||||
hop_freq1 = hop_freq;
|
||||
if(unlock_pll2_cnt!=0 || unlock_pll1_cnt !=0){
|
||||
xil_printf("pll1 unlock num: %d; pll2 unlock num: %d;.\n", unlock_pll1_cnt, unlock_pll2_cnt);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (C) 2016 - 2018 Xilinx, 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:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 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 <stdio.h>
|
||||
|
||||
#include "xparameters.h"
|
||||
#if defined (__arm__) || defined(__aarch64__)
|
||||
#include "xil_printf.h"
|
||||
#endif
|
||||
|
||||
#ifdef XPS_BOARD_ZCU102
|
||||
#ifdef XPAR_XIICPS_0_DEVICE_ID
|
||||
#include "xiicps.h"
|
||||
|
||||
#define BUF_LEN 10U
|
||||
|
||||
#define IOEXPANDER1_ADDR 0x20U
|
||||
|
||||
#define IIC_SCLK_RATE_IOEXP 400000
|
||||
|
||||
#define CMD_CFG_0_REG 0x06U
|
||||
#define CMD_OUTPUT_0_REG 0x02U
|
||||
#define DATA_OUTPUT 0x0U
|
||||
|
||||
#define DATA_COMMON_CFG 0xE0U
|
||||
#define DATA_GT_0000_CFG 0x00U
|
||||
|
||||
XIicPs I2c0InstancePtr;
|
||||
|
||||
int IicPhyReset(void)
|
||||
{
|
||||
|
||||
u8 WriteBuffer[BUF_LEN] = {0};
|
||||
XIicPs_Config *I2c0CfgPtr;
|
||||
int Status = XST_SUCCESS;
|
||||
|
||||
/* Initialize the IIC0 driver so that it is ready to use */
|
||||
I2c0CfgPtr = XIicPs_LookupConfig(XPAR_XIICPS_0_DEVICE_ID);
|
||||
if (I2c0CfgPtr == NULL) {
|
||||
Status = XST_FAILURE;
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = XIicPs_CfgInitialize(&I2c0InstancePtr, I2c0CfgPtr,
|
||||
I2c0CfgPtr->BaseAddress);
|
||||
if (Status != XST_SUCCESS) {
|
||||
Status = XST_FAILURE;
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Set the IIC serial clock rate */
|
||||
XIicPs_SetSClk(&I2c0InstancePtr, IIC_SCLK_RATE_IOEXP);
|
||||
|
||||
/* Configure I/O pins as Output */
|
||||
WriteBuffer[0] = CMD_CFG_0_REG;
|
||||
WriteBuffer[1] = DATA_OUTPUT;
|
||||
Status = XIicPs_MasterSendPolled(&I2c0InstancePtr,
|
||||
WriteBuffer, 2, IOEXPANDER1_ADDR);
|
||||
if (Status != XST_SUCCESS) {
|
||||
Status = XST_FAILURE;
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Wait until bus is idle to start another transfer */
|
||||
while (XIicPs_BusIsBusy(&I2c0InstancePtr));
|
||||
|
||||
/*
|
||||
* Deasserting I2C_MUX_RESETB
|
||||
* And GEM3 Resetb
|
||||
* Selecting lanes based on configuration
|
||||
*/
|
||||
WriteBuffer[0] = CMD_OUTPUT_0_REG;
|
||||
/* gt0000 or no GT configuration */
|
||||
WriteBuffer[1] = DATA_COMMON_CFG | DATA_GT_0000_CFG;
|
||||
|
||||
/* Send the Data */
|
||||
Status = XIicPs_MasterSendPolled(&I2c0InstancePtr,
|
||||
WriteBuffer, 2, IOEXPANDER1_ADDR);
|
||||
if (Status != XST_SUCCESS) {
|
||||
Status = XST_FAILURE;
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Wait until bus is idle */
|
||||
while (XIicPs_BusIsBusy(&I2c0InstancePtr));
|
||||
|
||||
xil_printf("IIC PHY reset on ZCU102 successful \n\r");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,300 @@
|
||||
/*
|
||||
* Copyright (C) 2016 - 2018 Xilinx, 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:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 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 <stdio.h>
|
||||
#include "xparameters.h"
|
||||
#include "netif/xadapter.h"
|
||||
#include "platform_config.h"
|
||||
#include "xil_printf.h"
|
||||
#include "xilinx_io.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "queue.h"
|
||||
#include "semphr.h"
|
||||
#include "math.h"
|
||||
|
||||
#if LWIP_IPV6==1
|
||||
#include "lwip/ip.h"
|
||||
#else
|
||||
#if LWIP_DHCP==1
|
||||
#include "lwip/dhcp.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef XPS_BOARD_ZCU102
|
||||
#ifdef XPAR_XIICPS_0_DEVICE_ID
|
||||
int IicPhyReset(void);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int main_thread();
|
||||
void print_echo_app_header();
|
||||
void echo_application_thread(void *);
|
||||
|
||||
void lwip_init();
|
||||
|
||||
#if LWIP_IPV6==0
|
||||
#if LWIP_DHCP==1
|
||||
extern volatile int dhcp_timoutcntr;
|
||||
err_t dhcp_start(struct netif *netif);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define THREAD_STACKSIZE 1024
|
||||
|
||||
static struct netif server_netif;
|
||||
struct netif *echo_netif;
|
||||
|
||||
#if LWIP_IPV6==1
|
||||
void print_ip6(char *msg, ip_addr_t *ip)
|
||||
{
|
||||
print(msg);
|
||||
xil_printf(" %x:%x:%x:%x:%x:%x:%x:%x\n\r",
|
||||
IP6_ADDR_BLOCK1(&ip->u_addr.ip6),
|
||||
IP6_ADDR_BLOCK2(&ip->u_addr.ip6),
|
||||
IP6_ADDR_BLOCK3(&ip->u_addr.ip6),
|
||||
IP6_ADDR_BLOCK4(&ip->u_addr.ip6),
|
||||
IP6_ADDR_BLOCK5(&ip->u_addr.ip6),
|
||||
IP6_ADDR_BLOCK6(&ip->u_addr.ip6),
|
||||
IP6_ADDR_BLOCK7(&ip->u_addr.ip6),
|
||||
IP6_ADDR_BLOCK8(&ip->u_addr.ip6));
|
||||
}
|
||||
|
||||
#else
|
||||
void
|
||||
print_ip(char *msg, ip_addr_t *ip)
|
||||
{
|
||||
xil_printf(msg);
|
||||
xil_printf("%d.%d.%d.%d\n\r", ip4_addr1(ip), ip4_addr2(ip),
|
||||
ip4_addr3(ip), ip4_addr4(ip));
|
||||
}
|
||||
|
||||
void
|
||||
print_ip_settings(ip_addr_t *ip, ip_addr_t *mask, ip_addr_t *gw)
|
||||
{
|
||||
|
||||
print_ip("Board IP: ", ip);
|
||||
print_ip("Netmask : ", mask);
|
||||
print_ip("Gateway : ", gw);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
xil_printf("start");
|
||||
|
||||
sys_thread_new("main_thrd", (void(*)(void*))main_thread, 0,
|
||||
THREAD_STACKSIZE,
|
||||
DEFAULT_THREAD_PRIO);
|
||||
vTaskStartScheduler();
|
||||
|
||||
while(1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void network_thread(void *p)
|
||||
{
|
||||
struct netif *netif;
|
||||
/* the mac address of the board. this should be unique per board */
|
||||
unsigned char mac_ethernet_address[] = { 0x00, 0x0a, 0x35, 0x00, 0x01, 0x02 };
|
||||
#if LWIP_IPV6==0
|
||||
ip_addr_t ipaddr, netmask, gw;
|
||||
#if LWIP_DHCP==1
|
||||
int mscnt = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
netif = &server_netif;
|
||||
|
||||
xil_printf("\r\n\r\n");
|
||||
xil_printf("-----lwIP Socket Mode CX9261 TEST server Application Version 2022.05.31------\r\n");
|
||||
|
||||
#if LWIP_IPV6==0
|
||||
#if LWIP_DHCP==0
|
||||
/* initliaze IP addresses to be used */
|
||||
IP4_ADDR(&ipaddr, 192, 168, 1, 99);
|
||||
IP4_ADDR(&netmask, 255, 255, 255, 0);
|
||||
IP4_ADDR(&gw, 192, 168, 1, 1);
|
||||
#endif
|
||||
|
||||
/* print out IP settings of the board */
|
||||
|
||||
#if LWIP_DHCP==0
|
||||
print_ip_settings(&ipaddr, &netmask, &gw);
|
||||
/* print all application headers */
|
||||
#endif
|
||||
|
||||
#if LWIP_DHCP==1
|
||||
ipaddr.addr = 0;
|
||||
gw.addr = 0;
|
||||
netmask.addr = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if LWIP_IPV6==0
|
||||
/* Add network interface to the netif_list, and set it as default */
|
||||
if (!xemac_add(netif, &ipaddr, &netmask, &gw, mac_ethernet_address, PLATFORM_EMAC_BASEADDR)) {
|
||||
xil_printf("Error adding N/W interface\r\n");
|
||||
return;
|
||||
}
|
||||
#else
|
||||
/* Add network interface to the netif_list, and set it as default */
|
||||
if (!xemac_add(netif, NULL, NULL, NULL, mac_ethernet_address, PLATFORM_EMAC_BASEADDR)) {
|
||||
xil_printf("Error adding N/W interface\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
netif->ip6_autoconfig_enabled = 1;
|
||||
|
||||
netif_create_ip6_linklocal_address(netif, 1);
|
||||
netif_ip6_addr_set_state(netif, 0, IP6_ADDR_VALID);
|
||||
|
||||
print_ip6("\n\rBoard IPv6 address ", &netif->ip6_addr[0].u_addr.ip6);
|
||||
#endif
|
||||
|
||||
netif_set_default(netif);
|
||||
|
||||
/* specify that the network if is up */
|
||||
netif_set_up(netif);
|
||||
|
||||
/* start packet receive thread - required for lwIP operation */
|
||||
sys_thread_new("xemacif_input_thread", (void(*)(void*))xemacif_input_thread, netif,
|
||||
THREAD_STACKSIZE,
|
||||
DEFAULT_THREAD_PRIO);
|
||||
|
||||
#if LWIP_IPV6==0
|
||||
#if LWIP_DHCP==1
|
||||
dhcp_start(netif);
|
||||
while (1) {
|
||||
vTaskDelay(DHCP_FINE_TIMER_MSECS / portTICK_RATE_MS);
|
||||
dhcp_fine_tmr();
|
||||
mscnt += DHCP_FINE_TIMER_MSECS;
|
||||
if (mscnt >= DHCP_COARSE_TIMER_SECS*1000) {
|
||||
dhcp_coarse_tmr();
|
||||
mscnt = 0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
xil_printf("\r\n");
|
||||
xil_printf("%20s %6s %s\r\n", "Server", "Port", "Connect With..");
|
||||
xil_printf("%20s %6s %s\r\n", "--------------------", "------", "--------------------");
|
||||
|
||||
print_echo_app_header();
|
||||
xil_printf("\r\n");
|
||||
sys_thread_new("echod", echo_application_thread, 0,
|
||||
THREAD_STACKSIZE,
|
||||
DEFAULT_THREAD_PRIO);
|
||||
vTaskDelete(NULL);
|
||||
#endif
|
||||
#else
|
||||
print_echo_app_header();
|
||||
xil_printf("\r\n");
|
||||
sys_thread_new("echod",echo_application_thread, 0,
|
||||
THREAD_STACKSIZE,
|
||||
DEFAULT_THREAD_PRIO);
|
||||
vTaskDelete(NULL);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
int main_thread()
|
||||
{
|
||||
#if LWIP_DHCP==1
|
||||
int mscnt = 0;
|
||||
#endif
|
||||
|
||||
#ifdef XPS_BOARD_ZCU102
|
||||
IicPhyReset();
|
||||
#endif
|
||||
|
||||
/* initialize lwIP before calling sys_thread_new */
|
||||
lwip_init();
|
||||
SpiPsInit(SPI_DEVICE_ID);
|
||||
GpioInit(GPIO_DEVICE_ID);
|
||||
AXIGpioInit();
|
||||
XScuGicInit();
|
||||
ConfigAXIGPIOIntr();
|
||||
ExceptionInit();
|
||||
|
||||
XAxiDma_Init(xAxiDma0Get(),AXI_DMA_DEVCIE_ID0);
|
||||
XAxiDma_Init(xAxiDma1Get(),AXI_DMA_DEVCIE_ID1);
|
||||
XAxiDma_Init(xAxiDma2Get(),AXI_DMA_DEVCIE_ID2);
|
||||
PackerRst();
|
||||
|
||||
/* cx9261a configuration */
|
||||
peripheral_test();
|
||||
cx3e04_config();
|
||||
// cx9261a_710_config();
|
||||
// frqhop_config(1);
|
||||
int temp = cx3e04_read(0x03A);
|
||||
/* any thread using lwIP should be created using sys_thread_new */
|
||||
sys_thread_new("NW_THRD", network_thread, NULL,
|
||||
THREAD_STACKSIZE,
|
||||
DEFAULT_THREAD_PRIO);
|
||||
|
||||
#if LWIP_IPV6==0
|
||||
#if LWIP_DHCP==1
|
||||
while (1) {
|
||||
vTaskDelay(DHCP_FINE_TIMER_MSECS / portTICK_RATE_MS);
|
||||
if (server_netif.ip_addr.addr) {
|
||||
xil_printf("DHCP request success\r\n");
|
||||
print_ip_settings(&(server_netif.ip_addr), &(server_netif.netmask), &(server_netif.gw));
|
||||
print_echo_app_header();
|
||||
xil_printf("\r\n");
|
||||
sys_thread_new("echod", echo_application_thread, 0,
|
||||
THREAD_STACKSIZE,
|
||||
DEFAULT_THREAD_PRIO);
|
||||
break;
|
||||
}
|
||||
mscnt += DHCP_FINE_TIMER_MSECS;
|
||||
if (mscnt >= 10000) {
|
||||
xil_printf("ERROR: DHCP request timed out\r\n");
|
||||
xil_printf("Configuring default IP of 192.168.1.100\r\n");
|
||||
IP4_ADDR(&(server_netif.ip_addr), 192, 168, 1, 100);
|
||||
IP4_ADDR(&(server_netif.netmask), 255, 255, 255, 0);
|
||||
IP4_ADDR(&(server_netif.gw), 192, 168, 1, 1);
|
||||
print_ip_settings(&(server_netif.ip_addr), &(server_netif.netmask), &(server_netif.gw));
|
||||
/* print all application headers */
|
||||
xil_printf("\r\n");
|
||||
xil_printf("%20s %6s %s\r\n", "Server", "Port", "Connect With..");
|
||||
xil_printf("%20s %6s %s\r\n", "--------------------", "------", "--------------------");
|
||||
|
||||
print_echo_app_header();
|
||||
xil_printf("\r\n");
|
||||
sys_thread_new("echod", echo_application_thread, 0,
|
||||
THREAD_STACKSIZE,
|
||||
DEFAULT_THREAD_PRIO);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
vTaskDelete(NULL);
|
||||
return 0;
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
#ifndef __PLATFORM_CONFIG_H_
|
||||
#define __PLATFORM_CONFIG_H_
|
||||
|
||||
|
||||
#define PLATFORM_EMAC_BASEADDR XPAR_XEMACPS_0_BASEADDR
|
||||
|
||||
#define PLATFORM_ZYNQ
|
||||
|
||||
|
||||
#endif
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* wideband_qec.c
|
||||
*
|
||||
* Created on: 2023Äê11ÔÂ30ÈÕ
|
||||
* Author: cxlab
|
||||
*/
|
||||
|
||||
#include "xilinx_io.h"
|
||||
#include "sleep.h"
|
||||
#include "math.h"
|
||||
void rxFFTCalib(int lo, int fs,int ref, int firLength, int chan) {
|
||||
u8 rx_data;
|
||||
SpiPs_write_read1(0x000, chan == 1 ? 0x12 : 0x22,&rx_data);
|
||||
SpiPs_write_read1(0x128, 0x00,&rx_data);
|
||||
SpiPs_write_read1(0x11B, 0x01,&rx_data);
|
||||
SpiPs_write_read1(0x11E, 0x01,&rx_data);
|
||||
configTxNcoFreq(0, fs);
|
||||
SpiPs_write_read1(0x161, 0x00,&rx_data);
|
||||
SpiPs_write_read1(0x162, 0x00,&rx_data);
|
||||
SpiPs_write_read1(0x162, 0x01,&rx_data);
|
||||
SpiPs_write_read1(0x161, 0x01,&rx_data);
|
||||
SpiPs_write_read1(0x000, chan == 1 ? 0x12 : chan == 2 ? 0x22 : 0x32,&rx_data);
|
||||
SpiPs_write_read1(0x102, 0x03,&rx_data);
|
||||
SpiPs_write_read1(0x102, 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x15C, 0x00,&rx_data);
|
||||
SpiPs_write_read1(0x160, 0x01,&rx_data);
|
||||
SpiPs_write_read1(0x77E, chan == 1 ? 0x50 : chan == 2 ? 0x0A : 0x03,&rx_data);
|
||||
SpiPs_write_read1(0x09B, 0x01,&rx_data); // TXPLL4
|
||||
SpiPs_write_read1(0x09D, firLength,&rx_data);
|
||||
SpiPs_write_read1(0x096, ((u32)round(lo) >> 8) & 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x097, (u32)round(lo) & 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x098, ((u32)round(ref * 10) >> 8) & 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x099, (u32)round(ref * 10) & 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x09E, ((u32)round(fs * 100) >> 8) & 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x09F, (u32)round(fs * 100) & 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x09C, chan,&rx_data);
|
||||
while (1) {
|
||||
if (SpiPs_write_read2(0x0B3,0x00,&rx_data) == 5)
|
||||
break;
|
||||
usleep(10000);
|
||||
}
|
||||
SpiPs_write_read1(0x09C, 0x00,&rx_data);
|
||||
SpiPs_write_read1(0x15C, 0x01,&rx_data);
|
||||
SpiPs_write_read1(0x77E, 0x00,&rx_data);
|
||||
|
||||
//ͨµÀʱÖÓÀ´Ô´
|
||||
u8 r77D=0xC0;
|
||||
u8 r775=0x24;
|
||||
u8 r6C3=0x00;
|
||||
SpiPs_write_read1(0x77D, r77D,&rx_data);
|
||||
SpiPs_write_read1(0x775, r775,&rx_data);
|
||||
SpiPs_write_read1(0x6C3, r6C3,&rx_data);
|
||||
}
|
||||
|
||||
|
||||
void configDcCalib(int dcCalibEnable,int dcCalibLength) {
|
||||
u8 rx_data;
|
||||
SpiPs_write_read1(0x109, dcCalibEnable ? 0x11 : 0x00,&rx_data);
|
||||
SpiPs_write_read1(0x10A, (dcCalibLength) << 4,&rx_data);
|
||||
SpiPs_write_read1(0x11F, dcCalibEnable ? 0x33 : 0x73,&rx_data);
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
#include "sd.h"
|
||||
/************************** Variable Definitions *****************************/
|
||||
static FIL fil; /* File object */
|
||||
static FATFS fatfs;
|
||||
/*
|
||||
* To test logical drive 0, FileName should be "0:/<File name>" or
|
||||
* "<file_name>". For logical drive 1, FileName should be "1:/<file_name>"
|
||||
*/
|
||||
static char FileName[32] = "BOOT.bin";
|
||||
static char *SD_File;
|
||||
|
||||
|
||||
//#define BUFF_SIZE sizeof(image_data)
|
||||
#define BUFF_SIZE 0x2000000
|
||||
#ifdef __ICCARM__
|
||||
#pragma data_alignment = 32
|
||||
u8 DestinationAddress[10*1024];
|
||||
#pragma data_alignment = 32
|
||||
u8 SourceAddress[10*1024];
|
||||
#else
|
||||
//u8 DestinationAddress[10*1024] __attribute__ ((aligned(32)));
|
||||
//u8 SourceAddress[10*1024] __attribute__ ((aligned(32)));
|
||||
|
||||
u8 DestinationAddress[BUFF_SIZE] __attribute__ ((aligned(32)));
|
||||
u8 SourceAddress[BUFF_SIZE] __attribute__ ((aligned(32)));
|
||||
#endif
|
||||
|
||||
#define TEST 7
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* File system example using SD driver to write to and read from an SD card
|
||||
* in polled mode. This example creates a new file on an
|
||||
* SD card (which is previously formatted with FATFS), write data to the file
|
||||
* and reads the same data back to verify.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
|
||||
*
|
||||
* @note None
|
||||
*
|
||||
******************************************************************************/
|
||||
int FfsSdWrite(u8*image_data, u32 FileSize)
|
||||
{
|
||||
int error_flag = 0;
|
||||
FRESULT Res;
|
||||
UINT NumBytesRead;
|
||||
UINT NumBytesWritten;
|
||||
u32 BuffCnt;
|
||||
BYTE work[FF_MAX_SS];
|
||||
// u32 FileSize = (8*1024);
|
||||
// u32 FileSize = sizeof(image_data);
|
||||
/*
|
||||
* To test logical drive 0, Path should be "0:/"
|
||||
* For logical drive 1, Path should be "1:/"
|
||||
*/
|
||||
TCHAR *Path = "0:/";
|
||||
u8 checksum = 0;
|
||||
|
||||
for(BuffCnt = 0; BuffCnt < FileSize; BuffCnt++){
|
||||
// SourceAddress[BuffCnt] = TEST + BuffCnt;
|
||||
SourceAddress[BuffCnt] = image_data[BuffCnt];
|
||||
checksum = checksum + image_data[BuffCnt];
|
||||
}
|
||||
xil_printf("checksum is 0x%x.",checksum);
|
||||
|
||||
|
||||
/*
|
||||
* Register volume work area, initialize device
|
||||
*/
|
||||
Res = f_mount(&fatfs, Path, 0);
|
||||
|
||||
if (Res != FR_OK) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Path - Path to logical driver, 0 - FDISK format.
|
||||
* 0 - Cluster size is automatically determined based on Vol size.
|
||||
*/
|
||||
Res = f_mkfs(Path, FM_FAT32, 0, work, sizeof work);
|
||||
if (Res != FR_OK) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Open file with required permissions.
|
||||
* Here - Creating new file with read/write permissions. .
|
||||
* To open file with write permissions, file system should not
|
||||
* be in Read Only mode.
|
||||
*/
|
||||
SD_File = (char *)FileName;
|
||||
|
||||
Res = f_open(&fil, SD_File, FA_CREATE_ALWAYS | FA_WRITE | FA_READ);
|
||||
if (Res) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Pointer to beginning of file .
|
||||
*/
|
||||
Res = f_lseek(&fil, 0);
|
||||
if (Res) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write data to file.
|
||||
*/
|
||||
Res = f_write(&fil, (const void*)SourceAddress, FileSize,
|
||||
&NumBytesWritten);
|
||||
if (Res) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
/*
|
||||
* Close file.
|
||||
*/
|
||||
Res = f_close(&fil);
|
||||
if (Res) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
Res = f_open(&fil, SD_File, FA_READ);
|
||||
if (Res) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
/*
|
||||
* Pointer to beginning of file .
|
||||
*/
|
||||
Res = f_lseek(&fil, 0);
|
||||
if (Res) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read data from file.
|
||||
*/
|
||||
Res = f_read(&fil, (void*)DestinationAddress, FileSize,
|
||||
&NumBytesRead);
|
||||
if (Res) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Data verification
|
||||
*/
|
||||
for(BuffCnt = 0; BuffCnt < FileSize; BuffCnt++){
|
||||
if(SourceAddress[BuffCnt] != DestinationAddress[BuffCnt]){
|
||||
// return XST_FAILURE;
|
||||
error_flag = 1;
|
||||
xil_printf('Data check error.');
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Close file.
|
||||
*/
|
||||
Res = f_close(&fil);
|
||||
if (Res) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
if(error_flag){
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
// Res = f_unmount(Path);
|
||||
// if (Res) {
|
||||
// return XST_FAILURE;
|
||||
// }
|
||||
//
|
||||
// sleep(5);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
/***************************** Include Files *********************************/
|
||||
#include "xparameters.h" /* SDK generated parameters */
|
||||
#include "xsdps.h" /* SD device driver */
|
||||
#include "xil_printf.h"
|
||||
#include "ff.h"
|
||||
#include "xil_cache.h"
|
||||
#include "xplatform_info.h"
|
||||
/************************** Function Prototypes ******************************/
|
||||
int FfsSdWrite(u8*image_data, u32 FileSize);
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* tx_bisection.c
|
||||
*
|
||||
* Created on: 2023Äê12ÔÂ1ÈÕ
|
||||
* Author: cxlab
|
||||
*/
|
||||
|
||||
|
||||
#include "xilinx_io.h"
|
||||
#include "sleep.h"
|
||||
#include "math.h"
|
||||
|
||||
void txBisectionQecCalib(int f0, int fs) {
|
||||
u8 rx_data;
|
||||
SpiPs_write_read1(0x02E, 0x03,&rx_data);
|
||||
SpiPs_write_read1(0x128, 0x11,&rx_data);
|
||||
SpiPs_write_read1(0x11E, 0x01,&rx_data);
|
||||
SpiPs_write_read1(0x77E, 0x24,&rx_data);
|
||||
SpiPs_write_read1(0x11F, 0x01,&rx_data);
|
||||
SpiPs_write_read1(0x121, 0x02,&rx_data);
|
||||
SpiPs_write_read1(0x11B, 0x01,&rx_data);
|
||||
SpiPs_write_read1(0x161, 0x01,&rx_data);
|
||||
SpiPs_write_read1(0x162, 0x01,&rx_data);
|
||||
SpiPs_write_read1(0x163, 0x00,&rx_data);
|
||||
configTxNcoFreq(f0, fs * 4);
|
||||
SpiPs_write_read1(0xA2D, 0x02,&rx_data);
|
||||
SpiPs_write_read1(0xA07, 0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA08, 0x0F,&rx_data);
|
||||
SpiPs_write_read1(0xA1C, 0x01,&rx_data);
|
||||
configRxNcoFreq(f0 * 2, fs);
|
||||
SpiPs_write_read1(0x186, 0x01,&rx_data);
|
||||
SpiPs_write_read1(0x763, 0x34,&rx_data);
|
||||
SpiPs_write_read1(0x76D, 0x34,&rx_data);
|
||||
SpiPs_write_read1(0x101, 0xEF,&rx_data);
|
||||
SpiPs_write_read1(0x101, 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x800, 0x00,&rx_data);
|
||||
SpiPs_write_read1(0x81A, 0xF7,&rx_data);
|
||||
SpiPs_write_read1(0x81B, 0x34,&rx_data);
|
||||
SpiPs_write_read1(0x81C, 0x33,&rx_data);
|
||||
SpiPs_write_read1(0x81D, 0x12,&rx_data);
|
||||
SpiPs_write_read1(0x81E, 0x00,&rx_data);
|
||||
SpiPs_write_read1(0x81F, 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x820, 0x00,&rx_data);
|
||||
SpiPs_write_read1(0x821, 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x800, 0x80,&rx_data);
|
||||
SpiPs_write_read1(0x800, 0x81,&rx_data);
|
||||
usleep(100000);
|
||||
SpiPs_write_read1(0x77E, 0x00,&rx_data);
|
||||
}
|
||||
|
||||
void txBisectionDcCalib(int f0, int fs) {
|
||||
u8 rx_data;
|
||||
SpiPs_write_read1(0x77E, 0x24,&rx_data);
|
||||
SpiPs_write_read1(0x11F, 0x03,&rx_data);
|
||||
SpiPs_write_read1(0x121, 0x02,&rx_data);
|
||||
SpiPs_write_read1(0x11B, 0x01,&rx_data);
|
||||
SpiPs_write_read1(0x11E, 0x01,&rx_data);
|
||||
SpiPs_write_read1(0x161, 0x01,&rx_data);
|
||||
SpiPs_write_read1(0x162, 0x01,&rx_data);
|
||||
configTxNcoFreq(f0, fs * 4);
|
||||
SpiPs_write_read1(0xA2D, 0x02,&rx_data);
|
||||
SpiPs_write_read1(0xA07, 0x00,&rx_data);
|
||||
SpiPs_write_read1(0xA08, 0x0F,&rx_data);
|
||||
SpiPs_write_read1(0xA1C, 0x01,&rx_data);
|
||||
configRxNcoFreq(f0, fs);
|
||||
SpiPs_write_read1(0x81A, 0xF7,&rx_data);
|
||||
SpiPs_write_read1(0x81B, 0x44,&rx_data);
|
||||
SpiPs_write_read1(0x81C, 0x33,&rx_data);
|
||||
SpiPs_write_read1(0x81D, 0x14,&rx_data);
|
||||
SpiPs_write_read1(0x800, 0x80,&rx_data);
|
||||
SpiPs_write_read1(0x800, 0x82,&rx_data);
|
||||
usleep(500000);
|
||||
SpiPs_write_read1(0x77E, 0x00,&rx_data);
|
||||
}
|
||||
@@ -0,0 +1,905 @@
|
||||
/*
|
||||
* xilinx_io.c
|
||||
*
|
||||
* Created on: 2021年9月6日
|
||||
* Author: cxlab
|
||||
*/
|
||||
|
||||
|
||||
#include "sleep.h"
|
||||
#include "math.h"
|
||||
#include "xilinx_io.h" /* SPI device driver */
|
||||
|
||||
static XSpiPs SpiInstance;
|
||||
XGpioPs Gpio; /* The driver instance for GPIO Device. */
|
||||
XGpio axi_gpio_inst; //PL 端 AXI GPIO 驱动实例
|
||||
XScuGic scugic_inst; //中断控制器 驱动实例
|
||||
XScuGic_Config * scugic_cfg_ptr; //中断控制器 配置信息
|
||||
int hop_flag,hop_intr_flag;
|
||||
static int spi_select_value=0;
|
||||
|
||||
XAxiDma AxiDma0,AxiDma1,AxiDma2;
|
||||
|
||||
XAxiDma* xAxiDma0Get(void){
|
||||
return &AxiDma0;
|
||||
}
|
||||
|
||||
XAxiDma* xAxiDma1Get(void){
|
||||
return &AxiDma1;
|
||||
}
|
||||
|
||||
XAxiDma* xAxiDma2Get(void){
|
||||
return &AxiDma2;
|
||||
}
|
||||
void AXIGpioInit(void){
|
||||
XGpio_Initialize(&axi_gpio_inst, AXI_GPIO_ID);
|
||||
//配置 PL AXI GPIO
|
||||
XGpio_SetDataDirection(&axi_gpio_inst, 1, 1); //设置 AXI GPIO 通道 1 为输入
|
||||
XGpio_InterruptEnable(&axi_gpio_inst, KEY_MASK); //使能通道 1 中断
|
||||
XGpio_InterruptGlobalEnable(&axi_gpio_inst); //使能 AXI GPIO 全局中断
|
||||
}
|
||||
|
||||
void ConfigAXIGPIOIntr(void){
|
||||
//设置中断优先级和触发类型(高电平触发)
|
||||
XScuGic_SetPriorityTriggerType(&scugic_inst, GPIO_INT_ID, 0xA0, 0x3);
|
||||
//关联中断 ID 和中断处理函数
|
||||
XScuGic_Connect(&scugic_inst, GPIO_INT_ID, axi_gpio_handler, &axi_gpio_inst);
|
||||
//使能 AXI GPIO 中断
|
||||
XScuGic_Enable(&scugic_inst, GPIO_INT_ID);
|
||||
}
|
||||
void axi_gpio_handler(void *CallbackRef){
|
||||
XGpio *GpioPtr = (XGpio *)CallbackRef;
|
||||
// print("Interrupt Detected!\n");
|
||||
GpioWritePin(hop,0x01);
|
||||
XGpio_InterruptDisable(GpioPtr, KEY_MASK); //关闭 AXI GPIO 中断使能
|
||||
// u32 r=XGpio_DiscreteRead(GpioPtr, 1);
|
||||
// if(r == 1){
|
||||
frqhop_config(hop_flag);
|
||||
// }else{
|
||||
// print("Interrupt unvalid!\n");
|
||||
// }
|
||||
XGpio_InterruptClear(GpioPtr, KEY_MASK); //清除中断
|
||||
XGpio_InterruptEnable(GpioPtr, KEY_MASK); //使能 AXI GPIO 中断
|
||||
GpioWritePin(hop,0x00);
|
||||
}
|
||||
void frqhop_flag(int frqhop_flag){
|
||||
u8 rx_data;
|
||||
hop_flag = frqhop_flag;
|
||||
GpioSetPinDir(hop,GPIO_DIR_OUTPUT);
|
||||
GpioWritePin(hop,0x01);
|
||||
SpiPs_write_read2(0x615,0x00,&rx_data);
|
||||
GpioWritePin(hop,0x00);
|
||||
}
|
||||
|
||||
void ExceptionInit(void){
|
||||
//设置并打开中断异常处理功能
|
||||
Xil_ExceptionInit();
|
||||
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler)XScuGic_InterruptHandler, &scugic_inst);
|
||||
Xil_ExceptionEnable();
|
||||
}
|
||||
void XScuGicInit(void){
|
||||
scugic_cfg_ptr = XScuGic_LookupConfig(SCUGIC_ID);
|
||||
XScuGic_CfgInitialize(&scugic_inst, scugic_cfg_ptr, scugic_cfg_ptr->CpuBaseAddress);
|
||||
}
|
||||
|
||||
int SpiPsInit(u16 SpiDeviceId){
|
||||
int Status;
|
||||
XSpiPs_Config *SpiConfig;
|
||||
/*
|
||||
* Initialize the SPI driver so that it's ready to use
|
||||
*/
|
||||
SpiConfig = XSpiPs_LookupConfig(SpiDeviceId);
|
||||
if (NULL == SpiConfig) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
Status = XSpiPs_CfgInitialize((&SpiInstance), SpiConfig,
|
||||
SpiConfig->BaseAddress);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform a self-test to check hardware build
|
||||
*/
|
||||
Status = XSpiPs_SelfTest((&SpiInstance));
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
/*
|
||||
* The SPI device is a slave by default and the clock phase
|
||||
* have to be set according to its master. In this example, CPOL is set
|
||||
* to quiescent high and CPHA is set to 1.
|
||||
*/
|
||||
|
||||
XSpiPs_SetOptions((&SpiInstance), (XSPIPS_CR_CPHA_MASK) |
|
||||
XSPIPS_MASTER_OPTION |
|
||||
XSPIPS_FORCE_SSELECT_OPTION);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
XSpiPs_SetClkPrescaler((&SpiInstance), XSPIPS_CLK_PRESCALE_8);
|
||||
/*
|
||||
* Set the Rx FIFO Threshold to the Max Data
|
||||
*/
|
||||
// XSpiPs_SetRXWatermark((&SpiInstance),MAX_DATA);
|
||||
/*
|
||||
* Enable the device.
|
||||
*/
|
||||
XSpiPs_Enable((&SpiInstance));
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
int cx3e04_write(int addr , int value)
|
||||
{
|
||||
Xil_Out32(AXI4_LITE0_SPI_BASEADDR+addr*4,value);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cx3e04_read(int addr)
|
||||
{
|
||||
return Xil_In32(AXI4_LITE0_SPI_BASEADDR+addr*4);
|
||||
}
|
||||
|
||||
int cx9261a_write(int addr , int value)
|
||||
{
|
||||
Xil_Out32(AXI4_LITE1_SPI_BASEADDR+addr*4,value);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cx9261a_read(int addr)
|
||||
{
|
||||
return Xil_In32(AXI4_LITE1_SPI_BASEADDR+addr*4);
|
||||
}
|
||||
|
||||
void cx3e04_config(void)
|
||||
{
|
||||
//城芯科技CX3E04
|
||||
//Common
|
||||
cx3e04_write(0x000,0x12);
|
||||
cx3e04_write(0x002,0x38);
|
||||
cx3e04_write(0x038,0x01);
|
||||
cx3e04_write(0x003,0x30);
|
||||
cx3e04_write(0x039,0x00);
|
||||
//CLK
|
||||
//clk lvds en
|
||||
cx3e04_write(0x011,0x7F);
|
||||
cx3e04_write(0x012,0x34);
|
||||
cx3e04_write(0x036,0x7F);
|
||||
cx3e04_write(0x01A,0x4B);
|
||||
cx3e04_write(0x013,0x04);
|
||||
cx3e04_write(0x014,0x04);
|
||||
cx3e04_write(0x004,0x00);
|
||||
cx3e04_write(0x008,0x00);
|
||||
cx3e04_write(0x009,0x00);
|
||||
cx3e04_write(0x015,0x04);
|
||||
cx3e04_write(0x016,0x04);
|
||||
cx3e04_write(0x005,0x00);
|
||||
cx3e04_write(0x00A,0x00);
|
||||
cx3e04_write(0x00B,0x00);
|
||||
cx3e04_write(0x017,0x04);
|
||||
cx3e04_write(0x018,0x04);
|
||||
cx3e04_write(0x006,0x00);
|
||||
cx3e04_write(0x00C,0x00);
|
||||
cx3e04_write(0x00D,0x00);
|
||||
cx3e04_write(0x019,0x04);
|
||||
cx3e04_write(0x007,0x00);
|
||||
cx3e04_write(0x00E,0x00);
|
||||
cx3e04_write(0x00F,0x00);
|
||||
cx3e04_write(0x010,0x00);
|
||||
cx3e04_write(0x029,0x00);
|
||||
cx3e04_write(0x02A,0x00);
|
||||
//SYNC
|
||||
//sync lvds en
|
||||
cx3e04_write(0x033,0x7F);
|
||||
cx3e04_write(0x034,0x34);
|
||||
cx3e04_write(0x035,0x7F);
|
||||
cx3e04_write(0x032,0x03);
|
||||
//sync inner div
|
||||
cx3e04_write(0x03A,0x00);
|
||||
cx3e04_write(0x03B,0x00);
|
||||
cx3e04_write(0x03A,0x01);
|
||||
cx3e04_write(0x03B,0xFF);//512分频
|
||||
cx3e04_write(0x03C,0x21);
|
||||
cx3e04_write(0x03D,0x80);
|
||||
cx3e04_write(0x02B,0x04);
|
||||
cx3e04_write(0x02C,0x04);
|
||||
cx3e04_write(0x01B,0x00);
|
||||
cx3e04_write(0x01C,0x00);
|
||||
cx3e04_write(0x022,0x00);
|
||||
cx3e04_write(0x023,0x00);
|
||||
cx3e04_write(0x02D,0x04);
|
||||
cx3e04_write(0x02E,0x04);
|
||||
cx3e04_write(0x01D,0x00);
|
||||
cx3e04_write(0x01E,0x00);
|
||||
cx3e04_write(0x024,0x00);
|
||||
cx3e04_write(0x025,0x00);
|
||||
cx3e04_write(0x02F,0x04);
|
||||
cx3e04_write(0x030,0x04);
|
||||
cx3e04_write(0x01F,0x00);
|
||||
cx3e04_write(0x020,0x00);
|
||||
cx3e04_write(0x026,0x00);
|
||||
cx3e04_write(0x027,0x00);
|
||||
cx3e04_write(0x031,0x04);
|
||||
cx3e04_write(0x021,0x00);
|
||||
cx3e04_write(0x028,0x00);
|
||||
//偏置电流
|
||||
cx3e04_write(0x040,0xFF);
|
||||
cx3e04_write(0x041,0xFF);
|
||||
cx3e04_write(0x042,0xFF);
|
||||
cx3e04_write(0x043,0xF0);
|
||||
cx3e04_write(0x044,0xFF);
|
||||
cx3e04_write(0x045,0xFF);
|
||||
cx3e04_write(0x046,0xFF);
|
||||
cx3e04_write(0x047,0xF0);
|
||||
//Others
|
||||
cx3e04_write(0x037,0x07);
|
||||
}
|
||||
|
||||
//int SpiPs_write_read(u8 cmd, u16 addr,u8 data,u8 * rx_data){
|
||||
int SpiPs_write_read(u8 * data,u8 * rx_data){
|
||||
int Status;
|
||||
u8 rx_buffer[3];
|
||||
|
||||
if(spi_select_value == 0){
|
||||
rx_buffer[0]= *data;
|
||||
rx_buffer[1]= *(data+1);
|
||||
rx_buffer[2]= *(data+2);
|
||||
if(rx_buffer[0] >= 128){
|
||||
cx9261a_write((rx_buffer[0]-128)*256+rx_buffer[1],rx_buffer[2]);
|
||||
}else{
|
||||
*rx_data=cx9261a_read(rx_buffer[0]*256+rx_buffer[1]);
|
||||
}
|
||||
}else{
|
||||
|
||||
XSpiPs_SetSlaveSelect((&SpiInstance),0x00);
|
||||
|
||||
Status = XSpiPs_PolledTransfer((&SpiInstance),data,rx_buffer,3);
|
||||
|
||||
*rx_data = rx_buffer[2];
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
int SpiPs_write_read1(u16 addr,u8 data,u8 * rx_data){
|
||||
u8 rx_data1;
|
||||
u16 temp;
|
||||
u8 rx_buffer[3];
|
||||
|
||||
temp= addr&0x00ff;
|
||||
rx_buffer[0]= temp/256+128;
|
||||
rx_buffer[1]= addr&0x00ff;
|
||||
rx_buffer[2]= data;
|
||||
|
||||
if(spi_select_value == 0){
|
||||
cx9261a_write(addr,data);
|
||||
}else{
|
||||
|
||||
SpiPs_write_read((u8 *)&rx_buffer,&rx_data1);
|
||||
*rx_data = rx_data1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
int SpiPs_write_read2(u16 addr,u8 data,u8 * rx_data){
|
||||
u8 rx_data1;
|
||||
u16 temp;
|
||||
u8 rx_buffer[3];
|
||||
|
||||
temp= addr&0x00ff;
|
||||
rx_buffer[0]= temp/256;
|
||||
rx_buffer[1]= addr&0x00ff;
|
||||
rx_buffer[2]= data;
|
||||
|
||||
if(spi_select_value == 0){
|
||||
*rx_data=cx9261a_read(addr);
|
||||
}else{
|
||||
SpiPs_write_read((u8 *)&rx_buffer,&rx_data1);
|
||||
*rx_data = rx_data1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GpioInit(u16 DeviceId)
|
||||
{
|
||||
int Status;
|
||||
XGpioPs_Config *ConfigPtr;
|
||||
/* Initialize the GPIO driver. */
|
||||
ConfigPtr = XGpioPs_LookupConfig(DeviceId);
|
||||
Status = XGpioPs_CfgInitialize(&Gpio, ConfigPtr,
|
||||
ConfigPtr->BaseAddr);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
int GpioSetPinDir(u32 Pin,u32 Direction){
|
||||
XGpioPs_SetDirectionPin((&Gpio),GPIO_EMIO_OFFSET + Pin,Direction);
|
||||
return 0;
|
||||
}
|
||||
int GpioWritePin(u32 Pin,u32 data){
|
||||
XGpioPs_SetOutputEnablePin(&Gpio, GPIO_EMIO_OFFSET + Pin, 1);
|
||||
XGpioPs_WritePin((&Gpio),GPIO_EMIO_OFFSET + Pin,data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GpioReadPin(u32 Pin){
|
||||
return XGpioPs_ReadPin((&Gpio),GPIO_EMIO_OFFSET + Pin);
|
||||
}
|
||||
|
||||
void DeviceRst(void){
|
||||
GpioWritePin(NRST,0);
|
||||
GpioWritePin(NRST,1);
|
||||
}
|
||||
|
||||
int XAxiDma_Init(XAxiDma* AxiDma,u16 DeviceId){
|
||||
|
||||
XAxiDma_Config *CfgPtr;
|
||||
int Status;
|
||||
/* Initialize the XAxiDma device.
|
||||
*/
|
||||
CfgPtr = XAxiDma_LookupConfig(DeviceId);
|
||||
if (!CfgPtr) {
|
||||
xil_printf("No config found for %d\r\n", DeviceId);
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
Status = XAxiDma_CfgInitialize(AxiDma, CfgPtr);
|
||||
if (Status != XST_SUCCESS) {
|
||||
xil_printf("Initialization failed %d\r\n", Status);
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
if(XAxiDma_HasSg(AxiDma)){
|
||||
xil_printf("Device configured as SG mode \r\n");
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/* Disable interrupts, we use polling mode
|
||||
*/
|
||||
XAxiDma_IntrDisable(AxiDma, XAXIDMA_IRQ_ALL_MASK,
|
||||
XAXIDMA_DEVICE_TO_DMA);
|
||||
XAxiDma_IntrDisable(AxiDma, XAXIDMA_IRQ_ALL_MASK,
|
||||
XAXIDMA_DMA_TO_DEVICE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int XAxiDmaCapture(XAxiDma* AxiDma,u32 data_length){
|
||||
int Status;
|
||||
u8 *TxBufferPtr;
|
||||
u32 MAX_PKT_LEN;
|
||||
MAX_PKT_LEN = data_length;
|
||||
TxBufferPtr = (u8 *)TX_BUFFER_BASE;
|
||||
Xil_DCacheFlushRange((UINTPTR)TxBufferPtr, MAX_PKT_LEN);
|
||||
Status = XAxiDma_Busy(AxiDma,XAXIDMA_DEVICE_TO_DMA);
|
||||
Status = XAxiDma_Busy(AxiDma,XAXIDMA_DMA_TO_DEVICE);
|
||||
XAxiDma_Reset(AxiDma);
|
||||
Status = XAxiDma_ResetIsDone(AxiDma);
|
||||
Status = XAxiDma_Busy(AxiDma,XAXIDMA_DEVICE_TO_DMA);
|
||||
Status = XAxiDma_Busy(AxiDma,XAXIDMA_DMA_TO_DEVICE);
|
||||
|
||||
Status = XAxiDma_SimpleTransfer(AxiDma,(UINTPTR) TxBufferPtr,MAX_PKT_LEN*8, XAXIDMA_DEVICE_TO_DMA);
|
||||
SetPacketSize(AxiDma,MAX_PKT_LEN);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
u32 start_TickCount,current_TickCount=0;
|
||||
start_TickCount = sys_now();
|
||||
u32 offset= 0;
|
||||
//never come out ,reason is stream does't have tlast.Need a module to pack excatly the same length defined in para.
|
||||
while ((offset< 500)&&(XAxiDma_Busy(AxiDma,XAXIDMA_DEVICE_TO_DMA))) {
|
||||
Status = XAxiDma_Busy(AxiDma,XAXIDMA_DEVICE_TO_DMA);
|
||||
|
||||
current_TickCount =sys_now();
|
||||
offset = current_TickCount-start_TickCount;
|
||||
// xil_printf("offset: %d\r\n", offset);
|
||||
}
|
||||
/*
|
||||
u64 offset= 0;
|
||||
//never come out ,reason is stream does't have tlast.Need a module to pack excatly the same length defined in para.
|
||||
while ((offset> 100000)||(XAxiDma_Busy(AxiDma,XAXIDMA_DEVICE_TO_DMA))) {
|
||||
Status = XAxiDma_Busy(AxiDma,XAXIDMA_DEVICE_TO_DMA);
|
||||
}*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int SetPacketSize(XAxiDma* AxiDma,u32 length){
|
||||
|
||||
UINTPTR Addr;
|
||||
if(AxiDma == xAxiDma0Get())
|
||||
Addr = PACKER_BASEADDR0;
|
||||
else if(AxiDma == xAxiDma1Get())
|
||||
Addr = PACKER_BASEADDR1;
|
||||
else
|
||||
Addr = PACKER_BASEADDR2;
|
||||
xil_printf("addr %x .\n",Addr);
|
||||
Xil_Out32(Addr,0);
|
||||
xil_printf("PACKER_BASEADDR DATA %d .\n",Xil_In32(Addr));
|
||||
Xil_Out32(Addr+4,length);
|
||||
xil_printf("PACKER_BASEADDR +4 DATA %d .\n",Xil_In32(Addr + 4));
|
||||
Xil_Out32(Addr,1);
|
||||
xil_printf("PACKER_BASEADDR DATA %d .\n",Xil_In32(Addr));
|
||||
return 0;
|
||||
}
|
||||
int DownloadWave(u8 * data){
|
||||
u32 * buffer;
|
||||
u64 addr;
|
||||
int i;
|
||||
buffer = (u32 *) data;
|
||||
addr = BRAM_BASEADDR;
|
||||
for(i=0;i<WAVELENGTH;i++){
|
||||
Xil_Out32(addr+i*4,* (buffer +i));
|
||||
// Xil_Out32(addr+i*4,0x11223344);
|
||||
// xil_printf("ADDR 0x%x DATA 0x%x.\r\n",(buffer +i), * (buffer +i));
|
||||
}
|
||||
addr = BRAM_BASEADDR_1;
|
||||
for(i=0;i<WAVELENGTH;i++){
|
||||
Xil_Out32(addr+i*4,* (buffer +i));
|
||||
// Xil_Out32(addr+i*4,0x11223344);
|
||||
// xil_printf("ADDR 0x%x DATA 0x%x.\r\n",(buffer +i), * (buffer +i));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
void dbg_printf( const char8 *ctrl1, ...){
|
||||
#ifdef DBGLOG
|
||||
xil_printf( ctrl1 );
|
||||
#endif
|
||||
}
|
||||
void PackerRst(void){
|
||||
GpioSetPinDir(0x03,GPIO_DIR_OUTPUT);
|
||||
GpioWritePin(3,0x0);//dma_axis_rx_rstn
|
||||
GpioWritePin(3,0x01);//dma_axis_rx_rstn
|
||||
GpioSetPinDir(0x09,GPIO_DIR_OUTPUT);
|
||||
GpioWritePin(9,0x01);//data_valid
|
||||
}
|
||||
int peripheral_test(void){
|
||||
u8 spi_test;
|
||||
u8 Gpio_test;
|
||||
u8 BRAM_test;
|
||||
u8 DDR_test;
|
||||
// SPI TEST
|
||||
u8 rx_data;
|
||||
xil_printf("start spi test.\r\n");
|
||||
u8 spi_wr_buff[3]={0x87,0x82,0x5A};
|
||||
u8 spi_rd_buff[3]={0x07,0x82,0x00};
|
||||
SpiPs_write_read(spi_wr_buff,&rx_data);
|
||||
SpiPs_write_read(spi_rd_buff,&rx_data);
|
||||
if(rx_data==spi_wr_buff[2])
|
||||
{
|
||||
xil_printf("spi test successful.\r\n");
|
||||
spi_test = 1;
|
||||
}else
|
||||
{
|
||||
xil_printf("spi test unsuccessful.\r\n");
|
||||
spi_test = 0;
|
||||
}
|
||||
|
||||
|
||||
//BRAM TEST
|
||||
xil_printf("start bram test.\r\n");
|
||||
BRAM_test = 1;
|
||||
//for (int i=0;i<8192;i++){
|
||||
// Xil_Out32(XPAR_BRAM_0_BASEADDR + 4*i,i);
|
||||
// if(i != Xil_In32(XPAR_BRAM_0_BASEADDR + 4*i)){
|
||||
//// xil_printf("BRAM ERROR,ADDR %x DATA %d read back is %d.\r\n",XPAR_BRAM_0_BASEADDR + 4*i,i,Xil_In32(XPAR_BRAM_0_BASEADDR + 4*i));
|
||||
// BRAM_test = 0;
|
||||
// }
|
||||
//// else{
|
||||
//// xil_printf("BRAM PASS,ADDR %x DATA %d read back is %d.\r\n",XPAR_BRAM_0_BASEADDR + 4*i,i,Xil_In32(XPAR_BRAM_0_BASEADDR + 4*i));
|
||||
//// }
|
||||
//}
|
||||
|
||||
//MIG TEST
|
||||
xil_printf("start mig test.\r\n");
|
||||
DDR_test = 1;
|
||||
for (int i=0;i<2048;i++){
|
||||
Xil_Out32(TX_BUFFER_BASE + 4*i,i);
|
||||
if(i != Xil_In32(TX_BUFFER_BASE + 4*i)){
|
||||
// xil_printf("MIG ERROR,ADDR %x DATA %d read back is %d.\r\n",TX_BUFFER_BASE + 4*i,i,Xil_In32(TX_BUFFER_BASE + 4*i));
|
||||
DDR_test = 0;
|
||||
}
|
||||
// else{
|
||||
// xil_printf("BRAM11 PASS,ADDR %x DATA %d read back is %d.\r\n",TX_BUFFER_BASE + 4*i,i,Xil_In32(TX_BUFFER_BASE + 4*i));
|
||||
// }
|
||||
}
|
||||
|
||||
// GPIO TEST
|
||||
int Gpio_data;
|
||||
xil_printf("start gpio test.\r\n");
|
||||
GpioSetPinDir(NRST,GPIO_DIR_OUTPUT);
|
||||
GpioWritePin(NRST,0x00);
|
||||
GpioWritePin(NRST,0x01);
|
||||
GpioSetPinDir(rst,GPIO_DIR_OUTPUT);
|
||||
GpioWritePin(rst,0x01);
|
||||
GpioWritePin(rst,0x00);
|
||||
GpioSetPinDir(aresetn_0,GPIO_DIR_OUTPUT);
|
||||
GpioWritePin(aresetn_0,0x00);
|
||||
GpioWritePin(aresetn_0,0x01);
|
||||
GpioSetPinDir(aresetn_1,GPIO_DIR_OUTPUT);
|
||||
GpioWritePin(aresetn_1,0x00);
|
||||
GpioWritePin(aresetn_1,0x01);
|
||||
GpioSetPinDir(aresetn_2,GPIO_DIR_OUTPUT);
|
||||
GpioWritePin(aresetn_2,0x00);
|
||||
GpioWritePin(aresetn_2,0x01);
|
||||
GpioSetPinDir(debug_mode,GPIO_DIR_OUTPUT);
|
||||
GpioWritePin(debug_mode,0x00);
|
||||
GpioSetPinDir(cx3e04_rstn,GPIO_DIR_OUTPUT);
|
||||
GpioWritePin(cx3e04_rstn,0x01);
|
||||
GpioSetPinDir(spi_select,GPIO_DIR_OUTPUT);
|
||||
GpioWritePin(spi_select,spi_select_value&0xff);
|
||||
//GpioSetPinDir(test_temp,GPIO_DIR_INPUT);
|
||||
Gpio_data=GpioReadPin(aresetn_1);
|
||||
if(Gpio_data==1)
|
||||
{
|
||||
xil_printf("GPIO test successful.\r\n");
|
||||
Gpio_test = 1;
|
||||
}else
|
||||
{
|
||||
xil_printf("GPIO test unsuccessful.\r\n");
|
||||
Gpio_test = 0;
|
||||
}
|
||||
//GpioSetPinDir(test_temp,GPIO_DIR_OUTPUT);
|
||||
//GpioWritePin(test_temp,0x01);
|
||||
|
||||
if((spi_test==1)&&(Gpio_test==1)&&(BRAM_test==1)&&(DDR_test==1))
|
||||
{
|
||||
xil_printf("peripheral test successful.\r\n");
|
||||
return 1;
|
||||
}else
|
||||
{
|
||||
xil_printf("peripheral test unsuccessful.\r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int spi_stack_in(u8 * data,struct spi_stack * spistack){
|
||||
spistack->recv_buf[spistack->spi_write_num * 3 + 0] = *(data + 0);
|
||||
spistack->recv_buf[spistack->spi_write_num * 3 + 1] = *(data + 1);
|
||||
spistack->recv_buf[spistack->spi_write_num * 3 + 2] = *(data + 2);
|
||||
spistack->spi_write_num = spistack->spi_write_num + 1;
|
||||
if(spistack->spi_write_num >= SPI_STACK_LENGTH-1){
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void spi_stack_out(struct spi_stack * spistack){
|
||||
|
||||
int i;
|
||||
u8 rx_data;
|
||||
for(i=0;i<spistack->spi_write_num;i++ ){
|
||||
SpiPs_write_read((u8 *)&(spistack->recv_buf[i * 3]),&rx_data);
|
||||
}
|
||||
spistack->spi_write_num = 0;
|
||||
}
|
||||
|
||||
int rom_read(u8 * data)
|
||||
{
|
||||
int addr ;
|
||||
addr = *(data + 0)*256+ *(data + 1);
|
||||
return Xil_In32(BROM_BASEADDR+addr*4);
|
||||
}
|
||||
|
||||
void trx_ch_pll_config(u8 pll_index)
|
||||
{
|
||||
u8 rx_data;
|
||||
u8 recv_buf[3]={0};
|
||||
u32 trx_ch_pll_data;
|
||||
|
||||
if(pll_index==1){
|
||||
trx_ch_pll_data = 0x00077DCF;
|
||||
}else if(pll_index==2){
|
||||
trx_ch_pll_data = 0x00077D0C;
|
||||
}
|
||||
|
||||
recv_buf[0] =(trx_ch_pll_data>>16 & 0xff)|0x80 ;
|
||||
recv_buf[1] = trx_ch_pll_data>>8 & 0xff;
|
||||
recv_buf[2] = trx_ch_pll_data & 0xff;
|
||||
SpiPs_write_read(recv_buf,&rx_data);
|
||||
}
|
||||
|
||||
u16 pll1_config_addr[] ={0x0620,0x061D,0x0B06,0x0B07,0x0B08,0x0B09,0x0B0A,0x061A,0x061B,0x061C,0x062A};
|
||||
u16 pll2_config_addr[] ={0x0642,0x063F,0x0B14,0x0B15,0x0B16,0x0B17,0x0B18,0x063C,0x063D,0x063E,0x064C};
|
||||
u16 pll3_config_addr[] ={0x0664,0x0661,0x0B22,0x0B23,0x0B24,0x0B25,0x0B26,0x065E,0x065F,0x0660,0x066E};
|
||||
u16 pll4_config_addr[] ={0x0686,0x0683,0x0B30,0x0B31,0x0B32,0x0B33,0x0B34,0x0680,0x0681,0x0682,0x0690};
|
||||
|
||||
int PLL_config(u8 pll_index,double pll_frq)
|
||||
{
|
||||
|
||||
int i = 0,afc_cnt=0;
|
||||
u16 pll_config_addr[11];
|
||||
u16 afc_addr,lock_addr;
|
||||
double ref=200;
|
||||
u8 pllreg_buf[11];
|
||||
u8 recv_buf[3];
|
||||
u8 rx_data,pll_div;
|
||||
u16 div_addr;
|
||||
|
||||
switch(pll_index){
|
||||
case 1:for (i = 0; i < 11; i++){pll_config_addr[i] = pll1_config_addr[i];} afc_addr=0x0617;lock_addr=0x0635;break;
|
||||
case 2:for (i = 0; i < 11; i++){pll_config_addr[i] = pll2_config_addr[i];} afc_addr=0x0639;lock_addr=0x0657;break;
|
||||
case 3:for (i = 0; i < 11; i++){pll_config_addr[i] = pll3_config_addr[i];} afc_addr=0x065B;lock_addr=0x0679;break;
|
||||
case 4:for (i = 0; i < 11; i++){pll_config_addr[i] = pll4_config_addr[i];} afc_addr=0x067D;lock_addr=0x069B;break;
|
||||
default :;
|
||||
}
|
||||
//caculate pll frequence word
|
||||
pll_frq_caculation_new(ref,pll_frq,(u8 *)&pllreg_buf);
|
||||
for (i = 0; i < 11; i++)
|
||||
{
|
||||
recv_buf[0] = (pll_config_addr[i]>>8 & 0xff)|0x80 ;
|
||||
recv_buf[1] = pll_config_addr[i] & 0xff;
|
||||
recv_buf[2] = pllreg_buf[i] & 0xff;
|
||||
SpiPs_write_read((u8 *)&recv_buf[0],&rx_data);
|
||||
}
|
||||
//afc pll
|
||||
pll_div = pllreg_buf[1];
|
||||
div_addr = pll_config_addr[1];
|
||||
recv_buf[0] = lock_addr>>8 & 0xff ;
|
||||
recv_buf[1] = lock_addr & 0xff;
|
||||
recv_buf[2] = 0x00;
|
||||
rx_data = 0;
|
||||
while(rx_data!=48){
|
||||
PLL_afc(afc_addr,div_addr,pll_div);
|
||||
SpiPs_write_read((u8 *)&recv_buf[0],&rx_data);
|
||||
afc_cnt++;
|
||||
}
|
||||
return afc_cnt;
|
||||
//xil_printf("afc lock count: %d.\r\n",afc_cnt);
|
||||
|
||||
}
|
||||
|
||||
void PLL_afc(u16 afc_addr,u16 div_addr,u8 pll_div){
|
||||
|
||||
u8 recv_buf[3];
|
||||
u8 rx_data;
|
||||
if(pll_div>=48){
|
||||
recv_buf[0] = (div_addr>>8 & 0xff)|0x80 ;
|
||||
recv_buf[1] = div_addr & 0xff;
|
||||
recv_buf[2] = pll_div & 0x2f;
|
||||
SpiPs_write_read((u8 *)&recv_buf[0],&rx_data);
|
||||
}
|
||||
recv_buf[0] = (afc_addr>>8 & 0xff)|0x80 ;
|
||||
recv_buf[1] = afc_addr & 0xff;
|
||||
recv_buf[2] = 0x00;
|
||||
SpiPs_write_read((u8 *)&recv_buf[0],&rx_data);
|
||||
recv_buf[2] = 0x03;
|
||||
SpiPs_write_read((u8 *)&recv_buf[0],&rx_data);
|
||||
usleep(30);
|
||||
if(pll_div>=48){
|
||||
recv_buf[0] = (div_addr>>8 & 0xff)|0x80 ;
|
||||
recv_buf[1] = div_addr & 0xff;
|
||||
recv_buf[2] = pll_div & 0xff;
|
||||
SpiPs_write_read((u8 *)&recv_buf[0],&rx_data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int pll_frq_caculation(double ref,double pll_frq,u8 *reg_data){
|
||||
|
||||
u8 row,column;
|
||||
int vco = pll_frq;
|
||||
int div = 1;
|
||||
while(vco < 7001){
|
||||
vco = vco*2;
|
||||
div = div*2;
|
||||
}
|
||||
char coreTable[7][4][3] = {{{0x0C,0x30,0x08},{0x0B,0x30,0x09},{0x0C,0x30,0x05},{0x0D,0x30,0x08}},
|
||||
{{0x0C,0x30,0x0C},{0x0B,0x30,0x0E},{0x0C,0x30,0x08},{0x0D,0x30,0x0B}},
|
||||
{{0x0C,0x20,0x10},{0x0B,0x20,0x10},{0x0C,0x20,0x0A},{0x0D,0x20,0x0D}},
|
||||
{{0x0C,0x20,0x11},{0x0B,0x20,0x13},{0x0C,0x20,0x0C},{0x0D,0x20,0x0F}},
|
||||
{{0x0D,0x30,0x14},{0x0D,0x22,0x14},{0x0D,0x20,0x0D},{0x0D,0x15,0x0C}},
|
||||
{{0x0E,0x30,0x18},{0x0E,0x25,0x16},{0x0E,0x25,0x0F},{0x0E,0x18,0x0F}},
|
||||
{{0x0F,0x38,0x1A},{0x0F,0x32,0x1C},{0x0F,0x18,0x12},{0x0F,0x18,0x12}}};
|
||||
|
||||
if (ref >= 28 && ref < 40){
|
||||
row = 0;
|
||||
}else if (ref >= 40 && ref < 60){
|
||||
row = 1;
|
||||
}else if (ref >= 60 && ref < 90){
|
||||
row = 2;
|
||||
}else if (ref >= 90 && ref < 110){
|
||||
row = 3;
|
||||
}else if (ref >= 110 && ref < 140){
|
||||
row = 4;
|
||||
}else if (ref >= 140 && ref < 180){
|
||||
row = 5;
|
||||
}else if (ref >= 180 && ref <= 240){
|
||||
row = 6;
|
||||
}
|
||||
|
||||
if (vco >= 7001 && vco < 8400){
|
||||
column = 0;
|
||||
}else if (vco >= 8400 && vco < 10500){
|
||||
column = 1;
|
||||
}else if (vco >= 10500 && vco < 12000){
|
||||
column = 2;
|
||||
}else if (vco >= 12000 && vco <= 14000){
|
||||
column = 3;
|
||||
}
|
||||
|
||||
char cp = coreTable[row][column][0];
|
||||
char c1r3 = coreTable[row][column][1];
|
||||
char r1 = coreTable[row][column][2];
|
||||
|
||||
char dither,nHigh,nLow,fHigh,fMiddle,fLow,outputDiv,core = 0x81;
|
||||
if(vco > 10500){
|
||||
core = core + 0x10;
|
||||
}
|
||||
if (div == 2){
|
||||
outputDiv = 0+7;
|
||||
}else if (div == 4){
|
||||
outputDiv = 32+7;
|
||||
}else{
|
||||
outputDiv = 48 + divBin(div);
|
||||
}
|
||||
|
||||
double nf = 1.0*vco / ref;
|
||||
int n = nf;
|
||||
double f = nf - n;
|
||||
if(f > 1e-10){
|
||||
dither = 11;
|
||||
}else{
|
||||
dither = 0;
|
||||
}
|
||||
if(n >= 256){
|
||||
nHigh = 1;
|
||||
}else{
|
||||
nHigh = 0;
|
||||
}
|
||||
nLow = n & 0xff;
|
||||
int f1 = f * pow(2,24);
|
||||
fHigh = f1>>16 & 0xff;
|
||||
fMiddle = f1>>8 & 0xff;
|
||||
fLow = f1 & 0xff;
|
||||
reg_data[0]=core;
|
||||
reg_data[1]=outputDiv;
|
||||
reg_data[2]=nHigh;
|
||||
reg_data[3]=nLow;
|
||||
reg_data[4]=fHigh;
|
||||
reg_data[5]=fMiddle;
|
||||
reg_data[6]=fLow;
|
||||
reg_data[7]=cp;
|
||||
reg_data[8]=c1r3;
|
||||
reg_data[9]=r1;
|
||||
reg_data[10]=dither;
|
||||
return 0;
|
||||
}
|
||||
int pll_frq_caculation_new(double ref,double pll_frq,u8 *reg_data){
|
||||
|
||||
u8 row,column;
|
||||
double vco = pll_frq;
|
||||
int div = 1;
|
||||
while(vco < 6701){
|
||||
vco = vco*2;
|
||||
div = div*2;
|
||||
}
|
||||
char coreTable[7][4][3] = {{{0x0C,0x30,0x08},{0x0B,0x30,0x09},{0x0C,0x30,0x05},{0x0D,0x30,0x08}},
|
||||
{{0x0C,0x30,0x0C},{0x0B,0x30,0x0E},{0x0C,0x30,0x08},{0x0D,0x30,0x0B}},
|
||||
{{0x0C,0x20,0x10},{0x0B,0x20,0x10},{0x0C,0x20,0x0A},{0x0D,0x20,0x0D}},
|
||||
{{0x0C,0x20,0x11},{0x0B,0x20,0x13},{0x0C,0x20,0x0C},{0x0D,0x20,0x0F}},
|
||||
{{0x0D,0x30,0x14},{0x0D,0x22,0x14},{0x0D,0x20,0x0D},{0x0D,0x15,0x0C}},
|
||||
{{0x0E,0x30,0x18},{0x0E,0x25,0x16},{0x0E,0x25,0x0F},{0x0E,0x18,0x0F}},
|
||||
{{0x0F,0x38,0x1A},{0x0F,0x32,0x1C},{0x0F,0x18,0x12},{0x0F,0x18,0x12}}};
|
||||
|
||||
if (ref >= 28 && ref < 40){
|
||||
row = 0;
|
||||
}else if (ref >= 40 && ref < 60){
|
||||
row = 1;
|
||||
}else if (ref >= 60 && ref < 90){
|
||||
row = 2;
|
||||
}else if (ref >= 90 && ref < 110){
|
||||
row = 3;
|
||||
}else if (ref >= 110 && ref < 140){
|
||||
row = 4;
|
||||
}else if (ref >= 140 && ref < 180){
|
||||
row = 5;
|
||||
}else if (ref >= 180 && ref <= 240){
|
||||
row = 6;
|
||||
}
|
||||
|
||||
if (vco < 8400){
|
||||
column = 0;
|
||||
}else if (vco >= 8400 && vco < 10150){
|
||||
column = 1;
|
||||
}else if (vco >= 10150 && vco < 12000){
|
||||
column = 2;
|
||||
}else if (vco >= 12000 ){
|
||||
column = 3;
|
||||
}
|
||||
|
||||
char cp = coreTable[row][column][0];
|
||||
char c1r3 = coreTable[row][column][1];
|
||||
char r1 = coreTable[row][column][2];
|
||||
|
||||
char dither,nHigh,nLow,fHigh,fMiddle,fLow,outputDiv,core = 0x81;
|
||||
if(vco > 10150){
|
||||
core = core + 0x10;
|
||||
}
|
||||
if (div == 2){
|
||||
outputDiv = 0+7;
|
||||
}else if (div == 4){
|
||||
outputDiv = 32+7;
|
||||
}else{
|
||||
outputDiv = 48 + divBin(div);
|
||||
}
|
||||
|
||||
double nf = 1.0*vco / ref;
|
||||
int n = nf;
|
||||
double f = nf - n;
|
||||
if(f > 1e-10){
|
||||
dither = 11;
|
||||
}else{
|
||||
dither = 0;
|
||||
}
|
||||
if(n >= 256){
|
||||
nHigh = 1;
|
||||
}else{
|
||||
nHigh = 0;
|
||||
}
|
||||
nLow = n & 0xff;
|
||||
int f1 = f * pow(2,24);
|
||||
fHigh = f1>>16 & 0xff;
|
||||
fMiddle = f1>>8 & 0xff;
|
||||
fLow = f1 & 0xff;
|
||||
reg_data[0]=core;
|
||||
reg_data[1]=outputDiv;
|
||||
reg_data[2]=nHigh;
|
||||
reg_data[3]=nLow;
|
||||
reg_data[4]=fHigh;
|
||||
reg_data[5]=fMiddle;
|
||||
reg_data[6]=fLow;
|
||||
reg_data[7]=cp;
|
||||
reg_data[8]=c1r3;
|
||||
reg_data[9]=r1;
|
||||
reg_data[10]=dither;
|
||||
return 0;
|
||||
}
|
||||
char divBin(u16 div){
|
||||
|
||||
switch(div){
|
||||
case 8:return 7;break;
|
||||
case 16:return 6;break;
|
||||
case 32:return 5;break;
|
||||
case 64:return 4;break;
|
||||
case 128:return 3;break;
|
||||
case 256:return 2;break;
|
||||
default :return 2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void configTxNcoFreq(int freq, int fs) {
|
||||
u8 rx_data;
|
||||
double ratio = (double) freq < 0 ? (freq + fs) / fs : freq / fs;
|
||||
double bin = ratio * pow(2,48);
|
||||
int bin_low = (u32) bin & 0xFFFFFF;
|
||||
int bin_high = (u32)(bin / pow(2,24)) & 0xFFFFFF;
|
||||
SpiPs_write_read1(0x164, (bin_high >> 16) & 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x165, (bin_high >> 8) & 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x166, bin_high & 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x167, (bin_low >> 16) & 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x168, (bin_low >> 8) & 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0x169, bin_low & 0xFF,&rx_data);
|
||||
}
|
||||
void configRxNcoFreq(int freq, int fs) {
|
||||
u8 rx_data;
|
||||
double ratio = (double) freq < 0 ? (freq + fs) / fs : freq / fs;
|
||||
double bin = ratio * pow(2,48);
|
||||
int bin_low = (u32) bin & 0xFFFFFF;
|
||||
int bin_high = (u32)(bin / pow(2,24)) & 0xFFFFFF;
|
||||
SpiPs_write_read1(0xA16, (bin_high >> 16) & 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0xA17, (bin_high >> 8) & 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0xA18, bin_high & 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0xA19, (bin_low >> 16) & 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0xA1A, (bin_low >> 8) & 0xFF,&rx_data);
|
||||
SpiPs_write_read1(0xA1B, bin_low & 0xFF,&rx_data);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* xilinx_io.h
|
||||
*
|
||||
* Created on: 2021年9月6日
|
||||
* Author: cxlab
|
||||
*/
|
||||
|
||||
#ifndef SRC_XILINX_IO_H_
|
||||
#define SRC_XILINX_IO_H_
|
||||
|
||||
|
||||
|
||||
#endif /* SRC_XILINX_IO_H_ */
|
||||
#include "xspips.h" /* SPI device driver */
|
||||
#include "xgpiops.h"
|
||||
#include "xgpio.h"
|
||||
#include "xaxidma.h"
|
||||
#include "xparameters.h"
|
||||
#include "xscugic.h"
|
||||
#include "xil_exception.h"
|
||||
|
||||
//#define DBGLOG
|
||||
#define MAX_DATA 100
|
||||
#define SPI_WRITE 0x80
|
||||
#define SPI_READ 0x00
|
||||
#define GPIO_DIR_INPUT 0x00
|
||||
#define GPIO_DIR_OUTPUT 0x01
|
||||
#define GPIO_EMIO_OFFSET 54
|
||||
|
||||
#define TX_EN 0x08
|
||||
#define RX_EN 0x07
|
||||
#define GPIO_1 0x06
|
||||
#define GPIO_0 0x05
|
||||
|
||||
#define NRST 0
|
||||
#define ENABLE_TRX1 1
|
||||
#define ENABLE_TRX2 2
|
||||
#define ENABLE_TRX3 3
|
||||
#define TXNRX_TRX1 4
|
||||
#define TXNRX_TRX2 5
|
||||
#define TXNRX_RX3 6
|
||||
|
||||
#define aresetn_0 33
|
||||
#define rst 34
|
||||
#define tr_sel 35
|
||||
#define tdd_fdd_sel 36
|
||||
#define r1t1_r2t2_sel 37
|
||||
#define sp_dp_sel 38
|
||||
#define aresetn_1 39
|
||||
#define aresetn_2 40
|
||||
#define hop 41
|
||||
#define cx3e04_rstn 42
|
||||
#define spi_select 46
|
||||
#define debug_mode 63
|
||||
|
||||
#define INTER_SIG3 0x03//dma_axis_rx_rstn
|
||||
#define INTER_SIG2 0x02//frame_pattern
|
||||
#define INTER_SIG1 0x01//mode_sel_async
|
||||
#define INTER_SIG0 0x00//rst_async
|
||||
|
||||
#define SPI_DEVICE_ID XPAR_XSPIPS_0_DEVICE_ID
|
||||
#define GPIO_DEVICE_ID XPAR_PS7_GPIO_0_DEVICE_ID
|
||||
|
||||
#define AXI_DMA_DEVCIE_ID0 XPAR_AXI_DMA_0_DEVICE_ID
|
||||
#define AXI_DMA_DEVCIE_ID1 XPAR_AXI_DMA_1_DEVICE_ID
|
||||
#define AXI_DMA_DEVCIE_ID2 XPAR_AXI_DMA_2_DEVICE_ID
|
||||
|
||||
#define BROM_BASEADDR XPAR_M08_AXI_0_BASEADDR
|
||||
|
||||
#define AXI4_LITE0_SPI_BASEADDR XPAR_AXI4_LITE_SPI_0_BASEADDR
|
||||
#define AXI4_LITE1_SPI_BASEADDR XPAR_AXI4_LITE_SPI_1_BASEADDR
|
||||
#define BRAM_BASEADDR XPAR_AXI_BRAM_CTRL_0_S_AXI_BASEADDR
|
||||
#define BRAM_BASEADDR_1 XPAR_AXI_BRAM_CTRL_1_S_AXI_BASEADDR
|
||||
#define PACKER_BASEADDR0 XPAR_AXIS_ADC_DATA_PACKER_0_S00_AXI_BASEADDR
|
||||
#define PACKER_BASEADDR1 XPAR_AXIS_ADC_DATA_PACKER_1_S00_AXI_BASEADDR
|
||||
#define PACKER_BASEADDR2 XPAR_AXIS_ADC_DATA_PACKER_2_S00_AXI_BASEADDR
|
||||
#define WAVELENGTH 8192
|
||||
#define TX_BUFFER_BASE XPAR_MIG_7SERIES_0_BASEADDR +0x2000
|
||||
#define WAVE_LENGTH 8192*4
|
||||
|
||||
#define GPIO_INT_ID XPAR_FABRIC_GPIO_0_VEC_ID //PL 端 AXI GPIO 中断 ID
|
||||
#define AXI_GPIO_ID XPAR_AXI_GPIO_0_DEVICE_ID //PL 端 AXI GPIO 器件 ID
|
||||
#define SCUGIC_ID XPAR_SCUGIC_0_DEVICE_ID //中断控制器 ID
|
||||
|
||||
#define KEY_MASK XGPIO_IR_CH1_MASK //通道 1 的位定义
|
||||
|
||||
int cx3e04_write(int addr , int value);
|
||||
int cx3e04_read(int addr);
|
||||
int cx9261a_write(int addr , int value);
|
||||
int cx9261a_read(int addr);
|
||||
void cx3e04_config(void);
|
||||
void cx9261a_710_config(void);
|
||||
|
||||
void AXIGpioInit(void);
|
||||
void ConfigAXIGPIOIntr(void);
|
||||
void axi_gpio_handler(void *CallbackRef);
|
||||
void XScuGicInit(void);
|
||||
void ExceptionInit(void);
|
||||
|
||||
int SpiPsInit(u16 SpiDeviceId);
|
||||
//int SpiPs_write_read(u8 cmd, u16 addr,u8 data,u8 * rx_data);
|
||||
int SpiPs_write_read(u8 * data,u8 * rx_data);
|
||||
int SpiPs_write_read1(u16 addr,u8 data,u8 * rx_data);
|
||||
int SpiPs_write_read2(u16 addr,u8 data,u8 * rx_data);
|
||||
int GpioInit(u16 DeviceId);
|
||||
int GpioSetPinDir(u32 Pin,u32 Direction);
|
||||
int GpioWritePin(u32 Pin,u32 data);
|
||||
int GpioReadPin(u32 Pin);
|
||||
void DeviceRst(void);
|
||||
|
||||
//校准
|
||||
void cx9261a_151_config(void);
|
||||
void cx9261a_076_config(void);
|
||||
void rxFFTCalib(int lo, int fs,int ref, int firLength,int chan);
|
||||
void configTxNcoFreq(int freq, int fs);
|
||||
void configRxNcoFreq(int freq, int fs);
|
||||
void configDcCalib(int dcCalibEnable,int dcCalibLength);
|
||||
void txBisectionQecCalib(int f0, int fs);
|
||||
void txBisectionDcCalib(int f0, int fs);
|
||||
|
||||
extern XAxiDma* xAxiDma0Get(void);
|
||||
extern XAxiDma* xAxiDma1Get(void);
|
||||
extern XAxiDma* xAxiDma2Get(void);
|
||||
int XAxiDma_Init(XAxiDma* AxiDma,u16 DeviceId);
|
||||
int XAxiDmaCapture(XAxiDma* AxiDma,u32 data_length);
|
||||
int XAxiDmaCapture2(XAxiDma* AxiDma,u32 data_length);
|
||||
|
||||
int DownloadWave(u8 * data);
|
||||
int SetPacketSize(XAxiDma* AxiDma,u32 length);
|
||||
void dbg_printf( const char8 *ctrl1, ...);
|
||||
void PackerRst(void);
|
||||
int peripheral_test(void);
|
||||
|
||||
#define SPI_STACK_LENGTH 65536
|
||||
struct spi_stack {
|
||||
int spi_write_num;
|
||||
u8 recv_buf[SPI_STACK_LENGTH*3];
|
||||
};
|
||||
int spi_stack_in(u8 * data,struct spi_stack * spistack);
|
||||
|
||||
void spi_stack_out(struct spi_stack * spistack);
|
||||
|
||||
int rom_read(u8 * data);
|
||||
void download_bin(void);
|
||||
//跳频
|
||||
void frqhop_config(int hop_flag);
|
||||
void frqhop_flag(int frqhop_flag);
|
||||
int PLL_config(u8 pll_index,double pll_frq);
|
||||
void trx_ch_pll_config(u8 pll_index);
|
||||
int pll_frq_caculation(double ref,double pll_frq,u8 *reg_data);
|
||||
int pll_frq_caculation_new(double ref,double pll_frq,u8 *reg_data);
|
||||
void PLL_afc(u16 afc_addr,u16 div_addr,u8 pll_div);
|
||||
char divBin(u16 div);
|
||||
+2188
File diff suppressed because it is too large
Load Diff
+546
@@ -0,0 +1,546 @@
|
||||
/**
|
||||
* @file cx9261adriver.h
|
||||
*/
|
||||
|
||||
#ifndef CX9261ADRIVER_CX9261ADRIVER_H
|
||||
#define CX9261ADRIVER_CX9261ADRIVER_H
|
||||
|
||||
#define VERSION 1.9.0
|
||||
|
||||
#include "defs.h"
|
||||
// 如果不需要输出日志内容,注释掉下面的宏定义
|
||||
#define USE_LOGGING
|
||||
|
||||
#ifdef USE_LOGGING
|
||||
# define LOGGING(x) logging(x);
|
||||
#else
|
||||
# define LOGGING(x)
|
||||
#endif
|
||||
|
||||
namespace CX9261A {
|
||||
#ifdef USE_LOGGING
|
||||
/**
|
||||
* @brief 输出日志的函数
|
||||
* @param msg 要输出的内容
|
||||
*/
|
||||
void logging(const std::string& msg);
|
||||
#endif
|
||||
/**
|
||||
* @brief 需要实现的函数,实现SPI写入寄存器功能
|
||||
* @param address 要写入的寄存器地址
|
||||
* @param value 要写入的寄存器值
|
||||
*/
|
||||
void writeSpi(int address, int value);
|
||||
/**
|
||||
* @brief 需要实现的函数,实现SPI读取寄存器功能
|
||||
* @param address 要读取的寄存器地址
|
||||
* @return 返回的寄存器值
|
||||
*/
|
||||
int readSpi(int address);
|
||||
/**
|
||||
* @brief 需要实现的函数,实现等待功能
|
||||
* @param ms 等待时间,单位毫秒
|
||||
*/
|
||||
void pause(double ms);
|
||||
/**
|
||||
* @brief 需要实现的函数,实现配置FPGA对应寄存器功能
|
||||
* @param pin 寄存器地址
|
||||
* @param value 寄存器值
|
||||
*/
|
||||
void setPin(int pin, int value);
|
||||
/**
|
||||
* @brief 初始化芯片状态,写入与具体配置无关的寄存器值
|
||||
*/
|
||||
void initialChip();
|
||||
/**
|
||||
* @brief 初始化电源配置,如果只自定义配置部分模式下的电源管理,在自定义配置之前需要先调用此函数
|
||||
*/
|
||||
void initialPowerConfig(const CX9261AConfiguration& config);
|
||||
/**
|
||||
* @brief 初始化BBPLL相关寄存器,如果调用了initialChip,则无需单独调用此函数
|
||||
*/
|
||||
void initialBBPLL();
|
||||
/**
|
||||
* @brief 初始化PLL1相关寄存器,如果调用了initialChip,则无需单独调用此函数
|
||||
*/
|
||||
void initialPLL1();
|
||||
/**
|
||||
* @brief 初始化PLL2相关寄存器,如果调用了initialChip,则无需单独调用此函数
|
||||
*/
|
||||
void initialPLL2();
|
||||
/**
|
||||
* @brief 初始化PLL3相关寄存器,如果调用了initialChip,则无需单独调用此函数
|
||||
*/
|
||||
void initialPLL3();
|
||||
/**
|
||||
* @brief 初始化PLL4相关寄存器,如果调用了initialChip,则无需单独调用此函数
|
||||
*/
|
||||
void initialPLL4();
|
||||
/**
|
||||
* @brief 初始化PLL5相关寄存器,如果调用了initialChip,则无需单独调用此函数
|
||||
*/
|
||||
void initialPLL5();
|
||||
/**
|
||||
* @brief 配置受参考时钟频率影响的寄存器
|
||||
* @param ref 参考时钟频率,单位MHz
|
||||
*/
|
||||
void configRef(double ref);
|
||||
/**
|
||||
* @brief 配置时钟相关寄存器,包括ADC和BBPLL
|
||||
* @param config CX9261A参数结构体
|
||||
*/
|
||||
void configBBPLL(const CX9261AConfiguration& config);
|
||||
/**
|
||||
* @brief BBPLL AFC
|
||||
* @return 是否锁定
|
||||
*/
|
||||
bool afcBBPll();
|
||||
/**
|
||||
* @brief 配置PLL1频率
|
||||
* @param lo 目标频率
|
||||
* @param clock 时钟结构体,使用其中的ref和refDoubler属性
|
||||
*/
|
||||
void configPll1(double lo, const Clock& clock);
|
||||
/**
|
||||
* @brief Pll1 AFC
|
||||
* @return 是否锁定
|
||||
*/
|
||||
bool afcPll1();
|
||||
/**
|
||||
* @brief 配置PLL2频率
|
||||
* @param lo 目标频率
|
||||
* @param clock 时钟结构体,使用其中的ref和refDoubler属性
|
||||
*/
|
||||
void configPll2(double lo, const Clock& clock);
|
||||
/**
|
||||
* @brief Pll2 AFC
|
||||
* @return 是否锁定
|
||||
*/
|
||||
bool afcPll2();
|
||||
/**
|
||||
* @brief 配置PLL3频率
|
||||
* @param lo 目标频率
|
||||
* @param clock 时钟结构体,使用其中的ref和refDoubler属性
|
||||
*/
|
||||
void configPll3(double lo, const Clock& clock);
|
||||
/**
|
||||
* @brief Pll3 AFC
|
||||
* @return 是否锁定
|
||||
*/
|
||||
bool afcPll3();
|
||||
/**
|
||||
* @brief 配置PLL4频率
|
||||
* @param lo 目标频率
|
||||
* @param clock 时钟结构体,使用其中的ref和refDoubler属性
|
||||
*/
|
||||
void configPll4(double lo, const Clock& clock);
|
||||
/**
|
||||
* @brief Pll4 AFC
|
||||
* @return 是否锁定
|
||||
*/
|
||||
bool afcPll4();
|
||||
/**
|
||||
* @brief 配置PLL5频率
|
||||
* @param lo 目标频率
|
||||
* @param clock 时钟结构体,使用其中的ref和refDoubler属性
|
||||
*/
|
||||
void configPll5(double lo, const Clock& clock);
|
||||
/**
|
||||
* @brief Pll5 AFC
|
||||
* @return 是否锁定
|
||||
*/
|
||||
bool afcPll5();
|
||||
/**
|
||||
* @brief 配置AGC模式
|
||||
* @param mode 模式0~13
|
||||
*/
|
||||
void configAGCMode(int mode);
|
||||
/**
|
||||
* @brief 配置AGC PDT
|
||||
* @param pdt AGCPDT结构体
|
||||
*/
|
||||
void configAGCPDT(const AGCPDT& pdt);
|
||||
/**
|
||||
* @brief 配置AGC LMT
|
||||
* @param lmt AGCLMT结构体
|
||||
*/
|
||||
void configAGCLMT(const AGCLMT& lmt);
|
||||
/**
|
||||
* @brief 配置AGC DIG
|
||||
* @param dig AGCDIG结构体
|
||||
*/
|
||||
void configAGCDIG(const AGCDIG& dig);
|
||||
/**
|
||||
* @brief 配置AGC
|
||||
* @param agc AGC结构体
|
||||
*/
|
||||
void configAGC(const AGC& agc);
|
||||
/**
|
||||
* @brief 配置片内处理器,仅在使用需要处理器辅助的校准方法时需要开启处理器
|
||||
* @param on 开启/关闭
|
||||
*/
|
||||
void configRISCV(bool on);
|
||||
/**
|
||||
* @brief 配置温补
|
||||
* @param mode 温补模式 DAC/Band
|
||||
*/
|
||||
void configTemperatureCompensation(TemperatureComp mode);
|
||||
/**
|
||||
* @brief ADC校准
|
||||
* @param adc ADC速率
|
||||
*/
|
||||
void configADCCalib(double adc);
|
||||
/**
|
||||
* @brief Flash校准
|
||||
*/
|
||||
void configFlashCalib();
|
||||
/**
|
||||
* @brief QEC校准会改变部分寄存器配置,在进行校准之前需要保存这部分寄存器,校准后恢复
|
||||
* @return 包含寄存器地址和值的map
|
||||
*/
|
||||
std::map<int, int> beforeQecState();
|
||||
/**
|
||||
* @brief 恢复QEC校准过程中改变的寄存器
|
||||
* @param state beforeQecState函数返回的map
|
||||
*/
|
||||
void restoreQecState(const std::map<int, int>& state);
|
||||
/**
|
||||
* @brief 根据pll来源配置校准模式下的电源管理
|
||||
* @param pllSource PllSource结构体
|
||||
*/
|
||||
void preparePowerForRxCalib(const PllSource& pllSource);
|
||||
/**
|
||||
* @brief 调整校准时Pll的配置
|
||||
* @param config CX9261A配置结构体
|
||||
* @param chan 要进行校准的通道
|
||||
*/
|
||||
void preparePllForRxCalib(const CX9261AConfiguration& config, RxChannel chan);
|
||||
/**
|
||||
* @brief 等待RxTST窄带校准结束,可重写
|
||||
* @return 校准是否结束
|
||||
*/
|
||||
bool waitRxTSTFinished();
|
||||
/**
|
||||
* @brief RX时域统计校准
|
||||
* @param chan 校准的RX通道
|
||||
*/
|
||||
void rxTSTCalib(RxChannel chan);
|
||||
/**
|
||||
* @brief RX延时线校准
|
||||
* @param fs ADC采样率
|
||||
* @param chan 校准的RX通道
|
||||
*/
|
||||
void rxDelayCalib(double fs, RxChannel chan);
|
||||
/**
|
||||
* @brief DC Tracking
|
||||
* @param config CX9261A配置结构体
|
||||
*/
|
||||
void configDcCalib(const Calib& config);
|
||||
void configDcCalibMethod(DCCalibMethod method);
|
||||
void configDcTrackingLength(int length);
|
||||
void configDcHighPassFactor(int factor);
|
||||
/**
|
||||
* @brief Rx校准
|
||||
* @param config CX9261A配置结构体
|
||||
* @param chan 要进行校准的通道
|
||||
*/
|
||||
void rxCalib(const CX9261AConfiguration& config, RxChannel chan);
|
||||
/**
|
||||
* @brief 选择校准方法
|
||||
* @param calib 校准结构体
|
||||
*/
|
||||
void configCalibMethod(const Calib& calib);
|
||||
/**
|
||||
* @brief 读取当前Rx chan通道的校准值
|
||||
* @param chan Rx通道
|
||||
* @return 校准值结构体
|
||||
*/
|
||||
CalibPredis readRxCalibPredis(RxChannel chan);
|
||||
/**
|
||||
* @brief 储存校准值
|
||||
* @param index 第index组校准值
|
||||
* @param chan 接收通道
|
||||
* @param pll 使用的PLL
|
||||
*/
|
||||
void saveRxCalibPredis(unsigned char index, RxChannel chan, LoSource pll);
|
||||
/**
|
||||
* @brief 加载保存的校准值
|
||||
* @param index 第index组校准值
|
||||
* @param chan 指定加载校准值的通道
|
||||
* @param pll 使用的PLL
|
||||
*/
|
||||
void loadRxCalibPredis(unsigned char index, RxChannel chan, LoSource pll);
|
||||
/**
|
||||
* @brief Rx窄带多点校准
|
||||
* @param config CX9261A配置结构体
|
||||
* @param points 校准点
|
||||
* @param chan 接收通道
|
||||
*/
|
||||
void configRxMultiPointsQec(const CX9261AConfiguration& config, const std::vector<double>& points, RxChannel chan);
|
||||
/**
|
||||
* @brief 根据pll来源配置校准模式下的电源管理
|
||||
* @param pllSource PllSource结构体
|
||||
*/
|
||||
void preparePowerForTxCalib(const PllSource& pllSource);
|
||||
/**
|
||||
* @brief 调整校准时Pll的配置
|
||||
* @param config CX9261A配置结构体
|
||||
*/
|
||||
void preparePllForTxCalib(const CX9261AConfiguration& config);
|
||||
/**
|
||||
* @brief TX二分法QEC校准
|
||||
* @param f0 校准音频率
|
||||
* @param fs adc频率
|
||||
*/
|
||||
void txBisectionQecCalib(double f0, double fs);
|
||||
/**
|
||||
* @brief TX时域统计法校准
|
||||
* @param config CX9261A配置结构体
|
||||
* @param chan 要校准的通道
|
||||
*/
|
||||
void txTSTCalib(const CX9261AConfiguration& config, TxChannel chan);
|
||||
/**
|
||||
* @brief TX二分法DC校准
|
||||
* @param f0 校准音频率
|
||||
* @param fs adc频率
|
||||
*/
|
||||
void txBisectionDcCalib(double f0, double fs);
|
||||
/**
|
||||
* @brief Tx多点校准
|
||||
* @param config CX9261A配置结构体
|
||||
* @param points 校准点
|
||||
*/
|
||||
void configTxMultiPointsQec(const CX9261AConfiguration& config, const std::vector<double>& points);
|
||||
/**
|
||||
* @brief Tx通道校准
|
||||
* @param config CX9261A配置结构体
|
||||
*/
|
||||
void txCalib(const CX9261AConfiguration& config);
|
||||
/**
|
||||
* @brief 储存校准值
|
||||
* @param index 第index组校准值
|
||||
* @param chan 发射通道
|
||||
* @param pll pll
|
||||
*/
|
||||
void saveTxCalibPredis(unsigned char index, TxChannel chan, LoSource pll);
|
||||
/**
|
||||
* @brief 加载保存的校准值
|
||||
* @param index 第index组校准值
|
||||
* @param chan 指定加载校准值的通道
|
||||
* @param pll 指定加载校准值对应的PLL
|
||||
*/
|
||||
void loadTxCalibPredis(unsigned char index, TxChannel chan, LoSource pll);
|
||||
/**
|
||||
* @brief Qec校准顶层函数,内部根据配置选择使用对应方法进行校准
|
||||
* @param config CX9261A配置结构体
|
||||
*/
|
||||
void configQecCalib(const CX9261AConfiguration& config);
|
||||
/**
|
||||
* @brief 配置TX NCO相关寄存器
|
||||
* @param nco TX NCO配置结构体
|
||||
* @param fs adc速率
|
||||
*/
|
||||
void configTxNco(const TxNCO& nco, double fs);
|
||||
/**
|
||||
* @brief 配置TX NCO BIST模式
|
||||
* @param bist 开启/关闭BIST
|
||||
*/
|
||||
void configTxBIST(bool bist);
|
||||
/**
|
||||
* @brief 配置TX NCO频率
|
||||
* @param freq 混频频率
|
||||
* @param fs adc抽取后速率
|
||||
*/
|
||||
void configTxNcoFreq(double freq, double fs);
|
||||
/**
|
||||
* @brief 配置RX NCO相关寄存器
|
||||
* @param nco RX NCO配置结构体
|
||||
* @param fs adc速率
|
||||
*/
|
||||
void configRxNco(const RxNCO& nco, double fs);
|
||||
/**
|
||||
* @brief 配置Rx NCO模式
|
||||
* @param mode NCO模式:Bypass/BIST/Up/Down
|
||||
*/
|
||||
void configRxNcoMode(NCOMode mode);
|
||||
/**
|
||||
* @brief 配置Rx NCO模式
|
||||
* @param mode NCO模式:Master/Slaver
|
||||
*/
|
||||
void configRxNcoMS(NCOMode mode);
|
||||
/**
|
||||
* @brief 配置Rx NCO频率
|
||||
* @param freq 混频频率
|
||||
* @param fs adc速率
|
||||
*/
|
||||
void configRxNcoFreq(double freq, double fs);
|
||||
/**
|
||||
* @brief 配置接口相关寄存器
|
||||
* @param interface Interface配置结构体
|
||||
*/
|
||||
void configInterface(const Interface& interface);
|
||||
/**
|
||||
* @brief 配置PLL来源
|
||||
* @param pllSource PLlSource结构体
|
||||
*/
|
||||
void configPllSource(const PllSource& pllSource);
|
||||
/**
|
||||
* @brief 切换电源模式
|
||||
* @param pm 电源模式
|
||||
*/
|
||||
void configPowerMode(PowerMode pm);
|
||||
/**
|
||||
* @brief 配置电源管理
|
||||
* @param power 电源配置结构体
|
||||
* @param pm 电源模式
|
||||
*/
|
||||
void configPowerPins(const Power& power, PowerMode pm);
|
||||
/**
|
||||
* @brief 配置参考倍频器
|
||||
* @param doubler 倍频器开关
|
||||
* @param ref 参考时钟频率,单位MHz
|
||||
*/
|
||||
void configRefDoubler(bool doubler, double ref);
|
||||
/**
|
||||
* @brief 初始化通道,调用initialChip函数会初始化RX1,RX2,RX3三个通道
|
||||
* @param chan 通道 RX1/RX2/RX3
|
||||
*/
|
||||
void initialRxChannel(RxChannel chan);
|
||||
/**
|
||||
* @brief 配置Rx带宽
|
||||
* @note 只改变Rx带宽会导致通道增益改变,建议使用configRxChannel函数进行带宽调整
|
||||
* @param bandwidth 带宽,单位(MHz)
|
||||
* @param chan 通道 Rx1/Rx2/Rx3
|
||||
*/
|
||||
void configRxBandwidth(double bandwidth, RxChannel chan);
|
||||
/**
|
||||
* @brief 配置Rx TIA
|
||||
* @note 只改变TIA会导致通道带宽改变,建议使用configRxChannel函数进行TIA调整
|
||||
* @param tia tia档位
|
||||
* @param chan 通道 Rx1/Rx2/Rx3
|
||||
*/
|
||||
void configRxTIA(int tia, RxChannel chan);
|
||||
/**
|
||||
* @brief 配置Rx Mixer
|
||||
* @param mixer mixer档位
|
||||
*/
|
||||
void configRxMixer(int mixer);
|
||||
/**
|
||||
* @brief 配置Rx通道,包含TIA,Mixer以及Bandwidth
|
||||
* @param config RxConfig结构体
|
||||
* @param chan Rx1/Rx2/Rx3
|
||||
*/
|
||||
void configRxChannel(const RxConfig& config, RxChannel chan);
|
||||
/**
|
||||
* @brief 配置Rx FIR滤波器抽取倍数
|
||||
* @param fir 抽取倍数 0(Bypass)/1/2/3/4/8
|
||||
*/
|
||||
void configRxFIR(int fir);
|
||||
/**
|
||||
* @brief 配置Rx HBF1滤波器抽取倍数
|
||||
* @param hbf 抽取倍数 0(Bypass)/2
|
||||
*/
|
||||
void configRxHBF1(int hbf);
|
||||
/**
|
||||
* @brief 配置Rx HBF2滤波器抽取倍数
|
||||
* @param hbf 抽取倍数 0(Bypass)/2
|
||||
*/
|
||||
void configRxHBF2(int hbf);
|
||||
/**
|
||||
* @brief 配置Rx HBF3滤波器抽取倍数
|
||||
* @param hbf 抽取倍数 0(Bypass)/2/3
|
||||
*/
|
||||
void configRxHBF3(int hbf);
|
||||
/**
|
||||
* @brief 配置Rx CIC滤波器
|
||||
* @param cic 抽取倍数 0(Bypass)/20
|
||||
*/
|
||||
void configRxCIC(int cic);
|
||||
/**
|
||||
* @brief 配置Rx滤波器
|
||||
* @param filters Filters结构体
|
||||
*/
|
||||
void configRxFilters(const Filters& filters);
|
||||
/**
|
||||
* @brief 配置Rx FIR滤波器系数
|
||||
* @param coe 滤波器系数,长度为16的整倍数,最大128
|
||||
*/
|
||||
void configRxFIRCoe(const std::vector<double>& coe);
|
||||
/**
|
||||
* @brief 配置Tx带宽
|
||||
* @param bandwidth 带宽,单位(MHz)
|
||||
* @param chan 通道 TX1/TX2
|
||||
*/
|
||||
void configTxBandwidth(double bandwidth, TxChannel chan);
|
||||
/**
|
||||
* @brief 配置Tx Mixer
|
||||
* @param mixer 混频器值
|
||||
* @param chan TX1/TX2
|
||||
*/
|
||||
void configTxMixer(int mixer, TxChannel chan);
|
||||
/**
|
||||
* @brief 初始化Tx通道
|
||||
* @param chan 通道 TX1/TX2
|
||||
*/
|
||||
void initialTxChannel(TxChannel chan);
|
||||
/**
|
||||
* @brief 根据Tx通道的本振频率,配置对应的参数
|
||||
* @param lo 本振频率,单位(MHz)
|
||||
* @param chan 通道(Tx1/Tx2)
|
||||
*/
|
||||
void configTxChannelFrequency(double lo, TxChannel chan);
|
||||
/**
|
||||
* @brief 配置Tx通道,Mixer以及Bandwidth
|
||||
* @param config TxConfig结构体
|
||||
* @param chan Tx1/Tx2
|
||||
*/
|
||||
void configTxChannel(const TxConfig& config, TxChannel chan);
|
||||
/**
|
||||
* @brief 配置Tx FIR滤波器插值倍数
|
||||
* @param fir 插值倍数 0(Bypass)/1/2/3/4/8
|
||||
*/
|
||||
void configTxFIR(int fir);
|
||||
/**
|
||||
* @brief 配置Tx HBF1滤波器插值倍数
|
||||
* @param hbf 插值倍数 0(Bypass)/2
|
||||
*/
|
||||
void configTxHBF1(int hbf);
|
||||
/**
|
||||
* @brief 配置Tx HBF2滤波器插值倍数
|
||||
* @param hbf 插值倍数 0(Bypass)/2
|
||||
*/
|
||||
void configTxHBF2(int hbf);
|
||||
/**
|
||||
* @brief 配置Tx HBF3滤波器插值倍数
|
||||
* @param hbf 插值倍数 0(Bypass)/2/3
|
||||
*/
|
||||
void configTxHBF3(int hbf);
|
||||
/**
|
||||
* @brief 配置Tx CIC滤波器
|
||||
* @param cic 插值倍数 0(Bypass)/8/20/32/80
|
||||
*/
|
||||
void configTxCIC(int cic);
|
||||
/**
|
||||
* @brief 配置Tx滤波器
|
||||
* @param filters Filters结构体
|
||||
*/
|
||||
void configTxFilters(const Filters& filters);
|
||||
/**
|
||||
* @brief 配置Tx FIR滤波器系数
|
||||
* @param coe 滤波器系数,长度为16的整倍数,最大128
|
||||
*/
|
||||
void configTxFIRCoe(const std::vector<double>& coe);
|
||||
/**
|
||||
* @brief 读取当前Tx chan通道的校准值
|
||||
* @param chan Tx通道
|
||||
* @return 校准值结构体
|
||||
*/
|
||||
CalibPredis readTxCalibPredis(TxChannel chan);
|
||||
/**
|
||||
* @brief 此函数为Demo板配套配置函数,用于配置FPGA接口,用户开发自己的程序时应重写对应功能
|
||||
* @param interface Interface结构体
|
||||
*/
|
||||
void configFPGA(const Interface& interface);
|
||||
} // namespace CX9261A
|
||||
|
||||
#endif // CX9261ADRIVER_CX9261ADRIVER_H
|
||||
@@ -0,0 +1,424 @@
|
||||
/**
|
||||
* @file defs.h
|
||||
*/
|
||||
|
||||
#ifndef CX9261ADRIVER_DEFS_H
|
||||
#define CX9261ADRIVER_DEFS_H
|
||||
|
||||
#include <bitset>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#ifdef interface
|
||||
# undef interface
|
||||
#endif
|
||||
|
||||
namespace CX9261A {
|
||||
/**
|
||||
* @brief 芯片工作模式
|
||||
*/
|
||||
enum class WorkMode : std::uint8_t { Rx, Tx, FDD };
|
||||
/**
|
||||
* @brief 收发数据通道数量
|
||||
* @note 此模式并不代表使用几个通道进行收发
|
||||
*/
|
||||
enum class TrMode : std::uint8_t { R1T1, R2T2 };
|
||||
/**
|
||||
* @brief 收发接口通道数量
|
||||
*/
|
||||
enum class PortMode : std::uint8_t { Single, Dual };
|
||||
/**
|
||||
* @brief 接口模式:
|
||||
* CMOS CMOS接口模式,
|
||||
* LVDS_S LVDS顺序模式,
|
||||
* LVDS_E LVDS奇偶模式
|
||||
*/
|
||||
enum class IOMode : std::uint8_t { CMOS, LVDS_S, LVDS_E };
|
||||
/**
|
||||
* @brief 本振来源
|
||||
*/
|
||||
enum class LoSource : std::uint8_t {
|
||||
Pll1 = 0b00001,
|
||||
Pll2 = 0b00010,
|
||||
Pll3 = 0b00100,
|
||||
Pll4 = 0b01000,
|
||||
Pll5 = 0b10000,
|
||||
Off = 0
|
||||
};
|
||||
|
||||
inline std::string toString(const LoSource source)
|
||||
{
|
||||
switch (source) {
|
||||
case LoSource::Pll1:
|
||||
return "Pll1";
|
||||
case LoSource::Pll2:
|
||||
return "Pll2";
|
||||
case LoSource::Pll3:
|
||||
return "Pll3";
|
||||
case LoSource::Pll4:
|
||||
return "Pll4";
|
||||
case LoSource::Pll5:
|
||||
return "Pll5";
|
||||
default:
|
||||
return "Off";
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief 接收通道
|
||||
*/
|
||||
enum class RxChannel : std::uint8_t { Rx1 = 1, Rx2, Rx3 };
|
||||
|
||||
inline std::string toString(const RxChannel chan)
|
||||
{
|
||||
switch (chan) {
|
||||
case RxChannel::Rx1:
|
||||
return "Rx1";
|
||||
case RxChannel::Rx2:
|
||||
return "Rx2";
|
||||
case RxChannel::Rx3:
|
||||
return "Rx3";
|
||||
default:
|
||||
return "Unknown Channel";
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief 发射通道
|
||||
*/
|
||||
enum class TxChannel : std::uint8_t { Tx1 = 1, Tx2 };
|
||||
|
||||
inline std::string toString(const TxChannel chan)
|
||||
{
|
||||
switch (chan) {
|
||||
case TxChannel::Tx1:
|
||||
return "Tx1";
|
||||
case TxChannel::Tx2:
|
||||
return "Tx2";
|
||||
default:
|
||||
return "Unknown Channel";
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief 电源模式
|
||||
*/
|
||||
enum class PowerMode : std::uint8_t { Shutdown = 0, Sleep, Alert, Calib, Receive, Transmit, Duplex, Obs };
|
||||
/**
|
||||
* @brief NCO模式
|
||||
*/
|
||||
enum class NCOMode : std::uint8_t { Bypass = 0, Up, Down, BIST, Master, Slaver };
|
||||
/**
|
||||
* @brief 温补模式 DAC: DAC模式 Band: 跳子带模式
|
||||
*/
|
||||
enum class TemperatureComp : std::uint8_t { DAC = 0, Band };
|
||||
/**
|
||||
* @brief 校准方法 TST: 时域统计 Rx通道使用, Bisec: 二分法 Tx通道使用, MultiPoints: 多点校准
|
||||
*/
|
||||
enum class CalibMethod : std::uint8_t { TST = 0, Bisec, MultiPoints, Tracking };
|
||||
/**
|
||||
* @brief DC校准方法 Tracking: 跟踪校准 HighPass: 高通滤波器滤掉直流
|
||||
*/
|
||||
enum class DCCalibMethod : std::uint8_t { Tracking = 0, HighPass };
|
||||
/**
|
||||
* @brief AFC等待延时,单位ms
|
||||
*/
|
||||
constexpr double delay = 100;
|
||||
/**
|
||||
* @brief QEC等待延时,单位ms
|
||||
*/
|
||||
constexpr double qecDelay = 500;
|
||||
/**
|
||||
* @brief 接收通道本振来源映射表
|
||||
*/
|
||||
static const std::map<std::pair<LoSource, LoSource>, std::bitset<7>> rxSrcMap = {
|
||||
{ { LoSource::Pll2, LoSource::Pll2 }, 0b0010000 }, { { LoSource::Pll1, LoSource::Pll1 }, 0b1101000 },
|
||||
{ { LoSource::Pll2, LoSource::Pll1 }, 0b0100000 }, { { LoSource::Pll1, LoSource::Pll2 }, 0b1000000 },
|
||||
{ { LoSource::Off, LoSource::Pll1 }, 0b0101010 }, { { LoSource::Off, LoSource::Pll2 }, 0b1010010 },
|
||||
{ { LoSource::Pll1, LoSource::Off }, 0b1001001 }, { { LoSource::Pll2, LoSource::Off }, 0b0110001 },
|
||||
{ { LoSource::Off, LoSource::Off }, 0b0011011 }
|
||||
};
|
||||
/**
|
||||
* @brief 发射通道本振来源映射表
|
||||
*/
|
||||
static const std::map<std::pair<LoSource, LoSource>, std::bitset<11>> txSrcMap = {
|
||||
{ { LoSource::Pll4, LoSource::Pll4 }, 16 }, { { LoSource::Pll3, LoSource::Pll3 }, 104 },
|
||||
{ { LoSource::Pll4, LoSource::Pll3 }, 32 }, { { LoSource::Pll3, LoSource::Pll4 }, 64 },
|
||||
{ { LoSource::Pll2, LoSource::Pll2 }, 1560 }, { { LoSource::Pll1, LoSource::Pll1 }, 1944 },
|
||||
{ { LoSource::Pll2, LoSource::Pll1 }, 1688 }, { { LoSource::Pll1, LoSource::Pll2 }, 1816 },
|
||||
{ { LoSource::Off, LoSource::Pll3 }, 42 }, { { LoSource::Off, LoSource::Pll4 }, 82 },
|
||||
{ { LoSource::Off, LoSource::Pll2 }, 794 }, { { LoSource::Off, LoSource::Pll1 }, 666 },
|
||||
{ { LoSource::Pll3, LoSource::Off }, 73 }, { { LoSource::Pll4, LoSource::Off }, 49 },
|
||||
{ { LoSource::Pll2, LoSource::Off }, 1177 }, { { LoSource::Pll1, LoSource::Off }, 1305 },
|
||||
{ { LoSource::Off, LoSource::Off }, 27 }, { { LoSource::Pll1, LoSource::Pll3 }, 1320 },
|
||||
{ { LoSource::Pll1, LoSource::Pll4 }, 1360 }, { { LoSource::Pll2, LoSource::Pll3 }, 1064 },
|
||||
{ { LoSource::Pll2, LoSource::Pll4 }, 1104 }, { { LoSource::Pll3, LoSource::Pll1 }, 712 },
|
||||
{ { LoSource::Pll4, LoSource::Pll1 }, 688 }, { { LoSource::Pll3, LoSource::Pll2 }, 584 },
|
||||
{ { LoSource::Pll4, LoSource::Pll2 }, 560 }
|
||||
};
|
||||
/**
|
||||
* @brief 环路参数选择表
|
||||
*/
|
||||
static const std::vector<std::vector<std::vector<int>>> coreTable = {
|
||||
{ { 0x0C, 0x30, 0x08 }, { 0x0B, 0x30, 0x09 }, { 0x0C, 0x30, 0x05 }, { 0x0D, 0x30, 0x08 } },
|
||||
{ { 0x0C, 0x30, 0x0C }, { 0x0B, 0x30, 0x0E }, { 0x0C, 0x30, 0x08 }, { 0x0D, 0x30, 0x0B } },
|
||||
{ { 0x0C, 0x20, 0x10 }, { 0x0B, 0x20, 0x10 }, { 0x0C, 0x20, 0x0A }, { 0x0D, 0x20, 0x0D } },
|
||||
{ { 0x0C, 0x20, 0x11 }, { 0x0B, 0x20, 0x13 }, { 0x0C, 0x20, 0x0C }, { 0x0D, 0x20, 0x0F } },
|
||||
{ { 0x0D, 0x30, 0x14 }, { 0x0D, 0x22, 0x14 }, { 0x0D, 0x20, 0x0D }, { 0x0D, 0x15, 0x0C } },
|
||||
{ { 0x0E, 0x30, 0x18 }, { 0x0E, 0x25, 0x16 }, { 0x0E, 0x25, 0x0F }, { 0x0E, 0x18, 0x0F } },
|
||||
{ { 0x0F, 0x38, 0x1A }, { 0x0F, 0x32, 0x1C }, { 0x0F, 0x18, 0x12 }, { 0x0F, 0x18, 0x12 } }
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief AGC PDT模式的结构体
|
||||
*/
|
||||
struct AGCPDT
|
||||
{
|
||||
int pdtN;
|
||||
int pdtM;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief AGC LMT模式的结构体
|
||||
*/
|
||||
struct AGCLMT
|
||||
{
|
||||
int count; /**< LMT统计次数阈值*/
|
||||
int threshold1; /**< LMT阈值第一档*/
|
||||
int threshold2; /**< LMT阈值第二档*/
|
||||
int threshold3; /**< LMT阈值第三档*/
|
||||
int threshold4; /**< LMT阈值第四档*/
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief AGC DIG模式的结构体
|
||||
*/
|
||||
struct AGCDIG
|
||||
{
|
||||
int count; /**< DIG统计次数阈值*/
|
||||
int threshold1; /**< DIG阈值第一档*/
|
||||
int threshold2; /**< DIG阈值第二档*/
|
||||
int threshold3; /**< DIG阈值第三档*/
|
||||
int threshold4; /**< DIG阈值第四档*/
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief AGC模式的结构体
|
||||
*/
|
||||
struct AGC
|
||||
{
|
||||
int mode; /**< AGC模式选择*/
|
||||
AGCPDT pdt; /**< AGC PDT模式的结构体*/
|
||||
AGCLMT lmt; /**< AGC LMT模式的结构体*/
|
||||
AGCDIG dig; /**< AGC DIG模式的结构体*/
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 时钟相关参数结构体
|
||||
*/
|
||||
struct Clock
|
||||
{
|
||||
double ref; /**< 参考时钟频率,单位MHz*/
|
||||
double adc; /**< ADC频率,单位MHz*/
|
||||
int refDiv; /**< 参考时钟分频比*/
|
||||
bool bbUseIntDiv; /**< 是否使用整数分频模式*/
|
||||
bool refDoubler; /**< 是否使用参考时钟倍频器*/
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 校准相关参数结构体
|
||||
*/
|
||||
struct Calib
|
||||
{
|
||||
bool calibDC; /**< 是否开启DC Tracking*/
|
||||
DCCalibMethod dcCalibMethod;
|
||||
int dcTrackingLength; /**< DC Tracking长度*/
|
||||
int dcHighPassFactor; /**< DC高通滤波系数,越大代表滤波器阶数越高,滤波范围越窄*/
|
||||
std::uint8_t rx1CalibPll; /**< rx1校准的pll选择,Pll1 | Pll2*/
|
||||
std::uint8_t rx2CalibPll; /**< rx2校准的pll选择,Pll1 | Pll2*/
|
||||
std::uint8_t rx3CalibPll; /**< rx3校准的pll选择,Pll5*/
|
||||
std::uint8_t tx1CalibPll; /**< tx1校准的pll选择,Pll1 | Pll2 | Pll3 | Pll4*/
|
||||
std::uint8_t tx2CalibPll; /**< tx2校准的pll选择,Pll1 | Pll2 | Pll3 | Pll4*/
|
||||
CalibMethod rxMethod;
|
||||
CalibMethod txMethod;
|
||||
double f0; /**< 校准音频率*/
|
||||
std::vector<double> rxMultiPoints; /**< Rx多点校准的频率*/
|
||||
std::vector<double> txMultiPoints; /**< Tx多点校准的频率*/
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 配置PLL来源相关参数结构体
|
||||
*/
|
||||
struct PllSource
|
||||
{
|
||||
bool rxUseExt; /**< 接收通道是否使用外本振*/
|
||||
bool txUseExt; /**< 发射通道是否使用外本振*/
|
||||
LoSource rx1Source; /**< Rx1通道本振来源*/
|
||||
LoSource rx2Source; /**< Rx2通道本振来源*/
|
||||
LoSource rx3Source; /**< Rx3通道本振来源*/
|
||||
LoSource tx1Source; /**< Tx1通道本振来源*/
|
||||
LoSource tx2Source; /**< Tx2通道本振来源*/
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 配置PLL频率相关参数结构体
|
||||
*/
|
||||
struct PllFreq
|
||||
{
|
||||
double pll1Freq; /**< PLL1本振时钟,单位MHz*/
|
||||
double pll2Freq; /**< PLL2本振时钟,单位MHz*/
|
||||
double pll3Freq; /**< PLL3本振时钟,单位MHz*/
|
||||
double pll4Freq; /**< PLL4本振时钟,单位MHz*/
|
||||
double pll5Freq; /**< PLL5本振时钟,单位MHz*/
|
||||
double rxExtFreq; /**< 接收通道使用外本振时,外本振频率,单位MHz*/
|
||||
double txExtFreq; /**< 发射通道使用外本振时,外本振频率,单位MHz*/
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 配置接口相关参数结构体
|
||||
*/
|
||||
struct Interface
|
||||
{
|
||||
WorkMode workMode; /**< 芯片工作模式*/
|
||||
TrMode trMode; /**< 收发数据通道模式*/
|
||||
PortMode portMode; /**< 收发接口通道模式*/
|
||||
IOMode ioMode; /**< 接口电平模式*/
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 配置TX NCO相关参数结构体
|
||||
*/
|
||||
struct TxNCO
|
||||
{
|
||||
bool txUseBist; /**< 是否开启BIST模式*/
|
||||
double txNCOFreq; /**< NCO频率*/
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 配置RX NCO相关参数结构体
|
||||
*/
|
||||
struct RxNCO
|
||||
{
|
||||
bool rxUseBist; /**< 是否开启BIST模式*/
|
||||
bool rxNCOBypass; /**< 是否Bypass NCO*/
|
||||
bool rxNCOUpward; /**< 开启上/下混频模式*/
|
||||
bool rxNCOMaster; /**< 使用Master/Slaver模式*/
|
||||
double rxNCOFreq; /**< NCO频率*/
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 配置接收通道相关参数结构体
|
||||
*/
|
||||
struct RxConfig
|
||||
{
|
||||
double bandwidth; /**< 接收通道1dB带宽,单位MHz*/
|
||||
int tia; /**< 接收通道TIA增益配置,推荐配置6*/
|
||||
int mixer; /**< 接收通道Mixer增益配置*/
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 配置发射通道相关参数结构体
|
||||
*/
|
||||
struct TxConfig
|
||||
{
|
||||
double bandwidth; /**< 发射通道1dB带宽,单位MHz*/
|
||||
int mixer; /**< 发射通道Mixer增益配置*/
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 配置滤波器相关参数结构体,0代表bypass
|
||||
*/
|
||||
struct Filters
|
||||
{
|
||||
int fir; /**< FIR滤波器抽取/插值倍数*/
|
||||
int hbf1; /**< HBF1滤波器抽取/插值倍数*/
|
||||
int hbf2; /**< HBF2滤波器抽取/插值倍数*/
|
||||
int hbf3; /**< HBF3滤波器抽取/插值倍数*/
|
||||
int cic; /**< CIC滤波器抽取/插值倍数*/
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 配置电源模式结构体,1代表该模块上电
|
||||
*/
|
||||
struct Power
|
||||
{
|
||||
bool dig_tx2;
|
||||
bool dig_tx1;
|
||||
bool dig_rx3;
|
||||
bool dig_rx2;
|
||||
bool dig_rx1;
|
||||
bool fref1_rx;
|
||||
bool auxadc2;
|
||||
bool auxadc1;
|
||||
bool auxdac;
|
||||
bool temp_sensor;
|
||||
bool bgr;
|
||||
bool exlo;
|
||||
bool tx2;
|
||||
bool tx1;
|
||||
bool rx3;
|
||||
bool rx2;
|
||||
bool rx1;
|
||||
bool pll5_ldo;
|
||||
bool pll5;
|
||||
bool pll4_ldo;
|
||||
bool pll4;
|
||||
bool pll3_ldo;
|
||||
bool pll3;
|
||||
bool pll2_ldo;
|
||||
bool pll2;
|
||||
bool pll1_ldo;
|
||||
bool pll1;
|
||||
bool bbpll;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 配置电源模式管理,包含模式选择,接收模式,发射模式,FDD模式
|
||||
*/
|
||||
struct PowerManagement
|
||||
{
|
||||
PowerMode powerMode;
|
||||
Power rxPower;
|
||||
Power txPower;
|
||||
Power fddPower;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 储存窄带校准结果的结构体
|
||||
*/
|
||||
struct CalibPredis
|
||||
{
|
||||
int bHigh;
|
||||
int bLow;
|
||||
int cHigh;
|
||||
int cLow;
|
||||
int dciHigh;
|
||||
int dciLow;
|
||||
int dcqHigh;
|
||||
int dcqLow;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief CX9261A结构体
|
||||
*/
|
||||
struct CX9261AConfiguration
|
||||
{
|
||||
TemperatureComp tempComp; /**< 温度补偿*/
|
||||
AGC agc; /**< AGC结构体*/
|
||||
Interface interface; /**< Interface结构体*/
|
||||
Clock clock; /**< Clock结构体*/
|
||||
PllSource pllSource; /**< PllSource结构体*/
|
||||
Calib calib; /**< Calib结构体*/
|
||||
PllFreq pllFreq; /**< PllFreq结构体*/
|
||||
TxNCO txNco; /**< TxNCO结构体*/
|
||||
RxNCO rxNco; /**< RxNCO结构体*/
|
||||
RxConfig rx1Config; /**< RxConfig结构体*/
|
||||
RxConfig rx2Config; /**< RxConfig结构体*/
|
||||
RxConfig rx3Config; /**< RxConfig结构体*/
|
||||
TxConfig tx1Config; /**< TxConfig结构体*/
|
||||
TxConfig tx2Config; /**< TxConfig结构体*/
|
||||
Filters rxFilters; /**< Filters结构体*/
|
||||
Filters txFilters; /**< Filters结构体*/
|
||||
PowerManagement powerManagement; /**< PowerManagement结构体*/
|
||||
std::vector<double> rxFIRCoe; /**< Rx FIR滤波器系数*/
|
||||
std::vector<double> txFIRCoe; /**< Tx FIR滤波器系数*/
|
||||
};
|
||||
} // namespace CX9261A
|
||||
#endif // CX9261ADRIVER_DEFS_H
|
||||
@@ -0,0 +1,138 @@
|
||||
#include "cx9261adriver.h"
|
||||
#include "defs.h"
|
||||
|
||||
int main() {
|
||||
|
||||
// 芯片配置结构体
|
||||
CX9261A::CX9261AConfiguration configuration;
|
||||
// 电源管理
|
||||
// 接收模式电源管理
|
||||
configuration.powerManagement.rxPower = {0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0,
|
||||
0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1};
|
||||
// 发射模式电源管理
|
||||
configuration.powerManagement.txPower = {1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1};
|
||||
// FDD模式电源管理
|
||||
configuration.powerManagement.fddPower = {1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1,
|
||||
0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1};
|
||||
// 电源模式 即配置结束后的电源模式
|
||||
configuration.powerManagement.powerMode = CX9261A::PowerMode::Receive;
|
||||
// 接口模式
|
||||
configuration.interface = {.workMode = CX9261A::WorkMode::Rx,
|
||||
.trMode = CX9261A::TrMode::R1T1,
|
||||
.portMode = CX9261A::PortMode::Single,
|
||||
.ioMode = CX9261A::IOMode::CMOS};
|
||||
// 时钟相关
|
||||
configuration.clock = {.ref = 125, .adc = 64, .refDiv = 2, .bbUseIntDiv = false, .refDoubler = false};
|
||||
// 本振相关
|
||||
using LoSource = CX9261A::LoSource;
|
||||
// 本振来源
|
||||
configuration.pllSource = {.rxUseExt = false,
|
||||
.txUseExt = false,
|
||||
.rx1Source = LoSource::Pll1,
|
||||
.rx2Source = LoSource::Pll1,
|
||||
.rx3Source = LoSource::Off,
|
||||
.tx1Source = LoSource::Off,
|
||||
.tx2Source = LoSource::Off};
|
||||
// 本振频率 注意:使用的所有PLL,频率必须设为正数
|
||||
configuration.pllFreq = {
|
||||
.pll1Freq = 5800, .pll2Freq = 5800, .pll3Freq = 800, .pll4Freq = 900, .pll5Freq = 1000};
|
||||
// Rx通道 注意:tia推荐配置为6 Mixer为三个通道共用同一个寄存器
|
||||
configuration.rx1Config = {.bandwidth = 32, .tia = 6, .mixer = 31};
|
||||
configuration.rx2Config = {.bandwidth = 32, .tia = 6, .mixer = 31};
|
||||
configuration.rx3Config = {.bandwidth = 32, .tia = 6, .mixer = 31};
|
||||
// Tx通道
|
||||
configuration.tx1Config = {.bandwidth = 20, .mixer = 63};
|
||||
configuration.tx2Config = {.bandwidth = 20, .mixer = 63};
|
||||
// 接收滤波器
|
||||
configuration.rxFilters = {.fir = 0, .hbf1 = 0, .hbf2 = 0, .hbf3 = 0, .cic = 0};
|
||||
// 发射滤波器
|
||||
configuration.txFilters = {.fir = 0, .hbf1 = 2, .hbf2 = 2, .hbf3 = 0, .cic = 0};
|
||||
// Rx NCO
|
||||
configuration.rxNco = {
|
||||
.rxUseBist = false, .rxNCOBypass = true, .rxNCOUpward = true, .rxNCOMaster = true, .rxNCOFreq = 0};
|
||||
// Tx NCO
|
||||
configuration.txNco = {.txUseBist = false, .txNCOFreq = 0};
|
||||
// AGC 注意:mode = 0表示关闭AGC,此时其他的参数可以不配置
|
||||
configuration.calib = {
|
||||
.calibDC = true,
|
||||
.dcCalibMethod = CX9261A::DCCalibMethod::Tracking,
|
||||
.dcTrackingLength = 16384,
|
||||
.dcHighPassFactor = 8191,
|
||||
.rx1CalibPll = int(LoSource::Pll1) | int(LoSource::Pll2),
|
||||
.rx2CalibPll = int(LoSource::Pll1) | int(LoSource::Pll2),
|
||||
.rx3CalibPll = int(LoSource::Pll5),
|
||||
.tx1CalibPll = 0,
|
||||
.tx2CalibPll = 0,
|
||||
.rxMethod = CX9261A::CalibMethod::MultiPoints,
|
||||
.txMethod = CX9261A::CalibMethod::Bisec,
|
||||
.f0 = 4
|
||||
};
|
||||
configuration.agc = {.mode = 0};
|
||||
// 校准
|
||||
configuration.calib.rxMultiPoints = {2200, 2400, 2600, 2800, 3000, 3200, 3400, 3600, 3800, 4000, 4200,
|
||||
4400, 4600, 4800, 5000, 5200, 5400, 5600, 5800, 6000};
|
||||
// 配置温补模式为跳子带温补
|
||||
configuration.tempComp = CX9261A::TemperatureComp::Band;
|
||||
|
||||
// 开始配置芯片
|
||||
CX9261A::initialChip(); // 最开始需要调用此函数
|
||||
CX9261A::initialPowerConfig(configuration);
|
||||
// 配置温补
|
||||
configTemperatureCompensation(configuration.tempComp);
|
||||
using PowerMode = CX9261A::PowerMode;
|
||||
// 不需要自定义电源管理时,这部分代码可以省略
|
||||
CX9261A::configPowerPins(configuration.powerManagement.rxPower, PowerMode::Receive);
|
||||
CX9261A::configPowerPins(configuration.powerManagement.txPower, PowerMode::Transmit);
|
||||
CX9261A::configPowerPins(configuration.powerManagement.fddPower, PowerMode::Duplex);
|
||||
// 配置pll
|
||||
CX9261A::configBBPLL(configuration);
|
||||
CX9261A::configPllSource(configuration.pllSource);
|
||||
CX9261A::configPll1(configuration.pllFreq.pll1Freq, configuration.clock);
|
||||
CX9261A::configPll2(configuration.pllFreq.pll2Freq, configuration.clock);
|
||||
// 配置Rx通道
|
||||
CX9261A::configRxChannel(configuration.rx1Config, CX9261A::RxChannel::Rx1);
|
||||
CX9261A::configRxChannel(configuration.rx2Config, CX9261A::RxChannel::Rx2);
|
||||
CX9261A::configRxChannel(configuration.rx3Config, CX9261A::RxChannel::Rx3);
|
||||
// 配置Tx通道
|
||||
using TxChannel = CX9261A::TxChannel;
|
||||
CX9261A::configTxChannelFrequency(configuration.pllFreq.pll1Freq, TxChannel::Tx1);
|
||||
CX9261A::configTxChannelFrequency(configuration.pllFreq.pll2Freq, TxChannel::Tx2);
|
||||
CX9261A::configTxChannel(configuration.tx1Config, TxChannel::Tx1);
|
||||
CX9261A::configTxChannel(configuration.tx2Config, TxChannel::Tx2);
|
||||
// 配置滤波器
|
||||
CX9261A::configRxFilters(configuration.rxFilters);
|
||||
CX9261A::configTxFilters(configuration.txFilters);
|
||||
// 配置NCO
|
||||
CX9261A::configRxNco(configuration.rxNco, configuration.clock.adc);
|
||||
const int filters = std::max(configuration.rxFilters.fir, 1) * std::max(configuration.rxFilters.hbf3, 1) *
|
||||
std::max(configuration.rxFilters.hbf2, 1) *
|
||||
std::max(configuration.rxFilters.hbf1, 1) * std::max(configuration.rxFilters.cic, 1);
|
||||
CX9261A::configTxNco(configuration.txNco, configuration.clock.adc / filters);
|
||||
// 配置AGC
|
||||
CX9261A::configAGC(configuration.agc);
|
||||
// 切换到休眠模式
|
||||
CX9261A::configPowerMode(PowerMode::Sleep);
|
||||
CX9261A::pause(1000);
|
||||
// 切换到校准模式
|
||||
CX9261A::configPowerMode(PowerMode::Calib);
|
||||
CX9261A::pause(100);
|
||||
// 锁定BBPLL
|
||||
CX9261A::afcBBPll();
|
||||
// 配置校准
|
||||
CX9261A::configADCCalib(configuration.clock.adc);
|
||||
CX9261A::configFlashCalib();
|
||||
configDcCalib(configuration.calib);
|
||||
configQecCalib(configuration);
|
||||
CX9261A::loadRxCalibPredis(0, CX9261A::RxChannel::Rx1, LoSource::Pll1);
|
||||
CX9261A::loadRxCalibPredis(0, CX9261A::RxChannel::Rx2, LoSource::Pll1);
|
||||
// 配置接口
|
||||
CX9261A::configInterface(configuration.interface);
|
||||
// 配置FPGA接口相关 此为示例,仅适用于Demo工程,用户应根据实际情况进行配置
|
||||
CX9261A::configFPGA(configuration.interface);
|
||||
// 锁定PLL1
|
||||
CX9261A::afcPll1();
|
||||
// 锁定PLL2
|
||||
CX9261A::afcPll2();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/**
|
||||
* @file utils.h
|
||||
*/
|
||||
|
||||
#ifndef CX9261ADRIVER_UTILS_H
|
||||
#define CX9261ADRIVER_UTILS_H
|
||||
#include <algorithm>
|
||||
#include <bitset>
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
namespace CX9261A {
|
||||
#if __cplusplus >= 201703L
|
||||
template <typename T>
|
||||
constexpr const T& clamp(const T& v, const T& lo, const T& hi) {
|
||||
return std::clamp(v, lo, hi);
|
||||
}
|
||||
#else
|
||||
template <typename T>
|
||||
constexpr const T& clamp(const T& v, const T& lo, const T& hi) {
|
||||
return std::max(std::min(hi, v), lo);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename Float>
|
||||
int round(Float f) {
|
||||
return static_cast<int>(std::round(f));
|
||||
}
|
||||
|
||||
template <typename Float>
|
||||
long long round64(Float f) {
|
||||
return static_cast<long long>(std::round(f));
|
||||
}
|
||||
|
||||
template <typename Float>
|
||||
int floor(Float f) {
|
||||
return static_cast<int>(std::floor(f));
|
||||
}
|
||||
|
||||
template <typename Float>
|
||||
long long floor64(Float f) {
|
||||
return static_cast<long long>(std::floor(f));
|
||||
}
|
||||
|
||||
template <typename Float>
|
||||
int ceil(Float f) {
|
||||
return static_cast<int>(std::ceil(f));
|
||||
}
|
||||
|
||||
template <typename Float>
|
||||
long long ceil64(Float f) {
|
||||
return static_cast<long long>(std::ceil(f));
|
||||
}
|
||||
/**
|
||||
* @brief Register类,提供方便的位操作函数
|
||||
*/
|
||||
class Register {
|
||||
public:
|
||||
template <typename T = int>
|
||||
constexpr Register(const T value = 0) {
|
||||
static_assert(std::is_integral_v<T>, "Register value must be integral!");
|
||||
m_value = static_cast<unsigned long long>(value);
|
||||
}
|
||||
/**
|
||||
* 以十进制返回寄存器值
|
||||
*/
|
||||
unsigned char value() const { return static_cast<unsigned char>(m_value.to_ulong()); }
|
||||
/**
|
||||
* 对寄存器值进行部分值的替换操作
|
||||
* 例:replace(7, 4, 0b1111); 使寄存器的高四位为1
|
||||
* @param start 起始位
|
||||
* @param end 中止位
|
||||
* @param after 要替换的值
|
||||
*/
|
||||
void replace(const unsigned int start, const unsigned int end, unsigned char after) {
|
||||
for (auto i = end; i <= start; ++i) {
|
||||
m_value[i] = (after >> (i - end)) & 0b1;
|
||||
}
|
||||
}
|
||||
|
||||
auto operator[](const size_t position) { return m_value[position]; }
|
||||
|
||||
template <typename Type>
|
||||
operator Type() const {
|
||||
static_assert(std::is_integral_v<Type>, "Type must be an integral");
|
||||
return static_cast<Type>(m_value.to_ulong());
|
||||
}
|
||||
|
||||
private:
|
||||
std::bitset<8> m_value{};
|
||||
};
|
||||
|
||||
template <int N>
|
||||
std::string frac2bin(const double frac) {
|
||||
const long double num = frac * (pow(2.0, N));
|
||||
std::string ret = std::bitset<N>(std::floor(num)).to_string();
|
||||
return ret;
|
||||
}
|
||||
} // namespace CX9261A
|
||||
#endif // CX9261ADRIVER_UTILS_H
|
||||
+331
@@ -0,0 +1,331 @@
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* 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 ************/
|
||||
#ifdef __aarch64__ // Zynq MPSoC (Zynq UltraScale+)
|
||||
#define CPU_CLK_HZ XPAR_CPU_CORTEXA53_0_CPU_CLK_FREQ_HZ
|
||||
#define FCLK_CLK0_HZ 100000000
|
||||
#define APP_TIMER_CLK_HZ FCLK_CLK0_HZ
|
||||
#else // Zynq-7000
|
||||
#define CPU_CLK_HZ XPAR_CPU_CORTEXA9_0_CPU_CLK_FREQ_HZ
|
||||
#define APP_TIMER_CLK_HZ (CPU_CLK_HZ / 2)
|
||||
#define FCLK_CLK0_HZ 100000000
|
||||
#endif
|
||||
/********* Zynq Platform Configs **********/
|
||||
// APP Timer (for logging)
|
||||
#ifdef __aarch64__ // Zynq MPSoC (Zynq UltraScale+)
|
||||
#define APPTIMER_DEVICE_ID XPAR_AXI_TIMER_DEVICE_ID
|
||||
#define APPTIMER_INTR_ID XPAR_FABRIC_AXI_TIMER_INTERRUPT_INTR
|
||||
#else
|
||||
#define APPTIMER_DEVICE_ID XPAR_PS7_SCUTIMER_0_DEVICE_ID
|
||||
#define APPTIMER_INTR_ID XPAR_SCUTIMER_INTR
|
||||
#endif
|
||||
// Physical Layer Configs
|
||||
#define PHY_DEVICE_ID (0x01 | 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_SYSMON_DEVICE_ID XPAR_SYSTEM_MANAGEMENT_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_BASE_ADDR XPAR_SYSTEMBUS_BASEADDR
|
||||
#define SYSBUS_TX_INTR_ID XPAR_FABRIC_SYSTEMBUS_TX_DONE_INTR
|
||||
#define SYSBUS_RX_INTR_ID XPAR_FABRIC_SYSTEMBUS_RX_DONE_INTR
|
||||
|
||||
// INTC configis
|
||||
#define INTC_DEVICE_ID XPAR_SCUGIC_0_DEVICE_ID
|
||||
|
||||
/********* Hardware Configurations **********/
|
||||
|
||||
// Clock Management Configuration
|
||||
//#define HMC7044
|
||||
//#define AD9528
|
||||
//#define LMK04828
|
||||
//#define LMX2594_ADC
|
||||
//#define LMX2594_DAC
|
||||
|
||||
// RF Transceiver Configuration
|
||||
//#define AD9361_REG
|
||||
//#define AD9361_API
|
||||
//#define RFSOC
|
||||
#define CX9261A
|
||||
|
||||
// ADC Configuration
|
||||
//#define AD9653
|
||||
//#define AD9694
|
||||
|
||||
// RFSoC Configuration
|
||||
#ifdef RFSOC
|
||||
#define RFDC_DEVICE_ID XPAR_XRFDC_0_DEVICE_ID
|
||||
#endif
|
||||
|
||||
// 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 0
|
||||
#define AD9361_SPI_ENGINE_BASEADDR 0
|
||||
#define AD9361_SPI_ENGINE_DATA_WIDTH 8
|
||||
#define AD9361_SPI_ENGINE_CS_DELAY 3
|
||||
#define AD9361_1_SPI_CS 0x01
|
||||
#define AD9361_2_SPI_CS 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;
|
||||
|
||||
// CX9261A Configurations
|
||||
#define CX9261A_GPIO_DEVICE_ID 0
|
||||
#define CX9261A_GPIO_OFFSET 54
|
||||
#define CX9261A_NRST (CX9261A_GPIO_OFFSET+0)
|
||||
#define CX9261A_TXNRX_TRX1 (CX9261A_GPIO_OFFSET+1)
|
||||
#define CX9261A_TXNRX_TRX2 (CX9261A_GPIO_OFFSET+2)
|
||||
#define CX9261A_TXNRX_RXFB (CX9261A_GPIO_OFFSET+3)
|
||||
#define CX9261A_ENABLE_TRX1 (CX9261A_GPIO_OFFSET+4)
|
||||
#define CX9261A_ENABLE_TRX2 (CX9261A_GPIO_OFFSET+5)
|
||||
#define CX9261A_ENABLE_RXFB (CX9261A_GPIO_OFFSET+6)
|
||||
#define CX9261A_PL_RST (CX9261A_GPIO_OFFSET+7)
|
||||
#define CX9261A_TR_SEL (CX9261A_GPIO_OFFSET+8)
|
||||
#define CX9261A_TDD_FDD_SEL (CX9261A_GPIO_OFFSET+9)
|
||||
#define CX9261A_R1T1_R2T2_SEL (CX9261A_GPIO_OFFSET+10)
|
||||
#define CX9261A_SP_DP_SEL (CX9261A_GPIO_OFFSET+11)
|
||||
#define CX9261A_MCLK_DELAY_CTRL0 (CX9261A_GPIO_OFFSET+12)
|
||||
#define CX9261A_MCLK_DELAY_CTRL1 (CX9261A_GPIO_OFFSET+13)
|
||||
#define CX9261A_MCLK_DELAY_CTRL2 (CX9261A_GPIO_OFFSET+14)
|
||||
#define CX9261A_HOP_FLAG (CX9261A_GPIO_OFFSET+15)
|
||||
// -- CX9261A SPI Engine Configuration
|
||||
#define CX9261A_SPI_DEVICE_ID 0
|
||||
#define CX9261A_SPI_ENGINE_REF_CLK FCLK_CLK0_HZ
|
||||
#define CX9261A_SPI_ENGINE_MAX_SPEED 5000000
|
||||
//#define CX9261A_SPI_ENGINE_BASEADDR 0
|
||||
#define CX9261A_SPI_ENGINE_BASEADDR 0
|
||||
#define CX9261A_SPI_ENGINE_DATA_WIDTH 8
|
||||
#define CX9261A_SPI_ENGINE_CS_DELAY 3
|
||||
#define CX9261A_SPI_CS 0x00
|
||||
|
||||
// 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 0
|
||||
#define HMC7044_SPI_ENGINE_DATA_WIDTH 8
|
||||
#define HMC7044_SPI_ENGINE_CS_DELAY 3
|
||||
#define HMC7044_SPI_CS 0x00
|
||||
|
||||
// AD9528 Configurations
|
||||
#define AD9528_GPIO_DEVICE_ID 0
|
||||
#define AD9528_GPIO_OFFSET 54
|
||||
#define AD9528_RESETB (AD9528_GPIO_OFFSET+0)
|
||||
#define AD9528_SYSREF_REQ (AD9528_GPIO_OFFSET+1)
|
||||
#define AD9528_STATUS_0 (AD9528_GPIO_OFFSET+2)
|
||||
#define AD9528_STATUS_1 (AD9528_GPIO_OFFSET+3)
|
||||
// -- AD9528 SPI Engine Configuration
|
||||
#define AD9528_SPI_DEVICE_ID 0
|
||||
#define AD9528_SPI_ENGINE_REF_CLK FCLK_CLK0_HZ
|
||||
#define AD9528_SPI_ENGINE_MAX_SPEED 5000000
|
||||
//#define AD9528_SPI_ENGINE_BASEADDR 0
|
||||
#define AD9528_SPI_ENGINE_BASEADDR 0
|
||||
#define AD9528_SPI_ENGINE_DATA_WIDTH 8
|
||||
#define AD9528_SPI_ENGINE_CS_DELAY 3
|
||||
#define AD9528_SPI_CS 0x00
|
||||
|
||||
// LMK04828 Configurations
|
||||
#define LMK04828_GPIO_DEVICE_ID 0
|
||||
#define LMK04828_GPIO_OFFSET 54
|
||||
// -- LMK04828 SPI Engine Configuration
|
||||
#define LMK04828_SPI_DEVICE_ID 0
|
||||
#define LMK04828_SPI_ENGINE_REF_CLK FCLK_CLK0_HZ
|
||||
#define LMK04828_SPI_ENGINE_MAX_SPEED 5000000
|
||||
#define LMK04828_SPI_ENGINE_BASEADDR 0
|
||||
#define LMK04828_SPI_ENGINE_DATA_WIDTH 8
|
||||
#define LMK04828_SPI_ENGINE_CS_DELAY 3
|
||||
#define LMK04828_SPI_CS 0x00
|
||||
|
||||
// LMX2594_ADC Configurations
|
||||
#define LMX2594_ADC_GPIO_DEVICE_ID 0
|
||||
#define LMX2594_ADC_GPIO_OFFSET 54
|
||||
// -- LMX2594_ADC SPI Engine Configuration
|
||||
#define LMX2594_ADC_SPI_DEVICE_ID 0
|
||||
#define LMX2594_ADC_SPI_ENGINE_REF_CLK FCLK_CLK0_HZ
|
||||
#define LMX2594_ADC_SPI_ENGINE_MAX_SPEED 5000000
|
||||
#define LMX2594_ADC_SPI_ENGINE_BASEADDR 0
|
||||
#define LMX2594_ADC_SPI_ENGINE_DATA_WIDTH 8
|
||||
#define LMX2594_ADC_SPI_ENGINE_CS_DELAY 3
|
||||
#define LMX2594_ADC_SPI_CS 0x01
|
||||
|
||||
// LMX2594_DAC Configurations
|
||||
#define LMX2594_DAC_GPIO_DEVICE_ID 0
|
||||
#define LMX2594_DAC_GPIO_OFFSET 54
|
||||
// -- LMX2594_DAC SPI Engine Configuration
|
||||
#define LMX2594_DAC_SPI_DEVICE_ID 0
|
||||
#define LMX2594_DAC_SPI_ENGINE_REF_CLK FCLK_CLK0_HZ
|
||||
#define LMX2594_DAC_SPI_ENGINE_MAX_SPEED 5000000
|
||||
#define LMX2594_DAC_SPI_ENGINE_BASEADDR 0
|
||||
#define LMX2594_DAC_SPI_ENGINE_DATA_WIDTH 8
|
||||
#define LMX2594_DAC_SPI_ENGINE_CS_DELAY 3
|
||||
#define LMX2594_DAC_SPI_CS 0x02
|
||||
|
||||
// AD9653 Configurations
|
||||
#define AD9653_GPIO_DEVICE_ID 0
|
||||
#define AD9653_GPIO_OFFSET 54
|
||||
#define AD9653_POWR_DOWN (AD9653_GPIO_OFFSET+0)
|
||||
// -- AD9653 SPI Engine Configuration
|
||||
#define AD9653_SPI_DEVICE_ID 0
|
||||
#define AD9653_SPI_ENGINE_REF_CLK FCLK_CLK0_HZ
|
||||
#define AD9653_SPI_ENGINE_MAX_SPEED 5000000
|
||||
//#define AD9653_SPI_ENGINE_BASEADDR 0
|
||||
#define AD9653_SPI_ENGINE_BASEADDR 0
|
||||
#define AD9653_SPI_ENGINE_DATA_WIDTH 8
|
||||
#define AD9653_SPI_ENGINE_CS_DELAY 3
|
||||
#define AD9653_SPI_CS 0x03
|
||||
|
||||
// AD9694 Configurations
|
||||
#define AD9694_GPIO_DEVICE_ID 0
|
||||
#define AD9694_GPIO_OFFSET 54
|
||||
// -- AD9694 SPI Engine Configuration
|
||||
#define AD9694_SPI_DEVICE_ID 0
|
||||
#define AD9694_SPI_ENGINE_REF_CLK FCLK_CLK0_HZ
|
||||
#define AD9694_SPI_ENGINE_MAX_SPEED 5000000
|
||||
//#define AD9694_SPI_ENGINE_BASEADDR 0
|
||||
#define AD9694_SPI_ENGINE_BASEADDR 0
|
||||
#define AD9694_SPI_ENGINE_DATA_WIDTH 8
|
||||
#define AD9694_SPI_ENGINE_CS_DELAY 3
|
||||
#define AD9694_SPI_CS 0x03
|
||||
|
||||
// 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
@@ -0,0 +1,340 @@
|
||||
#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_1_SPI_CS,
|
||||
.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
|
||||
};
|
||||
|
||||
+1746
File diff suppressed because it is too large
Load Diff
+134
@@ -0,0 +1,134 @@
|
||||
#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/ad9528/ad9528.h"
|
||||
|
||||
static struct spi_engine_init_param spi_engine_param = {
|
||||
.ref_clk_hz = AD9528_SPI_ENGINE_REF_CLK,
|
||||
.type = SPI_ENGINE,
|
||||
.spi_engine_baseaddr = AD9528_SPI_ENGINE_BASEADDR,
|
||||
.cs_delay = AD9528_SPI_ENGINE_CS_DELAY,
|
||||
.data_width = AD9528_SPI_ENGINE_DATA_WIDTH
|
||||
};
|
||||
|
||||
static struct xil_gpio_init_param xil_gpio_param = {
|
||||
.type = GPIO_PS,
|
||||
.device_id = AD9528_GPIO_DEVICE_ID
|
||||
};
|
||||
|
||||
static struct spi_init_param ad9528_spi_init = {
|
||||
.device_id = AD9528_SPI_DEVICE_ID,
|
||||
.max_speed_hz = AD9528_SPI_ENGINE_MAX_SPEED,
|
||||
.mode = SPI_MODE_0,
|
||||
.chip_select = AD9528_SPI_CS,
|
||||
.platform_ops = &spi_eng_platform_ops,
|
||||
.extra = &spi_engine_param
|
||||
};
|
||||
|
||||
static struct gpio_init_param ad9528_gpio_resetb_init = {
|
||||
.number = AD9528_RESETB,
|
||||
.platform_ops = &xil_gpio_ops,
|
||||
.extra = &xil_gpio_param
|
||||
};
|
||||
|
||||
static struct gpio_init_param ad9528_gpio_sysref_req_init = {
|
||||
.number = AD9528_SYSREF_REQ,
|
||||
.platform_ops = &xil_gpio_ops,
|
||||
.extra = &xil_gpio_param
|
||||
};
|
||||
|
||||
static ad9528pll1Settings_t clockPll1Settings = {
|
||||
.refA_Frequency_Hz = 50000000,
|
||||
.refA_Divider = 1,
|
||||
.refA_bufferCtrl = SINGLE_ENDED,
|
||||
.refB_Frequency_Hz = 0,
|
||||
.refB_Divider = 1,
|
||||
.refB_bufferCtrl = DISABLED,
|
||||
.vcxo_Frequency_Hz = 50000000,
|
||||
.vcxoBufferCtrl = SINGLE_ENDED,
|
||||
.nDivider = 1
|
||||
};
|
||||
|
||||
static ad9528pll2Settings_t clockPll2Settings = {
|
||||
.rfDivider = 4,
|
||||
.n2Divider = 20,
|
||||
.totalNdiv = 80
|
||||
};
|
||||
|
||||
/*******************************************************************
|
||||
* 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
|
||||
*******************************************************************
|
||||
*/
|
||||
static ad9528outputSettings_t clockOutputSettings = {
|
||||
.outPowerDown = 0xE001,
|
||||
.outSource = {
|
||||
AD9528_CHANNEL_DIV, AD9528_CHANNEL_DIV, AD9528_CHANNEL_DIV, AD9528_CHANNEL_DIV, AD9528_CHANNEL_DIV,
|
||||
AD9528_CHANNEL_DIV, AD9528_CHANNEL_DIV, AD9528_CHANNEL_DIV, AD9528_CHANNEL_DIV, AD9528_CHANNEL_DIV,
|
||||
AD9528_CHANNEL_DIV, AD9528_CHANNEL_DIV, AD9528_CHANNEL_DIV, AD9528_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 = {
|
||||
5,25,25,5,5,
|
||||
5,5,5,5,5,
|
||||
5,5,10,5
|
||||
},
|
||||
.outFrequency_Hz = {
|
||||
200e6, 40e6, 40e6, 200e6, 200e6,
|
||||
200e6, 200e6, 200e6, 200e6, 200e6,
|
||||
200e6, 200e6, 100e6, 200e6
|
||||
}
|
||||
};
|
||||
|
||||
static ad9528sysrefSettings_t clockSysrefSettings = {
|
||||
.sysrefRequestMethod = PIN,
|
||||
.sysrefSource = INTERNAL,
|
||||
.sysrefPinEdgeMode = LEVEL_ACTIVE_HIGH,
|
||||
.sysrefPinBufferMode = DISABLED,
|
||||
.sysrefPatternMode = CONTINUOUS,
|
||||
.sysrefNshotMode = FOUR_PULSES,
|
||||
.sysrefDivide = 256
|
||||
};
|
||||
|
||||
static ad9528spiSettings_t clockSpiSettings = {
|
||||
.chipSelectIndex = AD9528_SPI_CS, //chip select Index, not used
|
||||
.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;
|
||||
};
|
||||
|
||||
ad9528Init_t ad9528_default_init_param = {
|
||||
/* SPI */
|
||||
.spi_init = &ad9528_spi_init,
|
||||
.gpio_init_resetb = &ad9528_gpio_resetb_init,
|
||||
.gpio_init_sysref_req = &ad9528_gpio_sysref_req_init,
|
||||
.spiSettings = &clockSpiSettings,
|
||||
.pll1Settings = &clockPll1Settings,
|
||||
.pll2Settings = &clockPll2Settings,
|
||||
.outputSettings = &clockOutputSettings,
|
||||
.sysrefSettings = &clockSysrefSettings
|
||||
};
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
#include "dev_profile.h"
|
||||
#include "spi.h"
|
||||
#include "../config/app_config.h"
|
||||
#include "../drivers/adc/ad9653/ad9653.h"
|
||||
#include "../drivers/axi_core/spi_engine/spi_engine.h"
|
||||
#include "../drivers/platform/xilinx_gpio.h"
|
||||
|
||||
static struct spi_engine_init_param spi_engine_param = {
|
||||
.ref_clk_hz = AD9653_SPI_ENGINE_REF_CLK,
|
||||
.type = SPI_ENGINE,
|
||||
.spi_engine_baseaddr = AD9653_SPI_ENGINE_BASEADDR,
|
||||
.cs_delay = AD9653_SPI_ENGINE_CS_DELAY,
|
||||
.data_width = AD9653_SPI_ENGINE_DATA_WIDTH
|
||||
};
|
||||
|
||||
static struct xil_gpio_init_param xil_gpio_param = {
|
||||
.type = GPIO_PS,
|
||||
.device_id = AD9653_GPIO_DEVICE_ID
|
||||
};
|
||||
|
||||
static struct spi_init_param ad9653_spi_init = {
|
||||
.device_id = AD9653_SPI_DEVICE_ID,
|
||||
.max_speed_hz = AD9653_SPI_ENGINE_MAX_SPEED,
|
||||
.mode = SPI_MODE_4,
|
||||
.chip_select = AD9653_SPI_CS,
|
||||
.platform_ops = &spi_eng_platform_ops,
|
||||
.extra = &spi_engine_param
|
||||
};
|
||||
|
||||
static struct gpio_init_param ad9653_gpio_resetb_init = {
|
||||
.number = AD9653_POWR_DOWN,
|
||||
.platform_ops = &xil_gpio_ops,
|
||||
.extra = &xil_gpio_param
|
||||
};
|
||||
|
||||
struct ad9653_init_param ad9653_default_init_param = {
|
||||
/* SPI */
|
||||
.spi_init = &ad9653_spi_init,
|
||||
.gpio_pdwn = &ad9653_gpio_resetb_init
|
||||
};
|
||||
|
||||
const uint32_t ad9653_default_config_len = 36;
|
||||
const struct ad9653_config ad9653_default_config[] = {
|
||||
// configuration
|
||||
|
||||
};
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
#include "dev_profile.h"
|
||||
#include "spi.h"
|
||||
#include "../config/app_config.h"
|
||||
#include "../drivers/adc/ad9694/ad9694.h"
|
||||
#include "../drivers/axi_core/spi_engine/spi_engine.h"
|
||||
#include "../drivers/platform/xilinx_gpio.h"
|
||||
|
||||
static struct spi_engine_init_param spi_engine_param = {
|
||||
.ref_clk_hz = AD9694_SPI_ENGINE_REF_CLK,
|
||||
.type = SPI_ENGINE,
|
||||
.spi_engine_baseaddr = AD9694_SPI_ENGINE_BASEADDR,
|
||||
.cs_delay = AD9694_SPI_ENGINE_CS_DELAY,
|
||||
.data_width = AD9694_SPI_ENGINE_DATA_WIDTH
|
||||
};
|
||||
|
||||
//static struct xil_gpio_init_param xil_gpio_param = {
|
||||
// .type = GPIO_PS,
|
||||
// .device_id = AD9694_GPIO_DEVICE_ID
|
||||
//};
|
||||
|
||||
static struct spi_init_param ad9694_spi_init = {
|
||||
.device_id = AD9694_SPI_DEVICE_ID,
|
||||
.max_speed_hz = AD9694_SPI_ENGINE_MAX_SPEED,
|
||||
.mode = SPI_MODE_4,
|
||||
.chip_select = AD9694_SPI_CS,
|
||||
.platform_ops = &spi_eng_platform_ops,
|
||||
.extra = &spi_engine_param
|
||||
};
|
||||
|
||||
struct ad9694_init_param ad9694_default_init_param = {
|
||||
/* SPI */
|
||||
.spi_init = &ad9694_spi_init
|
||||
};
|
||||
|
||||
const uint32_t ad9694_default_config_len = 36;
|
||||
const struct ad9694_config ad9694_default_config[] = {
|
||||
// reset
|
||||
{0x0000, 0x81},
|
||||
{0x1228, 0x4F}, // JESD204B start-up circuit reset
|
||||
{0x1228, 0x0F}, // JESD204B start-up normal operation
|
||||
{0x1222, 0x04}, // PLL calibration
|
||||
{0x1222, 0x00}, // PLL normal operation
|
||||
{0x1262, 0x08}, // PLL loss of lock control - Clear loss of lock
|
||||
{0x1262, 0x00}, // PLL loss of lock control - Normal operation
|
||||
|
||||
// system clock
|
||||
{0x0108, 0x00}, // Clock divider = 1 -> device clock = 368.64MHz
|
||||
{0x0201, 0x00}, // Chip decimation ration = 1 -> full sample rate
|
||||
|
||||
// channel configuration
|
||||
{0x0009, 0x03}, // ADC Pair AB & CD receive all spi command
|
||||
{0x0571, 0x15}, // JESD204B map JTX Link Control 1
|
||||
{0x056E, 0x00}, // JESD204B map PLL control, lane rate 6.75~13.5Gbps, actual = 7.3728Gbps
|
||||
{0x0570, 0x49}, // JESD204B map JTX quick config: L=2 M=2 F=2
|
||||
{0x058B, 0x01}, // JESD204B map JTX SCR L config: scrambler disabled, L=2
|
||||
{0x0590, 0x2F}, // JESD204B map JTX Subclass & NP config: subclass 1, N' = 16
|
||||
{0x058D, 0x1F}, // JESD204B map JTX K config: K = 32
|
||||
{0x058F, 0x2D}, // JESD204B map JTX N config: CS = 0, N = 14
|
||||
{0x0571, 0x14}, // JESD204B map JTX Link Control 1
|
||||
{0x05B0, 0x00}, // SERDOUTx0, SERDOUTx1 power on
|
||||
{0x0120, 0x0A}, // SYSREF COntrol: continuous mode, captured on falling edge
|
||||
|
||||
// fast detect control
|
||||
{0x0040, 0x00}, // FD_B/FD_D, FD_A/FD_C function as Fast Detect B/D, A/C output
|
||||
{0x0245, 0x01}, // Fine fast detect enabled
|
||||
{0x0247, 0xFE}, // Channel map fast detect upper threshold LSB
|
||||
{0x0248, 0x1F}, // Channel map fast detect upper threshold MSB, -> 8190
|
||||
{0x0249, 0xA4}, // Channel map fast detect lower threshold LSB
|
||||
{0x024A, 0x1F}, // Channel map fast detect lower threshold MSB, -> 8100
|
||||
{0x024B, 0x80}, // Channel map fast detect dwell time LSB
|
||||
{0x024C, 0x00} // Channel map fast detect dwell time MSB, -> 128
|
||||
};
|
||||
+228
@@ -0,0 +1,228 @@
|
||||
#include "dev_profile.h"
|
||||
#include "spi.h"
|
||||
#include "../config/app_config.h"
|
||||
#include "../drivers/rf-transceiver/cx9261a/cx9261a.h"
|
||||
#include "../drivers/axi_core/spi_engine/spi_engine.h"
|
||||
#include "../drivers/platform/xilinx_gpio.h"
|
||||
|
||||
static struct spi_engine_init_param spi_engine_param = {
|
||||
.ref_clk_hz = CX9261A_SPI_ENGINE_REF_CLK,
|
||||
.type = SPI_ENGINE,
|
||||
.spi_engine_baseaddr = CX9261A_SPI_ENGINE_BASEADDR,
|
||||
.cs_delay = CX9261A_SPI_ENGINE_CS_DELAY,
|
||||
.data_width = CX9261A_SPI_ENGINE_DATA_WIDTH
|
||||
};
|
||||
|
||||
static struct xil_gpio_init_param xil_gpio_param = {
|
||||
.type = GPIO_PS,
|
||||
.device_id = CX9261A_GPIO_DEVICE_ID
|
||||
};
|
||||
|
||||
static struct spi_init_param cx9261a_spi_init = {
|
||||
.device_id = CX9261A_SPI_DEVICE_ID,
|
||||
.max_speed_hz = CX9261A_SPI_ENGINE_MAX_SPEED,
|
||||
.mode = SPI_MODE_1,
|
||||
.chip_select = CX9261A_SPI_CS,
|
||||
.platform_ops = &spi_eng_platform_ops,
|
||||
.extra = &spi_engine_param
|
||||
};
|
||||
|
||||
static struct gpio_init_param cx9261a_gpio_nrst_init = {
|
||||
.number = CX9261A_NRST,
|
||||
.platform_ops = &xil_gpio_ops,
|
||||
.extra = &xil_gpio_param
|
||||
};
|
||||
|
||||
static struct gpio_init_param cx9261a_gpio_txnrx_trx1_init = {
|
||||
.number = CX9261A_TXNRX_TRX1,
|
||||
.platform_ops = &xil_gpio_ops,
|
||||
.extra = &xil_gpio_param
|
||||
};
|
||||
|
||||
static struct gpio_init_param cx9261a_gpio_txnrx_trx2_init = {
|
||||
.number = CX9261A_TXNRX_TRX2,
|
||||
.platform_ops = &xil_gpio_ops,
|
||||
.extra = &xil_gpio_param
|
||||
};
|
||||
|
||||
static struct gpio_init_param cx9261a_gpio_txnrx_rxfb_init = {
|
||||
.number = CX9261A_TXNRX_RXFB,
|
||||
.platform_ops = &xil_gpio_ops,
|
||||
.extra = &xil_gpio_param
|
||||
};
|
||||
|
||||
static struct gpio_init_param cx9261a_gpio_enable_trx1_init = {
|
||||
.number = CX9261A_ENABLE_TRX1,
|
||||
.platform_ops = &xil_gpio_ops,
|
||||
.extra = &xil_gpio_param
|
||||
};
|
||||
|
||||
static struct gpio_init_param cx9261a_gpio_enable_trx2_init = {
|
||||
.number = CX9261A_ENABLE_TRX2,
|
||||
.platform_ops = &xil_gpio_ops,
|
||||
.extra = &xil_gpio_param
|
||||
};
|
||||
|
||||
static struct gpio_init_param cx9261a_gpio_enable_rxfb_init = {
|
||||
.number = CX9261A_ENABLE_RXFB,
|
||||
.platform_ops = &xil_gpio_ops,
|
||||
.extra = &xil_gpio_param
|
||||
};
|
||||
|
||||
static struct gpio_init_param cx9261a_gpio_pl_rst_init = {
|
||||
.number = CX9261A_PL_RST,
|
||||
.platform_ops = &xil_gpio_ops,
|
||||
.extra = &xil_gpio_param
|
||||
};
|
||||
|
||||
static struct gpio_init_param cx9261a_gpio_tr_sel_init = {
|
||||
.number = CX9261A_TR_SEL,
|
||||
.platform_ops = &xil_gpio_ops,
|
||||
.extra = &xil_gpio_param
|
||||
};
|
||||
|
||||
static struct gpio_init_param cx9261a_gpio_tdd_fdd_sel_init = {
|
||||
.number = CX9261A_TDD_FDD_SEL,
|
||||
.platform_ops = &xil_gpio_ops,
|
||||
.extra = &xil_gpio_param
|
||||
};
|
||||
|
||||
static struct gpio_init_param cx9261a_gpio_r1t1_r2t2_sel_init = {
|
||||
.number = CX9261A_R1T1_R2T2_SEL,
|
||||
.platform_ops = &xil_gpio_ops,
|
||||
.extra = &xil_gpio_param
|
||||
};
|
||||
|
||||
static struct gpio_init_param cx9261a_gpio_sp_dp_sel_init = {
|
||||
.number = CX9261A_SP_DP_SEL,
|
||||
.platform_ops = &xil_gpio_ops,
|
||||
.extra = &xil_gpio_param
|
||||
};
|
||||
|
||||
static struct gpio_init_param cx9261a_gpio_mclk_delay_ctrl0_init = {
|
||||
.number = CX9261A_MCLK_DELAY_CTRL0,
|
||||
.platform_ops = &xil_gpio_ops,
|
||||
.extra = &xil_gpio_param
|
||||
};
|
||||
|
||||
static struct gpio_init_param cx9261a_gpio_mclk_delay_ctrl1_init = {
|
||||
.number = CX9261A_MCLK_DELAY_CTRL1,
|
||||
.platform_ops = &xil_gpio_ops,
|
||||
.extra = &xil_gpio_param
|
||||
};
|
||||
|
||||
static struct gpio_init_param cx9261a_gpio_mclk_delay_ctrl2_init = {
|
||||
.number = CX9261A_MCLK_DELAY_CTRL2,
|
||||
.platform_ops = &xil_gpio_ops,
|
||||
.extra = &xil_gpio_param
|
||||
};
|
||||
|
||||
static struct gpio_init_param cx9261a_gpio_hop_flag_init = {
|
||||
.number = CX9261A_HOP_FLAG,
|
||||
.platform_ops = &xil_gpio_ops,
|
||||
.extra = &xil_gpio_param
|
||||
};
|
||||
|
||||
struct cx9261a_init_param cx9261a_default_init_param = {
|
||||
/* SPI */
|
||||
.spi_init = &cx9261a_spi_init,
|
||||
.gpio_nrst = &cx9261a_gpio_nrst_init,
|
||||
.gpio_txnrx_trx1 = &cx9261a_gpio_txnrx_trx1_init,
|
||||
.gpio_txnrx_trx2 = &cx9261a_gpio_txnrx_trx2_init,
|
||||
.gpio_txnrx_rxfb = &cx9261a_gpio_txnrx_rxfb_init,
|
||||
.gpio_enable_trx1 = &cx9261a_gpio_enable_trx1_init,
|
||||
.gpio_enable_trx2 = &cx9261a_gpio_enable_trx2_init,
|
||||
.gpio_enable_rxfb = &cx9261a_gpio_enable_rxfb_init,
|
||||
.gpio_pl_rst = &cx9261a_gpio_pl_rst_init,
|
||||
.gpio_tr_sel = &cx9261a_gpio_tr_sel_init,
|
||||
.gpio_tdd_fdd_sel = &cx9261a_gpio_tdd_fdd_sel_init,
|
||||
.gpio_r1t1_r2t2_sel = &cx9261a_gpio_r1t1_r2t2_sel_init,
|
||||
.gpio_sp_dp_sel = &cx9261a_gpio_sp_dp_sel_init,
|
||||
.gpio_mclk_delay_ctrl0 = &cx9261a_gpio_mclk_delay_ctrl0_init,
|
||||
.gpio_mclk_delay_ctrl1 = &cx9261a_gpio_mclk_delay_ctrl1_init,
|
||||
.gpio_mclk_delay_ctrl2 = &cx9261a_gpio_mclk_delay_ctrl2_init,
|
||||
.gpio_hop_flag = &cx9261a_gpio_hop_flag_init
|
||||
};
|
||||
|
||||
CX9261A_CX9261AConfiguration cx9261a_configuration = {
|
||||
// 电源管理 (与评估软件电源管理自定义电源里面勾选项相对应,先左再右,从上往下)
|
||||
.powerManagement =
|
||||
{
|
||||
// 接收模式电源管理
|
||||
.rxPower = {0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0,
|
||||
0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1},
|
||||
// 发射模式电源管理
|
||||
.txPower = {1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1},
|
||||
// FDD模式电源管理
|
||||
.fddPower = {1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1,
|
||||
0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1},
|
||||
.powerMode = CX9261A_PWM_Duplex,
|
||||
},
|
||||
// 接口模式
|
||||
.interface = {.workMode = CX9261A_WKM_FDD,
|
||||
.trMode = CX9261A_TRM_R1T1,
|
||||
.portMode = CX9261A_PORTM_Single,
|
||||
.ioMode = CX9261A_IOM_CMOS},
|
||||
// 时钟相关
|
||||
.clock = {.ref = 100,
|
||||
.adc = 64,
|
||||
.refDiv = 1,
|
||||
.bbUseIntDiv = false,
|
||||
.refDoubler = false},
|
||||
// 本振相关
|
||||
// 本振来源
|
||||
.pllSource = {.rxUseExt = false,
|
||||
.txUseExt = false,
|
||||
.rx1Source = CX9261A_LOSRC_Pll1,
|
||||
.rx2Source = CX9261A_LOSRC_Pll2,
|
||||
.rx3Source = CX9261A_LOSRC_Off,
|
||||
.tx1Source = CX9261A_LOSRC_Pll1,
|
||||
.tx2Source = CX9261A_LOSRC_Pll2},
|
||||
// 本振频率 注意:使用的所有PLL,频率必须设为正数
|
||||
.pllFreq = {.pll1Freq = 121.88,
|
||||
.pll2Freq = 5000,
|
||||
.pll3Freq = 800,
|
||||
.pll4Freq = 900,
|
||||
.pll5Freq = 1000},
|
||||
// Rx通道 注意:tia推荐配置为6 Mixer为三个通道共用同一个寄存器
|
||||
.rx1Config = {.bandwidth = 32, .tia = 6, .mixer = 31},
|
||||
.rx2Config = {.bandwidth = 32, .tia = 6, .mixer = 31},
|
||||
.rx3Config = {.bandwidth = 32, .tia = 6, .mixer = 31},
|
||||
// Tx通道
|
||||
.tx1Config = {.bandwidth = 20, .mixer = 63},
|
||||
.tx2Config = {.bandwidth = 20, .mixer = 63},
|
||||
// 接收滤波器
|
||||
.rxFilters = {.fir = 0, .hbf1 = 0, .hbf2 = 0, .hbf3 = 0, .cic = 0},
|
||||
// 发射滤波器
|
||||
.txFilters = {.fir = 0, .hbf1 = 2, .hbf2 = 2, .hbf3 = 0, .cic = 0},
|
||||
// Rx NCO
|
||||
.rxNco = {.rxUseBist = false,
|
||||
.rxNCOBypass = true,
|
||||
.rxNCOUpward = true,
|
||||
.rxNCOMaster = true,
|
||||
.rxNCOFreq = 0},
|
||||
// Tx NCO
|
||||
.txNco = {.txUseBist = false, .txNCOFreq = 0},
|
||||
// AGC 注意:mode = 0表示关闭AGC,此时其他的参数可以不配置
|
||||
// 校准
|
||||
.calib = {.calibDC = true,
|
||||
.dcCalibMethod = CX9261A_DCCALM_Tracking,
|
||||
.dcTrackingLength = 16384,
|
||||
.dcHighPassFactor = 8191,
|
||||
.rx1CalibPll = CX9261A_LOSRC_Pll1 | CX9261A_LOSRC_Pll2,
|
||||
.rx2CalibPll = CX9261A_LOSRC_Pll1 | CX9261A_LOSRC_Pll2,
|
||||
.rx3CalibPll = CX9261A_LOSRC_Pll5,
|
||||
.tx1CalibPll = 0,
|
||||
.tx2CalibPll = 0,
|
||||
.rxMethod = CX9261A_CALM_Tracking,
|
||||
.txMethod = CX9261A_CALM_Bisec,
|
||||
.f0 = 4,
|
||||
// .rxMultiPoints = {2200, 2400, 2600, 2800, 3000, 3200, 3400,
|
||||
// 3600, 3800, 4000, 4200, 4400, 4600, 4800,
|
||||
// 5000, 5200, 5400, 5600, 5800, 6000}
|
||||
},
|
||||
.agc = {.mode = 0},
|
||||
.tempComp = CX9261A_TEMPCP_Band
|
||||
};
|
||||
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
#ifndef _DEV_PROFILE_H_
|
||||
#define _DEV_PROFILE_H_
|
||||
|
||||
#include "irq.h"
|
||||
#include "error.h"
|
||||
#include "../drivers/frequency/hmc7044/hmc7044.h"
|
||||
#include "../drivers/frequency/ad9528/ad9528.h"
|
||||
#include "../drivers/frequency/lmk04828/lmk04828.h"
|
||||
#include "../drivers/frequency/lmx2594/lmx2594.h"
|
||||
#include "../drivers/rf-transceiver/ad9361_reg/ad9361_reg.h"
|
||||
#include "../drivers/rf-transceiver/ad9361/ad9361_api.h"
|
||||
#include "../drivers/rf-transceiver/cx9261a/cx9261a.h"
|
||||
#include "../drivers/rf-transceiver/cx9261a/cx9261adriver_c.h"
|
||||
#include "../drivers/adc/ad9694/ad9694.h"
|
||||
#include "../drivers/adc/ad9653/ad9653.h"
|
||||
#include "../config/app_config.h"
|
||||
|
||||
// device parameters
|
||||
extern struct irq_init_param intc_init_param;
|
||||
extern struct timer_init_param apptimer_init_param;
|
||||
|
||||
// HMC7044
|
||||
extern struct hmc7044_init_param hmc7044_default_init_param;
|
||||
|
||||
// AD9528
|
||||
extern ad9528Init_t ad9528_default_init_param;
|
||||
|
||||
// LMK04828
|
||||
extern struct lmk04828_init_param lmk04828_default_init_param;
|
||||
extern const struct lmk04828_config lmk04828_default_config[];
|
||||
extern const uint32_t lmk04828_default_config_len;
|
||||
|
||||
// LMX2594
|
||||
extern struct lmx2594_init_param lmx2594_adc_init_param;
|
||||
extern struct lmx2594_init_param lmx2594_dac_init_param;
|
||||
extern const struct lmx2594_config lmx2594_default_config[];
|
||||
extern const uint32_t lmx2594_default_config_len;
|
||||
|
||||
// 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);
|
||||
|
||||
// CX9261A
|
||||
extern struct cx9261a_init_param cx9261a_default_init_param;
|
||||
extern CX9261A_CX9261AConfiguration cx9261a_configuration;
|
||||
|
||||
// AD9653
|
||||
extern struct ad9653_init_param ad9653_default_init_param;
|
||||
extern const struct ad9653_config ad9653_default_config[];
|
||||
extern const uint32_t ad9653_default_config_len;
|
||||
|
||||
// AD9694
|
||||
extern struct ad9694_init_param ad9694_default_init_param;
|
||||
extern const struct ad9694_config ad9694_default_config[];
|
||||
extern const uint32_t ad9694_default_config_len;
|
||||
|
||||
|
||||
#endif /* SRC_DEV_PROFILE_H_ */
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
#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,
|
||||
.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
|
||||
};
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
#include "dev_profile.h"
|
||||
#include "irq.h"
|
||||
#include "../config/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
|
||||
};
|
||||
+182
@@ -0,0 +1,182 @@
|
||||
#include "dev_profile.h"
|
||||
#include "spi.h"
|
||||
#include "../config/app_config.h"
|
||||
#include "../drivers/frequency/lmk04828/lmk04828.h"
|
||||
#include "../drivers/axi_core/spi_engine/spi_engine.h"
|
||||
#include "../drivers/platform/xilinx_gpio.h"
|
||||
|
||||
static struct spi_engine_init_param spi_engine_param = {
|
||||
.ref_clk_hz = LMK04828_SPI_ENGINE_REF_CLK,
|
||||
.type = SPI_ENGINE,
|
||||
.spi_engine_baseaddr = LMK04828_SPI_ENGINE_BASEADDR,
|
||||
.cs_delay = LMK04828_SPI_ENGINE_CS_DELAY,
|
||||
.data_width = LMK04828_SPI_ENGINE_DATA_WIDTH
|
||||
};
|
||||
|
||||
//static struct xil_gpio_init_param xil_gpio_param = {
|
||||
// .type = GPIO_PS,
|
||||
// .device_id = LMK04828_GPIO_DEVICE_ID
|
||||
//};
|
||||
|
||||
static struct spi_init_param lmk04828_spi_init = {
|
||||
.device_id = LMK04828_SPI_DEVICE_ID,
|
||||
.max_speed_hz = LMK04828_SPI_ENGINE_MAX_SPEED,
|
||||
.mode = SPI_MODE_0,
|
||||
.chip_select = LMK04828_SPI_CS,
|
||||
.platform_ops = &spi_eng_platform_ops,
|
||||
.extra = &spi_engine_param
|
||||
};
|
||||
|
||||
struct lmk04828_init_param lmk04828_default_init_param = {
|
||||
/* SPI */
|
||||
.spi_init = &lmk04828_spi_init
|
||||
};
|
||||
|
||||
const uint32_t lmk04828_default_config_len = 137;
|
||||
const struct lmk04828_config lmk04828_default_config[] = {
|
||||
// 192MHz
|
||||
{0x0000, 0x90}, // [7] reset; [4] 3-wire mode disabled
|
||||
{0x0000, 0x10}, // [7] normal operation; [4] 3-wire mode disabled
|
||||
{0x0002, 0x00}, // [0] normal operation
|
||||
{0x0003, 0x06}, // [7-0] product device type, read only, default: 6
|
||||
{0x0004, 0xD0}, // [7-0] msb of product identifier, read only, default: 208
|
||||
{0x0005, 0x5B}, // [7-0] lsb of product identifier, read only, default: 91
|
||||
{0x0006, 0x00}, // [7-0] ic version identifier, read only, default: 32
|
||||
{0x000C, 0x51}, // [7-0] msb of vendor identifier, read only, default: 81
|
||||
{0x000D, 0x04}, // [7-0] lsb of vendor identifier, read only, default: 4
|
||||
// device clock 0
|
||||
{0x0100, 0x10}, // [6] output drive level (ODL); [5] input drive level (IDL); [4-0] device clock (DCLK) output divider
|
||||
{0x0101, 0x55}, // DCLK: [7-4] output digital delay (DDLY) high count; [3-0] DDLY low count
|
||||
{0x0102, 0x55},
|
||||
{0x0103, 0x01}, // DCLK: [7-3] analog delay (ADLY) value, 25 ps per lsb; [2] ADLY input mux; [1-0] DCLK input mux
|
||||
{0x0104, 0x22}, // [6] DCLK half step value; [5] SDCLK output MUX; [4-1] SDCLK DDLY; [0] SYSREF half step value
|
||||
{0x0105, 0x00}, // SYSREF: [4] ADLY enable; [3:0] ADLY value, 600 ps + 150 ps per lsb
|
||||
{0x0106, 0xF0}, // [7] DCLK DDLY enable; [6] DCLK glitchless half step enable; [5] DCLK glitchless ADLY enable; [4] DCLK ADLY enable; [3]: clock group enable; [2-1] SYSREF disable mode; [0]: SYSREF disable
|
||||
{0x0107, 0x11}, // [7] SDCLK output polarity; [6-4] SDCLK output format; [3] DCLK output polarity; [2:0] DCLK output format
|
||||
// device clock 2
|
||||
{0x0108, 0x10}, // [6] output drive level (ODL); [5] input drive level (IDL); [4-0] device clock (DCLK) output divider
|
||||
{0x0109, 0x55}, // DCLK: [7-4] output digital delay (DDLY) high count; [3-0] DDLY low count
|
||||
{0x010A, 0x55},
|
||||
{0x010B, 0x00}, // DCLK: [7-3] analog delay (ADLY) value, 25 ps per lsb; [2] ADLY input mux; [1-0] DCLK input mux
|
||||
{0x010C, 0x22}, // [6] DCLK half step value; [5] SDCLK output MUX; [4-1] SDCLK DDLY; [0] SYSREF half step value
|
||||
{0x010D, 0x00}, // SYSREF: [4] ADLY enable; [3:0] ADLY value, 600 ps + 150 ps per lsb
|
||||
{0x010E, 0xF0}, // [7] DCLK DDLY enable; [6] DCLK glitchless half step enable; [5] DCLK glitchless ADLY enable; [4] DCLK ADLY enable; [3]: clock group enable; [2-1] SYSREF disable mode; [0]: SYSREF disable
|
||||
{0x010F, 0x10}, // [7] SDCLK output polarity; [6-4] SDCLK output format; [3] DCLK output polarity; [2:0] DCLK output format
|
||||
// device clock 4
|
||||
{0x0110, 0x10}, // [6] output drive level (ODL); [5] input drive level (IDL); [4-0] device clock (DCLK) output divider
|
||||
{0x0111, 0x55}, // DCLK: [7-4] output digital delay (DDLY) high count; [3-0] DDLY low count
|
||||
{0x0112, 0x55},
|
||||
{0x0113, 0x00}, // DCLK: [7-3] analog delay (ADLY) value, 25 ps per lsb; [2] ADLY input mux; [1-0] DCLK input mux
|
||||
{0x0114, 0x22}, // [6] DCLK half step value; [5] SDCLK output MUX; [4-1] SDCLK DDLY; [0] SYSREF half step value
|
||||
{0x0115, 0x00}, // SYSREF: [4] ADLY enable; [3:0] ADLY value, 600 ps + 150 ps per lsb
|
||||
{0x0116, 0xF0}, // [7] DCLK DDLY enable; [6] DCLK glitchless half step enable; [5] DCLK glitchless ADLY enable; [4] DCLK ADLY enable; [3]: clock group enable; [2-1] SYSREF disable mode; [0]: SYSREF disable
|
||||
{0x0117, 0x11}, // [7] SDCLK output polarity; [6-4] SDCLK output format; [3] DCLK output polarity; [2:0] DCLK output format
|
||||
// device clock 6
|
||||
{0x0118, 0x10}, // [6] output drive level (ODL); [5] input drive level (IDL); [4-0] device clock (DCLK) output divider
|
||||
{0x0119, 0x55}, // DCLK: [7-4] output digital delay (DDLY) high count; [3-0] DDLY low count
|
||||
{0x011A, 0x55},
|
||||
{0x011B, 0x00}, // DCLK: [7-3] analog delay (ADLY) value, 25 ps per lsb; [2] ADLY input mux; [1-0] DCLK input mux
|
||||
{0x011C, 0x02}, // [6] DCLK half step value; [5] SDCLK output MUX; [4-1] SDCLK DDLY; [0] SYSREF half step value
|
||||
{0x011D, 0x00}, // SYSREF: [4] ADLY enable; [3:0] ADLY value, 600 ps + 150 ps per lsb
|
||||
{0x011E, 0xF0}, // [7] DCLK DDLY enable; [6] DCLK glitchless half step enable; [5] DCLK glitchless ADLY enable; [4] DCLK ADLY enable; [3]: clock group enable; [2-1] SYSREF disable mode; [0]: SYSREF disable
|
||||
{0x011F, 0x55}, // [7] SDCLK output polarity; [6-4] SDCLK output format; [3] DCLK output polarity; [2:0] DCLK output format
|
||||
// device clock 8
|
||||
{0x0120, 0x10}, // [6] output drive level (ODL); [5] input drive level (IDL); [4-0] device clock (DCLK) output divider
|
||||
{0x0121, 0x55}, // DCLK: [7-4] output digital delay (DDLY) high count; [3-0] DDLY low count
|
||||
{0x0122, 0x55},
|
||||
{0x0123, 0x00}, // DCLK: [7-3] analog delay (ADLY) value, 25 ps per lsb; [2] ADLY input mux; [1-0] DCLK input mux
|
||||
{0x0124, 0x22}, // [6] DCLK half step value; [5] SDCLK output MUX; [4-1] SDCLK DDLY; [0] SYSREF half step value
|
||||
{0x0125, 0x00}, // SYSREF: [4] ADLY enable; [3:0] ADLY value, 600 ps + 150 ps per lsb
|
||||
{0x0126, 0xF0}, // [7] DCLK DDLY enable; [6] DCLK glitchless half step enable; [5] DCLK glitchless ADLY enable; [4] DCLK ADLY enable; [3]: clock group enable; [2-1] SYSREF disable mode; [0]: SYSREF disable
|
||||
{0x0127, 0x55}, // [7] SDCLK output polarity; [6-4] SDCLK output format; [3] DCLK output polarity; [2:0] DCLK output format
|
||||
// device clock 10
|
||||
{0x0128, 0x10}, // [6] output drive level (ODL); [5] input drive level (IDL); [4-0] device clock (DCLK) output divider
|
||||
{0x0129, 0x55}, // DCLK: [7-4] output digital delay (DDLY) high count; [3-0] DDLY low count
|
||||
{0x012A, 0x55},
|
||||
{0x012B, 0x00}, // DCLK: [7-3] analog delay (ADLY) value, 25 ps per lsb; [2] ADLY input mux; [1-0] DCLK input mux
|
||||
{0x012C, 0x22}, // [6] DCLK half step value; [5] SDCLK output MUX; [4-1] SDCLK DDLY; [0] SYSREF half step value
|
||||
{0x012D, 0x00}, // SYSREF: [4] ADLY enable; [3:0] ADLY value, 600 ps + 150 ps per lsb
|
||||
{0x012E, 0xF0}, // [7] DCLK DDLY enable; [6] DCLK glitchless half step enable; [5] DCLK glitchless ADLY enable; [4] DCLK ADLY enable; [3]: clock group enable; [2-1] SYSREF disable mode; [0]: SYSREF disable
|
||||
{0x012F, 0x51}, // [7] SDCLK output polarity; [6-4] SDCLK output format; [3] DCLK output polarity; [2:0] DCLK output format
|
||||
// device clock 12
|
||||
{0x0130, 0x10}, // [6] output drive level (ODL); [5] input drive level (IDL); [4-0] device clock (DCLK) output divider
|
||||
{0x0131, 0x55}, // DCLK: [7-4] output digital delay (DDLY) high count; [3-0] DDLY low count
|
||||
{0x0132, 0x55},
|
||||
{0x0133, 0x00}, // DCLK: [7-3] analog delay (ADLY) value, 25 ps per lsb; [2] ADLY input mux; [1-0] DCLK input mux
|
||||
{0x0134, 0x22}, // [6] DCLK half step value; [5] SDCLK output MUX; [4-1] SDCLK DDLY; [0] SYSREF half step value
|
||||
{0x0135, 0x00}, // SYSREF: [4] ADLY enable; [3:0] ADLY value, 600 ps + 150 ps per lsb
|
||||
{0x0136, 0xF0}, // [7] DCLK DDLY enable; [6] DCLK glitchless half step enable; [5] DCLK glitchless ADLY enable; [4] DCLK ADLY enable; [3]: clock group enable; [2-1] SYSREF disable mode; [0]: SYSREF disable
|
||||
{0x0137, 0x55}, // [7] SDCLK output polarity; [6-4] SDCLK output format; [3] DCLK output polarity; [2:0] DCLK output format
|
||||
// clock distribution source
|
||||
{0x0138, 0x20}, // [6-5] VCO mux; [4] OSCout mux; [3:0] OSCout format
|
||||
{0x0139, 0x03}, // [2] SYSREF output mux; [1-0] SYSREF source
|
||||
{0x013A, 0x0C}, // [4-0] SYSREF divider [12:8]
|
||||
{0x013B, 0x00}, // [7-0] SYSREF divider [7:0]
|
||||
{0x013C, 0x00}, // [4-0] SYSREF DDLY [12:8]
|
||||
{0x013D, 0x08}, // [7-0] SYSREF DDLY [7:0]
|
||||
{0x013E, 0x03}, // [1-0] SYSREF pulse count
|
||||
{0x013F, 0x00}, // [4] pll2 mux; [3] pll1 mux; [2-1] feedback mux; [0] feedback mux enable
|
||||
{0x0140, 0x0B}, // power-down control: [7] pll1; [6] vco_ldo; [5] vco; [4] OSCin; [3] individual SYSREF; [2] SYSREF; [1] SYSREF DDLY; [0] SYSREF pluse generator
|
||||
{0x0141, 0x00}, // dynamic DDLY control
|
||||
{0x0142, 0x00}, // dynamic DDLY step control
|
||||
{0x0143, 0x10},
|
||||
{0x0144, 0xFF},
|
||||
{0x0145, 0x7F},
|
||||
{0x0146, 0x12},
|
||||
{0x0147, 0x1A},
|
||||
{0x0148, 0x03},
|
||||
{0x0149, 0x05},
|
||||
{0x014A, 0x1B},
|
||||
{0x014B, 0x16},
|
||||
{0x014C, 0x00},
|
||||
{0x014D, 0x00},
|
||||
{0x014E, 0xC0},
|
||||
{0x014F, 0x7F},
|
||||
{0x0150, 0x03},
|
||||
{0x0151, 0x02},
|
||||
{0x0152, 0x00},
|
||||
{0x0153, 0x00},
|
||||
{0x0154, 0x78},
|
||||
{0x0155, 0x00},
|
||||
{0x0156, 0x7D},
|
||||
{0x0157, 0x00},
|
||||
{0x0158, 0x96},
|
||||
{0x0159, 0x06},
|
||||
{0x015A, 0x00},
|
||||
{0x015B, 0xD4},
|
||||
{0x015C, 0x20},
|
||||
{0x015D, 0x00},
|
||||
{0x015E, 0x00},
|
||||
{0x015F, 0x3B},
|
||||
{0x0160, 0x00},
|
||||
{0x0161, 0x02},
|
||||
{0x0162, 0x44},
|
||||
{0x0163, 0x00},
|
||||
{0x0164, 0x00},
|
||||
{0x0165, 0x0C},
|
||||
{0x0171, 0xAA},
|
||||
{0x0172, 0x02},
|
||||
{0x017C, 0x15},
|
||||
{0x017D, 0x33},
|
||||
{0x0166, 0x00},
|
||||
{0x0167, 0x00},
|
||||
{0x0168, 0x19},
|
||||
{0x0169, 0x59},
|
||||
{0x016A, 0x20},
|
||||
{0x016B, 0x00},
|
||||
{0x016C, 0x00},
|
||||
{0x016D, 0x00},
|
||||
{0x016E, 0x1B},
|
||||
{0x0173, 0x00},
|
||||
{0x0182, 0x00},
|
||||
{0x0183, 0x00},
|
||||
{0x0184, 0x00},
|
||||
{0x0185, 0x00},
|
||||
{0x0188, 0x00},
|
||||
{0x0189, 0x00},
|
||||
{0x018A, 0x00},
|
||||
{0x018B, 0x00},
|
||||
{0x1FFD, 0x00},
|
||||
{0x1FFE, 0x00},
|
||||
{0x1FFF, 0x53}
|
||||
};
|
||||
+181
@@ -0,0 +1,181 @@
|
||||
#include "dev_profile.h"
|
||||
#include "spi.h"
|
||||
#include "../config/app_config.h"
|
||||
#include "../drivers/frequency/lmx2594/lmx2594.h"
|
||||
#include "../drivers/axi_core/spi_engine/spi_engine.h"
|
||||
#include "../drivers/platform/xilinx_gpio.h"
|
||||
|
||||
static struct spi_engine_init_param spi_engine_param = {
|
||||
.ref_clk_hz = AD9653_SPI_ENGINE_REF_CLK,
|
||||
.type = SPI_ENGINE,
|
||||
.spi_engine_baseaddr = AD9653_SPI_ENGINE_BASEADDR,
|
||||
.cs_delay = AD9653_SPI_ENGINE_CS_DELAY,
|
||||
.data_width = AD9653_SPI_ENGINE_DATA_WIDTH
|
||||
};
|
||||
|
||||
//static struct xil_gpio_init_param xil_gpio_param = {
|
||||
// .type = GPIO_PS,
|
||||
// .device_id = AD9653_GPIO_DEVICE_ID
|
||||
//};
|
||||
|
||||
static struct spi_init_param lmx2594_adc_spi_init = {
|
||||
.device_id = LMX2594_ADC_SPI_DEVICE_ID,
|
||||
.max_speed_hz = LMX2594_ADC_SPI_ENGINE_MAX_SPEED,
|
||||
.mode = SPI_MODE_0,
|
||||
.chip_select = LMX2594_ADC_SPI_CS,
|
||||
.platform_ops = &spi_eng_platform_ops,
|
||||
.extra = &spi_engine_param
|
||||
};
|
||||
|
||||
static struct spi_init_param lmx2594_dac_spi_init = {
|
||||
.device_id = LMX2594_DAC_SPI_DEVICE_ID,
|
||||
.max_speed_hz = LMX2594_DAC_SPI_ENGINE_MAX_SPEED,
|
||||
.mode = SPI_MODE_0,
|
||||
.chip_select = LMX2594_DAC_SPI_CS,
|
||||
.platform_ops = &spi_eng_platform_ops,
|
||||
.extra = &spi_engine_param
|
||||
};
|
||||
|
||||
struct lmx2594_init_param lmx2594_adc_init_param = {
|
||||
/* SPI */
|
||||
.spi_init = &lmx2594_adc_spi_init
|
||||
};
|
||||
|
||||
struct lmx2594_init_param lmx2594_dac_init_param = {
|
||||
/* SPI */
|
||||
.spi_init = &lmx2594_dac_spi_init
|
||||
};
|
||||
|
||||
const uint32_t lmx2594_default_config_len = 110;
|
||||
const struct lmx2594_config lmx2594_default_config[] = {
|
||||
// 0 ~ 78: General configuration
|
||||
// 79 ~ 106: Ramping configuration
|
||||
// 107 ~ 112: Readback registers
|
||||
|
||||
// Recommended Initial Power-Up Sequence
|
||||
// For the most reliable programming, TI recommends this procedure::
|
||||
// 1. Apply power to device.
|
||||
// 2. Program RESET = 1 to reset registers.
|
||||
// 3. Program RESET = 0 to remove reset.
|
||||
// 4. Program registers as shown in the register map in REVERSE order from highest to lowest.
|
||||
// 5. Wait 10 ms.
|
||||
// 6. Program register R0 one additional time with FCAL_EN = 1 to ensure that the VCO calibration runs from a stable state.
|
||||
|
||||
// Reset
|
||||
{ 0, 0x0002},
|
||||
|
||||
// Remove Reset
|
||||
{ 0, 0x0000},
|
||||
|
||||
// Reverse order programming
|
||||
{106, 0x0000},
|
||||
{105, 0x0021},
|
||||
{104, 0x0000},
|
||||
{103, 0xD555},
|
||||
{102, 0x3F97},
|
||||
{101, 0x0011},
|
||||
{100, 0x0000},
|
||||
{ 99, 0x2AAB},
|
||||
{ 98, 0x01A0},
|
||||
{ 97, 0x0888},
|
||||
{ 96, 0x0000},
|
||||
{ 95, 0x0000}, // fixed
|
||||
{ 94, 0x0000}, // fixed
|
||||
{ 93, 0x0000}, // fixed
|
||||
{ 92, 0x0000}, // fixed
|
||||
{ 91, 0x0000}, // fixed
|
||||
{ 90, 0x0000}, // fixed
|
||||
{ 89, 0x0000}, // fixed
|
||||
{ 88, 0x0000}, // fixed
|
||||
{ 87, 0x0000}, // fixed
|
||||
{ 86, 0x5879},
|
||||
{ 85, 0xEC58},
|
||||
{ 84, 0x0001},
|
||||
{ 83, 0x54C9},
|
||||
{ 82, 0x2961},
|
||||
{ 81, 0x0000},
|
||||
{ 80, 0x4000},
|
||||
{ 79, 0x001F},
|
||||
{ 78, 0x0003}, // [8:1] VCO_CAPCTRL_STRT
|
||||
{ 77, 0x0000}, // fixed
|
||||
{ 76, 0x000C}, // fixed
|
||||
{ 75, 0x0800}, // [10:6] CHDIV
|
||||
{ 74, 0x0000}, // [11:6] JESD_DAC4_CTRL; [5:0] JESD_DAC3_CTRL
|
||||
{ 73, 0x003F}, // [11:6] JESD_DAC2_CTRL; [5:0] JESD_DAC1_CTRL
|
||||
{ 72, 0x0001}, // [10:0] SYSREF_DIV
|
||||
{ 71, 0x0081}, // [7:5] SYSREF_DIV_PRE; [4] SYSREF_PULSE; [3] SYSREF_EN; [2] SYSREF_REPEAT
|
||||
{ 70, 0xC350}, // [15:0] MASH_RST_COUNT
|
||||
{ 69, 0x0000}, // [15:0] MASH_RST_COUNT
|
||||
{ 68, 0x03E8}, // fixed
|
||||
{ 67, 0x0000}, // fixed
|
||||
{ 66, 0x01F4}, // fixed
|
||||
{ 65, 0x0000}, // fixed
|
||||
{ 64, 0x1388}, // fixed
|
||||
{ 63, 0x0000}, // fixed
|
||||
{ 62, 0x0322}, // fixed
|
||||
{ 61, 0x00A8}, // fixed
|
||||
{ 60, 0x0000}, // [15:0] LD_DLY
|
||||
{ 59, 0x0001}, // [0] LD_TYPE
|
||||
{ 58, 0x9001}, // [15] INPIN_IGNORE; [14] INPIN_HYST; [13:12] INPIN_LVL; [11:9] INPIN_FMT
|
||||
{ 57, 0x0020}, // fixed
|
||||
{ 56, 0x0000}, // fixed
|
||||
{ 55, 0x0000}, // fixed
|
||||
{ 54, 0x0000}, // fixed
|
||||
{ 53, 0x0000}, // fixed
|
||||
{ 52, 0x0820}, // fixed
|
||||
{ 51, 0x0080}, // fixed
|
||||
{ 50, 0x0000}, // fixed
|
||||
{ 49, 0x4180}, // fixed
|
||||
{ 48, 0x0300}, // fixed
|
||||
{ 47, 0x0300}, // fixed
|
||||
{ 46, 0x07FC}, // [1:0] OUTB_MUX
|
||||
{ 45, 0xC0DF}, // [12:11] OUTA_MUX; [10:9] OUT_ISET; [5:0] OUTB_PWR
|
||||
{ 44, 0x1AA3}, // [13:8] OUTA_PWR; [7] OUTB_PD; [6] OUTA_PD; [5] MASH_RESET_N; [2:0] MASH_ORDER
|
||||
{ 43, 0x0000}, // [15:0] PLL_NUM
|
||||
{ 42, 0x0000}, // [15:0] PLL_NUM
|
||||
{ 41, 0x0000}, // [15:0] MASH_SEE
|
||||
{ 40, 0x0000}, // [15:0] MASH_SEE
|
||||
{ 39, 0x03E8}, // [15:0] PLL_DEN
|
||||
{ 38, 0x0000}, // [15:0] PLL_DEN
|
||||
{ 37, 0x0304}, // [37] MASH_SEED_EN; [13:8] PFD_DLY_SEL
|
||||
{ 36, 0x0028}, // [15:0] PLL_N
|
||||
{ 35, 0x0004}, // fixed
|
||||
{ 34, 0x0000}, // [2:0] PLL_N
|
||||
{ 33, 0x1E21}, // fixed
|
||||
{ 32, 0x0393}, // fixed
|
||||
{ 31, 0x43EC}, // [14] SEG1_EN
|
||||
{ 30, 0x318C}, // fixed
|
||||
{ 29, 0x318C}, // fixed
|
||||
{ 28, 0x0488}, // fixed
|
||||
{ 27, 0x0002}, // fixed
|
||||
{ 26, 0x0DB0}, // fixed
|
||||
{ 25, 0x0C2B}, // fixed
|
||||
{ 24, 0x071A}, // fixed
|
||||
{ 23, 0x007C}, // fixed
|
||||
{ 22, 0x0001}, // fixed
|
||||
{ 21, 0x0401}, // fixed
|
||||
{ 20, 0xE048}, // [13:11] VCO_SEL. [10] VCO_SEL_FORCE
|
||||
{ 19, 0x27B7}, // [7:0] VCO_CAPCTRL
|
||||
{ 18, 0x0064}, // fixed
|
||||
{ 17, 0x012C}, // [8:0] VCO_DACISET_STRT
|
||||
{ 16, 0x0080}, // [8:0] VCO_DACISET
|
||||
{ 15, 0x064F}, // fixed
|
||||
{ 14, 0x1E70}, // [6:4] CPG
|
||||
{ 13, 0x4000}, // fixed
|
||||
{ 12, 0x5001}, // [11:0] PLL_R_PR
|
||||
{ 11, 0x0018}, // [11:4] PLL_R
|
||||
{ 10, 0x10D8}, // [11:7] MULT
|
||||
{ 9, 0x0604}, // [12] OSC_2X
|
||||
{ 8, 0x2000}, // [14] VCO_DACISET_FORCE; [11] VCO_CAPCTRL_FORCE
|
||||
{ 7, 0x40B2}, // [14] OUT_FORCE
|
||||
{ 6, 0xC802}, // fixed
|
||||
{ 5, 0x00C8}, // fixed
|
||||
{ 4, 0x0C43}, // [15:8] ACAL_CMP_DLY
|
||||
{ 3, 0x0642}, // fixed
|
||||
{ 2, 0x0500}, // fixed
|
||||
{ 1, 0x0809}, // [2:0] CAL_CLK_DIV
|
||||
{ 0, 0x2598}, // [15] RAMP_EN; [14] VCO_PHASE_SYNC; [9] OUT_MUTE; [8:7] FCAL_HPFD_ADJ; [6:5] FCAL_LPFD_ADJ; [3] FCAL_EN; [2] MUXOUT_LD_SEL; [1] RESET; [0] POWERDOWN
|
||||
|
||||
// one more time
|
||||
{ 0, 0x2598}
|
||||
};
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
#include "dev_profile.h"
|
||||
#include "timer.h"
|
||||
#include "../config/app_config.h"
|
||||
#include "../drivers/platform/xilinx_timer.h"
|
||||
|
||||
struct xil_timer_init_param xil_apptimer_init_param = {
|
||||
.active_tmr = 0,
|
||||
#ifdef __aarch64__
|
||||
.type = TIMER_PL
|
||||
#else
|
||||
.type = TIMER_PS
|
||||
#endif
|
||||
};
|
||||
|
||||
struct timer_init_param apptimer_init_param = {
|
||||
.id = APPTIMER_DEVICE_ID,
|
||||
.freq_hz = APP_TIMER_CLK_HZ,
|
||||
.ticks_count = (APP_TIMER_CLK_HZ/10), //update log every 100ms
|
||||
.platform_ops = &xil_timer_ops,
|
||||
.extra = &xil_apptimer_init_param
|
||||
};
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
/***************************************************************************//**
|
||||
* @file ad9653.c
|
||||
* @brief Implementation of AD9653 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 "ad9653.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "../../../include/error.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief ad9653_read
|
||||
*******************************************************************************/
|
||||
int32_t ad9653_read(struct ad9653_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 ad9653_write
|
||||
*******************************************************************************/
|
||||
int32_t ad9653_write(struct ad9653_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 ad9653_init
|
||||
*******************************************************************************/
|
||||
int32_t ad9653_init(struct ad9653_dev **device,
|
||||
const struct ad9653_init_param *init_param)
|
||||
{
|
||||
int ret = SUCCESS;
|
||||
struct ad9653_dev *dev;
|
||||
|
||||
dev = (struct ad9653_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 ad9653_setup().
|
||||
*
|
||||
* @param dev - The device structure.
|
||||
*
|
||||
* @return SUCCESS in case of success, negative error code otherwise.
|
||||
*******************************************************************************/
|
||||
int32_t ad9653_remove(struct ad9653_dev *dev)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
ret = spi_remove(dev->spi_desc);
|
||||
|
||||
free(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
+233
@@ -0,0 +1,233 @@
|
||||
/***************************************************************************//**
|
||||
* @file ad9653.h
|
||||
* @brief Header file of AD9653 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 AD9653_H_
|
||||
#define AD9653_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 ad9653_dev {
|
||||
/* SPI */
|
||||
struct spi_desc *spi_desc;
|
||||
struct gpio_desc *gpio_desc_pdwn;
|
||||
};
|
||||
|
||||
struct ad9653_init_param {
|
||||
/* SPI */
|
||||
struct spi_init_param *spi_init;
|
||||
struct gpio_init_param *gpio_pdwn;
|
||||
};
|
||||
|
||||
struct ad9653_config {
|
||||
uint16_t addr;
|
||||
uint8_t value;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Declarations ******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
int32_t ad9653_read(struct ad9653_dev *dev,
|
||||
uint16_t reg_addr,
|
||||
uint8_t *reg_data);
|
||||
|
||||
int32_t ad9653_write(struct ad9653_dev *dev,
|
||||
uint16_t reg_addr,
|
||||
uint8_t reg_data);
|
||||
|
||||
int32_t ad9653_init(struct ad9653_dev **device,
|
||||
const struct ad9653_init_param *init_param);
|
||||
|
||||
int32_t ad9653_remove(struct ad9653_dev *dev);
|
||||
|
||||
#endif
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
/***************************************************************************//**
|
||||
* @file ad9694.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 <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
@@ -0,0 +1,231 @@
|
||||
/***************************************************************************//**
|
||||
* @file ad9694.h
|
||||
* @brief Header file of AD9694 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 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
@@ -0,0 +1,241 @@
|
||||
/***************************************************************************//**
|
||||
* @file gpio.c
|
||||
* @brief Implementation of the GPIO Interface
|
||||
* @author Antoniu Miclaus (antoniu.miclaus@analog.com)
|
||||
********************************************************************************
|
||||
* 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
@@ -0,0 +1,135 @@
|
||||
/***************************************************************************//**
|
||||
* @file i2c.c
|
||||
* @brief Implementation of the I2C Interface
|
||||
* @author Antoniu Miclaus (antoniu.miclaus@analog.com)
|
||||
********************************************************************************
|
||||
* 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);
|
||||
}
|
||||
+229
@@ -0,0 +1,229 @@
|
||||
/***************************************************************************//**
|
||||
* @file irq.c
|
||||
* @brief Implementation of the IRQ Interface
|
||||
* @author Andrei Porumb (andrei.porumb@analog.com)
|
||||
********************************************************************************
|
||||
* Copyright 2021(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
#include "irq.h"
|
||||
#include "error.h"
|
||||
|
||||
/**
|
||||
* @brief Initialize the IRQ interrupts.
|
||||
* @param desc - The IRQ descriptor.
|
||||
* @param param - The structure that contains the IRQ parameters.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t irq_ctrl_init(struct irq_ctrl_desc **desc,
|
||||
const struct irq_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;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free the resources allocated by irq_ctrl_init().
|
||||
* @param desc - The SPI descriptor.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t irq_ctrl_remove(struct irq_ctrl_desc *desc)
|
||||
{
|
||||
if (!desc || !desc->platform_ops)
|
||||
return -EINVAL;
|
||||
|
||||
if (!desc->platform_ops->remove)
|
||||
return -ENOSYS;
|
||||
|
||||
return desc->platform_ops->remove(desc);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Register a callback to handle the irq events.
|
||||
* @param desc - The IRQ controller descriptor.
|
||||
* @param irq_id - Interrupt identifier.
|
||||
* @param callback - Callback descriptor - platform specific type.
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t irq_register_callback(struct irq_ctrl_desc *desc,
|
||||
uint32_t irq_id,
|
||||
struct callback_desc *callback)
|
||||
{
|
||||
if (!desc || !desc->platform_ops)
|
||||
return -EINVAL;
|
||||
|
||||
if (!desc->platform_ops->register_callback)
|
||||
return -ENOSYS;
|
||||
|
||||
return desc->platform_ops->register_callback(desc, irq_id, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unregisters a generic IRQ handling function.
|
||||
* @param desc - The IRQ controller descriptor.
|
||||
* @param irq_id - Interrupt identifier.
|
||||
* @param callback - Callback descriptor - platform specific type.
|
||||
* @return SUCCESS in case of success, FAILURE otherwise.
|
||||
*/
|
||||
int32_t irq_unregister_callback(struct irq_ctrl_desc *desc,
|
||||
uint32_t irq_id,
|
||||
struct callback_desc *callback)
|
||||
{
|
||||
if (!desc || !desc->platform_ops)
|
||||
return -EINVAL;
|
||||
|
||||
if (!desc->platform_ops->unregister_callback)
|
||||
return -ENOSYS;
|
||||
|
||||
return desc->platform_ops->unregister_callback(desc, irq_id, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable global interrupts.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t irq_global_enable(struct irq_ctrl_desc *desc)
|
||||
{
|
||||
if (!desc || !desc->platform_ops)
|
||||
return -EINVAL;
|
||||
|
||||
if (!desc->platform_ops->global_enable)
|
||||
return -ENOSYS;
|
||||
|
||||
return desc->platform_ops->global_enable(desc);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable global interrupts.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t irq_global_disable(struct irq_ctrl_desc *desc)
|
||||
{
|
||||
if (!desc || !desc->platform_ops)
|
||||
return -EINVAL;
|
||||
|
||||
if (!desc->platform_ops->global_disable)
|
||||
return -ENOSYS;
|
||||
|
||||
return desc->platform_ops->global_disable(desc);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set interrupt trigger level.
|
||||
* @param desc - The IRQ controller descriptor.
|
||||
* @param irq_id - Interrupt identifier.
|
||||
* @param trig - New trigger level for the interrupt.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t irq_trigger_level_set(struct irq_ctrl_desc *desc,
|
||||
uint32_t irq_id,
|
||||
enum irq_trig_level trig)
|
||||
{
|
||||
if (!desc || !desc->platform_ops)
|
||||
return -EINVAL;
|
||||
|
||||
if(!desc->platform_ops->trigger_level_set)
|
||||
return -ENOSYS;
|
||||
|
||||
return desc->platform_ops->trigger_level_set(desc, irq_id, trig);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable specific interrupt.
|
||||
* @param desc - The IRQ controller descriptor.
|
||||
* @param irq_id - Interrupt identifier.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t irq_enable(struct irq_ctrl_desc *desc, uint32_t irq_id)
|
||||
{
|
||||
if (!desc || !desc->platform_ops)
|
||||
return -EINVAL;
|
||||
|
||||
if (!desc->platform_ops->enable)
|
||||
return -ENOSYS;
|
||||
|
||||
return desc->platform_ops->enable(desc, irq_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable specific interrupt.
|
||||
* @param desc - The IRQ controller descriptor.
|
||||
* @param irq_id - Interrupt identifier.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t irq_disable(struct irq_ctrl_desc *desc, uint32_t irq_id)
|
||||
{
|
||||
if (!desc || !desc->platform_ops)
|
||||
return -EINVAL;
|
||||
|
||||
if (!desc->platform_ops->disable)
|
||||
return -ENOSYS;
|
||||
|
||||
return desc->platform_ops->disable(desc, irq_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the priority for an interrupt.
|
||||
* @param desc - The IRQ controller descriptor.
|
||||
* @param irq_id - Interrupt identifier.
|
||||
* @param priority_level - The priority level of the interrupt.
|
||||
* @return 0 in case of success, negative errno error codes.
|
||||
*/
|
||||
int32_t irq_set_priority(struct irq_ctrl_desc *desc,
|
||||
uint32_t irq_id,
|
||||
uint32_t priority_level)
|
||||
{
|
||||
if (!desc || !desc->platform_ops)
|
||||
return -EINVAL;
|
||||
|
||||
if (!desc->platform_ops->set_priority)
|
||||
return -ENOSYS;
|
||||
|
||||
return desc->platform_ops->set_priority(desc, irq_id, priority_level);
|
||||
}
|
||||
+161
@@ -0,0 +1,161 @@
|
||||
/***************************************************************************//**
|
||||
* @file spi.c
|
||||
* @brief Implementation of the SPI Interface
|
||||
* @author Antoniu Miclaus (antoniu.miclaus@analog.com)
|
||||
********************************************************************************
|
||||
* 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;
|
||||
}
|
||||
+211
@@ -0,0 +1,211 @@
|
||||
/***************************************************************************//**
|
||||
* @file timer.c
|
||||
* @brief Implementation of the timer Interface
|
||||
* @author RBolboac (ramona.bolboaca@analog.com)
|
||||
********************************************************************************
|
||||
* Copyright 2022(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 "error.h"
|
||||
#include "timer.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Definitions *******************************/
|
||||
/******************************************************************************/
|
||||
/**
|
||||
* @brief Initialize hardware timer and the handler structure associated with
|
||||
* it.
|
||||
* @param [out] desc - Pointer to the reference of the device handler.
|
||||
* @param [in] param - Initialization structure.
|
||||
* @return 0 in case of success, negative error code otherwise
|
||||
*/
|
||||
int32_t timer_init(struct timer_desc **desc,
|
||||
struct timer_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;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free the memory allocated by timer_init().
|
||||
* @param [in] desc - Pointer to the device handler.
|
||||
* @return 0 in case of success, negative error code otherwise
|
||||
*/
|
||||
int32_t timer_remove(struct timer_desc *desc)
|
||||
{
|
||||
if (!desc || !desc->platform_ops)
|
||||
return -EINVAL;
|
||||
|
||||
if (!desc->platform_ops->remove)
|
||||
return -ENOSYS;
|
||||
|
||||
return desc->platform_ops->remove(desc);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Start a timer.
|
||||
* @param [in] desc - Pointer to the device handler.
|
||||
* @return 0 in case of success, negative error code otherwise
|
||||
*/
|
||||
int32_t timer_start(struct timer_desc *desc)
|
||||
{
|
||||
if (!desc || !desc->platform_ops)
|
||||
return -EINVAL;
|
||||
|
||||
if (!desc->platform_ops->start)
|
||||
return -ENOSYS;
|
||||
|
||||
return desc->platform_ops->start(desc);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stop a timer from counting.
|
||||
* @param [in] desc - Pointer to the device handler.
|
||||
* @return 0 in case of success, negative error code otherwise
|
||||
*/
|
||||
int32_t timer_stop(struct timer_desc *desc)
|
||||
{
|
||||
if (!desc || !desc->platform_ops)
|
||||
return -EINVAL;
|
||||
|
||||
if (!desc->platform_ops->stop)
|
||||
return -ENOSYS;
|
||||
|
||||
return desc->platform_ops->stop(desc);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the value of the counter register for the timer.
|
||||
* @param [in] desc - Pointer to the device handler.
|
||||
* @param [out] counter - Pointer to the counter value.
|
||||
* @return 0 in case of success, error code otherwise.
|
||||
*/
|
||||
int32_t timer_counter_get(struct timer_desc *desc,
|
||||
uint32_t *counter)
|
||||
{
|
||||
if (!desc || !desc->platform_ops || !counter)
|
||||
return -EINVAL;
|
||||
|
||||
if (!desc->platform_ops->counter_get)
|
||||
return -ENOSYS;
|
||||
|
||||
return desc->platform_ops->counter_get(desc, counter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the timer counter register value.
|
||||
* @param [in] desc - Pointer to the device handler.
|
||||
* @param [in] new_val - The new value of the counter register.
|
||||
* @return 0 in case of success, error code otherwise.
|
||||
*/
|
||||
int32_t timer_counter_set(struct timer_desc *desc, uint32_t new_val)
|
||||
{
|
||||
if (!desc || !desc->platform_ops)
|
||||
return -EINVAL;
|
||||
|
||||
if (!desc->platform_ops->counter_set)
|
||||
return -ENOSYS;
|
||||
|
||||
return desc->platform_ops->counter_set(desc, new_val);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the timer clock frequency.
|
||||
* @param [in] desc - Pointer to the device handler.
|
||||
* @param [out] freq_hz - The value in Hz of the timer clock.
|
||||
* @return 0 in case of success, error code otherwise.
|
||||
*/
|
||||
int32_t timer_count_clk_get(struct timer_desc *desc,
|
||||
uint32_t *freq_hz)
|
||||
{
|
||||
if (!desc || !desc->platform_ops || !freq_hz)
|
||||
return -EINVAL;
|
||||
|
||||
if (!desc->platform_ops->count_clk_get)
|
||||
return -ENOSYS;
|
||||
|
||||
return desc->platform_ops->count_clk_get(desc, freq_hz);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the timer clock frequency.
|
||||
* @param [in] desc - Pointer to the device handler.
|
||||
* @param [in] freq_hz - The value in Hz of the new timer clock.
|
||||
* @return 0 in case of success, error code otherwise.
|
||||
*/
|
||||
int32_t timer_count_clk_set(struct timer_desc *desc,
|
||||
uint32_t freq_hz)
|
||||
{
|
||||
if (!desc || !desc->platform_ops)
|
||||
return -EINVAL;
|
||||
|
||||
if (!desc->platform_ops->count_clk_set)
|
||||
return -ENOSYS;
|
||||
|
||||
return desc->platform_ops->count_clk_set(desc, freq_hz);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the elapsed time in nsec for the timer.
|
||||
* @param [in] desc - Pointer to the device handler.
|
||||
* @param [in] elapsed_time - The elapsed time in nsec.
|
||||
* @return 0 in case of success, error code otherwise.
|
||||
*/
|
||||
int32_t timer_get_elapsed_time_nsec(struct timer_desc *desc,
|
||||
uint64_t *elapsed_time)
|
||||
{
|
||||
if (!desc || !desc->platform_ops)
|
||||
return -EINVAL;
|
||||
|
||||
if (!desc->platform_ops->get_elapsed_time_nsec)
|
||||
return -ENOSYS;
|
||||
|
||||
return desc->platform_ops->get_elapsed_time_nsec(desc, elapsed_time);
|
||||
}
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
/***************************************************************************//**
|
||||
* @file trng.c
|
||||
* @brief Implementation of the TRNG Interface
|
||||
* @author Antoniu Miclaus (antoniu.miclaus@analog.com)
|
||||
********************************************************************************
|
||||
* 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);
|
||||
}
|
||||
+547
@@ -0,0 +1,547 @@
|
||||
/*******************************************************************************
|
||||
* @file axi_dmac.c
|
||||
* @brief Driver for the Analog Devices AXI-DMAC core.
|
||||
* @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 <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "axi_io.h"
|
||||
#include "error.h"
|
||||
#include "delay.h"
|
||||
#include "axi_dmac.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* @brief ISR for dev to mem DMA transfer. It computes the next transfer params,
|
||||
* if any, and sets the transfer structure fields accordingly.
|
||||
*
|
||||
* @param instance - the instance that triggered the ISR.
|
||||
*
|
||||
* @return None.
|
||||
*******************************************************************************/
|
||||
void axi_dmac_dev_to_mem_isr(void *instance)
|
||||
{
|
||||
struct axi_dmac *dmac = (struct axi_dmac *)instance;
|
||||
uint32_t burst_size;
|
||||
uint32_t reg_val;
|
||||
|
||||
/* Get interrupt sources and clear interrupts. */
|
||||
axi_dmac_read(dmac, AXI_DMAC_REG_IRQ_PENDING, ®_val);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_IRQ_PENDING, reg_val);
|
||||
|
||||
if (reg_val & AXI_DMAC_IRQ_SOT) {
|
||||
if (dmac->remaining_size) {
|
||||
/* See if remaining size is bigger than max transfer size and
|
||||
* set burst size. */
|
||||
if (dmac->remaining_size > dmac->max_length) {
|
||||
burst_size = dmac->max_length;
|
||||
} else {
|
||||
burst_size = dmac->remaining_size - 1;
|
||||
}
|
||||
|
||||
/* The current transfer was started; set up the new one. */
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_DEST_ADDRESS, dmac->next_dest_addr);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_DEST_STRIDE, 0x0);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_X_LENGTH, burst_size);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_Y_LENGTH, 0x0);
|
||||
|
||||
/* Compute size of the next transfer. */
|
||||
dmac->remaining_size = dmac->remaining_size - (burst_size + 1);
|
||||
/* Address must advance with +1 since the DMAC writes X_LENGTH+1. */
|
||||
dmac->next_dest_addr = dmac->next_dest_addr + (burst_size + 1);
|
||||
|
||||
/* Trigger the next transfer. */
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_TRANSFER_SUBMIT, AXI_DMAC_TRANSFER_SUBMIT);
|
||||
}
|
||||
}
|
||||
if (reg_val & AXI_DMAC_IRQ_EOT) {
|
||||
if (!dmac->remaining_size) {
|
||||
dmac->transfer.transfer_done = true;
|
||||
dmac->next_dest_addr = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* @brief ISR for mem DMA to dev transfer. It computes the next transfer params,
|
||||
* if any, and sets the transfer structure fields accordingly.
|
||||
*
|
||||
* @param instance - the instance that triggered the ISR.
|
||||
*
|
||||
* @return None.
|
||||
*******************************************************************************/
|
||||
void axi_dmac_mem_to_dev_isr(void *instance)
|
||||
{
|
||||
struct axi_dmac *dmac = (struct axi_dmac *)instance;
|
||||
uint32_t burst_size;
|
||||
uint32_t reg_val;
|
||||
|
||||
/* Get interrupt sources and clear interrupts. */
|
||||
axi_dmac_read(dmac, AXI_DMAC_REG_IRQ_PENDING, ®_val);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_IRQ_PENDING, reg_val);
|
||||
|
||||
if (reg_val & AXI_DMAC_IRQ_SOT) {
|
||||
if ((dmac->transfer.cyclic == CYCLIC) &&
|
||||
(dmac->next_src_addr >= (dmac->init_addr + dmac->transfer.size - 1))) {
|
||||
dmac->remaining_size = dmac->transfer.size;
|
||||
dmac->next_src_addr = dmac->init_addr;
|
||||
}
|
||||
|
||||
if (dmac->remaining_size) {
|
||||
/** See if remaining size is bigger than max transfer size and
|
||||
* set burst size. */
|
||||
if (dmac->remaining_size > dmac->max_length) {
|
||||
burst_size = dmac->max_length;
|
||||
} else {
|
||||
burst_size = dmac->remaining_size - 1;
|
||||
}
|
||||
|
||||
/* The current transfer was started; set up the new one. */
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_SRC_ADDRESS, dmac->next_src_addr);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_SRC_STRIDE, 0x0);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_X_LENGTH, burst_size);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_Y_LENGTH, 0x0);
|
||||
|
||||
/* Compute parameters for the next transfer. */
|
||||
dmac->remaining_size = dmac->remaining_size - (burst_size + 1);
|
||||
/* Address must advance with +1 since the DMAC writes X_LENGTH+1. */
|
||||
dmac->next_src_addr = dmac->next_src_addr + (burst_size + 1);
|
||||
|
||||
/* Trigger the current transfer */
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_TRANSFER_SUBMIT, AXI_DMAC_TRANSFER_SUBMIT);
|
||||
}
|
||||
}
|
||||
if (reg_val & AXI_DMAC_IRQ_EOT) {
|
||||
if ((!dmac->remaining_size) && (dmac->transfer.cyclic != CYCLIC)) {
|
||||
dmac->transfer.transfer_done = true;
|
||||
dmac->next_src_addr = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* @brief ISR for mem DMA to mem DMA transfer. It computes the next transfer
|
||||
* params, if any, and sets the transfer structure fields accordingly.
|
||||
*
|
||||
* @param instance - the instance that triggered the ISR.
|
||||
*
|
||||
* @return None.
|
||||
*******************************************************************************/
|
||||
void axi_dmac_mem_to_mem_isr(void *instance)
|
||||
{
|
||||
struct axi_dmac *dmac = (struct axi_dmac *)instance;
|
||||
uint32_t burst_size;
|
||||
uint32_t reg_val;
|
||||
|
||||
/* Get interrupt sources and clear interrupts. */
|
||||
axi_dmac_read(dmac, AXI_DMAC_REG_IRQ_PENDING, ®_val);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_IRQ_PENDING, reg_val);
|
||||
|
||||
if (reg_val & AXI_DMAC_IRQ_SOT) {
|
||||
if (dmac->remaining_size) {
|
||||
/** See if remaining size is bigger than max transfer size and
|
||||
* set burst size. */
|
||||
if (dmac->remaining_size > dmac->max_length) {
|
||||
burst_size = dmac->max_length;
|
||||
} else {
|
||||
burst_size = dmac->remaining_size - 1;
|
||||
}
|
||||
|
||||
/* The current transfer was started; set up the new one. */
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_SRC_ADDRESS, dmac->next_src_addr);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_SRC_STRIDE, 0x0);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_DEST_ADDRESS, dmac->next_dest_addr);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_DEST_STRIDE, 0x0);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_X_LENGTH, burst_size);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_Y_LENGTH, 0x0);
|
||||
|
||||
/* Compute parameters for the next transfer. */
|
||||
dmac->remaining_size = dmac->remaining_size - (burst_size + 1);
|
||||
/* Address must advance with +1 since the DMAC writes X_LENGTH+1. */
|
||||
dmac->next_src_addr = dmac->next_src_addr + (burst_size + 1);
|
||||
dmac->next_dest_addr = dmac->next_dest_addr + (burst_size + 1);
|
||||
|
||||
/* If transfer finished advance src address so that transfer_done can be set*/
|
||||
if (!dmac->remaining_size) {
|
||||
dmac->next_src_addr = dmac->next_src_addr + (burst_size + 1);
|
||||
}
|
||||
|
||||
/* Trigger the current transfer */
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_TRANSFER_SUBMIT, AXI_DMAC_TRANSFER_SUBMIT);
|
||||
}
|
||||
}
|
||||
if (reg_val & AXI_DMAC_IRQ_EOT) {
|
||||
if (!dmac->remaining_size) {
|
||||
if(dmac->next_src_addr > (dmac->init_addr + dmac->transfer.size)) {
|
||||
dmac->transfer.transfer_done = true;
|
||||
dmac->next_src_addr = 0;
|
||||
dmac->next_dest_addr = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* @brief Wrapper for AXI IO through UIO/devmem read function.
|
||||
*
|
||||
* @param dmac - DMAC istance containing UIO index (/dev/uioX)/base address.
|
||||
* @param reg_addr - Address to read from.
|
||||
* @param reg_data - Location where read data will be stored.
|
||||
*
|
||||
* @return 0 - success.
|
||||
*******************************************************************************/
|
||||
int32_t axi_dmac_read(struct axi_dmac *dmac,
|
||||
uint32_t reg_addr,
|
||||
uint32_t *reg_data)
|
||||
{
|
||||
axi_io_read(dmac->base, reg_addr, reg_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* @brief Wrapper for AXI IO through UIO/devmem wrrite function.
|
||||
*
|
||||
* @param dmac - DMAC istance containing UIO index (/dev/uioX)/base address.
|
||||
* @param reg_addr - Address to write to.
|
||||
* @param reg_data - Data to be written.
|
||||
*
|
||||
* @return 0 - success.
|
||||
*******************************************************************************/
|
||||
int32_t axi_dmac_write(struct axi_dmac *dmac,
|
||||
uint32_t reg_addr,
|
||||
uint32_t reg_data)
|
||||
{
|
||||
axi_io_write(dmac->base, reg_addr, reg_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* @brief Get transfer status (value of dmac->transfer.transfer_done flag).
|
||||
*
|
||||
* @note This function should not be used if DMA IRQ is not used.
|
||||
*
|
||||
* @param dmac - DMAC istance.
|
||||
* @param rdy - Transfer status (0 - not ready, 1 - ready).
|
||||
*
|
||||
* @return 0 - success.
|
||||
*******************************************************************************/
|
||||
int32_t axi_dmac_is_transfer_ready(struct axi_dmac *dmac, bool *rdy)
|
||||
{
|
||||
*rdy = dmac->transfer.transfer_done;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* @brief Get DMAC capabilities.
|
||||
*
|
||||
* @param dmac - DMAC istance.
|
||||
*
|
||||
* @return 0 for success, -1 in case of failure.
|
||||
*******************************************************************************/
|
||||
static int32_t axi_dmac_detect_caps(struct axi_dmac *dmac)
|
||||
{
|
||||
uint32_t reg_val, initial_reg_val = 0;
|
||||
uint32_t src_mem_mapped = 0;
|
||||
uint32_t dest_mem_mapped = 0;
|
||||
|
||||
dmac->max_length = -1;
|
||||
dmac->direction = INVALID_DIR;
|
||||
|
||||
/* Check if HW cyclic possible */
|
||||
axi_dmac_read(dmac, AXI_DMAC_REG_FLAGS, &initial_reg_val);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_FLAGS, DMA_CYCLIC);
|
||||
axi_dmac_read(dmac, AXI_DMAC_REG_FLAGS, ®_val);
|
||||
if (reg_val == DMA_CYCLIC)
|
||||
dmac->hw_cyclic = true;
|
||||
/* Restore initial value for AXI_DMAC_REG_FLAGS register */
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_FLAGS, initial_reg_val);
|
||||
|
||||
/* Get maximum burst size and set value. */
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_X_LENGTH, dmac->max_length);
|
||||
axi_dmac_read(dmac, AXI_DMAC_REG_X_LENGTH, &dmac->max_length);
|
||||
|
||||
/* Get transfer direction and set value. */
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_DEST_ADDRESS, 0xffffffff);
|
||||
axi_dmac_read(dmac, AXI_DMAC_REG_DEST_ADDRESS, &dest_mem_mapped);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_SRC_ADDRESS, 0xffffffff);
|
||||
axi_dmac_read(dmac, AXI_DMAC_REG_SRC_ADDRESS, &src_mem_mapped);
|
||||
|
||||
if (dest_mem_mapped && !src_mem_mapped) {
|
||||
dmac->direction = DMA_DEV_TO_MEM;
|
||||
} else if (!dest_mem_mapped && src_mem_mapped) {
|
||||
dmac->direction = DMA_MEM_TO_DEV;
|
||||
} else if (dest_mem_mapped && src_mem_mapped) {
|
||||
dmac->direction = DMA_MEM_TO_MEM;
|
||||
} else {
|
||||
printf("Destination and source memory-mapped interfaces not supported.\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* @brief Get transfer status (value of dmac->transfer.transfer_done flag).
|
||||
*
|
||||
* @param dmac_core - DMAC istance.
|
||||
* @param init - Structure containing initializing data.
|
||||
*
|
||||
* @return 0 for success, -1 in case of failure.
|
||||
*******************************************************************************/
|
||||
int32_t axi_dmac_init(struct axi_dmac **dmac_core,
|
||||
const struct axi_dmac_init *init)
|
||||
{
|
||||
struct axi_dmac *dmac;
|
||||
|
||||
dmac = (struct axi_dmac *)calloc(1, sizeof(*dmac));
|
||||
if (!dmac)
|
||||
return -1;
|
||||
|
||||
dmac->name = init->name;
|
||||
dmac->base = init->base;
|
||||
dmac->irq_option = init->irq_option;
|
||||
|
||||
*dmac_core = dmac;
|
||||
|
||||
int32_t status = axi_dmac_detect_caps(*dmac_core);
|
||||
if (status < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* @brief Remove the DMAC instance.
|
||||
*
|
||||
* @param dmac - DMAC istance.
|
||||
*
|
||||
* @return 0 for success, -1 in case of failure.
|
||||
*******************************************************************************/
|
||||
int32_t axi_dmac_remove(struct axi_dmac *dmac)
|
||||
{
|
||||
if (!dmac)
|
||||
return -1;
|
||||
|
||||
free(dmac);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* @brief Start a DMA transfer.
|
||||
*
|
||||
* @param dmac - DMAC istance.
|
||||
* @param dma_transfer - Structure containing transfer details.
|
||||
*
|
||||
* @return 0 for success, -1 in case of failure.
|
||||
*******************************************************************************/
|
||||
int32_t axi_dmac_transfer_start(struct axi_dmac *dmac,
|
||||
struct axi_dma_transfer *dma_transfer)
|
||||
{
|
||||
uint32_t reg_val, burst_size;
|
||||
|
||||
if (dma_transfer->size == 0)
|
||||
return 0; /* Nothing to do. */
|
||||
|
||||
/* Set current transfer parameters. */
|
||||
dmac->transfer.size = dma_transfer->size;
|
||||
dmac->transfer.cyclic = dma_transfer->cyclic;
|
||||
dmac->transfer.dest_addr = dma_transfer->dest_addr;
|
||||
dmac->transfer.src_addr = dma_transfer->src_addr;
|
||||
|
||||
dmac->remaining_size = dma_transfer->size;
|
||||
dmac->next_dest_addr = dma_transfer->dest_addr;
|
||||
dmac->next_src_addr = dma_transfer->src_addr;
|
||||
|
||||
/* If HW cyclic transfer selected and not available, show error */
|
||||
/* HW cyclic transfer available only for MEM to DEV transfers. */
|
||||
if ((!dmac->hw_cyclic) && (dma_transfer->cyclic == CYCLIC)) {
|
||||
printf("Transfer mode not supported!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Cyclic transfers not possible for DEV_TO_MEM and MEM_TO_MEM transmissions. */
|
||||
if ((dmac->direction == DMA_DEV_TO_MEM)
|
||||
|| (dmac->direction == DMA_MEM_TO_MEM)) {
|
||||
if (dma_transfer->cyclic == CYCLIC) {
|
||||
printf("Transfer mode not supported!\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Cyclic transfers set to HW or SW depending on size for MEM to DEV. */
|
||||
if ((dmac->direction == DMA_MEM_TO_DEV) && (dmac->transfer.cyclic == CYCLIC)) {
|
||||
if ((dmac->remaining_size - 1) <= dmac->max_length) {
|
||||
if (dmac->hw_cyclic) {
|
||||
axi_dmac_read(dmac, AXI_DMAC_REG_FLAGS, ®_val);
|
||||
reg_val = reg_val | DMA_CYCLIC;
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_FLAGS, reg_val);
|
||||
}
|
||||
} else {
|
||||
axi_dmac_read(dmac, AXI_DMAC_REG_FLAGS, ®_val);
|
||||
reg_val = reg_val & ~DMA_CYCLIC;
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_FLAGS, reg_val);
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable DMA if not already enabled. */
|
||||
axi_dmac_read(dmac, AXI_DMAC_REG_CTRL, ®_val);
|
||||
if (!(reg_val & AXI_DMAC_CTRL_ENABLE)) {
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_CTRL, 0x0);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_CTRL, AXI_DMAC_CTRL_ENABLE);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_IRQ_MASK, 0x0);
|
||||
}
|
||||
|
||||
axi_dmac_read(dmac, AXI_DMAC_REG_TRANSFER_SUBMIT, ®_val);
|
||||
/* If we don't have a start of transfer then start compute
|
||||
* values and trigger next transfer. */
|
||||
if (!(reg_val & AXI_DMAC_QUEUE_FULL)) {
|
||||
switch (dmac->direction) {
|
||||
case DMA_DEV_TO_MEM:
|
||||
dmac->init_addr = dmac->next_dest_addr;
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_DEST_ADDRESS, dmac->next_dest_addr);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_DEST_STRIDE, 0x0);
|
||||
break;
|
||||
case DMA_MEM_TO_DEV:
|
||||
dmac->init_addr = dmac->next_src_addr;
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_SRC_ADDRESS, dmac->next_src_addr);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_SRC_STRIDE, 0x0);
|
||||
break;
|
||||
case DMA_MEM_TO_MEM:
|
||||
dmac->init_addr = dmac->next_src_addr;
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_DEST_ADDRESS, dmac->next_dest_addr);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_DEST_STRIDE, 0x0);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_SRC_ADDRESS, dmac->next_src_addr);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_SRC_STRIDE, 0x0);
|
||||
break;
|
||||
default:
|
||||
return -1; /* Other directions are not supported yet. */
|
||||
}
|
||||
|
||||
/* Compute the burst size. */
|
||||
if (dmac->remaining_size > dmac->max_length) {
|
||||
burst_size = dmac->max_length;
|
||||
} else {
|
||||
burst_size = dmac->remaining_size - 1;
|
||||
}
|
||||
|
||||
/* Compute next address (src or dest, or both, depending on type of transfer). */
|
||||
switch (dmac->direction) {
|
||||
case DMA_DEV_TO_MEM:
|
||||
dmac->next_dest_addr = dmac->next_dest_addr + (burst_size + 1);
|
||||
break;
|
||||
case DMA_MEM_TO_DEV:
|
||||
dmac->next_src_addr = dmac->next_src_addr + (burst_size + 1);
|
||||
break;
|
||||
case DMA_MEM_TO_MEM:
|
||||
dmac->next_dest_addr = dmac->next_dest_addr + (burst_size + 1);
|
||||
dmac->next_src_addr = dmac->next_src_addr + (burst_size + 1);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Compute remaining size. */
|
||||
dmac->remaining_size = dmac->remaining_size - (burst_size + 1);
|
||||
|
||||
/* Specify the length of the transfer and trigger transfer. */
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_X_LENGTH, burst_size);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_Y_LENGTH, 0x0);
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_TRANSFER_SUBMIT, AXI_DMAC_TRANSFER_SUBMIT);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* @brief Wait for DMA transfer to be completed.
|
||||
*
|
||||
* @param dmac - DMAC istance.
|
||||
* @param timeout_ms - Number of ms to wait for completion of transfer.
|
||||
*
|
||||
* @return 0 for success, -1 in case trasnfer not completed in specified time.
|
||||
*******************************************************************************/
|
||||
int32_t axi_dmac_transfer_wait_completion(struct axi_dmac *dmac,
|
||||
uint32_t timeout_ms)
|
||||
{
|
||||
uint32_t timeout = 0;
|
||||
uint32_t reg_val = 0;
|
||||
|
||||
if (dmac->irq_option == IRQ_ENABLED) {
|
||||
while (!dmac->transfer.transfer_done) {
|
||||
timeout++;
|
||||
mdelay(1);
|
||||
if (timeout == timeout_ms) {
|
||||
printf("Error transferring data using DMA.\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} else if (dmac->irq_option == IRQ_DISABLED) {
|
||||
axi_dmac_read(dmac, AXI_DMAC_REG_IRQ_PENDING, ®_val);
|
||||
while (reg_val != (AXI_DMAC_IRQ_SOT | AXI_DMAC_IRQ_EOT)) {
|
||||
timeout++;
|
||||
mdelay(1);
|
||||
if (timeout == timeout_ms) {
|
||||
printf("Error transferring data using DMA.\n");
|
||||
return -1;
|
||||
}
|
||||
axi_dmac_read(dmac, AXI_DMAC_REG_IRQ_PENDING, ®_val);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* @brief Stop a DMA transfer.
|
||||
*
|
||||
* @param dmac - DMAC istance.
|
||||
*
|
||||
* @return None
|
||||
*******************************************************************************/
|
||||
void axi_dmac_transfer_stop(struct axi_dmac *dmac)
|
||||
{
|
||||
axi_dmac_write(dmac, AXI_DMAC_REG_CTRL, AXI_DMAC_CTRL_DISABLE);
|
||||
}
|
||||
+156
@@ -0,0 +1,156 @@
|
||||
/***************************************************************************//**
|
||||
* @file axi_dmac.h
|
||||
* @brief Driver for the Analog Devices AXI-DMAC core.
|
||||
* @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.
|
||||
*******************************************************************************/
|
||||
#ifndef AXI_DMAC_H_
|
||||
#define AXI_DMAC_H_
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
#include <stdint.h>
|
||||
#include "util.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** Macros and Constants Definitions **********************/
|
||||
/******************************************************************************/
|
||||
#define AXI_DMAC_REG_IRQ_MASK 0x80
|
||||
#define AXI_DMAC_REG_IRQ_PENDING 0x84
|
||||
#define AXI_DMAC_IRQ_SOT BIT(0)
|
||||
#define AXI_DMAC_IRQ_EOT BIT(1)
|
||||
|
||||
#define AXI_DMAC_REG_INTF_DESC 0x010
|
||||
#define AXI_DMAC_DMA_TYPE_DEST GENMASK(5,4)
|
||||
#define AXI_DMAC_DMA_TYPE_SRC GENMASK(13,12)
|
||||
//Define macro for src and dest
|
||||
|
||||
#define AXI_DMAC_REG_CTRL 0x400
|
||||
#define AXI_DMAC_CTRL_ENABLE BIT(0)
|
||||
#define AXI_DMAC_CTRL_DISABLE 0u
|
||||
#define AXI_DMAC_CTRL_PAUSE BIT(1)
|
||||
|
||||
#define AXI_DMAC_REG_TRANSFER_ID 0x404
|
||||
#define AXI_DMAC_REG_TRANSFER_SUBMIT 0x408
|
||||
#define AXI_DMAC_TRANSFER_SUBMIT BIT(0)
|
||||
#define AXI_DMAC_QUEUE_FULL BIT(0)
|
||||
#define AXI_DMAC_REG_FLAGS 0x40c
|
||||
#define AXI_DMAC_REG_DEST_ADDRESS 0x410
|
||||
#define AXI_DMAC_REG_SRC_ADDRESS 0x414
|
||||
#define AXI_DMAC_REG_X_LENGTH 0x418
|
||||
#define AXI_DMAC_REG_Y_LENGTH 0x41c
|
||||
#define AXI_DMAC_REG_DEST_STRIDE 0x420
|
||||
#define AXI_DMAC_REG_SRC_STRIDE 0x424
|
||||
#define AXI_DMAC_REG_TRANSFER_DONE 0x428
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
enum use_irq {
|
||||
IRQ_DISABLED = 0,
|
||||
IRQ_ENABLED = 1
|
||||
};
|
||||
|
||||
enum dma_direction {
|
||||
INVALID_DIR = 0,
|
||||
DMA_DEV_TO_MEM = 1,
|
||||
DMA_MEM_TO_DEV = 2,
|
||||
DMA_MEM_TO_MEM = 3
|
||||
};
|
||||
|
||||
enum dma_flags {
|
||||
DMA_CYCLIC = 1,
|
||||
DMA_LAST = 2,
|
||||
DMA_PARTIAL_REPORTING_EN = 4
|
||||
};
|
||||
|
||||
// Could be transformed to a bool
|
||||
enum cyclic_transfer {
|
||||
NO = 0,
|
||||
CYCLIC = 1
|
||||
};
|
||||
|
||||
struct axi_dma_transfer {
|
||||
uint32_t size;
|
||||
volatile bool transfer_done;
|
||||
enum cyclic_transfer cyclic;
|
||||
uint32_t src_addr;
|
||||
uint32_t dest_addr;
|
||||
};
|
||||
|
||||
struct axi_dmac {
|
||||
const char *name;
|
||||
uint32_t base;
|
||||
enum use_irq irq_option;
|
||||
enum dma_direction direction;
|
||||
bool hw_cyclic;
|
||||
uint32_t max_length;
|
||||
volatile struct axi_dma_transfer transfer;
|
||||
//Current sub-transfer properties
|
||||
uint32_t init_addr;
|
||||
uint32_t remaining_size;
|
||||
uint32_t next_src_addr;
|
||||
uint32_t next_dest_addr;
|
||||
};
|
||||
|
||||
struct axi_dmac_init {
|
||||
const char *name;
|
||||
uint32_t base;
|
||||
enum use_irq irq_option;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Declarations ******************************/
|
||||
/******************************************************************************/
|
||||
void axi_dmac_dev_to_mem_isr(void *instance);
|
||||
void axi_dmac_mem_to_dev_isr(void *instance);
|
||||
void axi_dmac_mem_to_mem_isr(void *instance);
|
||||
void axi_dmac_write_isr(void *instance);
|
||||
int32_t axi_dmac_read(struct axi_dmac *dmac, uint32_t reg_addr,
|
||||
uint32_t *reg_data);
|
||||
int32_t axi_dmac_write(struct axi_dmac *dmac, uint32_t reg_addr,
|
||||
uint32_t reg_data);
|
||||
int32_t axi_dmac_is_transfer_ready(struct axi_dmac *dmac, bool *rdy);
|
||||
int32_t axi_dmac_init(struct axi_dmac **adc_core,
|
||||
const struct axi_dmac_init *init);
|
||||
int32_t axi_dmac_remove(struct axi_dmac *dmac);
|
||||
int32_t axi_dmac_transfer_start(struct axi_dmac *dmac,
|
||||
struct axi_dma_transfer *dma_transfer);
|
||||
int32_t axi_dmac_transfer_wait_completion(struct axi_dmac *dmac,
|
||||
uint32_t timeout_ms);
|
||||
void axi_dmac_transfer_stop(struct axi_dmac *dmac);
|
||||
|
||||
#endif
|
||||
+996
@@ -0,0 +1,996 @@
|
||||
/*******************************************************************************
|
||||
* @file spi_engine.c
|
||||
* @brief Core implementation of the SPI Engine Driver.
|
||||
* @author Sergiu Cuciurean (sergiu.cuciurean@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.
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/* In debug mode the printf function used in displaying the messages is causing
|
||||
significant delays */
|
||||
//#define DEBUG_LEVEL 2
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sleep.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "axi_io.h"
|
||||
#include "error.h"
|
||||
#include "spi_engine.h"
|
||||
|
||||
/**
|
||||
* @brief Spi engine platform specific SPI platform ops structure
|
||||
*/
|
||||
const struct spi_platform_ops spi_eng_platform_ops = {
|
||||
.init = &spi_engine_init,
|
||||
.write_and_read = &spi_engine_write_and_read,
|
||||
.write_and_read_3wire = &spi_engine_write_and_read_3wire,
|
||||
.remove = &spi_engine_remove
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Static variables *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Static variable used to sync transfers
|
||||
*
|
||||
*/
|
||||
static uint8_t _sync_id = 0x01;
|
||||
|
||||
/******************************************************************************/
|
||||
/************************** Functions Implementation **************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Write SPI Engine's axi registers
|
||||
*
|
||||
* @param desc Decriptor containing SPI Engine's parameters
|
||||
* @param reg_addr The address of the SPI Engine's axi register where the data
|
||||
* will be written
|
||||
* @param reg_data Data that will be written
|
||||
* @return int32_t This function allways returns SUCCESS
|
||||
*/
|
||||
int32_t spi_engine_write(struct spi_engine_desc *desc,
|
||||
uint32_t reg_addr,
|
||||
uint32_t reg_data)
|
||||
{
|
||||
axi_io_write(desc->spi_engine_baseaddr, reg_addr, reg_data);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read SPI Engine's axi registers
|
||||
*
|
||||
* @param desc Decriptor containing SPI Engine's parameters
|
||||
* @param reg_addr The address of the SPI Engine's axi register from where the
|
||||
* data where the data will be read
|
||||
* @param reg_data Pointer where the read that will be stored
|
||||
* @return int32_t This function allways returns SUCCESS
|
||||
*/
|
||||
int32_t spi_engine_read(struct spi_engine_desc *desc,
|
||||
uint32_t reg_addr,
|
||||
uint32_t *reg_data)
|
||||
{
|
||||
axi_io_read(desc->spi_engine_baseaddr, reg_addr, reg_data);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set width of the transferred word over SPI
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @param data_width The desired data width
|
||||
* The supported values are:
|
||||
* - 8
|
||||
* - 16
|
||||
* - 24
|
||||
* - 32
|
||||
*/
|
||||
int32_t spi_engine_set_transfer_width(struct spi_desc *desc,
|
||||
uint8_t data_width)
|
||||
{
|
||||
struct spi_engine_desc *desc_extra;
|
||||
|
||||
desc_extra = desc->extra;
|
||||
|
||||
if (data_width > desc_extra->max_data_width)
|
||||
desc_extra->data_width = desc_extra->max_data_width;
|
||||
else
|
||||
desc_extra->data_width = data_width;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set SPI engine clock frequency
|
||||
*
|
||||
* @param desc Decriptor containing SPI Engine's parameters
|
||||
* @param speed_hz SPI engine transfer speed
|
||||
*/
|
||||
void spi_engine_set_speed(struct spi_desc *desc,
|
||||
uint32_t speed_hz)
|
||||
{
|
||||
struct spi_engine_desc *desc_extra;
|
||||
|
||||
desc_extra = desc->extra;
|
||||
|
||||
desc_extra->clk_div = desc_extra->ref_clk_hz /
|
||||
(2 * speed_hz) - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the number of words transferred in a single transaction
|
||||
*
|
||||
* @param desc Decriptor containing SPI Engine's parameters
|
||||
* @param bytes_number The number of bytes to be converted
|
||||
* @return uint8_t A number of words in which bytes_number can be grouped
|
||||
*/
|
||||
static uint8_t spi_get_words_number(struct spi_engine_desc *desc,
|
||||
uint8_t bytes_number)
|
||||
{
|
||||
uint8_t xfer_word_len;
|
||||
uint8_t words_number;
|
||||
|
||||
xfer_word_len = desc->data_width / 8;
|
||||
words_number = bytes_number / xfer_word_len;
|
||||
|
||||
if ((bytes_number % xfer_word_len) != 0)
|
||||
words_number++;
|
||||
|
||||
return words_number;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the word length in bytes
|
||||
*
|
||||
* @param desc Decriptor containing SPI Engine's parameters
|
||||
* @return uint8_t Number of bytes that fit in one word
|
||||
*/
|
||||
static uint8_t spi_get_word_length(struct spi_engine_desc *desc)
|
||||
{
|
||||
uint8_t word_length;
|
||||
|
||||
word_length = desc->data_width / 8;
|
||||
|
||||
return word_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Compute the prescaler used to set the sleep period.
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @param sleep_time_ns The amount of time where the transfer hangs
|
||||
* @param sleep_div Clock prescaler
|
||||
* @return int32_t This function allways returns SUCCESS
|
||||
*/
|
||||
static int32_t spi_get_sleep_div(struct spi_desc *desc,
|
||||
uint32_t sleep_time_ns,
|
||||
uint32_t *sleep_div)
|
||||
{
|
||||
struct spi_engine_desc *eng_desc;
|
||||
|
||||
eng_desc = desc->extra;
|
||||
|
||||
/*
|
||||
* Engine Wiki:
|
||||
*
|
||||
* The frequency of the SCLK signal is derived from the
|
||||
* module clock frequency using the following formula:
|
||||
* f_sclk = f_clk / ((div + 1) * 2)
|
||||
*/
|
||||
|
||||
*sleep_div = (desc->max_speed_hz / 1000000 * sleep_time_ns / 1000) /
|
||||
((eng_desc->clk_div + 1) * 2) - 1;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create a new commands queue used in a spi transfer
|
||||
*
|
||||
* @param fifo Command buffer, usually used in fifo mode
|
||||
* @param cmd Command with which the buffer will be initiated
|
||||
* @return int32_t Failure if the memory allocation failed
|
||||
*/
|
||||
static int32_t spi_engine_queue_new_cmd(struct spi_engine_cmd_queue **fifo,
|
||||
uint32_t cmd)
|
||||
{
|
||||
struct spi_engine_cmd_queue *local_fifo;
|
||||
|
||||
local_fifo = (spi_engine_cmd_queue*)malloc(sizeof(*local_fifo));
|
||||
|
||||
if(!local_fifo)
|
||||
return FAILURE;
|
||||
|
||||
local_fifo->cmd = cmd;
|
||||
local_fifo->next = NULL;
|
||||
*fifo = local_fifo;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Add a command at the end of an existing queue
|
||||
*
|
||||
* @param fifo Command buffer, usually used in fifo mode
|
||||
* @param cmd Command to be added
|
||||
*/
|
||||
static void spi_engine_queue_add_cmd(struct spi_engine_cmd_queue **fifo,
|
||||
uint32_t cmd)
|
||||
{
|
||||
struct spi_engine_cmd_queue *to_add = NULL;
|
||||
struct spi_engine_cmd_queue *local_fifo;
|
||||
|
||||
local_fifo = *fifo;
|
||||
while (local_fifo->next != NULL) {
|
||||
// Get the last element
|
||||
local_fifo = local_fifo->next;
|
||||
}
|
||||
|
||||
// Create a new element
|
||||
spi_engine_queue_new_cmd(&to_add, cmd);
|
||||
// Add as the next element
|
||||
local_fifo->next = to_add;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Add a command at the beginning of an existing queue
|
||||
*
|
||||
* @param fifo Command buffer, usually used in fifo mode
|
||||
* @param cmd Command to be added
|
||||
*/
|
||||
static void spi_engine_queue_append_cmd(struct spi_engine_cmd_queue **fifo,
|
||||
uint32_t cmd)
|
||||
{
|
||||
struct spi_engine_cmd_queue *to_add = NULL;
|
||||
|
||||
// Create a new element
|
||||
spi_engine_queue_new_cmd(&to_add, cmd);
|
||||
// Interchange the addresses
|
||||
to_add->next = *fifo;
|
||||
*fifo = to_add;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get the command from the beginning of the queue
|
||||
*
|
||||
* @param fifo Command buffer, usually used in fifo mode
|
||||
* @param cmd Value of the command that was extracted
|
||||
* @return int32_t Return FAILURE if the queue is empty
|
||||
*/
|
||||
static int32_t spi_engine_queue_get_cmd(struct spi_engine_cmd_queue **fifo,
|
||||
uint32_t *cmd)
|
||||
{
|
||||
struct spi_engine_cmd_queue *local_fifo;
|
||||
|
||||
if (!*fifo)
|
||||
return FAILURE;
|
||||
|
||||
local_fifo = *fifo;
|
||||
*cmd = local_fifo->cmd;
|
||||
if ((*fifo)->next) {
|
||||
*fifo = local_fifo->next;
|
||||
free(local_fifo);
|
||||
} else {
|
||||
free(*fifo);
|
||||
*fifo = NULL;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free the memory allocated by a queue
|
||||
*
|
||||
* @param fifo The queue that needs it's memory freed
|
||||
* @return int32_t This function always returns SUCCESS
|
||||
*/
|
||||
static int32_t spi_engine_queue_free(struct spi_engine_cmd_queue **fifo)
|
||||
{
|
||||
if(*fifo && (*fifo)->next)
|
||||
spi_engine_queue_free(&(*fifo)->next);
|
||||
if((*fifo) != NULL) {
|
||||
free(*fifo);
|
||||
*fifo = NULL;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write the SPI engine's command fifo
|
||||
*
|
||||
* @param desc Decriptor containing SPI Engine's parameters
|
||||
* @param cmd The command that will be written
|
||||
* @return int32_t Returns FAILURE if the the axi transfer failed
|
||||
*/
|
||||
static int32_t spi_engine_write_cmd_reg(struct spi_engine_desc *desc,
|
||||
uint32_t cmd)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
/* Check if offload is enabled */
|
||||
if(desc->offload_config & (OFFLOAD_TX_EN | OFFLOAD_RX_EN)) {
|
||||
ret = spi_engine_write(desc,
|
||||
SPI_ENGINE_REG_OFFLOAD_CMD_MEM(0),
|
||||
cmd);
|
||||
|
||||
} else {
|
||||
ret = spi_engine_write(desc,
|
||||
SPI_ENGINE_REG_CMD_FIFO,
|
||||
cmd);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write a transfer command to the SPI engine's command fifo
|
||||
*
|
||||
* @param desc Decriptor containing SPI Engine's parameters
|
||||
* @param read_write Read/Write operation flag
|
||||
* @param bytes_number Number of bytes to transfer
|
||||
* @return int32_t This function always returns SUCCESS
|
||||
*/
|
||||
static int32_t spi_engine_transfer(struct spi_engine_desc *desc,
|
||||
uint8_t read_write,
|
||||
uint8_t bytes_number)
|
||||
{
|
||||
uint8_t words_number;
|
||||
|
||||
words_number = spi_get_words_number(desc, bytes_number);
|
||||
|
||||
desc->offload_tx_len += words_number;
|
||||
|
||||
/*
|
||||
* Engine Wiki:
|
||||
*
|
||||
* https://wiki.analog.com/resources/fpga/peripherals/spi_engine
|
||||
*
|
||||
* The words number is zero based
|
||||
*/
|
||||
|
||||
spi_engine_write_cmd_reg(desc,
|
||||
SPI_ENGINE_CMD_TRANSFER(read_write,
|
||||
words_number - 1));
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Change the state of the chip select port
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @param assert Chip select state.
|
||||
* The supported values are :
|
||||
* -true (HIGH)
|
||||
* -false (LOW)
|
||||
*/
|
||||
static void spi_engine_set_cs(struct spi_desc *desc,
|
||||
bool assert)
|
||||
{
|
||||
uint8_t mask;
|
||||
struct spi_engine_desc *eng_desc;
|
||||
|
||||
eng_desc = desc->extra;
|
||||
|
||||
mask = 0xFF;
|
||||
/* Switch the state only of the selected chip select */
|
||||
if (!assert)
|
||||
mask ^= BIT(desc->chip_select);
|
||||
|
||||
spi_engine_write_cmd_reg(eng_desc,
|
||||
SPI_ENGINE_CMD_ASSERT(eng_desc->cs_delay,
|
||||
mask));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Add a delay between the engine commands
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @param sleep_time_ns Number of nanoseconds to sleep between commands
|
||||
*/
|
||||
static void spi_gen_sleep_ns(struct spi_desc *desc,
|
||||
uint32_t sleep_time_ns)
|
||||
{
|
||||
uint32_t sleep_div;
|
||||
struct spi_engine_desc *eng_desc;
|
||||
|
||||
eng_desc = desc->extra;
|
||||
|
||||
spi_get_sleep_div(desc, sleep_time_ns, &sleep_div);
|
||||
|
||||
spi_engine_write_cmd_reg(eng_desc, SPI_ENGINE_CMD_SLEEP(sleep_div));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Spi engine command interpreter
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @param cmd Command to send to the engine
|
||||
* @return int32_t - SUCCESS if the command is transferred
|
||||
* - FAILURE if the command format is invalid
|
||||
*/
|
||||
static int32_t spi_engine_write_cmd(struct spi_desc *desc,
|
||||
uint32_t cmd)
|
||||
{
|
||||
uint8_t engine_command;
|
||||
uint8_t parameter;
|
||||
uint8_t modifier;
|
||||
struct spi_engine_desc *desc_extra;
|
||||
|
||||
desc_extra = desc->extra;
|
||||
|
||||
engine_command = (cmd >> 12) & 0x0F;
|
||||
modifier = (cmd >> 8) & 0x0F;
|
||||
parameter = cmd & 0xFF;
|
||||
|
||||
switch(engine_command) {
|
||||
case SPI_ENGINE_INST_TRANSFER:
|
||||
spi_engine_transfer(desc_extra, modifier, parameter);
|
||||
break;
|
||||
|
||||
case SPI_ENGINE_INST_ASSERT:
|
||||
if(parameter == 0xFF) {
|
||||
/* Set the CS HIGH */
|
||||
spi_engine_set_cs(desc, true);
|
||||
} else if(parameter == 0x00) {
|
||||
/* Set the CS LOW */
|
||||
spi_engine_set_cs(desc, false);
|
||||
}
|
||||
break;
|
||||
|
||||
/* The SYNC and SLEEP commands got the same value but different
|
||||
modifier */
|
||||
case SPI_ENGINE_INST_SYNC_SLEEP:
|
||||
/* SYNC instruction */
|
||||
if(modifier == 0x00) {
|
||||
spi_engine_write_cmd_reg(desc_extra, cmd);
|
||||
} else if(modifier == 0x01) {
|
||||
spi_gen_sleep_ns(desc, parameter);
|
||||
}
|
||||
break;
|
||||
case SPI_ENGINE_INST_CONFIG:
|
||||
spi_engine_write_cmd_reg(desc_extra, cmd);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepare the command queue before sending it to the engine
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @param msg Structure used to store the transfer messages
|
||||
* @return int32_t This function always returns SUCCESS
|
||||
*/
|
||||
static int32_t spi_engine_compile_message(struct spi_desc *desc,
|
||||
struct spi_engine_msg *msg)
|
||||
{
|
||||
struct spi_engine_desc *desc_extra;
|
||||
|
||||
desc_extra = desc->extra;
|
||||
|
||||
/* Configure the prescaler */
|
||||
spi_engine_queue_append_cmd(&msg->cmds,
|
||||
SPI_ENGINE_CMD_CONFIG(
|
||||
SPI_ENGINE_CMD_REG_CLK_DIV,
|
||||
desc_extra->clk_div));
|
||||
|
||||
/* Set the data transfer length */
|
||||
spi_engine_queue_append_cmd(&msg->cmds,
|
||||
SPI_ENGINE_CMD_CONFIG(
|
||||
SPI_ENGINE_CMD_DATA_TRANSFER_LEN,
|
||||
desc_extra->data_width));
|
||||
/*
|
||||
* Configure the spi mode :
|
||||
* - 3 wire
|
||||
* - CPOL
|
||||
* - CPHA
|
||||
*/
|
||||
spi_engine_queue_append_cmd(&msg->cmds,
|
||||
SPI_ENGINE_CMD_CONFIG(
|
||||
SPI_ENGINE_CMD_REG_CONFIG,
|
||||
desc->mode));
|
||||
|
||||
/* Add a sync command to signal that the transfer has finished */
|
||||
spi_engine_queue_add_cmd(&msg->cmds, SPI_ENGINE_CMD_SYNC(_sync_id));
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initiate a spi transfer (Blocking)
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @param msg Structure used to store the transfer messages
|
||||
* @return int32_t - SUCCESS if the transfer finished
|
||||
* - FAILURE if the memory allocation failed
|
||||
*/
|
||||
static int32_t spi_engine_transfer_message(struct spi_desc *desc,
|
||||
struct spi_engine_msg *msg)
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t data;
|
||||
uint32_t sync_id;
|
||||
bool offload_en;
|
||||
struct spi_engine_desc *desc_extra;
|
||||
|
||||
desc_extra = desc->extra;
|
||||
|
||||
spi_engine_compile_message(desc, msg);
|
||||
|
||||
offload_en = (desc_extra->offload_config & OFFLOAD_TX_EN) |
|
||||
(desc_extra->offload_config & OFFLOAD_RX_EN);
|
||||
|
||||
/* Write the command fifo buffer */
|
||||
while(msg->cmds != NULL) {
|
||||
spi_engine_queue_get_cmd(&msg->cmds, &data);
|
||||
spi_engine_write_cmd(desc, data);
|
||||
}
|
||||
|
||||
/* Write a number of tx_length WORDS on the SDO line */
|
||||
if(offload_en) {
|
||||
for(i = 0; i < desc_extra->offload_tx_len; i++)
|
||||
spi_engine_write(desc_extra,
|
||||
SPI_ENGINE_REG_OFFLOAD_SDO_MEM(0),
|
||||
msg->tx_buf[i]);
|
||||
|
||||
} else {
|
||||
if(msg->tx_buf != NULL){
|
||||
for(i = 0; i < msg->tx_length; i++)
|
||||
spi_engine_write(desc_extra,
|
||||
SPI_ENGINE_REG_SDO_DATA_FIFO,
|
||||
msg->tx_buf[i]);
|
||||
}
|
||||
do {
|
||||
spi_engine_read(desc_extra,
|
||||
SPI_ENGINE_REG_SYNC_ID,
|
||||
&sync_id);
|
||||
}
|
||||
/* Wait for the end sync signal */
|
||||
while(sync_id != _sync_id);
|
||||
_sync_id++;
|
||||
|
||||
/* Read a number of rx_length WORDS from the SDI line and store
|
||||
them */
|
||||
for(i = 0; i < msg->rx_length; i++) {
|
||||
spi_engine_read(desc_extra,
|
||||
SPI_ENGINE_REG_SDI_DATA_FIFO,
|
||||
&data);
|
||||
/* Store the rx data if rx buffer valid, flush sdi_fifo if
|
||||
rx buffer is invalid.*/
|
||||
if(msg->rx_buf != NULL){
|
||||
msg->rx_buf[i] = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the spi engine
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @param param Structure containing the spi init parameters
|
||||
* @return int32_t - SUCCESS if the transfer finished
|
||||
* - FAILURE if the memory allocation failed
|
||||
*/
|
||||
int32_t spi_engine_init(struct spi_desc **desc,
|
||||
const struct spi_init_param *param)
|
||||
{
|
||||
uint32_t data_width;
|
||||
uint32_t spi_engine_version;
|
||||
struct spi_engine_desc *eng_desc;
|
||||
struct spi_engine_init_param *spi_engine_init;
|
||||
|
||||
if (!param) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
*desc = malloc(sizeof(**desc));
|
||||
if(! *desc) {
|
||||
free(*desc);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
eng_desc = (struct spi_engine_desc*)malloc(sizeof(*eng_desc));
|
||||
|
||||
if (!eng_desc)
|
||||
return FAILURE;
|
||||
|
||||
spi_engine_init = param->extra;
|
||||
|
||||
(*desc)->max_speed_hz = param->max_speed_hz;
|
||||
(*desc)->chip_select = param->chip_select;
|
||||
(*desc)->mode = param->mode;
|
||||
(*desc)->extra = eng_desc;
|
||||
|
||||
eng_desc->offload_config = OFFLOAD_DISABLED;
|
||||
eng_desc->spi_engine_baseaddr = spi_engine_init->spi_engine_baseaddr;
|
||||
eng_desc->type = spi_engine_init->type;
|
||||
eng_desc->cs_delay = spi_engine_init->cs_delay;
|
||||
eng_desc->ref_clk_hz = spi_engine_init->ref_clk_hz;
|
||||
eng_desc->clk_div = eng_desc->ref_clk_hz /
|
||||
(2 * param->max_speed_hz) - 1;
|
||||
|
||||
/* Perform a reset */
|
||||
spi_engine_write(eng_desc, SPI_ENGINE_REG_RESET, 0x01);
|
||||
usleep(1000);
|
||||
spi_engine_write(eng_desc, SPI_ENGINE_REG_RESET, 0x00);
|
||||
|
||||
/* Get current data width */
|
||||
spi_engine_read(eng_desc, SPI_ENGINE_REG_DATA_WIDTH, &data_width);
|
||||
eng_desc->max_data_width = data_width;
|
||||
|
||||
spi_engine_set_transfer_width(*desc, spi_engine_init->data_width);
|
||||
|
||||
/* Get spi engine version */
|
||||
spi_engine_read(eng_desc, SPI_ENGINE_REG_VERSION, &spi_engine_version);
|
||||
|
||||
printf("Spi engine v%"PRIu32".%"PRIu32".%"PRIu32" successfully initialized.\n",
|
||||
(spi_engine_version >> 16),
|
||||
((spi_engine_version >> 8) & 0xFF),
|
||||
(spi_engine_version & 0xFF));
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write/read on the spi interface in 4-wire mode (full-duplex)
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @param data Pointer to data buffer
|
||||
* @param bytes_number Number of bytes to transfer
|
||||
* @return int32_t - SUCCESS if the transfer finished
|
||||
* - FAILURE if the memory allocation or transfer failed
|
||||
*/
|
||||
int32_t spi_engine_write_and_read(struct spi_desc *desc,
|
||||
uint8_t *data,
|
||||
uint16_t bytes_number)
|
||||
{
|
||||
uint8_t word_len;
|
||||
uint8_t words_number;
|
||||
int32_t ret;
|
||||
struct spi_engine_msg msg;
|
||||
struct spi_engine_desc *desc_extra;
|
||||
|
||||
desc_extra = desc->extra;
|
||||
|
||||
/* If we want to access SPI interface and SPI engine offload module was
|
||||
* activated, we need to disable it
|
||||
* This is set in spi_engine_offload_init() */
|
||||
desc_extra->offload_config = OFFLOAD_DISABLED;
|
||||
/* This is set in spi_engine_offload_transfer() */
|
||||
spi_engine_write(desc_extra, SPI_ENGINE_REG_OFFLOAD_CTRL(0), 0);
|
||||
|
||||
words_number = spi_get_words_number(desc_extra, bytes_number);
|
||||
|
||||
msg.cmds = (spi_engine_cmd_queue*)malloc(sizeof(*msg.cmds));
|
||||
if (!msg.cmds)
|
||||
return FAILURE;
|
||||
|
||||
msg.tx_buf =(uint32_t*)calloc(words_number, sizeof(msg.tx_buf[0]));
|
||||
msg.rx_buf =(uint32_t*)calloc(words_number, sizeof(msg.rx_buf[0]));
|
||||
msg.tx_length = words_number;
|
||||
msg.rx_length = words_number;
|
||||
|
||||
/* Get the length of transferred word */
|
||||
word_len = spi_get_word_length(desc_extra);
|
||||
|
||||
/* Make sure the CS is HIGH before starting a transaction */
|
||||
msg.cmds->next = NULL;
|
||||
msg.cmds->cmd = CS_HIGH;
|
||||
// Assert select.
|
||||
spi_engine_queue_add_cmd(&msg.cmds, CS_LOW);
|
||||
// add read/write command
|
||||
spi_engine_queue_add_cmd(&msg.cmds, WRITE_READ(bytes_number));
|
||||
// Disable select.
|
||||
spi_engine_queue_add_cmd(&msg.cmds, CS_HIGH);
|
||||
|
||||
/* Pack the bytes into engine WORDS */
|
||||
for (int i = 0; i < bytes_number; i++)
|
||||
msg.tx_buf[i / word_len] |= data[i] << (desc_extra->data_width-
|
||||
(i % word_len + 1) * 8);
|
||||
|
||||
ret = spi_engine_transfer_message(desc, &msg);
|
||||
|
||||
for (int i = 0; i < bytes_number; i++)
|
||||
data[i] = msg.rx_buf[(i) / word_len] >>
|
||||
(desc_extra->data_width -
|
||||
((i) % word_len + 1) * 8);
|
||||
|
||||
spi_engine_queue_free(&msg.cmds);
|
||||
free(msg.tx_buf);
|
||||
free(msg.rx_buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write and read on the spi interface in 3-wire mode (half-duplex)
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @param data Pointer to data buffer
|
||||
* @param bytes_number Number of bytes to transfer
|
||||
* @return int32_t - SUCCESS if the transfer finished
|
||||
* - FAILURE if the memory allocation or transfer failed
|
||||
*/
|
||||
int32_t spi_engine_write_and_read_3wire(struct spi_desc *desc,
|
||||
uint8_t *write_data,
|
||||
uint8_t *read_data,
|
||||
uint16_t write_bytes_number,
|
||||
uint16_t read_bytes_number)
|
||||
{
|
||||
uint8_t word_len;
|
||||
uint8_t wr_words_number;
|
||||
uint8_t rd_words_number;
|
||||
int32_t ret;
|
||||
struct spi_engine_msg msg;
|
||||
struct spi_engine_desc *desc_extra;
|
||||
|
||||
desc_extra = desc->extra;
|
||||
|
||||
/* If we want to access SPI interface and SPI engine offload module was
|
||||
* activated, we need to disable it
|
||||
* This is set in spi_engine_offload_init() */
|
||||
desc_extra->offload_config = OFFLOAD_DISABLED;
|
||||
/* This is set in spi_engine_offload_transfer() */
|
||||
spi_engine_write(desc_extra, SPI_ENGINE_REG_OFFLOAD_CTRL(0), 0);
|
||||
|
||||
wr_words_number = spi_get_words_number(desc_extra, write_bytes_number);
|
||||
rd_words_number = spi_get_words_number(desc_extra, read_bytes_number);
|
||||
|
||||
msg.cmds = (spi_engine_cmd_queue*)malloc(sizeof(*msg.cmds));
|
||||
if (!msg.cmds)
|
||||
return FAILURE;
|
||||
|
||||
msg.tx_buf =(wr_words_number>0)?(uint32_t*)calloc(wr_words_number, sizeof(msg.tx_buf[0])):NULL;
|
||||
msg.rx_buf =(rd_words_number>0)?(uint32_t*)calloc(rd_words_number, sizeof(msg.rx_buf[0])):NULL;
|
||||
msg.tx_length = wr_words_number;
|
||||
msg.rx_length = rd_words_number;
|
||||
|
||||
/* Get the length of transferred word */
|
||||
word_len = spi_get_word_length(desc_extra);
|
||||
|
||||
/* Make sure the CS is HIGH before starting a transaction */
|
||||
msg.cmds->next = NULL;
|
||||
msg.cmds->cmd = CS_HIGH;
|
||||
|
||||
// Assert select.
|
||||
spi_engine_queue_add_cmd(&msg.cmds, CS_LOW);
|
||||
|
||||
// add read/write command
|
||||
if(write_bytes_number > 0)
|
||||
spi_engine_queue_add_cmd(&msg.cmds, WRITE(write_bytes_number));
|
||||
if(read_bytes_number > 0)
|
||||
spi_engine_queue_add_cmd(&msg.cmds, READ(read_bytes_number));
|
||||
|
||||
// Disable select.
|
||||
spi_engine_queue_add_cmd(&msg.cmds, CS_HIGH);
|
||||
|
||||
/* Pack the bytes into engine WORDS */
|
||||
for (int i = 0; i < write_bytes_number; i++)
|
||||
msg.tx_buf[i / word_len] |= write_data[i] << (desc_extra->data_width-
|
||||
(i % word_len + 1) * 8);
|
||||
|
||||
ret = spi_engine_transfer_message(desc, &msg);
|
||||
|
||||
for (int i = 0; i < read_bytes_number; i++)
|
||||
read_data[i] = msg.rx_buf[(i) / word_len] >>
|
||||
(desc_extra->data_width -
|
||||
((i) % word_len + 1) * 8);
|
||||
|
||||
spi_engine_queue_free(&msg.cmds);
|
||||
free(msg.tx_buf);
|
||||
free(msg.rx_buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the SPI engine's offload module
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @param param Structure containing the offload init parameters
|
||||
* @return int32_t This function always returns SUCCESS
|
||||
*/
|
||||
int32_t spi_engine_offload_init(struct spi_desc *desc,
|
||||
const struct spi_engine_offload_init_param *param)
|
||||
{
|
||||
struct spi_engine_desc *eng_desc;
|
||||
struct axi_dmac_init dmac_init;
|
||||
|
||||
eng_desc = desc->extra;
|
||||
|
||||
eng_desc->offload_config = param->offload_config;
|
||||
|
||||
if(!(param->dma_flags)) {
|
||||
eng_desc->cyclic = CYCLIC;
|
||||
} else {
|
||||
if((*(param->dma_flags)) & DMA_CYCLIC)
|
||||
eng_desc->cyclic = CYCLIC;
|
||||
else
|
||||
eng_desc->cyclic = NO;
|
||||
}
|
||||
|
||||
|
||||
if(param->offload_config & OFFLOAD_TX_EN) {
|
||||
dmac_init.name = "DAC DMAC";
|
||||
dmac_init.base = param->tx_dma_baseaddr;
|
||||
axi_dmac_init(&eng_desc->offload_tx_dma, &dmac_init);
|
||||
if(!eng_desc->offload_tx_dma)
|
||||
return FAILURE;
|
||||
}
|
||||
if(param->offload_config & OFFLOAD_RX_EN) {
|
||||
dmac_init.name = "ADC DMAC";
|
||||
dmac_init.base = param->rx_dma_baseaddr;
|
||||
axi_dmac_init(&eng_desc->offload_rx_dma, &dmac_init);
|
||||
if(!eng_desc->offload_rx_dma)
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initiate a SPI transfer in offload mode
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @param msg Offload message that get's to be transferred
|
||||
* @param no_samples Number of time the messages will be transferred
|
||||
* @return int32_t This function always returns SUCCESS
|
||||
*/
|
||||
int32_t spi_engine_offload_transfer(struct spi_desc *desc,
|
||||
struct spi_engine_offload_message msg,
|
||||
uint32_t no_samples)
|
||||
{
|
||||
struct spi_engine_msg transfer;
|
||||
struct spi_engine_desc *eng_desc;
|
||||
uint32_t i;
|
||||
uint8_t word_length;
|
||||
|
||||
eng_desc = desc->extra;
|
||||
|
||||
/* Check if offload is disabled */
|
||||
if(!((eng_desc->offload_config & OFFLOAD_TX_EN) |
|
||||
(eng_desc->offload_config & OFFLOAD_RX_EN)))
|
||||
return FAILURE;
|
||||
|
||||
spi_engine_write(eng_desc, SPI_ENGINE_REG_OFFLOAD_RESET(0), 1);
|
||||
spi_engine_write(eng_desc, SPI_ENGINE_REG_OFFLOAD_RESET(0), 0);
|
||||
|
||||
eng_desc->offload_tx_len = 0;
|
||||
eng_desc->offload_rx_len = 0;
|
||||
|
||||
transfer.cmds = (spi_engine_cmd_queue*)malloc(sizeof(*transfer.cmds));
|
||||
|
||||
if (!transfer.cmds)
|
||||
return -1;
|
||||
|
||||
transfer.tx_buf = msg.commands_data;
|
||||
|
||||
/* Load the commands into the message */
|
||||
transfer.cmds->next = NULL;
|
||||
transfer.cmds->cmd = msg.commands[0];
|
||||
i = 1;
|
||||
while(i < msg.no_commands) {
|
||||
spi_engine_queue_add_cmd(&transfer.cmds, msg.commands[i++]);
|
||||
|
||||
}
|
||||
|
||||
spi_engine_transfer_message(desc, &transfer);
|
||||
|
||||
/* Start transfer */
|
||||
spi_engine_write(eng_desc, SPI_ENGINE_REG_OFFLOAD_CTRL(0), 0x0001);
|
||||
|
||||
word_length = spi_get_word_length(eng_desc);
|
||||
if(eng_desc->offload_config & OFFLOAD_TX_EN) {
|
||||
struct axi_dma_transfer tx_transfer = {
|
||||
// Number of bytes to write/read
|
||||
.size = word_length * eng_desc->offload_tx_len * no_samples,
|
||||
// Transfer done flag
|
||||
.transfer_done = 0,
|
||||
// Signal transfer mode
|
||||
.cyclic = eng_desc->cyclic,
|
||||
// Address of data source
|
||||
.src_addr = (uintptr_t)msg.tx_addr,
|
||||
// Address of data destination
|
||||
.dest_addr = 0
|
||||
};
|
||||
axi_dmac_transfer_start(eng_desc->offload_tx_dma, &tx_transfer);
|
||||
}
|
||||
|
||||
if(eng_desc->offload_config & OFFLOAD_RX_EN) {
|
||||
struct axi_dma_transfer rx_transfer = {
|
||||
// Number of bytes to write/read
|
||||
.size = word_length * eng_desc->offload_tx_len * no_samples,
|
||||
// Transfer done flag
|
||||
.transfer_done = 0,
|
||||
// Signal transfer mode
|
||||
.cyclic = NO,
|
||||
// Address of data source
|
||||
.src_addr = 0,
|
||||
// Address of data destination
|
||||
.dest_addr = (uintptr_t)msg.rx_addr
|
||||
};
|
||||
axi_dmac_transfer_start(eng_desc->offload_rx_dma, &rx_transfer);
|
||||
axi_dmac_transfer_wait_completion(eng_desc->offload_rx_dma, 500);
|
||||
}
|
||||
|
||||
usleep(1000);
|
||||
|
||||
spi_engine_queue_free(&transfer.cmds);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free the resources allocated by spi_init().
|
||||
*
|
||||
* @param desc Decriptor containing SPI interface parameters
|
||||
* @return int32_t This function allways returns SUCCESS
|
||||
*/
|
||||
int32_t spi_engine_remove(struct spi_desc *desc)
|
||||
{
|
||||
struct spi_engine_desc *eng_desc;
|
||||
|
||||
eng_desc = desc->extra;
|
||||
|
||||
if(eng_desc->offload_config & OFFLOAD_TX_EN)
|
||||
axi_dmac_remove(eng_desc->offload_tx_dma);
|
||||
if(eng_desc->offload_config & OFFLOAD_RX_EN)
|
||||
axi_dmac_remove(eng_desc->offload_rx_dma);
|
||||
free(desc->extra);
|
||||
free(desc);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
+229
@@ -0,0 +1,229 @@
|
||||
/*******************************************************************************
|
||||
* @file spi_engine.h
|
||||
* @brief Header file of SPI Engine core features.
|
||||
* @author Sergiu Cuciurean (sergiu.cuciurean@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 SPI_ENGINE_H
|
||||
#define SPI_ENGINE_H
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "spi_engine_private.h"
|
||||
#include "../axi_dmac/axi_dmac.h"
|
||||
#include "../../platform/xilinx_spi.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** Macros and Constants Definitions **********************/
|
||||
/******************************************************************************/
|
||||
|
||||
#define OFFLOAD_DISABLED 0x00
|
||||
#define OFFLOAD_TX_EN BIT(0)
|
||||
#define OFFLOAD_RX_EN BIT(1)
|
||||
#define OFFLOAD_TX_RX_EN OFFLOAD_TX_EN | OFFLOAD_RX_EN
|
||||
|
||||
#define SPI_ENGINE_MSG_QUEUE_END 0xFFFFFFFF
|
||||
|
||||
/* Spi engine commands */
|
||||
#define WRITE(no_bytes) ((SPI_ENGINE_INST_TRANSFER << 12) |\
|
||||
(SPI_ENGINE_INSTRUCTION_TRANSFER_W << 8) | no_bytes)
|
||||
|
||||
#define READ(no_bytes) ((SPI_ENGINE_INST_TRANSFER << 12) |\
|
||||
(SPI_ENGINE_INSTRUCTION_TRANSFER_R << 8) | no_bytes)
|
||||
|
||||
#define WRITE_READ(no_bytes) ((SPI_ENGINE_INST_TRANSFER << 12) |\
|
||||
(SPI_ENGINE_INSTRUCTION_TRANSFER_RW << 8) | no_bytes)
|
||||
|
||||
#define SLEEP(time) SPI_ENGINE_CMD_SLEEP(time & 0xF)
|
||||
|
||||
/* The delay and chip select parmeters are passed over the engine descriptor
|
||||
and will be used inside the function call */
|
||||
#define CS_HIGH SPI_ENGINE_CMD_ASSERT(0x01, 0xFF)
|
||||
#define CS_LOW SPI_ENGINE_CMD_ASSERT(0x01, 0x00)
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @struct spi_engine_init_param
|
||||
* @brief Structure containing the init parameters needed by the SPI engine
|
||||
*/
|
||||
struct spi_engine_init_param {
|
||||
/** SPI engine reference clock */
|
||||
uint32_t ref_clk_hz;
|
||||
/** Type of implementation */
|
||||
enum xil_spi_type type;
|
||||
/** Base address where the HDL core is situated */
|
||||
uint32_t spi_engine_baseaddr;
|
||||
/** Delay between the CS toggle and the start of SCLK */
|
||||
uint32_t cs_delay;
|
||||
/** Data with of one SPI transfer ( in bits ) */
|
||||
uint8_t data_width;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @struct spi_engine_desc
|
||||
* @brief Structure representing an SPI engine device
|
||||
*/
|
||||
struct spi_engine_desc {
|
||||
/** SPI engine reference clock */
|
||||
uint32_t ref_clk_hz;
|
||||
/** Type of implementation */
|
||||
enum xil_spi_type type;
|
||||
/** Pointer to a DMAC used in transmission */
|
||||
struct axi_dmac *offload_tx_dma;
|
||||
/** Pointer to a DMAC used in reception */
|
||||
struct axi_dmac *offload_rx_dma;
|
||||
/** Transfer mode for Tx DMAC */
|
||||
enum cyclic_transfer cyclic;
|
||||
/** Offload's module transfer direction : TX, RX or both */
|
||||
uint8_t offload_config;
|
||||
/** Number of words that the module has to send */
|
||||
uint8_t offload_tx_len;
|
||||
/** Number of words that the module has to receive */
|
||||
uint8_t offload_rx_len;
|
||||
/** Base address where the HDL core is situated */
|
||||
uint32_t spi_engine_baseaddr;
|
||||
/** Base address where the RX DMAC core is situated */
|
||||
uint32_t rx_dma_baseaddr;
|
||||
/** Base address where the TX DMAC core is situated */
|
||||
uint32_t tx_dma_baseaddr;
|
||||
/** Delay between the CS toggle and the start of SCLK */
|
||||
uint8_t cs_delay;
|
||||
/** Clock divider used in transmission delays */
|
||||
uint32_t clk_div;
|
||||
/** Data with of one SPI transfer ( in bits ) */
|
||||
uint8_t data_width;
|
||||
/** The maximum data width supported by the engine */
|
||||
uint8_t max_data_width;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @struct spi_engine_offload_init_param
|
||||
* @brief Structure containing the init parameters needed by the offload module
|
||||
*/
|
||||
struct spi_engine_offload_init_param {
|
||||
/** Base address where the RX DMAC core is situated */
|
||||
uint32_t rx_dma_baseaddr;
|
||||
/** Base address where the TX DMAC core is situated */
|
||||
uint32_t tx_dma_baseaddr;
|
||||
/** DMAC flags - if not initialized, the default value is DMA_CYCLIC */
|
||||
uint32_t *dma_flags;
|
||||
/** Offload's module transfer direction : TX, RX or both */
|
||||
uint8_t offload_config;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct spi_engine_offload_message
|
||||
* @brief Structure representing an offload message
|
||||
*/
|
||||
struct spi_engine_offload_message {
|
||||
/** Pointer to the SPI engine commands buffer that will be sent.
|
||||
* The available commands can be found at:
|
||||
* https://wiki.analog.com/resources/fpga/peripherals/spi_engine/
|
||||
*/
|
||||
uint32_t *commands;
|
||||
/** Length of the SPI engine commands buffer */
|
||||
uint32_t no_commands;
|
||||
/** Pointer of the data that will be sent over spi */
|
||||
uint32_t *commands_data;
|
||||
/** The address where the data that will be transmitted is situated */
|
||||
uint32_t tx_addr;
|
||||
/** The address where the data that will be received is situated */
|
||||
uint32_t rx_addr;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Declarations ******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Spi engine platform specific SPI platform ops structure
|
||||
*/
|
||||
extern const struct spi_platform_ops xil_spi_ops;
|
||||
|
||||
/* Write SPI Engine's axi registers */
|
||||
int32_t spi_engine_write(struct spi_engine_desc *desc,
|
||||
uint32_t reg_addr,
|
||||
uint32_t reg_data);
|
||||
|
||||
/* Read SPI Engine's axi registers */
|
||||
int32_t spi_engine_read(struct spi_engine_desc *desc,
|
||||
uint32_t reg_addr,
|
||||
uint32_t *reg_data);
|
||||
/* Initialize the SPI engine device */
|
||||
int32_t spi_engine_init(struct spi_desc **desc,
|
||||
const struct spi_init_param *param);
|
||||
|
||||
/* Write and read data over SPI using the SPI engine */
|
||||
int32_t spi_engine_write_and_read(struct spi_desc *desc,
|
||||
uint8_t *data,
|
||||
uint16_t bytes_number);
|
||||
|
||||
/* Write and read data over SPI using the SPI engine in 3-wire mode */
|
||||
int32_t spi_engine_write_and_read_3wire(struct spi_desc *desc,
|
||||
uint8_t *write_data,
|
||||
uint8_t *read_data,
|
||||
uint16_t write_bytes_number,
|
||||
uint16_t read_bytes_number);
|
||||
/* Free the resources used by the SPI engine device */
|
||||
int32_t spi_engine_remove(struct spi_desc *desc);
|
||||
|
||||
/* Initialize the SPI engine offload module */
|
||||
int32_t spi_engine_offload_init(struct spi_desc *desc,
|
||||
const struct spi_engine_offload_init_param *param);
|
||||
|
||||
/* Write and read data over SPI using the offload module */
|
||||
int32_t spi_engine_offload_transfer(struct spi_desc *desc,
|
||||
struct spi_engine_offload_message msg,
|
||||
uint32_t no_samples);
|
||||
|
||||
/* Set SPI transfer width */
|
||||
int32_t spi_engine_set_transfer_width(struct spi_desc *desc,
|
||||
uint8_t data_wdith);
|
||||
|
||||
/* Set SPI transfer speed */
|
||||
void spi_engine_set_speed(struct spi_desc *desc,
|
||||
uint32_t speed_hz);
|
||||
|
||||
#endif // SPI_ENGINE_H
|
||||
+154
@@ -0,0 +1,154 @@
|
||||
/*******************************************************************************
|
||||
* @file spi_engine_private.h
|
||||
* @brief Private definitions of the SPI Engine
|
||||
* @author Sergiu Cuciurean (sergiu.cuciurean@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 SPI_ENGINE_PRIVATE_H
|
||||
#define SPI_ENGINE_PRIVATE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "spi.h"
|
||||
#include "util.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Spi Engine registers *****************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#define SPI_ENGINE_REG_VERSION 0x00
|
||||
#define SPI_ENGINE_REG_DATA_WIDTH 0x0C
|
||||
#define SPI_ENGINE_REG_RESET 0x40
|
||||
#define SPI_ENGINE_REG_INT_ENABLE 0x80
|
||||
#define SPI_ENGINE_REG_INT_PENDING 0x84
|
||||
#define SPI_ENGINE_REG_INT_SOURCE 0x88
|
||||
#define SPI_ENGINE_REG_SYNC_ID 0xC0
|
||||
#define SPI_ENGINE_REG_CMD_FIFO_ROOM 0xD0
|
||||
#define SPI_ENGINE_REG_SDO_FIFO_ROOM 0xD4
|
||||
#define SPI_ENGINE_REG_SDI_FIFO_LEVEL 0xD8
|
||||
#define SPI_ENGINE_REG_CMD_FIFO 0xE0
|
||||
#define SPI_ENGINE_REG_SDO_DATA_FIFO 0xE4
|
||||
#define SPI_ENGINE_REG_SDI_DATA_FIFO 0xE8
|
||||
#define SPI_ENGINE_REG_SDI_DATA_FIFO_PEEK 0xEC
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Spi Engine register parameters **********************/
|
||||
/******************************************************************************/
|
||||
|
||||
#define SPI_ENGINE_INST_TRANSFER 0x00
|
||||
#define SPI_ENGINE_INST_ASSERT 0x01
|
||||
#define SPI_ENGINE_INST_CONFIG 0x02
|
||||
#define SPI_ENGINE_INST_SYNC_SLEEP 0x03
|
||||
#define SPI_ENGINE_INST_MISC 0x03
|
||||
#define SPI_ENGINE_CMD_REG_CLK_DIV 0x00
|
||||
#define SPI_ENGINE_CMD_REG_CONFIG 0x01
|
||||
#define SPI_ENGINE_CMD_DATA_TRANSFER_LEN 0x02
|
||||
#define SPI_ENGINE_MISC_SYNC 0x00
|
||||
#define SPI_ENGINE_MISC_SLEEP 0x01
|
||||
#define SPI_ENGINE_SYNC_TRANSFER_BEGIN BIT(1)
|
||||
#define SPI_ENGINE_SYNC_TRANSFER_END BIT(2)
|
||||
#define SPI_ENGINE_INT_CMD_ALMOST_EMPTY BIT(0)
|
||||
#define SPI_ENGINE_INT_SDO_ALMOST_EMPTY BIT(1)
|
||||
#define SPI_ENGINE_INT_SDI_ALMOST_FULL BIT(2)
|
||||
#define SPI_ENGINE_INT_SYNC BIT(3)
|
||||
#define SPI_ENGINE_OFFLOAD_CTRL_ENABLE BIT(0)
|
||||
#define SPI_ENGINE_OFFLOAD_STATUS_ENABLED BIT(0)
|
||||
#define SPI_ENGINE_CONFIG_CPHA BIT(0)
|
||||
#define SPI_ENGINE_CONFIG_CPOL BIT(1)
|
||||
#define SPI_ENGINE_CONFIG_3WIRE BIT(2)
|
||||
#define SPI_ENGINE_VERSION_MAJOR(x) ((x >> 16) & 0xff)
|
||||
#define SPI_ENGINE_VERSION_MINOR(x) ((x >> 8) & 0xff)
|
||||
#define SPI_ENGINE_VERSION_PATCH(x) (x & 0xff)
|
||||
|
||||
/******************************************************************************/
|
||||
/**************************** Spi Engine commands *****************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#define SPI_ENGINE_INSTRUCTION_TRANSFER_W 0x01
|
||||
#define SPI_ENGINE_INSTRUCTION_TRANSFER_R 0x02
|
||||
#define SPI_ENGINE_INSTRUCTION_TRANSFER_RW 0x03
|
||||
|
||||
#define SPI_ENGINE_REG_OFFLOAD_CTRL(x) (0x100 + (0x20 * x))
|
||||
#define SPI_ENGINE_REG_OFFLOAD_STATUS(x) (0x104 + (0x20 * x))
|
||||
#define SPI_ENGINE_REG_OFFLOAD_RESET(x) (0x108 + (0x20 * x))
|
||||
#define SPI_ENGINE_REG_OFFLOAD_CMD_MEM(x) (0x110 + (0x20 * x))
|
||||
#define SPI_ENGINE_REG_OFFLOAD_SDO_MEM(x) (0x114 + (0x20 * x))
|
||||
|
||||
#define SPI_ENGINE_CMD(inst, arg1, arg2) \
|
||||
(((inst & 0x03) << 12) | \
|
||||
((arg1 & 0x03) << 8) | arg2 )
|
||||
|
||||
#define SPI_ENGINE_CMD_TRANSFER(readwrite, n) \
|
||||
SPI_ENGINE_CMD(SPI_ENGINE_INST_TRANSFER, \
|
||||
(readwrite), (n))
|
||||
|
||||
#define SPI_ENGINE_CMD_ASSERT(delay, cs) \
|
||||
SPI_ENGINE_CMD(SPI_ENGINE_INST_ASSERT, \
|
||||
(delay), (cs))
|
||||
|
||||
#define SPI_ENGINE_CMD_CONFIG(reg, val) \
|
||||
SPI_ENGINE_CMD(SPI_ENGINE_INST_CONFIG, \
|
||||
(reg), (val))
|
||||
|
||||
#define SPI_ENGINE_CMD_SLEEP(delay) \
|
||||
SPI_ENGINE_CMD(SPI_ENGINE_INST_MISC, \
|
||||
SPI_ENGINE_MISC_SLEEP, \
|
||||
(delay))
|
||||
|
||||
#define SPI_ENGINE_CMD_SYNC(id) \
|
||||
SPI_ENGINE_CMD(SPI_ENGINE_INST_MISC, \
|
||||
SPI_ENGINE_MISC_SYNC, \
|
||||
(id))
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
typedef struct spi_engine_cmd_queue {
|
||||
uint32_t cmd;
|
||||
struct spi_engine_cmd_queue *next;
|
||||
} spi_engine_cmd_queue;
|
||||
|
||||
typedef struct spi_engine_msg {
|
||||
uint32_t *tx_buf;
|
||||
uint32_t *rx_buf;
|
||||
uint32_t tx_length;
|
||||
uint32_t rx_length;
|
||||
struct spi_engine_cmd_queue *cmds;
|
||||
} spi_engine_msg;
|
||||
|
||||
#endif // SPI_ENGINE_PRIVATE_H
|
||||
+783
@@ -0,0 +1,783 @@
|
||||
/**
|
||||
* \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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "ad9528.h"
|
||||
#include "../../../include/error.h"
|
||||
|
||||
static uint32_t _desired_time_to_elapse_ms = 0;
|
||||
|
||||
/**
|
||||
* \brief Write data to a register
|
||||
*/
|
||||
int32_t AD9528_spiWriteByte(ad9528Device_t *device, uint16_t addr,
|
||||
uint8_t data)
|
||||
{
|
||||
uint8_t buf[3];
|
||||
int32_t status;
|
||||
|
||||
buf[0] = (addr >> 8) & 0x7F;
|
||||
buf[1] = addr & 0xFF;
|
||||
buf[2] = data;
|
||||
status = spi_write_and_read_3wire(device->spi_desc,
|
||||
buf, NULL, 3, 0);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Read data from a register
|
||||
*/
|
||||
int32_t AD9528_spiReadByte(ad9528Device_t *device, uint16_t addr,
|
||||
uint8_t *readdata)
|
||||
{
|
||||
uint8_t tx_buf[2];
|
||||
uint8_t rx_buf[1];
|
||||
int32_t status;
|
||||
|
||||
tx_buf[0] = 0x80 | addr >> 8;
|
||||
tx_buf[1] = addr & 0xFF;
|
||||
|
||||
status = spi_write_and_read_3wire(device->spi_desc,
|
||||
tx_buf, rx_buf, 2, 1);
|
||||
|
||||
*readdata = rx_buf[0];
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Modify a field of bits from a register
|
||||
*/
|
||||
int32_t AD9528_spiWriteField(ad9528Device_t *device,
|
||||
uint16_t addr, uint8_t fieldVal, uint8_t mask, uint8_t startBit)
|
||||
{
|
||||
int32_t errVal;
|
||||
uint8_t readVal;
|
||||
|
||||
errVal = AD9528_spiReadByte(device, addr, &readVal);
|
||||
if (errVal < 0)
|
||||
return errVal;
|
||||
|
||||
readVal = (readVal & ~mask) | ((fieldVal << startBit) & mask);
|
||||
|
||||
return AD9528_spiWriteByte(device, addr, readVal);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the desired timeout value
|
||||
*/
|
||||
int32_t AD9528_setTimeout_ms(uint32_t timeOut_ms)
|
||||
{
|
||||
_desired_time_to_elapse_ms = timeOut_ms;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Verify if the desired time has elapsed
|
||||
*/
|
||||
int32_t AD9528_hasTimeoutExpired()
|
||||
{
|
||||
udelay(1000);
|
||||
|
||||
_desired_time_to_elapse_ms--;
|
||||
if (_desired_time_to_elapse_ms > 0)
|
||||
return SUCCESS;
|
||||
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
/**
|
||||
* \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
|
||||
*/
|
||||
int32_t AD9528_resetDevice(ad9528Device_t *device)
|
||||
{
|
||||
gpio_direction_output(device->gpio_resetb, 0);
|
||||
mdelay(100);
|
||||
gpio_direction_output(device->gpio_resetb, 1);
|
||||
mdelay(100);
|
||||
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_ADI_SPI_CONFIG_A, 0x81);
|
||||
mdelay(100);
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_ADI_SPI_CONFIG_A, 0x00);
|
||||
mdelay(100);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* \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
|
||||
*/
|
||||
int32_t AD9528_setSpiSettings(ad9528Device_t *device)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_ADI_SPI_CONFIG_A, spiReg);
|
||||
|
||||
if (device->spiSettings->enSpiStreaming > 0) {
|
||||
/* Allow SPI streaming mode: SPI message ends when chip select deasserts */
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_ADI_SPI_CONFIG_B, 0x00);
|
||||
} else {
|
||||
/* Force single instruction mode */
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_ADI_SPI_CONFIG_B, 0x80);
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* \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
|
||||
*/
|
||||
int32_t 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;
|
||||
|
||||
// struct spi_init_param spi_param;
|
||||
// int32_t status;
|
||||
//
|
||||
// status = gpio_get(&device->gpio_resetb, CLK_RESETB);
|
||||
// status |= gpio_get(&device->gpio_sysref_req, ADRV_SYSREF_REQ);
|
||||
//
|
||||
// spi_param.id = 0;
|
||||
// spi_param.mode = SPI_MODE_0;
|
||||
// spi_param.chip_select = CLK_CS;
|
||||
// status |= spi_init(&device->spi_desc, &spi_param);
|
||||
//
|
||||
// if (status != SUCCESS)
|
||||
// return FAILURE;
|
||||
|
||||
/*******************************************************************
|
||||
* 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 FAILURE;
|
||||
// }
|
||||
|
||||
// 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 FAILURE;
|
||||
// } else {
|
||||
// chDiv = (uint16_t)(chDivU64);
|
||||
// }
|
||||
//
|
||||
// validPll2DivSetting = 1;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (validPll2DivSetting == 1) {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (validPll2DivSetting == 0) {
|
||||
// return FAILURE;
|
||||
// }
|
||||
//
|
||||
// device->outputSettings->outPowerDown = (uint16_t)(
|
||||
// ~0x318A); //enable outputs 13,12,8,7,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[7] = 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 =
|
||||
// CONTINUOUS; //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 = PIN; //SPI=0,PIN=1
|
||||
// device->sysrefSettings->sysrefSource =
|
||||
// INTERNAL; //EXTERNAL=0, EXT_RESAMPLED=1, INTERNAL=2
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int32_t AD9528_init(ad9528Device_t **device, const ad9528Init_t *init_device)
|
||||
{
|
||||
int ret = SUCCESS;
|
||||
ad9528Device_t *dev;
|
||||
|
||||
dev = (ad9528Device_t *)malloc(sizeof(*dev));
|
||||
if (!dev)
|
||||
return FAILURE;
|
||||
|
||||
/* SPI */
|
||||
ret = spi_init(&dev->spi_desc, init_device->spi_init);
|
||||
ret |= gpio_get(&dev->gpio_resetb, init_device->gpio_init_resetb);
|
||||
ret |= gpio_get(&dev->gpio_sysref_req, init_device->gpio_init_sysref_req);
|
||||
|
||||
gpio_direction_output(dev->gpio_resetb, 0);
|
||||
gpio_direction_output(dev->gpio_sysref_req, 0);
|
||||
|
||||
AD9528_resetDevice(dev);
|
||||
|
||||
dev->spiSettings = init_device->spiSettings;
|
||||
dev->pll1Settings = init_device->pll1Settings;
|
||||
dev->pll2Settings = init_device->pll2Settings;
|
||||
dev->outputSettings = init_device->outputSettings;
|
||||
dev->sysrefSettings = init_device->sysrefSettings;
|
||||
|
||||
*device = dev;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* \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
|
||||
*/
|
||||
int32_t AD9528_config(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=0x4;
|
||||
uint8_t i = 0;
|
||||
uint8_t j = 0;
|
||||
uint8_t reg508;
|
||||
int32_t retval = SUCCESS;
|
||||
|
||||
retval = AD9528_setSpiSettings(device);
|
||||
if (retval != SUCCESS) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* Configure PLL1
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_REF_A_DIVIDER_LSB,
|
||||
device->pll1Settings->refA_Divider & 0xFF); //REF A div[7:0]
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_REF_A_DIVIDER_MSB,
|
||||
(device->pll1Settings->refA_Divider >> 8) & 0x03); //REF A div[9:8]
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_REF_B_DIVIDER_LSB,
|
||||
device->pll1Settings->refB_Divider & 0xFF); //REF B div[7:0]
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_REF_B_DIVIDER_MSB,
|
||||
(device->pll1Settings->refB_Divider >> 8) & 0x03); //REF B div[9:8]
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_PLL1_N_DIV_LSB,
|
||||
device->pll1Settings->nDivider & 0xFF); //PLL1 N div[7:0]
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_PLL1_N_DIV_MSB,
|
||||
(device->pll1Settings->nDivider >> 8) & 0x03); //PLL1 N div[9:8]
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_PLL1_CHARGEPUMP,
|
||||
0x0A); //PLL1 Charge Pump control 1
|
||||
AD9528_spiWriteByte(device, 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
|
||||
}
|
||||
|
||||
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_INPUT_RECEIVERS1,
|
||||
reg108); //Input receiver settings (single ended or differential clock inputs)
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_INPUT_RECEIVERS2,
|
||||
reg109); //Input receiver settings
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_INPUT_RECEIVERS3,
|
||||
0x0A); //Reference selection mode
|
||||
AD9528_spiWriteByte(device, 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)
|
||||
return FAILURE;
|
||||
}
|
||||
if (pll2_Bdiv < 3 || pll2_Bdiv > 63) {
|
||||
return FAILURE;
|
||||
}
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_PLL2_CHARGEPUMP,
|
||||
0xE6); //PLL2 Charge Pump[7:0]
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_PLL2_N_DIV,
|
||||
((pll2_Adiv & 0x3) << 6) | (pll2_Bdiv & 0x3F)); //PLL2 A and B divider
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_PLL2_CTRL, 0x03); //PLL2 control
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_PLL2_VCO_CTRL, 0x01); //Manual VCO CAL
|
||||
|
||||
if (device->pll2Settings->rfDivider < 3
|
||||
|| device->pll2Settings->rfDivider > 5) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_PLL2_VCO_DIV,
|
||||
device->pll2Settings->rfDivider); //VCO divider
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_PLL2_LF_CTRL1,
|
||||
0x3A); //PLL2 Loop filter [7:0]
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_PLL2_LF_CTRL2,
|
||||
0x00); //PLL2 Loop filter [8]
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_PLL2_RDIV, 0x01); //R divider
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_PLL2_REPLICA_CHDIV,
|
||||
(device->pll2Settings->totalNdiv / device->pll2Settings->rfDivider)
|
||||
-1 ); //Replica channel divider: Ndivider = rfDivider * R divider
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_PLL2_REPLICA_DIV_PHASE,
|
||||
0x00); //Replica Channel Divider phase
|
||||
|
||||
/**********************************************************************
|
||||
* Configure Output Distribution
|
||||
**********************************************************************
|
||||
*/
|
||||
for (i=0; i<14; i=i+1) {
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_CH_OUT0_CTRL1 + j,
|
||||
((device->outputSettings->outSource[i] & 0x7) << 5) |
|
||||
(device->outputSettings->outAnalogDelay[i] & 0x1F));
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_CH_OUT0_CTRL2 + j,
|
||||
((device->outputSettings->outBufferCtrl[i] & 0x3) << 6) |
|
||||
(device->outputSettings->outDigitalDelay[i] & 0x3F));
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_CH_OUT0_CHDIV + j,
|
||||
device->outputSettings->outChannelDiv[i]-1);
|
||||
j = j+3;
|
||||
}
|
||||
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_OUTPUT_SYNC, 0x00); //Sync outputs
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_MASK_SYNC1, 0x00); //Mask SYNC[7:0]
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_MASK_SYNC2, 0x00); //Mask SYNC[13:8]
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_EN_OUTPUT_PATH_SEL1,
|
||||
0x00); //Bypass SYSREF resample [6:0], bit0:Enable VCXO to feed output distrubution
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_EN_OUTPUT_PATH_SEL2,
|
||||
0x00); //Bypass SYSREF resample [13:7]
|
||||
|
||||
/**********************************************************************
|
||||
* Configure SYSREF operation
|
||||
**********************************************************************
|
||||
*/
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_SYSERF_DIV_LSB,
|
||||
device->sysrefSettings->sysrefDivide & 0xFF); //SYSREF divider [7:0]
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_SYSERF_DIV_MSB,
|
||||
(device->sysrefSettings->sysrefDivide >> 8) & 0xFF); //SYSREF divider [7:0]
|
||||
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_SYSREF_CTRL3,
|
||||
((device->sysrefSettings->sysrefRequestMethod & 0x1) << 7) |
|
||||
((device->sysrefSettings->sysrefPinEdgeMode & 0x3) << 5) );
|
||||
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_SYSREF_CTRL4,
|
||||
((device->sysrefSettings->sysrefSource & 0x03) << 6) |
|
||||
((device->sysrefSettings->sysrefPatternMode & 0x3) << 4 ) |
|
||||
((device->sysrefSettings->sysrefNshotMode & 0x7) << 1) );
|
||||
|
||||
if(device->sysrefSettings->sysrefPinBufferMode == DISABLED) {
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_SYSREF_CTRL5,
|
||||
0x04); //power down input buffer for external SYSREF
|
||||
} else if(device->sysrefSettings->sysrefPinBufferMode == SINGLE_ENDED) {
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_SYSREF_CTRL5,
|
||||
0x00); //enable positive singled ended input
|
||||
} else if(device->sysrefSettings->sysrefPinBufferMode == NEG_SINGLE_ENDED) {
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_SYSREF_CTRL5,
|
||||
0x02); //enable negative singled ended input
|
||||
} else if(device->sysrefSettings->sysrefPinBufferMode == DIFFERENTIAL) {
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_SYSREF_CTRL5,
|
||||
0x01); //enable differential input buffer
|
||||
} else {
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_SYSREF_CTRL5,
|
||||
0x04); //power down input buffer for external SYSREF
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* Power down control
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
if (device->pll1Settings->bypassPll1 > 0) {
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_POWERDOWN_CTRL,
|
||||
0x14);// power up PLL2 and output distribution, power down PLL1
|
||||
} else {
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_POWERDOWN_CTRL,
|
||||
0x10);// power up PLL1, PLL2 and output distribution
|
||||
}
|
||||
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_CH_POWERDOWN1,
|
||||
device->outputSettings->outPowerDown & 0xFF); //power down out[7:0]
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_CH_POWERDOWN2,
|
||||
((device->outputSettings->outPowerDown >> 8) & 0x3F)); //power down out[13:8]
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_LDO_ENABLES1,
|
||||
0xFF); //LDO enable per output channel [7:0]
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_LDO_ENABLES2,
|
||||
0xFF); //LDO enable per output channel [15:8]
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_STATUS0_CTRL,
|
||||
0x07); //STATUS 0 outputs REFA present
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_STATUS1_CTRL,
|
||||
0x01); //STATUS 1 outputs PLL1 and PLL2 locked
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_STATUS_OE,
|
||||
0x0C);// Make Status0 and Status1 outputs after reset.
|
||||
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_IO_UPDATE,
|
||||
0x01); //IO update to make all these settings valid in the 9528
|
||||
|
||||
AD9528_setTimeout_ms(1000);
|
||||
|
||||
do {
|
||||
AD9528_spiReadByte(device, AD9528_ADDR_STATUS_READBACK0, ®508);
|
||||
if(AD9528_hasTimeoutExpired() > 0) {
|
||||
return FAILURE;
|
||||
}
|
||||
} while((reg508 & 0x26) != 0x26);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/// 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
|
||||
***********************************************************************************/
|
||||
int32_t AD9528_requestSysref(ad9528Device_t *device, uint8_t enableSYSREF)
|
||||
{
|
||||
uint8_t _enableSYSREF=0;
|
||||
|
||||
if (device->sysrefSettings->sysrefPatternMode == NSHOT || enableSYSREF > 0) {
|
||||
_enableSYSREF = 1;
|
||||
} else {
|
||||
_enableSYSREF = 0;
|
||||
}
|
||||
|
||||
AD9528_spiWriteField(device, AD9528_ADDR_SYSREF_CTRL4, _enableSYSREF, 0x01,
|
||||
0x00); //Set SPI SYSREF request bit
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_IO_UPDATE,
|
||||
0x01); //IO update to make all these settings valid in the 9528
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/// 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
|
||||
***********************************************************************************/
|
||||
int32_t 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
|
||||
|
||||
AD9528_spiReadByte(device, AD9528_ADDR_SYSREF_CTRL4, ®403);
|
||||
|
||||
reg403 = reg403 & ~0x01; //clear bit 0 to stop a continuous sysref if it is on.
|
||||
AD9528_spiWriteByte(device, 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);
|
||||
AD9528_spiWriteByte(device, 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
|
||||
AD9528_spiWriteByte(device, AD9528_ADDR_IO_UPDATE,
|
||||
0x01); //IO update to make all these settings valid in the 9528
|
||||
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int32_t AD9528_sysrefReq(ad9528Device_t *device,
|
||||
ad9528SysrefReqMode_t mode)
|
||||
{
|
||||
if (mode == SYSREF_CONT_ON)
|
||||
gpio_direction_output(device->gpio_sysref_req, 1);
|
||||
else if (mode == SYSREF_CONT_OFF)
|
||||
gpio_direction_output(device->gpio_sysref_req, 0);
|
||||
else if (mode == SYSREF_PULSE) {
|
||||
gpio_direction_output(device->gpio_sysref_req, 1);
|
||||
mdelay(1);
|
||||
gpio_direction_output(device->gpio_sysref_req, 0);
|
||||
} else
|
||||
return FAILURE;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Free the allocated resources
|
||||
*/
|
||||
int32_t AD9528_remove(ad9528Device_t *device)
|
||||
{
|
||||
int32_t status;
|
||||
|
||||
status = gpio_remove(device->gpio_resetb);
|
||||
status |= gpio_remove(device->gpio_sysref_req);
|
||||
status |= spi_remove(device->spi_desc);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
+245
@@ -0,0 +1,245 @@
|
||||
/**
|
||||
* \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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _AD9528_H_
|
||||
#define _AD9528_H_
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
#include <stdint.h>
|
||||
#include "delay.h"
|
||||
#include "spi.h"
|
||||
#include "gpio.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** Macros and Constants Definitions **********************/
|
||||
/******************************************************************************/
|
||||
|
||||
/* 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
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
///Enum to select what source outputs from each AD9528 output channel
|
||||
typedef enum {
|
||||
AD9528_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 {
|
||||
AD9528_LVDS = 0, AD9528_LVDS_BOOST = 1, AD9528_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 SPI settings
|
||||
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 */
|
||||
} ad9528spiSettings_t;
|
||||
|
||||
/// Structure to hold AD9528 settings
|
||||
typedef struct {
|
||||
struct gpio_desc *gpio_resetb;
|
||||
struct gpio_desc *gpio_sysref_req;
|
||||
struct spi_desc *spi_desc;
|
||||
ad9528spiSettings_t *spiSettings;
|
||||
ad9528pll1Settings_t *pll1Settings;
|
||||
ad9528pll2Settings_t *pll2Settings;
|
||||
ad9528outputSettings_t *outputSettings;
|
||||
ad9528sysrefSettings_t *sysrefSettings;
|
||||
} ad9528Device_t;
|
||||
|
||||
typedef struct {
|
||||
struct gpio_init_param *gpio_init_resetb;
|
||||
struct gpio_init_param *gpio_init_sysref_req;
|
||||
struct spi_init_param *spi_init;
|
||||
ad9528spiSettings_t *spiSettings;
|
||||
ad9528pll1Settings_t *pll1Settings;
|
||||
ad9528pll2Settings_t *pll2Settings;
|
||||
ad9528outputSettings_t *outputSettings;
|
||||
ad9528sysrefSettings_t *sysrefSettings;
|
||||
} ad9528Init_t;
|
||||
|
||||
typedef enum {
|
||||
SYSREF_CONT_ON,
|
||||
SYSREF_CONT_OFF,
|
||||
SYSREF_PULSE,
|
||||
} ad9528SysrefReqMode_t;
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Declarations ******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
//Helper function to setup the 9528 device data structure specifically for the ADI transceiver evaluation cards
|
||||
int32_t AD9528_initDeviceDataStruct(ad9528Device_t *device,
|
||||
uint32_t vcxoFrequency_Hz, uint32_t refAFrequency_Hz,
|
||||
uint32_t outputDeviceClock_Hz);
|
||||
int32_t AD9528_spiReadByte(ad9528Device_t *device, uint16_t addr,
|
||||
uint8_t *readdata);
|
||||
|
||||
//AD9528 API functions
|
||||
int32_t AD9528_hasTimeoutExpired();
|
||||
int32_t AD9528_resetDevice(ad9528Device_t *device);
|
||||
int32_t AD9528_init(ad9528Device_t **device, const ad9528Init_t *init_device);
|
||||
int32_t AD9528_config(ad9528Device_t
|
||||
*device); //writes all registers to desired values, leaves clock outputs off.
|
||||
int32_t AD9528_setupSYSREF(ad9528Device_t *device,
|
||||
uint16_t divideFromPll1Out, sysrefPatternMode_t sysrefPatternMode,
|
||||
sysrefNshotMode_t nShotPulses);
|
||||
int32_t AD9528_requestSysref(ad9528Device_t *device, uint8_t enableSYSREF);
|
||||
int32_t AD9528_sysrefReq(ad9528Device_t *device,
|
||||
ad9528SysrefReqMode_t mode);
|
||||
int32_t AD9528_remove(ad9528Device_t *device);
|
||||
|
||||
#endif
|
||||
+927
@@ -0,0 +1,927 @@
|
||||
/***************************************************************************//**
|
||||
* @file hmc7044.c
|
||||
* @brief Implementation of HMC7044, HMC7043 Driver.
|
||||
* @author DBogdan (dragos.bogdan@analog.com)
|
||||
********************************************************************************
|
||||
* 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
@@ -0,0 +1,276 @@
|
||||
/***************************************************************************//**
|
||||
* @file hmc7044.h
|
||||
* @brief Header file of HMC7044, HMC7043 Driver.
|
||||
* @author DBogdan (dragos.bogdan@analog.com)
|
||||
********************************************************************************
|
||||
* 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_
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
/***************************************************************************//**
|
||||
* @file lmk04828.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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "lmk04828.h"
|
||||
#include "../../../include/error.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief lmk04828_read
|
||||
*******************************************************************************/
|
||||
int32_t lmk04828_read(struct lmk04828_dev *dev,
|
||||
uint16_t reg_addr,
|
||||
uint8_t *reg_data)
|
||||
{
|
||||
uint8_t tx_buf[2];
|
||||
uint8_t rx_buf[1];
|
||||
int32_t ret;
|
||||
|
||||
tx_buf[0] = 0x80 | (reg_addr >> 8);
|
||||
tx_buf[1] = reg_addr & 0xFF;
|
||||
|
||||
|
||||
ret = spi_write_and_read_3wire(dev->spi_desc,
|
||||
tx_buf, rx_buf, 2, 1);
|
||||
|
||||
*reg_data = rx_buf[0];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief lmk04828_write
|
||||
*******************************************************************************/
|
||||
int32_t lmk04828_write(struct lmk04828_dev *dev,
|
||||
uint16_t reg_addr,
|
||||
uint8_t reg_data)
|
||||
{
|
||||
uint8_t buf[3];
|
||||
|
||||
int32_t ret;
|
||||
|
||||
buf[0] = reg_addr >> 8;
|
||||
buf[1] = reg_addr & 0xFF;
|
||||
buf[2] = reg_data;
|
||||
|
||||
ret = spi_write_and_read_3wire(dev->spi_desc,
|
||||
buf, NULL, 3, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief lmk04828_init
|
||||
*******************************************************************************/
|
||||
int32_t lmk04828_init(struct lmk04828_dev **device,
|
||||
const struct lmk04828_init_param *init_param)
|
||||
{
|
||||
int ret = SUCCESS;
|
||||
struct lmk04828_dev *dev;
|
||||
|
||||
dev = (struct lmk04828_dev *)malloc(sizeof(*dev));
|
||||
if (!dev)
|
||||
return FAILURE;
|
||||
|
||||
/* SPI */
|
||||
ret = spi_init(&dev->spi_desc, init_param->spi_init);
|
||||
|
||||
*device = dev;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Free the resources allocated by lmk04828_setup().
|
||||
*
|
||||
* @param dev - The device structure.
|
||||
*
|
||||
* @return SUCCESS in case of success, negative error code otherwise.
|
||||
*******************************************************************************/
|
||||
int32_t lmk04828_remove(struct lmk04828_dev *dev)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
ret = spi_remove(dev->spi_desc);
|
||||
|
||||
free(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
/***************************************************************************//**
|
||||
* @file lmk04828.h
|
||||
* @brief Header file of lmk04828 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 LMK04828_H_
|
||||
#define LMK04828_H_
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
#include <stdint.h>
|
||||
#include "delay.h"
|
||||
#include "spi.h"
|
||||
#include "gpio.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** Macros and Constants Definitions **********************/
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
struct lmk04828_dev {
|
||||
/* SPI */
|
||||
struct spi_desc *spi_desc;
|
||||
};
|
||||
|
||||
struct lmk04828_init_param {
|
||||
/* SPI */
|
||||
struct spi_init_param *spi_init;
|
||||
};
|
||||
|
||||
struct lmk04828_config {
|
||||
uint16_t addr;
|
||||
uint8_t value;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Declarations ******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
int32_t lmk04828_read(struct lmk04828_dev *dev,
|
||||
uint16_t reg_addr,
|
||||
uint8_t *reg_data);
|
||||
|
||||
int32_t lmk04828_write(struct lmk04828_dev *dev,
|
||||
uint16_t reg_addr,
|
||||
uint8_t reg_data);
|
||||
|
||||
int32_t lmk04828_init(struct lmk04828_dev **device,
|
||||
const struct lmk04828_init_param *init_param);
|
||||
|
||||
int32_t lmk04828_remove(struct lmk04828_dev *dev);
|
||||
|
||||
#endif
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
/***************************************************************************//**
|
||||
* @file lmx2594.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 "../lmx2594/lmx2594.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "../../../include/error.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief lmx2594_read
|
||||
*******************************************************************************/
|
||||
int32_t lmx2594_read(struct lmx2594_dev *dev,
|
||||
uint8_t reg_addr,
|
||||
uint16_t *reg_data)
|
||||
{
|
||||
uint8_t tx_buf[1];
|
||||
uint8_t rx_buf[2];
|
||||
int32_t ret;
|
||||
|
||||
tx_buf[0] = 0x80 | reg_addr;
|
||||
|
||||
|
||||
ret = spi_write_and_read_3wire(dev->spi_desc,
|
||||
tx_buf, rx_buf, 1, 2);
|
||||
|
||||
*reg_data = rx_buf[1];
|
||||
*reg_data |= ((uint16_t)rx_buf[0]) << 8;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief lmx2594_write
|
||||
*******************************************************************************/
|
||||
int32_t lmx2594_write(struct lmx2594_dev *dev,
|
||||
uint8_t reg_addr,
|
||||
uint16_t reg_data)
|
||||
{
|
||||
uint8_t buf[3];
|
||||
|
||||
int32_t ret;
|
||||
|
||||
buf[0] = reg_addr;
|
||||
buf[1] = reg_data >> 8;
|
||||
buf[2] = reg_data & 0xFF;
|
||||
|
||||
ret = spi_write_and_read_3wire(dev->spi_desc,
|
||||
buf, NULL, 3, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief lmx2594_init
|
||||
*******************************************************************************/
|
||||
int32_t lmx2594_init(struct lmx2594_dev **device,
|
||||
const struct lmx2594_init_param *init_param)
|
||||
{
|
||||
int ret = SUCCESS;
|
||||
struct lmx2594_dev *dev;
|
||||
|
||||
dev = (struct lmx2594_dev *)malloc(sizeof(*dev));
|
||||
if (!dev)
|
||||
return FAILURE;
|
||||
|
||||
/* SPI */
|
||||
ret = spi_init(&dev->spi_desc, init_param->spi_init);
|
||||
|
||||
*device = dev;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Free the resources allocated by lmx2594_setup().
|
||||
*
|
||||
* @param dev - The device structure.
|
||||
*
|
||||
* @return SUCCESS in case of success, negative error code otherwise.
|
||||
*******************************************************************************/
|
||||
int32_t lmx2594_remove(struct lmx2594_dev *dev)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
ret = spi_remove(dev->spi_desc);
|
||||
|
||||
free(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
/***************************************************************************//**
|
||||
* @file lmx2594.h
|
||||
* @brief Header file of lmx2594 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 LMX2594_H_
|
||||
#define LMX2594_H_
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
#include <stdint.h>
|
||||
#include "delay.h"
|
||||
#include "spi.h"
|
||||
#include "gpio.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** Macros and Constants Definitions **********************/
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
struct lmx2594_dev {
|
||||
/* SPI */
|
||||
struct spi_desc *spi_desc;
|
||||
};
|
||||
|
||||
struct lmx2594_init_param {
|
||||
/* SPI */
|
||||
struct spi_init_param *spi_init;
|
||||
};
|
||||
|
||||
struct lmx2594_config {
|
||||
uint8_t addr;
|
||||
uint16_t value;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Declarations ******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
int32_t lmx2594_read(struct lmx2594_dev *dev,
|
||||
uint8_t reg_addr,
|
||||
uint16_t *reg_data);
|
||||
|
||||
int32_t lmx2594_write(struct lmx2594_dev *dev,
|
||||
uint8_t reg_addr,
|
||||
uint16_t reg_data);
|
||||
|
||||
int32_t lmx2594_init(struct lmx2594_dev **device,
|
||||
const struct lmx2594_init_param *init_param);
|
||||
|
||||
int32_t lmx2594_remove(struct lmx2594_dev *dev);
|
||||
|
||||
#endif
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
/***************************************************************************//**
|
||||
* @file xilinx/xilinx_axi_io.c
|
||||
* @brief Implementation of Xilinx AXI IO.
|
||||
* @author Antoniu Miclaus (antoniu.miclaus@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.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#include <xil_io.h>
|
||||
#include "error.h"
|
||||
#include "axi_io.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Definitions *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief AXI IO Xilinx specific read function.
|
||||
* @param base - Base address
|
||||
* @param offset - Address offset
|
||||
* @param data - variable where returned data is stored
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t axi_io_read(uint32_t base, uint32_t offset, uint32_t *data)
|
||||
{
|
||||
*data = Xil_In32(base + offset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief AXI IO Xilinx specific write function.
|
||||
* @param base - Base address
|
||||
* @param offset - Address offset
|
||||
* @param data - data to be written.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t axi_io_write(uint32_t base, uint32_t offset, uint32_t data)
|
||||
{
|
||||
Xil_Out32(base + offset, data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
/***************************************************************************//**
|
||||
* @file xilinx/xilinx_delay.c
|
||||
* @brief Implementation of Xilinx Delay Functions.
|
||||
* @author Antoniu Miclaus (antoniu.miclaus@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.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "delay.h"
|
||||
#include <sleep.h>
|
||||
#ifdef _XPARAMETERS_PS_H_
|
||||
#include "util.h"
|
||||
#include "xtime_l.h"
|
||||
#endif
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Definitions *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Generate microseconds delay.
|
||||
* @param usecs - Delay in microseconds.
|
||||
* @return None.
|
||||
*/
|
||||
void udelay(uint32_t usecs)
|
||||
{
|
||||
#ifdef _XPARAMETERS_PS_H_
|
||||
usleep(usecs);
|
||||
#else
|
||||
usleep_MB(usecs);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Generate miliseconds delay.
|
||||
* @param msecs - Delay in miliseconds.
|
||||
* @return None.
|
||||
*/
|
||||
void mdelay(uint32_t msecs)
|
||||
{
|
||||
#ifdef _XPARAMETERS_PS_H_
|
||||
usleep(msecs * 1000);
|
||||
#else
|
||||
usleep_MB(msecs * 1000);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get current time.
|
||||
* @return Current time structure from system start (seconds, microseconds).
|
||||
*/
|
||||
struct time get_time(void)
|
||||
{
|
||||
struct time t = {0, 0};
|
||||
#ifdef _XPARAMETERS_PS_H_
|
||||
unsigned long long Xtime_Global;
|
||||
uint32_t rem;
|
||||
|
||||
XTime_GetTime(&Xtime_Global);
|
||||
t.s = div_u64_rem(Xtime_Global, COUNTS_PER_SECOND, &rem);
|
||||
t.us = div_u64((uint64_t)rem * 1000000, COUNTS_PER_SECOND);
|
||||
#endif
|
||||
|
||||
return t;
|
||||
}
|
||||
+464
@@ -0,0 +1,464 @@
|
||||
/***************************************************************************//**
|
||||
* @file xilinx/xilinx_gpio.c
|
||||
* @brief Implementation of Xilinx GPIO Generic Driver.
|
||||
* @author Antoniu Miclaus (antoniu.miclaus@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.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** 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
@@ -0,0 +1,95 @@
|
||||
/*******************************************************************************
|
||||
* @file xilinx/xilinx_gpio.h
|
||||
* @brief Header containing extra types used in the gpio driver
|
||||
* @author scuciurean (sergiu.cuciurean@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 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
@@ -0,0 +1,360 @@
|
||||
/***************************************************************************//**
|
||||
* @file xilinx/xilinx_gpio_irq.c
|
||||
* @brief Implementation of Xilinx GPIO IRQ Generic Driver.
|
||||
* @author Porumb Andrei (andrei.porumb@analog.com)
|
||||
********************************************************************************
|
||||
* 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(¶m->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(¶m->my_Gpio, callback_desc->pin_nb);
|
||||
XGpioPs_IntrClearPin(¶m->my_Gpio, callback_desc->pin_nb);
|
||||
callback_desc->callback.legacy_callback(callback_desc->callback.ctx, 0U, NULL);
|
||||
if(callback_desc->enabled)
|
||||
XGpioPs_IntrEnablePin(¶m->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
@@ -0,0 +1,92 @@
|
||||
/***************************************************************************//**
|
||||
* @file xilinx_gpio_irq.h
|
||||
* @brief Implementation of Xilinx GPIO IRQ Generic Driver.
|
||||
* @author Porumb Andrei (andrei.porumb@analog.com)
|
||||
********************************************************************************
|
||||
* 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
@@ -0,0 +1,514 @@
|
||||
/***************************************************************************//**
|
||||
* @file xilinx/xilinx_i2c.c
|
||||
* @brief Implementation of Xilinx I2C Generic Driver.
|
||||
* @author Antoniu Miclaus (antoniu.miclaus@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.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** 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
@@ -0,0 +1,115 @@
|
||||
/*******************************************************************************
|
||||
* @file xilinx/xilinx_i2c.h
|
||||
* @brief Header containing types used in the i2c driver.
|
||||
* @author scuciurean (sergiu.cuciurean@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 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_
|
||||
+433
@@ -0,0 +1,433 @@
|
||||
/***************************************************************************//**
|
||||
* @file xilinx/xilinx_irq.c
|
||||
* @brief Implementation of Xilinx IRQ Generic Driver.
|
||||
* @author Cristian Pop (cristian.pop@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.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#include <xparameters.h>
|
||||
#include <stdlib.h>
|
||||
#include "error.h"
|
||||
#include "irq.h"
|
||||
#include "xilinx_irq.h"
|
||||
#ifdef XPAR_XSCUGIC_NUM_INSTANCES
|
||||
#include <xscugic.h>
|
||||
#endif
|
||||
#ifdef XPAR_XINTC_NUM_INSTANCES
|
||||
#include <xintc.h>
|
||||
#endif
|
||||
#ifdef XPAR_XTMRCTR_NUM_INSTANCES
|
||||
#include <xtmrctr.h>
|
||||
#endif
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Definitions *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Initialize the IRQ interrupts.
|
||||
* @param desc - The IRQ controller descriptor.
|
||||
* @param param - The structure that contains the IRQ parameters.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t xil_irq_ctrl_init(struct irq_ctrl_desc **desc,
|
||||
const struct irq_init_param *param)
|
||||
{
|
||||
int32_t status;
|
||||
struct irq_ctrl_desc *descriptor;
|
||||
struct xil_irq_desc *xil_dev;
|
||||
#ifdef XSCUGIC_H
|
||||
void *config;
|
||||
#endif
|
||||
|
||||
descriptor = (struct irq_ctrl_desc *)calloc(1, sizeof *descriptor);
|
||||
if(!descriptor)
|
||||
return -1;
|
||||
xil_dev = (struct xil_irq_desc *)calloc(1, sizeof *xil_dev);
|
||||
if(!xil_dev) {
|
||||
free(descriptor);
|
||||
return -1;
|
||||
}
|
||||
|
||||
Xil_ExceptionInit();
|
||||
|
||||
descriptor->irq_ctrl_id = param->irq_ctrl_id;
|
||||
descriptor->extra = xil_dev;
|
||||
xil_dev->type = ((struct xil_irq_init_param *)param->extra)->type;
|
||||
|
||||
switch(xil_dev->type) {
|
||||
case IRQ_PS:
|
||||
#ifdef XSCUGIC_H
|
||||
xil_dev->instance = calloc(1, sizeof(XScuGic));
|
||||
if(!xil_dev->instance)
|
||||
goto error;
|
||||
|
||||
config = XScuGic_LookupConfig(descriptor->irq_ctrl_id);
|
||||
if(!config)
|
||||
goto ps_error;
|
||||
|
||||
status = XScuGic_CfgInitialize(xil_dev->instance, config,
|
||||
((XScuGic_Config *)config)->CpuBaseAddress);
|
||||
if (status != 0)
|
||||
goto ps_error;
|
||||
|
||||
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
|
||||
(Xil_ExceptionHandler)XScuGic_InterruptHandler,
|
||||
xil_dev->instance);
|
||||
|
||||
break;
|
||||
ps_error:
|
||||
free(xil_dev->instance);
|
||||
#endif
|
||||
goto error;
|
||||
case IRQ_PL:
|
||||
#ifdef XINTC_H
|
||||
xil_dev->instance = calloc(1, sizeof(XIntc));
|
||||
if(!xil_dev->instance)
|
||||
goto error;
|
||||
|
||||
status = XIntc_Initialize(xil_dev->instance, descriptor->irq_ctrl_id);
|
||||
if(status != 0)
|
||||
goto pl_error;
|
||||
|
||||
status = XIntc_Start(xil_dev->instance, XIN_REAL_MODE);
|
||||
if(status != 0)
|
||||
goto pl_error;
|
||||
|
||||
break;
|
||||
pl_error:
|
||||
free(xil_dev->instance);
|
||||
#endif
|
||||
goto error;
|
||||
default:
|
||||
goto error;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
*desc = descriptor;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
free(xil_dev);
|
||||
free(descriptor);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable global interrupts.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t xil_irq_global_enable(struct irq_ctrl_desc *desc)
|
||||
{
|
||||
/* Enable interrupts */
|
||||
Xil_ExceptionEnable();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable global interrupts.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t xil_irq_global_disable(struct irq_ctrl_desc *desc)
|
||||
{
|
||||
/* Disable interrupts */
|
||||
Xil_ExceptionDisable();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable specific interrupt.
|
||||
* @param desc - The IRQ controller descriptor.
|
||||
* @param irq_id - Interrupt identifier.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t xil_irq_enable(struct irq_ctrl_desc *desc, uint32_t irq_id)
|
||||
{
|
||||
struct xil_irq_desc *xil_dev = desc->extra;
|
||||
|
||||
switch(xil_dev->type) {
|
||||
case IRQ_PS:
|
||||
#ifdef XSCUGIC_H
|
||||
XScuGic_Enable(xil_dev->instance, irq_id);
|
||||
#endif
|
||||
break;
|
||||
case IRQ_PL:
|
||||
#ifdef XINTC_H
|
||||
XIntc_Enable(xil_dev->instance, irq_id);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable specific interrupt.
|
||||
* @param desc - The IRQ controller descriptor.
|
||||
* @param irq_id - Interrupt identifier.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t xil_irq_disable(struct irq_ctrl_desc *desc, uint32_t irq_id)
|
||||
{
|
||||
struct xil_irq_desc *xil_dev = desc->extra;
|
||||
|
||||
switch(xil_dev->type) {
|
||||
case IRQ_PS:
|
||||
#ifdef XSCUGIC_H
|
||||
XScuGic_Disable(xil_dev->instance, irq_id);
|
||||
#endif
|
||||
break;
|
||||
case IRQ_PL:
|
||||
#ifdef XINTC_H
|
||||
XIntc_Disable(xil_dev->instance, irq_id);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Register a callback to handle the irq events.
|
||||
* @param desc - The IRQ controller descriptor.
|
||||
* @param irq_id - Interrupt identifier.
|
||||
* @param callback_desc - Callback descriptor
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t xil_irq_register_callback(struct irq_ctrl_desc *desc,
|
||||
uint32_t irq_id,
|
||||
struct callback_desc *callback_desc)
|
||||
{
|
||||
struct xil_irq_desc *xil_dev = desc->extra;
|
||||
|
||||
switch(xil_dev->type) {
|
||||
case IRQ_PS:
|
||||
#ifdef XSCUGIC_H
|
||||
return XScuGic_Connect(xil_dev->instance, irq_id,
|
||||
(Xil_InterruptHandler) callback_desc->callback,
|
||||
callback_desc->ctx);
|
||||
#endif
|
||||
break;
|
||||
case IRQ_PL:
|
||||
#ifdef XINTC_H
|
||||
if (irq_id == XPAR_AXI_INTC_AXI_TIMER_INTERRUPT_INTR) {
|
||||
int32_t ret;
|
||||
|
||||
ret = XIntc_Connect(xil_dev->instance, irq_id,
|
||||
XTmrCtr_InterruptHandler, callback_desc->legacy_config);
|
||||
if (IS_ERR_VALUE(ret))
|
||||
return -1;
|
||||
XTmrCtr_SetHandler(callback_desc->legacy_config,
|
||||
(XTmrCtr_Handler)callback_desc->callback,
|
||||
callback_desc->ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
return XIntc_Connect(xil_dev->instance, irq_id,
|
||||
(XInterruptHandler) callback_desc->callback,
|
||||
callback_desc->ctx);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set interrupt trigger level.
|
||||
* @param desc - The IRQ controller descriptor.
|
||||
* @param irq_id - Interrupt identifier.
|
||||
* @param trig - New trigger level for the interrupt.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t xil_irq_trigger_level_set(struct irq_ctrl_desc *desc,
|
||||
uint32_t irq_id,
|
||||
enum irq_trig_level trig)
|
||||
{
|
||||
struct xil_irq_desc *xil_dev = desc->extra;
|
||||
|
||||
if(trig == IRQ_EDGE_BOTH)
|
||||
return -EINVAL;
|
||||
|
||||
switch(xil_dev->type) {
|
||||
case IRQ_PS:
|
||||
#ifdef XSCUGIC_H
|
||||
;
|
||||
uint8_t priority, trigger;
|
||||
|
||||
XScuGic_GetPriorityTriggerType(xil_dev->instance, irq_id, &priority,
|
||||
&trigger);
|
||||
trigger = trig;
|
||||
XScuGic_SetPriorityTriggerType(xil_dev->instance, irq_id, priority,
|
||||
trigger);
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
break;
|
||||
case IRQ_PL:
|
||||
#ifdef XINTC_H
|
||||
/* Interrupt trigger determined in hardware. TODO: verify */
|
||||
return 0;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set interrupt trigger level.
|
||||
* @param desc - The IRQ controller descriptor.
|
||||
* @param irq_id - Interrupt identifier.
|
||||
* @param priority_level - New priority level for the interrupt.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t xil_irq_set_priority(struct irq_ctrl_desc *desc,
|
||||
uint32_t irq_id,
|
||||
uint32_t priority_level)
|
||||
{
|
||||
struct xil_irq_desc *xil_dev = desc->extra;
|
||||
|
||||
if(priority_level % 8 != 0)
|
||||
return -EINVAL;
|
||||
|
||||
switch(xil_dev->type) {
|
||||
case IRQ_PS:
|
||||
#ifdef XSCUGIC_H
|
||||
;
|
||||
uint8_t priority, trigger;
|
||||
|
||||
XScuGic_GetPriorityTriggerType(xil_dev->instance, irq_id, &priority,
|
||||
&trigger);
|
||||
priority = priority_level;
|
||||
XScuGic_SetPriorityTriggerType(xil_dev->instance, irq_id, priority,
|
||||
trigger);
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
break;
|
||||
case IRQ_PL:
|
||||
#ifdef XINTC_H
|
||||
/* Interrupt priority level determined in hardware. TODO: verify */
|
||||
return 0;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unregisters a generic IRQ handling function.
|
||||
* @param desc - The IRQ controller descriptor.
|
||||
* @param irq_id - Interrupt identifier.
|
||||
* @param cb - Callback descriptor.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t xil_irq_unregister_callback(struct irq_ctrl_desc *desc,
|
||||
uint32_t irq_id, struct callback_desc *cb)
|
||||
{
|
||||
struct xil_irq_desc *xil_dev = desc->extra;
|
||||
|
||||
switch(xil_dev->type) {
|
||||
case IRQ_PS:
|
||||
#ifdef XSCUGIC_H
|
||||
XScuGic_Disconnect(xil_dev->instance, irq_id);
|
||||
#endif
|
||||
break;
|
||||
case IRQ_PL:
|
||||
#ifdef XINTC_H
|
||||
XIntc_Disconnect(xil_dev->instance, irq_id);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free the resources allocated by irq_ctrl_init().
|
||||
* @param desc - The IRQ control descriptor.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t xil_irq_ctrl_remove(struct irq_ctrl_desc *desc)
|
||||
{
|
||||
struct xil_irq_desc *xil_dev = desc->extra;
|
||||
free(xil_dev->instance);
|
||||
free(desc->extra);
|
||||
free(desc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Xilinx platform specific IRQ platform ops structure
|
||||
*/
|
||||
const struct irq_platform_ops xil_irq_ops = {
|
||||
.init = &xil_irq_ctrl_init,
|
||||
.register_callback = &xil_irq_register_callback,
|
||||
.unregister_callback = &xil_irq_unregister_callback,
|
||||
.global_enable = &xil_irq_global_enable,
|
||||
.global_disable = &xil_irq_global_disable,
|
||||
.trigger_level_set = &xil_irq_trigger_level_set,
|
||||
.set_priority = &xil_irq_set_priority,
|
||||
.enable = &xil_irq_enable,
|
||||
.disable = &xil_irq_disable,
|
||||
.remove = &xil_irq_ctrl_remove
|
||||
};
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
/*******************************************************************************
|
||||
* @file xilinx_irq.h
|
||||
* @brief Header containing types used in the irq driver.
|
||||
* @author Cristian Pop (cristian.pop@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 XILINX_IRQ_H_
|
||||
#define XILINX_IRQ_H_
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "irq.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @enum xil_irq_type
|
||||
* @brief Xilinx platform architecture sections
|
||||
*/
|
||||
enum xil_irq_type {
|
||||
/** Programmable Logic */
|
||||
IRQ_PL,
|
||||
/** Processing System */
|
||||
IRQ_PS
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct xil_irq_init_param
|
||||
* @brief Structure holding the initialization parameters for Xilinx platform
|
||||
* specific IRQ parameters.
|
||||
*/
|
||||
struct xil_irq_init_param {
|
||||
/** Xilinx architecture */
|
||||
enum xil_irq_type type;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct xil_irq_desc
|
||||
* @brief Xilinx platform specific IRQ descriptor
|
||||
*/
|
||||
struct xil_irq_desc {
|
||||
/** Xilinx architecture */
|
||||
enum xil_irq_type type;
|
||||
/** Xilinx IRQ Instance */
|
||||
void *instance;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Xilinx specific IRQ platform ops structure
|
||||
*/
|
||||
extern const struct irq_platform_ops xil_irq_ops;
|
||||
|
||||
#endif
|
||||
+462
@@ -0,0 +1,462 @@
|
||||
/***************************************************************************//**
|
||||
* @file xilinx/xilinx_spi.c
|
||||
* @brief Implementation of Xilinx SPI Generic Driver.
|
||||
* @author Antoniu Miclaus (antoniu.miclaus@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.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <xparameters.h>
|
||||
#ifdef XPAR_XSPI_NUM_INSTANCES
|
||||
#include <xspi.h>
|
||||
#endif
|
||||
#ifdef XPAR_XSPIPS_NUM_INSTANCES
|
||||
#include <xspips.h>
|
||||
#endif
|
||||
|
||||
#include "error.h"
|
||||
#include "spi.h"
|
||||
#include "xilinx_spi.h"
|
||||
|
||||
#if defined(PLATFORM_ZYNQ)
|
||||
#define SPI_CLK_FREQ_HZ(dev) (XPAR_PS7_SPI_ ## dev ## _SPI_CLK_FREQ_HZ)
|
||||
#define SPI_NUM_INSTANCES XPAR_XSPIPS_NUM_INSTANCES
|
||||
#elif defined(PLATFORM_ZYNQMP)
|
||||
#define SPI_CLK_FREQ_HZ(dev) (XPAR_PSU_SPI_ ## dev ## _SPI_CLK_FREQ_HZ)
|
||||
#define SPI_NUM_INSTANCES XPAR_XSPIPS_NUM_INSTANCES
|
||||
#else
|
||||
#define SPI_NUM_INSTANCES 0
|
||||
#endif
|
||||
|
||||
#warning SPI delays are not supported on the xilinx platform
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Definitions *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Initialize the hardware SPI peripherial
|
||||
*
|
||||
* @param xdesc Platform specific SPI descriptor
|
||||
* @param xinit Platform specific SPI init param
|
||||
* @return int32_t -1 if the device couldn't be found or configured
|
||||
*/
|
||||
static int32_t spi_init_pl(struct spi_desc *desc,
|
||||
const struct spi_init_param *param)
|
||||
{
|
||||
#ifdef XSPI_H
|
||||
int32_t ret;
|
||||
struct xil_spi_desc *xdesc;
|
||||
struct xil_spi_init_param *xinit;
|
||||
|
||||
xdesc = (struct xil_spi_desc*)malloc(sizeof(struct xil_spi_desc));
|
||||
if(!xdesc) {
|
||||
free(xdesc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
desc->extra = xdesc;
|
||||
xinit = param->extra;
|
||||
xdesc->type = xinit->type;
|
||||
xdesc->flags = xinit->flags;
|
||||
|
||||
xdesc->instance = (XSpi*)calloc(1, sizeof(XSpi));
|
||||
if(!xdesc->instance)
|
||||
goto pl_error;
|
||||
|
||||
xdesc->config = XSpi_LookupConfig(param->device_id);
|
||||
if(xdesc->config == NULL)
|
||||
goto pl_error;
|
||||
|
||||
ret = XSpi_CfgInitialize(xdesc->instance,
|
||||
xdesc->config,
|
||||
((XSpi_Config*)xdesc->config)
|
||||
->BaseAddress);
|
||||
if(ret != 0)
|
||||
goto pl_error;
|
||||
|
||||
ret = XSpi_Initialize(xdesc->instance, param->device_id);
|
||||
if (ret != 0)
|
||||
goto pl_error;
|
||||
|
||||
ret = XSpi_SetOptions(xdesc->instance,
|
||||
XSP_MASTER_OPTION |
|
||||
((desc->mode & SPI_CPOL) ?
|
||||
XSP_CLK_ACTIVE_LOW_OPTION : 0) |
|
||||
((desc->mode & SPI_CPHA) ?
|
||||
XSP_CLK_PHASE_1_OPTION : 0));
|
||||
if (ret != 0)
|
||||
goto pl_error;
|
||||
|
||||
ret = XSpi_Start(xdesc->instance);
|
||||
if (ret != 0)
|
||||
goto pl_error;
|
||||
|
||||
XSpi_IntrGlobalDisable((XSpi *)(xdesc->instance));
|
||||
|
||||
return 0;
|
||||
|
||||
pl_error:
|
||||
free(xdesc->instance);
|
||||
free(xdesc);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the hardware SPI peripherial
|
||||
*
|
||||
* @param xdesc Platform specific SPI descriptor
|
||||
* @param xinit Platform specific SPI init param
|
||||
* @return int32_t -1 if the device couldn't be found or configured
|
||||
*/
|
||||
static int32_t spi_init_ps(struct spi_desc *desc,
|
||||
const struct spi_init_param *param)
|
||||
{
|
||||
#ifdef XSPIPS_H
|
||||
int32_t ret;
|
||||
struct xil_spi_desc *xdesc;
|
||||
struct xil_spi_init_param *xinit;
|
||||
const uint32_t prescaler_default = XSPIPS_CLK_PRESCALE_64;
|
||||
const uint32_t prescaler_min = XSPIPS_CLK_PRESCALE_4;
|
||||
const uint32_t prescaler_max = XSPIPS_CLK_PRESCALE_256;
|
||||
uint32_t prescaler = 0u;
|
||||
uint32_t input_clock = 0u;
|
||||
|
||||
xdesc = (struct xil_spi_desc*)malloc(sizeof(struct xil_spi_desc));
|
||||
if(!xdesc) {
|
||||
free(xdesc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
desc->extra = xdesc;
|
||||
xinit = param->extra;
|
||||
xdesc->type = xinit->type;
|
||||
xdesc->flags = xinit->flags;
|
||||
|
||||
xdesc->instance = (XSpiPs*)malloc(sizeof(XSpiPs));
|
||||
if(!xdesc->instance)
|
||||
goto ps_error;
|
||||
|
||||
xdesc->config = XSpiPs_LookupConfig(param->device_id);
|
||||
if(xdesc->config == NULL)
|
||||
goto ps_error;
|
||||
|
||||
ret = XSpiPs_CfgInitialize(xdesc->instance,
|
||||
xdesc->config,
|
||||
((XSpiPs_Config*)xdesc->config)
|
||||
->BaseAddress);
|
||||
if(ret != 0)
|
||||
goto ps_error;
|
||||
|
||||
switch (param->device_id) {
|
||||
#if (SPI_NUM_INSTANCES >= 1)
|
||||
case 0:
|
||||
input_clock = SPI_CLK_FREQ_HZ(0);
|
||||
break;
|
||||
#endif
|
||||
#if (SPI_NUM_INSTANCES >= 2)
|
||||
case 1:
|
||||
input_clock = SPI_CLK_FREQ_HZ(1);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
goto ps_error;
|
||||
};
|
||||
|
||||
if (desc->max_speed_hz != 0u) {
|
||||
uint32_t div = input_clock / desc->max_speed_hz;
|
||||
uint32_t rem = input_clock % desc->max_speed_hz;
|
||||
uint32_t po2 = !(div & (div - 1)) && !rem;
|
||||
|
||||
// find the power of two just higher than div and
|
||||
// store the exponent in prescaler
|
||||
while(div) {
|
||||
prescaler += 1;
|
||||
div >>= 1u;
|
||||
}
|
||||
|
||||
// this exponent - 1 is needed because of the way
|
||||
// xilinx stores it into registers
|
||||
if (prescaler)
|
||||
prescaler -= 1;
|
||||
|
||||
// this exponent - 1 is needed when initial div was
|
||||
// precisely a power of two
|
||||
if (prescaler && po2)
|
||||
prescaler -= 1;
|
||||
|
||||
if (prescaler < prescaler_min)
|
||||
prescaler = prescaler_min;
|
||||
|
||||
if (prescaler > prescaler_max)
|
||||
prescaler = prescaler_max;
|
||||
} else
|
||||
prescaler = prescaler_default;
|
||||
|
||||
ret = XSpiPs_SetClkPrescaler(xdesc->instance, prescaler);
|
||||
|
||||
if(ret != 0)
|
||||
goto ps_error;
|
||||
|
||||
return 0;
|
||||
|
||||
ps_error:
|
||||
free(xdesc->instance);
|
||||
free(xdesc);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 xil_spi_init(struct spi_desc **desc,
|
||||
const struct spi_init_param *param)
|
||||
{
|
||||
int32_t ret;
|
||||
enum xil_spi_type *spi_type;
|
||||
|
||||
if (!param) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*desc = malloc(sizeof(**desc));
|
||||
if(! *desc) {
|
||||
free(*desc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
spi_type = param->extra;
|
||||
|
||||
if(!spi_type)
|
||||
goto init_error;
|
||||
|
||||
(*desc)->max_speed_hz = param->max_speed_hz;
|
||||
(*desc)->mode = param->mode;
|
||||
(*desc)->bit_order = param->bit_order;
|
||||
(*desc)->chip_select = param->chip_select;
|
||||
|
||||
switch (*spi_type) {
|
||||
case SPI_PL:
|
||||
ret = spi_init_pl(*desc, param);
|
||||
break;
|
||||
case SPI_PS:
|
||||
ret = spi_init_ps(*desc, param);
|
||||
break;
|
||||
|
||||
default:
|
||||
goto init_error;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
init_error:
|
||||
free(*desc);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free the resources allocated by spi_init().
|
||||
* @param desc - The SPI descriptor.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t xil_spi_remove(struct spi_desc *desc)
|
||||
{
|
||||
#ifdef XSPI_H
|
||||
int32_t ret;
|
||||
#endif
|
||||
struct xil_spi_desc *xdesc = NULL;
|
||||
enum xil_spi_type *spi_type;
|
||||
|
||||
spi_type = desc->extra;
|
||||
|
||||
if(!spi_type)
|
||||
return -1;
|
||||
|
||||
switch (*spi_type ) {
|
||||
case SPI_PL:
|
||||
#ifdef XSPI_H
|
||||
xdesc = desc->extra;
|
||||
|
||||
if(!xdesc)
|
||||
return -1;
|
||||
|
||||
ret = XSpi_Stop((XSpi *)(xdesc->instance));
|
||||
if(ret != 0)
|
||||
goto error;
|
||||
#endif
|
||||
break;
|
||||
case SPI_PS:
|
||||
#ifdef XSPIPS_H
|
||||
xdesc = desc->extra;
|
||||
|
||||
if(!xdesc)
|
||||
return -1;
|
||||
#endif
|
||||
break;
|
||||
|
||||
/* Intended fallthrough */
|
||||
#ifdef XSPI_H
|
||||
error:
|
||||
#endif
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(xdesc)
|
||||
free(xdesc->instance);
|
||||
free(desc->extra);
|
||||
free(desc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 xil_spi_write_and_read(struct spi_desc *desc,
|
||||
uint8_t *data,
|
||||
uint16_t bytes_number)
|
||||
{
|
||||
int32_t ret;
|
||||
#ifdef XSPI_H
|
||||
uint32_t ctrl_reg;
|
||||
#endif
|
||||
struct xil_spi_desc *xdesc;
|
||||
enum xil_spi_type *spi_type;
|
||||
|
||||
ret = -1;
|
||||
|
||||
spi_type = desc->extra;
|
||||
|
||||
if(!spi_type)
|
||||
return -1;
|
||||
|
||||
xdesc = desc->extra;
|
||||
|
||||
switch (*spi_type) {
|
||||
case SPI_PL:
|
||||
#ifdef XSPI_H
|
||||
ret = XSpi_SetOptions(xdesc->instance,
|
||||
XSP_MASTER_OPTION |
|
||||
((desc->mode & SPI_CPOL) ?
|
||||
XSP_CLK_ACTIVE_LOW_OPTION : 0) |
|
||||
((desc->mode & SPI_CPHA) ?
|
||||
XSP_CLK_PHASE_1_OPTION : 0));
|
||||
if (ret != 0)
|
||||
goto error;
|
||||
|
||||
ctrl_reg = XSpi_GetControlReg(((XSpi*)xdesc->instance));
|
||||
if (desc->bit_order == SPI_BIT_ORDER_LSB_FIRST)
|
||||
ctrl_reg |= XSP_CR_LSB_MSB_FIRST_MASK;
|
||||
else
|
||||
ctrl_reg &= ~ XSP_CR_LSB_MSB_FIRST_MASK;
|
||||
XSpi_SetControlReg(((XSpi*)xdesc->instance), ctrl_reg);
|
||||
|
||||
ret = XSpi_SetSlaveSelect(xdesc->instance,
|
||||
0x01 << desc->chip_select);
|
||||
if (ret != 0)
|
||||
goto error;
|
||||
|
||||
ret = XSpi_Transfer(xdesc->instance,
|
||||
data,
|
||||
data,
|
||||
bytes_number);
|
||||
if (ret != 0)
|
||||
goto error;
|
||||
#endif
|
||||
break;
|
||||
case SPI_PS:
|
||||
#ifdef XSPIPS_H
|
||||
ret = XSpiPs_SetOptions(xdesc->instance,
|
||||
XSPIPS_MASTER_OPTION |
|
||||
((xdesc->flags & SPI_CS_DECODE) ?
|
||||
XSPIPS_DECODE_SSELECT_OPTION : 0) |
|
||||
XSPIPS_FORCE_SSELECT_OPTION |
|
||||
((desc->mode & SPI_CPOL) ?
|
||||
XSPIPS_CLK_ACTIVE_LOW_OPTION : 0) |
|
||||
((desc->mode & SPI_CPHA) ?
|
||||
XSPIPS_CLK_PHASE_1_OPTION : 0));
|
||||
if (ret != 0)
|
||||
goto error;
|
||||
|
||||
ret = XSpiPs_SetSlaveSelect(xdesc->instance,
|
||||
desc->chip_select);
|
||||
if (ret != 0)
|
||||
goto error;
|
||||
ret = XSpiPs_PolledTransfer(xdesc->instance,
|
||||
data,
|
||||
data,
|
||||
bytes_number);
|
||||
if (ret != 0)
|
||||
goto error;
|
||||
ret = XSpiPs_SetSlaveSelect(xdesc->instance, SPI_DEASSERT_CURRENT_SS);
|
||||
if (ret != 0)
|
||||
goto error;
|
||||
#endif
|
||||
break;
|
||||
error:
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Xilinx platform specific SPI platform ops structure
|
||||
*/
|
||||
const struct spi_platform_ops xil_spi_ops = {
|
||||
.init = &xil_spi_init,
|
||||
.write_and_read = &xil_spi_write_and_read,
|
||||
.remove = &xil_spi_remove
|
||||
};
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
/*******************************************************************************
|
||||
* @file xilinx/xilinx_spi.h
|
||||
* @brief Header containing extra types used in the spi driver.
|
||||
* @author scuciurean (sergiu.cuciurean@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 XILINX_SPI_H_
|
||||
#define XILINX_SPI_H_
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "spi.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** Macros and Constants Definitions **********************/
|
||||
/******************************************************************************/
|
||||
|
||||
#define SPI_CS_DECODE 0x01
|
||||
#define SPI_DEASSERT_CURRENT_SS 0x0F
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @enum xil_spi_type
|
||||
* @brief Xilinx platform architecture sections
|
||||
*/
|
||||
enum xil_spi_type {
|
||||
/** Programmable Logic */
|
||||
SPI_PL,
|
||||
/** Processing System */
|
||||
SPI_PS,
|
||||
/** SPI Engine */
|
||||
SPI_ENGINE
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct xil_spi_init_param
|
||||
* @brief Structure holding the initialization parameters for Xilinx platform
|
||||
* specific SPI parameters when using xil_spi_ops.
|
||||
*/
|
||||
struct xil_spi_init_param {
|
||||
/** Xilinx architecture */
|
||||
enum xil_spi_type type;
|
||||
/** SPI flags */
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct xil_spi_desc
|
||||
* @brief Xilinx platform specific SPI descriptor
|
||||
*/
|
||||
struct xil_spi_desc {
|
||||
/** Xilinx architecture */
|
||||
enum xil_spi_type type;
|
||||
/** SPI flags */
|
||||
uint32_t flags;
|
||||
/** SPI configuration */
|
||||
void *config;
|
||||
/** SPI instance */
|
||||
void *instance;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief SPI engine platform ops structure
|
||||
*/
|
||||
extern const struct spi_platform_ops spi_eng_platform_ops;
|
||||
|
||||
/**
|
||||
* @brief Xilinx specific SPI platform ops structure
|
||||
*/
|
||||
extern const struct spi_platform_ops xil_spi_ops;
|
||||
|
||||
/**
|
||||
* @brief Xilinx SPI PS register functions. No extra param needed
|
||||
*/
|
||||
extern const struct spi_platform_ops xil_spi_pl_ops;
|
||||
|
||||
#endif // XILINX_SPI_H_
|
||||
+533
@@ -0,0 +1,533 @@
|
||||
/*******************************************************************************
|
||||
* @file xilinx/xilinx_spi_pl.c
|
||||
* @brief Driver for spi pl device using registers
|
||||
* @author Mihail Chindris (mihail.chindris@analog.com)
|
||||
********************************************************************************
|
||||
* Copyright 2021(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
#include <xparameters.h>
|
||||
|
||||
#ifdef XPAR_XSPI_NUM_INSTANCES
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#include <xspi.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include "spi.h"
|
||||
#include "error.h"
|
||||
#include "delay.h"
|
||||
#include "util.h"
|
||||
#include "alloc.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** Macros and Constants Definitions **********************/
|
||||
/******************************************************************************/
|
||||
|
||||
#define XPS_TYPE_WRITE 0x1
|
||||
#define XPS_TYPE_READ 0x2
|
||||
#define XSP_DEFAULT_SR_VALUE 0x25
|
||||
#define XSP_DUMMY_DATA 0xFF
|
||||
|
||||
/*
|
||||
* Used to store current spi device configuration in order to not update it for
|
||||
* each spi transaction if not needed.
|
||||
*/
|
||||
static struct spi_desc g_spi_desc[XPAR_XSPI_NUM_INSTANCES];
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/* Xilinx PL spi specific data */
|
||||
struct xspi_desc {
|
||||
uint32_t base_addr;
|
||||
uint32_t disable_slaves_mask;
|
||||
uint32_t fifo_depth;
|
||||
uint8_t cs_asserted;
|
||||
};
|
||||
|
||||
/* Structure used to iterate over SPI messages */
|
||||
struct msg_iter {
|
||||
struct spi_msg *msgs;
|
||||
uint32_t len;
|
||||
uint32_t i;
|
||||
uint32_t buff_i;
|
||||
uint8_t is_wr;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Definitions *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/* Read device register */
|
||||
static inline uint32_t _read(struct xspi_desc *xdesc, uint32_t reg)
|
||||
{
|
||||
return Xil_In32(xdesc->base_addr + reg);
|
||||
}
|
||||
|
||||
/* Write device register */
|
||||
static inline void _write(struct xspi_desc *xdesc, uint32_t reg, uint32_t val)
|
||||
{
|
||||
Xil_Out32(xdesc->base_addr + reg, val);
|
||||
}
|
||||
|
||||
/* Update device register. Only bits set to 1 in mask will be modified */
|
||||
static inline void _wr_mask(struct xspi_desc *xdesc, uint32_t reg,
|
||||
uint32_t val, uint32_t mask)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
tmp = _read(xdesc, reg);
|
||||
tmp &= ~mask;
|
||||
tmp |= val & mask;
|
||||
_write(xdesc, reg, tmp);
|
||||
}
|
||||
|
||||
/* Update spi device configuration if needed */
|
||||
static void _update_mode(struct spi_desc *desc)
|
||||
{
|
||||
uint32_t val;
|
||||
uint32_t mask;
|
||||
|
||||
if (desc->mode == g_spi_desc[desc->device_id].mode &&
|
||||
desc->bit_order == g_spi_desc[desc->device_id].bit_order)
|
||||
return ;
|
||||
|
||||
/* Update mode */
|
||||
val = desc->mode | SPI_CPOL ? XSP_CR_CLK_POLARITY_MASK : 0;
|
||||
val |= desc->mode | SPI_CPHA ? XSP_CR_CLK_PHASE_MASK : 0;
|
||||
mask = XSP_CR_CLK_POLARITY_MASK | XSP_CR_CLK_PHASE_MASK;
|
||||
|
||||
val |= desc->bit_order == SPI_BIT_ORDER_LSB_FIRST ?
|
||||
XSP_CR_LSB_MSB_FIRST_MASK : 0;
|
||||
mask |= XSP_CR_LSB_MSB_FIRST_MASK;
|
||||
|
||||
_wr_mask(desc->extra, XSP_CR_OFFSET, val, mask);
|
||||
g_spi_desc[desc->device_id] = *desc;
|
||||
}
|
||||
|
||||
/* Configure SPI PL device */
|
||||
static int32_t _xil_spi_init_dev(struct xspi_desc *xdesc)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
/* Software reset */
|
||||
_write(xdesc, XSP_SRR_OFFSET, XSP_SRR_RESET_MASK);
|
||||
mdelay(1);
|
||||
|
||||
/* Check if success reset */
|
||||
val = _read(xdesc, XSP_SR_OFFSET);
|
||||
if (val != XSP_DEFAULT_SR_VALUE)
|
||||
return -ENODEV;
|
||||
|
||||
/* Disable interrupts. Drivers only works with pooled mode */
|
||||
_write(xdesc, XSP_IIER_OFFSET, 0);
|
||||
|
||||
/* Deasert chip selects */
|
||||
_write(xdesc, XSP_SSR_OFFSET, 0xFFFFFFFF);
|
||||
|
||||
/* Get fifo depth */
|
||||
while (!(_read(xdesc, XSP_SR_OFFSET) & XSP_SR_TX_FULL_MASK))
|
||||
_write(xdesc, XSP_DTR_OFFSET, XSP_DUMMY_DATA);
|
||||
xdesc->fifo_depth = _read(xdesc, XSP_TFO_OFFSET) + 1;
|
||||
|
||||
/* Configure spi device */
|
||||
val = XSP_CR_ENABLE_MASK |
|
||||
XSP_CR_MANUAL_SS_MASK |
|
||||
XSP_CR_TXFIFO_RESET_MASK |
|
||||
XSP_CR_RXFIFO_RESET_MASK |
|
||||
XSP_CR_MASTER_MODE_MASK |
|
||||
XSP_CR_TRANS_INHIBIT_MASK;
|
||||
|
||||
_write(xdesc, XSP_CR_OFFSET, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Initialize spi_desc structure and device */
|
||||
static int32_t xil_spi_init_pl(struct spi_desc **desc,
|
||||
const struct spi_init_param *param)
|
||||
{
|
||||
struct spi_desc *ldesc;
|
||||
struct xspi_desc *xdesc;
|
||||
int32_t err;
|
||||
XSpi_Config *cfg;
|
||||
|
||||
if (!desc || !param || param->device_id >= XPAR_XSPI_NUM_INSTANCES)
|
||||
return -EINVAL;
|
||||
|
||||
cfg = XSpi_LookupConfig(param->device_id);
|
||||
if (!cfg)
|
||||
return -EINVAL;
|
||||
|
||||
if (param->chip_select > cfg->NumSlaveBits)
|
||||
return -EINVAL;
|
||||
|
||||
ldesc = (struct spi_desc *)calloc(1, sizeof(*ldesc));
|
||||
if (!ldesc)
|
||||
return -ENOMEM;
|
||||
|
||||
xdesc = (struct xspi_desc *)calloc(1, sizeof(*xdesc));
|
||||
if (!xdesc) {
|
||||
err = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
ldesc->bit_order = param->bit_order;
|
||||
ldesc->chip_select = param->chip_select;
|
||||
ldesc->mode = param->mode;
|
||||
xdesc->base_addr = cfg->BaseAddress;
|
||||
xdesc->disable_slaves_mask = (1 << cfg->NumSlaveBits) - 1;
|
||||
xdesc->cs_asserted = 0;
|
||||
|
||||
err = _xil_spi_init_dev(xdesc);
|
||||
if (IS_ERR_VALUE(err))
|
||||
goto error;
|
||||
|
||||
ldesc->extra = xdesc;
|
||||
*desc = ldesc;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
free(xdesc);
|
||||
free(ldesc);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Remove allocated resources */
|
||||
static int32_t xil_spi_remove_pl(struct spi_desc *desc)
|
||||
{
|
||||
if (!desc)
|
||||
return -EINVAL;
|
||||
|
||||
free(desc->extra);
|
||||
free(desc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill fifo until fifo is full or no more data available.
|
||||
* Return the number of written bytes.
|
||||
*/
|
||||
static uint32_t _wr_fifo(struct xspi_desc *xdesc, uint8_t *data,
|
||||
uint32_t len)
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t to_write;
|
||||
uint32_t tx_available;
|
||||
|
||||
tx_available = xdesc->fifo_depth - _read(xdesc, XSP_TFO_OFFSET);
|
||||
to_write = min(tx_available, len);
|
||||
for (i = 0; i < to_write; ++i)
|
||||
if (data)
|
||||
_write(xdesc, XSP_DTR_OFFSET, data[i]);
|
||||
else
|
||||
_write(xdesc, XSP_DTR_OFFSET, XSP_DUMMY_DATA);
|
||||
|
||||
return to_write;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read fifo until fifo is empty or no more buffer available to read into
|
||||
* Returns the number of read bytes
|
||||
*/
|
||||
static uint32_t _rd_fifo(struct xspi_desc *xdesc, uint8_t *data,
|
||||
uint32_t len)
|
||||
{
|
||||
uint32_t rx_available;
|
||||
uint32_t to_read;
|
||||
uint32_t tmp;
|
||||
uint32_t i;
|
||||
|
||||
tmp = _read(xdesc, XSP_SR_OFFSET);
|
||||
if (tmp & XSP_SR_RX_EMPTY_MASK)
|
||||
return 0;
|
||||
|
||||
rx_available = _read(xdesc, XSP_RFO_OFFSET) + 1;
|
||||
to_read = min(rx_available, len);
|
||||
for (i = 0; i < to_read; ++i) {
|
||||
tmp = _read(xdesc, XSP_DRR_OFFSET);
|
||||
if (data)
|
||||
data[i] = tmp;
|
||||
}
|
||||
|
||||
return to_read;
|
||||
}
|
||||
|
||||
/* If start is 0 stop transfer, else start it.
|
||||
* CS will be asserted if needed. If different CS othere than the one needed
|
||||
* is asserted. Deassert it and assert correct one */
|
||||
static void _xil_spi_start_transfer(struct spi_desc *desc, uint8_t start)
|
||||
{
|
||||
struct xspi_desc *xdesc;
|
||||
|
||||
xdesc = desc->extra;
|
||||
if (start) {
|
||||
if (xdesc->cs_asserted) {
|
||||
if (desc->chip_select ==
|
||||
g_spi_desc[desc->device_id].chip_select)
|
||||
return ;
|
||||
else
|
||||
/* Stop transfer to start again with new CS */
|
||||
_xil_spi_start_transfer(desc, 0);
|
||||
}
|
||||
_write(xdesc, XSP_SSR_OFFSET, ~(1 << desc->chip_select));
|
||||
_wr_mask(xdesc, XSP_CR_OFFSET, 0, XSP_CR_TRANS_INHIBIT_MASK);
|
||||
} else {
|
||||
_wr_mask(xdesc, XSP_CR_OFFSET, XSP_CR_TRANS_INHIBIT_MASK,
|
||||
XSP_CR_TRANS_INHIBIT_MASK);
|
||||
_write(xdesc, XSP_SSR_OFFSET, xdesc->disable_slaves_mask);
|
||||
}
|
||||
xdesc->cs_asserted = start;
|
||||
}
|
||||
|
||||
|
||||
/* SPI polled transfer */
|
||||
static int32_t xil_spi_write_and_read_pl(struct spi_desc *desc,
|
||||
uint8_t *data,
|
||||
uint16_t bytes_number)
|
||||
{
|
||||
struct xspi_desc *xdesc;
|
||||
uint32_t rx;
|
||||
uint32_t tx;
|
||||
|
||||
if (!desc || !desc->extra)
|
||||
return -EINVAL;
|
||||
|
||||
xdesc = desc->extra;
|
||||
_update_mode(desc);
|
||||
|
||||
_xil_spi_start_transfer(desc, 1);
|
||||
rx = 0;
|
||||
tx = 0;
|
||||
while (rx < bytes_number) {
|
||||
if (tx < bytes_number)
|
||||
tx += _wr_fifo(xdesc, data + tx, bytes_number - tx);
|
||||
rx += _rd_fifo(xdesc, data + rx, bytes_number - rx);
|
||||
}
|
||||
_xil_spi_start_transfer(desc, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get type of message. It can be READ, WRITE or both */
|
||||
static uint32_t _get_msg_type(struct spi_msg *msg)
|
||||
{
|
||||
uint32_t type;
|
||||
|
||||
type = 0;
|
||||
if (msg->tx_buff)
|
||||
type |= XPS_TYPE_WRITE;
|
||||
if (msg->rx_buff)
|
||||
type |= XPS_TYPE_READ;
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
/* Get information based on current iterator position */
|
||||
static void _get_data(struct msg_iter *it, uint8_t **buff, uint32_t *len,
|
||||
uint32_t *type)
|
||||
{
|
||||
struct spi_msg *msg;
|
||||
|
||||
if (it->i == it->len) {
|
||||
*len = 0;
|
||||
return ;
|
||||
}
|
||||
|
||||
msg = it->msgs + it->i;
|
||||
if (it->is_wr)
|
||||
*buff = msg->tx_buff;
|
||||
else
|
||||
*buff = msg->rx_buff;
|
||||
|
||||
if (*buff)
|
||||
*buff += it->buff_i;
|
||||
|
||||
*len = msg->bytes_number - it->buff_i;
|
||||
if (type)
|
||||
*type = _get_msg_type(msg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Increment iterator position with desired length.
|
||||
* If the new position has a different message type, new_type will be set to 1
|
||||
* If a CS change is needed, cs_change is set
|
||||
*/
|
||||
static void _increment_iter(struct msg_iter *it, uint32_t len,
|
||||
uint8_t *cs_change, uint8_t *new_type)
|
||||
{
|
||||
struct spi_msg *msg;
|
||||
uint32_t type;
|
||||
uint32_t extra_len;
|
||||
|
||||
if (!len)
|
||||
return ;
|
||||
|
||||
*cs_change = 0;
|
||||
*new_type = 0;
|
||||
msg = it->msgs + it->i;
|
||||
if (it->buff_i + len > msg->bytes_number)
|
||||
extra_len = it->buff_i + len - msg->bytes_number;
|
||||
else
|
||||
extra_len = 0;
|
||||
len -= extra_len;
|
||||
it->buff_i += len;
|
||||
if (it->buff_i == msg->bytes_number) {
|
||||
type = _get_msg_type(msg);
|
||||
++it->i;
|
||||
it->buff_i = 0;
|
||||
if (cs_change && msg->cs_change)
|
||||
*cs_change = 1;
|
||||
if (new_type)
|
||||
if (it->i == it->len ||
|
||||
type != _get_msg_type(it->msgs + it->i))
|
||||
*new_type = 1;
|
||||
}
|
||||
if (extra_len)
|
||||
_increment_iter(it, extra_len, cs_change, new_type);
|
||||
}
|
||||
|
||||
/*
|
||||
* SPI polling transfer of multiple messages.
|
||||
*/
|
||||
static int32_t xil_spi_transfer_pl(struct spi_desc *desc,
|
||||
struct spi_msg *msgs,
|
||||
uint32_t len)
|
||||
|
||||
{
|
||||
struct xspi_desc *xdesc;
|
||||
uint8_t cs_change;
|
||||
uint8_t new_type;
|
||||
struct msg_iter rx = {.msgs = msgs, .len = len, .is_wr = 0};
|
||||
struct msg_iter tx = {.msgs = msgs, .len = len, .is_wr = 1};
|
||||
uint8_t *buff;
|
||||
uint32_t bytes;
|
||||
uint32_t type;
|
||||
/* Bytes to increment rx when only a write transaction is executed */
|
||||
uint32_t to_inc_rx;
|
||||
/* Difference between rx and tx iterators in bytes */
|
||||
uint32_t tx_advance;
|
||||
/* Save bytes sent during a write loop */
|
||||
uint32_t tx_sent;
|
||||
/* Used to loop if need to empty the RX FIFO */
|
||||
uint32_t loop;
|
||||
|
||||
if (!desc || !desc->extra)
|
||||
return -EINVAL;
|
||||
|
||||
xdesc = desc->extra;
|
||||
_update_mode(desc);
|
||||
|
||||
tx_advance = 0;
|
||||
to_inc_rx = 0;
|
||||
buff = NULL;
|
||||
type = 0;
|
||||
do {
|
||||
_xil_spi_start_transfer(desc, 1);
|
||||
|
||||
tx_sent = 0;
|
||||
/* Writing loop */
|
||||
do {
|
||||
_get_data(&tx, &buff, &bytes, &type);
|
||||
if (type & XPS_TYPE_READ)
|
||||
/*
|
||||
* Do not write more bytes than fifo_depth if
|
||||
* they haven't been read.
|
||||
*/
|
||||
bytes = min(bytes,
|
||||
xdesc->fifo_depth - tx_advance);
|
||||
bytes = _wr_fifo(xdesc, buff, bytes);
|
||||
tx_sent += bytes;
|
||||
_increment_iter(&tx, bytes, &cs_change, &new_type);
|
||||
tx_advance += bytes;
|
||||
} while (!cs_change && !new_type && bytes);
|
||||
|
||||
if (type & XPS_TYPE_READ) {
|
||||
loop = 1;
|
||||
/*
|
||||
* Loop only when no more data to write otherwise read
|
||||
* only available data.
|
||||
*/
|
||||
while (loop) {
|
||||
if (!new_type)
|
||||
loop = 0;
|
||||
_get_data(&rx, &buff, &bytes, NULL);
|
||||
bytes = _rd_fifo(xdesc, buff, bytes);
|
||||
_increment_iter(&rx, bytes, &cs_change, &new_type);
|
||||
tx_advance -= bytes;
|
||||
if (loop && new_type)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* Clean RX FIFO if it was only a WRITE message */
|
||||
to_inc_rx += tx_sent;
|
||||
if (new_type) {
|
||||
/* Wait for TX to be sent */
|
||||
while (!(_read(xdesc, XSP_SR_OFFSET) &
|
||||
XSP_SR_TX_EMPTY_MASK))
|
||||
;
|
||||
/* Reset fifo. Only write was performed */
|
||||
_wr_mask(xdesc, XSP_CR_OFFSET,
|
||||
XSP_CR_RXFIFO_RESET_MASK,
|
||||
XSP_CR_RXFIFO_RESET_MASK);
|
||||
|
||||
_increment_iter(&rx, to_inc_rx, NULL, NULL);
|
||||
tx_advance -= to_inc_rx;
|
||||
to_inc_rx = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ((cs_change && rx.i != len) || (!cs_change && rx.i == len))
|
||||
_xil_spi_start_transfer(desc, 0);
|
||||
} while (rx.i < len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct spi_platform_ops xil_spi_pl_ops = {
|
||||
.init = xil_spi_init_pl,
|
||||
.remove = xil_spi_remove_pl,
|
||||
.write_and_read = xil_spi_write_and_read_pl,
|
||||
.transfer = xil_spi_transfer_pl
|
||||
};
|
||||
|
||||
#endif // XPAR_XSPI_NUM_INSTANCES
|
||||
+456
@@ -0,0 +1,456 @@
|
||||
/***************************************************************************//**
|
||||
* @file xilinx/xilinx_timer.c
|
||||
* @brief Timer and GIC control module source.
|
||||
* @author Andrei Drimbarean (andrei.drimbarean@analog.com)
|
||||
********************************************************************************
|
||||
* 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 Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <xparameters.h>
|
||||
#include "timer.h"
|
||||
#include "xilinx_timer.h"
|
||||
#include "error.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** Macros and Constants Definitions **********************/
|
||||
/******************************************************************************/
|
||||
|
||||
#if defined(_XPARAMETERS_PS_H_)
|
||||
#define CORE_PRIVATE_TIMER_CLOCK (XPAR_CPU_CORTEXA9_CORE_CLOCK_FREQ_HZ / 2)
|
||||
#endif
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Functions Definitions *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Set the current counter value of the timer.
|
||||
* @param [in] desc - Pointer to the device handler.
|
||||
* @param [in] new_val - New value for the timer counter.
|
||||
* @return 0 in case of success, -1 otherwise
|
||||
*/
|
||||
int32_t xilinx_timer_counter_set(struct timer_desc *desc,
|
||||
uint32_t new_val)
|
||||
{
|
||||
struct xil_timer_desc *xdesc;
|
||||
|
||||
if (!desc)
|
||||
return -1;
|
||||
|
||||
xdesc = desc->extra;
|
||||
|
||||
switch (xdesc->type) {
|
||||
case TIMER_PS:
|
||||
#ifdef XSCUTIMER_H
|
||||
XScuTimer_LoadTimer((XScuTimer *)xdesc->instance, new_val - 1);
|
||||
break;
|
||||
#endif
|
||||
return -1;
|
||||
case TIMER_PL:
|
||||
#ifdef XTMRCTR_H
|
||||
XTmrCtr_SetResetValue(xdesc->instance, xdesc->active_tmr, new_val);
|
||||
XTmrCtr_Reset(xdesc->instance, xdesc->active_tmr);
|
||||
break;
|
||||
#endif
|
||||
return -1;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the timer clock frequency.
|
||||
* @param [in] desc - Pointer to the device handler.
|
||||
* @param [in] freq_hz - New timer frequency in hertz.
|
||||
* @return 0 in case of success, -1 otherwise
|
||||
*/
|
||||
int32_t xilinx_timer_count_clk_set(struct timer_desc *desc,
|
||||
uint32_t freq_hz)
|
||||
{
|
||||
struct xil_timer_desc *xdesc;
|
||||
|
||||
if (!desc || !freq_hz)
|
||||
return -1;
|
||||
|
||||
xdesc = desc->extra;
|
||||
|
||||
switch (xdesc->type) {
|
||||
case TIMER_PS:
|
||||
#ifdef XSCUTIMER_H
|
||||
;
|
||||
uint32_t prescaler = CORE_PRIVATE_TIMER_CLOCK / freq_hz;
|
||||
if (prescaler == 0 || prescaler >= 256)
|
||||
return -1;
|
||||
XScuTimer_SetPrescaler(xdesc->instance, prescaler - 1);
|
||||
desc->freq_hz = CORE_PRIVATE_TIMER_CLOCK / prescaler;
|
||||
break;
|
||||
#endif
|
||||
return -1;
|
||||
case TIMER_PL:
|
||||
#ifdef XTMRCTR_H
|
||||
(void *)xdesc;
|
||||
/** Cannot be done. */
|
||||
#endif
|
||||
return -1;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize hardware timer and the handler structure associated with
|
||||
* it.
|
||||
* @param [out] desc - Pointer to the reference of the device handler.
|
||||
* @param [in] param - Initialization structure.
|
||||
* @return 0 in case of success, -1 otherwise
|
||||
*/
|
||||
int32_t xilinx_timer_init(struct timer_desc **desc,
|
||||
const struct timer_init_param *param)
|
||||
{
|
||||
int32_t ret;
|
||||
struct timer_desc *dev;
|
||||
struct xil_timer_desc *xdesc;
|
||||
struct xil_timer_init_param *xinit;
|
||||
|
||||
if (!desc || !param)
|
||||
return -1;
|
||||
|
||||
xinit = param->extra;
|
||||
|
||||
dev = (struct timer_desc *)calloc(1, sizeof(*dev));
|
||||
if(!dev)
|
||||
return -1;
|
||||
xdesc = (struct xil_timer_desc *)calloc(1, sizeof(*xdesc));
|
||||
if(!xdesc)
|
||||
goto error_desc;
|
||||
|
||||
dev->id = param->id;
|
||||
dev->freq_hz = param->freq_hz;
|
||||
dev->ticks_count = param->ticks_count;
|
||||
dev->extra = xdesc;
|
||||
xdesc->active_tmr = xinit->active_tmr;
|
||||
xdesc->type = xinit->type;
|
||||
|
||||
switch (xdesc->type) {
|
||||
case TIMER_PS:
|
||||
#ifdef XSCUTIMER_H
|
||||
xdesc->config = XScuTimer_LookupConfig(dev->id);
|
||||
xdesc->instance = calloc(1, sizeof(XScuTimer));
|
||||
if (!xdesc->instance)
|
||||
goto error_xdesc;
|
||||
ret = XScuTimer_CfgInitialize(xdesc->instance, xdesc->config,
|
||||
((XScuTimer_Config *)xdesc->config)->BaseAddr);
|
||||
if (ret != XST_SUCCESS) {
|
||||
free(xdesc->instance);
|
||||
goto error_xdesc;
|
||||
}
|
||||
ret = xilinx_timer_count_clk_set(dev, param->freq_hz);
|
||||
if (IS_ERR_VALUE(ret))
|
||||
goto error_xdesc;
|
||||
|
||||
ret = xilinx_timer_counter_set(dev, dev->ticks_count);
|
||||
if (IS_ERR_VALUE(ret))
|
||||
goto error_xdesc;
|
||||
|
||||
XScuTimer_EnableAutoReload((XScuTimer *)xdesc->instance);
|
||||
XScuTimer_EnableInterrupt((XScuTimer *)xdesc->instance);
|
||||
break;
|
||||
#endif
|
||||
goto error_xdesc;
|
||||
case TIMER_PL:
|
||||
#ifdef XTMRCTR_H
|
||||
xdesc->instance = (XTmrCtr *)calloc(1, sizeof(XTmrCtr));
|
||||
if (!xdesc->instance)
|
||||
return -1;
|
||||
|
||||
xdesc->config = XTmrCtr_LookupConfig(dev->id);
|
||||
if (!xdesc->config) {
|
||||
free(xdesc->instance);
|
||||
goto error_desc;
|
||||
}
|
||||
XTmrCtr_CfgInitialize(xdesc->instance, xdesc->config,
|
||||
((XTmrCtr_Config *)xdesc->config)->BaseAddress);
|
||||
ret = XTmrCtr_InitHw(xdesc->instance);
|
||||
if (ret != 0) {
|
||||
free(xdesc->instance);
|
||||
goto error_desc;
|
||||
}
|
||||
dev->freq_hz = ((XTmrCtr_Config *)xdesc->config)->SysClockFreqHz;
|
||||
|
||||
ret = XTmrCtr_SelfTest(xdesc->instance, dev->id);
|
||||
if(ret != 0)
|
||||
goto error_desc;
|
||||
XTmrCtr_SetOptions(xdesc->instance, xdesc->active_tmr,
|
||||
XTC_DOWN_COUNT_OPTION | XTC_INT_MODE_OPTION |
|
||||
XTC_AUTO_RELOAD_OPTION);
|
||||
XTmrCtr_SetResetValue(xdesc->instance, xdesc->active_tmr,
|
||||
dev->ticks_count);
|
||||
break;
|
||||
#endif
|
||||
goto error_xdesc;
|
||||
default:
|
||||
goto error_xdesc;
|
||||
}
|
||||
|
||||
*desc = dev;
|
||||
|
||||
return 0;
|
||||
|
||||
error_xdesc:
|
||||
free(xdesc);
|
||||
error_desc:
|
||||
free(dev);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free the memory allocated by timer_setup().
|
||||
* @param [in] desc - Pointer to the device handler.
|
||||
* @return 0 in case of success, -1 otherwise
|
||||
*/
|
||||
int32_t xilinx_timer_remove(struct timer_desc *desc)
|
||||
{
|
||||
struct xil_timer_desc *xdesc;
|
||||
|
||||
if(!desc)
|
||||
return -1;
|
||||
|
||||
xdesc = desc->extra;
|
||||
|
||||
switch (xdesc->type) {
|
||||
case TIMER_PS:
|
||||
#ifdef XSCUTIMER_H
|
||||
XScuTimer_Stop(xdesc->instance);
|
||||
free(xdesc->instance);
|
||||
break;
|
||||
#endif
|
||||
return -1;
|
||||
case TIMER_PL:
|
||||
#ifdef XTMRCTR_H
|
||||
XTmrCtr_Stop(xdesc->instance, xdesc->active_tmr);
|
||||
break;
|
||||
#endif
|
||||
return -1;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(xdesc);
|
||||
free(desc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Start a timer.
|
||||
* @param [in] desc - Pointer to the device handler.
|
||||
* @return 0 in case of success, -1 otherwise
|
||||
*/
|
||||
int32_t xilinx_timer_start(struct timer_desc *desc)
|
||||
{
|
||||
struct xil_timer_desc *xdesc;
|
||||
|
||||
if (!desc)
|
||||
return -1;
|
||||
|
||||
xdesc = desc->extra;
|
||||
|
||||
switch (xdesc->type) {
|
||||
case TIMER_PS:
|
||||
#ifdef XSCUTIMER_H
|
||||
XScuTimer_Start(xdesc->instance);
|
||||
break;
|
||||
#endif
|
||||
return -1;
|
||||
case TIMER_PL:
|
||||
#ifdef XTMRCTR_H
|
||||
XTmrCtr_Start(xdesc->instance, xdesc->active_tmr);
|
||||
break;
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stop a timer from counting.
|
||||
* @param [in] desc - Pointer to the device handler.
|
||||
* @return 0 in case of success, -1 otherwise
|
||||
*/
|
||||
int32_t xilinx_timer_stop(struct timer_desc *desc)
|
||||
{
|
||||
struct xil_timer_desc *xdesc;
|
||||
|
||||
if (!desc)
|
||||
return -1;
|
||||
|
||||
xdesc = desc->extra;
|
||||
|
||||
switch (xdesc->type) {
|
||||
case TIMER_PS:
|
||||
#ifdef XSCUTIMER_H
|
||||
XScuTimer_Stop(xdesc->instance);
|
||||
break;
|
||||
#endif
|
||||
return -1;
|
||||
case TIMER_PL:
|
||||
#ifdef XTMRCTR_H
|
||||
XTmrCtr_Stop(xdesc->instance, xdesc->active_tmr);
|
||||
break;
|
||||
#endif
|
||||
return -1;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the current counter value of the timer.
|
||||
* @param [in] desc - Pointer to the device handler.
|
||||
* @param [out] counter - Pointer to the current counter value.
|
||||
* @return 0 in case of success, -1 otherwise
|
||||
*/
|
||||
int32_t xilinx_timer_counter_get(struct timer_desc *desc,
|
||||
uint32_t *counter)
|
||||
{
|
||||
struct xil_timer_desc *xdesc;
|
||||
|
||||
if (!desc || !counter)
|
||||
return -1;
|
||||
|
||||
xdesc = desc->extra;
|
||||
|
||||
switch (xdesc->type) {
|
||||
case TIMER_PS:
|
||||
#ifdef XSCUTIMER_H
|
||||
*counter = XScuTimer_GetCounterValue((XScuTimer *)xdesc->instance);
|
||||
++(*counter);
|
||||
break;
|
||||
#endif
|
||||
return -1;
|
||||
case TIMER_PL:
|
||||
#ifdef XTMRCTR_H
|
||||
*counter = XTmrCtr_GetValue(xdesc->instance, xdesc->active_tmr);
|
||||
break;
|
||||
#endif
|
||||
return -1;
|
||||
default:
|
||||
*counter = 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get the timer clock frequency.
|
||||
* @param [in] desc - Pointer to the device handler.
|
||||
* @param [out] freq_hz - Pointer to the returned frequency.
|
||||
* @return 0 in case of success, -1 otherwise
|
||||
*/
|
||||
int32_t xilinx_timer_count_clk_get(struct timer_desc *desc,
|
||||
uint32_t *freq_hz)
|
||||
{
|
||||
struct xil_timer_desc *xdesc;
|
||||
|
||||
if (!desc || !freq_hz)
|
||||
return -1;
|
||||
|
||||
xdesc = desc->extra;
|
||||
|
||||
switch (xdesc->type) {
|
||||
case TIMER_PS:
|
||||
#ifdef XSCUTIMER_H
|
||||
*freq_hz = desc->freq_hz;
|
||||
break;
|
||||
#endif
|
||||
return -1;
|
||||
case TIMER_PL:
|
||||
#ifdef XTMRCTR_H
|
||||
*freq_hz = ((XTmrCtr_Config *)xdesc->config)->SysClockFreqHz;
|
||||
break;
|
||||
#endif
|
||||
return -1;
|
||||
default:
|
||||
*freq_hz = 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get the elapsed time in nsec for the timer.
|
||||
* @param [in] desc - Pointer to the device handler.
|
||||
* @param [in] elapsed_time - The elapsed time in nsec.
|
||||
* @return -ENOSYS.
|
||||
*/
|
||||
int32_t xilinx_timer_get_elapsed_time_nsec(struct timer_desc *desc,
|
||||
uint64_t *elapsed_time)
|
||||
{
|
||||
/* Function not implemented */
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Xilinx platform specific timer platform ops structure
|
||||
*/
|
||||
const struct timer_platform_ops xil_timer_ops = {
|
||||
.init = &xilinx_timer_init,
|
||||
.start = &xilinx_timer_start,
|
||||
.stop = &xilinx_timer_stop,
|
||||
.counter_get = &xilinx_timer_counter_get,
|
||||
.counter_set = &xilinx_timer_counter_set,
|
||||
.count_clk_get = &xilinx_timer_count_clk_get,
|
||||
.count_clk_set = &xilinx_timer_count_clk_set,
|
||||
.get_elapsed_time_nsec = &xilinx_timer_get_elapsed_time_nsec,
|
||||
.remove = &xilinx_timer_remove
|
||||
};
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
/***************************************************************************//**
|
||||
* @file xilinx_timer.h
|
||||
* @brief Timer control module header.
|
||||
* @author Andrei Drimbarean (andrei.drimbarean@analog.com)
|
||||
********************************************************************************
|
||||
* 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 XILINX_TIMER_H_
|
||||
#define XILINX_TIMER_H_
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#include <xparameters.h>
|
||||
#ifdef XPAR_XSCUTIMER_NUM_INSTANCES
|
||||
#include <xscutimer.h>
|
||||
#endif
|
||||
#ifdef XPAR_XTMRCTR_NUM_INSTANCES
|
||||
#include <xtmrctr.h>
|
||||
#endif
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Types Declarations *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @enum xil_timer_type
|
||||
* @brief Xilinx platform architecture sections
|
||||
*/
|
||||
enum xil_timer_type {
|
||||
/** Programmable Logic */
|
||||
TIMER_PL,
|
||||
/** Processing System */
|
||||
TIMER_PS
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct xil_timer_desc
|
||||
* @brief Xilinx specific timer descriptor
|
||||
*/
|
||||
struct xil_timer_desc {
|
||||
/** Pointer to the BSP driver handler */
|
||||
void *instance;
|
||||
/** Pointer to the BSP driver configuration handler */
|
||||
void *config;
|
||||
/** Timer used from the PL 3-timer core */
|
||||
uint8_t active_tmr;
|
||||
/** Platform selection parameter */
|
||||
enum xil_timer_type type;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct xil_timer_init_param
|
||||
* @brief Xilinx specific timer initialization structure
|
||||
*/
|
||||
struct xil_timer_init_param {
|
||||
/** Timer used from the PL 3-timer core */
|
||||
uint8_t active_tmr;
|
||||
/** Platform selection parameter */
|
||||
enum xil_timer_type type;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Xilinx platform specific timer platform ops structure
|
||||
*/
|
||||
extern const struct timer_platform_ops xil_timer_ops;
|
||||
|
||||
#endif /* XILINX_TIMER_H_ */
|
||||
+7475
File diff suppressed because it is too large
Load Diff
+3568
File diff suppressed because it is too large
Load Diff
+2157
File diff suppressed because it is too large
Load Diff
+552
@@ -0,0 +1,552 @@
|
||||
/***************************************************************************//**
|
||||
* @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
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
|
||||
/***************************************************************************//**
|
||||
* @file ad9361_conv.c
|
||||
* @brief Implementation of AD9361 Conv Driver.
|
||||
********************************************************************************
|
||||
* Copyright 2014-2015(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** Include Files **********************************/
|
||||
/******************************************************************************/
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include "ad9361.h"
|
||||
#include "ad9361_util.h"
|
||||
#include "delay.h"
|
||||
#include "../../../config/app_config.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** Macros and Constants Definitions **********************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* HDL loopback enable/disable.
|
||||
* @param phy The AD9361 state structure.
|
||||
* @param enable Enable/disable option.
|
||||
* @return 0 in case of success, negative error code otherwise.
|
||||
*/
|
||||
int32_t ad9361_hdl_loopback(struct ad9361_rf_phy *phy, bool enable)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/**
|
||||
* Digital tune.
|
||||
* @param phy The AD9361 state structure.
|
||||
* @param max_freq Maximum frequency.
|
||||
* @param flags Flags: BE_VERBOSE, BE_MOREVERBOSE, DO_IDELAY, DO_ODELAY.
|
||||
* @return 0 in case of success, negative error code otherwise.
|
||||
*/
|
||||
int32_t ad9361_dig_tune(struct ad9361_rf_phy *phy, uint32_t max_freq,
|
||||
enum dig_tune_flags flags)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the AD9361 device.
|
||||
* @param phy The AD9361 state structure.
|
||||
* @return 0 in case of success, negative error code otherwise.
|
||||
*/
|
||||
int32_t ad9361_post_setup(struct ad9361_rf_phy *phy)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
+335
@@ -0,0 +1,335 @@
|
||||
/***************************************************************************//**
|
||||
* @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;
|
||||
}
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
/***************************************************************************//**
|
||||
* @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
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
/***************************************************************************//**
|
||||
* @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_
|
||||
+151
@@ -0,0 +1,151 @@
|
||||
/***************************************************************************//**
|
||||
* @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;
|
||||
}
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
/***************************************************************************//**
|
||||
* @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
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user