全国产T3+FPGA的SPI与I2C通信方案分享
近年来,随着中国新基建、中国制造2025规划的持续推进,单ARM处理器越来越难胜任工业现场的功能要求,特别是如今能源电力、工业控制、智慧医疗等行业,往往更需要ARM + FPGA架构的处理器平台来实现例如多路/高速AD采集、多路网口、多路串口、多路/高速并行DI/DO、高速数据并行处理等特定功能,因此ARM + FPGA架构处理器平台愈发受市场欢迎。
因此,创龙科技一年前正式推出了国产化率100%的ARM + FPGA工业核心板,它基于全志T3 + 紫光同创Logos处理器设计。
全志T3为准车规级芯片,四核ARM Cortex-A7架构,主频高达1.2GHz,支持双路网口、八路UART、SATA大容量存储接口,同时支持4路显示、GPU以及1080P H.264视频硬件编解码。另外,创龙科技已在T3平台适配国产嵌入式系统翼辉SylixOS,真正实现软硬件国产化。
紫光同创Logos PGL25G/PGL50G FPGA在工业领域应用广泛,逻辑资源分别为27072/51360,与国外友商产品pin to pin兼容,主要用于多通道/高速AD采集或接口拓展。因其价格低、质量稳定、开发环境易用等优点,受到工业用户的广泛好评。尤其是开发环境,最快3天可完成从国外友商产品到紫光同创产品的切换。
SPI通信优势与应用场景
SPI(Serial Peripheral Interface)是一种用于串行数据传输的通信协议,SPI通信具有带宽高、实时性强、传输速度快、连接简单、可靠性高和灵活性强等优势。
SPI协议适用于许多嵌入式系统和外围设备之间的通信需求,可提供快速、可靠和灵活的数据传输,非常适合“小数据-低时延”和“大数据-高带宽”的应用场景。

图2 SPI通信总线
I2C通信优势和应用场景
I2C(Inter-Integrated Circuit)是一种串行双向通信协议,I2C通信具有硬件资源需求低、简单灵活、可靠性高和支持多种设备类型等优势。
I2C协议可提供简单、可靠和灵活的数据传输。它广泛应用于各种传感器、存储设备、显示设备和通信模块等领域。适用控制命名传输和系统配置的应用场景。

图3 I2C通信总线
国产T3 + FPGA的SPI与I2C通信方案介绍
本章节主要介绍全志科技T3与紫光同创Logos基于SPI、I2C的ARM + FPGA通信方案,使用的硬件平台为:创龙科技TLT3F-EVM工业评估板。I2C通信案例案例功能:实现T3(ARM Cortex-A7)与FPGA的TWI(I2C)通信功能。
FPGA案例源码为“4-软件资料\Demo\fpga-demo\i2c_slave”,实现I2C Slave功能,并内置用户可读写寄存器、LED寄存器、KEY寄存器。
ARM端作为I2C Master,可通过TWI(I2C)总线读写FPGA端用户可读写寄存器0x00、LED写寄存器0x01(写1则点亮FPGA端LED,写0则熄灭),以及查看KEY寄存器0x02检测FPGA端用户输入按键状态。
案例测试:评估板上电,请先加载运行FPGA端可执行程序。执行如下命令可查看到I2C总线上的挂载设备,其中0x2a为FPGA端I2C Slave的地址。
Target#echo "1 4 1 7" > /proc/sys/kernel/printk //屏蔽内核printk打印,避免I2C驱动扫描找不到设备时打印警告信息
Target#i2cdetect -r -y 0

图4
执行如下命令,读写FPGA端用户可读写寄存器0x00。
Target#i2cset -f -y 0 0x2a 0x00 0x55 //往寄存器0x00写0x55
Target#i2cget -f -y 0 0x2a 0x00 //读取寄存器0x00,值为0x55
图5
执行如下命令,写FPGA端LED寄存器0x01,实现对FPGA端用户可编程指示灯控制。
Target#i2cset -f -y 0 0x2a 0x01 0xc0 //往LED寄存器0x01写0xc0,点亮FPGA端LED3、LED4
Target#i2cset -f -y 0 0x2a 0x01 0x00 //往LED寄存器0x01写0x00,熄灭FPGA端LED3、LED4
图6
执行如下命令,读FPGA端KEY寄存器0x02,实现对FPGA端用户输入按键的状态检测。
Target#i2cget -f -y 0 0x2a 0x02 //读取KEY寄存器0x02,值为0xe0
图7
请按下FPGA端用户输入按键KEY7并保持按下状态,再执行如下命令。
Target#i2cget -f -y 0 0x2a 0x02 //读取KEY寄存器0x02,值为0xc0
图8
请按下FPGA端用户输入按键KEY8并保持按下状态,再执行如下命令。
Target#i2cget -f -y 0 0x2a 0x02 //读取KEY寄存器0x02,值为0xa0

图9
请按下FPGA端用户输入按键KEY9并保持按下状态,再执行如下命令。
Target#i2cget -f -y 0 0x2a 0x02 //读取KEY寄存器0x02,值为0x60
图10
基于Linux的SPI通信案例
案例功能:基于Linux系统,实现T3(ARM Cortex-A7)与FPGA的SPI通信功能。
ARM端案例源码为“4-软件资料\Demo\module-demos\spi_rw”,实现SPI Master功能,具体如下:
(1)打开SPI设备节点,如:/dev/spidev0.1。
(2)使用ioctl配置SPI总线,如SPI总线极性和相位、通信速率、数据长度等。
(3)选择模式为单线模式或双线模式。当设置SPI总线为双线模式时,发送数据为单线模式,接收数据为双线模式。
(4)发送数据至SPI总线,以及从SPI总线读取数据。
校验数据,然后打印读写速率、误码率。
FPGA端案例源码为“4-软件资料\Demo\fpga-demos\dram_spi”和“4-软件资料\Demo\fpga-demos\dram_spi_dual”,实现SPI Slave功能,具体说明如下:(1)将SPI Master发送的数据保存至DRAM。(2)SPI Master发起读数据时,FPGA从DRAM读取数据通过SPI总线传输至SPI Master。当SPI总线为双线模式时,接收数据支持双线模式,而发送数据仅支持单线模式。

图11 ARM端程序流程图
案例测试:评估板上电,请先加载运行FPGA端可执行程序,若进行SPI单线模式测试,请运行案例"dram_spi\bin\"目录下的程序可执行文件;若进行SPI双线模式测试,请运行"dram_spi_dual\bin\"目录下的程序可执行文件。同时将ARM端可执行程序spi_rw拷贝至评估板文件系统任意目录下。
进入评估板文件系统,执行如下命令查看新生成的spidev设备节点。
Target#ls /dev/spidev0.1

执行如下命令查询程序命令参数。
Target#./spi_rw -h

图13
1 SPI单线模式
1.1 功能测试
执行如下命令运行程序,ARM通过SPI总线写入1KByte随机数据至FPGA DRAM,然后读出数据、进行数据校验,同时打印SPI总线读写速率和误码率,最终实测写速率为2.405MB/s,读速率为2.405MB/s,误码率为0。如下图所示。
Target#./spi_rw -d /dev/spidev0.1 -s 50000000 -OH -m 1 -S 1024 -c 2
参数解析:
-d:设备节点;
-s:设置通信时钟频率(Hz),本次测试设置SPI总线通信时钟频率为50MHz,则SPI单线模式理论通信速率为:(50000000 / 1024 / 1024 / 8)MB/s ≈ 5.96MB/s;
-O:空闲状态时,SCLK为高电平(CPOL=1);
-H:从第二个跳变沿开始采样(CPHA=1);
-m:选择模式传输模式(1表示单线模式,2表示双线模式);
-S:设置传输数据大小,单位为Byte;
-c:循环传输数据包的次数。
图14
1.2 性能测试
(1)基于50MHz时钟频率
执行如下命令运行程序,基于50MHz时钟频率、增大读写数据量测试SPI总线最高传输速率。ARM通过SPI总线写入1MByte随机数据至FPGA DRAM,然后读出数据,不做数据检验,最后打印SPI总线读写速率和误码率,如下图所示。
备注:本案例设计一次读写1KByte随机数据至FPGA DRAM,因此误码率较高。
Target#./spi_rw -d /dev/spidev0.1 -s 50000000 -OH -m 1 -S 1048576 -c 2
图15
本次测试设置SPI总线通信时钟频率为50MHz,则SPI单线模式理论通信速率为:(50000000 / 1024 / 1024 / 8)MB/s ≈ 5.96MB/s。从上图可知,本次实测写速率为5.757MB/s,读速率为5.757MB/s,接近理论通信速率。
本次测试SPI使用了DMA传输,测得CPU的占用率约为1%,如下图所示。
图16
(2)基于100MHz时钟频率
执行如下命令运行程序,测试基于100MHz时钟频率的SPI单线模式的最高通信带宽。ARM通过SPI总线写入1MByte随机数据至FPGA DRAM并读出数据,不做数据检验,最后打印SPI总线读写速率和误码率,如下图所示。
备注:本次测试旨在测试SPI的最高传输速率,目前SPI速率最大支持50MHz时钟频率,当时钟频率配置到最大100MHz时速率会出现时序问题,现象是整体往右移了1bit。例如发送10000000,实际接收到01000000,并在测试中出现误码。
Target#./spi_rw -d /dev/spidev0.1 -s 100000000 -OH -m 1 -S 1048576 -c 100

图17
根据官方数据手册(如下图),SPI总线通信时钟频率理论值最大为100MHz。本次测试设置SPI总线通信时钟频率为最大值100MHz,则SPI单线模式理论速率为:(100000000 / 1024 / 1024 / 8)MB/s ≈ 11.92MB/s。从上图可知,在100MHz下实测SPI单线模式写速率为:11.331MB/s,SPI单线模式读速率为:11.331MB/s,接近理论通信速率。
图18
本次测试SPI使用了DMA传输,测得CPU的占用率约为1%,如下图所示。
图19
2 SPI双线模式
2.1 功能测试
执行如下命令运行程序,ARM通过SPI总线写入1KByte随机数据至FPGA DRAM,然后读出数据、进行数据校验,同时打印SPI总线读写速率和误码率,如下图所示。
Target#./spi_rw -d /dev/spidev0.1 -s 50000000 -OH -m 2 -S 1024 -c 1
参数解析:
-d:设备节点;
-s:设置通信时钟频率(Hz),本次测试设置SPI总线通信时钟频率为50MHz,则SPI双线模式理论通信速率为:(50000000 / 1024 / 1024 / 4)MB/s ≈ 11.92MB/s;
-O:空闲状态时,SCLK为高电平(CPOL=1);
-H:从第二个跳变沿开始采样(CPHA=1);
-m:选择模式传输模式(1表示单线模式,2表示双线模式);
-S:设置传输数据大小,单位为Byte;
-c:循环传输数据包的次数。
图20
从上图可知,本次实测写速率为2.577MB/s,读速率为5.222MB/s,误码率为0。
2.2 性能测试
(1)基于50MHz时钟频率
执行如下命令运行程序,基于50MHz时钟频率、增大读写数据量测试SPI总线最高传输速率。ARM通过SPI总线写入1MByte随机数据至FPGA DRAM,然后读出数据,不做数据检验,最后打印SPI总线读写速率和误码率,最终本次实测写速率为5.892MB/s,读速率为11.365MB/s。如下图所示。
备注:本案例设计一次读写1KByte随机数据至FPGA DRAM,因此误码率较高。
Target#./spi_rw -d /dev/spidev0.1 -s 50000000 -OH -m 2 -S 1048576 -c 1
图21
本次测试设置SPI总线通信时钟频率为50MHz,则SPI单线模式理论通信速率为:(50000000/1024/1024/8)MB/s ≈ 5.96MB/s;SPI双线模式理论通信速率为:(50000000 / 1024 / 1024 / 4)MB/s ≈ 11.92MB/s。
本次测试SPI使用了DMA传输,测得CPU的占用率约为0%,如下图所示。

图22
(2)基于100MHz时钟频率
执行如下命令运行程序,测试基于100MHz时钟频率的SPI双线模式的最高通信带宽。ARM通过SPI总线写入1MByte随机数据至FPGA DRAM并读出数据,不做数据检验,最后打印SPI总线读写速率和误码率,最终在100MHz下实测SPI双线模式写速率为:11.684MB/s,SPI双线模式读速率为:23.432MB/s。如下图所示。
备注:本次测试旨在测试SPI的最高传输速率,目前SPI速率最大支持50MHz时钟频率,当时钟频率配置到最大100MHz时速率会出现时序问题,现象是整体往右移了1bit。例如发送10000000,实际接收到01000000,并在测试中出现误码。
Target#./spi_rw -d /dev/spidev0.1 -s 100000000 -OH -m 2 -S 1048576 -c 100

根据官方数据手册(如下图),SPI总线通信时钟频率理论值最大为100MHz。本次测试设置SPI总线通信时钟频率为最大值100MHz,则SPI单线模式理论通信速率为:(100000000/1024/1024/8)MB/s ≈ 11.92MB/s;SPI双线模式理论速率为:(100000000 / 1024 / 1024 / 4)MB/s ≈ 23.84MB/s。
图24
本次测试SPI使用了DMA传输,测得CPU的占用率约为0%,如下图所示。
图25
基于Linux-RT的SPI通信案例
案例功能:基于Linux-RT实时系统,演示T3(ARM Cortex-A7)与FPGA之间的SPI通信功能。本案例通信数据量少、带宽低,但实时性高,适用于对通信带宽要求不高,但通信实时性有严格要求的工控场合。
ARM端案例源码为“4-软件资料\Demo\module-demos\rt_spi_rw”,实现SPI Master功能,具体如下:
(1)打开SPI设备节点。如:/dev/spidev0.1。
(2)使用ioctl配置SPI总线。如SPI总线极性和相位、通信速率、数据字长度等。
(3)创建实时线程。
(4)发送数据至SPI总线,以及从SPI总线读取数据。
(5)打印发送、接收的速率和传输耗时。
校验数据,然后打印读写速率、误码率。
FPGA端案例源码为“4-软件资料\Demo\fpga-demos\dram_spi”,实现SPI Slave功能,具体如下:(1)将SPI Master发送的数据保存至DRAM。SPI Master发起读数据时,FPGA从DRAM读取数据并通过SPI总线传输至SPI Master。
图26 ARM端程序流程图
案例测试:由于我司默认使用是的Linux内核,因此需参考Linux系统使用手册文档中的“替换内核、内核模块”章节将Linux系统启动卡替换为Linux-RT系统。
评估板上电,请先加载运行FPGA端可执行程序。将ARM端可执行文件rt_spi_rw拷贝至评估板文件系统任意目录下,执行如下命令,查看新生成的spidev设备节点。
Target#ls /dev/spidev0.1
图27
执行如下命令,查询程序命令参数。
Target#./rt_spi_rw -h
图28
1 非轮询方式
执行如下命令运行程序,ARM通过SPI总线写入随机数据至FPGA DRAM,然后读出数据、进行数据校验,同时打印SPI总线读写速率、传输耗时和误码率,最终实测最小耗时为44us,最大耗时为167us,平均耗时为48us;写速率为0.076MB/s,读速率为0.076MB/s,误码率为0。如下图所示。
Target#./rt_spi_rw -d /dev/spidev0.1 -s 50000000 -OH -S 4 -c 1024
参数解析:
-d:设备节点;
-s:设置通信时钟频率(Hz),本次测试设置SPI总线通信时钟频率为50MHz,则理论通信速率为:(50000000 / 1024 / 1024 / 8)MB/s ≈ 5.96MB/s;
-O:空闲状态时,SCLK为高电平(CPOL=1);
-H:从第二个跳变沿开始采样(CPHA=1);
-S:设置传输数据大小,单位为Byte;
-c:循环传输数据包的次数。
图29
2 轮询方式
执行如下命令运行程序,ARM通过SPI总线写入4Byte随机数据至FPGA DRAM,读出数据、进行数据校验,同时打印SPI总线读写速率、传输耗时和误码率,最终实测最小耗时为27us,最大耗时为152us,平均耗时为30us;写速率为0.118MB/s,读速率为0.118MB/s,误码率为0。如下图所示。
Target#./rt_spi_rw -d /dev/spidev0.1 -s 50000000 -OHp -S 4 -c 1024
参数解析:
-d:设备节点;
-s:设置通信时钟频率(Hz),本次测试设置SPI总线通信时钟频率为50MHz,则理论通信速率为:(50000000 / 1024 / 1024 / 8)MB/s ≈ 5.96MB/s;
-O:空闲状态时,SCLK为高电平(CPOL=1);
-H:从第二个跳变沿开始采样(CPHA=1);
-p:SPI发送端采用轮询方式(每次发送数据量≤64Byte);
-S:设置传输数据大小,单位为Byte;
-c:循环传输数据包的次数。
图30


全国产T3+FPGA的SPI与I2C通信方案分享的更多相关文章
- ADXL345经验总结,采用SPI和I2C总线操作
一. ADXL345简介 ADXL345是ADI公司推出的三轴(x,y,z)iMEMS数字加速度计(digital accelerometer),具有在16G下高分辨率(13Bit)测量能 ...
- UART、SPI和I2C详解
做单片机开发时UART,SPI和I2C都是我们最经常使用到的硬件接口,我收集了相关的具体材料对这三种接口进行了详细的解释. UART UART是一种通用串行数据总线,用于异步通信.该总线双向通信,可以 ...
- SPI、I2C、UART、I2S、GPIO、SDIO、CAN 简介
转自http://sanwen.net/a/fmxnjoo.html SPI.I2C.UART.I2S.GPIO.SDIO.CAN,看这篇就够了 总线 总线,总要陷进里面.这世界上的信号都一样,但是总 ...
- SPI、I2C、UART、I2S、GPIO、SDIO、CAN
总线,总线,总要陷进里面.这世界上的信号都一样,但是总线却成千上万,让人头疼. 总的来说,总线有三种:内部总线.系统总线和外部总线.内部总线是微机内部各外围芯片与处理器之间的总线,用于芯片一级的互连: ...
- 嵌入式驱动开发之dsp fpga通信接口---spi串行外围接口、emif sram接口
-----------------------------------------author:pkf ------------------------------------------------ ...
- Uart、SPI和I2C的区别
串口通信:UART.SPI.I2C区别[引用] 1.UART就是两线,一根发送一根接收,可以全双工通信,线数也比较少.数据是异步传输的,对双方的时序要求比较严格,通信速度也不是很快.在多机通信上面 ...
- SPI,UART,I2C都有什么区别,及其各自的特点
区别: SPI:高速同步串行口.3-4线接口,收发独立.可同步进行 UART:通用异步串行口.按照标准波特率完成双向通讯,速度慢 I2C:一种串行传输方式,三线制,网上可找到其通信协议和用法的 3根线 ...
- FPGA的SPI从机模块实现
一. SPI总线协议 SPI(Serial Peripheral Interface)接口,中文为串行外设接口.它只需要3根线或4根线即可完成通信工作(这里讨论4根线的情况). ...
- SPI、I2C、UART(转)
UART与USART(转) UART需要固定的波特率,就是说两位数据的间隔要相等. UART总线是异步串口,一般由波特率产生器(产生的波特率等于传输波特率的16倍).UART接收器.UART发送器组成 ...
- FPGA构造spi时序——AD7176为例(转)
reference:https://blog.csdn.net/fzhykx/article/details/79490330 项目中用到了一种常见的低速接口(spi),于是整理了一下关于spi相关的 ...
随机推荐
- SuperSonic简介
SuperSonic融合ChatBI和HeadlessBI打造新一代的数据分析平台.通过SuperSonic的问答对话界面,用户能够使用自然语言查询数据,系统会选择合适的可视化图表呈现结果. Supe ...
- 在英特尔至强 CPU 上使用 🤗 Optimum Intel 实现超快 SetFit 推理
在缺少标注数据场景,SetFit 是解决的建模问题的一个有前途的解决方案,其由 Hugging Face 与 Intel 实验室 以及 UKP Lab 合作共同开发.作为一个高效的框架,SetFit ...
- 05 elasticsearch学习笔记-基本CRUD
目录 视频教程 4.1 基本CRUD 4.2 URI查询 按时间段查 视频教程 Elasticsearch(7.8.1)沥血之作(包含仿百度搜索案例) https://www.bilibili.com ...
- 飞桨动态图PyLayer机制
一.主要用法 如下是官方文档上的使用样例: import paddle from paddle.autograd import PyLayer # Inherit from PyLayer class ...
- 【项目学习】Anchor:一种提供稳定币存款低波动收益率的去中心化的储蓄协议
简介 基于稳定币的获利产品. 贷方人放出稳定币以供借款.借方通过抵押资产(base asset)的方式,以低于协议定义的借贷比率借入稳定币.Anchor 协议使用抵押资产进行质押以获得奖励,然后将质押 ...
- [POJ2891]Strange Way to Express Integers公式推导
没啥事干,想着推个式子玩玩. 题目链接 题意不过多赘述,直接上过程: 由题意得 \[\begin{cases} x\equiv a_1\,(mod\,\, n_1) \\ x\equiv a_2\,( ...
- 【问题解决】java.lang.NoSuchMethodError错误
问题现象 近期本人负责的一个SpringBoot模块出现了java.lang.NoSuchMethodError报错,问题情况如下: A类提供了setJumpType(String type),B类调 ...
- Swoole 源码分析之 Coroutine 协程模块
首发原文链接:Swoole 源码分析之 Coroutine 协程模块 大家好,我是码农先森. 引言 协程又称轻量级线程,但与线程不同的是:协程是用户级线程,不需要操作系统参与.由用户显式控制,可以在需 ...
- zookeeper:Unexpected exception, exiting abnormally ::java.io.EOFException
转载请注明出处: 服务器中断,重启服务器在重启kafka服务时,遇到如下报错: 2024-06-05 13:52:56,251 [myid:] - ERROR [main:ZooKeeperServe ...
- 编程语言界的丐帮 C#.NET FRAMEWORK 4.6 EF 连接MYSQL
1.nuget 引用 EntityFramework .和 MySql.Data.EntityFramework. EntityFramework 版本:6.4.4,MySql.Data.Entit ...