0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

怎么样利用AXI Quad SPI快速打通Linux至PL端SPI从设备?

FPGA之家 来源:CSDN技术社区 作者:嵌入式客栈 2021-04-09 17:45 次阅读

[导读] 前面写过篇介绍ZYNQ基本情况的文章,今天来肝一篇实战文章介绍AXI quad SPI 使用方法,如果你正使用ZYNQ的这个IP,希望对你有所帮助。

初识AXI quad SPI

f25d2ec4-990e-11eb-8b86-12bb97331649.png

自《PG153 AXI Quad SPI v3.2》

支持:

Legacy Mode

standard mode: 准SPI通常就称SPI,它是一种串行外设接口规范,有4根通信脚:SCK (时钟), CS(片选), MOSI(主出从入), MISO(主入从出)。

Dual/Quad SPI Mode:

f269a73a-990e-11eb-8b86-12bb97331649.png

AXI QuadSPI 模式

在标准模式下,支持高达32个从站,这是非常灵活的指标。本文对于手册中的详细技术细节不做过多阐述,有兴趣的自行深入阅读研究。

该SPI IP能干神马呢?

完成如下这样一个应用场景:

f2ac0864-990e-11eb-8b86-12bb97331649.png

SPI IP访问多从SPI芯片

所需要实现的需求用例为:

f2e1edbc-990e-11eb-8b86-12bb97331649.png

本文实现用例描述

利用AXI quad SPI 实现SPI外设控制器

实现SPI外设控制器驱动

实现多SPI从设备挂载在SPI总线

实现用户空间访问多从SPI物理从设备

从软件分层的视角来看,上述的需求需要实现下面的访问层级:

f30a8b32-990e-11eb-8b86-12bb97331649.png

PS/PL软硬件层次架构图

为什么要研究这个呢?实际用ZYNQ芯片做产品时,很有可能外部有多个SPI从设备芯片需要利用Linux访问,你或许会说ZYNQ的PS端不是自带了两个SPI控制器吗?但有时候项目中这两个SPI对应的引脚可能用做其他用途了,而一个复杂的项目中又不得不使用多个SPI从设备芯片时,本文所讨论的话题就能很好的解决这样的需求场景了。通过本文,你会发现,原来ZYNQ的SPI IP是如此灵活好用!

本文目的实战描述,如何一步一步从PL端设计:

block design

约束

综合

导出

乃至PS端:

SPI驱动配置

设备树修改

系统编译部署

设备驱动测试

按照这个流程,那么第一步需要设计PL端与PS端的配置,且看:

AXI Quad SPI 之配置

从IP catalog中按下图从ip库中添加如下IP:

ZYNQ7 processing System

AXI interconnect

AXI Quad SPI(可根据需要添加多个)

Processing System Reset(添加ZYNQ7 processing System 点自动连线会自动添加,当然也可以手动添加)

Concat

f3450aa0-990e-11eb-8b86-12bb97331649.png

Block设计图

使能ZYNQ7 processing System的时钟PL Fabric clocks,用以驱动PL端的IP:

f38dc678-990e-11eb-8b86-12bb97331649.png

PL Fabric clocks设置

使能M AXI GP0接口如下:

f3ddadf0-990e-11eb-8b86-12bb97331649.png

M AXI GP0设置

双击AXI interconnect,设置2主1从:

f41cf5d2-990e-11eb-8b86-12bb97331649.png

AXI interconnect设置

双击axi_quad_spi_0设置如下,设置4个从设备(最多可支持32个从设备,PS端内置的SPI控制器1个最多支持3个从设备,从这一点可看出该IP的灵活性)

f44f9ee2-990e-11eb-8b86-12bb97331649.png

axi_quad_spi设置

同样将axi_quad_spi_1设置为2个从设备接口。

然后按照前面的连线图,将各块连接好,做过硬件的盆友会比较适应,这就像画原理图一样,就将各IP建立了逻辑连接关系了。除此之外,对于一个ZYNQ的板子而言,你还需要做如下的PS端设置:

DDR RAM设置,根据自身的板子的内存芯片以及内存大小进行设置

Peripheral IO外设设置,比如SD卡,UART,QUAD SPI Flash,erthernet等

clock时钟系统设置,根据板子的情况进行设置CPU、DDR时钟频率、IO时钟等

......

至于这些怎么配置,比较常见这里就不赘述了。

对于AXI quad SPI外设还有一个很重要的配置,就是其地址范围:

f4786c50-990e-11eb-8b86-12bb97331649.png

AXI quad SPI地址设置

该地址最终将导出到设备树描述文件,用于SPI控制器驱动访问,从而让SPI控制器驱动得以与该IP通过AXI总线进行通信。

导出硬件文件

点击open elaborated design ,然后打开io ports进行管脚分配,这需要根据各自的硬件实际情况进行设置,比如我是这样设置的:

f49cfaac-990e-11eb-8b86-12bb97331649.png

管脚约束设置

电平标准

是否上拉

驱动能力

.....

然后点击Run synthesis进行综合,成功之后点击生成bit stream。再点击export hardware,得到.hdf文件,这个文件用于构建内核。

f4e1be1c-990e-11eb-8b86-12bb97331649.png

导出硬件描述文件

将得到的硬件描述hdf文件以及bitstream文件拷贝至内核编译文件夹下:

f5297810-990e-11eb-8b86-12bb97331649.png

硬件描述及bit文件

配置编译内核

运行命令读取硬件描述文件:

petalinux-config--get-hw-description../base.sdk

注:这里将hdf文件以及.bit文件放置在petalinux编译路径的上级目录的base.sdk,根据习惯可自行设置,只有上述命令传入的路径正确即可。

等待一段时间后,可得到一个配置界面,用于配置内核源、u-boot源、Image 等配置。

f546d3a6-990e-11eb-8b86-12bb97331649.png

petalinux-config

根据实际情况配置好后,退出配置并保存配置。使用过的会比较熟悉,这里不赘述了。

配置设备树

编辑用户设备树文件,用户设备树文件在下面路径中:

./project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi

配置设备树如下:

/include/"system-conf.dtsi" /{ }; &axi_quad_spi_0{ status="okay"; clock-names="axi_clk","axi4_clk","spi_clk"; clocks=<&clkc 15>,<&clkc 15>,<&clkc 15>; spi0_dev_0@0{ compatible="spidev"; reg=<0>; spi-max-frequency=<500000>; #address-cells=<1>; #size-cells=<1>; }; spi0_dev_1@1{ compatible="spidev"; reg=<1>; spi-max-frequency=<500000>; #address-cells=<1>; #size-cells=<1>; }; spi0_dev_2@2{ compatible="spidev"; reg=<2>; spi-max-frequency=<500000>; #address-cells=<1>; #size-cells=<1>; }; spi0_dev_3@3{ compatible="spidev"; reg=<3>; spi-max-frequency=<500000>; #address-cells=<1>; #size-cells=<1>; }; }; &axi_quad_spi_1{ status="okay"; clock-names="axi_clk","axi4_clk","spi_clk"; clocks=<&clkc 15>,<&clkc 15>,<&clkc 15>; spi1_dev_0@0{ compatible="spidev"; reg=<0>; spi-max-frequency=<500000>; #address-cells=<1>; #size-cells=<1>; }; spi1_dev_1@1{ compatible="spidev"; reg=<1>; spi-max-frequency=<500000>; #address-cells=<1>; #size-cells=<1>; }; };

这里直接使用内置spidev兼容从设备驱动,当然如果需要自己定义一个SPI设备驱动也是非常容易的,但是对于大部分普通的SPI从芯片而言直接使用spidev设备驱动即可,只需要在读写时按照芯片手册协议进行访问即可。

配置内核

运行下面命令进行内核配置:

petalinux-config-ckernel

f5720d1e-990e-11eb-8b86-12bb97331649.png

内核配置

对于本应用而言,需要配置SPI驱动:

DeviceDrivers---> +-SPIsupport--->

配置如下:

f5956458-990e-11eb-8b86-12bb97331649.png

SPI控制器及设备驱动配置

这里调试中遇到一个奇怪的问题,CONFIG_SUSPEND需要禁止,否则控制器驱动加载不成功,目前还没有深入研究为什么不成功,猜想可能是主控制器驱动关于SUSPEND功能还不支持或者有bug,如果有哪位大神知道怎么解决请求留言指点。

Powermanagementoptions---> SuspendtoRAMandstandby

f5a3bbb6-990e-11eb-8b86-12bb97331649.png

功能管理配置

退出并保存配置,然后运行下面命令编译系统:

petalinux-build

等待编译成功后,运行下面命令将bitstream文件包进BOOT.bin中。

petalipackage--boot--fsbl./images/linux/zynq_fsbl.elf--fpga../base.sdk/design_1_wrapper.bit--u-boot--force

将得到下面的输出信息,表示操作成功:

INFO:FileinBOOTBIN:"/home/zynq/ALINX/spi_ip/ax_peta/images/linux/zynq_fsbl.elf" INFO:FileinBOOTBIN:"/home/zynq/ALINX/spi_ip/base.sdk/design_1_wrapper.bit" INFO:FileinBOOTBIN:"/home/zynq/ALINX/spi_ip/ax_peta/images/linux/u-boot.elf" INFO:GeneratingzynqbinarypackageBOOT.BIN... INFO:Binaryisready. WARNING:UnabletoaccesstheTFTPBOOTfolder/tftpboot!!! WARNING:SkipfilecopytoTFTPBOOTfolder!!!

注:/home/zynq/ALINX/spi_ip/ax_peta 是本文工程的目录

测试SPI从设备

编写驱动测试程序,代码如下:

#include #include #include #include intmain(intargc,char**argv) { intfd; intlen; unsignedcharbuf[10]; unsignedchartmp; /*验证输入参数个数*/ if(3!=argc) { printf("nonepara "); return-1; } /*打开输入的设备文件,获取文件句柄*/ fd=open(argv[1],O_RDWR); if(fd< 0)     {         /* 打开文件失败 */         printf("Can't open file %s ", argv[1]);         return -1;     }     int i = 0;     int j = 0;     len =strlen(argv[2]);     for(i=0;i='0'&&argv[2][i]<='9')         {             tmp = argv[2][i] - '0';         }         else if(argv[2][i]>='a'&&argv[2][i]<='f')         {             tmp = argv[2][i] - 'a'+10;         }         else if(argv[2][i]>='A'&&argv[2][i]<='F')         {             tmp = argv[2][i] - 'A'+10;         }         else         {             printf("Invalid input parameters  ");             return -1;         }         if(i%2==0)            buf[j] = tmp<<4;         else         {             buf[j] += tmp;             j++;         }     }     len = j;     printf("Test wr:");     for(i=0;i

编译:arm-linux-gnueabihf-gcctest.c-otest

将编译所得的BOOT.BIN以及image.ub文件拷贝至制作好的SD的BOOT区,test文件拷贝至/home下。然后插上SD卡上电运行电路板:

登录控制台后,运行ls /dev查看spidev设备是否加载成功:

f5d4c620-990e-11eb-8b86-12bb97331649.png

spidev设备挂载情况

可见spedev1.0、spidev1.1以及spidev2.0--spidev2.3加载成功,与预期一样。

然后运行测试程序:

root@ax_peta:/run/media/mmcblk0p2/home#./test/dev/spidev1.078aa Testwr:78aa

示波器或者逻辑分析仪观察对应引脚,将出现正确的SPI通信波形。

总结一下

至此,就基本实现了从PS端Linux用户空间访问PL端的SPI从设备了。当然实际项目中还有很多细节需要进一步研究:

CPOL/CPHA 组合四种模式设置

SPI通信速率设置

从设备应用协议程序编写

AXI Quad SPI FIFO特性的深入应用

AXI Quad SPI 其他模式及细节研究等

对于这些更细节的内容,相信在将基本框架搭建成功后,只要深入细致研究都不会有太大的难度。从本文可看出,ZYNQ之所以如此灵活好用,是其厂家或者第三方提供了大量成熟可供使用的IP以及配套的驱动程序。如有兴趣尝试用来开发项目,相信你会很快喜欢上这个体系的芯片,真的可以做到片上即可实现系统这一目标!

编辑:jq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • SPI
    SPI
    +关注

    关注

    17

    文章

    1615

    浏览量

    89600
  • CS
    CS
    +关注

    关注

    0

    文章

    52

    浏览量

    24320
  • AXI
    AXI
    +关注

    关注

    1

    文章

    126

    浏览量

    16286

原文标题:【ZYNQ实战】利用AXI Quad SPI快速打通Linux至PL端SPI从设备

文章出处:【微信号:zhuyandz,微信公众号:FPGA之家】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    STM32H7的Octo-SPI或者Quad-SPI能否支持读取ADC的数据?

    ADC使用的AD7380.2通道4M的同步ADC。 SPI接口需要使用2个数据接收引脚 和一个数据输出引脚。等于是三根数据线。 普通的SPI只有两根线。Quad-SPI看描述说一般用于FLASH。 如果使用Octo-
    发表于 04-01 06:10

    请问QUAD SPI是否支持SD卡?

    如题,单线SPI读取SD卡肯定没有4线读取的速率快,问题是STM32某些芯片没有SDIO引脚,但是有QUAD SPI,不知道是否能4线驱动SD卡呢?
    发表于 03-25 06:34

    ModusToolbox中如何设置CYW20719B2的Quad SPI接口?

    您好, 请问Modus Toolbox 中如何设置CYW20719B2的Quad SPI接口? 我利用下图方法 打开了wiced_btsdk下的design.modus文件,并配置了SPI
    发表于 03-01 11:16

    硬件spi和软件spi的区别

    硬件SPI(串行外设接口)和软件SPI是两种不同的SPI传输方式。SPI是一种同步串行数据通信协议,通常用于连接微控制器和外部设备,如存储器
    的头像 发表于 12-26 16:55 2058次阅读

    linux内核中的SPI框架及SPI核心的初始化简析

    在嵌入式linux开发中,SPI是一种常见的通信方式
    的头像 发表于 12-11 09:10 667次阅读
    <b class='flag-5'>linux</b>内核中的<b class='flag-5'>SPI</b>框架及<b class='flag-5'>SPI</b>核心的初始化简析

    SPI上拉合不上拉的区别 UART和SPI的主要区别

     使用SPI接口时,需要根据具体的外设和系统需求来配置SPI的参数,如通信速度、数据位宽、主从模式等。主设备通过操作SPI相关的寄存器或调用相应的库函数来控制数据传输和通信。从
    的头像 发表于 11-10 16:47 3913次阅读

    单片机spi接口的使用方法有哪些(spi接口和串口的区别)

    如果单片机没有硬件SPI模块,或者需要额外的IO引脚来实现多个SPI设备的通信,可以使用软件SPI模拟。软件SPI通常使用GPIO口模拟
    的头像 发表于 11-10 16:38 1643次阅读

    ZYNQ的ARM和FPGA数据交互——AXI交互最重要的细节

    的存储器。 ⑥ACP : PL可以直接PS的Cache中拿到CPU计算的结果,延时低 ⑦DMA :DMA控制接口,用于控制高速数据传输的通道。 (3)AXI协议
    发表于 11-03 10:51

    如何使用MCU通过spi的方式同时控制多个设备

    )、PA7(MOSI)引脚分别连接5个adc的对应引脚; 利用stm32的5个GPIO口分别作为连接5个adc的MISO引脚; 使用该方法可以控制adc,但是由于gpio模拟spi速度相对较慢导致采样率过低。 请问使用系统函数有方法实现同时接收多个
    发表于 08-08 07:26

    标准4线SPI四根线有哪些

    SPI hardware SPI:Serial Perripheral Interface,串行外围设备接口,由 Motorola 公司提出,是一种高速、全双工、同步通信总线。SPI
    的头像 发表于 07-27 10:26 4713次阅读
    标准4线<b class='flag-5'>SPI</b>四根线有哪些

    SPI子系统:SPI设备驱动

    SPI 设备驱动 【设备】声明在设备树中 注意:设备的声明,slave device node 应该包含在你所要挂载的 } /* remov
    的头像 发表于 07-25 11:05 582次阅读
    <b class='flag-5'>SPI</b>子系统:<b class='flag-5'>SPI</b><b class='flag-5'>设备</b>驱动

    SPI通用接口层介绍

    SPI 通用接口层 SPI 通用接口层把具体的 SPI 设备的协议驱动和 SPI 控制器驱动连接在一起。 负责
    的头像 发表于 07-25 10:52 474次阅读

    SPI驱动源文件目录在哪

    /drivers/ spi/spidev.c linux 提供的 SPI 通用设备驱动程序kernel- 4.14 /include/ linux
    的头像 发表于 07-25 10:49 489次阅读
    <b class='flag-5'>SPI</b>驱动源文件目录在哪

    Linux SPI设备驱动:四线SPI OLED驱动实战

    SPI设备芯片的种类非常广泛,包括用于模拟传感器和编解码器的数字/模拟转换器、内存芯片、USB 控制器或以太网适配器等外设,以及其他类型的芯片。
    发表于 06-16 10:33 548次阅读
    <b class='flag-5'>Linux</b> <b class='flag-5'>SPI</b><b class='flag-5'>设备</b>驱动:四线<b class='flag-5'>SPI</b> OLED驱动实战

    SPI可以像I2C挂多个设备吗?

    最近看到有小伙伴在讨论:SPI可以像I2C挂多个设备吗?
    的头像 发表于 05-14 10:10 2356次阅读
    <b class='flag-5'>SPI</b>可以像I2C挂多个<b class='flag-5'>设备</b>吗?