Menu Close

基于课程1,Zynq添加ps spi flash

前面我们基于Zynq实现了最基本的串口打印hello world功能,这一篇文章我们会基于hello world的基础上实现PS端SPI Flash的功能。

完成功能:Zynq单板配置SPI Flash并且进行SPI Flash验证。

实验平台:智芯融的BM7030开发板,其他开发板操作类似。

核心芯片:Xilinx Xc7z030-2ffg676I

实验步骤:Zynq配置SPI的Flash 芯片,并进行初始化。

SPI协议概述

串行外设接口(SPI)是微控制器和外围IC(如传感器、ADC、DAC、移位寄存器、SRAM等)之间使用最广泛的接口之一。SPI是一种同步、全双工、主从式接口。来自主机或从机的数据在时钟上升沿或下降沿同步。主机和从机可以同时传输数据。SPI接口可以是3线式或4线式。本文重点介绍常用的4线SPI接口。

接口

图1. 含主机和从机的SPI配置 图1. 含主机和从机的SPI配置。

4线SPI器件有四个信号:

1) SCLK:串行时钟,用来同步数据传输,由主机输出;

2) MOSI:主机输出从机输入(Master Output Slaver Input)数据线;

3) MISO:主机输入从机输出数据线;

4) SS:片选线,低电平有效,由主机输出。

在SPI总线上,某一时刻可以出现多个从机,但只能存在一个主机,主机通过片选线来确定要通信的从机。这就要求从机的MISO口具有三态特性,使得该口线在器件未被选通时表现为高阻抗。

产生时钟信号的器件称为主机。主机和从机之间传输的数据与主机产生的时钟同步。同I2C接口相比,SPI器件支持更高的时钟频率。用户应查阅产品数据手册以了解SPI接口的时钟频率规格。

SPI接口只能有一个主机,但可以有一个或多个从机。图1显示了主机和从机之间的SPI连接。

来自主机的片选信号用于选择从机。这通常是一个低电平有效信号,拉高时从机与SPI总线断开连接。当使用多个从机时,主机需要为每个从机提供单独的片选信号。本文中的片选信号始终是低电平有效信号。

MOSI和MISO是数据线。MOSI将数据从主机发送到从机,MISO将数据从从机发送到主机。

SPI传输的优缺点

SPI接口具有如下优点:

1) 支持全双工操作;

2) 操作简单;

3) 数据传输速率较高。

同时,它也具有如下缺点:

1) 需要占用主机较多的口线(每个从机都需要一根片选线);

2) 只支持单个主机。

硬件环境搭建

Vivado中配置Zynq IP核,SPI控制器可以路由到MIO或EMIO。选择路由到MIO时SS[1]和SS[2]是可选的。配置DDR、UART等其它选项。

查看BM7030硬件原理图中PS端MIO口的配置如下:

%title插图%num

SPI Flash的硬件原理图设计如下:

%title插图%num

在Vivado的Block Diagram中点击Zynq IP核,点击MIO Configuration:

选中Quad SPI Flash,Single SS 4bit IO,选择LVCMOS3.3V,对应MIO1-6

%title插图%num

可以核对和原理图的IO管脚是否一致。

在Block Design空白处点击右键,点击Validate Design,点击确定

右键点击ARM_SOCCreate HDL Wrapper形成新的arm_soc_wrapper文件,wrapper文件就是将Processing_System7_0封装为一个Verilog接口的文件

%title插图%num

选择Let Vivado manage Wrapper and auto-update,生成新的arm_soc_wrapper.v 文件

%title插图%num

生成新的arm_soc_wrapper.v文件后,因为FPGA外部接口未改变,arm_soc_top.v最后形成的顶层文件不用更改;点击保存,模块会自动分层,source文件层结构如下图:

%title插图%num

点击左侧Generate Bitstream,会生成bit文件

当Bitstream 生成后操作如下:FileExportHardwareExport Hardware选择Include bitstream OK

FileLaunch SDK 会生成SDK界面,从Vivado到SDK界面,是硬件环境到软件环境的转换

%title插图%num %title插图%num

SDK start界面如下图所示:

其中硬件描述文件system.hdf 列出了每个PS7-cortexta9_[0-1]中每个模块的地址映射,如ps7_uart_0的起始地址位为0xe0000000,最高地址位为0xe0000fff. 新增加的PS_qspi_0的起始地址位0xe000d000,最高地址位为0xe000dfff。

%title插图%num

建立应用程序项目:FilenewApplication Project,命名为SPI_Flash_test,

%title插图%num

选择空白模板empty Application:

%title插图%num

点击src点击右键,分别增加head文件qspips_header.h和xqspips_selftest_example.c以及主函数文件main.c文件。

%title插图%num

头文件qspips_header.h定义了函数定义和xilinx的qspi需要的头文件类型:

#ifndef QSPIPS_HEADER_H /* prevent circular inclusions */

#define QSPIPS_HEADER_H /* by using protection macros */

#include “xil_types.h”

#include “xil_assert.h”

#include “xstatus.h”

#include “xparameters.h”

int QspiPsSelfTestExample(u16 DeviceId);

#endif

测试SPI Flash的自测程序如下:

#include “xparameters.h”

#include “xqspips.h”

#include “xil_printf.h”

XQspiPs Qspi;

int QspiPsSelfTestExample(u16 DeviceId)

{

int Status;

XQspiPs_Config *QspiConfig;

/*

* Initialize the QSPI device.

*/

QspiConfig = XQspiPs_LookupConfig(DeviceId);

if (NULL == QspiConfig) {

return XST_FAILURE;

}

Status = XQspiPs_CfgInitialize(&Qspi, QspiConfig, QspiConfig->BaseAddress);

if (Status != XST_SUCCESS) {

return XST_FAILURE;

}

/*

* Perform a self-test to check hardware build.

*/

Status = XQspiPs_SelfTest(&Qspi);

if (Status != XST_SUCCESS) {

return XST_FAILURE;

}

return XST_SUCCESS;

}

主函数main.c是打印测试串口信息:

#include <stdio.h>

#include “xparameters.h”

#include “xqspips.h”

#include “qspips_header.h”

int main ()

{

int Status;

print(“\r\n Running SPI Flash test \r\n”);

Status = QspiPsSelfTestExample(XPAR_PS7_QSPI_0_DEVICE_ID);

if (Status == 0) {

print(“SPI Flash test PASSED\r\n”);

}

else {

print(“SPI Flash test FAILED\r\n”);

}

return 0;

}

该程序是SPI设备初始化的程序,使用XQspiPs_SelfTest函数对SPI设备进行自检。这个函数会执行一次所有SPI控制器寄存器的读取和写入,主要是对延时参数,相当于复位SPI设备。自检成功返回XST_SUCCESS;读取或写入某个寄存器失败时返回XST_REGISTER_ERROR。

如果SPI Flash 配置成功,串口则会打印如下信息:

%title插图%num

本文的项目主要是进行SPI Flash的硬件初始化,后续会有更深入的应用,比如会应用Flash做启动文件作为Zynq的启动程序和其他应用程序等等。

Posted in SoC, SOC, 教材与教案
0 0 投票数
Article Rating
订阅评论
提醒
guest
0 评论
内联反馈
查看所有评论

相关链接