2323#include "esp_log.h"
2424#include "freertos/ringbuf.h"
2525
26+ const static char TAG [] = "test_spi" ;
2627
2728static 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}
0 commit comments