Skip to content

Commit 9a6fcab

Browse files
committed
Merge branch 'test/spi_speed_fix' into 'master'
test(spi_master): test spi master speed performance by median value. See merge request idf/esp-idf!2048
2 parents 09a30dd + 15be082 commit 9a6fcab

File tree

2 files changed

+70
-39
lines changed

2 files changed

+70
-39
lines changed

components/driver/test/test_spi_master.c

Lines changed: 69 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "esp_log.h"
2424
#include "freertos/ringbuf.h"
2525

26+
const static char TAG[] = "test_spi";
2627

2728
static void check_spi_pre_n_for(int clk, int pre, int n)
2829
{
@@ -733,12 +734,9 @@ TEST_CASE("SPI master variable cmd & addr test","[spi]")
733734
#define RECORD_TIME_START() do {__t1 = xthal_get_ccount();}while(0)
734735
#define RECORD_TIME_END(p_time) do{__t2 = xthal_get_ccount(); *p_time = (__t2-__t1)/240;}while(0)
735736

736-
TEST_CASE("spi_speed","[spi]")
737+
static void speed_setup(spi_device_handle_t* spi, bool use_dma)
737738
{
738-
RECORD_TIME_PREPARE();
739-
uint32_t t_no_dma, t_dma;
740739
esp_err_t ret;
741-
spi_device_handle_t spi;
742740
spi_bus_config_t buscfg={
743741
.miso_io_num=PIN_NUM_MISO,
744742
.mosi_io_num=PIN_NUM_MOSI,
@@ -750,54 +748,87 @@ TEST_CASE("spi_speed","[spi]")
750748
.clock_speed_hz=10*1000*1000, //currently only up to 4MHz for internel connect
751749
.mode=0, //SPI mode 0
752750
.spics_io_num=PIN_NUM_CS, //CS pin
753-
.queue_size=16, //We want to be able to queue 7 transactions at a time
751+
.queue_size=8, //We want to be able to queue 7 transactions at a time
754752
.pre_cb=NULL,
755753
.cs_ena_pretrans = 0,
756754
};
757-
//Initialize the SPI bus
758-
ret=spi_bus_initialize(HSPI_HOST, &buscfg, 1);
755+
//Initialize the SPI bus and the device to test
756+
ret=spi_bus_initialize(HSPI_HOST, &buscfg, (use_dma?1:0));
759757
TEST_ASSERT(ret==ESP_OK);
760-
//Attach the LCD to the SPI bus
761-
ret=spi_bus_add_device(HSPI_HOST, &devcfg, &spi);
758+
ret=spi_bus_add_device(HSPI_HOST, &devcfg, spi);
762759
TEST_ASSERT(ret==ESP_OK);
760+
}
763761

764-
spi_transaction_t trans = {
765-
.length = 1*8,
766-
.flags = SPI_TRANS_USE_TXDATA,
767-
};
768-
spi_device_transmit(spi, &trans);
769-
770-
//only record the second time
771-
RECORD_TIME_START();
772-
spi_device_transmit(spi, &trans);
773-
RECORD_TIME_END(&t_dma);
774-
775-
TEST_PERFORMANCE_LESS_THAN( SPI_PER_TRANS_NO_POLLING, "%d us", t_dma );
776-
762+
static void speed_deinit(spi_device_handle_t spi)
763+
{
777764
TEST_ESP_OK( spi_bus_remove_device(spi) );
778765
TEST_ESP_OK( spi_bus_free(HSPI_HOST) );
766+
}
779767

780-
ret=spi_bus_initialize(HSPI_HOST, &buscfg, 0);
781-
TEST_ASSERT(ret==ESP_OK);
782-
//Attach the LCD to the SPI bus
783-
ret=spi_bus_add_device(HSPI_HOST, &devcfg, &spi);
784-
TEST_ASSERT(ret==ESP_OK);
768+
static void sorted_array_insert(uint32_t* array, int* size, uint32_t item)
769+
{
770+
int pos;
771+
for (pos = *size; pos>0; pos--) {
772+
if (array[pos-1] < item) break;
773+
array[pos] = array[pos-1];
774+
}
775+
array[pos]=item;
776+
(*size)++;
777+
}
778+
779+
#define TEST_TIMES 11
785780

786-
trans = (spi_transaction_t){
781+
TEST_CASE("spi_speed","[spi]")
782+
{
783+
RECORD_TIME_PREPARE();
784+
uint32_t t_flight;
785+
//to get rid of the influence of randomly interrupts, we measured the performance by median value
786+
uint32_t t_flight_sorted[TEST_TIMES];
787+
int t_flight_num = 0;
788+
789+
spi_device_handle_t spi;
790+
const bool use_dma = true;
791+
WORD_ALIGNED_ATTR spi_transaction_t trans = {
787792
.length = 1*8,
788793
.flags = SPI_TRANS_USE_TXDATA,
789794
};
790-
spi_device_transmit(spi, &trans);
791-
792-
//only record the second time
793-
RECORD_TIME_START();
794-
spi_device_transmit(spi, &trans);
795-
RECORD_TIME_END(&t_no_dma);
796795

797-
TEST_PERFORMANCE_LESS_THAN( SPI_PER_TRANS_NO_POLLING_NO_DMA, "%d us", t_no_dma );
798-
799-
TEST_ESP_OK( spi_bus_remove_device(spi) );
800-
TEST_ESP_OK( spi_bus_free(HSPI_HOST) );
796+
//first work with DMA
797+
speed_setup(&spi, use_dma);
801798

799+
//first time introduces a device switch, which costs more time. we skip this
800+
spi_device_transmit(spi, &trans);
802801

802+
//record flight time by isr, with DMA
803+
t_flight_num = 0;
804+
for (int i = 0; i < TEST_TIMES; i++) {
805+
RECORD_TIME_START();
806+
spi_device_transmit(spi, &trans);
807+
RECORD_TIME_END(&t_flight);
808+
sorted_array_insert(t_flight_sorted, &t_flight_num, t_flight);
809+
}
810+
TEST_PERFORMANCE_LESS_THAN(SPI_PER_TRANS_NO_POLLING, "%d us", t_flight_sorted[(TEST_TIMES+1)/2]);
811+
for (int i = 0; i < TEST_TIMES; i++) {
812+
ESP_LOGI(TAG, "%d", t_flight_sorted[i]);
813+
}
814+
815+
speed_deinit(spi);
816+
speed_setup(&spi, !use_dma);
817+
818+
//first time introduces a device switch, which costs more time. we skip this
819+
spi_device_transmit(spi, &trans);
820+
821+
//record flight time by isr, without DMA
822+
t_flight_num = 0;
823+
for (int i = 0; i < TEST_TIMES; i++) {
824+
RECORD_TIME_START();
825+
spi_device_transmit(spi, &trans);
826+
RECORD_TIME_END(&t_flight);
827+
sorted_array_insert(t_flight_sorted, &t_flight_num, t_flight);
828+
}
829+
TEST_PERFORMANCE_LESS_THAN( SPI_PER_TRANS_NO_POLLING_NO_DMA, "%d us", t_flight_sorted[(TEST_TIMES+1)/2]);
830+
for (int i = 0; i < TEST_TIMES; i++) {
831+
ESP_LOGI(TAG, "%d", t_flight_sorted[i]);
832+
}
833+
speed_deinit(spi);
803834
}

components/idf_test/include/idf_performance.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@
1515
#define IDF_PERFORMANCE_MAX_FREERTOS_SPINLOCK_CYCLES_PER_OP_UNICORE 130
1616
#define IDF_PERFORMANCE_MAX_ESP_TIMER_GET_TIME_PER_CALL 1000
1717
#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING 30
18-
#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING_NO_DMA 25
18+
#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING_NO_DMA 27
1919

2020

0 commit comments

Comments
 (0)