Merge pull request #7686 from gamblor21/esp_family_spi_speed_increase
ESP32 Family: Add multiple transctions to SPI for improved efficency
This commit is contained in:
commit
fcc4299b92
|
@ -33,6 +33,7 @@
|
|||
#include "driver/spi_common_internal.h"
|
||||
|
||||
#define SPI_MAX_DMA_BITS (SPI_MAX_DMA_LEN * 8)
|
||||
#define MAX_SPI_TRANSACTIONS 10
|
||||
|
||||
static bool spi_never_reset[SOC_SPI_PERIPH_NUM];
|
||||
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,
|
|||
.clock_speed_hz = baudrate,
|
||||
.mode = phase | (polarity << 1),
|
||||
.spics_io_num = -1, // No CS pin
|
||||
.queue_size = 1,
|
||||
.queue_size = MAX_SPI_TRANSACTIONS,
|
||||
.pre_cb = NULL
|
||||
};
|
||||
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,
|
|||
mp_raise_ValueError(translate("No MISO Pin"));
|
||||
}
|
||||
|
||||
spi_transaction_t transaction = { 0 };
|
||||
spi_transaction_t transactions[MAX_SPI_TRANSACTIONS];
|
||||
|
||||
// Round to nearest whole set of bits
|
||||
int bits_to_send = len * 8 / self->bits * self->bits;
|
||||
|
||||
if (len <= 4) {
|
||||
memset(&transactions[0], 0, sizeof(spi_transaction_t));
|
||||
if (data_out != NULL) {
|
||||
memcpy(&transaction.tx_data, data_out, len);
|
||||
memcpy(&transactions[0].tx_data, data_out, len);
|
||||
}
|
||||
|
||||
transaction.flags = SPI_TRANS_USE_TXDATA | SPI_TRANS_USE_RXDATA;
|
||||
transaction.length = bits_to_send;
|
||||
spi_device_transmit(spi_handle[self->host_id], &transaction);
|
||||
transactions[0].flags = SPI_TRANS_USE_TXDATA | SPI_TRANS_USE_RXDATA;
|
||||
transactions[0].length = bits_to_send;
|
||||
spi_device_transmit(spi_handle[self->host_id], &transactions[0]);
|
||||
|
||||
if (data_in != NULL) {
|
||||
memcpy(data_in, &transaction.rx_data, len);
|
||||
memcpy(data_in, &transactions[0].rx_data, len);
|
||||
}
|
||||
} else {
|
||||
int offset = 0;
|
||||
int bits_remaining = bits_to_send;
|
||||
int cur_trans = 0;
|
||||
|
||||
while (bits_remaining && !mp_hal_is_interrupted()) {
|
||||
memset(&transaction, 0, sizeof(transaction));
|
||||
|
||||
transaction.length =
|
||||
bits_remaining > SPI_MAX_DMA_BITS ? SPI_MAX_DMA_BITS : bits_remaining;
|
||||
cur_trans = 0;
|
||||
while (bits_remaining && (cur_trans != MAX_SPI_TRANSACTIONS)) {
|
||||
memset(&transactions[cur_trans], 0, sizeof(spi_transaction_t));
|
||||
|
||||
if (data_out != NULL) {
|
||||
transaction.tx_buffer = data_out + offset;
|
||||
}
|
||||
if (data_in != NULL) {
|
||||
transaction.rx_buffer = data_in + offset;
|
||||
transactions[cur_trans].length =
|
||||
bits_remaining > SPI_MAX_DMA_BITS ? SPI_MAX_DMA_BITS : bits_remaining;
|
||||
|
||||
if (data_out != NULL) {
|
||||
transactions[cur_trans].tx_buffer = data_out + offset;
|
||||
}
|
||||
if (data_in != NULL) {
|
||||
transactions[cur_trans].rx_buffer = data_in + offset;
|
||||
}
|
||||
|
||||
bits_remaining -= transactions[cur_trans].length;
|
||||
|
||||
// doesn't need ceil(); loop ends when bits_remaining is 0
|
||||
offset += transactions[cur_trans].length / 8;
|
||||
cur_trans++;
|
||||
}
|
||||
|
||||
spi_device_transmit(spi_handle[self->host_id], &transaction);
|
||||
bits_remaining -= transaction.length;
|
||||
for (int i = 0; i < cur_trans; i++) {
|
||||
spi_device_queue_trans(spi_handle[self->host_id], &transactions[i], portMAX_DELAY);
|
||||
}
|
||||
|
||||
// doesn't need ceil(); loop ends when bits_remaining is 0
|
||||
offset += transaction.length / 8;
|
||||
|
||||
RUN_BACKGROUND_TASKS;
|
||||
spi_transaction_t *rtrans;
|
||||
for (int x = 0; x < cur_trans; x++) {
|
||||
RUN_BACKGROUND_TASKS;
|
||||
spi_device_get_trans_result(spi_handle[self->host_id], &rtrans, portMAX_DELAY);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
Loading…
Reference in New Issue