@@ -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}
0 commit comments