DSP

TMS320F28335之外部接口与CPLD通信问题

2019-07-13 10:33发布

  • 系统原理
我用CPLD采集AD数据,利用XINTF接口将数据传输到DSP,CCS观察DSP地址数据。系统框图如下所示。
这里写图片描述
其中28335的XINTF采用16位数据总线连接。
这里写图片描述
GPIO端口设置如下 void InitGpio(void) //初始化GPIO { EALLOW; //----------------------------------------------------------------------------------- GpioCtrlRegs.GPBMUX1.all = 0xFFFFFFF0; // 配置 GPIO32-33为I/O口 // 配置 GPIO34 for XREADY 就绪 // 配置 GPIO35 for XR/W 读 // 配置 GPIO36 for XZCS0 片选 // 配置 GPIO37 for XZCS7 片选 // 配置 GPIO38 for XWE0 写 // 配置 GPIO39 for XA16 地址 // 配置 GPIO40 for XA0 // 配置 GPIO41 for XA1 // 配置 GPIO42 for XA2 // 配置 GPIO43 for XA3 // 配置 GPIO44 for XA4 // 配置 GPIO45 for XA5 // 配置 GPIO46 for XA6 // 配置 GPIO47 for XA7 GpioCtrlRegs.GPCMUX1.all = 0xFFFFFFFF; // 配置 GPIO64-GPIO79 for XD15-XD0 数据 GpioCtrlRegs.GPCMUX2.all = 0xFFFFFFFF; // 配置 GPIO80-GPIO87 for XA8-XA15 地址 // GpioCtrlRegs.GPBDIR.all = 0xE0000000; // GPIO32-GPIO60 为输入 GpioCtrlRegs.GPCDIR.all = 0x00000000; // GPI064-GPIO95 为输入 //---------------------------------------------------------------------------------------- GpioCtrlRegs.GPAPUD.all = 0x0100; // 内部上拉 GPIO0-GPIO31 GpioCtrlRegs.GPBPUD.all = 0x0000; // 内部上拉 GPIO32-GPIO63 GpioCtrlRegs.GPCPUD.all = 0x0000; // 内部上拉 GPIO64-GPIO79 EDIS; } XINTF访问区域0地址 void InitXintf(void) { // 这显示了如何写XINTF寄存器。 // 这里使用了重置后的默认状态值。 // 不同的硬件需要不同的配置。 // 为INTF配置一个例子,在如下目录 // F28335 eZdsp, refer to the examples/run_from_xintf project. // 任何更改XINTF配置只能从XINTF扩展之外的区域运行代码。 // 所有区域--------------------------------- // 所有区域的基准时间时钟为 XTIMCLK = 1/2 SYSCLKOUT EALLOW; SysCtrlRegs.PCLKCR3.bit.XINTFENCLK = 1; //开启XINTF时钟信号 XintfRegs.XINTCNF2.bit.XTIMCLK = 1; //基准时钟XTIMCLK = 1/2 SYSCLKOUT XintfRegs.XINTCNF2.bit.WRBUFF = 0; //无写缓冲寄存器 XintfRegs.XINTCNF2.bit.CLKOFF = 1; //禁止XCLKOUT XintfRegs.XINTCNF2.bit.CLKMODE = 1; //XCLKOUT=XTIMCLK/2 XintfRegs.XTIMING0.bit.XWRLEAD = 2; //区域0写建立时间为11b,周期数为6 XintfRegs.XTIMING0.bit.XWRACTIVE = 5; //有效时间为111b,周期数为14 XintfRegs.XTIMING0.bit.XWRTRAIL = 2; //跟踪时间为11b,周期数为6 // Zone read timing XintfRegs.XTIMING0.bit.XRDLEAD = 2; //区域0读建立时间为11b,周期数为6 XintfRegs.XTIMING0.bit.XRDACTIVE = 5; //有效时间为111b,周期数为14 XintfRegs.XTIMING0.bit.XRDTRAIL = 2; //跟踪时间为11b,周期数为6 // double all Zone read/write lead/active/trail timing XintfRegs.XTIMING0.bit.X2TIMING = 1; //比值2:1 // Zone will sample XREADY signal XintfRegs.XTIMING0.bit.USEREADY = 0; //XREADY信号采样 XintfRegs.XTIMING0.bit.READYMODE = 1; //异步采样 XintfRegs.XTIMING0.bit.XSIZE = 3; //数据总线宽度,16位 EDIS; } CPLD与AD芯片之间采样时序如下
这里写图片描述
  • 问题
    从DSP外部中断1的中断函数内,读取CPLD地址数据,发现8路ADC数据错乱,给AD通道1电平变化,其他相邻地址位也出现数据变化,相互串扰。其中测试确保程序进入了外部中断函数中。
#define FPGA_BASE_ADDR 0X4000 //区域0起始地址 #define HSAD_OUT_CUR_A1 (*(volatile int16 *)(FPGA_BASE_ADDR + 0x0004)) //HSAD采样 #define HSAD_OUT_CUR_B1 (*(volatile int16 *)(FPGA_BASE_ADDR + 0x0005)) //HSAD采样电流 #define HSAD_OUT_CUR_A2 (*(volatile int16 *)(FPGA_BASE_ADDR + 0x0006)) //HSAD采样电流 #define HSAD_OUT_CUR_B2 (*(volatile int16 *)(FPGA_BASE_ADDR + 0x0007)) //HSAD采样电流 #define HSAD_OUT_CUR_A3 (*(volatile int16 *)(FPGA_BASE_ADDR + 0x0008)) //HSAD采样电流 #define HSAD_OUT_CUR_B3 (*(volatile int16 *)(FPGA_BASE_ADDR + 0x0009)) //HSAD采样电流 #define HSAD_OUT_CUR_A4 (*(volatile int16 *)(FPGA_BASE_ADDR + 0x000A)) //HSAD采样电流 #define HSAD_OUT_CUR_A5 (*(volatile int16 *)(FPGA_BASE_ADDR + 0x000B)) //HSAD采样电流 interrupt void XINT1_ISR(void) { // ISR代码插入这里 outCurADeal_pSt[0].in_I16 = HSAD_OUT_CUR_A1; //1_A相电流 outCurBDeal_pSt[0].in_I16 = HSAD_OUT_CUR_B1; //1_B相电流 outCurADeal_pSt[1].in_I16 = HSAD_OUT_CUR_A2; //2_A相电流 outCurBDeal_pSt[1].in_I16 = HSAD_OUT_CUR_B2; //2_B相电流 outCurADeal_pSt[2].in_I16 = HSAD_OUT_CUR_A3; //3_A相电流 outCurBDeal_pSt[2].in_I16 = HSAD_OUT_CUR_B3; //3_B相电流 outCurADeal_pSt[3].in_I16 = HSAD_OUT_CUR_A4; //1_A相电流 outCurADeal_pSt[4].in_I16 = HSAD_OUT_CUR_A5; //2_A相电流 PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; } 起初以为是CPLD与AD之间采样时序错误,造成CPLD本身地址上数据错乱,经XINTF传送后,DSP也接收到错乱数据,CPLD程序如下。 always@(posedge SYS_10M_CLK) begin cs_r[2] =(XA == BASE_AD_ZONE0 + 16'H0004) &(!rd_filter)&(!XZCS0_N); //0x04 AD1_V1 cs_r[3] =(XA == BASE_AD_ZONE0 + 16'H0005) &(!rd_filter)&(!XZCS0_N); //0x05 AD1_V2 cs_r[4] =(XA == BASE_AD_ZONE0 + 16'H0006) &(!rd_filter)&(!XZCS0_N); //0x06 AD1_V3 cs_r[5] =(XA == BASE_AD_ZONE0 + 16'H0007) &(!rd_filter)&(!XZCS0_N); //0x07 AD1_V4 cs_r[6] =(XA == BASE_AD_ZONE0 + 16'H0008) &(!rd_filter)&(!XZCS0_N); //0x08 AD1_V5 cs_r[7] =(XA == BASE_AD_ZONE0 + 16'H0009) &(!rd_filter)&(!XZCS0_N); //0x09 AD1_V6 cs_r[8] =(XA == BASE_AD_ZONE0 + 16'H000A) &(!rd_filter)&(!XZCS0_N); //0x0A AD2_V1 cs_r[9] =(XA == BASE_AD_ZONE0 + 16'H000B) &(!rd_filter)&(!XZCS0_N); //0x0B AD2_V2 end always@(posedge SYS_10M_CLK) case(cs_r) 15'b000_0000_0000_0100: begin dsp_dat_reg = ad1_dout[15:0]; end //30 AD1_V1 1_A相电流 15'b000_0000_0000_1000: begin dsp_dat_reg = ad1_dout[31:16]; end //40 AD1_V2 1_B相电流 15'b000_0000_0001_0000: begin dsp_dat_reg = ad1_dout[47:32]; end //50 AD1_V3 2_A相电流 15'b000_0000_0010_0000: begin dsp_dat_reg = ad1_dout[63:48]; end //60 AD1_V4 2_B相电流 15'b000_0000_0100_0000: begin dsp_dat_reg = ad1_dout[79:64]; end //70 AD1_V5 3_A相电流 15'b000_0000_1000_0000: begin dsp_dat_reg = ad1_dout[95:80]; end //80 AD1_V6 3_B相电流 15'b000_0001_0000_0000: begin dsp_dat_reg = ad2_dout[15:0]; end //110 AD2_V1 1_A相电流 15'b000_0010_0000_0000: begin dsp_dat_reg = ad2_dout[31:16]; end //120 AD2_V2 2_A相电流 default: begin dsp_dat_reg = dsp_dat_reg;end //数据寄存器数据保持 endcase 因CPLD程序无法调试和观察变量,我将CPLD采集程序屏蔽到只剩下一路AD采样,然后再次观察DSP地址变量数据,发现数据正确,单独测试每一路均能正确接收数据,但将多路AD采样通道开启却出现错误,再次检查CPLD与AD芯片采样时序,确保AD采样时序符合最小时序要求,发现还是出现错误。最后将CPLD采样程序屏蔽,直接在地址位上赋常量,如下所示。 always@(posedge SYS_10M_CLK) begin cs_r[2] =(XA == BASE_AD_ZONE0 + 16'H0004) &(!rd_filter)&(!XZCS0_N); //0x04 AD1_V1 cs_r[3] =(XA == BASE_AD_ZONE0 + 16'H0005) &(!rd_filter)&(!XZCS0_N); //0x05 AD1_V2 cs_r[4] =(XA == BASE_AD_ZONE0 + 16'H0006) &(!rd_filter)&(!XZCS0_N); //0x06 AD1_V3 cs_r[5] =(XA == BASE_AD_ZONE0 + 16'H0007) &(!rd_filter)&(!XZCS0_N); //0x07 AD1_V4 cs_r[6] =(XA == BASE_AD_ZONE0 + 16'H0008) &(!rd_filter)&(!XZCS0_N); //0x08 AD1_V5 cs_r[7] =(XA == BASE_AD_ZONE0 + 16'H0009) &(!rd_filter)&(!XZCS0_N); //0x09 AD1_V6 cs_r[8] =(XA == BASE_AD_ZONE0 + 16'H000A) &(!rd_filter)&(!XZCS0_N); //0x0A AD2_V1 cs_r[9] =(XA == BASE_AD_ZONE0 + 16'H000B) &(!rd_filter)&(!XZCS0_N); //0x0B AD2_V2 end always@(posedge SYS_10M_CLK) case(cs_r) 15'b000_0000_0000_0100: begin dsp_dat_reg = 30; end //30 AD1_V1 1_A相电流 15'b000_0000_0000_1000: begin dsp_dat_reg = 40; end //40 AD1_V2 1_B相电流 15'b000_0000_0001_0000: begin dsp_dat_reg = 50; end //50 AD1_V3 2_A相电流 15'b000_0000_0010_0000: begin dsp_dat_reg = 60; end //60 AD1_V4 2_B相电流 15'b000_0000_0100_0000: begin dsp_dat_reg = 70; end //70 AD1_V5 3_A相电流 15'b000_0000_1000_0000: begin dsp_dat_reg = 80; end //80 AD1_V6 3_B相电流 15'b000_0001_0000_0000: begin dsp_dat_reg = 110; end //110 AD2_V1 1_A相电流 15'b000_0010_0000_0000: begin dsp_dat_reg = 120; end //120 AD2_V2 2_A相电流 default: begin dsp_dat_reg = dsp_dat_reg;end //数据寄存器数据保持 endcase 测试发现DSP地址数据出现跳变错乱,可以判断是CPLD与DSP的xintf通信问题,当时单路测试时正确以为xintf通信已经没有问题,导致花费很多时间测试CPLD与AD之间时序。仔细观察,发现ADC通道1数据串扰到通道2地址上,并影响通道3,怀疑DSP与CPLD通信时序不匹配,DSP速度过快,CPLD速度过慢,通过改变xintf配置寄存器,将建立、有效、跟踪时间调整至最高和最低,如下。 XintfRegs.XTIMING0.bit.XWRLEAD = 1; //区域0写建立时间为1b,周期数为1 XintfRegs.XTIMING0.bit.XWRACTIVE = 1; //有效时间为1b,周期数为1 XintfRegs.XTIMING0.bit.XWRTRAIL = 1; //跟踪时间为1b,周期数为1 // Zone read timing XintfRegs.XTIMING0.bit.XRDLEAD = 1; //区域0读建立时间为1b,周期数为1 XintfRegs.XTIMING0.bit.XRDACTIVE = 1; //有效时间为1b,周期数为1 XintfRegs.XTIMING0.bit.XRDTRAIL = 1; //跟踪时间为1b,周期数为1 // double all Zone read/write lead/active/trail timing XintfRegs.XTIMING0.bit.X2TIMING = 0; //比值1:1 发现差别明显,另外通过将DSP系统时钟设置进行降频,发现数据能达到一个比较稳定状态。 //#define DSP28_DIVSEL 0 // Enable /4 for SYSCLKOUT //#define DSP28_DIVSEL 1 // Enable /4 for SYSCKOUT #define DSP28_DIVSEL 2 // Enable /2 for SYSCLKOUT //#define DSP28_DIVSEL 3 // Enable /1 for SYSCLKOUT #define DSP28_PLLCR 10 //#define DSP28_PLLCR 9 //#define DSP28_PLLCR 8 //#define DSP28_PLLCR 7 //#define DSP28_PLLCR 6 //#define DSP28_PLLCR 5 //#define DSP28_PLLCR 4 //#define DSP28_PLLCR 3 //#define DSP28_PLLCR 2 //#define DSP28_PLLCR 1 //#define DSP28_PLLCR 0 // PPL旁路 void InitSysCtrl(void) //初始化系统控制 { DisableDog(); //关闭看门狗 InitPll(DSP28_PLLCR,DSP28_DIVSEL); //初始化PLL控制 InitPeripheralClocks(); //初始化外设时钟 } 最后发现DSP晶振为30Mhz,CPLD晶振为10Mhz,导致CPLD数据线上数据变化过慢,当DSP地址改变时,CPLD数据线上的数据还是前一位数据,造成数据延迟,串扰到第一位地址。尝试将xintf接口速度减慢,CPLD芯片无PLL,采用上下沿触发,软件倍频,还是达不到匹配状态。最后只得将CPLD晶振替换为30MHz才正确匹配。