Skip to content

Commit

Permalink
Merge branch 'bugfix/add_len_check_per_spi_master_transaction_v4.4' i…
Browse files Browse the repository at this point in the history
…nto 'release/v4.4'

spi master: added transaction length check to refuse longer than hardware supported length (v4.4)

See merge request espressif/esp-idf!23749
  • Loading branch information
suda-morris committed Jun 12, 2023
2 parents ad08d94 + 61ecbb4 commit d9d5327
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 7 deletions.
12 changes: 12 additions & 0 deletions components/driver/include/driver/spi_master.h
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,18 @@ void spi_get_timing(bool gpio_is_used, int input_delay_ns, int eff_clk, int *dum
*/
int spi_get_freq_limit(bool gpio_is_used, int input_delay_ns);

/**
* @brief Get max length (in bytes) of one transaction
*
* @param host_id SPI peripheral
* @param[out] max_bytes Max length of one transaction, in bytes
*
* @return
* - ESP_OK: On success
* - ESP_ERR_INVALID_ARG: Invalid argument
*/
esp_err_t spi_bus_get_max_transaction_len(spi_host_device_t host_id, size_t *max_bytes);

#ifdef __cplusplus
}
#endif
27 changes: 27 additions & 0 deletions components/driver/spi_master.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ We have two bits to control the interrupt:
*/

#include <string.h>
#include <sys/param.h>
#include "driver/spi_common_internal.h"
#include "driver/spi_master.h"

Expand All @@ -120,6 +121,7 @@ We have two bits to control the interrupt:
#include "soc/soc_memory_layout.h"
#include "driver/gpio.h"
#include "hal/spi_hal.h"
#include "hal/spi_ll.h"
#include "esp_heap_caps.h"


Expand Down Expand Up @@ -720,6 +722,14 @@ static SPI_MASTER_ISR_ATTR esp_err_t check_trans_valid(spi_device_handle_t handl
//Dummy phase is not available when both data out and in are enabled, regardless of FD or HD mode.
SPI_CHECK(!tx_enabled || !rx_enabled || !dummy_enabled || !extra_dummy_enabled, "Dummy phase is not available when both data out and in are enabled", ESP_ERR_INVALID_ARG);

if (bus_attr->dma_enabled) {
SPI_CHECK(trans_desc->length <= SPI_LL_DMA_MAX_BIT_LEN, "txdata transfer > hardware max supported len", ESP_ERR_INVALID_ARG);
SPI_CHECK(trans_desc->rxlength <= SPI_LL_DMA_MAX_BIT_LEN, "rxdata transfer > hardware max supported len", ESP_ERR_INVALID_ARG);
} else {
SPI_CHECK(trans_desc->length <= SPI_LL_CPU_MAX_BIT_LEN, "txdata transfer > hardware max supported len", ESP_ERR_INVALID_ARG);
SPI_CHECK(trans_desc->rxlength <= SPI_LL_CPU_MAX_BIT_LEN, "rxdata transfer > hardware max supported len", ESP_ERR_INVALID_ARG);
}

return ESP_OK;
}

Expand Down Expand Up @@ -1013,3 +1023,20 @@ esp_err_t SPI_MASTER_ISR_ATTR spi_device_polling_transmit(spi_device_handle_t ha

return spi_device_polling_end(handle, portMAX_DELAY);
}

esp_err_t spi_bus_get_max_transaction_len(spi_host_device_t host_id, size_t *max_bytes)
{
SPI_CHECK(is_valid_host(host_id), "invalid host", ESP_ERR_INVALID_ARG);
if (bus_driver_ctx[host_id] == NULL || max_bytes == NULL) {
return ESP_ERR_INVALID_ARG;
}

spi_host_t *host = bus_driver_ctx[host_id];
if (host->bus_attr->dma_enabled) {
*max_bytes = MIN(host->bus_attr->max_transfer_sz, (SPI_LL_DMA_MAX_BIT_LEN / 8));
} else {
*max_bytes = MIN(host->bus_attr->max_transfer_sz, (SPI_LL_CPU_MAX_BIT_LEN / 8));
}

return ESP_OK;
}
8 changes: 6 additions & 2 deletions components/esp_lcd/src/esp_lcd_panel_io_spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,13 @@ esp_err_t esp_lcd_new_panel_io_spi(esp_lcd_spi_bus_handle_t bus, const esp_lcd_p
spi_panel_io->base.tx_color = panel_io_spi_tx_color;
spi_panel_io->base.del = panel_io_spi_del;
spi_panel_io->base.register_event_callbacks = panel_io_spi_register_event_callbacks;
spi_panel_io->spi_trans_max_bytes = spi_bus_get_attr((spi_host_device_t)bus)->max_transfer_sz;

size_t max_trans_bytes = 0;
ESP_GOTO_ON_ERROR(spi_bus_get_max_transaction_len((spi_host_device_t)bus, &max_trans_bytes), err, TAG, "get spi max transaction len failed");
spi_panel_io->spi_trans_max_bytes = max_trans_bytes;

*ret_io = &(spi_panel_io->base);
ESP_LOGD(TAG, "new spi lcd panel io @%p", spi_panel_io);
ESP_LOGD(TAG, "new spi lcd panel io @%p, max_trans_bytes: %d", spi_panel_io, (int)max_trans_bytes);

return ESP_OK;

Expand Down
3 changes: 2 additions & 1 deletion components/hal/esp32/include/hal/spi_ll.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ extern "C" {
#define SPI_LL_PERIPH_CLK_FREQ (80 * 1000000)
#define SPI_LL_GET_HW(ID) ((ID)==0? &SPI1:((ID)==1? &SPI2 : &SPI3))

#define SPI_LL_DATA_MAX_BIT_LEN (1 << 24)
#define SPI_LL_DMA_MAX_BIT_LEN (1 << 24) //reg len: 24 bits
#define SPI_LL_CPU_MAX_BIT_LEN (16 * 32) //Fifo len: 16 words

/**
* The data structure holding calculated clock configuration. Since the
Expand Down
3 changes: 2 additions & 1 deletion components/hal/esp32c3/include/hal/spi_ll.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ extern "C" {
#define SPI_LL_PERIPH_CLK_FREQ (80 * 1000000)
#define SPI_LL_GET_HW(ID) ((ID)==0? ({abort();NULL;}):&GPSPI2)

#define SPI_LL_DATA_MAX_BIT_LEN (1 << 18)
#define SPI_LL_DMA_MAX_BIT_LEN (1 << 18) //reg len: 18 bits
#define SPI_LL_CPU_MAX_BIT_LEN (16 * 32) //Fifo len: 16 words

/**
* The data structure holding calculated clock configuration. Since the
Expand Down
3 changes: 2 additions & 1 deletion components/hal/esp32h2/include/hal/spi_ll.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ extern "C" {
#define SPI_LL_PERIPH_CLK_FREQ (80 * 1000000)
#define SPI_LL_GET_HW(ID) ((ID)==0? ({abort();NULL;}):&GPSPI2)

#define SPI_LL_DATA_MAX_BIT_LEN (1 << 18)
#define SPI_LL_DMA_MAX_BIT_LEN (1 << 18) //reg len: 18 bits
#define SPI_LL_CPU_MAX_BIT_LEN (16 * 32) //Fifo len: 16 words

/**
* The data structure holding calculated clock configuration. Since the
Expand Down
3 changes: 2 additions & 1 deletion components/hal/esp32s2/include/hal/spi_ll.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ extern "C" {
#define SPI_LL_PERIPH_CLK_FREQ (80 * 1000000)
#define SPI_LL_GET_HW(ID) ((ID)==0? ({abort();NULL;}):((ID)==1? &GPSPI2 : &GPSPI3))

#define SPI_LL_DATA_MAX_BIT_LEN (1 << 23)
#define SPI_LL_DMA_MAX_BIT_LEN (1 << 23) //reg len: 23 bits
#define SPI_LL_CPU_MAX_BIT_LEN (18 * 32) //Fifo len: 18 words

/**
* The data structure holding calculated clock configuration. Since the
Expand Down
3 changes: 2 additions & 1 deletion components/hal/esp32s3/include/hal/spi_ll.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ extern "C" {
#define SPI_LL_PERIPH_CLK_FREQ (80 * 1000000)
#define SPI_LL_GET_HW(ID) ((ID)==0? ({abort();NULL;}):((ID)==1? &GPSPI2 : &GPSPI3))

#define SPI_LL_DATA_MAX_BIT_LEN (1 << 18)
#define SPI_LL_DMA_MAX_BIT_LEN (1 << 18) //reg len: 18 bits
#define SPI_LL_CPU_MAX_BIT_LEN (16 * 32) //Fifo len: 16 words

/**
* The data structure holding calculated clock configuration. Since the
Expand Down

0 comments on commit d9d5327

Please sign in to comment.