mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'fix/spi_dma_config_in_iram' into 'master'
SPI: put dma config and slave functions into IRAM See merge request idf/esp-idf!3038
This commit is contained in:
commit
7abed5fc9e
@ -6,8 +6,8 @@ config ADC_FORCE_XPD_FSM
|
||||
bool "Use the FSM to control ADC power"
|
||||
default n
|
||||
help
|
||||
ADC power can be controlled by the FSM instead of software. This allows the ADC to
|
||||
be shut off when it is not working leading to lower power consumption. However
|
||||
ADC power can be controlled by the FSM instead of software. This allows the ADC to
|
||||
be shut off when it is not working leading to lower power consumption. However
|
||||
using the FSM control ADC power will increase the noise of ADC.
|
||||
|
||||
config ADC2_DISABLE_DAC
|
||||
@ -20,7 +20,7 @@ config ADC2_DISABLE_DAC
|
||||
|
||||
endmenu # ADC Configuration
|
||||
|
||||
menu "SPI master configuration"
|
||||
menu "SPI configuration"
|
||||
|
||||
config SPI_MASTER_IN_IRAM
|
||||
bool "Place transmitting functions of SPI master into IRAM"
|
||||
@ -44,6 +44,26 @@ config SPI_MASTER_ISR_IN_IRAM
|
||||
Place the SPI master ISR in to IRAM to avoid possibly cache miss, or
|
||||
being disabled during flash writing access.
|
||||
|
||||
endmenu # SPI Master Configuration
|
||||
config SPI_SLAVE_IN_IRAM
|
||||
bool "Place transmitting functions of SPI slave into IRAM"
|
||||
default n
|
||||
select SPI_SLAVE_ISR_IN_IRAM
|
||||
help
|
||||
Normally only the ISR of SPI slave is placed in the IRAM, so that it
|
||||
can work without the flash when interrupt is triggered.
|
||||
For other functions, there's some possibility that the flash cache
|
||||
miss when running inside and out of SPI functions, which may increase
|
||||
the interval of SPI transactions.
|
||||
Enable this to put ``queue_trans``, ``get_trans_result`` and
|
||||
``transmit`` functions into the IRAM to avoid possible cache miss.
|
||||
|
||||
config SPI_SLAVE_ISR_IN_IRAM
|
||||
bool "Place SPI slave ISR function into IRAM"
|
||||
default y
|
||||
help
|
||||
Place the SPI slave ISR in to IRAM to avoid possibly cache miss, or
|
||||
being disabled during flash writing access.
|
||||
|
||||
endmenu # SPI Configuration
|
||||
|
||||
endmenu # Driver configurations
|
||||
|
@ -330,7 +330,7 @@ void spicommon_cs_free_io(int cs_gpio_num)
|
||||
}
|
||||
|
||||
//Set up a list of dma descriptors. dmadesc is an array of descriptors. Data is the buffer to point to.
|
||||
void spicommon_setup_dma_desc_links(lldesc_t *dmadesc, int len, const uint8_t *data, bool isrx)
|
||||
void IRAM_ATTR spicommon_setup_dma_desc_links(lldesc_t *dmadesc, int len, const uint8_t *data, bool isrx)
|
||||
{
|
||||
int n = 0;
|
||||
while (len) {
|
||||
|
@ -47,6 +47,18 @@ static const char *SPI_TAG = "spi_slave";
|
||||
|
||||
#define VALID_HOST(x) (x>SPI_HOST && x<=VSPI_HOST)
|
||||
|
||||
#ifdef CONFIG_SPI_SLAVE_ISR_IN_IRAM
|
||||
#define SPI_SLAVE_ISR_ATTR IRAM_ATTR
|
||||
#else
|
||||
#define SPI_SLAVE_ISR_ATTR
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SPI_SLAVE_IN_IRAM
|
||||
#define SPI_SLAVE_ATTR IRAM_ATTR
|
||||
#else
|
||||
#define SPI_SLAVE_ATTR
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
spi_slave_interface_config_t cfg;
|
||||
intr_handle_t intr;
|
||||
@ -79,7 +91,7 @@ esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *b
|
||||
|
||||
spi_chan_claimed=spicommon_periph_claim(host);
|
||||
SPI_CHECK(spi_chan_claimed, "host already in use", ESP_ERR_INVALID_STATE);
|
||||
|
||||
|
||||
if ( dma_chan != 0 ) {
|
||||
dma_chan_claimed=spicommon_dma_chan_claim(dma_chan);
|
||||
if ( !dma_chan_claimed ) {
|
||||
@ -138,7 +150,11 @@ esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *b
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
err = esp_intr_alloc(spicommon_irqsource_for_host(host), ESP_INTR_FLAG_INTRDISABLED, spi_intr, (void *)spihost[host], &spihost[host]->intr);
|
||||
int flags = ESP_INTR_FLAG_INTRDISABLED;
|
||||
#ifdef CONFIG_SPI_SLAVE_ISR_IN_IRAM
|
||||
flags |= ESP_INTR_FLAG_IRAM;
|
||||
#endif
|
||||
err = esp_intr_alloc(spicommon_irqsource_for_host(host), flags, spi_intr, (void *)spihost[host], &spihost[host]->intr);
|
||||
if (err != ESP_OK) {
|
||||
ret = err;
|
||||
goto cleanup;
|
||||
@ -250,14 +266,14 @@ esp_err_t spi_slave_free(spi_host_device_t host)
|
||||
}
|
||||
|
||||
|
||||
esp_err_t spi_slave_queue_trans(spi_host_device_t host, const spi_slave_transaction_t *trans_desc, TickType_t ticks_to_wait)
|
||||
esp_err_t SPI_SLAVE_ATTR spi_slave_queue_trans(spi_host_device_t host, const spi_slave_transaction_t *trans_desc, TickType_t ticks_to_wait)
|
||||
{
|
||||
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),
|
||||
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),
|
||||
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);
|
||||
@ -268,7 +284,7 @@ esp_err_t spi_slave_queue_trans(spi_host_device_t host, const spi_slave_transact
|
||||
}
|
||||
|
||||
|
||||
esp_err_t spi_slave_get_trans_result(spi_host_device_t host, spi_slave_transaction_t **trans_desc, TickType_t ticks_to_wait)
|
||||
esp_err_t SPI_SLAVE_ATTR spi_slave_get_trans_result(spi_host_device_t host, spi_slave_transaction_t **trans_desc, TickType_t ticks_to_wait)
|
||||
{
|
||||
BaseType_t r;
|
||||
SPI_CHECK(VALID_HOST(host), "invalid host", ESP_ERR_INVALID_ARG);
|
||||
@ -279,7 +295,7 @@ esp_err_t spi_slave_get_trans_result(spi_host_device_t host, spi_slave_transacti
|
||||
}
|
||||
|
||||
|
||||
esp_err_t spi_slave_transmit(spi_host_device_t host, spi_slave_transaction_t *trans_desc, TickType_t ticks_to_wait)
|
||||
esp_err_t SPI_SLAVE_ATTR spi_slave_transmit(spi_host_device_t host, spi_slave_transaction_t *trans_desc, TickType_t ticks_to_wait)
|
||||
{
|
||||
esp_err_t ret;
|
||||
spi_slave_transaction_t *ret_trans;
|
||||
@ -316,7 +332,7 @@ static void dumpll(lldesc_t *ll)
|
||||
}
|
||||
#endif
|
||||
|
||||
static void IRAM_ATTR spi_slave_restart_after_dmareset(void *arg)
|
||||
static void SPI_SLAVE_ISR_ATTR spi_slave_restart_after_dmareset(void *arg)
|
||||
{
|
||||
spi_slave_t *host = (spi_slave_t *)arg;
|
||||
esp_intr_enable(host->intr);
|
||||
@ -325,7 +341,7 @@ static void IRAM_ATTR spi_slave_restart_after_dmareset(void *arg)
|
||||
//This is run in interrupt context and apart from initialization and destruction, this is the only code
|
||||
//touching the host (=spihost[x]) variable. The rest of the data arrives in queues. That is why there are
|
||||
//no muxes in this code.
|
||||
static void IRAM_ATTR spi_intr(void *arg)
|
||||
static void SPI_SLAVE_ISR_ATTR spi_intr(void *arg)
|
||||
{
|
||||
BaseType_t r;
|
||||
BaseType_t do_yield = pdFALSE;
|
||||
@ -342,7 +358,7 @@ static void IRAM_ATTR spi_intr(void *arg)
|
||||
|
||||
if (host->cur_trans) {
|
||||
//when data of cur_trans->length are all sent, the slv_rdata_bit
|
||||
//will be the length sent-1 (i.e. cur_trans->length-1 ), otherwise
|
||||
//will be the length sent-1 (i.e. cur_trans->length-1 ), otherwise
|
||||
//the length sent.
|
||||
host->cur_trans->trans_len = host->hw->slv_rd_bit.slv_rdata_bit;
|
||||
if ( host->cur_trans->trans_len == host->cur_trans->length - 1 ) {
|
||||
|
Loading…
Reference in New Issue
Block a user