fix(driver_spi): added bit trans length check for master driver

Closes https://github.com/espressif/esp-idf/issues/16049

Closes https://github.com/espressif/esp-idf/issues/17725
This commit is contained in:
wanckl
2026-01-14 20:09:33 +08:00
committed by Wan Lei
parent 89d3051b53
commit 488c933500
16 changed files with 169 additions and 18 deletions
@@ -375,6 +375,25 @@ SPI 主机逐字节地将数据读入和写入内存。默认情况下,数据
例如,如果需要发送 ``0b00010``,则应将其写成 ``uint8_t`` 变量,读取长度设置为 5 位。此时,设备仍然会收到 8 位数据,并另有 3 个“随机”位,所以读取过程必须准确。
不是所有芯片都支持任意位长度的数据传输,发送或接收不支持的位长度时会返回 :c:macro:`ESP_ERR_NOT_SUPPORTED` 错误。支持的长度如下表所示(**YES** 表示支持任意长度,**NO** 表示只支持整字节 8 bits 长度):
+------+--------+-------+----------+--------------------+---------------------+
| | ESP32 | ESP32-S2 | ESP32-S3/C2/C3/C6 | ESP32-H2/P4/C5/C61 |
+======+========+=======+==========+====================+=====================+
| TX | DMA | YES | YES | (bit_len % 8) != 1 | YES |
+ +--------+-------+----------+--------------------+---------------------+
| | NO DMA | YES | YES | (bit_len % 8) != 1 | YES |
+------+--------+-------+----------+--------------------+---------------------+
| RX | DMA | NO | NO | YES | YES |
+ +--------+-------+----------+--------------------+---------------------+
| | NO DMA | YES | NO | YES | YES |
+------+--------+-------+----------+--------------------+---------------------+
如仍需使用不支持的长度传输,根据表格可以有以下替代方法:
1. 使用 :cpp:member:`spi_transaction_t::cmd`:cpp:member:`spi_transaction_t::addr` 和数据阶段组合。缺点:命令和地址阶段不接收从机数据。
2. 使用两次支持长度的传输组合,比如 ``2+7`` 实现 ``9 bit`` 传输,期间保持 CS 线有效。缺点:两次传输之间有最小时间间隔(见 :ref:`transaction_time_cost`),整体速率较低。
此外,{IDF_TARGET_NAME} 属于小端芯片,即 ``uint16_t````uint32_t`` 变量的最低有效位存储在最小的地址。因此,如果 ``uint16_t`` 存储在内存中,则首先发送位 [7:0],其次是位 [15:8]。
在某些情况下,要传输的数据大小与 ``uint8_t`` 数组不同,可使用以下宏将数据转换为可由 SPI 驱动直接发送的格式:
@@ -536,6 +555,7 @@ GPIO 矩阵与 IO_MUX 管脚
影响大传输事务传输速度的主要参数是时钟频率。而多个小传输事务的传输速度主要由传输事务间隔时长决定。
.. _transaction_time_cost:
传输事务持续时间
^^^^^^^^^^^^^^^^^^^^