ESP SPI 从机 HD（半双工）模式协议
==========================================

:link_to_translation:`en:[English]`

.. only:: esp32

    .. warning::

        ESP32 不支持此功能。

.. _esp_spi_slave_caps:

乐鑫芯片的 SPI 从机功能支持概况
---------------------------------

+---------+------------+-----------+-----------+------+------+----------------+
|         |SPI Slave HD|Tohost intr|Frhost intr|TX DMA|RX DMA|Shared registers|
+---------+------------+-----------+-----------+------+------+----------------+
|ESP32    |     N      |           |           |      |      |                |
+---------+------------+-----------+-----------+------+------+----------------+
|ESP32-S2 |   Y(v2)    |     N     |   2 \*    |  Y   |  Y   |       72       |
+---------+------------+-----------+-----------+------+------+----------------+
|ESP32-C3 |   Y(v2)    |     N     |   2 \*    |   Y  |  Y   |       64       |
+---------+------------+-----------+-----------+------+------+----------------+
|ESP32-S3 |   Y(v2)    |     N     |   2 \*    |   Y  |  Y   |       64       |
+---------+------------+-----------+-----------+------+------+----------------+
|ESP32-C2 |   Y(v2)    |     N     |   2 \*    |   Y  |  Y   |       64       |
+---------+------------+-----------+-----------+------+------+----------------+
|ESP32-C6 |   Y(v2)    |     N     |   2 \*    |   Y  |  Y   |       64       |
+---------+------------+-----------+-----------+------+------+----------------+
|ESP32-H2 |   Y(v2)    |     N     |   2 \*    |   Y  |  Y   |       64       |
+---------+------------+-----------+-----------+------+------+----------------+
|ESP32-P4 |   Y(v2)    |     N     |   2 \*    |   Y  |  Y   |       64       |
+---------+------------+-----------+-----------+------+------+----------------+
|ESP32-C5 |   Y(v2)    |     N     |   2 \*    |   Y  |  Y   |       64       |
+---------+------------+-----------+-----------+------+------+----------------+
|ESP32-C61|   Y(v2)    |     N     |   2 \*    |   Y  |  Y   |       64       |
+---------+------------+-----------+-----------+------+------+----------------+
|ESP32-H21|   Y(v2)    |     N     |   2 \*    |   Y  |  Y   |       64       |
+---------+------------+-----------+-----------+------+------+----------------+

概述
----

在半双工模式下，主机须使用从机定义的协议与从机通信。每个传输事务按顺序可能包括以下阶段：

- 命令阶段：8 位，主机到从机

    此阶段决定事务的其它阶段。参见 :ref:`spi_slave_hd_supported_cmds`。

- 地址阶段：8 位，主机到从机，可选

    对于某些命令（如 WRBUF、RDBUF），此阶段指定要写入/读取的共享寄存器地址。对于其他包括此阶段的命令，这没有实际意义，但仍必须存在于事务中。

.. only:: esp32s2

    - Dummy 阶段：8 位 (1线模式) 或 4 位 (2/4线模式)，浮动，可选

        此阶段是主机和从机在总线上的周转时间，并为从机向主机发送数据提供了充分的准备时间。

.. only:: not esp32s2

    - Dummy 阶段：8 位，浮动，可选

        此阶段是主机和从机在总线上的周转时间，并为从机向主机发送数据提供了充分的准备时间。

- 数据阶段：长度可变，方向由命令确定。

    这一阶段可以输出数据（OUT，方向为由从机向主机），或者输入数据（IN，方向为由主机向从机）。

**方向** 是指哪一方（主机或从机）控制 MOSI、MISO、WP 和 HD 管脚。

数据 IO 模式
-------------

在某些 IO 模式下，可以使用更多数据线来发送数据。因此，与 1 位模式相比，发送相同数据量所需的 SPI 时钟周期更少。例如，在 QIO 模式下，地址和数据（IN 和 OUT）应发送到全部 4 条数据线上（MOSI、MISO、WP 和 HD）。下表展示了 ESP32-S2 SPI 从机支持的模式，以及相应模式下使用的数据线数量。

+-------+----------+----------+------------+----------+
| Mode  | 命令线数 | 地址线数 | dummy 线数 | 数据线数 |
+-------+----------+----------+------------+----------+
| 1-bit | 1        | 1        | 1          | 1        |
+-------+----------+----------+------------+----------+
| DOUT  | 1        | 1        | 4          | 2        |
+-------+----------+----------+------------+----------+
| DIO   | 1        | 2        | 4          | 2        |
+-------+----------+----------+------------+----------+
| QOUT  | 1        | 1        | 4          | 4        |
+-------+----------+----------+------------+----------+
| QIO   | 1        | 4        | 4          | 4        |
+-------+----------+----------+------------+----------+
| QPI   | 4        | 4        | 4          | 4        |
+-------+----------+----------+------------+----------+

除 QPI 模式外，使用哪种模式通常取决于主机发送的命令（请参考 :ref:`spi_slave_hd_supported_cmds`）。

QPI 模式
^^^^^^^^

QPI 模式是 SPI 从机的一种特殊状态。主机可发送 ENQPI 命令，使从机进入 QPI 模式。在 QPI 模式下，命令以 4 位形式发送，因此与其他正常模式不兼容。只有在从机处于 QPI 模式时，主机才能发送 QPI 命令。主机可发送 EXQPI 命令退出 QPI 模式。

.. _spi_slave_hd_supported_cmds:

支持的命令
----------

.. note::
    命令名称是从主机视角确定的。例如，WRBUF 表示由主机向从机的缓冲区写入。

+----------+---------------+------+----------+------------------------------+
| 名称     | 描述          | 命令 | 地址     | 数据                         |
+----------+---------------+------+----------+------------------------------+
| WRBUF    | 写入缓冲区    | 0x01 | Buf addr | 主到从，不超过缓冲区大小     |
+----------+---------------+------+----------+------------------------------+
| RDBUF    | 读取缓冲区    | 0x02 | Buf addr | 从到主，不超过缓冲区大小     |
+----------+---------------+------+----------+------------------------------+
| WRDMA    | 写入 DMA      | 0x03 | 8 位     | 主到从，不超过从机提供的长度 |
+----------+---------------+------+----------+------------------------------+
| RDDMA    | 读取 DMA      | 0x04 | 8 位     | 从到主，不超过从机提供的长度 |
+----------+---------------+------+----------+------------------------------+
| SEG_DONE | 段完成        | 0x05 | -        | -                            |
+----------+---------------+------+----------+------------------------------+
| ENQPI    | 进入 QPI 模式 | 0x06 | -        | -                            |
+----------+---------------+------+----------+------------------------------+
| WR_DONE  | 写入段完成    | 0x07 | -        | -                            |
+----------+---------------+------+----------+------------------------------+
| CMD8     | 中断          | 0x08 | -        | -                            |
+----------+---------------+------+----------+------------------------------+
| CMD9     | 中断          | 0x09 | -        | -                            |
+----------+---------------+------+----------+------------------------------+
| CMDA     | 中断          | 0x0A | -        | -                            |
+----------+---------------+------+----------+------------------------------+
| EXQPI    | 退出 QPI 模式 | 0xDD | -        | -                            |
+----------+---------------+------+----------+------------------------------+

此外，WRBUF、RDBUF、WRDMA 和 RDDMA 命令都有 2 位和 4 位版本。要在 2 位或 4 位模式下操作，请用下表中的对应命令掩码与原始命令按位或 (bit OR) 后发送。例如，命令 0xA1 表示 QIO 模式下的 WRBUF。

+-------+------+
| 模式  | 掩码 |
+-------+------+
| 1-bit | 0x00 |
+-------+------+
| DOUT  | 0x10 |
+-------+------+
| DIO   | 0x50 |
+-------+------+
| QOUT  | 0x20 |
+-------+------+
| QIO   | 0xA0 |
+-------+------+
| QPI   | 0xA0 |
+-------+------+

段事务模式
------------------

目前，SPI 从机 HD 驱动程序仅支持段事务模式。在此模式下，对于从机加载到 DMA 的事务，主机可以分段读取或写入。这样，主机就无需准备与从机数据大小相同的大缓冲区。主机在一个缓冲区的读取/写入完成后，须向从机发送相应的终止命令作为同步信号。在从机收到终止命令后，从机驱动程序会将新数据（如有）更新到 DMA 上。

WRDMA 的终止命令是 WR_DONE (0x07)，RDDMA 的终止命令是 CMD8 (0x08)。

以下是主机自从机 DMA 读取数据的流程示例：

1. 从机将 4092 字节数据加载到 RDDMA。
2. 主机进行七次 RDDMA 事务，每个事务长 512 字节，并自从机读取前 3584 字节。
3. 主机进行最后一次 RDDMA 事务，长度为 512 字节（长度可以与从机相同、更长或更短）。前 508 字节是从机发送的有效数据，最后 4 字节无意义。
4. 主机向从机发送 CMD8。
5. 从机将其他的 4092 字节数据加载到 RDDMA。
6. 主机发送 CMD8 后，可以开始新的读取事务。
