[X]关闭

[米联客-XILINX-H3_CZ08_7100] FPGA_SDK入门篇连载-13PS SPI 环路测试实验

文档创建者:FPGA课程
浏览次数:307
最后更新:2024-09-26
文档课程分类-AMD-ZYNQ
AMD-ZYNQ: ZYNQ-SOC » 1_SDK应用方案(仅旗舰型号) » 1-SDK基础入门方案
本帖最后由 FPGA课程 于 2024-9-26 09:55 编辑

软件版本:VIVADO2021.1
操作系统:WIN10 64bit
硬件平台:适用 XILINX A7/K7/Z7/ZU/KU 系列 FPGA
实验平台:米联客-MLK-H3-CZ08-7100开发板
板卡获取平台:https://milianke.tmall.com/
登录“米联客”FPGA社区 http://www.uisrc.com 视频课程、答疑解惑!​
1概述
SPI总线接口简单,SPI的时钟可以到100M以上,SPI总线可以用于多种场合串行通信,比如存储器,温度传感器,压力传感器,模拟转换器,实时时钟,显示器以及任何支持串行模式的SD卡。一些ADC比如AD7606也可以用SPI接口实现通信。
2a463c9ac52f4f958281c0e41f08910d.jpg
实验目的:
1:熟悉掌握SPI通信协议
2:熟悉SPI控制器的硬件资源
3:通过VITIS-SDK实现对SPI控制器的使用
2系统框图
b367c8bfe59c434eb380310ed2811940.jpg
3SPI总线协议介绍
技术性能:
SPI接口是Motorola 首先提出的全双工三线同步串行外围接口,采用主从模式(MasterSlave)架构;支持多slave模式应用,一般仅支持单Master。时钟由Master控制,在时钟移位脉冲下,数据按位传输,高位在前,低位在后(MSBfirst);SPI接口有2根单向数据线,为全双工通信,目前应用中的数据速率可达几Mbps的水平。总线结构如下图所示。
4fcc0a26cc5144f88267d190c8e70ff7.jpg
接口定义:
SPI接口共有4根信号线,分别是:设备选择线、时钟线、串行输出数据线、串行输入数据线。
(1)MOSI:主器件数据输出,从器件数据输入
(2)MISO:主器件数据输入,从器件数据输出
(3)SCLK:时钟信号,由主器件产生
(4)/SS:从器件使能信号,由主器件控制
时钟极性和时钟相位:
SPI数据的传输是在串行同步时钟信号(Serial Clock,SCK)的控制下进行的。主机的时钟发生器一方面控制主机的移位寄存器,另一方面通过从机的SCK信号线来控制从机的移位寄存器,从而保证主机与从机的数据交换是同步进行的。
SPI串行同步时钟可以设置为不同的极性(Clock Polarity ,CPOL)与相位(Clock Phase ,CPHA)。
时钟的极性(CPOL)用来决定在总线空闲时,同步时钟(SCK)信号线上的电位是高电平还是低电平。当时钟极性为0时(CPOL=0),SCK信号线在空闲时为低电平;当时钟极性为1时(CPOL=1),SCK信号线在空闲时为高电平;
时钟的相位(CPHA)用来决定何时进行信号采样。
当时钟相位为1时(CPHA=1),在SCK信号线的第二个跳变沿进行采样;这里的跳变沿究竟是上升沿还是下降沿?取决于时钟的极性。当时钟极性为0时,取下降沿;当时钟极性为1时,取上升沿;如下图:
466c19121c5e48e1813684a560930b3f.jpg
CPHA=1 的SPI时序
当时钟相位为0时(CPHA=0),在SCK信号线的第一个跳变沿进行采样。跳变沿同样与时钟极性有关:当时钟极性为0时,取上升沿;当时钟极性为1时,取下降沿;如下图:
bfc57f2f573b42779f4feee228f55f7b.jpg
CPHA=0 的SPI时序

数据传输
在一个SPI时钟周期内,会完成如下操作:
1)主机通过MOSI线发送1位数据,从机通过该线读取这1位数据;
2)从机通过MISO线发送1位数据,主机通过该线读取这1位数据。
这是通过移位寄存器来实现的。如下图所示,主机和从机各有一个移位寄存器,且二者连接成环。随着时钟脉冲,数据按照从高位到低位的方式依次移出主机寄存器和从机寄存器,并且依次移入从机寄存器和主机寄存器。当寄存器中的内容全部移出时,相当于完成了两个寄存器内容的交换。
0ea242351637479cb9bac679d2f42f5a.jpg
4ZYNQ SPI控制器介绍
4.1SPI控制器介绍
SPI控制器通过APB总线接入到ARM,SPI控制器部分包含了数据的SPI控制器、SPI中断、发送模块、发送FIFO、接收模块、接收FIFO,并且支持SPI Master模式,以及SPI Slave模式,对于SPI的SLAVE模式还有SLAVE 同步默默。SPI的信号接口可以定义为MIO也可以定于到FPGA的EMIO,对于MIO速度可以到50M,对于EMIO速度为25M.

7f589757cf214bf9874e09346b5c977c.jpg
以下介绍SPI控制器的重要功能模块。
1:SPI的SS选通信号
当SPI作为Master模式的时候,SPI的可以通过3个SS信号实现1~3个外设或者通过3-8译码可以实现1~8个外设选通。SS选通支持手动模式和自动模式,默认是自动模式,在自动模式下每次发送数据会自动设置SS。如果手动模式则需要手动取消SS的片选。我们演示demo就是自动模式。
2:SPI控制器的FIFO
SPI控制器的RxFIFO和TxFIFO深度各是128字节。
往已经满的RxFIFO中送入数据,会导致溢出标志置1,新的数据不会添加进入FIFO。可以通过软件写1清除[RX_OVERFLOW]位。
往已经满的TxFIFO写入数据,这个数据会被忽略。当TxFIFO已经写满,TX_FIFO_full标志会置1,直到数据被读出,当FIFO非满后TX_FIFO_full标志会置0。如果TxFIFO读空产生向下溢出, TX_FIFO_underflow位置1。
3:SPI控制器的时钟
SPI_REF_CLK时钟在主机模式提供控制器的工作时钟,并且是SCLK的波特率分频器的参考时钟。在主模式下, SCLK使用波特率分频器从SPI_REF_CLK分频而来。 波特率分频器支持4~256分频(4,8,16,... 256分频)。
在从机模式下使用输入的SCL时钟驱动MISO信号和对MOSI以及SS信号采样,数据最终需要和SPI_REF_CLK时钟同步到SPI的控制器。
4:控制器的中断
下图中RXFIFO和TXFIFO的最多可以保存128个数据。可以通过设置TX FIFO或者RX FIFO的Threshold寄存器设置TX FIFO的将满中断以及RX FIFO的将空中断中FIFO的数据量。
f7830b69ec7b47fd90c18a68d1a42ad1.jpg
以下这种图表示了中断相关寄存器的设置关系。
5b62ef75619c42ddad70696484e90758.jpg
4.2 SPI控制器的寄存器
XSPIPS_CR寄存器XSPIPS_CR_OFFSET (0x00U)
                        
Field Name
                        
                        
Bits
                        
                        
Type
                        
                        
Reset Value
                        
                        
Description
                        
                        
保留
                        
                        
31:18
                        
                        
RO
                        
                        
0x0
                        
                        
保留
                        
                        
Modefail_gen_en
                        
                        
17
                        
                        
WR
                        
                        
0x1
                        
                        
模式失败生成启动
                        
1:使能,当总线冲突导致模式设置失败
                        
0:禁用
                        
                        
MANSTRT
                        
                        
                        
16
                        
                        
WO
                        
                        
0x0
                        
                        
Master启动命令
                        
1:使能
                        
0:禁用
                        
                        
Man_start_en
                        
                        
15
                        
                        
WR
                        
                        
0x0
                        
                        
手动启动使能
                        
1:使能
                        
0:禁用
                        
                        
Manual_CS
                        
                        
14
                        
                        
WR
                        
                        
0x0
                        
                        
手动CS
                        
1:手动模式
                        
0:自动模式
                        
                        
CS
                        
                        
13:10
                        
                        
WR
                        
                        
0x0
                        
                        
外设选择
                        
xxx0:Slave0选通
                        
xx01:Slave1选通
                        
x010:Slave2选通
                        
0111:保留
                        
1111:没有Slave选通
                        
                        
PERI_SEL
                        
                        
9
                        
                        
WR
                        
                        
0x0
                        
                        
外设译码选择
                        
1:支持3-8译码
                        
0:支持1~3个外设
                        
                        
REF_CLK
                        
                        
8
                        
                        
                        
                        
0x0
                        
                        
参考时钟
                        
1:不支持
                        
0:使用SPI REFERENCE CLOCK
                        
                        
保留
                        
                        
7:6
                        
                        
RO
                        
                        
0x0
                        
                        
保留
                        
                        
BAUD_RATE_DIV
                        
                        
5:3
                        
                        
WR
                        
                        
0x0
                        
                        
分频器
                        
只有Master模式才支持对spi_ref_clk分频
                        
000:不支持
                        
001:4分频
                        
010:8分频
                        
011:16分频
                        
100:32分频
                        
101:64分频
                        
110:128分频
                        
111:256分频
                        
                        
CPHA
                        
                        
2
                        
                        
WR
                        
                        
0x0
                        
                        
时钟相位
                        
1:在SCLK第2个时钟沿采样
                        
0:在SCLK第1个时钟沿采样
                        
                        
CPOL
                        
                        
1
                        
                        
WR
                        
                        
0x0
                        
                        
时钟极性
                        
1:在SCLK上升沿采样
                        
0:在SCLK下降沿采样
                        
                        
MSTREN
                        
                        
0
                        
                        
WR
                        
                        
0x0
                        
                        
模式选择
                        
1:主机模式
                        
0:从机模式
                        

XSPIPS_SR寄存器XSPIPS_SR_OFFSET (0x04U)
中断状态寄存器,当相应的中断产生后,中断状态寄存器相应的位置1,写1清零
                        
Field Name
                        
                        
Bits
                        
                        
Type
                        
                        
Reset Value
                        
                        
Description
                        
                        
保留
                        
                        
31:7
                        
                        
RO
                        
                        
0x0
                        
                        
31~7bit:保留
                        
                        
TX_FIFO_underflow
                        
                        
6
                        
                        
WTC
                        
                        
0x0
                        
                        
TX FIFO下溢
                        
1:溢出
                        
0:未溢出
                        
                        
RX_FIFO_full
                        
                        
5
                        
                        
WTC
                        
                        
0x0
                        
                        
RX FIFO满
                        
1:满
                        
0:未满
                        
                        
RX_FIFO_not_empty
                        
                        
4
                        
                        
WTC
                        
                        
0x0
                        
                        
RX FIFO非空
                        
1:FIFO数据大于等于THRESHOLD
                        
0:FIFO数据小于THRESHOLD
                        
                        
TX_FIFO_full
                        
                        
3
                        
                        
WTC
                        
                        
0x0
                        
                        
TX FIFO满
                        
1:满
                        
0:未满
                        
                        
TX_FIFO_not_full
                        
                        
2
                        
                        
WTC
                        
                        
0x0
                        
                        
TX FIFO将满
                        
1:FIFO数据小于THRESHOLD
                        
0:FIFO数据大于等于THRESHOLD
                        
                        
MODE_FAIL
                        
                        
1
                        
                        
WTC
                        
                        
0x0
                        
                        
SPI 模式错误
                        
表示管脚 n_ss_in上的电压与SPI模式不一致。如果 n_ss_in在主机模式(多主机竞争)下为低电平,或者n_ss_in在从机模式下传输期间变为高电平,则设置 =1。这些条件将清除 spi_enable 位并禁用SPI。该位仅在系统复位时复位,
                        
并且仅在读取该寄存器时清零。 ModeFail 中断,向该位写入1清除。
                        
1:产生模式错误
                        
0:没有错误
                        
                        
RX_OVERFLOW
                        
                        
0
                        
                        
WTC
                        
                        
0x0
                        
                        
接收溢出中断
                        
1:溢出
                        
0:未溢出
                        

XSPIPS_IER寄存器XSPIPS_IER_OFFSET (0x08U)
中断使能寄存器,对应于之前的中断状态寄存器,设置1为使能相关中断
                        
Field Name
                        
                        
Bits
                        
                        
Type
                        
                        
Reset Value
                        
                        
Description
                        
                        
保留
                        
                        
31:7
                        
                        
RO
                        
                        
0x0
                        
                        
保留
                        
                        
TX_FIFO_underflow
                        
                        
6
                        
                        
WO
                        
                        
0x0
                        
                        
TX FIFO下溢中断使能
                        
                        
RX_FIFO_full
                        
                        
5
                        
                        
WO
                        
                        
0x0
                        
                        
RX FIFO满中断使能
                        
                        
RX_FIFO_not_empty
                        
                        
4
                        
                        
WO
                        
                        
0x0
                        
                        
RX FIFO非空中断使能
                        
                        
TX_FIFO_full
                        
                        
3
                        
                        
WO
                        
                        
0x0
                        
                        
TX FIFO满中断使能
                        
                        
TX_FIFO_not_full
                        
                        
2
                        
                        
WO
                        
                        
0x0
                        
                        
TX FIFO非满中断使能
                        
                        
MODE_FAIL
                        
                        
1
                        
                        
WO
                        
                        
0x0
                        
                        
SPI 模式错误中断使能
                        
                        
RX_OVERFLOW
                        
                        
0
                        
                        
WO
                        
                        
0x0
                        
                        
接收溢出中断中断使能
                        

XSPIPS_IDR寄存器XSPIPS_IDR_OFFSET (0x0CU)
中断禁用寄存器, 对应于之前的中断状态寄存器,设置1为禁用相关中断
                        
Field Name
                        
                        
Bits
                        
                        
Type
                        
                        
Reset Value
                        
                        
Description
                        
                        
保留
                        
                        
31:7
                        
                        
RO
                        
                        
0x0
                        
                        
保留
                        
                        
TX_FIFO_underflow
                        
                        
6
                        
                        
WO
                        
                        
0x0
                        
                        
TX FIFO下溢中断禁用
                        
                        
RX_FIFO_full
                        
                        
5
                        
                        
WO
                        
                        
0x0
                        
                        
RX FIFO满中断禁用
                        
                        
RX_FIFO_not_empty
                        
                        
4
                        
                        
WO
                        
                        
0x0
                        
                        
RX FIFO非空中断禁用
                        
                        
TX_FIFO_full
                        
                        
3
                        
                        
WO
                        
                        
0x0
                        
                        
TX FIFO满中断禁用
                        
                        
TX_FIFO_not_full
                        
                        
2
                        
                        
WO
                        
                        
0x0
                        
                        
TX FIFO非满中断禁用
                        
                        
MODE_FAIL
                        
                        
1
                        
                        
WO
                        
                        
0x0
                        
                        
SPI 模式错误中断禁用
                        
                        
RX_OVERFLOW
                        
                        
0
                        
                        
WO
                        
                        
0x0
                        
                        
接收溢出中断禁用
                        

XSPIPS_IMR寄存器XSPIPS_IMR_OFFSET (0x10U)
中断掩码寄存器, 对应于之前的中断状态寄存器、中断使能寄存器、中断禁用寄存器,1代表相关中断禁用
                        
Field Name
                        
                        
Bits
                        
                        
Type
                        
                        
Reset Value
                        
                        
Description
                        
                        
保留
                        
                        
31:7
                        
                        
RO
                        
                        
0x0
                        
                        
保留
                        
                        
TX_FIFO_underflow
                        
                        
6
                        
                        
RO
                        
                        
0x0
                        
                        
TX FIFO下溢中断掩码
                        
                        
RX_FIFO_full
                        
                        
5
                        
                        
RO
                        
                        
0x0
                        
                        
RX FIFO满中断掩码
                        
                        
RX_FIFO_not_empty
                        
                        
4
                        
                        
RO
                        
                        
0x0
                        
                        
RX FIFO非空中断掩码
                        
                        
TX_FIFO_full
                        
                        
3
                        
                        
RO
                        
                        
0x0
                        
                        
TX FIFO满中断掩码
                        
                        
TX_FIFO_not_full
                        
                        
2
                        
                        
RO
                        
                        
0x0
                        
                        
TX FIFO非满中断掩码
                        
                        
MODE_FAIL
                        
                        
1
                        
                        
RO
                        
                        
0x0
                        
                        
SPI 模式错误中断掩码
                        
                        
RX_OVERFLOW
                        
                        
0
                        
                        
RO
                        
                        
0x0
                        
                        
接收溢出中断掩码
                        

XSPIPS_ER寄存器XSPIPS_ER_OFFSET (0x14U)
SPI使能寄存器
                        
Field Name
                        
                        
Bits
                        
                        
Type
                        
                        
Reset Value
                        
                        
Description
                        
                        
保留
                        
                        
31:1
                        
                        
RO
                        
                        
0x0
                        
                        
保留
                        
                        
SPI_EN
                        
                        
0
                        
                        
WR
                        
                        
0x0
                        
                        
1:使能SPI
                        
0:禁止SPI
                        

XSPIPS_DR寄存器XSPIPS_DR_OFFSET (0x18U)
SPI的延迟寄存器用于控制选通到非选通、非选通到选通、当前WORD最后bit到下个WORD第1bit、选通到第一个Bit开始的延迟参数。
                        
Field Name
                        
                        
Bits
                        
                        
Type
                        
                        
Reset Value
                        
                        
Description
                        
                        
d_nss
                        
                        
31:24
                        
                        
RW
                        
                        
0x0
                        
                        
选通到取消选通延迟
                        
Master模式,当cpha=0时,设置SPI REFERENCE CLOCK或ext_clk个周期的延迟。
                        
                        
d_btwn
                        
                        
23:16
                        
                        
RW
                        
                        
0x0
                        
                        
取消选通到选通的延迟
                        
从取消选通到选通之间延迟SPI REFERENCE CLOCK或ext_clk个周期
                        
                        
d_after
                        
                        
15:8
                        
                        
RW
                        
                        
0x0
                        
                        
最后1Bit到下1bit间延迟
                        
当前WORD的最后1Bit到下个WORD的第1bit间延迟SPI REFERENCE CLOCK或ext_clk个周期
                        
                        
d_int
                        
                        
7:0
                        
                        
RW
                        
                        
0x0
                        
                        
nss低电平到第1bit的延迟
                        
低电平到第1bit间延迟SPI REFERENCE CLOCK或ext_clk个周期
                        

XSPIPS_TXD寄存器XSPIPS_TXD_OFFSET (0x1CU)
SPI的发送数据寄存器
                        
Field Name
                        
                        
Bits
                        
                        
Type
                        
                        
Reset Value
                        
                        
Description
                        
                        
TX_FIFO_data
                        
                        
31:0
                        
                        
WO
                        
                        
0x0
                        
                        
7~0bit:数据寄存器写入这个寄存器的数据会写入FIFO
                        

XSPIPS_RXD寄存器XSPIPS_RXD_OFFSET (0x20U)
SPI的接收数据寄存器
                        
Field Name
                        
                        
Bits
                        
                        
Type
                        
                        
Reset Value
                        
                        
Description
                        
                        
RX_FIFO_data
                        
                        
31:0
                        
                        
RW
                        
                        
0x0
                        
                        
7~0bit:从接收FIFO读出的数据
                        

XSPIPS_SICR寄存器XSPIPS_SICR_OFFSET (0x24U)
SPI的SLAVE启动对于总线时钟监测设置
                        
Field Name
                        
                        
Bits
                        
                        
Type
                        
                        
Reset Value
                        
                        
Description
                        
                        
保留
                        
                        
31:8
                        
                        
RW
                        
                        
0x0
                        
                        
保留
                        
                        
Slave_Idle_coun
                        
                        
7:0
                        
                        
rw
                        
                        
0xff
                        
                        
7~0bit:当外部主机输出的SCLK时钟稳定的输入Slave_Idle_coun个SPI参考时钟周期或者SPI被取消选择,则SPI  SLAVE模式会检测到启动
                        

XSPIPS_TXWR寄存器XSPIPS_TXWR_OFFSET (0x28U)
XSPIPS_TXWR将满值
                        
Field Name
                        
                        
Bits
                        
                        
Type
                        
                        
Reset Value
                        
                        
Description
                        
                        
Threshold_of_TX_FIFO
                        
                        
31:0
                        
                        
RW
                        
                        
0x1
                        
                        
设置TX FIFO将满值
                        

RX_thres_reg0寄存器RX_thres_reg0_OFFSET (0x2CU)
设置RX FIFO的将空值
                        
Field Name
                        
                        
Bits
                        
                        
Type
                        
                        
Reset Value
                        
                        
Description
                        
                        
Threshold_of_RX_FIFO
                        
                        
31:0
                        
                        
RW
                        
                        
0x1
                        
                        
设置RX FIFO将空值
                        

Mod_id_reg0寄存器Mod_id_reg0 (0xFCU)
这个寄存器暂时不清楚作用
                        
Field Name
                        
                        
Bits
                        
                        
Type
                        
                        
Reset Value
                        
                        
Description
                        
                        
保留
                        
                        
31:25
                        
                        
RO
                        
                        
0x0
                        
                        
保留
                        
                        
module_ID
                        
                        
24:0
                        
                        
RO
                        
                        
0x90106
                        
                        
模块ID号
                        
5硬件电路分析
FEP-BASE-CARD是米联客设计开发用于支持一些基本的FPGA接口学习的模块,可以支持SPI动态驱动数码管实验、RTC实验、EEPROM实验、液晶屏实验、PL串口实验,以及通过CEP扩展到GPIO可以支持LVDS实验、GPIO验证、DVP摄像头连接
FEP-BASE-CARD分3.3V和1.8V版本,由于默认IO采用1.8V因此,这里仅介绍1.8V版本,我们本方案只需要短接MISO和MOSI就可以完成环路测试.
6797680831dc493fb96704c66c4e2bea.jpg
配套工程的FPGA PIN脚定义路径为soc_prj/uisrc/04_pin/ fpga_pin.xdc。
68835072dd134b258a412c4815aba45d.jpg
6搭建SOC系统工程
详细的搭建过程这里不再重复,对于初学读者如果还不清楚如何创建SOC工程的,请学习“01Vitis Soc开发入门”这篇文章。
6.1SOC系统工程
dac37155f1b042f684fb6c3c80a3fc59.jpg
ZYNQ IP中设置SPI0
faca60352b3c42b0b0df3d1d9e05b760.jpg
设置SPI的参考时钟,以及PL 50M时钟提供给ILA使用
a794a615dee54ca7bbf652b4aec0f923.jpg
ILA设置
7ac30f7912204aa585f5a7b2a8f3912e.jpg
6.2编译并导出平台文件
以下步骤简写,有不清楚的看第一篇文章。
1:单击Block文件à右键àGenerate the Output ProductsàGlobalàGenerate。
2:单击Block文件à右键à Create a HDL wrapper(生成HDL顶层文件)àLet vivado manager wrapper and auto-update(自动更新)。
3:添加配套工程路径下uisrc/04_pin/fpga_pin.xdc约束文件
4:生成Bit文件。
5:导出到硬件: FileàExport HardwareàInclude bitstream
6:导出完成后,对应工程路径的soc_hw路径下有硬件平台文件:system_wrapper.xsa的文件。根据硬件平台文件system_wrapper.xsa来创建需要Platform平台。
e566dd2074e548e1a5cc61af2548c637.jpg
​​7搭建Vitis-sdk工程
创建soc_base sdk platform和APP工程的过程不再重复,如果不清楚请参考本章节第一个demo。
7.1创建SDK Platform工程
17d992c6599249879cd3119c173dca8f.jpg
右击soc_base编译,编译的时间可能会有点长
7.2创建APP工程
be98d9c45f7f444baee5f17513668499.jpg
8spi polled模式程序分析
8.1SpiPs_Init(SPI_DEVICE_ID)函数
1:XSpiPs_LookupConfig(SpiDeviceId)函数
f1c03633694c46618628c91b30ab3074.jpg
首先依然是通过查找配置程序来获取SPI控制器的硬件配置。我们跟踪这个程序,看看他获取的配置是什么。
d7abfb73805c4b5a9da70c136f87383b.jpg
右击参数打开参数定义
51ea1299cf074881bacf58aa9ca72c9f.jpg
可以看到,这个数组里存放的是SPI设备ID、SPI控制器的基地址,SPI的时钟。
0e9d82ccccd54828abbc37d02099460e.jpg
可以继续右击这些参数定位到这些参数的定义
e5e615f9f40f4575ab7a1b6e6e91b27c.jpg
在xparameters.h中找到如下定义,可以看到spi的基地址和SPI时钟
89bf0811b605414aab286674fd534672.jpg
2:XSpiPs_CfgInitialize((&SpiInstance), SpiConfig,SpiConfig->BaseAddress)函数
a821ae2d12a841bcb800726695035943.jpg
2.1: XSpiPs *InstancePtr
XSpiPs结构体定义了包括SPI数据收发缓存指针、还剩下的数据量未传输、忙状态,主机或从机模式、回调函数、回调函数的参数。
ff868c3060ef44bd9e14d35c4ca467cf.jpg
2.2XSpiPs_Reset(InstancePtr)函数
5e503a00039345e5a59fc92276ce38b5.jpg
2.3SPI配置寄存器
fc373003804c4bac99c5ca23e9ace79b.jpg
SPI的配置寄存器偏移地址:XSPIPS_CR_OFFSET = 0x00
设置XSPIPS_CR_RESET_STATE模式失败生成启用,这个资料没有详细说明大概的意思是用于多主机模式的系统中。以下是 SPI配置寄存器的功能说明
9598a59f11a641dfadb736a3f645ed80.jpg
dc2ac655af01447a9d8a8d1806e634fa.jpg
3:XSpiPs_SetOptions((&SpiInstance),  XSPIPS_MASTER_OPTION)
SPI默认是Slave模式,所以我们必须设置的是Master模式,我们来进入这个函数继续分析。
04f46565648a4112be63d61e2c592ba2.jpg
3.1XSpiPs_ReadReg(InstancePtr->Config.BaseAddress,XSPIPS_CR_OFFSET)
这个函数首先读取配置寄存器的值
3.2接下来是一个for循环
e916ccd816a9455a9c2c7da86cbe625c.jpg
在这个for循环中,关键是通过传递进来的Options变量和OptionsTable查表比对,然后设置相应的功能位。我们这里传递进来的参数是:
XSPIPS_MASTER_OPTION,用于设置SPI位主机模式;
XSPIPS_FORCE_SSELECT_OPTION设置强制从机选择;
97e196670524447faf66f70e78e005e7.jpg
最后计算结果配置寄存器的低16bit 00xx_xx0x_xxxx_x001
5e3f7f85704041298fb74c22f9075b71.jpg
fd667caf288c4818a2c4b0032434d7e8.jpg
可以得出CPOL=0 CPHA=0 SCK空闲低电平,第一个SCLK的跳变沿接收数据
150453463e0a46ed8a215b3e5b4016dd.jpg
9a564545cf964b718d213a02cf2769a7.jpg
3.3 XSpiPs_Disable(InstancePtr)函数
这段代码的意思是如果要切换SPI的CPOL-CPHA的模式,则先禁止SPI控制器,然后再写入
13c62e32396b4541b6d075a8d1c19bc8.jpg

Enable/Disable寄存器的地址偏移XSPIPS_ER_OFFSET=0x14
f3444940895645ed9606c346cbd6033c.jpg
3.3XSpiPs_Enable(SpiInstance)函数
作用和XSpiPs_Disable(InstancePtr)相反,使能SPI控制器
4:XSpiPs_SetClkPrescaler(&SpiInstance, XSPIPS_CLK_PRESCALE_64)函数
这个函数设置SPI的时钟分频参数
b10e021a59e5487d8d1c069ed4989d16.jpg
参数XSPIPS_CLK_PRESCALE_64 =0x05,所以设置64分频
f026c76095e147a2bb5a33d0485fad5b.jpg
5:XSpiPs_SetSlaveSelect(&SpiInstance, 0x01)
XSpiPs_SetSlaveSelect(XSpiPs *InstancePtr, u8 SlaveSel)函数用来设置被选择的从设备,通常来说,可以选择3个从设备,但是如果通过三八译码器,最多可以支持8个从设备的选择,一次只能选择一个从设备。
d0cace4d79fa4209adee227cc6fc4a36.jpg
7.1XSpiPs_IsDecodeSSelect( InstancePtr )函数
3fa26434fc12485ca5365b803ac1917a.jpg
793f72dd7b514ac08834043d62dafdc3.jpg

以上代码中先通过XSpiPs_IsDecodeSSelect( InstancePtr )函数获取当前SPI 配置寄存器的值,然后对其中OptionsTable的值进行判断,以获取当然的Options值。(XSpiPs_GetOptions(InstancePtr)函数定义如下:

eaece6c1e1c0408596161d17af9961d0.jpg
关于OptionsTable的介绍,在前面也介绍过,这里再次给出定义:
3c71c7a95f714d5f9439e76753e0ffa3.jpg
所以这段代码最终的目的时判单从设备选项是否已经设置了从设备选择方式,相关的寄存器功能如下:
becc08d633eb49e5b36bb90d481490f7.jpg
我们这里没有用到三八译码方式,所以这一位为0,所以以上代码会执行else分支的部分,并且设置配置寄存器的
13~10位。
99186e8c94bb4075927251c6d81ccbe1.jpg
8.2SpiPs_Send(&SpiInstance,SendBuf,10)函数
00af5d07479949928ed77a242ccac18e.jpg
这里为了完成数据的回传,把tx和rx短接。SPI控制器的发送和接收本质就是移位寄存器,每个SCK时钟移出或者移入1位数据。
c50b98608c2d44f1ac8155114942c740.jpg
所以对于发送移位寄存器:不管是发数据,还是收数据,SPI的发送移位控制器都会把发送寄存器里面的数据发出,接收控制器的移位寄存器都会把数据移位输入;
所以对于接收移位寄存器:不管是发数据,还是收数据,SPI的发送移位控制器都会把发送寄存器里面的数据发出,接收控制器的移位寄存器都会把数据移位输入;
接下来我们主要分析XSpiPs_PolledTransfer(IntcInstancePtr, SendBuffer, ReadBuf,ByteCount)函数。这个函数负责SPI数据的收发。因为上面我们也分析了,对于SPI不管是发送数据,还是接收数据,其实收发 过程都是在发生的。
d23960659c14407bba0a3055fc44a753.jpg
以上代码中,在大while循环中完成所有SPI数的收发。在第一个被框选的代码中完成数的发送,在第二个框选的代码中完成数据的接收。下面我们对整个函数的流程做一个分析:
1:从设备选择是否是自动还是手动
5e61a68125a847dbbb3df9e4f08d6110.jpg
这里也是通过XSpiPs_GetOptions函数判断,这个分析过程在前面代码已经分析过
69af9130f34b4bf3bfb8b477d2f0cd96.jpg
2:XSpiPs_Enable(InstancePtr)
8dc32bd5d7134b868e3db489b41236d6.jpg
这个函数使能SPI控制器
a7614c3aea374c60bfefc1d43ab3c3a8.jpg
3:数据发送
3.3.1写数据到FIFO
这部分代码判断需要发送的数据是否小于SPI FIFO深度的大小,如果是则把数据都发送,直到达到SPI FIFO深度
5f4f056cdc2b4f8fac7cea33af8571ea.jpg
9340b3936bac425ba9aa69a9b2b491d1.jpg
SPI发送数据寄存器XSPIPS_TXD_OFFSET=0x1C
fb8a41b12c5445d58002d52bcf86cb74.jpg
3.3.2自动模式还是主动模式
我们是自动模式,再初始化阶段已经完成了寄存器的配置
7f7fd887f78448ffa1c04db8e68d1b11.jpg
3.3.3等待数据发送完毕
通过读取状态寄存器,判单是否传输完毕
dd1188a3a76249828850ed4bbf7bfa03.jpg
SPI状态寄存器的偏移地址XSPIPS_SR_OFFSET = 0x04
cb9d17c7fbe7448993ca2bc8323b0697.jpg
这里还有一个寄存器,TX阈值寄存器,这个寄存器的值和XSPIPS_IXR_TXOW_MASK位相关,当TX的FIFO数据量小于这个阈值XSPIPS_IXR_TXOW_MASK置1.后面的中断程序分析中,中断的触发和这个置的设置也有关系。默认是1,那么当TxFIFO的数据为0的时候XSPIPS_IXR_TXOW_MASK置1。当使能了中断传输就会触发中断。
7a8d1005177e4796a3a0396dddf57d19.jpg
4:数据接收
以下代码中,通过判断TransCount值,直到发送了多少数据,那么RXFIFO就会接收多少数据。直接读SPI的RX数据寄存器。
4a4d8a6cca7d4935a4f6d94d3edc2042.jpg
e651f5a9b9a54f409d4ed61f06b1dce3.jpg
SPI的RX数据寄存器地址偏移XSPIPS_RXD_OFFSET= 0x20
59d2bd814f22483cb54ab932c25a9431.jpg
5:停止SPI传输
当一次传输完毕后,如果手动模式需要手动设置XSPIPS_CR_SSCTRL_MASK相关位。我们这里是自动模式,所以if里面的代码不被执行。
67f8cca62b2e4f23a02e9bd3b8786104.jpg
1571faf902ba44f6a28354a75eafd604.jpg
6: XSpiPs_Disable(InstancePtr)函数
停止SPI控制器
1f8cbbd3dc5941b9acf67e50ea75b017.jpg
8.3SpiPs_Read(&SpiInstance,ReadBuf,10)函数
f4fa8537082c4848a689e8a495fdbae2.jpg
370f896c0b7040f2990306980b864283.jpg
前面用SpiPs_Send实际上已经把数据接收到了RevBuf了,这次再次传输会再发送端继续传输RevBuf的值,并且接收到ReadBuffer。这就完成了本文需要演示的loop功能。
​​ 9spi interrupt模式程序分析
前面我们已经详细分析了polled模式下的工作机制,对于中断模式,数据传输结束后触发中断。其他的内容都非常类似。而且大家学习米联客的代码,很多代码具备类似的结构。中断部分亦是如此。中断部分介绍有不少重复类似的分析过程,我们依然再次说明,已经熟悉我们代码结构的读者可以提高效率,跳过一部分分析代码。
9.1init_intr_sys函数
  1. void init_intr_sys(void) {
  2. Init_Intr_System(&Intc);
  3. Init_SpiPs(&SpiInstance,SPI_DEVICE_ID);
  4. SpiPs_Setup_IntrSystem(&Intc, &SpiInstance, SPI_INTR_ID); Setup_Intr_Exception(&Intc);
  5. }
复制代码

此函数在程序文件spi_test.c中通过调用相关中断函数实现中断功能。为了实现多类型中断,用户必须根据以下方式设置中断。
9.2Init_Intr_System(&Intc)函数
  1. int Init_Intr_System(XScuGic * IntcInstancePtr)
  2. {
  3.         int Status;

  4.         XScuGic_Config *IntcConfig;
  5.         /*
  6.          * Initialize the interrupt controller driver so that it is ready to
  7.          * use.
  8.          */
  9.         IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
  10.         if (NULL == IntcConfig) {
  11.                 return XST_FAILURE;
  12.         }

  13.         Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,
  14.                                         IntcConfig->CpuBaseAddress);
  15.         if (Status != XST_SUCCESS) {
  16.                 return XST_FAILURE;
  17.         }
  18.         return XST_SUCCESS;
  19. }
复制代码

1:XScuGic_LookupConfig(INTC_DEVICE_ID) 函数
5ffc4c60f54c4d5a8f2b753f1ce59fc6.jpg
右击XScuGic_ConfigTable查看参数定义:
288fd5e3f1364c2f82a429a7195798de.jpg
可以继续右击以下参数查看其定义
e10ecec4ea1a459082d9b67df4d7a1bd.jpg
可以看到这里定义了GIC中断控制器的基地址
2882a449c8dd49e39c7d3f48ff5443ac.jpg
2: XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,IntcConfig->CpuBaseAddress)
中断部分主要内容是回调函数的设置,以下回调函数相关参数定义如下:
3c852a39b5304d9ea63e2a231da62f57.jpg
以下代码对所有为定义的全局中断进行定义回调函数和回调参数。
a28aa6153d134c70b7f643291f09c025.jpg
StubHandler函数定义如下:
cd406e4af3c2417e865374a3765020f1.jpg
9.3Setup_Intr_Exception函数
  1. void Setup_Intr_Exception(XScuGic * IntcInstancePtr)
  2. {
  3.         /* Enable interrupts from the hardware */
  4.         Xil_ExceptionInit();
  5.         Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
  6.                         (Xil_ExceptionHandler)XScuGic_InterruptHandler,
  7.                         (void *)IntcInstancePtr);
  8.         Xil_ExceptionEnable();
  9. }
复制代码

这个函数中对设置全局中断回调函数,以及使能全局中断
1:Xil_ExceptionInit()函数
这个函数目前说明都没做,只是未来保留兼容性,预留在这里。
2d9e6c7080fe4c78a29959e26e90147d.jpg
2:Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler,(void *)IntcInstancePtr)函数 aba20f440ccd48e7bec66b8084801dc8.jpg
2.1XIL_EXCEPTION_ID_INT定义
b025f998cf754d51864c14839262e4a5.jpg
12a8be1f49544820b392862c9e8b4ccc.jpg
2.2: XExc_VectorTableEntry定义
任何的中断都可以理解位异常处理,这里定义了MPSOC或者ZYNQ支持的异常处理类型。
49be02432a3d4cddbb023384b6d7d292.jpg
2.3XScuGic_InterruptHandler函数
可以看到这个函数会根据读取到的中断号调用相应的回调函数,这个回调函数会在具体的外设中断初始化中设置。
8765f7484a7846c1813fbfee41fa18a8.jpg
2.3中断异常回调函数
37373590a5d44606bed9a4c49b1ac980.jpg
由于XIL_EXCEPTION_ID_INT=2所以Xil_ExceptionNullHandler在中断产生的时候会被调用。
ec866463d90742e4b26ccda9ac2b2ada.jpg
a958fc40751546d1bb99870e1c2ea16c.jpg
3:Xil_ExceptionEnable()函数
这条函数最终指向了汇编指令:
205eaf5b1e63483fb308b58fbb7c114d.jpg
e0bdbedda9764b34a49302392a088a08.jpg
ecec863a56164ec0aa0a8f0089028586.jpg
9.4Init_SpiPs (&SpiInstance,SPI_DEVICE_ID)函数
此函数内容部分和SPI Polled模式一样,这里不再重复。
9.5SpiPs_Setup_IntrSystem(&Intc, &SpiInstance, SPI_INTR_ID)函数
此函数负责设置中断的回调函数,中断回调函数一般分2此,第一次是系统中断函数回调,每次控制器完成一次数据传输都会中断,第二次是用户的函数回调,全部数据传输完,系统中断函数里面回调用户回调函数。
这里函数XSpiPs_InterruptHandler就是系统中断函数,SpiHandler是用户回调函数。
a5e534d629bb4afe94d7fccde4081fad.jpg
1:XScuGic_Connect(IntcInstancePtr, SpiIntrId, (Xil_ExceptionHandler)XSpiPs_InterruptHandler, (void *)SpiInstancePtr)
这个函数负责把对应中断号从回调函数,以及回调参数,连接到之前在Init_Intr_System(&Intc)函数中定义的回调函数。
14213d596bdd424d922f97c03ef04be6.jpg
2:XSpiPs_InterruptHandler(XSpiPs *InstancePtr)函数
2.1清中断禁用中断
进入中断函数后需要立马清除中断,和禁用中断,否则可能再次产生中断。
1b16a3583dda408a8c969046cc87cbad.jpg
2.2判断模式错误
如果传输发送错误,直接停止传输,并且调用用户回调函数
bd348025d2e5453b8171488de33aad15.jpg
2.3数据传输
d7d3187322324125968c01d2deeffc9d.jpg
首先判断是否有数据已经发送完了,通过判断XSPIPS_IXR_TXOW_MASK位
9ed3dbe4456c49c88e3428f0dd1f3db4.jpg
接着一个while循环,完成数据的接收。读者如果对SPI传输还不明白的看看Polled模式介绍。SPI发送和接收是同时进行的。
2.3判断数据是否完成传输
以下代码中判断数据是否完成传输,如果已经传输结束,则禁用中断、释放SPI选通信号、停止SPI传输、调用用户回调函数。
否则重新使能中断。
349d755dd5644a27b2112fa870da1ea2.jpg
2.4检查上溢和下溢错误
判断发送FIFO和接收FIFO是否存在下溢(读空)和上溢(写满)错误。
a6ebc3c4c32b4a50a2d43f80a88b88bf.jpg
3:XSpiPs_SetStatusHandler(SpiInstancePtr, SpiInstancePtr,(XSpiPs_StatusHandler) SpiHandler)函数
设置用户回调函数
e52d386a90dc45299019d20067aa4d0c.jpg
4: SpiHandler(void *CallBackRef, u32 StatusEvent, unsigned int ByteCount)
通知已经完成传输,以及通知错误的情况。
9f9e9ae637d34819920ba28da2610134.jpg
10实验结果
10.1硬件准备
本实验需要用到 JTAG 下载器、USB 转串口外设,另外需要把核心板上的 2P 模式开关设置到 JTAG 模式,即 ON ON(注意新版本的 MLK_H3_CZ08-7100-MZ7100FC),支持 JTAG 模式,对于老版本的核心板,JTAG 调试的时候 一定要拔掉 TF 卡,并且设置模式开关为 OFF OFF)
MLK_H3_CZ08-7100-MZ7100FC 支持跳线帽修改 FEP 或者 FMC IO BANK  电压,默认设置 1.8V,本实验需要用到 FEP-BASE-CARD-1.8V,短接用于 MISO 和 MOSI 的短接帽。
7c9b356d7bc949e0b045485fef638966.jpg
10.2实验结果
Polled模式
dc6aa02955c545169a71bec82b7198e9.jpg
中断模式
96e0942e19704a35a17ef293f2c45fa9.jpg
通过在线逻辑分析仪观察数据
9a758c3201cd4cbca145fc3ec8471e84.jpg

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则