4. SPI 总线节点属性:spi-max-frequency、spi-cpha、spi-cpol、spi-cs-high 等属性配置
SPI 从设备节点的属性配置决定了控制器与设备之间的通信协议细节。这些属性必须在设备树中正确设置,以确保时序匹配、信号极性正确以及总线速率在设备允许范围内。本节将详细解析最关键的四个 SPI 属性及其配置方法。
4.1 属性概览与功能对照
下表列出了 SPI 从设备节点中最常用的属性,以及它们各自控制的硬件行为:
| 属性名 | 数据类型 | 默认值 | 功能描述 |
|---|---|---|---|
spi-max-frequency |
<u32> | 无(必须指定) | 设置 SPI 时钟(SCLK)的最高频率,单位 Hz |
spi-cpha |
空属性(布尔) | 0(CPHA=0) | 设置时钟相位:0 表示第一个边沿采样,1 表示第二个边沿采样 |
spi-cpol |
空属性(布尔) | 0(CPOL=0) | 设置时钟极性:0 表示空闲时低电平,1 表示空闲时高电平 |
spi-cs-high |
空属性(布尔) | 片选低电平有效 | 设置片选信号为高电平有效(默认低电平有效) |
spi-3wire |
空属性(布尔) | 标准 4 线模式 | 启用 3 线半双工模式(MISO 与 MOSI 共用) |
spi-lsb-first |
空属性(布尔) | MSB 优先 | 设置数据以 LSB 优先方式传输 |
关键理解:
spi-cpha 和 spi-cpol 共同定义了 SPI 的四种工作模式(Mode 0~3)。这两个属性是布尔类型,在设备树中只要出现即表示值为 1,不出现则表示值为 0。
4.2 spi-max-frequency:总线速率上限
spi-max-frequency 是每个从设备节点必须指定的属性,它告诉 SPI 控制器该从设备支持的最高时钟频率。控制器在通信时会根据此值自动分频,确保实际 SCLK 频率不超过该上限。
/* 设备树示例:为不同从设备设置不同的最大频率 */
&spi1 {
status = "okay";
temperature_sensor: sensor@0 {
compatible = "maxim,ds18b20";
reg = <0>;
spi-max-frequency = <1000000>; /* 最高 1 MHz */
};
display_controller: display@1 {
compatible = "ilitek,ili9341";
reg = <1>;
spi-max-frequency = <32000000>; /* 最高 32 MHz */
};
};
配置陷阱: 如果
spi-max-frequency 设置过高,超出从设备规格,可能导致数据采样错误、通信不稳定甚至设备损坏。建议参考芯片数据手册中的最大 SCLK 参数,并保留 10%~20% 的余量。
4.3 spi-cpha 与 spi-cpol:时钟相位与极性
这两个属性共同决定了 SPI 的四种标准模式。理解它们对正确配置至关重要:
- CPOL(Clock Polarity):定义 SCLK 空闲时的电平状态。
- CPOL=0:空闲时 SCLK 为低电平
- CPOL=1:空闲时 SCLK 为高电平
- CPHA(Clock Phase):定义数据采样发生在哪个时钟边沿。
- CPHA=0:在第一个边沿(上升沿或下降沿)采样数据
- CPHA=1:在第二个边沿采样数据
四种模式的组合关系如下表所示:
| SPI 模式 | CPOL | CPHA | 空闲时钟电平 | 数据采样边沿 |
|---|---|---|---|---|
| Mode 0 | 0 | 0 | 低电平 | 上升沿(第一个边沿) |
| Mode 1 | 0 | 1 | 低电平 | 下降沿(第二个边沿) |
| Mode 2 | 1 | 0 | 高电平 | 下降沿(第一个边沿) |
| Mode 3 | 1 | 1 | 高电平 | 上升沿(第二个边沿) |
/* 设备树配置示例:设置 SPI Mode 3(CPOL=1, CPHA=1) */
spi_nor_flash: flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <50000000>;
spi-cpol; /* 空闲时高电平 */
spi-cpha; /* 第二个边沿采样 */
};
模式匹配原则: 从设备的数据手册通常会明确标注其支持的 SPI 模式(如 "SPI Mode 0 and Mode 3")。务必确保设备树中配置的模式与从设备要求的模式完全一致,否则通信将完全失败。
4.4 SPI 四种模式时序对比 SVG
下图直观展示了四种 SPI 模式下 SCLK、数据输出(MOSI)和数据采样点的时序关系:
4.5 spi-cs-high:片选极性控制
SPI 总线的片选信号(CS/SS)默认是低电平有效,即 CS 引脚为低电平时选中从设备。但部分从设备要求片选信号为高电平有效。此时需要在设备树节点中添加 spi-cs-high 属性。
/* 片选高电平有效配置示例 */
spi_adc: adc@2 {
compatible = "ti,ads1256";
reg = <2>;
spi-max-frequency = <19200000>;
spi-cs-high; /* 片选信号高电平有效 */
};
硬件兼容性注意: 并非所有 SPI 控制器都支持片选极性反转。如果控制器硬件不支持高电平有效片选,即使设备树中配置了
spi-cs-high,驱动也可能忽略该属性。此时需要通过外部逻辑电路(如反相器)进行电平转换。
4.6 属性配置完整示例与驱动匹配流程
以下是一个完整的 SPI 从设备节点配置,展示了所有关键属性的组合使用:
/* 完整 SPI 从设备节点配置示例 */
&spi2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_spi2>;
status = "okay";
/* 从设备 0:SPI NOR Flash */
flash: w25q128@0 {
compatible = "winbond,w25q128", "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <104000000>;
spi-cpol;
spi-cpha;
#address-cells = <1>;
#size-cells = <1>;
partition@0 {
label = "bootloader";
reg = <0x00000000 0x00100000>;
};
};
/* 从设备 1:SPI 触摸控制器 */
touch: touch@1 {
compatible = "focaltech,ft5426";
reg = <1>;
spi-max-frequency = <5000000>;
spi-cs-high;
interrupt-parent = <&gpio3>;
interrupts = <19 IRQ_TYPE_EDGE_FALLING>;
};
};
内核在枚举 SPI 从设备时,会按照以下流程匹配和配置这些属性:
- 解析节点:内核 SPI 核心层读取设备树中每个从设备子节点。
- 提取属性:调用
of_spi_parse_dt()函数解析spi-max-frequency、spi-cpol、spi-cpha、spi-cs-high等属性。 - 填充结构体:将解析结果写入
struct spi_device的对应字段(max_speed_hz、mode等)。 - 控制器配置:SPI 控制器驱动根据
spi_device中的模式信息,配置硬件寄存器(时钟分频、极性、相位、片选极性)。 - 设备注册:将配置好的
spi_device注册到 SPI 总线,触发匹配对应的从设备驱动。
内核源码参考: 属性解析的核心函数位于
drivers/spi/spi.c 中的 of_spi_parse_dt()。该函数通过 of_property_read_u32() 读取 spi-max-frequency,通过 of_property_read_bool() 读取布尔类型的模式属性。
4.7 属性配置与驱动匹配流程 SVG
下图展示了从设备树解析到 SPI 设备注册的完整数据流: