ADC09QJ1300的CLK给了100M时钟,SYSREF给了7.8125M,FPGA的GLBLCLK及REFCLK均为125M,SYSREF为7.8125M。
在使用ADC的测试模式时,JESD204BIP核中的输出信号为乱码。
ARM软核的配置代码在附件中,请麻烦帮忙检查一下是否有问题。
#include "xparameters.h"
#include "sleep.h"
#include "xgpio.h"
#include "xil_io.h"
#include "xil_types.h"
//#include <stdio.h>
//#include <stdlib.h>
/* // spi的地址和数据
6'h00: rdata = { 31'b0 , spi_busy };
6'h01: rdata = { 8'b0 , spi_wr_data };
6'h02: rdata = { 24'b0 , spi_rd_data };
*/
XGpio LMK_CFG;
#define LMK_BASE_ADDR 0x44A10000
#define ADC_BASE_ADDR 0x44A00000
#define R_JESD_BADDR 0x44A20000
u32 LMK_DATA[136] = {
0x000090, 0x000010, 0x000200, 0x000306, 0x0004D0, 0x00055B, 0x000600, 0x000C51,
0x000D04, 0x01001E, 0x010155, 0x010255, 0x010300, 0x010422, 0x010500, 0x0106F0,
0x010755, 0x01081E, 0x010955, 0x010A55, 0x010B00, 0x010C22, 0x010D00, 0x010EF0,
0x010F55, 0x011018, 0x011155, 0x011255, 0x011300, 0x011402, 0x011500, 0x0116F1,
0x011705, 0x011818, 0x011955, 0x011A55, 0x011B00, 0x011C02, 0x011D00, 0x011EF1,
0x011F05, 0x01200C, 0x012155, 0x012255, 0x012300, 0x012402, 0x012500, 0x0126F1,
0x012705, 0x01280C, 0x012955, 0x012A55, 0x012B00, 0x012C02, 0x012D00, 0x012EF1,
0x012F05, 0x013006, 0x013155, 0x013255, 0x013300, 0x013422, 0x013500, 0x0136F0,
0x013750, 0x013825, 0x013903, 0x013A01, 0x013B80, 0x013C00, 0x013D08, 0x013E00,
0x013F02, 0x014081, 0x014100, 0x014200, 0x014310, 0x0144FF, 0x01457F, 0x014619,
0x014713, 0x014802, 0x014942, 0x014A33, 0x014B16, 0x014C00, 0x014D00, 0x014EC0,
0x014F7F, 0x015003, 0x015102, 0x015200, 0x015300, 0x015473, 0x015500, 0x01560A,
0x015700, 0x015896, 0x015900, 0x015A01, 0x015BD4, 0x015C20, 0x015D00, 0x015E00,
0x015F0B, 0x016000, 0x016105, 0x016244, 0x016300, 0x016400, 0x01650C, 0x0171AA,
0x017202, 0x017C15, 0x017D33, 0x016600, 0x016700, 0x016896, 0x016959, 0x016A20,
0x016B00, 0x016C00, 0x016D00, 0x016E13, 0x017300, 0x018200, 0x018300, 0x018400,
0x018500, 0x018800, 0x018900, 0x018A00, 0x018B00, 0x1FFD00, 0x1FFE00, 0x1FFF53
};
u32 DAC_CFG_DATA[102] = {
0x000018, 0x010003, 0x022002, 0x03A300, 0x040000, 0x05FF03, 0x06FFFF, 0x073100,
0x080000, 0x090000, 0x0A0000, 0x0B0000, 0x0C0400, 0x0D0400, 0x0E0400, 0x0F0400,
0x100000, 0x110000, 0x120000, 0x130000, 0x140000, 0x150000, 0x160000, 0x170000,
0x180000, 0x190000, 0x1A0020, 0x1B0000, 0x1E9999, 0x1F9980, 0x208008, 0x221B1B,
0x2301FF, 0x240020, 0x252000, 0x260000, 0x2D0001, 0x2EFFFF, 0x2F0004, 0x300000,
0x311000, 0x320000, 0x330000, 0x340000, 0x3B0800, 0x3C0028, 0x3D0088, 0x3E0108,
0x3F0000, 0x461882, 0x4701C8, 0x483143, 0x490000, 0x4AFF01, 0x4B1200, 0x4C1307,
0x4D0300, 0x4E0F4F, 0x4F1C61, 0x500000, 0x5100DC, 0x5200FF, 0x530000, 0x5400FC,
0x5500FF, 0x560000, 0x5700FF, 0x5800FF, 0x590000, 0x5A00FF, 0x5B00FF, 0x5C1133,
0x5E0000, 0x5F3210, 0x605764, 0x610211, 0x640001, 0x650001, 0x660001, 0x670001,
0x687709, 0x690000, 0x6A0000, 0x6BBD07, 0x6C0007, 0x6D0090, 0x6E0000, 0x6F0000,
0x700000, 0x710000, 0x720000, 0x730000, 0x740000, 0x750000, 0x760000, 0x770000,
0x780000, 0x790000, 0x7A0000, 0x7B0000, 0x7C0000, 0x7D0000
};
u32 Xil_SPI( u32 spi_addr, u32 dev_raddr){
u32 rd_state = 0;
u32 rd_data = 0;
Xil_Out32(spi_addr + 0x04 , dev_raddr); //写入读取数据的命令
do{
rd_state = Xil_In32(spi_addr + 0x0); //读取忙状态
}while(rd_state == 0x1);
rd_data = Xil_In32(spi_addr + 0x8); //读取读出数据
//usleep(1);
return rd_data;
}
int DAC_INIT(void){
}
int ADC_INIT(void){
u32 Xil_Rdata = 0;
Xil_Rdata = Xil_SPI(ADC_BASE_ADDR , 0x800C00); //读取FPGAVID
Xil_SPI(ADC_BASE_ADDR , 0x0000B0); //AD芯片复位,等待750ns,地址0x00,默认数据0x30
usleep(1000);
//do{ Xil_Rdata = Xil_SPI(ADC_BASE_ADDR , 0x820800); }while(Xil_Rdata == 0x0); //读取cpll锁定状态
do{ Xil_Rdata = Xil_SPI(ADC_BASE_ADDR , 0x827000); }while(Xil_Rdata == 0x0); //读取init状态,直到返回1,在继续
//Xil_SPI(ADC_BASE_ADDR , 0x002B05); //设置参考时钟消抖
Xil_SPI(ADC_BASE_ADDR , 0x002A03);
Xil_SPI(ADC_BASE_ADDR , 0x0029B0);
Xil_SPI(ADC_BASE_ADDR , 0x003F4A); //向vco_bias中写入0x4a来设置vco的偏置
Xil_SPI(ADC_BASE_ADDR , 0x005881); //调整调整PLL输入管脚设置为管脚模式或者SPI模式,以及输入模式设置。
Xil_SPI(ADC_BASE_ADDR , 0x005C01); //编程cpll_reset置1到复位以继续cpll编程
//Xil_Rdata = Xil_SPI(ADC_BASE_ADDR , 0x803F00);
Xil_SPI(ADC_BASE_ADDR , 0x003D05); //设置pll_p_div,pll_v_div,目前要求是1000M,根据手册可知,需要的p*v=8,在这里设置成p=2,v=4
Xil_SPI(ADC_BASE_ADDR , 0x003E0A); //设置pll_n_div 公式为:采样率 = N * Fref,因为在SE_CLK口输入的频率为100MHZ,则需要写入十进制的10,即16进制的0A,达到1000M频率 //***********************************
Xil_SPI(ADC_BASE_ADDR , 0x005D41); //设置vco_cal_en到1以启动vco校准
Xil_SPI(ADC_BASE_ADDR , 0x005C00); //设置将cpll设置到0以校准和启动vco及启动cpll
Xil_SPI(ADC_BASE_ADDR , 0x005781); //TRIGOUT输出控制
Xil_SPI(ADC_BASE_ADDR , 0x002B15);
usleep(1000);
do{ Xil_Rdata = Xil_SPI(ADC_BASE_ADDR , 0x805E00); }while(Xil_Rdata == 0x0); //读取vco校准状态直到校准完成
//GET_BIT();
//do{ Xil_Rdata = Xil_SPI(ADC_BASE_ADDR , 0x820800); }while(Xil_Rdata == 0x0); //读取CPLL校准状态直到校准完成(读到1)
do{ Xil_Rdata = Xil_SPI(ADC_BASE_ADDR , 0x820800); }while((Xil_Rdata << 31) != 0x80000000); //读取CPLL校准状态直到校准完成(读到1)
Xil_SPI(ADC_BASE_ADDR , 0x020000); //关闭JESD204接口的状态机,以允许更改设置
Xil_SPI(ADC_BASE_ADDR , 0x006100); //关闭校准状态机以允许设置
//Xil_SPI(ADC_BASE_ADDR , 0x003746); //设置低功率模式1寄存器,设置1G及以内的低功率
//Xil_SPI(ADC_BASE_ADDR , 0x029A06); //设置低功率模式2寄存器,设置1G及以内的低功率
//Xil_SPI(ADC_BASE_ADDR , 0x029B00); //设置低功率模式3寄存器,设置1G及以内的低功率
//Xil_SPI(ADC_BASE_ADDR , 0x029C14); //设置低功率模式4寄存器,设置1G及以内的低功率
Xil_SPI(ADC_BASE_ADDR , 0x020109); //设置JMODE,选定的输出模式为JMODE1
Xil_SPI(ADC_BASE_ADDR , 0x02021f); //设置KM1寄存器,目前的值为默认的十进制的31,即十六进制的1F
Xil_SPI(ADC_BASE_ADDR , 0x020401); //选择同步信号是单端还是查分输入,此处选择默认单端
Xil_SPI(ADC_BASE_ADDR , 0x020505);
//Xil_SPI(ADC_BASE_ADDR , 0x006201); //设置默认前景校准
//Xil_SPI(ADC_BASE_ADDR , 0x006501); //设置默认偏移参考值
//Xil_SPI(ADC_BASE_ADDR , 0x005781); //TRIGOUT输出控制
Xil_SPI(ADC_BASE_ADDR , 0x02130f); //启动超量程显示
Xil_SPI(ADC_BASE_ADDR , 0x006101); //启动校准状态机
Xil_SPI(ADC_BASE_ADDR , 0x020001); //启动jesd204的状态机
Xil_SPI(ADC_BASE_ADDR , 0x006C00); //拉低启动前景校准器的命令
Xil_SPI(ADC_BASE_ADDR , 0x006C01); //拉高启动前景校准器的命令
do{ Xil_Rdata = Xil_SPI(ADC_BASE_ADDR , 0x806A00); }while(Xil_Rdata == 0x0); //读取前景校准状态直到校准完成
return 0;
}
int RD_JESD_INIT(void){
u32 Xil_Rdata = 0;
Xil_Out32(R_JESD_BADDR + 0x08 , 0x01); //启动ILA
Xil_Out32(R_JESD_BADDR + 0x0C , 0x00); //不加扰码
Xil_Out32(R_JESD_BADDR + 0x10 , 0x01); //掉链后自动重连
Xil_Out32(R_JESD_BADDR + 0x18 , 0x00); //测试模式选择普通模式
Xil_Out32(R_JESD_BADDR + 0x20 , 0x00); //设置F = 1
Xil_Out32(R_JESD_BADDR + 0x24 , 0x1f); //设置K =32
Xil_Out32(R_JESD_BADDR + 0x28 , 0xff); //设置全通道启动
Xil_Out32(R_JESD_BADDR + 0x2C , 0x01); //设置子类1
//Xil_Out32(R_JESD_BADDR + 0x2C , 0x00); //设置子类0
Xil_Out32(R_JESD_BADDR + 0x30 , 0xfff); //设置RX缓冲延时
Xil_Out32(R_JESD_BADDR + 0x34 , 0x00); //关闭错误计数,启动sync报错
Xil_Out32(R_JESD_BADDR + 0x04 , 0x00010001); //启动复位信号
do{ Xil_Rdata = Xil_In32(R_JESD_BADDR + 0x04); }while( Xil_Rdata != 0x00010000 );//等待RX的reset拉低(reset完成)
do{ Xil_Rdata = Xil_In32(R_JESD_BADDR + 0x38); }while( Xil_Rdata != 0x00010001 );//等待RX获得sync和连接
/*
while(1){
usleep(1);
//Xil_Rdata = Xil_In32(R_JESD_BADDR + 0x04); //复位状态
Xil_Rdata = Xil_In32(R_JESD_BADDR + 0x38); //sync状态
Xil_Rdata = Xil_In32(R_JESD_BADDR + 0x1C); //链接错误报警
//Xil_Rdata = Xil_In32(R_JESD_BADDR + 0x30);
Xil_Rdata = Xil_In32(R_JESD_BADDR + 0x34); //错误报告
Xil_Rdata = Xil_In32(R_JESD_BADDR + 0x824);
}
*/
return 0;
}
int LMK_INIT(void){
int status;
u32 Xil_Rdata = 0;
/*
do{ status = XGpio_Initialize(&LMK_CFG , XPAR_GPIO_0_DEVICE_ID ); }while( status != 0 ); //设置使能初始化
XGpio_DiscreteWrite(&LMK_CFG, 1, 0x0);
usleep(500);
XGpio_DiscreteWrite(&LMK_CFG, 1, 0x1);
usleep(1000);*/
do{ status = XGpio_Initialize(&LMK_CFG , XPAR_GPIO_0_DEVICE_ID ); }while( status != 0 ); //设置使能初始化
XGpio_DiscreteWrite(&LMK_CFG, 1, 0x1);
Xil_SPI(LMK_BASE_ADDR , 0x000090);
usleep(1000);
Xil_SPI(LMK_BASE_ADDR , 0x000010);
usleep(1000);
XGpio_DiscreteWrite(&LMK_CFG, 1, 0x0);
Xil_SPI(LMK_BASE_ADDR , 0x014A33);
usleep(1000);
Xil_Rdata = Xil_SPI(LMK_BASE_ADDR , 0x800400); //读取PROD ID MSB
Xil_Rdata = Xil_SPI(LMK_BASE_ADDR , 0x800500); //读取PROD ID LSB
int i = 0;
for( i = 2; i <= 136; i++){
Xil_SPI(LMK_BASE_ADDR , LMK_DATA[i]);
usleep(1);
}
return 0;
}
int main(void) {
//u32 Xil_Rdata = 0;
usleep(1000);
LMK_INIT();
usleep(1000);
ADC_INIT();
RD_JESD_INIT();
return 0;
}