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
endmenu # ADC Configuration
-menu "SPI master configuration"
+menu "SPI configuration"
config SPI_MASTER_IN_IRAM
bool "Place transmitting functions of SPI master into 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
#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;
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 ) {
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;
}
-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);
}
-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);
}
-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;
}
#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);
//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;
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 ) {