SPI Master
概述
ESP32 有四个 SPI 外设,称为 SPI0,SPI1,HSPI 和 VSPI。 SPI0 是 ESP32 专用于将连接的 SPI 闪存设备映射到存储器的闪存缓存。 SPI1 和 SPI0 使用相同的硬件线,SPI1 用于写入闪存芯片。 HSPI 和 VSPI 可以任意使用。 SPI1,HSPI 和 VSPI 都有三条片选线,作为 SPI 主机允许它们最多驱动三个 SPI 设备。
spi_master 驱动
即使在多线程环境中,spi_master 驱动程序也可以轻松与 SPI 从设备进行通信。 它完全透明地处理 DMA 传输以读取和写入数据,并自动处理同一主机上不同 SPI 从站之间的多路复用
术语
spi_master 驱动程序使用以下术语:
- 主机:ESP32 内部的 SPI 外设启动 SPI 传输。 SPI,HSPI或VSPI之一。 (目前,驱动程序实际上只支持HSPI或VSPI;它将在未来的某个地方支持所有3个外设。)
- 总线:SPI总线,与连接到一个主机的所有SPI设备共用。通常,总线由味噌,mosi,sclk和可选的quadwp和quadhd信号组成。 SPI从设备并联连接到这些信号。
- miso - 也称为q,这是将串行流输入到ESP32中
- mosi - 也称为d,这是来自ESP32的串行流的输出
- sclk - 时钟信号。每个数据位在该信号的正或负边沿输出或输出
- quadwp - 写保护信号。仅用于4位(qio / qout)事务。
- quadhd - 保持信号。仅用于4位(qio / qout)事务。
- 设备:SPI从设备。每个SPI从器件都有自己的片选(CS)线,当发送到/从SPI从器件发送时,该线被激活。
- 事务:一个CS活动的实例,来自和/或发生的设备的数据传输,以及CS再次变为非活动状态。事务是原子的,因为它们永远不会被另一个事务中断。
SPI transactions
SPI 总线上的事务由五个阶段组成,其中任何阶段都可以跳过:
- 命令阶段。 在此阶段,命令(0-16位)被输出。
- 地址阶段。 在此阶段,地址(0-64位)被输出。
- 写阶段。 主设备将数据发送到从设备。
- 虚拟阶段。 该阶段是可配置的,用于满足时序要求。
- 阅读阶段。 从站将数据发送给主站。
在全双工模式下,读写阶段被组合,SPI 主机同时读写数据。总事务长度由command_bits + address_bits + trans_conf.length
决定,而trans_conf.rx_length
仅确定接收到缓冲区的数据长度。
在半双工模式下,主机具有独立的写和读阶段。写入阶段和读取阶段的长度分别由trans_conf.length
和trans_conf.rx_length
决定。
命令和地址阶段是可选的,因为不是每个 SPI 设备都需要发送命令和/或地址。这反映在设备配置中:当command_bits
或address_bits
字段设置为零时,不执行命令或地址阶段。
读写阶段的情况类似:并非每个事务都需要写入数据以及要读取的数据。当rx_buffer
为NULL(并且未设置SPI_USE_RXDATA
)时,将跳过读取阶段。当tx_buffer
为NULL(并且未设置SPI_USE_TXDATA
)时,将跳过写入阶段。
GPIO matrix and IOMUX
ESP32 中的大多数外设信号可以直接连接到特定的 GPIO,称为 IOMUX 引脚。 当外设信号路由到 IOMUX 引脚以外的引脚时,ESP32 使用较不直接的 GPIO matrix 进行连接。
如果驱动器配置了所有SPI信号设置为其特定的IOMUX引脚(或未连接),它将绕过GPIO matrix。 如果任何SPI信号配置到IOMUx引脚以外的引脚,驱动器将自动通过GPIO matrix路由所有信号。 GPIO matrix对80MHz的所有信号进行采样,并在GPIO和外设之间发送。
当使用GPIO matrix时,由于MISO信号的输入延迟增加,因此超过40MHz的信号不能传播并且MISO的建立时间更容易被违反。 GPIO Matrix的最大时钟频率为40MHz或更低,而使用所有IOMUX引脚允许80MHz。
有关输入延迟对最大时钟频率影响的更多详细信息,请参阅下面的时序注意事项。
SPI控制器的IOMUX引脚如下:
Pin Name | HSPI(GPIO Number) | VSPI(GPIO Number) |
---|---|---|
CS0* | 15 | 5 |
SCLK | 14 | 18 |
MISO | 12 | 19 |
MOSI | 13 | 23 |
QUADWP | 2 | 22 |
QUADHD | 4 | 21 |
只有连接到总线的第一个设备才能使用CS0引脚。
使用 spi_master 驱动
- 通过调用
spi_bus_initialize
初始化 SPI 总线。 确保在bus_config
结构中设置正确的IO引脚。 注意将不需要的信号设置为-1。 - 通过调用
spi_bus_add_device
告诉驱动程序有关连接到总线的SPI从设备。 确保在dev_config
结构中配置设备具有的任何时序要求。 您现在应该拥有该设备的句柄,以便在发送事务时使用。 - 要与设备交互,请使用您需要的任何事务参数填充一个或多个
spi_transaction_t
结构。 通过调用spi_device_queue_trans
对所有事务进行排队,稍后使用spi_device_get_trans_result
查询结果,或者通过将它们提供给spi_device_transmit
来同时处理所有请求。 - 可选:要卸载设备的驱动程序,请以设备句柄作为参数调用
spi_bus_remove_device
- 可选:要删除总线的驱动程序,请确保没有连接更多驱动程序并调用
spi_bus_free
。
命令和地址阶段
在命令和地址阶段,spi_transaction_t
结构中的cmd
和addr
字段将发送到总线,而不会同时读取任何内容。 命令和地址阶段的缺省长度在spi_device_interface_config_t
和spi_bus_add_device
中设置。 当spi_transaction_t
中未设置标志SPI_TRANS_VARIABLE_CMD
和SPI_TRANS_VARIABLE_ADDR
时,驱动程序会自动将这些阶段的长度设置为分别初始化设备时设置的默认值。
如果命令和地址阶段的长度需要变量,则声明一个spi_transaction_ext_t
描述符,在基数成员的标志中设置标志SPI_TRANS_VARIABLE_CMD
或/和SPI_TRANS_VARIABLE_ADDR
,并像往常一样配置base
的其余部分。 然后每个阶段的长度将是spi_transaction_ext_t
中设置的command_bits
和address_bits
。
应用示例
API Reference - SPI Common
在WROVER-Kits的320x240 LCD上显示图形:peripherals/spi_master.