# ESP 串行从机链路

[English]

## 概述

乐鑫有多款芯片可用作从机。这些从机依赖于一些通用总线，并在总线上实现了各自的通信协议。 `esp_serial_slave_link` 组件能让主机通过总线驱动和相应的协议与 ESP 从机进行通信。

`esp_serial_slave_link` 设备初始化完成后，应用程序就能通过它与 ESP 从机方便地通信。

备注

`esp_serial_slave_link` 组件自 ESP-IDF 版本 v5.0 起移到了单独的仓库：

- ESSL component on GitHub

运行 `idf.py add-dependency espressif/esp_serial_slave_link` 将 ESSL 组件添加到你的项目中。

## 乐鑫设备协议

如需了解关于乐鑫设备协议详情，请参考以下文档：

- ESP SDIO 主从机通信
- ESP SPI 从机 HD（半双工）模式协议

## 术语解释

- ESSL：ESP 串行从机链路 (ESP Serial Slave Link)，即本文档描述的组件。

- 主机：运行 `esp_serial_slave_link` 组件的设备。

- ESSL 设备：主机上的虚拟设备，关联到一个 ESP 从机，其设备上下文中具有如何通过总线驱动和从机的总线协议与其通信的信息。

- ESSL 设备句柄：ESSL 设备上下文的一个句柄，包含配置信息、状态信息和 ESSL 组件所需的数据。设备上下文中储存了驱动配置、通信状态和主从机共享的数据等。

  > - 在使用前，应将上下文初始化；如不再使用，应该反初始化。主机应用程序通过这一句柄操作 ESSL 设备。

- ESP 从机：连接到总线的从机，ESSL 组件的通信对象。

- 总线：特指用于主机和从机相互通信的总线。

- 从机协议：Espressif 硬件和软件在总线上使用的特殊通信协议。

- TX buffer num：计数器，位于从机，可由主机读取。指示由从机加载到硬件上、用于接收主机数据的累计 buffer 总数。

- RX data size：计数器，位于从机，可由主机读取。指示由从机加载到硬件上、需发送给主机的累计数据大小。

## ESP 从机提供的服务

Espressif 从机提供下列服务：

1. Tohost 中断：从机可通过中断线向主机通知某些事件。（可选）

2. Frhost 中断：主机可向从机通知某些事件。

3. TX FIFO（主机到从机）：从机能够以接收 buffer 为单位，接收主机发送的数据。

   从机通过更新 TX buffer num 的方式，将可以接收多少数据的信息通知主机。主机读取 TX buffer num，减去已使用的 buffer 数，得到剩余 buffer 数量。

4. RX FIFO（从机到主机）：从机可向主机发送数据流。SDIO 从机也可通过中断线通知主机，从机有待发送的新数据。

   从机通过更新 RX data size，将准备发送的数据大小通知主机。主机读取该数据大小，减去已接收的数据长度，得到剩余数据大小。

5. 共享寄存器：主机可以读取从机寄存器上的部分内容，也可写入从机寄存器供从机读取。

从机提供的服务取决于从机的模型。如需了解详情，请参考 乐鑫芯片的 SDIO 从机功能 和 乐鑫芯片的 SPI 从机功能支持概况。

## 初始化 ESP 串行从机链路

### ESP SDIO 从机

ESP SDIO 从机链路 (ESSL SDIO) 设备依赖于 SDMMC 组件。它可通过 SDMMC Host 或 SDSPI Host 功能均可与 ESP SDIO 从机通信。ESSL 设备初始化步骤如下：

1. 初始化 SDMMC 卡（参考 SDMMC 驱动相关文档 ）结构体。

2. 调用 `sdmmc_card_init()` 初始化该卡。

3. 用 `essl_sdio_config_t` 初始化 ESSL 设备。其中， `card` 成员应为第二步中的 `sdmmc_card_t`， `recv_buffer_size` 成员应填写为预先协商的值。

4. 调用 `essl_init()` 对 SDIO 部分进行初始化。

5. 调用 `essl_wait_for_ready()` 等待从机就绪。

### ESP SPI 从机

备注

如果你正在用 SPI 接口与 ESP SDIO 从机进行通信，则应该用 SDIO 接口 代替。

暂不支持。

## API

初始化完成后，你可调用以下 API 使用从机提供的服务：

### Tohost 中断（可选）

1. 调用 `essl_get_intr_ena()` 了解哪些事件触发了对主机的中断。

2. 调用 `essl_set_intr_ena()` 设置能够触发主机中断的事件。

3. 调用 `essl_wait_int()` 等待从机中断或超时。

4. 中断触发后，调用 `essl_get_intr()` 了解哪些事件处于活跃状态，并调用 `essl_clear_intr()` 将其清空。

### Frhost 中断

1. 调用 `essl_send_slave_intr()` 触发从机的通用中断。

### TX FIFO

1. 调用 `essl_get_tx_buffer_num()` 了解从机准备用于接收主机数据的 buffer 数。你可选择是否调用该函数。主机向从机发送数据包前，也会轮询 `tx_buffer_num`，直到从机的 buffer 数量足够或超时。

2. 调用 `essl_send_packet()` 向从机发送数据。

### RX FIFO

1. 调用 `essl_get_rx_data_size()` 了解从机需发送给主机的数据大小。你可选择是否调用该函数。当主机尝试接收数据时，如果目前的 `rx_data_size` 小于主机准备接收数据的 buffer 大小，就会对 `rx_data_size` 进行一次更新。如果 `rx_data_size` 一直为 0，主机可能会轮询 `rx_data_size` 直到超时。

2. 调用 `essl_get_packet()` 接收来自从机的数据。

### 重置计数器（可选）

如果从机计数器已重置，调用 `essl_reset_cnt()` 重置内部计数器。

## 应用示例

以下示例展示了 ESP32-C6 SDIO 主机如何与从机互相通信，其中主机使用了 ESSL SDIO：

peripherals/sdio

如需了解详情，请参考 README.md 中的示例。

## API 参考

### Header File

- components/driver/test_apps/components/esp_serial_slave_link/include/esp_serial_slave_link/essl.h

### Functions

esp_err_t essl_init(essl_handle_t handle, uint32_t wait_ms)

  Initialize the slave.

  参数:

    - handle -- Handle of an ESSL device.

    - wait_ms -- Millisecond to wait before timeout, will not wait at all if set to 0-9.

  返回:

    - ESP_OK: If success

    - ESP_ERR_NOT_SUPPORTED: Current device does not support this function.

    - Other value returned from lower layer `init`.

esp_err_t essl_wait_for_ready(essl_handle_t handle, uint32_t wait_ms)

  Wait for interrupt of an ESSL slave device.

  参数:

    - handle -- Handle of an ESSL device.

    - wait_ms -- Millisecond to wait before timeout, will not wait at all if set to 0-9.

  返回:

    - ESP_OK: If success

    - ESP_ERR_NOT_SUPPORTED: Current device does not support this function.

    - One of the error codes from SDMMC host controller

esp_err_t essl_get_tx_buffer_num(essl_handle_t handle, uint32_t *out_tx_num, uint32_t wait_ms)

  Get buffer num for the host to send data to the slave. The buffers are size of `buffer_size`.

  参数:

    - handle -- Handle of a ESSL device.

    - out_tx_num -- Output of buffer num that host can send data to ESSL slave.

    - wait_ms -- Millisecond to wait before timeout, will not wait at all if set to 0-9.

  返回:

    - ESP_OK: Success

    - ESP_ERR_NOT_SUPPORTED: This API is not supported in this mode

    - One of the error codes from SDMMC/SPI host controller

esp_err_t essl_get_rx_data_size(essl_handle_t handle, uint32_t *out_rx_size, uint32_t wait_ms)

  Get the size, in bytes, of the data that the ESSL slave is ready to send

  参数:

    - handle -- Handle of an ESSL device.

    - out_rx_size -- Output of data size to read from slave, in bytes

    - wait_ms -- Millisecond to wait before timeout, will not wait at all if set to 0-9.

  返回:

    - ESP_OK: Success

    - ESP_ERR_NOT_SUPPORTED: This API is not supported in this mode

    - One of the error codes from SDMMC/SPI host controller

esp_err_t essl_reset_cnt(essl_handle_t handle)

  Reset the counters of this component. Usually you don't need to do this unless you know the slave is reset.

  参数:

    handle -- Handle of an ESSL device.

  返回:

    - ESP_OK: Success

    - ESP_ERR_NOT_SUPPORTED: This API is not supported in this mode

    - ESP_ERR_INVALID_ARG: Invalid argument, handle is not init.

esp_err_t essl_send_packet(essl_handle_t handle, const void *start, size_t length, uint32_t wait_ms)

  Send a packet to the ESSL Slave. The Slave receives the packet into buffers whose size is `buffer_size` (configured during initialization).

  参数:

    - handle -- Handle of an ESSL device.

    - start -- Start address of the packet to send

    - length -- Length of data to send, if the packet is over-size, the it will be divided into blocks and hold into different buffers automatically.

    - wait_ms -- Millisecond to wait before timeout, will not wait at all if set to 0-9.

  返回:

    - ESP_OK Success

    - ESP_ERR_INVALID_ARG: Invalid argument, handle is not init or other argument is not valid.

    - ESP_ERR_TIMEOUT: No buffer to use, or error ftrom SDMMC host controller.

    - ESP_ERR_NOT_FOUND: Slave is not ready for receiving.

    - ESP_ERR_NOT_SUPPORTED: This API is not supported in this mode

    - One of the error codes from SDMMC/SPI host controller.

esp_err_t essl_get_packet(essl_handle_t handle, void *out_data, size_t size, size_t *out_length, uint32_t wait_ms)

  Get a packet from ESSL slave.

  参数:

    - handle -- Handle of an ESSL device.

    - out_data -- [out] Data output address

    - size -- The size of the output buffer, if the buffer is smaller than the size of data to receive from slave, the driver returns `ESP_ERR_NOT_FINISHED`

    - out_length -- [out] Output of length the data actually received from slave.

    - wait_ms -- Millisecond to wait before timeout, will not wait at all if set to 0-9.

  返回:

    - ESP_OK Success: All the data has been read from the slave.

    - ESP_ERR_INVALID_ARG: Invalid argument, The handle is not initialized or the other arguments are invalid.

    - ESP_ERR_NOT_FINISHED: Read was successful, but there is still data remaining.

    - ESP_ERR_NOT_FOUND: Slave is not ready to send data.

    - ESP_ERR_NOT_SUPPORTED: This API is not supported in this mode

    - One of the error codes from SDMMC/SPI host controller.

esp_err_t essl_write_reg(essl_handle_t handle, uint8_t addr, uint8_t value, uint8_t *value_o, uint32_t wait_ms)

  Write general purpose R/W registers (8-bit) of ESSL slave.

  备注

  sdio 28-31 are reserved, the lower API helps to skip.

  参数:

    - handle -- Handle of an ESSL device.

    - addr -- Address of register to write. For SDIO, valid address: 0-59. For SPI, see `essl_spi.h`

    - value -- Value to write to the register.

    - value_o -- Output of the returned written value.

    - wait_ms -- Millisecond to wait before timeout, will not wait at all if set to 0-9.

  返回:

    - ESP_OK Success

    - One of the error codes from SDMMC/SPI host controller

esp_err_t essl_read_reg(essl_handle_t handle, uint8_t add, uint8_t *value_o, uint32_t wait_ms)

  Read general purpose R/W registers (8-bit) of ESSL slave.

  参数:

    - handle -- Handle of a `essl` device.

    - add -- Address of register to read. For SDIO, Valid address: 0-27, 32-63 (28-31 reserved, return interrupt bits on read). For SPI, see `essl_spi.h`

    - value_o -- Output value read from the register.

    - wait_ms -- Millisecond to wait before timeout, will not wait at all if set to 0-9.

  返回:

    - ESP_OK Success

    - One of the error codes from SDMMC/SPI host controller

esp_err_t essl_wait_int(essl_handle_t handle, uint32_t wait_ms)

  wait for an interrupt of the slave

  参数:

    - handle -- Handle of an ESSL device.

    - wait_ms -- Millisecond to wait before timeout, will not wait at all if set to 0-9.

  返回:

    - ESP_OK: If interrupt is triggered.

    - ESP_ERR_NOT_SUPPORTED: Current device does not support this function.

    - ESP_ERR_TIMEOUT: No interrupts before timeout.

esp_err_t essl_clear_intr(essl_handle_t handle, uint32_t intr_mask, uint32_t wait_ms)

  Clear interrupt bits of ESSL slave. All the bits set in the mask will be cleared, while other bits will stay the same.

  参数:

    - handle -- Handle of an ESSL device.

    - intr_mask -- Mask of interrupt bits to clear.

    - wait_ms -- Millisecond to wait before timeout, will not wait at all if set to 0-9.

  返回:

    - ESP_OK: Success

    - ESP_ERR_NOT_SUPPORTED: Current device does not support this function.

    - One of the error codes from SDMMC host controller

esp_err_t essl_get_intr(essl_handle_t handle, uint32_t *intr_raw, uint32_t *intr_st, uint32_t wait_ms)

  Get interrupt bits of ESSL slave.

  参数:

    - handle -- Handle of an ESSL device.

    - intr_raw -- Output of the raw interrupt bits. Set to NULL if only masked bits are read.

    - intr_st -- Output of the masked interrupt bits. set to NULL if only raw bits are read.

    - wait_ms -- Millisecond to wait before timeout, will not wait at all if set to 0-9.

  返回:

    - ESP_OK: Success

    - ESP_INVALID_ARG: If both `intr_raw` and `intr_st` are NULL.

    - ESP_ERR_NOT_SUPPORTED: Current device does not support this function.

    - One of the error codes from SDMMC host controller

esp_err_t essl_set_intr_ena(essl_handle_t handle, uint32_t ena_mask, uint32_t wait_ms)

  Set interrupt enable bits of ESSL slave. The slave only sends interrupt on the line when there is a bit both the raw status and the enable are set.

  参数:

    - handle -- Handle of an ESSL device.

    - ena_mask -- Mask of the interrupt bits to enable.

    - wait_ms -- Millisecond to wait before timeout, will not wait at all if set to 0-9.

  返回:

    - ESP_OK: Success

    - ESP_ERR_NOT_SUPPORTED: Current device does not support this function.

    - One of the error codes from SDMMC host controller

esp_err_t essl_get_intr_ena(essl_handle_t handle, uint32_t *ena_mask_o, uint32_t wait_ms)

  Get interrupt enable bits of ESSL slave.

  参数:

    - handle -- Handle of an ESSL device.

    - ena_mask_o -- Output of interrupt bit enable mask.

    - wait_ms -- Millisecond to wait before timeout, will not wait at all if set to 0-9.

  返回:

    - ESP_OK Success

    - One of the error codes from SDMMC host controller

esp_err_t essl_send_slave_intr(essl_handle_t handle, uint32_t intr_mask, uint32_t wait_ms)

  Send interrupts to slave. Each bit of the interrupt will be triggered.

  参数:

    - handle -- Handle of an ESSL device.

    - intr_mask -- Mask of interrupt bits to send to slave.

    - wait_ms -- Millisecond to wait before timeout, will not wait at all if set to 0-9.

  返回:

    - ESP_OK: Success

    - ESP_ERR_NOT_SUPPORTED: Current device does not support this function.

    - One of the error codes from SDMMC host controller

### Type Definitions

typedef struct essl_dev_t *essl_handle_t

  Handle of an ESSL device.

### Header File

- components/driver/test_apps/components/esp_serial_slave_link/include/esp_serial_slave_link/essl_sdio.h

### Functions

esp_err_t essl_sdio_init_dev(essl_handle_t *out_handle, const essl_sdio_config_t *config)

  Initialize the ESSL SDIO device and get its handle.

  参数:

    - out_handle -- Output of the handle.

    - config -- Configuration for the ESSL SDIO device.

  返回:

    - ESP_OK: on success

    - ESP_ERR_NO_MEM: memory exhausted.

esp_err_t essl_sdio_deinit_dev(essl_handle_t handle)

  Deinitialize and free the space used by the ESSL SDIO device.

  参数:

    handle -- Handle of the ESSL SDIO device to deinit.

  返回:

    - ESP_OK: on success

    - ESP_ERR_INVALID_ARG: wrong handle passed

### Structures

struct essl_sdio_config_t

  Configuration for the ESSL SDIO device.

  Public Members

  sdmmc_card_t *card

    The initialized sdmmc card pointer of the slave.

  int recv_buffer_size

    The pre-negotiated recv buffer size used by both the host and the slave.

### Header File

- components/driver/test_apps/components/esp_serial_slave_link/include/esp_serial_slave_link/essl_spi.h

### Functions

esp_err_t essl_spi_init_dev(essl_handle_t *out_handle, const essl_spi_config_t *init_config)

  Initialize the ESSL SPI device function list and get its handle.

  参数:

    - out_handle -- [out] Output of the handle

    - init_config -- Configuration for the ESSL SPI device

  返回:

    - ESP_OK: On success

    - ESP_ERR_NO_MEM: Memory exhausted

    - ESP_ERR_INVALID_STATE: SPI driver is not initialized

    - ESP_ERR_INVALID_ARG: Wrong register ID

esp_err_t essl_spi_deinit_dev(essl_handle_t handle)

  Deinitialize the ESSL SPI device and free the memory used by the device.

  参数:

    handle -- Handle of the ESSL SPI device

  返回:

    - ESP_OK: On success

    - ESP_ERR_INVALID_STATE: ESSL SPI is not in use

esp_err_t essl_spi_read_reg(void *arg, uint8_t addr, uint8_t *out_value, uint32_t wait_ms)

  Read from the shared registers.

  备注

  The registers for Master/Slave synchronization are reserved. Do not use them. (see `rx_sync_reg` in `essl_spi_config_t`)

  参数:

    - arg -- Context of the component. (Member `arg` from `essl_handle_t`)

    - addr -- Address of the shared registers. (Valid: 0 ~ SOC_SPI_MAXIMUM_BUFFER_SIZE, registers for M/S sync are reserved, see note1).

    - out_value -- [out] Read buffer for the shared registers.

    - wait_ms -- Time to wait before timeout (reserved for future use, user should set this to 0).

  返回:

    - ESP_OK: success

    - ESP_ERR_INVALID_STATE: ESSL SPI has not been initialized.

    - ESP_ERR_INVALID_ARG: The address argument is not valid. See note 1.

    - or other return value from :cpp:func:`spi_device_transmit`.

esp_err_t essl_spi_get_packet(void *arg, void *out_data, size_t size, uint32_t wait_ms)

  Get a packet from Slave.

  参数:

    - arg -- Context of the component. (Member `arg` from `essl_handle_t`)

    - out_data -- [out] Output data address

    - size -- The size of the output data.

    - wait_ms -- Time to wait before timeout (reserved for future use, user should set this to 0).

  返回:

    - ESP_OK: On Success

    - ESP_ERR_INVALID_STATE: ESSL SPI has not been initialized.

    - ESP_ERR_INVALID_ARG: The output data address is neither DMA capable nor 4 byte-aligned

    - ESP_ERR_INVALID_SIZE: Master requires `size` bytes of data but Slave did not load enough bytes.

esp_err_t essl_spi_write_reg(void *arg, uint8_t addr, uint8_t value, uint8_t *out_value, uint32_t wait_ms)

  Write to the shared registers.

  备注

  The registers for Master/Slave synchronization are reserved. Do not use them. (see `tx_sync_reg` in `essl_spi_config_t`)

  备注

  Feature of checking the actual written value (`out_value`) is not supported.

  参数:

    - arg -- Context of the component. (Member `arg` from `essl_handle_t`)

    - addr -- Address of the shared registers. (Valid: 0 ~ SOC_SPI_MAXIMUM_BUFFER_SIZE, registers for M/S sync are reserved, see note1)

    - value -- Buffer for data to send, should be align to 4.

    - out_value -- [out] Not supported, should be set to NULL.

    - wait_ms -- Time to wait before timeout (reserved for future use, user should set this to 0).

  返回:

    - ESP_OK: success

    - ESP_ERR_INVALID_STATE: ESSL SPI has not been initialized.

    - ESP_ERR_INVALID_ARG: The address argument is not valid. See note 1.

    - ESP_ERR_NOT_SUPPORTED: Should set `out_value` to NULL. See note 2.

    - or other return value from :cpp:func:`spi_device_transmit`.

esp_err_t essl_spi_send_packet(void *arg, const void *data, size_t size, uint32_t wait_ms)

  Send a packet to Slave.

  参数:

    - arg -- Context of the component. (Member `arg` from `essl_handle_t`)

    - data -- Address of the data to send

    - size -- Size of the data to send.

    - wait_ms -- Time to wait before timeout (reserved for future use, user should set this to 0).

  返回:

    - ESP_OK: On success

    - ESP_ERR_INVALID_STATE: ESSL SPI has not been initialized.

    - ESP_ERR_INVALID_ARG: The data address is not DMA capable

    - ESP_ERR_INVALID_SIZE: Master will send `size` bytes of data but Slave did not load enough RX buffer

void essl_spi_reset_cnt(void *arg)

  Reset the counter in Master context.

  备注

  Shall only be called if the slave has reset its counter. Else, Slave and Master would be desynchronized

  参数:

    arg -- Context of the component. (Member `arg` from `essl_handle_t`)

esp_err_t essl_spi_rdbuf(spi_device_handle_t spi, uint8_t *out_data, int addr, int len, uint32_t flags)

  Read the shared buffer from the slave in ISR way.

  备注

  The slave's HW doesn't guarantee the data in one SPI transaction is consistent. It sends data in unit of byte. In other words, if the slave SW attempts to update the shared register when a rdbuf SPI transaction is in-flight, the data got by the master will be the combination of bytes of different writes of slave SW.

  备注

  `out_data` should be prepared in words and in the DRAM. The buffer may be written in words by the DMA. When a byte is written, the remaining bytes in the same word will also be overwritten, even the `len` is shorter than a word.

  参数:

    - spi -- SPI device handle representing the slave

    - out_data -- [out] Buffer for read data, strongly suggested to be in the DRAM and aligned to 4

    - addr -- Address of the slave shared buffer

    - len -- Length to read

    - flags -- `SPI_TRANS_*` flags to control the transaction mode of the transaction to send.

  返回:

    - ESP_OK: on success

    - or other return value from :cpp:func:`spi_device_transmit`.

esp_err_t essl_spi_rdbuf_polling(spi_device_handle_t spi, uint8_t *out_data, int addr, int len, uint32_t flags)

  Read the shared buffer from the slave in polling way.

  备注

  `out_data` should be prepared in words and in the DRAM. The buffer may be written in words by the DMA. When a byte is written, the remaining bytes in the same word will also be overwritten, even the `len` is shorter than a word.

  参数:

    - spi -- SPI device handle representing the slave

    - out_data -- [out] Buffer for read data, strongly suggested to be in the DRAM and aligned to 4

    - addr -- Address of the slave shared buffer

    - len -- Length to read

    - flags -- `SPI_TRANS_*` flags to control the transaction mode of the transaction to send.

  返回:

    - ESP_OK: on success

    - or other return value from :cpp:func:`spi_device_transmit`.

esp_err_t essl_spi_wrbuf(spi_device_handle_t spi, const uint8_t *data, int addr, int len, uint32_t flags)

  Write the shared buffer of the slave in ISR way.

  备注

  `out_data` should be prepared in words and in the DRAM. The buffer may be written in words by the DMA. When a byte is written, the remaining bytes in the same word will also be overwritten, even the `len` is shorter than a word.

  参数:

    - spi -- SPI device handle representing the slave

    - data -- Buffer for data to send, strongly suggested to be in the DRAM

    - addr -- Address of the slave shared buffer,

    - len -- Length to write

    - flags -- `SPI_TRANS_*` flags to control the transaction mode of the transaction to send.

  返回:

    - ESP_OK: success

    - or other return value from :cpp:func:`spi_device_transmit`.

esp_err_t essl_spi_wrbuf_polling(spi_device_handle_t spi, const uint8_t *data, int addr, int len, uint32_t flags)

  Write the shared buffer of the slave in polling way.

  备注

  `out_data` should be prepared in words and in the DRAM. The buffer may be written in words by the DMA. When a byte is written, the remaining bytes in the same word will also be overwritten, even the `len` is shorter than a word.

  参数:

    - spi -- SPI device handle representing the slave

    - data -- Buffer for data to send, strongly suggested to be in the DRAM

    - addr -- Address of the slave shared buffer,

    - len -- Length to write

    - flags -- `SPI_TRANS_*` flags to control the transaction mode of the transaction to send.

  返回:

    - ESP_OK: success

    - or other return value from :cpp:func:`spi_device_polling_transmit`.

esp_err_t essl_spi_rddma(spi_device_handle_t spi, uint8_t *out_data, int len, int seg_len, uint32_t flags)

  Receive long buffer in segments from the slave through its DMA.

  备注

  This function combines several :cpp:func:`essl_spi_rddma_seg` and one :cpp:func:`essl_spi_rddma_done` at the end. Used when the slave is working in segment mode.

  参数:

    - spi -- SPI device handle representing the slave

    - out_data -- [out] Buffer to hold the received data, strongly suggested to be in the DRAM and aligned to 4

    - len -- Total length of data to receive.

    - seg_len -- Length of each segment, which is not larger than the maximum transaction length allowed for the spi device. Suggested to be multiples of 4. When set < 0, means send all data in one segment (the `rddma_done` will still be sent.)

    - flags -- `SPI_TRANS_*` flags to control the transaction mode of the transaction to send.

  返回:

    - ESP_OK: success

    - or other return value from :cpp:func:`spi_device_transmit`.

esp_err_t essl_spi_rddma_seg(spi_device_handle_t spi, uint8_t *out_data, int seg_len, uint32_t flags)

  Read one data segment from the slave through its DMA.

  备注

  To read long buffer, call :cpp:func:`essl_spi_rddma` instead.

  参数:

    - spi -- SPI device handle representing the slave

    - out_data -- [out] Buffer to hold the received data. strongly suggested to be in the DRAM and aligned to 4

    - seg_len -- Length of this segment

    - flags -- `SPI_TRANS_*` flags to control the transaction mode of the transaction to send.

  返回:

    - ESP_OK: success

    - or other return value from :cpp:func:`spi_device_transmit`.

esp_err_t essl_spi_rddma_done(spi_device_handle_t spi, uint32_t flags)

  Send the `rddma_done` command to the slave. Upon receiving this command, the slave will stop sending the current buffer even there are data unsent, and maybe prepare the next buffer to send.

  备注

  This is required only when the slave is working in segment mode.

  参数:

    - spi -- SPI device handle representing the slave

    - flags -- `SPI_TRANS_*` flags to control the transaction mode of the transaction to send.

  返回:

    - ESP_OK: success

    - or other return value from :cpp:func:`spi_device_transmit`.

esp_err_t essl_spi_wrdma(spi_device_handle_t spi, const uint8_t *data, int len, int seg_len, uint32_t flags)

  Send long buffer in segments to the slave through its DMA.

  备注

  This function combines several :cpp:func:`essl_spi_wrdma_seg` and one :cpp:func:`essl_spi_wrdma_done` at the end. Used when the slave is working in segment mode.

  参数:

    - spi -- SPI device handle representing the slave

    - data -- Buffer for data to send, strongly suggested to be in the DRAM

    - len -- Total length of data to send.

    - seg_len -- Length of each segment, which is not larger than the maximum transaction length allowed for the spi device. Suggested to be multiples of 4. When set < 0, means send all data in one segment (the `wrdma_done` will still be sent.)

    - flags -- `SPI_TRANS_*` flags to control the transaction mode of the transaction to send.

  返回:

    - ESP_OK: success

    - or other return value from :cpp:func:`spi_device_transmit`.

esp_err_t essl_spi_wrdma_seg(spi_device_handle_t spi, const uint8_t *data, int seg_len, uint32_t flags)

  Send one data segment to the slave through its DMA.

  备注

  To send long buffer, call :cpp:func:`essl_spi_wrdma` instead.

  参数:

    - spi -- SPI device handle representing the slave

    - data -- Buffer for data to send, strongly suggested to be in the DRAM

    - seg_len -- Length of this segment

    - flags -- `SPI_TRANS_*` flags to control the transaction mode of the transaction to send.

  返回:

    - ESP_OK: success

    - or other return value from :cpp:func:`spi_device_transmit`.

esp_err_t essl_spi_wrdma_done(spi_device_handle_t spi, uint32_t flags)

  Send the `wrdma_done` command to the slave. Upon receiving this command, the slave will stop receiving, process the received data, and maybe prepare the next buffer to receive.

  备注

  This is required only when the slave is working in segment mode.

  参数:

    - spi -- SPI device handle representing the slave

    - flags -- `SPI_TRANS_*` flags to control the transaction mode of the transaction to send.

  返回:

    - ESP_OK: success

    - or other return value from :cpp:func:`spi_device_transmit`.

### Structures

struct essl_spi_config_t

  Configuration of ESSL SPI device.

  Public Members

  spi_device_handle_t *spi

    Pointer to SPI device handle.

  uint32_t tx_buf_size

    The pre-negotiated Master TX buffer size used by both the host and the slave.

  uint8_t tx_sync_reg

    The pre-negotiated register ID for Master-TX-SLAVE-RX synchronization. 1 word (4 Bytes) will be reserved for the synchronization.

  uint8_t rx_sync_reg

    The pre-negotiated register ID for Master-RX-Slave-TX synchronization. 1 word (4 Bytes) will be reserved for the synchronization.

此文档对您有帮助吗？

- 反馈已收到，谢谢！
- 如果您有其他意见，欢迎填写乐鑫文档反馈表。

- 我们重视您的反馈。
- 您可以填写乐鑫文档反馈表告诉我们如何改进该文档。