esp_err_t spi_device_queue_trans(spi_device_handle_t handle, spi_transaction_t *trans_desc, TickType_t ticks_to_wait)
{
+ esp_err_t ret = ESP_OK;
BaseType_t r;
SPI_CHECK(handle!=NULL, "invalid dev handle", ESP_ERR_INVALID_ARG);
//check transmission length
//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.
ESP_LOGV( SPI_TAG, "Allocate RX buffer for DMA" );
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;
+ if ( trans_buf.buffer_to_rcv==NULL ) {
+ ret = ESP_ERR_NO_MEM;
+ goto clean_up;
+ }
}
const uint32_t *txdata;
ESP_LOGV( SPI_TAG, "Allocate TX buffer for DMA" );
trans_buf.buffer_to_send = heap_caps_malloc((trans_desc->length+7)/8, MALLOC_CAP_DMA);
if ( trans_buf.buffer_to_send==NULL ) {
- // free malloc-ed buffer (if needed) before return.
- if ( (void*)trans_buf.buffer_to_rcv != trans_desc->rx_buffer && (void*)trans_buf.buffer_to_rcv != &trans_desc->rx_data[0] ) {
- free( trans_buf.buffer_to_rcv );
- }
- return ESP_ERR_NO_MEM;
+ ret = ESP_ERR_NO_MEM;
+ goto clean_up;
}
memcpy( trans_buf.buffer_to_send, txdata, (trans_desc->length+7)/8 );
} else {
// else use the original buffer (forced-conversion) or assign to NULL
trans_buf.buffer_to_send = (uint32_t*)txdata;
}
+
#ifdef CONFIG_PM_ENABLE
esp_pm_lock_acquire(handle->host->pm_lock);
#endif
-
r=xQueueSend(handle->trans_queue, (void*)&trans_buf, ticks_to_wait);
- if (!r) return ESP_ERR_TIMEOUT;
+ if (!r) {
+ ret = ESP_ERR_TIMEOUT;
+#ifdef CONFIG_PM_ENABLE
+ //Release APB frequency lock
+ esp_pm_lock_release(handle->host->pm_lock);
+#endif
+ goto clean_up;
+ }
esp_intr_enable(handle->host->intr);
return ESP_OK;
+
+clean_up:
+ // free malloc-ed buffer (if needed) before return.
+ if ( (void*)trans_buf.buffer_to_rcv != trans_desc->rx_buffer && (void*)trans_buf.buffer_to_rcv != &trans_desc->rx_data[0] ) {
+ free( trans_buf.buffer_to_rcv );
+ }
+ if ( (void*)trans_buf.buffer_to_send!= trans_desc->tx_buffer && (void*)trans_buf.buffer_to_send != &trans_desc->tx_data[0] ) {
+ free( trans_buf.buffer_to_send );
+ }
+ assert( ret != ESP_OK );
+ return ret;
}
esp_err_t spi_device_get_trans_result(spi_device_handle_t handle, spi_transaction_t **trans_desc, TickType_t ticks_to_wait)