From 5a283072fa4598dd6c4863f87ea46ced2c3ef22d Mon Sep 17 00:00:00 2001 From: David Cermak Date: Thu, 16 May 2024 17:00:13 +0200 Subject: [PATCH] fix(eppp): Fix SIDO host to check/clear interrupts atomically --- components/eppp_link/eppp_sdio.h | 1 + components/eppp_link/eppp_sdio_host.c | 22 ++++++++++++++-------- components/eppp_link/eppp_sdio_slave.c | 15 +++++++-------- 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/components/eppp_link/eppp_sdio.h b/components/eppp_link/eppp_sdio.h index 757f83d54e6..b6d1e4a69ad 100644 --- a/components/eppp_link/eppp_sdio.h +++ b/components/eppp_link/eppp_sdio.h @@ -8,6 +8,7 @@ #define MAX_SDIO_PAYLOAD 1500 #define SDIO_ALIGN(size) (((size) + 3U) & ~(3U)) #define SDIO_PAYLOAD SDIO_ALIGN(MAX_SDIO_PAYLOAD) +#define PPP_SOF 0x7E // Interrupts and registers #define SLAVE_INTR 0 diff --git a/components/eppp_link/eppp_sdio_host.c b/components/eppp_link/eppp_sdio_host.c index 0acb16cf5bb..b08399c187b 100644 --- a/components/eppp_link/eppp_sdio_host.c +++ b/components/eppp_link/eppp_sdio_host.c @@ -23,13 +23,13 @@ // Short timeout for sending/receiving ESSL packets #define PACKET_TIMEOUT_MS 50 // Used for padding unaligned packets, to simplify the logic and keep PPP protocol intact when padded -#define PPP_SOF 0x7E + static const char *TAG = "eppp_sdio_host"; static SemaphoreHandle_t s_essl_mutex = NULL; static essl_handle_t s_essl = NULL; static sdmmc_card_t *s_card = NULL; -static CACHE_ALIGNED_ATTR uint8_t send_buffer[SDIO_PAYLOAD]; +static DRAM_DMA_ALIGNED_ATTR uint8_t send_buffer[SDIO_PAYLOAD]; static DMA_ATTR uint8_t rcv_buffer[SDIO_PAYLOAD]; esp_err_t eppp_sdio_host_tx(void *h, void *buffer, size_t len) @@ -93,6 +93,7 @@ esp_err_t eppp_sdio_host_init(struct eppp_config_sdio_s *eppp_config) sdmmc_host_t config = SDMMC_HOST_DEFAULT(); config.flags = SDMMC_HOST_FLAG_4BIT; + config.flags |= SDMMC_HOST_FLAG_ALLOC_ALIGNED_BUF; config.max_freq_khz = SDMMC_FREQ_HIGHSPEED; s_card = (sdmmc_card_t *)malloc(sizeof(sdmmc_card_t)); @@ -118,9 +119,8 @@ esp_err_t eppp_sdio_host_init(struct eppp_config_sdio_s *eppp_config) static esp_err_t get_intr(uint32_t *out_raw) { esp_err_t ret = ESP_OK; - ESP_GOTO_ON_ERROR(essl_wait_int(s_essl, TIMEOUT_MAX), err, TAG, "essl-wait-int failed"); - ESP_GOTO_ON_ERROR(essl_get_intr(s_essl, out_raw, NULL, TIMEOUT_MAX), err, TAG, "essl-get-int failed"); - ESP_GOTO_ON_ERROR(essl_clear_intr(s_essl, *out_raw, TIMEOUT_MAX), err, TAG, "essl-clear-int failed"); + ESP_GOTO_ON_ERROR(essl_get_intr(s_essl, out_raw, NULL, 0), err, TAG, "essl-get-int failed"); + ESP_GOTO_ON_ERROR(essl_clear_intr(s_essl, *out_raw, 0), err, TAG, "essl-clear-int failed"); ESP_LOGD(TAG, "intr: %08"PRIX32, *out_raw); err: return ret; @@ -129,16 +129,22 @@ static esp_err_t get_intr(uint32_t *out_raw) esp_err_t eppp_sdio_host_rx(esp_netif_t *netif) { uint32_t intr; - esp_err_t err = get_intr(&intr); + esp_err_t err = essl_wait_int(s_essl, TIMEOUT_MAX); if (err == ESP_ERR_TIMEOUT) { return ESP_OK; } + xSemaphoreTake(s_essl_mutex, portMAX_DELAY); + err = get_intr(&intr); + if (err == ESP_ERR_TIMEOUT) { + xSemaphoreGive(s_essl_mutex); + return ESP_OK; + } if (err != ESP_OK) { ESP_LOGE(TAG, "failed to check for interrupts %d", err); + xSemaphoreGive(s_essl_mutex); return ESP_FAIL; } if (intr & ESSL_SDIO_DEF_ESP32.new_packet_intr_mask) { - xSemaphoreTake(s_essl_mutex, portMAX_DELAY); esp_err_t ret; do { size_t size_read = SDIO_PAYLOAD; @@ -159,8 +165,8 @@ esp_err_t eppp_sdio_host_rx(esp_netif_t *netif) } } } while (ret == ESP_ERR_NOT_FINISHED); - xSemaphoreGive(s_essl_mutex); } + xSemaphoreGive(s_essl_mutex); return ESP_OK; } diff --git a/components/eppp_link/eppp_sdio_slave.c b/components/eppp_link/eppp_sdio_slave.c index 620533bcfd4..aeb37ffb2c9 100644 --- a/components/eppp_link/eppp_sdio_slave.c +++ b/components/eppp_link/eppp_sdio_slave.c @@ -12,12 +12,12 @@ #include "eppp_sdio.h" #include "esp_check.h" -#if CONFIG_EPPP_LINK_DEVICE_SDIO_SLAV +#if CONFIG_EPPP_LINK_DEVICE_SDIO_SLAVE #define BUFFER_NUM 4 - +#define BUFFER_SIZE SDIO_PAYLOAD static const char *TAG = "eppp_sdio_slave"; -static WORD_ALIGNED_ATTR uint8_t sdio_slave_rx_buffer[BUFFER_NUM][SDIO_PAYLOAD]; -static WORD_ALIGNED_ATTR uint8_t sdio_slave_tx_buffer[SDIO_PAYLOAD]; +static DMA_ATTR uint8_t sdio_slave_rx_buffer[BUFFER_NUM][BUFFER_SIZE]; +static DMA_ATTR uint8_t sdio_slave_tx_buffer[SDIO_PAYLOAD]; static int s_slave_request = 0; esp_err_t eppp_sdio_slave_tx(void *h, void *buffer, size_t len) @@ -30,7 +30,7 @@ esp_err_t eppp_sdio_slave_tx(void *h, void *buffer, size_t len) size_t send_len = SDIO_ALIGN(len); if (send_len > len) { // pad with SOF's if the size is not 4 bytes aligned - memset(&sdio_slave_tx_buffer[len], 0x7E, send_len - len); + memset(&sdio_slave_tx_buffer[len], PPP_SOF, send_len - len); } ESP_LOG_BUFFER_HEXDUMP(TAG, sdio_slave_tx_buffer, send_len, ESP_LOG_VERBOSE); @@ -92,6 +92,7 @@ esp_err_t eppp_sdio_slave_rx(esp_netif_t *netif) goto again; } } + ESP_LOG_BUFFER_HEXDUMP(TAG, ptr, length, ESP_LOG_VERBOSE); return ESP_OK; } ESP_LOGE(TAG, "Error when receiving packet %d", ret); @@ -113,10 +114,8 @@ esp_err_t eppp_sdio_slave_init(void) sdio_slave_config_t config = { .sending_mode = SDIO_SLAVE_SEND_PACKET, .send_queue_size = BUFFER_NUM, - .recv_buffer_size = SDIO_PAYLOAD, + .recv_buffer_size = BUFFER_SIZE, .event_cb = event_cb, - .flags = SDIO_SLAVE_FLAG_HIGH_SPEED, - .timing = SDIO_SLAVE_TIMING_NSEND_PSAMPLE, }; esp_err_t ret = sdio_slave_initialize(&config); if (ret != ESP_OK) {