kopia lustrzana https://github.com/espressif/esp-idf
Merge branch 'bugfix/spi_example' into 'master'
SPI: Various fixes (examples, mem leak, arg check) - Fix SPI master example to use DMA-capable memory for display initialization. Fixes https://github.com/espressif/esp-idf/issues/551 - SPI master: Do not leak DMA descriptor pointer array on free - SPI Master/Slave: Check if DMA'ed buffers actually live in DMA-capable memory See merge request !735pull/350/merge
commit
a41ac2d21d
|
@ -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
|
||||
|
|
|
@ -350,7 +350,7 @@ bool IRAM_ATTR spicommon_dmaworkaround_req_reset(int dmachan, dmaworkaround_cb_t
|
|||
int otherchan = (dmachan == 1) ? 2 : 1;
|
||||
bool ret;
|
||||
portENTER_CRITICAL(&dmaworkaround_mux);
|
||||
if (dmaworkaround_channels_busy[otherchan]) {
|
||||
if (dmaworkaround_channels_busy[otherchan-1]) {
|
||||
//Other channel is busy. Call back when it's done.
|
||||
dmaworkaround_cb = cb;
|
||||
dmaworkaround_cb_arg = arg;
|
||||
|
@ -374,7 +374,7 @@ bool IRAM_ATTR spicommon_dmaworkaround_reset_in_progress()
|
|||
void IRAM_ATTR spicommon_dmaworkaround_idle(int dmachan)
|
||||
{
|
||||
portENTER_CRITICAL(&dmaworkaround_mux);
|
||||
dmaworkaround_channels_busy[dmachan] = 0;
|
||||
dmaworkaround_channels_busy[dmachan-1] = 0;
|
||||
if (dmaworkaround_waiting_for_chan == dmachan) {
|
||||
//Reset DMA
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI_DMA_RST);
|
||||
|
@ -390,7 +390,7 @@ void IRAM_ATTR spicommon_dmaworkaround_idle(int dmachan)
|
|||
void IRAM_ATTR spicommon_dmaworkaround_transfer_active(int dmachan)
|
||||
{
|
||||
portENTER_CRITICAL(&dmaworkaround_mux);
|
||||
dmaworkaround_channels_busy[dmachan] = 1;
|
||||
dmaworkaround_channels_busy[dmachan-1] = 1;
|
||||
portEXIT_CRITICAL(&dmaworkaround_mux);
|
||||
}
|
||||
|
||||
|
|
|
@ -177,6 +177,8 @@ esp_err_t spi_bus_free(spi_host_device_t host)
|
|||
spihost[host]->hw->slave.trans_done=0;
|
||||
esp_intr_free(spihost[host]->intr);
|
||||
spicommon_periph_free(host);
|
||||
free(spihost[host]->dmadesc_tx);
|
||||
free(spihost[host]->dmadesc_rx);
|
||||
free(spihost[host]);
|
||||
spihost[host]=NULL;
|
||||
return ESP_OK;
|
||||
|
@ -573,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
|
|
@ -50,7 +50,8 @@ typedef struct {
|
|||
uint8_t databytes; //No of data in data; bit 7 = delay after set; 0xFF = end of cmds.
|
||||
} ili_init_cmd_t;
|
||||
|
||||
static const ili_init_cmd_t ili_init_cmds[]={
|
||||
//Place data into DRAM. Constant data gets placed into DROM by default, which is not accessible by DMA.
|
||||
DRAM_ATTR static const ili_init_cmd_t ili_init_cmds[]={
|
||||
{0xCF, {0x00, 0x83, 0X30}, 3},
|
||||
{0xED, {0x64, 0x03, 0X12, 0X81}, 4},
|
||||
{0xE8, {0x85, 0x01, 0x79}, 3},
|
||||
|
|
Ładowanie…
Reference in New Issue