From 2298624d4ed189eb7d9281890ed27ed88bc5fea3 Mon Sep 17 00:00:00 2001 From: thashok <108740933+thashok@users.noreply.github.com> Date: Tue, 22 Nov 2022 20:31:01 +0530 Subject: [PATCH] [EFR32] RSI_send_error_fix (#23540) * RSI_send_error_fix * Addressing review comments Co-authored-by: riwaghe --- examples/platform/efr32/rs911x/hal/efx_spi.c | 31 ++++++++++++++++++-- examples/platform/efr32/rs911x/hal/rsi_hal.h | 6 ++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/examples/platform/efr32/rs911x/hal/efx_spi.c b/examples/platform/efr32/rs911x/hal/efx_spi.c index 87a9fbaa9abfe5..b053e57486767e 100644 --- a/examples/platform/efr32/rs911x/hal/efx_spi.c +++ b/examples/platform/efr32/rs911x/hal/efx_spi.c @@ -284,13 +284,40 @@ int16_t rsi_spi_transfer(uint8_t * tx_buf, uint8_t * rx_buf, uint16_t xlen, uint { transmitDMA(rx_buf, tx_buf, xlen); } + /* - * Wait for the call-back to complete + * receiveDMA() and transmitDMA() are asynchronous + * Our application design assumes that this function is synchronous + * To make it synchronous, we wait to re-acquire the semaphore before exiting this function + * rx_dma_complete() gives back the semaphore when the SPI transfer is done */ - if (xSemaphoreTake(spi_sem, portMAX_DELAY) == pdTRUE) + if (xSemaphoreTake(spi_sem, pdMS_TO_TICKS(RSI_SEM_BLOCK_MIN_TIMER_VALUE_MS)) == pdTRUE) { + // Transfer complete + // Give back the semaphore before exiting, so that it may be re-acquired + // in this function, just before the next transfer xSemaphoreGive(spi_sem); } + // Temporary patch + // Sometimes the xSemaphoreTake() above is getting stuck indefinitely + // As a workaround, if the transfer is not done within RSI_SEM_BLOCK_MIN_TIMER_VALUE_MS + // stop and start it again + // No need to re-acquire the semaphore since this is the function that acquired it + // TODO: Remove this after a permanent solution is found to the problem of the transfer getting stuck + else + { + uint32_t ldma_flags = 0; + uint32_t rem_len = 0; + rem_len = LDMA_TransferRemainingCount(RSI_LDMA_TRANSFER_CHANNEL_NUM); + LDMA_StopTransfer(RSI_LDMA_TRANSFER_CHANNEL_NUM); + ldma_flags = LDMA_IntGet(); + LDMA_IntClear(ldma_flags); + receiveDMA(rx_buf, rem_len); + if (xSemaphoreTake(spi_sem, portMAX_DELAY) == pdTRUE) + { + xSemaphoreGive(spi_sem); + } + } } return RSI_ERROR_NONE; diff --git a/examples/platform/efr32/rs911x/hal/rsi_hal.h b/examples/platform/efr32/rs911x/hal/rsi_hal.h index 8e4e6e25952583..4e195433edc57f 100644 --- a/examples/platform/efr32/rs911x/hal/rsi_hal.h +++ b/examples/platform/efr32/rs911x/hal/rsi_hal.h @@ -54,6 +54,12 @@ // Macro to drive high value on GPIO #define RSI_HAL_GPIO_HIGH 1 +// Macro to drive LDMA channel number +#define RSI_LDMA_TRANSFER_CHANNEL_NUM 3 + +// Macro to drive semaphore block minimun timer in milli seconds +#define RSI_SEM_BLOCK_MIN_TIMER_VALUE_MS 50 + /****************************************************** * * Function Declarations * ******************************************************/