]> granicus.if.org Git - esp-idf/commitdiff
spi_master: change high part config to allow transactions of 64 bytes
authormichael <xiaoxufeng@espressif.com>
Thu, 16 Aug 2018 07:44:06 +0000 (15:44 +0800)
committermichael <xiaoxufeng@espressif.com>
Thu, 16 Aug 2018 10:55:09 +0000 (18:55 +0800)
components/driver/spi_master.c
components/driver/test/test_spi_master.c
docs/en/api-reference/peripherals/spi_master.rst

index 5728bd45e9810672b21855e523d68607db9f32bf..2802dec17f4e32d098091857954b69c66ee22ae6 100644 (file)
@@ -177,7 +177,7 @@ esp_err_t spi_bus_initialize(spi_host_device_t host, const spi_bus_config_t *bus
 
     spihost[host]->dma_chan=dma_chan;
     if (dma_chan == 0) {
-        spihost[host]->max_transfer_sz = 32;
+        spihost[host]->max_transfer_sz = 64;
     } else {
         //See how many dma descriptors we need and allocate them
         int dma_desc_ct=(bus_config->max_transfer_sz+SPI_MAX_DMA_LEN-1)/SPI_MAX_DMA_LEN;
@@ -213,6 +213,10 @@ esp_err_t spi_bus_initialize(spi_host_device_t host, const spi_bus_config_t *bus
     //Reset timing
     spihost[host]->hw->ctrl2.val=0;
 
+    //master use all 64 bytes of the buffer
+    spihost[host]->hw->user.usr_miso_highpart=0;
+    spihost[host]->hw->user.usr_mosi_highpart=0;
+
     //Disable unneeded ints
     spihost[host]->hw->slave.rd_buf_done=0;
     spihost[host]->hw->slave.wr_buf_done=0;
@@ -633,7 +637,6 @@ static void SPI_MASTER_ISR_ATTR spi_intr(void *arg)
         //Fill DMA descriptors
         int extra_dummy=0;
         if (trans_buf->buffer_to_rcv) {
-            host->hw->user.usr_miso_highpart=0;
             if (host->dma_chan == 0) {
                 //No need to setup anything; we'll copy the result out of the work registers directly later.
             } else {
@@ -662,16 +665,13 @@ static void SPI_MASTER_ISR_ATTR spi_intr(void *arg)
                     //Use memcpy to get around alignment issues for txdata
                     uint32_t word;
                     memcpy(&word, &trans_buf->buffer_to_send[x/32], 4);
-                    host->hw->data_buf[(x/32)+8]=word;
+                    host->hw->data_buf[(x/32)]=word;
                 }
-                host->hw->user.usr_mosi_highpart=1;
             } else {
                 spicommon_dmaworkaround_transfer_active(host->dma_chan); //mark channel as active
                 spicommon_setup_dma_desc_links(host->dmadesc_tx, (trans->length+7)/8, (uint8_t*)trans_buf->buffer_to_send, false);
-                host->hw->user.usr_mosi_highpart=0;
                 host->hw->dma_out_link.addr=(int)(&host->dmadesc_tx[0]) & 0xFFFFF;
                 host->hw->dma_out_link.start=1;
-                host->hw->user.usr_mosi_highpart=0;
             }
         }
 
index 8887d5cefc17a2394fe2e0c3b1727adddf3e4792..8e245b526d3ace093a35dfb0c09be5f7e22d79bd 100644 (file)
@@ -234,6 +234,10 @@ TEST_CASE("SPI Master test", "[spi]")
     success &= spi_test(handle, 4); //aligned
     success &= spi_test(handle, 16); //small
     success &= spi_test(handle, 21); //small, unaligned
+    success &= spi_test(handle, 32); //small
+    success &= spi_test(handle, 47); //small, unaligned
+    success &= spi_test(handle, 63); //small
+    success &= spi_test(handle, 64); //small, unaligned
 
     destroy_spi_bus(handle);
 
@@ -693,8 +697,22 @@ TEST_CASE("SPI Master DMA test: length, start, not aligned", "[spi]")
 
 static const char MASTER_TAG[] = "test_master";
 static const char SLAVE_TAG[] = "test_slave";
-DRAM_ATTR static uint8_t master_send[] = {0x93, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0xaa, 0xcc, 0xff, 0xee, 0x55, 0x77, 0x88, 0x43};
-DRAM_ATTR static uint8_t slave_send[] = { 0xaa, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x13, 0x57, 0x9b, 0xdf, 0x24, 0x68, 0xac, 0xe0 };
+DRAM_ATTR static uint8_t master_send[] = {
+    0x93, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0xaa, 0xcc, 0xff, 0xee, 0x55, 0x77, 0x88, 0x43,
+    0x74,
+    0x93, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0xaa, 0xcc, 0xff, 0xee, 0x55, 0x77, 0x88, 0x43,
+    0x74,
+    0x93, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0xaa, 0xcc, 0xff, 0xee, 0x55, 0x77, 0x88, 0x43,
+    0x74,
+    };
+DRAM_ATTR static uint8_t slave_send[] = {
+    0xaa, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x13, 0x57, 0x9b, 0xdf, 0x24, 0x68, 0xac, 0xe0,
+    0xda,
+    0xaa, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x13, 0x57, 0x9b, 0xdf, 0x24, 0x68, 0xac, 0xe0,
+    0xda,
+    0xaa, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x13, 0x57, 0x9b, 0xdf, 0x24, 0x68, 0xac, 0xe0,
+    0xda,
+    };
 
 
 static void master_deinit(spi_device_handle_t spi)
@@ -1006,6 +1024,8 @@ esp_err_t check_data(spi_transaction_t *t, spi_dup_t dup, slave_rxdata_t *slave_
     return ESP_OK;
 }
 
+int test_len[] = {1, 3, 5, 7, 9, 11, 33, 64};
+
 static void timing_init_transactions(spi_dup_t dup, timing_context_t* context)
 {
     spi_transaction_t* trans = context->master_trans;
@@ -1014,7 +1034,7 @@ static void timing_init_transactions(spi_dup_t dup, timing_context_t* context)
         for (int i = 0; i < 8; i++ ) {
             trans[i] = (spi_transaction_t) {
                 .flags = 0,
-                .rxlength = 8*(i*2+1),
+                .rxlength = 8*test_len[i],
                 .rx_buffer = rx_buf_ptr,
             };
             rx_buf_ptr += ((context->master_trans[i].rxlength + 31)/8)&(~3);
@@ -1023,7 +1043,7 @@ static void timing_init_transactions(spi_dup_t dup, timing_context_t* context)
         for (int i = 0; i < 8; i++ ) {
             trans[i] = (spi_transaction_t) {
                 .flags = 0,
-                .length = 8*(i*2+1),
+                .length = 8*test_len[i],
                 .tx_buffer = master_send+i,
             };
         }
@@ -1031,7 +1051,7 @@ static void timing_init_transactions(spi_dup_t dup, timing_context_t* context)
         for (int i = 0; i < 8; i++ ) {
             trans[i] = (spi_transaction_t) {
                 .flags = 0,
-                .length = 8*(i*2+1),
+                .length = 8*test_len[i],
                 .tx_buffer = master_send+i,
                 .rx_buffer = rx_buf_ptr,
             };
@@ -1042,7 +1062,7 @@ static void timing_init_transactions(spi_dup_t dup, timing_context_t* context)
     for (int i = 0; i < 8; i ++) {
         context->slave_trans[i] = (slave_txdata_t) {
             .start = slave_send + 4*(i%3),
-            .len = 256,
+            .len = 512,
         };
     }
 }
@@ -1073,7 +1093,7 @@ typedef struct {
 #define ESP_SPI_SLAVE_MAX_FREQ_SYNC SPI_MASTER_FREQ_40M
 
 
-static test_timing_config_t timing_master_conf_t[] = {/**/
+static test_timing_config_t timing_master_conf_t[] = {
     { .cfg_name = "FULL_DUP, MASTER IOMUX",
       .freq_limit = SPI_MASTER_FREQ_13M,
       .dup = FULL_DUPLEX,
index 26c3933cb5566f1315ad6e86df4e4164d3e3b95e..e836c1be453be4b4e46141516811b36570a520a2 100644 (file)
@@ -217,7 +217,7 @@ speed a lot if small transactions are used.
             2.  When the DMA is enabled, it needs about 2us per transaction to setup the linked list. When the master is
                 transferring, it automatically read data from the linked list. If the DMA is not enabled,
                 CPU has to write/read each byte to/from the FIFO by itself. Usually this is faster than 2us, but the
-                transaction length is limited to 32 bytes for both write and read.
+                transaction length is limited to 64 bytes for both write and read.
 
        Typical transaction interval with one byte data is as below:
 
@@ -401,7 +401,7 @@ Known Issues
    2. disable the DMA by setting the last parameter to 0 in bus initialization function just as below:
       ``ret=spi_bus_initialize(VSPI_HOST, &buscfg, 0);``
 
-      this may prohibit you from transmitting and receiving data longer than 32 bytes.
+      this may prohibit you from transmitting and receiving data longer than 64 bytes.
    3. try to use command and address field to replace the write phase.
 
 2. Full duplex mode is not compatible with the *dummy bit workaround*, hence the frequency is limited. See :ref:`dummy