summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Shawcroft <scott@adafruit.com>2020-09-17 11:11:56 -0700
committerGitHub <noreply@github.com>2020-09-17 11:11:56 -0700
commit9cf9441ba6b32b53d0ba8d3e287302c620b79e34 (patch)
tree648b6b6d7c13bca1c47d3b84b42ebf6c3cbd5ca3
parent78338ac12b74a46795391cb3b4f0860392036212 (diff)
parentc7c90f47b0986e0f8c4bcba574bccc2352bf700f (diff)
Merge pull request #3393 from tannewt/fix_spi_psram
Add non-DMA SPI support.
-rw-r--r--ports/esp32s2/common-hal/busio/SPI.c41
-rw-r--r--ports/esp32s2/common-hal/busio/SPI.h4
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;