SPI 使用指南
1. 模块介绍
1.1. 术语定义
术语 | 定义 | 注释说明 |
---|---|---|
SPI | Serial Peripheral Interface | 串行外设接口 |
Dual SPI | Dual Serial Peripheral Interface | 双路 SPI |
Quad SPI | Quad Serial Peripheral Interface | 四路 SPI,又称 QSPI |
CPOL | Clock polarity | 时钟极性 |
CPHA | Clock phase | 时钟相位 |
1.2. 模块简介
SPI (Serial Peripheral Interface) 最初是 Motorola 提出的4线同步串行数据传输接口, 是一种高速、全双工的同步通信总线。由于其实现比较简单,没有专利限制等,因此在各种器件中得到广泛的应用。 SPI 总线是一种行业事实标准,并没有统一的标准化组织,不同厂商在实际应用中演化出多种工作模式。
SPI 总线接口的应用领域:
- 存储设备:Flash、SD、MMC、EEPROM 等
- 传感器:温度传感器、压力传感器等
- ADC/DAC
- Audio Codec
- LCD 显示屏幕
- 触摸屏幕
- RTC
- 数字电位计
- 游戏控制器等
Artinchip SPI 支持:
- 全双工、半双工模式
- DMA 读写模式
- CPU 读写模式
- 最高工作频率 100MHz
- 支持四线制模式:标准4线 SPI、DUAL SPI、QUAD SPI
- 支持三线制模式
- 数据位传输的模式可配置,CPOL 和 CPHA
1.2.1. 标准4线 SPI
这是一种四线制的 SPI 连接和工作模式。
图 7.35 四线制标准 SPI
1.2.2. DUAL SPI
主机端的 MISO 为 SIO0, MOSI 为 SIO1,常用于 SPI Flash。
图 7.36 四线制 DUAL SPI
1.2.3. QUAD SPI
主机端的 MOSI 为 IO0, MISO 为 IO1, WP 为 IO2, HOLD 为 IO3,常用于 SPI Flash。
图 7.37 四线制 QUAD SPI
1.2.4. 三线制 SPI
三线制 SPI 常用于工业控制类场景。这种接线方式,主机端使用 MOSI 作为 DIO。
图 7.38 三线制 SPI
1.2.5. CPOL 与 CPHA
CPHA 是时钟相位,CPOL 是时钟极性,两者的不同组合是 SPI 数据传输的不同模式。
CPHA | 说明 |
---|---|
0 | 数据采样在第1个边沿,数据发送在第2个边沿 |
1 | 数据采样在第2个边沿,数据发送在第1个边沿 |
CPOL | 说明 |
---|---|
0 | 空闲状态时,SCK 为低电平 |
1 | 空闲状态时,SCK 为高电平 |
Mode | 值 | 说明 |
---|---|---|
0 | CPOL=0, CPHA=0 | 空闲时,SCK 处于低电平数据采样在上升沿,下降沿保持 |
1 | CPOL=0, CPHA=1 | 空闲时,SCK 处于高电平数据采样在下降沿,上升沿保持 |
2 | CPOL=1, CPHA=0 | 空闲时,SCK 处于低电平数据采样在下降沿,上升沿保持 |
3 | CPOL=1, CPHA=1 | 空闲时,SCK 处于高电平数据采样在上升沿,下降沿保持 |
2. 参数配置
2.1. 内核配置
使能 SPI 相关的内核驱动,可在通过下列命令进行配置(在 SDK 顶层目录执行):
make linux-menuconfig
在内核的配置界面中,进行下列的选择:
Device Drivers --->
[*] SPI support --->
<*> Artinchip SPI controller
......
[*] DMA Engine support --->
<*> Artinchip SoCs DMA support
进行如上的配置之后,内核 SPI 驱动使能,并且 SPI 可使用 DMA 进行数据传输。
2.2. DTS 配置
芯片级的 DTS:
spi0: spi@10400000 {
compatible = "artinchip,aic-spi-v1.0";
reg = <0x0 0x10400000 0x0 0x1000>;
interrupts-extended = <&plic0 44 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cmu CLK_SPI0>;
resets = <&rst RESET_SPI0>;
dmas = <&dma DMA_SPI0>, <&dma DMA_SPI0>;
dma-names = "rx", "tx";
#address-cells = <1>;
#size-cells = <0>;
spi-max-frequency = <24000000>;
};
spi1: spi@10410000 {
compatible = "artinchip,aic-spi-v1.0";
reg = <0x0 0x10410000 0x0 0x1000>;
interrupts-extended = <&plic0 45 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cmu CLK_SPI1>;
resets = <&rst RESET_SPI1>;
dmas = <&dma DMA_SPI1>, <&dma DMA_SPI1>;
dma-names = "rx", "tx";
#address-cells = <1>;
#size-cells = <0>;
spi-max-frequency = <24000000>;
};
其中板级的配置 board.dts
中需要使能该模块,并且根据实际情况,配置最大工作频率:
&spi0 {
pinctrl-names = "default";
pinctrl-0 = <&spi0_pins_a>;
spi-max-frequency = <100000000>;
status = "okay";
};
&spi1 {
pinctrl-names = "default";
pinctrl-0 = <&spi1_pins_a>;
spi-max-frequency = <100000000>;
status = "okay";
};
board-u-boot.dtsi
需要设置 u-boot,dm-pre-reloc
,只有设置了该标记,SPL 中才可以使用 SPI:
&spi0 {
u-boot,dm-pre-reloc;
};
&spi1 {
u-boot,dm-pre-reloc;
};
3. 调试指南
3.1. 调试开关
可通过内核配置使能 SPI 模块的 DEBUG 选项。在 SDK 根目录下执行:
make linux-menuconfig (or make km)
进入内核的配置界面:
Linux
Kernel hacking
Artinchip Debug
[*] SPI driver debug
勾选使能该 DEBUG 选项后:
- SPI 的驱动源码将以
-O0
编译- SPI 驱动中的 pr_dbg() 和 dev_dbg() 调试信息会被编译
如果需要看到 pr_dbg() 和 dev_dbg() 的打印信息,还需要设置 loglevel=8
。
若需要在启动过程中即可看到打印,需要在 env.txt
中修改 bootargs,增加 loglevel=8
。 若仅需要在板子启动到 Linux shell 后使能相关打印,可以通过下列命令调整 loglevel:
echo 8 > /proc/sys/kernel/printk