]> granicus.if.org Git - esp-idf/commitdiff
spi_slave: add new menuconfig item to decide whether spi slave should be put into...
authorMichael (XIAO Xufeng) <xiaoxufeng@espressif.com>
Mon, 20 Aug 2018 10:30:40 +0000 (18:30 +0800)
committerbot <bot@espressif.com>
Thu, 23 Aug 2018 05:21:49 +0000 (05:21 +0000)
components/driver/Kconfig
components/driver/spi_slave.c

index bff45a46bfdebed9bd75aea02b666eaeeb48b474..eaf61508d9e905ddce4341e3312b828bddb60fae 100644 (file)
@@ -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
index 7ff89e6c8af4d8ea11110580afd5840388c58a64..e563ef074353d6057af1e29c14634dab8749bb8f 100644 (file)
@@ -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 ) {