SPI概述
串行外设接口(SPI)是一种短距离串行通信接口,它使用高速时钟(与I2C相比),适用于更高的数据速率。SPI接口有多种不同的串行通信变体,但四线接口是最流行的一种。这四个信号是:
- SCLK(串行时钟):用于同步数据传输的时钟信号。
- MOSI(主出从入):主机发送数据到从机的线路。
- MISO(主入从出):从机发送数据到主机的线路。
- CS(片选):用于选择与主机通信的从设备的信号
nRF54L的SPI资源
- SPI设备
SPIO0
SPI20, SPI21, SPI22
SPI30 - 每组SPI都可以配置为SPIM或者SPIS
- 像nRF53,52一样,SPI外设与具有相同ID的其他外设共享寄存器和其他资源。

SPIM设备
- EasyDMA直接传输到RAM和从RAM传输
- SPI模式 [0...3】
- 独立选择1/O引脚

SPIS设备
- EasyDMA直接传输到RAM和从RAM传输
- SPI模式[0...3】
- 独立选择1/O引脚
- 基于硬件的信号量:机制,用于SPIS和CPU之间同步访问数据缓冲区

SPI 模式
- SPI模式0-3
- CPOL决定了SPI时钟信号(SCK)的空闲状态电平。
CPOL=0:表示SCK在空闲状态时保持低电平。
CPOL=1:表示SCK在空闲状态时保持高电平。 - CPHA决定了数据在SCK的哪个边沿被采样。
CPHA=0:表示数据在SCK的第一个跳变沿被采样。
CPHA=1:表示数据在SCK的第二个跳变沿被采样。
- CPOL决定了SPI时钟信号(SCK)的空闲状态电平。
- CPOL和CPHA的组合产生了四种SPI模式
例如模式2,CPOL=1CPHA=O.SCK空闲状态为高电平.数据在SCK的下降沿被采样

SPI配置
- 片选极性
CSNPOL=O,低电平有效
CSNPOL=1,高电平有效 - 位序
MsbFirst最高位会在传输过程中最先被发送出去
LsbFirset最低位会在传输过程中最先被发送出去 - ORC(Over-read Character)
在接收数据时,如果主设备(SPIMaster)发送的数据比预期的多,ORC就会填充这些额外的字节
SPI的管脚使用以及时钟配置

SPI20/21使用P2的属于跨域
SPI 时钟软件限制



SPI设备片选管脚的使用
- SPIM片选信号在zephyr SPI中使用软件片选,也就是只要这个管脚只要具有GPIO功能就可以,因此可以使用本域以外的管脚。
- 如果SPIM需要使用硬件片选,那么也要遵循上面表格的要求,并且需要直接使用nrfx_spim驱动,并要使能NRFX_SPIM_EXTENDED_ENABLED
- SPIS片选不能使用GPIO,只能是硬件片选。


SPI管脚使用的其他注意事项
- SPISCK管脚需要使用时钟脚,关于哪些脚是时钟脚请参照规格书Pin assignments章节
- 虽然SPI20/21可以跨域使用GPIO2的专用管脚,但不是最节能的方式。跨域使用SPI20/21管脚时使用EngineeringB芯片时可能会有传输失败的问题,这时可以加入下面代码nrfx_power_constlat_mode_request()临时测试。加入这个代码功耗会有上升。(正式量产芯片要去掉这条代码!),这个问题已经在Revision1中修复了。(errata38)
errata32,对于CSP封装的Engineering B芯片,P1.09-P1.12由于辐射问题需:
串联一个3300或更大的串联电阻
尽可能保持PCB导线短且位于接地层之间
使用低于1MHz的切换速度
Zephyr SPi驱动
- Zephyr 使用设备模型来管理硬件设备,包括SPI控制器。每个SPI控制器在系统中都被表示为一个设备对象。
(设备模型 Academy Intermediate:Lesson 7- Device driver model) - 每个SPI控制器和SPI设备在系统中都表示为一个struct device 对象。这个对象包含了设备的配置信息和操作函数
Zephyr SPi驱动
- Zephyr 的SPI驱动支持nRF54L的SPIM和 SPIS 设备
- 代码实现
Zephyr/drivers/spi/spi_nrfx_spim.c
Zephyr/drivers/spi/spi_nrfx_spis.c - 使用步骤
Kconfig设置(Prj.conf)
配置设备树
调用SPIAPI控制SPI设备
配置文件
在prj.conf加入CONFIG_SPI=y
如何需要支持异步API,还要加入
CONFIG_SPI_AYNC=y
SPI M驱动
设备树的配置:


设备定义和配置
定义spi设备
- struct spi_dt_spec spispec spi_dt_spec =
SPI_DT_SPEC_GET(DT_NODELABEL(spim_dev), SPI_OP, cs_delay) - 片选极性,最大频率,orc,rx_delay等参数在device tree中获取
- spi_option_t类型定义了一个32位的标志位。可以使用#define SPI_OP组合下面的flag
- 使用SPI_WORD_SET(8)
SPI Mode 0-3 由SPI_MODE_CPOL 和SPI_MODE_CPHA组合,加入flag表示相应位为1
使用SPI_TRANSFER_MSB,SPI_TRANSFER_LSB表示位序,默认O表示SPI_TRANSFER_MSB
SPIM 同步API
- spi_transceive_dt(spec, tx_bufs, rx_bufs)
等同与spi_traneive(spec->bus, &spec-config,tx_bufs, rx_bufs) - spi_read_dt(spec, rx_bufs)
等同与spi_read(spec->bus, &spec-config, rx_bufs) - spi_write_dt(spec, tx_bufs)
等同与spi_read(spec->bus, &spec-config, tx_bufs)
说明:上面三个函数最终还是调用spi_transceive_dt

SPIM异步API-CallBack方式
- spi_tranceive_cb()
- Callback 参数result表示SPI是否传输成功。收到的数据被放在rx_bufs中
Zephyr SPi驱动vs nrfxSPi驱动
Zephyr SPI驱动
- 设备模型一致性:Zephyr提供统一的设备模型和API,使得驱动程序的开发和集成更加简便。
- 低功耗管理:集成了设备电源管理模块,用户可以轻松实现低功耗管理。
- 示例SPI模式3,先传输高位字节
nrfxSPI驱动
- 硬件层效率:更接近硬件层,效率更高。
- 高级功能支持:支持硬件片选和更多频率设置等高级功能。
#define SPI_OP SPI_WORD_SET(8) I SPI_ MODE_CPOL I SPI _MODE_CPHA