Skip to content

Commit 9cf9441

Browse files
authored
Merge pull request #3393 from tannewt/fix_spi_psram
Add non-DMA SPI support.
2 parents 78338ac + c7c90f4 commit 9cf9441

File tree

2 files changed

+29
-16
lines changed

2 files changed

+29
-16
lines changed

ports/esp32s2/common-hal/busio/SPI.c

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,6 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
183183

184184
// spi_hal_init clears the given hal context so set everything after.
185185
spi_hal_init(hal, host_id);
186-
hal->dmadesc_tx = &self->tx_dma;
187-
hal->dmadesc_rx = &self->rx_dma;
188-
hal->dmadesc_n = 1;
189186

190187
// We don't use native CS.
191188
// hal->cs_setup = 0;
@@ -196,7 +193,6 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
196193
hal->half_duplex = 0;
197194
// hal->tx_lsbfirst = 0;
198195
// hal->rx_lsbfirst = 0;
199-
hal->dma_enabled = 1;
200196
hal->no_compensate = 1;
201197
// Ignore CS bits
202198

@@ -315,16 +311,34 @@ bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, const uint8_t *data_ou
315311
hal->rcv_buffer = NULL;
316312
// Reset timing_conf in case we've moved since the last time we used it.
317313
hal->timing_conf = &self->timing_conf;
314+
lldesc_t tx_dma __attribute__((aligned(16)));
315+
lldesc_t rx_dma __attribute__((aligned(16)));
316+
hal->dmadesc_tx = &tx_dma;
317+
hal->dmadesc_rx = &rx_dma;
318+
hal->dmadesc_n = 1;
319+
320+
size_t burst_length;
321+
// If both of the incoming pointers are DMA capable then use DMA. Otherwise, do
322+
// bursts the size of the SPI data buffer without DMA.
323+
if ((data_out == NULL || esp_ptr_dma_capable(data_out)) &&
324+
(data_in == NULL || esp_ptr_dma_capable(data_out))) {
325+
hal->dma_enabled = 1;
326+
burst_length = LLDESC_MAX_NUM_PER_DESC;
327+
} else {
328+
hal->dma_enabled = 0;
329+
burst_length = sizeof(hal->hw->data_buf);
330+
}
331+
318332
// This rounds up.
319-
size_t dma_count = (len + LLDESC_MAX_NUM_PER_DESC - 1) / LLDESC_MAX_NUM_PER_DESC;
320-
for (size_t i = 0; i < dma_count; i++) {
321-
size_t offset = LLDESC_MAX_NUM_PER_DESC * i;
322-
size_t dma_len = len - offset;
323-
if (dma_len > LLDESC_MAX_NUM_PER_DESC) {
324-
dma_len = LLDESC_MAX_NUM_PER_DESC;
333+
size_t burst_count = (len + burst_length - 1) / burst_length;
334+
for (size_t i = 0; i < burst_count; i++) {
335+
size_t offset = burst_length * i;
336+
size_t this_length = len - offset;
337+
if (this_length > burst_length) {
338+
this_length = burst_length;
325339
}
326-
hal->tx_bitlen = dma_len * self->bits;
327-
hal->rx_bitlen = dma_len * self->bits;
340+
hal->tx_bitlen = this_length * self->bits;
341+
hal->rx_bitlen = this_length * self->bits;
328342
if (data_out != NULL) {
329343
hal->send_buffer = (uint8_t*) data_out + offset;
330344
}
@@ -341,6 +355,9 @@ bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, const uint8_t *data_ou
341355
}
342356
spi_hal_fetch_result(hal);
343357
}
358+
hal->dmadesc_tx = NULL;
359+
hal->dmadesc_rx = NULL;
360+
hal->dmadesc_n = 0;
344361

345362
return true;
346363
}

ports/esp32s2/common-hal/busio/SPI.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,6 @@ typedef struct {
4444
spi_hal_context_t hal_context;
4545
spi_hal_timing_conf_t timing_conf;
4646
intr_handle_t interrupt;
47-
// IDF allocates these in DMA accessible memory so they may need to move when
48-
// we use external RAM for CircuitPython.
49-
lldesc_t tx_dma;
50-
lldesc_t rx_dma;
5147
uint32_t target_frequency;
5248
int32_t real_frequency;
5349
uint8_t polarity;

0 commit comments

Comments
 (0)