mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'feat/spi_non_dma_64byte' into 'master'
spi_master: change high part config to allow transactions of 64 bytes See merge request idf/esp-idf!3025
This commit is contained in:
commit
9de884f586
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user