From 0a4dc0d4c2270cd02f414692362988dbe87e286a Mon Sep 17 00:00:00 2001 From: Xu Si Yu Date: Thu, 18 Jun 2026 19:21:52 +0800 Subject: [PATCH] fix(openthread): use spi slave tx_length/rx_length and remove rx DMA bounce buffer --- .../src/port/esp_openthread_spi_slave.c | 28 +++---------------- 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/components/openthread/src/port/esp_openthread_spi_slave.c b/components/openthread/src/port/esp_openthread_spi_slave.c index 787daadd2ea..d9415639ad8 100644 --- a/components/openthread/src/port/esp_openthread_spi_slave.c +++ b/components/openthread/src/port/esp_openthread_spi_slave.c @@ -33,11 +33,6 @@ typedef struct { uint16_t input_buf_len; } pending_transaction_t; -// DMA bounce buffer for RX — always sized to max(input, output) so MISO is -// driven for the full output even when NcpSpi passes a small input buffer. -#define SPI_SLAVE_RX_DMA_BUF_SIZE OPENTHREAD_CONFIG_NCP_SPI_BUFFER_SIZE -static DRAM_ATTR uint8_t *s_rx_dma_buf = NULL; - // Guards the BUSY path: only return OT_ERROR_BUSY when a transaction is truly // queued in the driver, so post_trans_cb is guaranteed to fire and re-queue. static volatile DRAM_ATTR bool s_transaction_in_flight = false; @@ -70,11 +65,6 @@ static void IRAM_ATTR handle_spi_transaction_done(spi_slave_transaction_t *trans trans->trans_len = max_buf_len; } - // Copy RX bounce buffer back to the actual NcpSpi input buffer. - if (s_input_buf && s_rx_dma_buf && s_rx_dma_buf != s_input_buf) { - memcpy(s_input_buf, s_rx_dma_buf, pending_transaction->input_buf_len); - } - if (s_complete_callback && s_complete_callback(s_context, (void*)trans->tx_buffer, pending_transaction->output_buf_len, s_input_buf, pending_transaction->input_buf_len, trans->trans_len)) { @@ -108,8 +98,6 @@ esp_err_t esp_openthread_host_rcp_spi_init(const esp_openthread_platform_config_ ESP_GOTO_ON_FALSE(s_spi_transaction != NULL, ESP_ERR_NO_MEM, err, OT_PLAT_LOG_TAG, "failed to allocate memory for SPI transaction on internal heap"); s_pending_transaction = heap_caps_calloc(1, sizeof(pending_transaction_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); ESP_GOTO_ON_FALSE(s_pending_transaction != NULL, ESP_ERR_NO_MEM, err, OT_PLAT_LOG_TAG, "failed to allocate memory for pending transaction on internal heap"); - s_rx_dma_buf = heap_caps_calloc(1, SPI_SLAVE_RX_DMA_BUF_SIZE, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); - ESP_GOTO_ON_FALSE(s_rx_dma_buf != NULL, ESP_ERR_NO_MEM, err, OT_PLAT_LOG_TAG, "failed to allocate memory for RX DMA buffer on internal heap"); s_spi_transaction->user = (void *)s_pending_transaction; @@ -128,8 +116,6 @@ err: s_spi_transaction = NULL; heap_caps_free(s_pending_transaction); s_pending_transaction = NULL; - heap_caps_free(s_rx_dma_buf); - s_rx_dma_buf = NULL; return ret; } @@ -141,11 +127,9 @@ void esp_openthread_spi_slave_deinit(void) heap_caps_free(s_spi_config); heap_caps_free(s_spi_transaction); heap_caps_free(s_pending_transaction); - heap_caps_free(s_rx_dma_buf); s_spi_config = NULL; s_spi_transaction = NULL; s_pending_transaction = NULL; - s_rx_dma_buf = NULL; return; } @@ -162,7 +146,6 @@ otError IRAM_ATTR otPlatSpiSlavePrepareTransaction(uint8_t *aOutputBuf, uint16_t uint16_t aInputBufLen, bool aRequestTransactionFlag) { esp_err_t trans_state = ESP_OK; - uint16_t trans_length = 0; if (aOutputBuf != NULL) { s_output_buf = aOutputBuf; @@ -173,11 +156,6 @@ otError IRAM_ATTR otPlatSpiSlavePrepareTransaction(uint8_t *aOutputBuf, uint16_t s_input_len = aInputBufLen; } - // Use max(input, output) so MISO is driven for the full output frame; - // s_rx_dma_buf absorbs extra RX bytes to avoid overflowing the NcpSpi buffer. - uint16_t trans_data_len = (s_input_len > s_output_len) ? s_input_len : s_output_len; - trans_length = trans_data_len * CHAR_BIT; - // In task context, return BUSY only when a transaction is already in flight // AND CS is asserted — ensures post_trans_cb will fire to re-queue. // In ISR context (post_trans_cb) we always queue unconditionally. @@ -186,8 +164,10 @@ otError IRAM_ATTR otPlatSpiSlavePrepareTransaction(uint8_t *aOutputBuf, uint16_t ESP_EARLY_LOGE(SPI_SLAVE_TAG, "SPI busy"); return OT_ERROR_BUSY; } - s_spi_transaction->length = trans_length; - s_spi_transaction->rx_buffer = s_rx_dma_buf; + s_spi_transaction->length = 0; + s_spi_transaction->tx_length = s_output_len * CHAR_BIT; + s_spi_transaction->rx_length = s_input_len * CHAR_BIT; + s_spi_transaction->rx_buffer = s_input_buf; s_spi_transaction->tx_buffer = s_output_buf; pending_transaction_t *pending_transaction = (pending_transaction_t *)s_spi_transaction->user;