From 074f36afff1c9fda86985bf3cbc7fbe5c92a0c6c Mon Sep 17 00:00:00 2001 From: michael Date: Fri, 15 Sep 2017 16:19:11 +0800 Subject: [PATCH 1/2] fix(spi_master): fix the heap corruption bug that RX DMA writes over the temporary buffer boundary. TW#15434 Closes #994. --- components/driver/spi_master.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/driver/spi_master.c b/components/driver/spi_master.c index dc073dc28..465f06899 100644 --- a/components/driver/spi_master.c +++ b/components/driver/spi_master.c @@ -620,8 +620,8 @@ esp_err_t spi_device_queue_trans(spi_device_handle_t handle, spi_transaction_t * trans_buf.buffer_to_rcv = trans_desc->rx_buffer; } if ( trans_buf.buffer_to_rcv && handle->host->dma_chan && (!esp_ptr_dma_capable( trans_buf.buffer_to_rcv ) || ((int)trans_buf.buffer_to_rcv%4!=0)) ) { - //if rxbuf in the desc not DMA-capable, malloc a new one - trans_buf.buffer_to_rcv = heap_caps_malloc((trans_desc->rxlength+7)/8, MALLOC_CAP_DMA); + //if rxbuf in the desc not DMA-capable, malloc a new one. The rx buffer need to be length of multiples of 32 bits to avoid heap corruption. + trans_buf.buffer_to_rcv = heap_caps_malloc((trans_desc->rxlength+31)/8, MALLOC_CAP_DMA); if ( trans_buf.buffer_to_rcv==NULL ) return ESP_ERR_NO_MEM; } From 1b91cb7be0b09d47cf06472a186057dee6981b85 Mon Sep 17 00:00:00 2001 From: michael Date: Tue, 19 Sep 2017 16:43:31 +0800 Subject: [PATCH 2/2] fix(sdspi): fix issues causing the sdspi driver to work low efficiently with DMA. --- components/driver/sdspi_host.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/components/driver/sdspi_host.c b/components/driver/sdspi_host.c index 11f702e52..57cf3f993 100644 --- a/components/driver/sdspi_host.c +++ b/components/driver/sdspi_host.c @@ -172,10 +172,11 @@ static void release_bus(int slot) /// Clock out 80 cycles (10 bytes) before GO_IDLE command static void go_idle_clockout(int slot) { - uint8_t data[10]; + //actually we need 10, declare 12 to meet requirement of RXDMA + uint8_t data[12]; memset(data, 0xff, sizeof(data)); spi_transaction_t t = { - .length = sizeof(data) * 8, + .length = 10*8, .tx_buffer = data, .rx_buffer = data, }; @@ -428,22 +429,21 @@ static esp_err_t start_command_default(int slot, int flags, sdspi_hw_cmd_t *cmd) static esp_err_t poll_busy(int slot, spi_transaction_t* t) { uint8_t t_rx; - uint8_t rd_data; *t = (spi_transaction_t) { .tx_buffer = &t_rx, - .rx_buffer = &rd_data, + .flags = SPI_TRANS_USE_RXDATA, //data stored in rx_data .length = 8, }; esp_err_t ret; for (int i = 0; i < SDSPI_RETRY_COUNT; i++) { t_rx = SDSPI_MOSI_IDLE_VAL; - rd_data = 0; + t->rx_data[0] = 0; ret = spi_device_transmit(spi_handle(slot), t); if (ret != ESP_OK) { return ret; } - if (rd_data != 0) { + if (t->rx_data[0] != 0) { if (i < SDSPI_RETRY_COUNT - 2) { i = SDSPI_RETRY_COUNT - 2; } @@ -456,28 +456,27 @@ static esp_err_t poll_busy(int slot, spi_transaction_t* t) static esp_err_t poll_response_token(int slot, spi_transaction_t* t) { uint8_t t_rx; - uint8_t rd_data; *t = (spi_transaction_t) { .tx_buffer = &t_rx, - .rx_buffer = &rd_data, + .flags = SPI_TRANS_USE_RXDATA, .length = 8, }; esp_err_t ret; for (int retry = 0; retry < SDSPI_RETRY_COUNT; retry++) { t_rx = SDSPI_MOSI_IDLE_VAL; - rd_data = 0; + t->rx_data[0] = 0; ret = spi_device_transmit(spi_handle(slot), t); if (ret != ESP_OK) { return ret; } - if ((rd_data & TOKEN_RSP_MASK) == TOKEN_RSP_OK) { + if ((t->rx_data[0] & TOKEN_RSP_MASK) == TOKEN_RSP_OK) { break; } - if ((rd_data & TOKEN_RSP_MASK) == TOKEN_RSP_CRC_ERR) { + if ((t->rx_data[0] & TOKEN_RSP_MASK) == TOKEN_RSP_CRC_ERR) { return ESP_ERR_INVALID_CRC; } - if ((rd_data & TOKEN_RSP_MASK) == TOKEN_RSP_WRITE_ERR) { + if ((t->rx_data[0] & TOKEN_RSP_MASK) == TOKEN_RSP_WRITE_ERR) { return ESP_ERR_INVALID_RESPONSE; } if (retry == SDSPI_RETRY_COUNT - 1) {