mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
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:
@@ -375,6 +375,25 @@ An SPI Host reads and writes data into memory byte by byte. By default, data is
|
||||
|
||||
For example, if ``0b00010`` needs to be sent, it should be written into a ``uint8_t`` variable, and the length for reading should be set to 5 bits. The Device will still receive 8 bits with 3 additional "random" bits, so the reading must be performed correctly.
|
||||
|
||||
Not all chips support data transmission with any bit lengths. Sending or receiving unsupported bit lengths will return :c:macro:`ESP_ERR_NOT_SUPPORTED` error. The supported lengths are shown in the table below (**YES** means support any bits length, **NO** means bytes (8 bits) only):
|
||||
|
||||
+------+--------+-------+----------+--------------------+---------------------+
|
||||
| | 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 |
|
||||
+------+--------+-------+----------+--------------------+---------------------+
|
||||
|
||||
If you still need to use unsupported bit lengths, you can use the following alternatives:
|
||||
|
||||
1. Use :cpp:member:`spi_transaction_t::cmd` and :cpp:member:`spi_transaction_t::addr` and data phase combination. The drawback is that the command and address phases do not receive data from the slave device.
|
||||
2. Use two supported length transmissions combination, like ``2+7`` to implement ``9 bit`` transmission, while keeping the CS line valid. The drawback is that there is a minimum time interval between two transmissions (see :ref:`transaction_time_cost`), and the overall transfer rate is lower.
|
||||
|
||||
On top of that, {IDF_TARGET_NAME} is a little-endian chip, which means that the least significant byte of ``uint16_t`` and ``uint32_t`` variables is stored at the smallest address. Hence, if ``uint16_t`` is stored in memory, bits [7:0] are sent first, followed by bits [15:8].
|
||||
|
||||
For cases when the data to be transmitted has a size differing from ``uint8_t`` arrays, the following macros can be used to transform data to the format that can be sent by the SPI driver directly:
|
||||
@@ -536,6 +555,7 @@ There are three factors limiting the transfer speed:
|
||||
|
||||
The main parameter that determines the transfer speed for large transactions is clock frequency. For multiple small transactions, the transfer speed is mostly determined by the length of transaction intervals.
|
||||
|
||||
.. _transaction_time_cost:
|
||||
|
||||
Transaction Duration
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -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:
|
||||
|
||||
传输事务持续时间
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Reference in New Issue
Block a user