Skip to content

Commit fcc4299

Browse files
authored
Merge pull request adafruit#7686 from gamblor21/esp_family_spi_speed_increase
ESP32 Family: Add multiple transctions to SPI for improved efficency
2 parents 21305e3 + ab70506 commit fcc4299

File tree

1 file changed

+36
-21
lines changed
  • ports/espressif/common-hal/busio

1 file changed

+36
-21
lines changed

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

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "driver/spi_common_internal.h"
3434

3535
#define SPI_MAX_DMA_BITS (SPI_MAX_DMA_LEN * 8)
36+
#define MAX_SPI_TRANSACTIONS 10
3637

3738
static bool spi_never_reset[SOC_SPI_PERIPH_NUM];
3839
static spi_device_handle_t spi_handle[SOC_SPI_PERIPH_NUM];
@@ -59,7 +60,7 @@ static void set_spi_config(busio_spi_obj_t *self,
5960
.clock_speed_hz = baudrate,
6061
.mode = phase | (polarity << 1),
6162
.spics_io_num = -1, // No CS pin
62-
.queue_size = 1,
63+
.queue_size = MAX_SPI_TRANSACTIONS,
6364
.pre_cb = NULL
6465
};
6566
esp_err_t result = spi_bus_add_device(self->host_id, &device_config, &spi_handle[self->host_id]);
@@ -213,47 +214,61 @@ bool common_hal_busio_spi_transfer(busio_spi_obj_t *self,
213214
mp_raise_ValueError(translate("No MISO Pin"));
214215
}
215216

216-
spi_transaction_t transaction = { 0 };
217+
spi_transaction_t transactions[MAX_SPI_TRANSACTIONS];
217218

218219
// Round to nearest whole set of bits
219220
int bits_to_send = len * 8 / self->bits * self->bits;
220221

221222
if (len <= 4) {
223+
memset(&transactions[0], 0, sizeof(spi_transaction_t));
222224
if (data_out != NULL) {
223-
memcpy(&transaction.tx_data, data_out, len);
225+
memcpy(&transactions[0].tx_data, data_out, len);
224226
}
225227

226-
transaction.flags = SPI_TRANS_USE_TXDATA | SPI_TRANS_USE_RXDATA;
227-
transaction.length = bits_to_send;
228-
spi_device_transmit(spi_handle[self->host_id], &transaction);
228+
transactions[0].flags = SPI_TRANS_USE_TXDATA | SPI_TRANS_USE_RXDATA;
229+
transactions[0].length = bits_to_send;
230+
spi_device_transmit(spi_handle[self->host_id], &transactions[0]);
229231

230232
if (data_in != NULL) {
231-
memcpy(data_in, &transaction.rx_data, len);
233+
memcpy(data_in, &transactions[0].rx_data, len);
232234
}
233235
} else {
234236
int offset = 0;
235237
int bits_remaining = bits_to_send;
238+
int cur_trans = 0;
236239

237240
while (bits_remaining && !mp_hal_is_interrupted()) {
238-
memset(&transaction, 0, sizeof(transaction));
239241

240-
transaction.length =
241-
bits_remaining > SPI_MAX_DMA_BITS ? SPI_MAX_DMA_BITS : bits_remaining;
242+
cur_trans = 0;
243+
while (bits_remaining && (cur_trans != MAX_SPI_TRANSACTIONS)) {
244+
memset(&transactions[cur_trans], 0, sizeof(spi_transaction_t));
242245

243-
if (data_out != NULL) {
244-
transaction.tx_buffer = data_out + offset;
245-
}
246-
if (data_in != NULL) {
247-
transaction.rx_buffer = data_in + offset;
248-
}
246+
transactions[cur_trans].length =
247+
bits_remaining > SPI_MAX_DMA_BITS ? SPI_MAX_DMA_BITS : bits_remaining;
249248

250-
spi_device_transmit(spi_handle[self->host_id], &transaction);
251-
bits_remaining -= transaction.length;
249+
if (data_out != NULL) {
250+
transactions[cur_trans].tx_buffer = data_out + offset;
251+
}
252+
if (data_in != NULL) {
253+
transactions[cur_trans].rx_buffer = data_in + offset;
254+
}
252255

253-
// doesn't need ceil(); loop ends when bits_remaining is 0
254-
offset += transaction.length / 8;
256+
bits_remaining -= transactions[cur_trans].length;
257+
258+
// doesn't need ceil(); loop ends when bits_remaining is 0
259+
offset += transactions[cur_trans].length / 8;
260+
cur_trans++;
261+
}
255262

256-
RUN_BACKGROUND_TASKS;
263+
for (int i = 0; i < cur_trans; i++) {
264+
spi_device_queue_trans(spi_handle[self->host_id], &transactions[i], portMAX_DELAY);
265+
}
266+
267+
spi_transaction_t *rtrans;
268+
for (int x = 0; x < cur_trans; x++) {
269+
RUN_BACKGROUND_TASKS;
270+
spi_device_get_trans_result(spi_handle[self->host_id], &rtrans, portMAX_DELAY);
271+
}
257272
}
258273
}
259274
return true;

0 commit comments

Comments
 (0)