esp32的spi驱动的编写遇到的问题

最近在使用esp32驱动一个spi设备的时候,spi设备没有应答,奇怪的时候我之前用stm32成功驱动过这个spi设备,怎么移植到esp32就不行呢?
在使用stm32的时候我是使用spimode3,即CPOL=1, CPHA=1,参考通用的spi模式定义:

spi四种模式SPI的相位(CPHA)和极性(CPOL)分别可以为0或1,对应的4种组合构成了SPI的4种模式(mode) Mode 0 CPOL=0, CPHA=0 Mode 1 CPOL=0, CPHA=1 Mode 2 CPOL=1, CPHA=0 Mode 3 CPOL=1, CPHA=1 时钟极性CPOL: 即SPI空闲时,时钟信号SCLK的电平(1:空闲时高电平; 0:空闲时低电平) 时钟相位CPHA: 即SPI在SCLK第几个边沿开始采样(0:第一个边沿开始; 1:第二个边沿开始)

时序图如下:
esp32的spi驱动的编写遇到的问题
文章图片


在esp32上面我也应该使用mode3的,最后我改esp32的spi模式=SPI_MODE2的时候协议分析仪获取到的数据才是正确的,都有点让我怀疑人生了。难道标准规范不对?

SPI.begin(sck, miso, mosi, cs); SPI.beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE2));

或者esp32没有根据通用规范来标识,查看esp32的底层驱动文件发现真是这样:
源文件名称:esp32-hal-spi.c

void spiSetDataMode(spi_t * spi, uint8_t dataMode) { if(!spi) { return; } SPI_MUTEX_LOCK(); switch (dataMode) { case SPI_MODE1: spi->dev->pin.ck_idle_edge = 0; spi->dev->user.ck_out_edge = 1; break; case SPI_MODE2: spi->dev->pin.ck_idle_edge = 1; spi->dev->user.ck_out_edge = 1; break; case SPI_MODE3: spi->dev->pin.ck_idle_edge = 1; spi->dev->user.ck_out_edge = 0; break; case SPI_MODE0: default: spi->dev->pin.ck_idle_edge = 0; spi->dev->user.ck_out_edge = 0; break; } SPI_MUTEX_UNLOCK(); }


原来esp32是用“SPI_MODE2”来代表:
CPOL=1, CPHA=1


至此真相大白,看来有时候必须追根问底才能得到真理。




参考资料:
【1】SPI四种模式区别

【2】 linux spi驱动开发学习(三)-----spi_bitbang.c详解

【esp32的spi驱动的编写遇到的问题】【3】 github源文件:arduino-esp32/cores/esp32/esp32-hal-spi.c

    推荐阅读