diff --git a/components/driver/spi_master.c b/components/driver/spi_master.c index 80e7d8743..5728bd45e 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 534bf8b9d..26c3933cb 100644 --- a/docs/en/api-reference/peripherals/spi_master.rst +++ b/docs/en/api-reference/peripherals/spi_master.rst @@ -407,6 +407,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 -------------------