Warn against and check for non-DMA-capable pointers being passed to SPI when DMA is used
This commit is contained in:
parent
530c3ca05c
commit
8af3fe4e84
5 changed files with 29 additions and 0 deletions
|
@ -100,6 +100,10 @@ typedef struct spi_device_t* spi_device_handle_t; ///< Handle for a device on a
|
|||
* for a SPI bus allows transfers on the bus to have sizes only limited by the amount of
|
||||
* internal memory. Selecting no DMA channel (by passing the value 0) limits the amount of
|
||||
* bytes transfered to a maximum of 32.
|
||||
*
|
||||
* @warning If a DMA channel is selected, any transmit and receive buffer used should be allocated in
|
||||
* DMA-capable memory.
|
||||
*
|
||||
* @return
|
||||
* - ESP_ERR_INVALID_ARG if configuration is invalid
|
||||
* - ESP_ERR_INVALID_STATE if host already is in use
|
||||
|
|
|
@ -69,6 +69,10 @@ struct spi_slave_transaction_t {
|
|||
* @param dma_chan Either 1 or 2. A SPI bus used by this driver must have a DMA channel associated with
|
||||
* it. The SPI hardware has two DMA channels to share. This parameter indicates which
|
||||
* one to use.
|
||||
*
|
||||
* @warning If a DMA channel is selected, any transmit and receive buffer used should be allocated in
|
||||
* DMA-capable memory.
|
||||
*
|
||||
* @return
|
||||
* - ESP_ERR_INVALID_ARG if configuration is invalid
|
||||
* - ESP_ERR_INVALID_STATE if host already is in use
|
||||
|
|
|
@ -575,6 +575,10 @@ esp_err_t spi_device_queue_trans(spi_device_handle_t handle, spi_transaction_t *
|
|||
SPI_CHECK(!((trans_desc->flags & (SPI_TRANS_MODE_DIO|SPI_TRANS_MODE_QIO)) && (!(handle->cfg.flags & SPI_DEVICE_HALFDUPLEX))), "incompatible iface params", ESP_ERR_INVALID_ARG);
|
||||
SPI_CHECK(trans_desc->length <= handle->host->max_transfer_sz*8, "txdata transfer > host maximum", ESP_ERR_INVALID_ARG);
|
||||
SPI_CHECK(trans_desc->rxlength <= handle->host->max_transfer_sz*8, "rxdata transfer > host maximum", ESP_ERR_INVALID_ARG);
|
||||
SPI_CHECK(handle->host->dma_chan == 0 || (trans_desc->flags & SPI_TRANS_USE_TXDATA) ||
|
||||
trans_desc->tx_buffer==NULL || esp_ptr_dma_capable(trans_desc->tx_buffer), "txdata not in DMA-capable memory", ESP_ERR_INVALID_ARG);
|
||||
SPI_CHECK(handle->host->dma_chan == 0 || (trans_desc->flags & SPI_TRANS_USE_RXDATA) ||
|
||||
trans_desc->rx_buffer==NULL || esp_ptr_dma_capable(trans_desc->rx_buffer), "rxdata not in DMA-capable memory", ESP_ERR_INVALID_ARG);
|
||||
r=xQueueSend(handle->trans_queue, (void*)&trans_desc, ticks_to_wait);
|
||||
if (!r) return ESP_ERR_TIMEOUT;
|
||||
esp_intr_enable(handle->host->intr);
|
||||
|
|
|
@ -202,6 +202,10 @@ esp_err_t spi_slave_queue_trans(spi_host_device_t host, const spi_slave_transact
|
|||
BaseType_t r;
|
||||
SPI_CHECK(VALID_HOST(host), "invalid host", ESP_ERR_INVALID_ARG);
|
||||
SPI_CHECK(spihost[host], "host not slave", ESP_ERR_INVALID_ARG);
|
||||
SPI_CHECK(spihost[host]->dma_chan == 0 || trans_desc->tx_buffer==NULL || esp_ptr_dma_capable(trans_desc->tx_buffer),
|
||||
"txdata not in DMA-capable memory", ESP_ERR_INVALID_ARG);
|
||||
SPI_CHECK(spihost[host]->dma_chan == 0 || trans_desc->rx_buffer==NULL || esp_ptr_dma_capable(trans_desc->rx_buffer),
|
||||
"rxdata not in DMA-capable memory", ESP_ERR_INVALID_ARG);
|
||||
|
||||
SPI_CHECK(trans_desc->length <= spihost[host]->max_transfer_sz * 8, "data transfer > host maximum", ESP_ERR_INVALID_ARG);
|
||||
r = xQueueSend(spihost[host]->trans_queue, (void *)&trans_desc, ticks_to_wait);
|
||||
|
|
|
@ -87,4 +87,17 @@ size_t xPortGetMinimumEverFreeHeapSizeCaps( uint32_t caps );
|
|||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Convenience function to check if a pointer is DMA-capable.
|
||||
*
|
||||
* @param ptr Pointer to check
|
||||
*
|
||||
* @return True if DMA-capable, false if not.
|
||||
*/
|
||||
static inline bool esp_ptr_dma_capable( const void *ptr )
|
||||
{
|
||||
return ( (int)ptr >= 0x3FFAE000 && (int)ptr < 0x40000000 );
|
||||
}
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue