fix(spi_dma_rx): fixed the invalid argument issue in full-duplex mode.

force rxlength=length and mosi=1 and inlink.start=1 on in full-duplex mode.
set rxlength > length is forbidden in full-duplex mode.

TW#12609, TW#14240, https://www.esp32.com/viewtopic.php?f=13&t=2519
This commit is contained in:
michael 2017-08-01 22:16:41 +08:00
parent 227b011f6a
commit 366e4397e9

View file

@ -514,9 +514,12 @@ static void IRAM_ATTR spi_intr(void *arg)
host->hw->dma_in_link.addr=(int)(&host->dmadesc_rx[0]) & 0xFFFFF;
host->hw->dma_in_link.start=1;
}
host->hw->user.usr_miso=1;
} else {
host->hw->user.usr_miso=0;
//DMA temporary workaround: let RX DMA work somehow to avoid the issue in ESP32 v0/v1 silicon
if (host->dma_chan != 0 ) {
host->hw->dma_in_link.addr=0;
host->hw->dma_in_link.start=1;
}
}
if (trans_buf->buffer_to_send) {
@ -540,7 +543,12 @@ static void IRAM_ATTR spi_intr(void *arg)
}
host->hw->mosi_dlen.usr_mosi_dbitlen=trans->length-1;
host->hw->miso_dlen.usr_miso_dbitlen=trans->rxlength-1;
if ( dev->cfg.flags & SPI_DEVICE_HALFDUPLEX ) {
host->hw->miso_dlen.usr_miso_dbitlen=trans->rxlength-1;
} else {
//rxlength is not used in full-duplex mode
host->hw->miso_dlen.usr_miso_dbitlen=trans->length-1;
}
host->hw->user2.usr_command_value=trans->command;
if (dev->cfg.address_bits>32) {
@ -549,7 +557,7 @@ static void IRAM_ATTR spi_intr(void *arg)
} else {
host->hw->addr=trans->address & 0xffffffff;
}
host->hw->user.usr_mosi=(trans_buf->buffer_to_send)?1:0;
host->hw->user.usr_mosi=( (!(dev->cfg.flags & SPI_DEVICE_HALFDUPLEX) && trans_buf->buffer_to_rcv) || trans_buf->buffer_to_send)?1:0;
host->hw->user.usr_miso=(trans_buf->buffer_to_rcv)?1:0;
//Call pre-transmission callback, if any
@ -571,6 +579,7 @@ esp_err_t spi_device_queue_trans(spi_device_handle_t handle, spi_transaction_t *
SPI_CHECK(!((trans_desc->flags & (SPI_TRANS_MODE_DIO|SPI_TRANS_MODE_QIO)) && (!(handle->cfg.flags & SPI_DEVICE_HALFDUPLEX))), "incompatible iface params", ESP_ERR_INVALID_ARG);
SPI_CHECK(trans_desc->length <= handle->host->max_transfer_sz*8, "txdata transfer > host maximum", ESP_ERR_INVALID_ARG);
SPI_CHECK(trans_desc->rxlength <= handle->host->max_transfer_sz*8, "rxdata transfer > host maximum", ESP_ERR_INVALID_ARG);
SPI_CHECK((handle->cfg.flags & SPI_DEVICE_HALFDUPLEX) || trans_desc->rxlength <= trans_desc->length, "rx length > tx length in full duplex mode", ESP_ERR_INVALID_ARG);
//Default rxlength to be the same as length, if not filled in.
// set rxlength to length is ok, even when rx buffer=NULL