zynq中PS访问BRAM(二)

  • 2019 年 11 月 5 日
  • 筆記

前情回顾

(1)ZYNQ中PS端MIO操作 (2)ZYNQ中PS端MIO中断 (3)ZYNQ中PS端UART通信

(4)ZYNQ中PS端XADC读取

(5)Zynq中PL读写PS端DDR数据

(6)zynq中PS访问BRAM(一)

PS端程序设计流程为:

  • 输入起始地址和长度
  • PS端通过BRAM控制器写入BRAM数据
  • 通知PL端控制器读取BRAM数据
  • PL内部读完后向相同位置写入数据,初始数据由PS端确定:

函数里先通过BRAM控制器写入数据,数据初值为TEST初值,之后配置PLRAM控制器参数,有长度,起始地址,初始数据,以及开始信号。

  • 写完后使能write_end信号,触发GPIO中断
  • 中断读取BRAM数据,打印显示

主循环如下:

while(1)

{

if (Gpio_flag)//如果完成,则进行下一次循环读写

{

Gpio_flag= 0 ;

printf("Please provide start addresstn") ;

scanf("%d", &Start_Addr) ;

printf("Start address is %dtn", Start_Addr) ;

printf("Please provide lengthtn") ;

scanf("%d", &Len) ;

printf("Length is %dtn", Len) ;

Status= bram_read_write() ;

if (Status != XST_SUCCESS)

{

Gpio_flag = 1 ;

}

}

}

控制BRAM读写如下:

int bram_read_write()

{

u32 Write_Data = TEST_START_VAL ;//确定PL写的初值

int i ;

//判断是否越界

if ((Start_Addr + Len) > (BRAM_CTRL_HIGH -BRAM_CTRL_BASE + 1)/4)

{

xil_printf("******************************************rn");

xil_printf("Error! Exceed Bram ControlAddress Range!rn");

return XST_FAILURE ;

}

//给BRAM中写数据

for(i = BRAM_BYTENUM*Start_Addr ; i <BRAM_BYTENUM*(Start_Addr + Len) ; i += BRAM_BYTENUM)

{

XBram_WriteReg(XPAR_BRAM_0_BASEADDR, i ,Write_Data) ;

Write_Data+= 1 ;

}

//设置BRAM的读长度和读地址

PL_RAM_CTRL_mWriteReg(PL_RAM_BASE,PL_RAM_LEN , BRAM_BYTENUM*Len) ;

PL_RAM_CTRL_mWriteReg(PL_RAM_BASE,PL_RAM_ST_ADDR , BRAM_BYTENUM*Start_Addr) ;

//设置PL初始写数据地址

PL_RAM_CTRL_mWriteReg(PL_RAM_BASE,PL_RAM_INIT_DATA , (Start_Addr+1)) ;

//设置PL读RAM开始

PL_RAM_CTRL_mWriteReg(PL_RAM_BASE,PL_RAM_START , 1) ;

return XST_SUCCESS ;

}

首先是PL控制器从BRAM读数据,之后是写数据,可以看到红色为PL读出的BRAM数据,正是CPU写入的数据,从12开始,共10个数据,PL写入的数据为黄色部分从1开始,共10个数据。

中断处理,打印出读RAM的数据

void GpioHandler(void *CallbackRef)

{

XGpio *GpioInstancePtr = (XGpio *)CallbackRef ;

int Read_Data ;

int i ;

printf("Enter interrupttn");

//clear interrupt status

XGpio_InterruptClear(GpioInstancePtr,GPIO_INTR_MASK) ;

for(i = BRAM_BYTENUM*Start_Addr ; i < BRAM_BYTENUM*(Start_Addr+ Len) ; i += BRAM_BYTENUM)

{

Read_Data= XBram_ReadReg(XPAR_BRAM_0_BASEADDR , i) ;

printf("Address is %dt Read data is %dtn", i/BRAM_BYTENUM,Read_Data) ;

}

Gpio_flag= 1 ;

}