cancel
Showing results for 
Search instead for 
Did you mean: 

STM32wbxx_hal_smartcard not fully working in v1.10

Félix TREFOU
Associate II

Hi,

We've just updated our HAL from 1.6 to 1.10 and encountered some issues with our link to secured element.

ATR is successfully received.

After any transmit (we are using DMA), a call to a receive return BUSY.

We get file STM32wbxx_hal_smartcard.c back to v1.6 and applied diff one by one, and some lines made the difference.

Here is the diff with minimal git chunks to works:

iff --git a/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_smartcard.c b/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_smartcard.c
index 22f84da1..52bafae6 100644
--- a/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_smartcard.c
+++ b/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_smartcard.c
@@ -823,23 +823,14 @@ HAL_StatusTypeDef HAL_SMARTCARD_Transmit(SMARTCARD_HandleTypeDef *hsmartcard, ui
     /* Disable the Peripheral first to update mode for TX master */
     CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_UE);
 
-    /* In case of TX only mode, if NACK is enabled, the USART must be able to monitor
-       the bidirectional line to detect a NACK signal in case of parity error.
-       Therefore, the receiver block must be enabled as well (RE bit must be set). */
-    if ((hsmartcard->Init.Mode == SMARTCARD_MODE_TX)
-     && (hsmartcard->Init.NACKEnable == SMARTCARD_NACK_ENABLE))
-    {
-      SET_BIT(hsmartcard->Instance->CR1, USART_CR1_RE);
-    }
-    /* Enable Tx */
+    /* Disable Rx, enable Tx */
+    CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_RE);
+    SET_BIT(hsmartcard->Instance->RQR, SMARTCARD_RXDATA_FLUSH_REQUEST);
     SET_BIT(hsmartcard->Instance->CR1, USART_CR1_TE);
 
     /* Enable the Peripheral */
     SET_BIT(hsmartcard->Instance->CR1, USART_CR1_UE);
 
-    /* Perform a TX/RX FIFO Flush */
-    __HAL_SMARTCARD_FLUSH_DRREGISTER(hsmartcard);
-
     hsmartcard->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
     hsmartcard->TxXferSize = Size;
     hsmartcard->TxXferCount = Size;
@@ -854,28 +845,19 @@ HAL_StatusTypeDef HAL_SMARTCARD_Transmit(SMARTCARD_HandleTypeDef *hsmartcard, ui
       hsmartcard->Instance->TDR = (uint8_t)(*ptmpdata & 0xFFU);
       ptmpdata++;
     }
-    if (SMARTCARD_WaitOnFlagUntilTimeout(hsmartcard, SMARTCARD_TRANSMISSION_COMPLETION_FLAG(hsmartcard), RESET, tickstart,
-                                         Timeout) != HAL_OK)
+    if (SMARTCARD_WaitOnFlagUntilTimeout(hsmartcard, SMARTCARD_TRANSMISSION_COMPLETION_FLAG(hsmartcard), RESET, tickstart, Timeout) != HAL_OK)
     {
       return HAL_TIMEOUT;
     }
-
-    /* Disable the Peripheral first to update mode */
-    CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_UE);
-    if ((hsmartcard->Init.Mode == SMARTCARD_MODE_TX)
-     && (hsmartcard->Init.NACKEnable == SMARTCARD_NACK_ENABLE))
+    /* Re-enable Rx at end of transmission if initial mode is Rx/Tx */
+    if (hsmartcard->Init.Mode == SMARTCARD_MODE_TX_RX)
     {
-      /* In case of TX only mode, if NACK is enabled, receiver block has been enabled
-         for Transmit phase. Disable this receiver block. */
-      CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_RE);
-    }
-    if ((hsmartcard->Init.Mode == SMARTCARD_MODE_TX_RX)
-     || (hsmartcard->Init.NACKEnable == SMARTCARD_NACK_ENABLE))
-    {
-      /* Perform a TX FIFO Flush at end of Tx phase, as all sent bytes are appearing in Rx Data register */
-      __HAL_SMARTCARD_FLUSH_DRREGISTER(hsmartcard);
+      /* Disable the Peripheral first to update modes */
+      CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_UE);
+      SET_BIT(hsmartcard->Instance->CR1, USART_CR1_RE);
+      /* Enable the Peripheral */
+      SET_BIT(hsmartcard->Instance->CR1, USART_CR1_UE);
     }
-    SET_BIT(hsmartcard->Instance->CR1, USART_CR1_UE);
 
     /* At end of Tx process, restore hsmartcard->gState to Ready */
     hsmartcard->gState = HAL_SMARTCARD_STATE_READY;
@@ -996,23 +978,14 @@ HAL_StatusTypeDef HAL_SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsmartcard,
     /* Disable the Peripheral first to update mode for TX master */
     CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_UE);
 
-    /* In case of TX only mode, if NACK is enabled, the USART must be able to monitor
-       the bidirectional line to detect a NACK signal in case of parity error.
-       Therefore, the receiver block must be enabled as well (RE bit must be set). */
-    if ((hsmartcard->Init.Mode == SMARTCARD_MODE_TX)
-     && (hsmartcard->Init.NACKEnable == SMARTCARD_NACK_ENABLE))
-    {
-      SET_BIT(hsmartcard->Instance->CR1, USART_CR1_RE);
-    }
-    /* Enable Tx */
+    /* Disable Rx, enable Tx */
+    CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_RE);
+    SET_BIT(hsmartcard->Instance->RQR, SMARTCARD_RXDATA_FLUSH_REQUEST);
     SET_BIT(hsmartcard->Instance->CR1, USART_CR1_TE);
 
     /* Enable the Peripheral */
     SET_BIT(hsmartcard->Instance->CR1, USART_CR1_UE);
 
-    /* Perform a TX/RX FIFO Flush */
-    __HAL_SMARTCARD_FLUSH_DRREGISTER(hsmartcard);
-
     /* Configure Tx interrupt processing */
     if (hsmartcard->FifoMode == SMARTCARD_FIFOMODE_ENABLE)
     {
@@ -1153,23 +1126,14 @@ HAL_StatusTypeDef HAL_SMARTCARD_Transmit_DMA(SMARTCARD_HandleTypeDef *hsmartcard
     /* Disable the Peripheral first to update mode for TX master */
     CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_UE);
 
-    /* In case of TX only mode, if NACK is enabled, the USART must be able to monitor
-       the bidirectional line to detect a NACK signal in case of parity error.
-       Therefore, the receiver block must be enabled as well (RE bit must be set). */
-    if ((hsmartcard->Init.Mode == SMARTCARD_MODE_TX)
-     && (hsmartcard->Init.NACKEnable == SMARTCARD_NACK_ENABLE))
-    {
-      SET_BIT(hsmartcard->Instance->CR1, USART_CR1_RE);
-    }
-    /* Enable Tx */
+    /* Disable Rx, enable Tx */
+    CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_RE);
+    SET_BIT(hsmartcard->Instance->RQR, SMARTCARD_RXDATA_FLUSH_REQUEST);
     SET_BIT(hsmartcard->Instance->CR1, USART_CR1_TE);
 
     /* Enable the Peripheral */
     SET_BIT(hsmartcard->Instance->CR1, USART_CR1_UE);
 
-    /* Perform a TX/RX FIFO Flush */
-    __HAL_SMARTCARD_FLUSH_DRREGISTER(hsmartcard);
-
     /* Set the SMARTCARD DMA transfer complete callback */
     hsmartcard->hdmatx->XferCpltCallback = SMARTCARD_DMATransmitCplt;
 
@@ -2980,22 +2944,15 @@ static void SMARTCARD_EndTransmit_IT(SMARTCARD_HandleTypeDef *hsmartcard)
     CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_EIE);
   }
 
-  /* Disable the Peripheral first to update mode */
-  CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_UE);
-  if ((hsmartcard->Init.Mode == SMARTCARD_MODE_TX)
-   && (hsmartcard->Init.NACKEnable == SMARTCARD_NACK_ENABLE))
+  /* Re-enable Rx at end of transmission if initial mode is Rx/Tx */
+  if (hsmartcard->Init.Mode == SMARTCARD_MODE_TX_RX)
   {
-    /* In case of TX only mode, if NACK is enabled, receiver block has been enabled
-       for Transmit phase. Disable this receiver block. */
-    CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_RE);
-  }
-  if ((hsmartcard->Init.Mode == SMARTCARD_MODE_TX_RX)
-   || (hsmartcard->Init.NACKEnable == SMARTCARD_NACK_ENABLE))
-  {
-    /* Perform a TX FIFO Flush at end of Tx phase, as all sent bytes are appearing in Rx Data register */
-    __HAL_SMARTCARD_FLUSH_DRREGISTER(hsmartcard);
+    /* Disable the Peripheral first to update modes */
+    CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_UE);
+    SET_BIT(hsmartcard->Instance->CR1, USART_CR1_RE);
+    /* Enable the Peripheral */
+    SET_BIT(hsmartcard->Instance->CR1, USART_CR1_UE);
   }
-  SET_BIT(hsmartcard->Instance->CR1, USART_CR1_UE);
 
   /* Tx process is ended, restore hsmartcard->gState to Ready */
   hsmartcard->gState = HAL_SMARTCARD_STATE_READY;

0 REPLIES 0