前言
射频模块完成之后,就是基带处理板的工作了,最初提到我买了一块微相科技的Z7-lite开发板,ZYNQ7020处理器。我用它实现了MAX2769功能的验证,但是当我用它跑软件的时候,发现PL部分根本无法工作,连自带的hello world都跑不起来,无奈只能放弃。于是我又在在某鱼上看到了绿宝石XAVIER核心板拆机件,只需要一两百块,可以说性价比极高,赠送了引脚说明和底板的参考设计资料。于是我把MAX2769也做到了底板上,这样就构成了一个双层结构的接收机。
ZYNQ7020简介
ZYNQ7020 核心板主控芯片采用 Xilinx 公司的 ZYNQ7000 系列的 XC7Z020 ,具体型号为
XC7Z020CLG400-2 。 ZYNQ 分为 PS ( Processing System )和 PL ( Programmable Logic )两部分。 PL 部分拥有 85K 个逻辑单元、 4.9Mbits 的嵌入式存储资源、 220 个 DSP 单元、
4 个时钟管理单元( CMT )、 16 个全局时钟网络、 6 个用户 I/O BANK 和最大 253 个用户 I/O ,是一款非常具有性价比的芯片。
XC7Z020 集成了两个 Cortex-A9 处理器, AMBA® 互连,内部存储器,外部存储器接口 和外设。这些外设主要包括 USB 总线接口,以太网接口, SD/SDIO 接口, I2C 总线接口, CAN 总线接口, UART 接口, GPIO 等。 ZYNQ 芯片系统框图如下图
接下来就是一些必备功能的验证,我需要用到两个硬件中断,PS-PL交互,任务和队列邮箱等。
首先是PS-PL的配置,结果如下图,除了ZYNQ处理器之外,只用到了一个AXI-EMC IP,非常简洁。
ZYNQ PL-PS中断
首先验证了在裸机下的中断程序,通过串口打印中断次数计数,证明整个通路无问题。因为我要跑操作系统,还需要在freeRTOS下实现,下面直接上代码,在初始化时调用 interrupt_init()即可。
void ExtIrq_Handler0(void *InstancePtr)
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
GPS_ISR();
}
void ExtIrq_Handler1(void *InstancePtr)
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
GPS_ISR_50ms();
//xil_printf("GPS_ISR_50ms TEST!! %d\n\r",i);
}
void IntcTypeSetup(XScuGic *InstancePtr, int intId, int intType)
{
int mask;
intType &= INT_TYPE_MASK;
mask = XScuGic_DistReadReg(InstancePtr, INT_CFG0_OFFSET + (intId/16)*4);
mask &= ~(INT_TYPE_MASK << (intId%16)*2);
mask |= intType << ((intId%16)*2);
XScuGic_DistWriteReg(InstancePtr, INT_CFG0_OFFSET + (intId/16)*4, mask);
}
void interrupt_init()
{
xPortInstallInterruptHandler(XPAR_FABRIC_EXT_IRQ_INTR0, ExtIrq_Handler0, (void *)NULL);
xPortInstallInterruptHandler(XPAR_FABRIC_EXT_IRQ_INTR1, ExtIrq_Handler1, (void *)NULL);
IntcTypeSetup(&xInterruptController, XPAR_FABRIC_EXT_IRQ_INTR0, INT_TYPE_RISING_EDGE);
IntcTypeSetup(&xInterruptController, XPAR_FABRIC_EXT_IRQ_INTR1, INT_TYPE_RISING_EDGE);
vPortEnableInterrupt(XPAR_FABRIC_EXT_IRQ_INTR0);
vPortEnableInterrupt(XPAR_FABRIC_EXT_IRQ_INTR1);
}
最初看资料说,需要中断提供一个信号量,传递给任务,在任务里实现具体功能;测试发现,中断函数无法被及时响应,直接调用使问题得到解决。
AXI-EMC PL-PS交互
发现ZYNQ支持EMIF方式进行PL与PS数据交互,因为之前的资料中DSP与FPGA就是这种方式,所以移植过来非常方便。
AXI-EMC IP设置
(1)位宽设置为 32bit 其他参数默认,其中 Base Address 和 High Address 是 AXI_EMC IP 在 ZYNQ 4GB 地址空间中的分配的地址
(2)设置 Memory Type 为 Async SRAM , 也就是异步 SRAM 。这种 SRAM 读写起来比较方便。位宽设置为 32bit 。 Timing Parameters 是 AXI 系统时钟为 100M 的情况下的时间参数,如果采用其他时钟可能要修改时间参数。
读写方式也可以一致,这一点减少了很多工作量,只需要把基地址改一下就可以了。
//启动C码捕获模块
*(vu32 *)(C_Acq_Start_Addr) = 0x01;
//读取捕获结果地址
temp = *(vu32 *)(C_Acq_Result_Addr);
总结
中断和 交互是我认为的两个最重要的基本功能,跑通了之后就可以开始具体的工作了。下一篇讲一下用这个板子实现捕获的过程。