mirror of
https://github.com/espressif/esp-idf.git
synced 2025-11-28 21:29:50 +01:00
Merge branch 'feature/spi_slave_hd_segment_example' into 'master'
spi_slave_halfduplex: add an example for segment mode Closes IDF-1699 See merge request espressif/esp-idf!10043
This commit is contained in:
@@ -58,7 +58,9 @@ typedef enum {
|
||||
typedef struct {
|
||||
slave_cb_t cb_buffer_tx; ///< Callback when master reads from shared buffer
|
||||
slave_cb_t cb_buffer_rx; ///< Callback when master writes to shared buffer
|
||||
slave_cb_t cb_send_dma_ready; ///< Callback when TX data buffer is loaded to the hardware (DMA)
|
||||
slave_cb_t cb_sent; ///< Callback when data are sent
|
||||
slave_cb_t cb_recv_dma_ready; ///< Callback when RX data buffer is loaded to the hardware (DMA)
|
||||
slave_cb_t cb_recv; ///< Callback when data are received
|
||||
slave_cb_t cb_cmd9; ///< Callback when CMD9 received
|
||||
slave_cb_t cb_cmdA; ///< Callback when CMDA received
|
||||
|
||||
@@ -350,6 +350,15 @@ static IRAM_ATTR void spi_slave_hd_intr_segment(void *arg)
|
||||
if (ret == pdTRUE) {
|
||||
spi_slave_hd_hal_txdma(hal, host->tx_desc->data, host->tx_desc->len);
|
||||
tx_sent = true;
|
||||
if (callback->cb_send_dma_ready) {
|
||||
spi_slave_hd_event_t ev = {
|
||||
.event = SPI_EV_SEND_DMA_READY,
|
||||
.trans = host->tx_desc,
|
||||
};
|
||||
BaseType_t cb_awoken = pdFALSE;
|
||||
callback->cb_send_dma_ready(callback->arg, &ev, &cb_awoken);
|
||||
awoken |= cb_awoken;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!host->rx_desc) {
|
||||
@@ -357,6 +366,15 @@ static IRAM_ATTR void spi_slave_hd_intr_segment(void *arg)
|
||||
if (ret == pdTRUE) {
|
||||
spi_slave_hd_hal_rxdma(hal, host->rx_desc->data, host->rx_desc->len);
|
||||
rx_sent = true;
|
||||
if (callback->cb_recv_dma_ready) {
|
||||
spi_slave_hd_event_t ev = {
|
||||
.event = SPI_EV_RECV_DMA_READY,
|
||||
.trans = host->rx_desc,
|
||||
};
|
||||
BaseType_t cb_awoken = pdFALSE;
|
||||
callback->cb_recv_dma_ready(callback->arg, &ev, &cb_awoken);
|
||||
awoken |= cb_awoken;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -483,7 +501,6 @@ esp_err_t spi_slave_hd_queue_trans(spi_host_device_t host_id, spi_slave_chan_t c
|
||||
{
|
||||
spi_slave_hd_slot_t* host = spihost[host_id];
|
||||
|
||||
SPIHD_CHECK(trans->len <= SPI_MAX_DMA_LEN, "Currently we only support transaction with data length within 4092 bytes", ESP_ERR_INVALID_ARG);
|
||||
SPIHD_CHECK(host->append_mode == 0, "This API should be used for SPI Slave HD Segment Mode", ESP_ERR_INVALID_STATE);
|
||||
SPIHD_CHECK(esp_ptr_dma_capable(trans->data), "The buffer should be DMA capable.", ESP_ERR_INVALID_ARG);
|
||||
SPIHD_CHECK(trans->len <= host->max_transfer_sz && trans->len > 0, "Invalid buffer size", ESP_ERR_INVALID_ARG);
|
||||
|
||||
@@ -76,6 +76,22 @@ esp_err_t essl_spi_rdbuf(spi_device_handle_t spi, uint8_t *out_data, int addr, i
|
||||
return spi_device_transmit(spi, (spi_transaction_t*)&t);
|
||||
}
|
||||
|
||||
esp_err_t essl_spi_rdbuf_polling(spi_device_handle_t spi, uint8_t *out_data, int addr, int len, uint32_t flags)
|
||||
{
|
||||
spi_transaction_ext_t t = {
|
||||
.base = {
|
||||
.cmd = get_hd_command(CMD_HD_RDBUF_REG, flags),
|
||||
.addr = addr % 72,
|
||||
.rxlength = len * 8,
|
||||
.rx_buffer = out_data,
|
||||
.flags = flags | SPI_TRANS_VARIABLE_DUMMY,
|
||||
},
|
||||
.dummy_bits = get_hd_dummy_bits(flags),
|
||||
};
|
||||
|
||||
return spi_device_polling_transmit(spi, (spi_transaction_t*)&t);
|
||||
}
|
||||
|
||||
esp_err_t essl_spi_wrbuf(spi_device_handle_t spi, const uint8_t *data, int addr, int len, uint32_t flags)
|
||||
{
|
||||
spi_transaction_ext_t t = {
|
||||
@@ -91,6 +107,21 @@ esp_err_t essl_spi_wrbuf(spi_device_handle_t spi, const uint8_t *data, int addr,
|
||||
return spi_device_transmit(spi, (spi_transaction_t*)&t);
|
||||
}
|
||||
|
||||
esp_err_t essl_spi_wrbuf_polling(spi_device_handle_t spi, const uint8_t *data, int addr, int len, uint32_t flags)
|
||||
{
|
||||
spi_transaction_ext_t t = {
|
||||
.base = {
|
||||
.cmd = get_hd_command(CMD_HD_WRBUF_REG, flags),
|
||||
.addr = addr % 72,
|
||||
.length = len * 8,
|
||||
.tx_buffer = data,
|
||||
.flags = flags | SPI_TRANS_VARIABLE_DUMMY,
|
||||
},
|
||||
.dummy_bits = get_hd_dummy_bits(flags),
|
||||
};
|
||||
return spi_device_polling_transmit(spi, (spi_transaction_t*)&t);
|
||||
}
|
||||
|
||||
esp_err_t essl_spi_rddma_seg(spi_device_handle_t spi, uint8_t *out_data, int seg_len, uint32_t flags)
|
||||
{
|
||||
spi_transaction_ext_t t = {
|
||||
|
||||
@@ -28,7 +28,7 @@ extern "C"
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* @brief Read the shared buffer from the slave.
|
||||
* @brief Read the shared buffer from the slave in ISR way
|
||||
*
|
||||
* @note ``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
|
||||
@@ -46,7 +46,25 @@ extern "C"
|
||||
esp_err_t essl_spi_rdbuf(spi_device_handle_t spi, uint8_t *out_data, int addr, int len, uint32_t flags);
|
||||
|
||||
/**
|
||||
* @brief Write the shared buffer of the slave.
|
||||
* @brief Read the shared buffer from the slave in polling way
|
||||
*
|
||||
* @note ``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.
|
||||
*
|
||||
* @param spi SPI device handle representing the slave
|
||||
* @param out_data Buffer for read data, strongly suggested to be in the DRAM and align to 4
|
||||
* @param addr Address of the slave shared buffer
|
||||
* @param len Length to read
|
||||
* @param flags `SPI_TRANS_*` flags to control the transaction mode of the transaction to send.
|
||||
* @return
|
||||
* - 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);
|
||||
|
||||
/**
|
||||
* @brief Write the shared buffer of the slave in ISR way
|
||||
*
|
||||
* @note ``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
|
||||
@@ -63,6 +81,24 @@ esp_err_t essl_spi_rdbuf(spi_device_handle_t spi, uint8_t *out_data, int addr, i
|
||||
*/
|
||||
esp_err_t essl_spi_wrbuf(spi_device_handle_t spi, const uint8_t *data, int addr, int len, uint32_t flags);
|
||||
|
||||
/**
|
||||
* @brief Write the shared buffer of the slave in polling way
|
||||
*
|
||||
* @note ``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.
|
||||
*
|
||||
* @param spi SPI device handle representing the slave
|
||||
* @param data Buffer for data to send, strongly suggested to be in the DRAM and align to 4
|
||||
* @param addr Address of the slave shared buffer,
|
||||
* @param len Length to write
|
||||
* @param flags `SPI_TRANS_*` flags to control the transaction mode of the transaction to send.
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - or other return value from :cpp:func:`spi_device_polling_transmit`.
|
||||
*/
|
||||
esp_err_t essl_spi_wrbuf_polling(spi_device_handle_t spi, const uint8_t *data, int addr, int len, uint32_t flags);
|
||||
|
||||
/**
|
||||
* @brief Receive long buffer in segments from the slave through its DMA.
|
||||
*
|
||||
|
||||
@@ -31,13 +31,17 @@ typedef enum {
|
||||
|
||||
/// SPI Events
|
||||
typedef enum {
|
||||
SPI_EV_BUF_TX = BIT(0), ///< The buffer has sent data to master, Slave HD only
|
||||
SPI_EV_BUF_RX = BIT(1), ///< The buffer has received data from master, Slave HD only
|
||||
SPI_EV_SEND = BIT(2), ///< Slave has loaded some data to DMA, and master has received certain number of the data, the number is determined by master. Slave HD only
|
||||
SPI_EV_RECV = BIT(3), ///< Slave has received certain number of data from master, the number is determined by master. Slave HD only.
|
||||
SPI_EV_CMD9 = BIT(4), ///< Received CMD9 from master, Slave HD only
|
||||
SPI_EV_CMDA = BIT(5), ///< Received CMDA from master, Slave HD only
|
||||
SPI_EV_TRANS = BIT(6), ///< A transaction has done
|
||||
/* Slave HD Only */
|
||||
SPI_EV_BUF_TX = BIT(0), ///< The buffer has sent data to master.
|
||||
SPI_EV_BUF_RX = BIT(1), ///< The buffer has received data from master.
|
||||
SPI_EV_SEND_DMA_READY = BIT(2), ///< Slave has loaded its TX data buffer to the hardware (DMA).
|
||||
SPI_EV_SEND = BIT(3), ///< Master has received certain number of the data, the number is determined by Master.
|
||||
SPI_EV_RECV_DMA_READY = BIT(4), ///< Slave has loaded its RX data buffer to the hardware (DMA).
|
||||
SPI_EV_RECV = BIT(5), ///< Slave has received certain number of data from master, the number is determined by Master.
|
||||
SPI_EV_CMD9 = BIT(6), ///< Received CMD9 from master.
|
||||
SPI_EV_CMDA = BIT(7), ///< Received CMDA from master.
|
||||
/* Common Event */
|
||||
SPI_EV_TRANS = BIT(8), ///< A transaction has done
|
||||
} spi_event_t;
|
||||
FLAG_ATTR(spi_event_t)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user