From 8676830e61985e61286c494de957c57bdf610b9e Mon Sep 17 00:00:00 2001 From: michael Date: Tue, 19 Jun 2018 20:38:17 +0800 Subject: [PATCH] fix(spi_master): allow to use cs_ena_pretrans in full duplex mode without command and address phases --- components/driver/spi_master.c | 28 ++++++++++++------- .../api-reference/peripherals/spi_master.rst | 2 ++ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/components/driver/spi_master.c b/components/driver/spi_master.c index 4641e4bca..49b14b2a2 100644 --- a/components/driver/spi_master.c +++ b/components/driver/spi_master.c @@ -333,8 +333,7 @@ esp_err_t spi_bus_add_device(spi_host_device_t host, const spi_device_interface_ SPI_CHECK(freecs!=NO_CS, "no free cs pins for host", ESP_ERR_NOT_FOUND); //The hardware looks like it would support this, but actually setting cs_ena_pretrans when transferring in full //duplex mode does absolutely nothing on the ESP32. - SPI_CHECK(dev_config->cs_ena_pretrans <= 1 || (dev_config->flags & SPI_DEVICE_HALFDUPLEX), "cs pretrans delay > 1 incompatible with full-duplex", ESP_ERR_INVALID_ARG); - SPI_CHECK( dev_config->cs_ena_pretrans != 1 || (dev_config->address_bits == 0 && dev_config->command_bits == 0) || + SPI_CHECK( dev_config->cs_ena_pretrans <= 1 || (dev_config->address_bits == 0 && dev_config->command_bits == 0) || (dev_config->flags & SPI_DEVICE_HALFDUPLEX), "In full-duplex mode, only support cs pretrans delay = 1 and without address_bits and command_bits", ESP_ERR_INVALID_ARG); duty_cycle = (dev_config->duty_cycle_pos==0? 128: dev_config->duty_cycle_pos); @@ -711,17 +710,26 @@ static void SPI_MASTER_ISR_ATTR spi_intr(void *arg) //Configure bit sizes, load addr and command int cmdlen; - if ( trans->flags & SPI_TRANS_VARIABLE_CMD ) { - cmdlen = ((spi_transaction_ext_t*)trans)->command_bits; - } else { - cmdlen = dev->cfg.command_bits; - } int addrlen; - if ( trans->flags & SPI_TRANS_VARIABLE_ADDR ) { - addrlen = ((spi_transaction_ext_t*)trans)->address_bits; + if (!(dev->cfg.flags & SPI_DEVICE_HALFDUPLEX) && dev->cfg.cs_ena_pretrans != 0) { + /* The command and address phase is not compatible with cs_ena_pretrans + * in full duplex mode. + */ + cmdlen = 0; + addrlen = 0; } else { - addrlen = dev->cfg.address_bits; + if (trans->flags & SPI_TRANS_VARIABLE_CMD) { + cmdlen = ((spi_transaction_ext_t *)trans)->command_bits; + } else { + cmdlen = dev->cfg.command_bits; + } + if (trans->flags & SPI_TRANS_VARIABLE_ADDR) { + addrlen = ((spi_transaction_ext_t *)trans)->address_bits; + } else { + addrlen = dev->cfg.address_bits; + } } + host->hw->user1.usr_addr_bitlen=addrlen-1; host->hw->user2.usr_command_bitlen=cmdlen-1; host->hw->user.usr_addr=addrlen?1:0; diff --git a/docs/en/api-reference/peripherals/spi_master.rst b/docs/en/api-reference/peripherals/spi_master.rst index 3a526fbd5..bb09472ec 100644 --- a/docs/en/api-reference/peripherals/spi_master.rst +++ b/docs/en/api-reference/peripherals/spi_master.rst @@ -384,6 +384,8 @@ Known Issues 2. Full duplex mode is not compatible with the *dummy bit workaround*, hence the frequency is limited. See :ref:`dummy bit speed-up workaround `. +3. ``cs_ena_pretrans`` is not compatible with command, address phases in full duplex mode. + Application Example -------------------