]> granicus.if.org Git - esp-idf/commitdiff
spi_master: speed up polling performance by putting into IRAM
authorMichael (XIAO Xufeng) <xiaoxufeng@espressif.com>
Mon, 22 Oct 2018 07:25:41 +0000 (15:25 +0800)
committerMichael (XIAO Xufeng) <xiaoxufeng@espressif.com>
Thu, 25 Oct 2018 04:31:45 +0000 (12:31 +0800)
components/driver/spi_master.c
components/driver/spi_slave.c
components/driver/test/test_spi_master.c

index ffbedd203d13aad7f64b1ea4ed2ad0a18a8c7a95..95eaa60a7a4d46e762d6c0f7b6d632bc501cd2ca 100644 (file)
@@ -135,7 +135,6 @@ We have two bits to control the interrupt:
 #include "freertos/semphr.h"
 #include "freertos/xtensa_api.h"
 #include "freertos/task.h"
-#include "freertos/ringbuf.h"
 #include "soc/soc.h"
 #include "soc/soc_memory_layout.h"
 #include "soc/dport_reg.h"
@@ -709,7 +708,7 @@ static SPI_MASTER_ISR_ATTR esp_err_t device_acquire_bus_internal(spi_device_t *h
 
 /*  This function check for whether the ISR is done, if not, block until semaphore given.
  */
-static inline esp_err_t device_wait_for_isr_idle(spi_device_t *handle, TickType_t wait)
+static inline SPI_MASTER_ISR_ATTR esp_err_t device_wait_for_isr_idle(spi_device_t *handle, TickType_t wait)
 {
     //quickly skip if the isr is already free
     if (!handle->host->isr_free) {
@@ -767,7 +766,7 @@ static SPI_MASTER_ISR_ATTR void device_release_bus_internal(spi_host_t *host)
     }
 }
 
-static inline bool device_is_polling(spi_device_t *handle)
+static inline SPI_MASTER_ISR_ATTR bool device_is_polling(spi_device_t *handle)
 {
     return atomic_load(&handle->host->acquire_cs) == handle->id && handle->host->polling;
 }
@@ -1088,7 +1087,7 @@ static void SPI_MASTER_ISR_ATTR spi_intr(void *arg)
     if (do_yield) portYIELD_FROM_ISR();
 }
 
-static esp_err_t check_trans_valid(spi_device_handle_t handle, spi_transaction_t *trans_desc)
+static SPI_MASTER_ISR_ATTR esp_err_t check_trans_valid(spi_device_handle_t handle, spi_transaction_t *trans_desc)
 {
     SPI_CHECK(handle!=NULL, "invalid dev handle", ESP_ERR_INVALID_ARG);
     spi_host_t *host = handle->host;
@@ -1112,7 +1111,7 @@ static esp_err_t check_trans_valid(spi_device_handle_t handle, spi_transaction_t
     return ESP_OK;
 }
 
-static SPI_MASTER_ATTR void uninstall_priv_desc(spi_trans_priv_t* trans_buf)
+static SPI_MASTER_ISR_ATTR void uninstall_priv_desc(spi_trans_priv_t* trans_buf)
 {
     spi_transaction_t *trans_desc = trans_buf->trans;
     if ((void *)trans_buf->buffer_to_send != &trans_desc->tx_data[0] &&
@@ -1131,7 +1130,7 @@ static SPI_MASTER_ATTR void uninstall_priv_desc(spi_trans_priv_t* trans_buf)
     }
 }
 
-static SPI_MASTER_ATTR esp_err_t setup_priv_desc(spi_transaction_t *trans_desc, spi_trans_priv_t* new_desc, bool isdma)
+static SPI_MASTER_ISR_ATTR esp_err_t setup_priv_desc(spi_transaction_t *trans_desc, spi_trans_priv_t* new_desc, bool isdma)
 {
     *new_desc = (spi_trans_priv_t) { .trans = trans_desc, };
 
index 970bc6910826bb91053d8471e68e477042766611..5d3026dc6579a2960635bfdcd2c075bff1969fd3 100644 (file)
@@ -29,7 +29,6 @@
 #include "freertos/semphr.h"
 #include "freertos/xtensa_api.h"
 #include "freertos/task.h"
-#include "freertos/ringbuf.h"
 #include "soc/soc.h"
 #include "soc/soc_memory_layout.h"
 #include "soc/dport_reg.h"
index a1fd107c422697563787052f7891fdf3ba4ae7be..dc8ea63d3493894b76297fa22e4b91a5228f8651 100644 (file)
@@ -1359,9 +1359,26 @@ static void sorted_array_insert(uint32_t* array, int* size, uint32_t item)
 
 #define TEST_TIMES  11
 
-TEST_CASE("spi_speed","[spi]")
+static IRAM_ATTR void spi_transmit_measure(spi_device_handle_t spi, spi_transaction_t* trans, uint32_t* t_flight)
+{
+    RECORD_TIME_PREPARE();
+    spi_device_transmit(spi, trans); // prime the flash cache
+    RECORD_TIME_START();
+    spi_device_transmit(spi, trans);
+    RECORD_TIME_END(t_flight);
+}
+
+static IRAM_ATTR void spi_transmit_polling_measure(spi_device_handle_t spi, spi_transaction_t* trans, uint32_t* t_flight)
 {
     RECORD_TIME_PREPARE();
+    spi_device_polling_transmit(spi, trans); // prime the flash cache
+    RECORD_TIME_START();
+    spi_device_polling_transmit(spi, trans);
+    RECORD_TIME_END(t_flight);
+}
+
+TEST_CASE("spi_speed","[spi]")
+{
     uint32_t t_flight;
     //to get rid of the influence of randomly interrupts, we measured the performance by median value
     uint32_t t_flight_sorted[TEST_TIMES];
@@ -1381,16 +1398,13 @@ TEST_CASE("spi_speed","[spi]")
     //record flight time by isr, with DMA
     t_flight_num = 0;
     for (int i = 0; i < TEST_TIMES; i++) {
-        spi_device_transmit(spi, &trans); // prime the flash cache
-        RECORD_TIME_START();
-        spi_device_transmit(spi, &trans);
-        RECORD_TIME_END(&t_flight);
+        spi_transmit_measure(spi, &trans, &t_flight);
         sorted_array_insert(t_flight_sorted, &t_flight_num, t_flight);
     }
-    TEST_PERFORMANCE_LESS_THAN(SPI_PER_TRANS_NO_POLLING, "%d us", t_flight_sorted[(TEST_TIMES+1)/2]);
     for (int i = 0; i < TEST_TIMES; i++) {
         ESP_LOGI(TAG, "%d", t_flight_sorted[i]);
     }
+    TEST_PERFORMANCE_LESS_THAN(SPI_PER_TRANS_NO_POLLING, "%d us", t_flight_sorted[(TEST_TIMES+1)/2]);
 
     //acquire the bus to send polling transactions faster
     ret = spi_device_acquire_bus(spi, portMAX_DELAY);
@@ -1399,16 +1413,13 @@ TEST_CASE("spi_speed","[spi]")
     //record flight time by polling and with DMA
     t_flight_num = 0;
     for (int i = 0; i < TEST_TIMES; i++) {
-        spi_device_polling_transmit(spi, &trans); // prime the flash cache
-        RECORD_TIME_START();
-        spi_device_polling_transmit(spi, &trans);
-        RECORD_TIME_END(&t_flight);
+        spi_transmit_polling_measure(spi, &trans, &t_flight);
         sorted_array_insert(t_flight_sorted, &t_flight_num, t_flight);
     }
-    TEST_PERFORMANCE_LESS_THAN(SPI_PER_TRANS_POLLING, "%d us", t_flight_sorted[(TEST_TIMES+1)/2]);
     for (int i = 0; i < TEST_TIMES; i++) {
         ESP_LOGI(TAG, "%d", t_flight_sorted[i]);
     }
+    TEST_PERFORMANCE_LESS_THAN(SPI_PER_TRANS_POLLING, "%d us", t_flight_sorted[(TEST_TIMES+1)/2]);
 
     //release the bus
     spi_device_release_bus(spi);
@@ -1419,16 +1430,13 @@ TEST_CASE("spi_speed","[spi]")
     //record flight time by isr, without DMA
     t_flight_num = 0;
     for (int i = 0; i < TEST_TIMES; i++) {
-        spi_device_transmit(spi, &trans); // prime the flash cache
-        RECORD_TIME_START();
-        spi_device_transmit(spi, &trans);
-        RECORD_TIME_END(&t_flight);
+        spi_transmit_measure(spi, &trans, &t_flight);
         sorted_array_insert(t_flight_sorted, &t_flight_num, t_flight);
     }
-    TEST_PERFORMANCE_LESS_THAN( SPI_PER_TRANS_NO_POLLING_NO_DMA, "%d us", t_flight_sorted[(TEST_TIMES+1)/2]);
     for (int i = 0; i < TEST_TIMES; i++) {
         ESP_LOGI(TAG, "%d", t_flight_sorted[i]);
     }
+    TEST_PERFORMANCE_LESS_THAN( SPI_PER_TRANS_NO_POLLING_NO_DMA, "%d us", t_flight_sorted[(TEST_TIMES+1)/2]);
 
     //acquire the bus to send polling transactions faster
     ret = spi_device_acquire_bus(spi, portMAX_DELAY);
@@ -1436,16 +1444,13 @@ TEST_CASE("spi_speed","[spi]")
     //record flight time by polling, without DMA
     t_flight_num = 0;
     for (int i = 0; i < TEST_TIMES; i++) {
-        spi_device_polling_transmit(spi, &trans); // prime the flash cache
-        RECORD_TIME_START();
-        spi_device_polling_transmit(spi, &trans);
-        RECORD_TIME_END(&t_flight);
+        spi_transmit_polling_measure(spi, &trans, &t_flight);
         sorted_array_insert(t_flight_sorted, &t_flight_num, t_flight);
     }
-    TEST_PERFORMANCE_LESS_THAN(SPI_PER_TRANS_POLLING_NO_DMA, "%d us", t_flight_sorted[(TEST_TIMES+1)/2]);
     for (int i = 0; i < TEST_TIMES; i++) {
         ESP_LOGI(TAG, "%d", t_flight_sorted[i]);
     }
+    TEST_PERFORMANCE_LESS_THAN(SPI_PER_TRANS_POLLING_NO_DMA, "%d us", t_flight_sorted[(TEST_TIMES+1)/2]);
 
     //release the bus
     spi_device_release_bus(spi);