外设

本移植通过 TTY、I2C、SPI、ALSA 和 SocketCAN 等标准 Linux 接口提供外设功能。 使用设备树覆盖层启用可选控制器并选择引脚。

本章中的原生 I2C、SPI、I2S、以太网和 SD/MMC 驱动均包含在统一的完整配置中;实际外接设备可能需要额外驱动。

启用外设

例如,要启用 I2C0:

s31-overlay apply i2c0

该选择会被保存,并在启动时恢复。添加 --volatile 可使配置仅临时生效。 查看引脚和可用设置:

s31-overlay routes i2c0
s31-overlay parameters i2c0

连接设备前请检查开发板原理图。覆盖层目录 列出了可用控制器及其配置选项。

接线、命令、预期现象和清理步骤见外设示例。 GPIO 编号表示 SoC 信号;开发板默认配置 列出了随仓库提供的路由和预留资源。

接口

外设

Linux 接口

覆盖层或设置

GPIO

GPIO 字符设备;libgpiod 和 esp32-config gpio

选择空闲引脚;托管 GPIO 设置在启动时恢复

UART

/dev/ttyS*

uart1、uart2、uart3 或 uart3-dma

I2C

/dev/i2c-*

i2c0 或 i2c1

SPI

SPI 子系统;用户空间客户端使用 /dev/spidev*

gpspi2、gpspi3 或对应的目标模式配置

I2S/TDM

ALSA PCM

i2s0 或 i2s1

TWAI/CAN

SocketCAN

twai0 或 twai1;需要外部收发器

SD/MMC

MMC 块设备

sdmmc0、sdmmc1、sdmmc-dual 或 sdmmc-uhs

以太网

网络接口和 PHY 驱动

gmac;需要外部 PHY

USB

DWC2 主机、ACM 串口 gadget 或 ECM 网络 gadget

esp32-config usb configure host|serial|network

GDMA

内核 DMAengine API

由客户端选择 AHB/AXI 提供者

通用定时器

Counter 框架

timers

LEDC、MCPWM、SDM 和脉冲计数器

PWM 和 Counter 框架

pwm-counter

ADC、DAC、触摸、比较器

IIO

analog 和合适的模拟引脚

温度传感器

hwmon

analog

看门狗

Watchdog 框架

watchdogs

eFuse、随机数、加密

只读 NVMEM、hwrng 和内核 crypto API

对应的内核驱动

UART0 用作串口控制台。UART3 的 DMA 覆盖层还会使用 UHCI0 和一个 AHB GDMA 通道。当前功能状态见支持矩阵。

I2C

两个 I2C 控制器都支持 7 位和 10 位地址,以及组合写入/读取事务。默认总线 速率为 100 kHz。要选择 400 kHz 并将 I2C0 路由到 GPIO35 和 GPIO36:

s31-overlay apply i2c0 i2c0.scl=35 i2c0.sda=36 clock-frequency=400000

SCL 和 SDA 需要合适的上拉电阻。覆盖层还接受 100000 和 1000000 Hz。

列出适配器:

i2cdetect -l

对于适配器 0 上地址为 0x51 的设备,可以在一次事务中先用一个字节选择 寄存器,再读取一个字节:

i2ctransfer -y 0 w1@0x51 0x00 r1

将适配器、地址和寄存器替换为你的设备对应的值。在 C 中,使用 I2C_RDWR 执行这一组合操作,使写入和读取之间以重复 START 分隔。

传输限制和错误

用户空间 I2C_RDWR 的每条消息最多可包含 8192 字节。内核客户端使用 16 位 消息长度,最多允许 65535 字节。支持零长度写入;不支持零长度读取和协议修改标志。

长传输会分批处理,每批最多发送 32 字节或接收 31 字节。控制器在批次之间 保持总线,并在最后一条消息之后发送 STOP。每批的完成超时时间为 500 ms。

错误

含义

ENXIO

目标未应答

EAGAIN

丢失仲裁

ETIMEDOUT

硬件超时或等待完成超时

EIO

接收 FIFO 计数异常

驱动包含总线恢复功能。如果反复超时,还应检查上拉电阻、接线、总线速率和 目标设备的行为。

SPI

GPSPI2 和 GPSPI3 均可作为主机或目标端运行。根据控制器实例和角色选择 对应的覆盖层,例如 gpspi2 或 gpspi2-target。

主机客户端使用 Linux SPI API。使用 spidev 的应用通过其 ioctl 选择模式、 时钟速率和传输缓冲区。主机模式只接受 8 位字长。 随仓库提供的主机覆盖层 为 spidev 子节点设置了 20 MHz 的最高速率;请求的速率还必须处于控制器的 时钟范围内。主机回环示例 从 100 kHz 开始。

目标模式传输

目标模式等待外部主机提供时钟和片选。它支持模式 0–3、高电平有效的片选, 以及 8、16 或 32 位字长。传输长度必须为字长的整数倍。

设置

限制

DMA 传输

4096 字节

仅使用 FIFO 的传输

64 字节

等待外部主机

可中断;无固定超时

事务结束后等待 DMA 完成

每个需要的传输方向为 100 ms

目标端将 Linux 小端序数据字转换为选定的总线字节序。对于 16 位和 32 位的 MSB 优先传输,发送时会反转每个字内的字节顺序,接收时再转换回来。

拉有效片选前,应留出足够时间让目标端准备好每次传输。需要就绪信号的应用 应单独实现握手。目标模式使用单数据通道,没有独立的命令、地址或空周期阶段。

等待被中断或取消时返回 EINTR。事务长度异常时返回 EMSGSIZE, DMA 完成超时时返回 ETIMEDOUT。

I2S 和 TDM

I2S0 和 I2S1 使用 ALSA SoC,通过 GDMA 支持播放和录音。启用对应的覆盖 配置后,列出 PCM 设备:

aplay -l
arecord -l

在应用中使用输出里的声卡和设备编号。随仓库提供的 i2s0 和 i2s1 覆盖层 在播放和录音两个方向都接收外部 BCLK 和帧时钟,需要由 codec 或测试对端 产生时钟。如果 DAC 也需要接收这两个时钟,就必须使用不同的声卡和引脚配置, 具体见完整音频示例。

PCM 设置

设置

可用值

采样格式

S8、S16_LE、S24_LE、S32_LE

采样率

8–192 kHz,受时钟和声卡配置限制

通道数

1–16

周期大小

256–4032 字节

每个缓冲区的周期数

2–8

播放和录音共用 MCLK,同时配置两个流时必须使用相同的采样率。两个流还需 使用兼容的时钟设置。ALSA 负责非一致性 DMA 缓冲区的缓存同步。

帧格式和时钟

CPU DAI 支持 I2S、左对齐、DSP A 和 DSP B 帧格式。它可以同时提供 BCLK 和帧时钟,也可以同时接收另一设备提供的这两个时钟。支持帧时钟反相, 目前不支持混合时钟角色、位时钟反相和外部 MCLK 输入。

set_sysclk() 使用 ID 0 和 SND_SOC_CLOCK_OUT 配置内部 MCLK。速率设为 零时自动选择 MCLK。接收外部 BCLK 时,内部模块时钟必须至少达到 BCLK 的八倍。

TDM 时隙

使用 set_tdm_slot() 选择 1–16 个时隙,每个时隙宽度为 8–32 位。时隙宽度 必须能容纳采样数据,每帧的总位数必须为偶数。非零的 TX/RX 掩码选择活动 时隙,每个 PCM 通道必须对应一个置位位。将时隙数和掩码都设为零,可清除 显式时隙设置。

更改格式、时隙或 MCLK 之前,先释放已配置的流。允许重新应用相同的设置。

连接外部 codec

带外部 codec 的开发板应使用 ASoC machine 驱动,例如 simple-audio-card。 向所选控制器添加以下属性:

&i2s0 {
    #sound-dai-cells = <0>;
    espressif,external-card;
    status = "okay";
};

然后在 machine 声卡中描述 CPU/codec 链路、引脚、帧格式、时钟,以及需要的 TDM 设置。espressif,external-card 会禁用内置虚拟声卡,让外部声卡使用该 控制器。还需在内核配置中启用 machine 驱动和所选 codec 的驱动;完整外设 配置本身不会选择 CONFIG_SND_SIMPLE_CARD 或真实 codec。machine 驱动的 格式设置会选择两个方向的时钟角色。随仓库提供的虚拟声卡覆盖层在两个方向 都使用时钟输入。

驱动中也提供原始 PDM 选项;这些选项不提供 PCM 到 PDM 的转换。

存储、网络和其他外设

SD 卡使用 MMC 块层,TWAI 使用 SocketCAN,以太网使用常规 Linux 网络接口。 对应的覆盖层选择控制器和引脚,底板则提供卡座、收发器或 PHY。

基础设备树启用 DWC2 主机模式及 USB 存储路径,标准内核内建 ext4 支持。使用 esp32-config usb 管理主机、ACM 串口和 ECM 网络模式。管理器临时应用 usb-device、创建所选 ConfigFS gadget 并绑定到 UDC。单独应用原始 usb-device 覆盖层只会切换控制器角色;自定义 gadget 仍需自行配置功能并绑定。 不要让手工配置的 gadget 与管理器同时拥有同一个 UDC。切换角色之前, 请卸载 USB 文件系统并禁用位于 USB 存储上的 swap。 存储和 gadget 示例给出了配置与清理步骤; 实现是否存在与支持矩阵中记录的硬件状态是两个不同的问题。

定时和模拟设备使用各自的 Linux 子系统接口。在 timers 覆盖层中, 每个定时器组的定时器 0 可供应用使用,定时器 1 则保留用于 CPU 空闲唤醒。 模拟和数字信号路由可能共用物理焊盘,因此每个引脚只应选择一种功能。

驱动源码位于 linux-esp32-s31/drivers/,音频驱动位于 sound/soc/espressif/。集成步骤见添加驱动。