[EFR32] RSI_send_error_fix (#23540)

* RSI_send_error_fix

* Addressing review comments

Co-authored-by: riwaghe <RiteshGovind.Waghe@silabs.com>
diff --git a/examples/platform/efr32/rs911x/hal/efx_spi.c b/examples/platform/efr32/rs911x/hal/efx_spi.c
index 87a9fba..b053e57 100644
--- a/examples/platform/efr32/rs911x/hal/efx_spi.c
+++ b/examples/platform/efr32/rs911x/hal/efx_spi.c
@@ -284,13 +284,40 @@
         {
             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 8e4e6e2..4e19543 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
  * ******************************************************/