说明:以下为在官方库文件SPI Master driver release/v3.3基础上的总结,如果使用其他版本库,可能不适用
文章目录
一、学习文档目录
- 乐鑫官方API : SPI Master driver release/v3.3
- 以上中文翻译版本可以查阅(以英文版为准):ESP32 学习笔记(八)SPI - SPI Master
- ESP32之软件SPI驱动及SPI、HSPI和VSPI的理解
二、关于SPI引脚的选择
1.优先推荐使用IOMUX映射的引脚
Pin Name | HSPI | VSPI |
---|---|---|
GPIO Number | GPIO Number | |
CS0* | 15 | 5 |
SCLK | 14 | 18 |
MISO | 12 | 19 |
MOSI | 13 | 23 |
QUADWP | 2 | 22 |
QUADHD | 4 | 21 |
note * Only the first device attaching to the bus can use CS0 pin.
2.注意GPIO matrix的效率损失
如果IOMUX映射的引脚已经作为他用,并且无法替代。可以使用GPIO matrix映射到其他引脚,但是因为要经过中间期间,会造成时间的损失,进而直接降低极限速度。如果超过速度的限制在编译阶段会有提示。
三、两种运行模式的区别
比较项目 | Interrupt transactions | Polling transactions |
---|---|---|
官方介绍 | The interrupt transactions use an interrupt-driven logic when the transactions are in-flight. The routine will get blocked, allowing the CPU to run other tasks, while it is waiting for a transaction to be finished. | The polling transactions don’t rely on the interrupt, the routine keeps polling the status bit of the SPI peripheral until the transaction is done. |
中断通知 | 有 | 无 |
时间损失 | 有 | 无 |
CPU损失 | 低 | 高 |
- Polling transactions 可以节约掉队列处理和上下文切换的时间,但是CPU始终处于繁忙的状态。
- Interrupt transactions 支持传输队列,A task can queue several transactions, and then do something else before the transactions are finished.
四、关于大小端问题
- 首先ESP32 存储为小端模式,即低地址保存数据的低位,高地址保存数据的高位。
- SPI工作在MSB first模式,也就意味着
uint8_t
的类型,8个bit的发送顺序是从7->0 - 综上,如果一个
uint16_t
数据被发送,byte按照地址顺序从低到高发送,bit按照字节顺序从高到低发送,7 is first sent, then bit 6 to 0, then comes its bit 15 to bit 8.
五、SPI 模式/时序
//Configure polarity
if (dev->cfg.mode==0) {
host->hw->pin.ck_idle_edge=0;
host->hw->user.ck_out_edge=0;
} else if (dev->cfg.mode==1) {
host->hw->pin.ck_idle_edge=0;
host->hw->user.ck_out_edge=1;
} else if (dev->cfg.mode==2) {
host->hw->pin.ck_idle_edge=1;
host->hw->user.ck_out_edge=1;
} else if (dev->cfg.mode==3) {
host->hw->pin.ck_idle_edge=1;
host->hw->user.ck_out_edge=0;
}
六、已知问题
- Half duplex mode is not compatible with DMA when both writing and reading phases exist.
If such transactions are required, you have to use one of the alternative solutions:- use full-duplex mode instead.
- disable the DMA by setting the last parameter to 0 in bus initialization function just as below:
ret=spi_bus_initialize(VSPI_HOST, &buscfg, 0)
; this may prohibit you from transmitting and receiving data longer than 64 bytes. - try to use command and address field to replace the write phase.
- Full duplex mode is not compatible with the dummy bit workaround, hence the frequency is limited. See dummy bit speed-up workaround.
cs_ena_pretrans
is not compatible with command, address phases in full duplex mode.
七、官方例程分析