diff options
| author | Scott Shawcroft <scott@adafruit.com> | 2020-09-17 11:11:56 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-09-17 11:11:56 -0700 |
| commit | 9cf9441ba6b32b53d0ba8d3e287302c620b79e34 (patch) | |
| tree | 648b6b6d7c13bca1c47d3b84b42ebf6c3cbd5ca3 | |
| parent | 78338ac12b74a46795391cb3b4f0860392036212 (diff) | |
| parent | c7c90f47b0986e0f8c4bcba574bccc2352bf700f (diff) | |
Merge pull request #3393 from tannewt/fix_spi_psram
Add non-DMA SPI support.
| -rw-r--r-- | ports/esp32s2/common-hal/busio/SPI.c | 41 | ||||
| -rw-r--r-- | ports/esp32s2/common-hal/busio/SPI.h | 4 |
2 files changed, 29 insertions, 16 deletions
diff --git a/ports/esp32s2/common-hal/busio/SPI.c b/ports/esp32s2/common-hal/busio/SPI.c index a22075cd5..350580ea8 100644 --- a/ports/esp32s2/common-hal/busio/SPI.c +++ b/ports/esp32s2/common-hal/busio/SPI.c @@ -183,9 +183,6 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, // spi_hal_init clears the given hal context so set everything after. spi_hal_init(hal, host_id); - hal->dmadesc_tx = &self->tx_dma; - hal->dmadesc_rx = &self->rx_dma; - hal->dmadesc_n = 1; // We don't use native CS. // hal->cs_setup = 0; @@ -196,7 +193,6 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, hal->half_duplex = 0; // hal->tx_lsbfirst = 0; // hal->rx_lsbfirst = 0; - hal->dma_enabled = 1; hal->no_compensate = 1; // Ignore CS bits @@ -315,16 +311,34 @@ bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, const uint8_t *data_ou hal->rcv_buffer = NULL; // Reset timing_conf in case we've moved since the last time we used it. hal->timing_conf = &self->timing_conf; + lldesc_t tx_dma __attribute__((aligned(16))); + lldesc_t rx_dma __attribute__((aligned(16))); + hal->dmadesc_tx = &tx_dma; + hal->dmadesc_rx = &rx_dma; + hal->dmadesc_n = 1; + + size_t burst_length; + // If both of the incoming pointers are DMA capable then use DMA. Otherwise, do + // bursts the size of the SPI data buffer without DMA. + if ((data_out == NULL || esp_ptr_dma_capable(data_out)) && + (data_in == NULL || esp_ptr_dma_capable(data_out))) { + hal->dma_enabled = 1; + burst_length = LLDESC_MAX_NUM_PER_DESC; + } else { + hal->dma_enabled = 0; + burst_length = sizeof(hal->hw->data_buf); + } + // This rounds up. - size_t dma_count = (len + LLDESC_MAX_NUM_PER_DESC - 1) / LLDESC_MAX_NUM_PER_DESC; - for (size_t i = 0; i < dma_count; i++) { - size_t offset = LLDESC_MAX_NUM_PER_DESC * i; - size_t dma_len = len - offset; - if (dma_len > LLDESC_MAX_NUM_PER_DESC) { - dma_len = LLDESC_MAX_NUM_PER_DESC; + size_t burst_count = (len + burst_length - 1) / burst_length; + for (size_t i = 0; i < burst_count; i++) { + size_t offset = burst_length * i; + size_t this_length = len - offset; + if (this_length > burst_length) { + this_length = burst_length; } - hal->tx_bitlen = dma_len * self->bits; - hal->rx_bitlen = dma_len * self->bits; + hal->tx_bitlen = this_length * self->bits; + hal->rx_bitlen = this_length * self->bits; if (data_out != NULL) { hal->send_buffer = (uint8_t*) data_out + offset; } @@ -341,6 +355,9 @@ bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, const uint8_t *data_ou } spi_hal_fetch_result(hal); } + hal->dmadesc_tx = NULL; + hal->dmadesc_rx = NULL; + hal->dmadesc_n = 0; return true; } diff --git a/ports/esp32s2/common-hal/busio/SPI.h b/ports/esp32s2/common-hal/busio/SPI.h index 6d8203831..38fbe42ff 100644 --- a/ports/esp32s2/common-hal/busio/SPI.h +++ b/ports/esp32s2/common-hal/busio/SPI.h @@ -44,10 +44,6 @@ typedef struct { spi_hal_context_t hal_context; spi_hal_timing_conf_t timing_conf; intr_handle_t interrupt; - // IDF allocates these in DMA accessible memory so they may need to move when - // we use external RAM for CircuitPython. - lldesc_t tx_dma; - lldesc_t rx_dma; uint32_t target_frequency; int32_t real_frequency; uint8_t polarity; |
