-
Main Changes
+
Main Changes
- First official release of HAL and LL drivers for STM32H573xx / STM32H563xx / STM32H562xx / STM32H503xx devices
-
Known Limitations
+
Known Limitations
-
Backward compatibility
+
Backward compatibility
diff --git a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal.c b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal.c
index f7e50f7883..55d98c7cc0 100644
--- a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal.c
+++ b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal.c
@@ -48,10 +48,10 @@
/* Private typedef ---------------------------------------------------------------------------------------------------*/
/* Private define ----------------------------------------------------------------------------------------------------*/
/**
- * @brief STM32H5xx HAL Driver version number 1.4.0
+ * @brief STM32H5xx HAL Driver version number 1.5.0.RC1
*/
#define __STM32H5XX_HAL_VERSION_MAIN (0x01U) /*!< [31:24] main version */
-#define __STM32H5XX_HAL_VERSION_SUB1 (0x04U) /*!< [23:16] sub1 version */
+#define __STM32H5XX_HAL_VERSION_SUB1 (0x05U) /*!< [23:16] sub1 version */
#define __STM32H5XX_HAL_VERSION_SUB2 (0x00U) /*!< [15:8] sub2 version */
#define __STM32H5XX_HAL_VERSION_RC (0x00U) /*!< [7:0] release candidate */
#define __STM32H5XX_HAL_VERSION ((__STM32H5XX_HAL_VERSION_MAIN << 24U)\
diff --git a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_cryp.c b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_cryp.c
index 6997679741..3d9ee4ff59 100644
--- a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_cryp.c
+++ b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_cryp.c
@@ -1670,6 +1670,7 @@ HAL_StatusTypeDef HAL_CRYP_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint32_t *pInpu
default:
hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
+ hcryp->State = HAL_CRYP_STATE_READY;
status = HAL_ERROR;
break;
}
@@ -1778,6 +1779,7 @@ HAL_StatusTypeDef HAL_CRYP_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint32_t *pInpu
default:
hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
+ hcryp->State = HAL_CRYP_STATE_READY;
status = HAL_ERROR;
break;
}
@@ -1947,6 +1949,7 @@ HAL_StatusTypeDef HAL_CRYP_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint32_t *pInp
default:
hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
+ hcryp->State = HAL_CRYP_STATE_READY;
status = HAL_ERROR;
break;
}
@@ -2037,6 +2040,7 @@ HAL_StatusTypeDef HAL_CRYP_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint32_t *pInp
default:
hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
+ hcryp->State = HAL_CRYP_STATE_READY;
status = HAL_ERROR;
break;
}
diff --git a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dma.c b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dma.c
index e29c115476..cc1ab31e03 100644
--- a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dma.c
+++ b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dma.c
@@ -280,6 +280,17 @@ HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *const hdma)
/* Allocate lock resource */
__HAL_UNLOCK(hdma);
+ /* Initialize the callbacks */
+ if (hdma->State == HAL_DMA_STATE_RESET)
+ {
+ /* Clean all callbacks */
+ hdma->XferCpltCallback = NULL;
+ hdma->XferHalfCpltCallback = NULL;
+ hdma->XferErrorCallback = NULL;
+ hdma->XferAbortCallback = NULL;
+ hdma->XferSuspendCallback = NULL;
+ }
+
/* Update the DMA channel state */
hdma->State = HAL_DMA_STATE_BUSY;
@@ -474,6 +485,12 @@ HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *const hdma,
return HAL_ERROR;
}
+ /* Check the DMA Mode is DMA_NORMAL */
+ if (hdma->Mode != DMA_NORMAL)
+ {
+ return HAL_ERROR;
+ }
+
/* Check the parameters */
assert_param(IS_DMA_BLOCK_SIZE(SrcDataSize));
@@ -529,6 +546,12 @@ HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *const hdma,
return HAL_ERROR;
}
+ /* Check the DMA Mode is DMA_NORMAL */
+ if (hdma->Mode != DMA_NORMAL)
+ {
+ return HAL_ERROR;
+ }
+
/* Check the parameters */
assert_param(IS_DMA_BLOCK_SIZE(SrcDataSize));
@@ -910,7 +933,7 @@ void HAL_DMA_IRQHandler(DMA_HandleTypeDef *const hdma)
}
/* Data Transfer Error Interrupt management *************************************************************************/
- if ((__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_DTE) != 0U))
+ if (__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_DTE) != 0U)
{
/* Check if interrupt source is enabled */
if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_DTE) != 0U)
@@ -924,7 +947,7 @@ void HAL_DMA_IRQHandler(DMA_HandleTypeDef *const hdma)
}
/* Update Linked-list Error Interrupt management ********************************************************************/
- if ((__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_ULE) != 0U))
+ if (__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_ULE) != 0U)
{
/* Check if interrupt source is enabled */
if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_ULE) != 0U)
@@ -938,7 +961,7 @@ void HAL_DMA_IRQHandler(DMA_HandleTypeDef *const hdma)
}
/* User Setting Error Interrupt management **************************************************************************/
- if ((__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_USE) != 0U))
+ if (__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_USE) != 0U)
{
/* Check if interrupt source is enabled */
if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_USE) != 0U)
@@ -952,7 +975,7 @@ void HAL_DMA_IRQHandler(DMA_HandleTypeDef *const hdma)
}
/* Trigger Overrun Interrupt management *****************************************************************************/
- if ((__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_TO) != 0U))
+ if (__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_TO) != 0U)
{
/* Check if interrupt source is enabled */
if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TO) != 0U)
@@ -966,7 +989,7 @@ void HAL_DMA_IRQHandler(DMA_HandleTypeDef *const hdma)
}
/* Half Transfer Complete Interrupt management **********************************************************************/
- if ((__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_HT) != 0U))
+ if (__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_HT) != 0U)
{
/* Check if interrupt source is enabled */
if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != 0U)
@@ -984,7 +1007,7 @@ void HAL_DMA_IRQHandler(DMA_HandleTypeDef *const hdma)
}
/* Suspend Transfer Interrupt management ****************************************************************************/
- if ((__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_SUSP) != 0U))
+ if (__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_SUSP) != 0U)
{
/* Check if interrupt source is enabled */
if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_SUSP) != 0U)
@@ -1042,7 +1065,7 @@ void HAL_DMA_IRQHandler(DMA_HandleTypeDef *const hdma)
}
/* Transfer Complete Interrupt management ***************************************************************************/
- if ((__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_TC) != 0U))
+ if (__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_TC) != 0U)
{
/* Check if interrupt source is enabled */
if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != 0U)
@@ -1539,7 +1562,7 @@ HAL_StatusTypeDef HAL_DMA_LockChannelAttributes(DMA_HandleTypeDef const *const h
*/
HAL_StatusTypeDef HAL_DMA_GetLockChannelAttributes(DMA_HandleTypeDef const *const hdma, uint32_t *const pLockState)
{
- DMA_TypeDef *p_dma_instance;
+ const DMA_TypeDef *p_dma_instance;
uint32_t channel_idx;
/* Check the DMA peripheral handle and lock state parameters */
diff --git a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dma_ex.c b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dma_ex.c
index 27d2c19b62..b225e71846 100644
--- a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dma_ex.c
+++ b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dma_ex.c
@@ -824,6 +824,12 @@ HAL_StatusTypeDef HAL_DMAEx_List_Start(DMA_HandleTypeDef *const hdma)
return HAL_ERROR;
}
+ /* Check the DMA Mode is not DMA_NORMAL */
+ if (hdma->Mode == DMA_NORMAL)
+ {
+ return HAL_ERROR;
+ }
+
/* Check DMA channel state */
dma_state = hdma->State;
ccr_value = hdma->Instance->CCR & DMA_CCR_LSM;
@@ -886,6 +892,12 @@ HAL_StatusTypeDef HAL_DMAEx_List_Start_IT(DMA_HandleTypeDef *const hdma)
return HAL_ERROR;
}
+ /* Check the DMA Mode is not DMA_NORMAL */
+ if (hdma->Mode == DMA_NORMAL)
+ {
+ return HAL_ERROR;
+ }
+
/* Check DMA channel state */
dma_state = hdma->State;
ccr_value = hdma->Instance->CCR & DMA_CCR_LSM;
@@ -3109,6 +3121,12 @@ HAL_StatusTypeDef HAL_DMAEx_List_LinkQ(DMA_HandleTypeDef *const hdma,
return HAL_ERROR;
}
+ /* Check the DMA Mode is not DMA_NORMAL */
+ if (hdma->Mode == DMA_NORMAL)
+ {
+ return HAL_ERROR;
+ }
+
/* Get DMA state */
state = hdma->State;
@@ -3189,6 +3207,12 @@ HAL_StatusTypeDef HAL_DMAEx_List_UnLinkQ(DMA_HandleTypeDef *const hdma)
return HAL_ERROR;
}
+ /* Check the DMA Mode is not DMA_NORMAL */
+ if (hdma->Mode == DMA_NORMAL)
+ {
+ return HAL_ERROR;
+ }
+
/* Get DMA state */
state = hdma->State;
@@ -3257,6 +3281,12 @@ HAL_StatusTypeDef HAL_DMAEx_ConfigDataHandling(DMA_HandleTypeDef *const hdma,
return HAL_ERROR;
}
+ /* Check the DMA Mode is DMA_NORMAL */
+ if (hdma->Mode != DMA_NORMAL)
+ {
+ return HAL_ERROR;
+ }
+
/* Check the parameters */
assert_param(IS_DMA_DATA_ALIGNMENT(pConfigDataHandling->DataAlignment));
assert_param(IS_DMA_DATA_EXCHANGE(pConfigDataHandling->DataExchange));
@@ -3297,6 +3327,12 @@ HAL_StatusTypeDef HAL_DMAEx_ConfigTrigger(DMA_HandleTypeDef *const hdma,
return HAL_ERROR;
}
+ /* Check the DMA Mode is DMA_NORMAL */
+ if (hdma->Mode != DMA_NORMAL)
+ {
+ return HAL_ERROR;
+ }
+
/* Check the parameters */
assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
assert_param(IS_DMA_TRIGGER_POLARITY(pConfigTrigger->TriggerPolarity));
@@ -3345,6 +3381,12 @@ HAL_StatusTypeDef HAL_DMAEx_ConfigRepeatBlock(DMA_HandleTypeDef *const hdma,
return HAL_ERROR;
}
+ /* Check the DMA Mode is DMA_NORMAL */
+ if (hdma->Mode != DMA_NORMAL)
+ {
+ return HAL_ERROR;
+ }
+
/* Check parameters */
assert_param(IS_DMA_2D_ADDRESSING_INSTANCE(hdma->Instance));
assert_param(IS_DMA_REPEAT_COUNT(pConfigRepeatBlock->RepeatCount));
@@ -4467,7 +4509,7 @@ static void DMA_List_ConvertNodeToStatic(uint32_t ContextNodeAddr,
uint32_t contextnode_reg_counter = 0U;
uint32_t cllr_idx;
uint32_t cllr_mask;
- DMA_NodeTypeDef *context_node = (DMA_NodeTypeDef *)ContextNodeAddr;
+ const DMA_NodeTypeDef *context_node = (DMA_NodeTypeDef *)ContextNodeAddr;
DMA_NodeTypeDef *current_node = (DMA_NodeTypeDef *)CurrentNodeAddr;
uint32_t update_link[NODE_MAXIMUM_SIZE] = {DMA_CLLR_UT1, DMA_CLLR_UT2, DMA_CLLR_UB1, DMA_CLLR_USA,
DMA_CLLR_UDA, DMA_CLLR_UT3, DMA_CLLR_UB2, DMA_CLLR_ULL
diff --git a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_eth.c b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_eth.c
index be5ef6cf96..7bdbfe5e13 100644
--- a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_eth.c
+++ b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_eth.c
@@ -1040,6 +1040,8 @@ HAL_StatusTypeDef HAL_ETH_Transmit_IT(ETH_HandleTypeDef *heth, ETH_TxPacketConfi
HAL_StatusTypeDef HAL_ETH_ReadData(ETH_HandleTypeDef *heth, void **pAppBuff)
{
uint32_t descidx;
+ uint32_t descidx_next;
+ ETH_DMADescTypeDef *dmarxdesc_next;
ETH_DMADescTypeDef *dmarxdesc;
uint32_t desccnt = 0U;
uint32_t desccntmax;
@@ -1065,14 +1067,8 @@ HAL_StatusTypeDef HAL_ETH_ReadData(ETH_HandleTypeDef *heth, void **pAppBuff)
while ((READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_OWN) == (uint32_t)RESET) && (desccnt < desccntmax)
&& (rxdataready == 0U))
{
- if (READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_CTXT) != (uint32_t)RESET)
- {
- /* Get timestamp high */
- heth->RxDescList.TimeStamp.TimeStampHigh = dmarxdesc->DESC1;
- /* Get timestamp low */
- heth->RxDescList.TimeStamp.TimeStampLow = dmarxdesc->DESC0;
- }
- if ((READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_FD) != (uint32_t)RESET) || (heth->RxDescList.pRxStart != NULL))
+ if ((READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_FD) != (uint32_t)RESET) ||
+ (heth->RxDescList.pRxStart != NULL))
{
/* Check if first descriptor */
if (READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_FD) != (uint32_t)RESET)
@@ -1092,6 +1088,22 @@ HAL_StatusTypeDef HAL_ETH_ReadData(ETH_HandleTypeDef *heth, void **pAppBuff)
/* Packet ready */
rxdataready = 1;
+
+ if (READ_BIT(dmarxdesc->DESC1, ETH_DMARXNDESCWBF_TSA) != (uint32_t)RESET)
+ {
+ descidx_next = descidx;
+ INCR_RX_DESC_INDEX(descidx_next, 1U);
+
+ dmarxdesc_next = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx_next];
+
+ if (READ_BIT(dmarxdesc_next->DESC3, ETH_DMARXNDESCWBF_CTXT) != (uint32_t)RESET)
+ {
+ /* Get timestamp high */
+ heth->RxDescList.TimeStamp.TimeStampHigh = dmarxdesc_next->DESC1;
+ /* Get timestamp low */
+ heth->RxDescList.TimeStamp.TimeStampLow = dmarxdesc_next->DESC0;
+ }
+ }
}
/* Link data */
@@ -2743,6 +2755,16 @@ uint32_t HAL_ETH_GetMACWakeUpSource(const ETH_HandleTypeDef *heth)
return heth->MACWakeUpEvent;
}
+/**
+ * @brief Returns the ETH Tx Buffers in use number
+ * @param heth: pointer to a ETH_HandleTypeDef structure that contains
+ * the configuration information for ETHERNET module
+ * @retval ETH Tx Buffers in use number
+ */
+uint32_t HAL_ETH_GetTxBuffersNumber(const ETH_HandleTypeDef *heth)
+{
+ return heth->TxDescList.BuffersInUse;
+}
/**
* @}
*/
diff --git a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_flash_ex.c b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_flash_ex.c
index db13a53225..962c3a8d2b 100644
--- a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_flash_ex.c
+++ b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_flash_ex.c
@@ -1054,7 +1054,6 @@ static void FLASH_OB_EnableWRP(uint32_t WRPSector, uint32_t Banks)
{
/* Check the parameters */
assert_param(IS_FLASH_BANK(Banks));
-
if ((Banks & FLASH_BANK_1) == FLASH_BANK_1)
{
/* Enable Write Protection for bank 1 */
diff --git a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_gpio.c b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_gpio.c
index a59d2ca1fb..9fdffd7dd6 100644
--- a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_gpio.c
+++ b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_gpio.c
@@ -237,7 +237,8 @@ void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, const GPIO_InitTypeDef *pGPIO_Init)
GPIOx->OTYPER = tmp;
}
- if (pGPIO_Init->Mode != GPIO_MODE_ANALOG)
+ if (((pGPIO_Init->Mode & GPIO_MODE) != GPIO_MODE_ANALOG) ||
+ (((pGPIO_Init->Mode & GPIO_MODE) == GPIO_MODE_ANALOG) && (pGPIO_Init->Pull != GPIO_PULLUP)))
{
/* Check the Pull parameters */
assert_param(IS_GPIO_PULL(pGPIO_Init->Pull));
diff --git a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_gtzc.c b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_gtzc.c
index 13482f839d..00e93a75c9 100644
--- a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_gtzc.c
+++ b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_gtzc.c
@@ -840,8 +840,7 @@ HAL_StatusTypeDef HAL_GTZC_MPCBB_ConfigMem(uint32_t MemBaseAddress,
uint32_t size_in_superblocks;
uint32_t i;
-#if defined (GTZC_MPCBB3)
- /* check entry parameters */
+#if defined(GTZC_MPCBB3)
if ((!(IS_GTZC_BASE_ADDRESS(SRAM1, MemBaseAddress))
&& !(IS_GTZC_BASE_ADDRESS(SRAM2, MemBaseAddress))
&& !(IS_GTZC_BASE_ADDRESS(SRAM3, MemBaseAddress)))
@@ -850,7 +849,7 @@ HAL_StatusTypeDef HAL_GTZC_MPCBB_ConfigMem(uint32_t MemBaseAddress,
if ((!(IS_GTZC_BASE_ADDRESS(SRAM1, MemBaseAddress))
&& !(IS_GTZC_BASE_ADDRESS(SRAM2, MemBaseAddress)))
|| MPCBB_PARAMETERS_CHECK())
-#endif /* defined (GTZC_MPCBB3) */
+#endif /* defined(GTZC_MPCBB3) */
{
return HAL_ERROR;
}
@@ -860,7 +859,7 @@ HAL_StatusTypeDef HAL_GTZC_MPCBB_ConfigMem(uint32_t MemBaseAddress,
mpcbb_ptr = GTZC_MPCBB1;
mem_size = GTZC_MEM_SIZE(SRAM1);
}
-#if defined (GTZC_MPCBB3)
+#if defined(GTZC_MPCBB3)
else if (IS_GTZC_BASE_ADDRESS(SRAM2, MemBaseAddress))
{
mpcbb_ptr = GTZC_MPCBB2;
@@ -877,7 +876,7 @@ HAL_StatusTypeDef HAL_GTZC_MPCBB_ConfigMem(uint32_t MemBaseAddress,
mpcbb_ptr = GTZC_MPCBB2;
mem_size = GTZC_MEM_SIZE(SRAM2);
}
-#endif /* defined (GTZC_MPCBB3) */
+#endif /* defined(GTZC_MPCBB3) */
/* translate mem_size in number of super-blocks */
size_in_superblocks = (mem_size / GTZC_MPCBB_SUPERBLOCK_SIZE);
@@ -940,14 +939,14 @@ HAL_StatusTypeDef HAL_GTZC_MPCBB_GetConfigMem(uint32_t MemBaseAddress,
uint32_t i;
/* check entry parameters */
-#if defined (GTZC_MPCBB3)
+#if defined(GTZC_MPCBB3)
if (!(IS_GTZC_BASE_ADDRESS(SRAM1, MemBaseAddress))
&& !(IS_GTZC_BASE_ADDRESS(SRAM2, MemBaseAddress))
&& !(IS_GTZC_BASE_ADDRESS(SRAM3, MemBaseAddress)))
#else
if (!(IS_GTZC_BASE_ADDRESS(SRAM1, MemBaseAddress))
&& !(IS_GTZC_BASE_ADDRESS(SRAM2, MemBaseAddress)))
-#endif /* defined (GTZC_MPCBB3) */
+#endif /* defined(GTZC_MPCBB3) */
{
return HAL_ERROR;
}
@@ -959,7 +958,7 @@ HAL_StatusTypeDef HAL_GTZC_MPCBB_GetConfigMem(uint32_t MemBaseAddress,
mpcbb_ptr = GTZC_MPCBB1;
mem_size = GTZC_MEM_SIZE(SRAM1);
}
-#if defined (GTZC_MPCBB3)
+#if defined(GTZC_MPCBB3)
else if (IS_GTZC_BASE_ADDRESS(SRAM2, MemBaseAddress))
{
mpcbb_ptr = GTZC_MPCBB2;
@@ -976,7 +975,7 @@ HAL_StatusTypeDef HAL_GTZC_MPCBB_GetConfigMem(uint32_t MemBaseAddress,
mpcbb_ptr = GTZC_MPCBB2;
mem_size = GTZC_MEM_SIZE(SRAM2);
}
-#endif /* */
+#endif /* defined(GTZC_MPCBB3) */
/* translate mem_size in number of super-blocks */
size_in_superblocks = (mem_size / GTZC_MPCBB_SUPERBLOCK_SIZE);
@@ -1075,7 +1074,7 @@ HAL_StatusTypeDef HAL_GTZC_MPCBB_ConfigMemAttributes(uint32_t MemAddress,
base_address = SRAM2_BASE_S;
}
#endif /* defined (GTZC_TZIC1) */
-#if defined (GTZC_MPCBB3)
+#if defined(GTZC_MPCBB3)
else if (((IS_ADDRESS_IN_NS(SRAM3, MemAddress))
&& (IS_ADDRESS_IN_NS(SRAM3, end_address))) != 0U)
{
@@ -1302,7 +1301,6 @@ HAL_StatusTypeDef HAL_GTZC_MPCBB_LockConfig(uint32_t MemAddress,
- 1U))))
{
base_address = GTZC_BASE_ADDRESS(SRAM1);
- /* limitation: code not portable with memory > 512K */
reg_mpcbb = (__IO uint32_t *)>ZC_MPCBB1_S->CFGLOCKR1;
}
else if ((IS_ADDRESS_IN(SRAM2, MemAddress))
@@ -1311,7 +1309,6 @@ HAL_StatusTypeDef HAL_GTZC_MPCBB_LockConfig(uint32_t MemAddress,
- 1U))))
{
base_address = GTZC_BASE_ADDRESS(SRAM2);
- /* limitation: code not portable with memory > 256K */
reg_mpcbb = (__IO uint32_t *)>ZC_MPCBB2_S->CFGLOCKR1;
}
else if ((IS_ADDRESS_IN(SRAM3, MemAddress))
@@ -1320,7 +1317,6 @@ HAL_StatusTypeDef HAL_GTZC_MPCBB_LockConfig(uint32_t MemAddress,
- 1U))))
{
base_address = GTZC_BASE_ADDRESS(SRAM3);
- /* limitation: code not portable with memory > 512K */
reg_mpcbb = (__IO uint32_t *)>ZC_MPCBB3_S->CFGLOCKR1;
}
@@ -1395,7 +1391,6 @@ HAL_StatusTypeDef HAL_GTZC_MPCBB_GetLockConfig(uint32_t MemAddress,
- 1U))))
{
base_address = GTZC_BASE_ADDRESS(SRAM1);
- /* limitation: code not portable with memory > 512K */
reg_mpcbb = GTZC_MPCBB1_S->CFGLOCKR1;
}
else if ((IS_ADDRESS_IN(SRAM2, MemAddress))
@@ -1405,7 +1400,6 @@ HAL_StatusTypeDef HAL_GTZC_MPCBB_GetLockConfig(uint32_t MemAddress,
- 1U))))
{
base_address = GTZC_BASE_ADDRESS(SRAM2);
- /* limitation: code not portable with memory > 512K */
reg_mpcbb = GTZC_MPCBB2_S->CFGLOCKR1;
}
else if ((IS_ADDRESS_IN(SRAM3, MemAddress))
@@ -1415,7 +1409,6 @@ HAL_StatusTypeDef HAL_GTZC_MPCBB_GetLockConfig(uint32_t MemAddress,
- 1U))))
{
base_address = GTZC_BASE_ADDRESS(SRAM3);
- /* limitation: code not portable with memory > 512K */
reg_mpcbb = GTZC_MPCBB3_S->CFGLOCKR1;
}
else
diff --git a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_hash.c b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_hash.c
index d96e47c510..5f27a9ce93 100644
--- a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_hash.c
+++ b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_hash.c
@@ -305,7 +305,7 @@ HAL_StatusTypeDef HAL_HASH_DeInit(HASH_HandleTypeDef *hhash)
* the configuration information for HASH module
* @retval HAL status
*/
-HAL_StatusTypeDef HAL_HASH_SetConfig(HASH_HandleTypeDef *hhash, HASH_ConfigTypeDef *pConf)
+HAL_StatusTypeDef HAL_HASH_SetConfig(HASH_HandleTypeDef *hhash, const HASH_ConfigTypeDef *pConf)
{
uint32_t cr_value;
@@ -1868,11 +1868,10 @@ HAL_StatusTypeDef HAL_HASH_HMAC_Start_IT(HASH_HandleTypeDef *hhash, const uint8_
{
return HAL_BUSY;
}
-
+ status = HASH_WriteData_IT(hhash);
/* Enable the specified HASH interrupt*/
__HAL_HASH_ENABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI);
- status = HASH_WriteData_IT(hhash);
/* Return function status */
return status;
@@ -1949,10 +1948,10 @@ HAL_StatusTypeDef HAL_HASH_HMAC_Accumulate_IT(HASH_HandleTypeDef *hhash, const u
/* Set the phase */
hhash->Phase = HAL_HASH_PHASE_PROCESS;
}
+ status = HASH_WriteData_IT(hhash);
/* Enable the specified HASH interrupt*/
__HAL_HASH_ENABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI);
- status = HASH_WriteData_IT(hhash);
}
else
{
@@ -1999,10 +1998,10 @@ HAL_StatusTypeDef HAL_HASH_HMAC_AccumulateLast_IT(HASH_HandleTypeDef *hhash, con
hhash->Size = Size;
/* Set multi buffers accumulation flag */
hhash->Accumulation = 0U;
+ status = HASH_WriteData_IT(hhash);
/* Enable the specified HASH interrupt*/
__HAL_HASH_ENABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI);
- status = HASH_WriteData_IT(hhash);
}
else
{
@@ -2252,7 +2251,7 @@ void HAL_HASH_IRQHandler(HASH_HandleTypeDef *hhash)
}
/* If Peripheral ready to accept new data */
- if ((itflag & HASH_FLAG_DINIS) == HASH_FLAG_DINIS)
+ if (((itflag & HASH_FLAG_DINIS) == HASH_FLAG_DINIS) && ((itflag & HASH_FLAG_DCIS) != HASH_FLAG_DCIS))
{
if ((itsource & HASH_IT_DINI) == HASH_IT_DINI)
{
@@ -2958,7 +2957,7 @@ static HAL_StatusTypeDef HASH_WriteData_IT(HASH_HandleTypeDef *hhash)
}
}
}
- else if ((hhash->State == HAL_HASH_STATE_SUSPENDED))
+ else if (hhash->State == HAL_HASH_STATE_SUSPENDED)
{
return HAL_OK;
}
diff --git a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_i3c.c b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_i3c.c
index fe73e7c155..9006937e5b 100644
--- a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_i3c.c
+++ b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_i3c.c
@@ -6680,7 +6680,7 @@ HAL_StatusTypeDef HAL_I3C_Tgt_IBIReq(I3C_HandleTypeDef *hi3c, const uint8_t *pPa
else
{
/* Verify if IBI request feature is enabled*/
- if ((LL_I3C_IsEnabledIBI(hi3c->Instance) != 1U))
+ if (LL_I3C_IsEnabledIBI(hi3c->Instance) != 1U)
{
hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED;
status = HAL_ERROR;
diff --git a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_mmc.c b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_mmc.c
index 373df018e8..854d469414 100644
--- a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_mmc.c
+++ b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_mmc.c
@@ -92,6 +92,7 @@
(#) Select the corresponding MMC Card according to the address read with the step 2.
(#) Configure the MMC Card in wide bus mode: 4-bits data.
+ (#) Select the MMC Card partition using HAL_MMC_SwitchPartition()
*** MMC Card Read operation ***
==============================
@@ -168,6 +169,64 @@
(+) The HAL_MMC_GetCardCID() API allows to get the parameters of the CID register.
Some of the CID parameters are useful for card initialization and identification.
+ *** MMC Card Reply Protected Memory Block (RPMB) Key Programming operation ***
+ ==============================
+ [..]
+ (+) You can program the authentication key of RPMB area in polling mode by using function
+ HAL_MMC_RPMB_ProgramAuthenticationKey().
+ This function is only used once during the life of an MMC card.
+ After this, you have to ensure that the transfer is done correctly. The check is done
+ through HAL_MMC_GetRPMBError() function for operation state.
+ (+) You can program the authentication key of RPMB area in Interrupt mode by using function
+ HAL_MMC_RPMB_ProgramAuthenticationKey_IT().
+ This function is only used once during the life of an MMC card.
+ After this, you have to ensure that the transfer is done correctly. The check is done
+ through HAL_MMC_GetRPMBError() function for operation state.
+
+ *** MMC Card Reply Protected Memory Block (RPMB) write counter operation ***
+ ==============================
+ [..]
+ (+) You can get the write counter value of RPMB area in polling mode by using function
+ HAL_MMC_RPMB_GetWriteCounter().
+ (+) You can get the write counter value of RPMB area in Interrupt mode by using function
+ HAL_MMC_RPMB_GetWriteCounter_IT().
+
+ *** MMC Card Reply Protected Memory Block (RPMB) write operation ***
+ ==============================
+ [..]
+ (+) You can write to the RPMB area of MMC card in polling mode by using function
+ HAL_MMC_WriteBlocks().
+ This function supports the one, two, or thirty two blocks write operation
+ (with 512-bytes block length).
+ You can choose the number of blocks at the multiple block read operation by adjusting
+ the "NumberOfBlocks" parameter.
+ After this, you have to ensure that the transfer is done correctly. The check is done
+ through HAL_MMC_GetRPMBError() function for operation state.
+ (+) You can write to the RPMB area of MMC card in Interrupt mode by using function
+ HAL_MMC_WriteBlocks_IT().
+ This function supports the one, two, or thirty two blocks write operation
+ (with 512-bytes block length).
+ You can choose the number of blocks at the multiple block read operation by adjusting
+ the "NumberOfBlocks" parameter.
+ After this, you have to ensure that the transfer is done correctly. The check is done
+ through HAL_MMC_GetRPMBError() function for operation state.
+
+ *** MMC Card Reply Protected Memory Block (RPMB) read operation ***
+ ==============================
+ [..]
+ (+) You can read from the RPMB area of MMC card in polling mode by using function
+ HAL_MMC_RPMB_ReadBlocks().
+ The block size should be chosen as multiple of 512 bytes.
+ You can choose the number of blocks by adjusting the "NumberOfBlocks" parameter.
+ After this, you have to ensure that the transfer is done correctly. The check is done
+ through HAL_MMC_GetRPMBError() function for MMC card state.
+ (+) You can read from the RPMB area of MMC card in Interrupt mode by using function
+ HAL_MMC_RPMB_ReadBlocks_IT().
+ The block size should be chosen as multiple of 512 bytes.
+ You can choose the number of blocks by adjusting the "NumberOfBlocks" parameter.
+ After this, you have to ensure that the transfer is done correctly. The check is done
+ through HAL_MMC_GetRPMBError() function for MMC card state.
+
*** MMC HAL driver macros list ***
==================================
[..]
@@ -289,6 +348,11 @@
#define MMC_INIT_FREQ 400000U /* Initialization phase : 400 kHz max */
#define MMC_HIGH_SPEED_FREQ 52000000U /* High speed phase : 52 MHz max */
+/* The Data elements' postitions in the frame Frame for RPMB area */
+#define MMC_RPMB_KEYMAC_POSITION 196U
+#define MMC_RPMB_DATA_POSITION 228U
+#define MMC_RPMB_NONCE_POSITION 484U
+#define MMC_RPMB_WRITE_COUNTER_POSITION 500U
/**
* @}
*/
@@ -2069,7 +2133,7 @@ HAL_StatusTypeDef HAL_MMC_UnRegisterCallback(MMC_HandleTypeDef *hmmc, HAL_MMC_Ca
* contains all CID register parameters
* @retval HAL status
*/
-HAL_StatusTypeDef HAL_MMC_GetCardCID(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCIDTypeDef *pCID)
+HAL_StatusTypeDef HAL_MMC_GetCardCID(const MMC_HandleTypeDef *hmmc, HAL_MMC_CardCIDTypeDef *pCID)
{
pCID->ManufacturerID = (uint8_t)((hmmc->CID[0] & 0xFF000000U) >> 24U);
@@ -2220,7 +2284,7 @@ HAL_StatusTypeDef HAL_MMC_GetCardCSD(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCSDTyp
* will contain the MMC card status information
* @retval HAL status
*/
-HAL_StatusTypeDef HAL_MMC_GetCardInfo(MMC_HandleTypeDef *hmmc, HAL_MMC_CardInfoTypeDef *pCardInfo)
+HAL_StatusTypeDef HAL_MMC_GetCardInfo(const MMC_HandleTypeDef *hmmc, HAL_MMC_CardInfoTypeDef *pCardInfo)
{
pCardInfo->CardType = (uint32_t)(hmmc->MmcCard.CardType);
pCardInfo->Class = (uint32_t)(hmmc->MmcCard.Class);
@@ -4260,6 +4324,1553 @@ static uint32_t MMC_PwrClassUpdate(MMC_HandleTypeDef *hmmc, uint32_t Wide, uint3
return errorstate;
}
+/**
+ * @brief Used to select the partition.
+ * @param hmmc: Pointer to MMC handle
+ * @param Partition: Partition type
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_MMC_SwitchPartition(MMC_HandleTypeDef *hmmc, HAL_MMC_PartitionTypeDef Partition)
+{
+ uint32_t errorstate;
+ uint32_t response = 0U;
+ uint32_t count;
+ uint32_t tickstart = HAL_GetTick();
+ uint32_t arg = Partition | 0x03B30000U;
+
+ /* Check the state of the driver */
+ if (hmmc->State == HAL_MMC_STATE_READY)
+ {
+ /* Change State */
+ hmmc->State = HAL_MMC_STATE_BUSY;
+
+ /* Index : 179 - Value : partition */
+ errorstate = SDMMC_CmdSwitch(hmmc->Instance, arg);
+ if (errorstate == HAL_MMC_ERROR_NONE)
+ {
+ /* Wait that the device is ready by checking the D0 line */
+ while ((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
+ {
+ if ((HAL_GetTick() - tickstart) >= SDMMC_MAXERASETIMEOUT)
+ {
+ errorstate = HAL_MMC_ERROR_TIMEOUT;
+ }
+ }
+
+ /* Clear the flag corresponding to end D0 bus line */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
+
+ if (errorstate == HAL_MMC_ERROR_NONE)
+ {
+ /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
+ count = SDMMC_MAX_TRIAL;
+ do
+ {
+ errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
+ if (errorstate != HAL_MMC_ERROR_NONE)
+ {
+ break;
+ }
+
+ /* Get command response */
+ response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
+ count--;
+ } while (((response & 0x100U) == 0U) && (count != 0U));
+
+ /* Check the status after the switch command execution */
+ if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
+ {
+ /* Check the bit SWITCH_ERROR of the device status */
+ if ((response & 0x80U) != 0U)
+ {
+ errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
+ }
+ }
+ else if (count == 0U)
+ {
+ errorstate = SDMMC_ERROR_TIMEOUT;
+ }
+ else
+ {
+ /* Nothing to do */
+ }
+ }
+ }
+
+ /* Change State */
+ hmmc->State = HAL_MMC_STATE_READY;
+
+ /* Manage errors */
+ if (errorstate != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+
+ if (errorstate != HAL_MMC_ERROR_TIMEOUT)
+ {
+ return HAL_ERROR;
+ }
+ else
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ else
+ {
+ return HAL_OK;
+ }
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Allows to program the authentication key within the RPMB partition
+ * @param hmmc: Pointer to MMC handle
+ * @param pKey: pointer to the authentication key (32 bytes)
+ * @param Timeout: Specify timeout value
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_MMC_RPMB_ProgramAuthenticationKey(MMC_HandleTypeDef *hmmc, const uint8_t *pKey, uint32_t Timeout)
+{
+ SDMMC_DataInitTypeDef config;
+ uint32_t errorstate;
+ uint32_t tickstart = HAL_GetTick();
+ uint32_t count;
+ uint32_t byte_count = 0;
+ uint32_t data;
+ uint32_t dataremaining;
+ uint8_t tail_pack[12] = {0};
+ uint8_t zero_pack[4] = {0};
+ const uint8_t *rtempbuff;
+ uint8_t *tempbuff;
+
+ tail_pack[11] = 0x01;
+
+ if (NULL == pKey)
+ {
+ hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
+ return HAL_ERROR;
+ }
+
+ if (hmmc->State == HAL_MMC_STATE_READY)
+ {
+ hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
+
+ hmmc->State = HAL_MMC_STATE_BUSY;
+
+ /* Initialize data control register */
+ hmmc->Instance->DCTRL = 0U;
+
+ errorstate = SDMMC_CmdBlockCount(hmmc->Instance, 0x80000001U);
+ if (errorstate != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Configure the MMC DPSM (Data Path State Machine) */
+ config.DataTimeOut = SDMMC_DATATIMEOUT;
+ config.DataLength = MMC_BLOCKSIZE;
+ config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
+ config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD;
+ config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
+ config.DPSM = SDMMC_DPSM_DISABLE;
+ (void)SDMMC_ConfigData(hmmc->Instance, &config);
+ __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
+
+ /* Write Blocks in Polling mode */
+ {
+ hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
+
+ /* Write Multi Block command */
+ errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, 0);
+ }
+
+ if (errorstate != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Write block(s) in polling mode */
+ rtempbuff = zero_pack;
+ dataremaining = config.DataLength;
+ while (!__HAL_MMC_GET_FLAG(hmmc,
+ SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
+ {
+ if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) && (dataremaining >= SDMMC_FIFO_SIZE))
+ {
+ /* Write data to SDMMC Tx FIFO */
+ for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
+ {
+ data = (uint32_t)(*rtempbuff);
+ rtempbuff++;
+ byte_count++;
+ data |= ((uint32_t)(*rtempbuff) << 8U);
+ rtempbuff++;
+ byte_count++;
+ data |= ((uint32_t)(*rtempbuff) << 16U);
+ rtempbuff++;
+ byte_count++;
+ data |= ((uint32_t)(*rtempbuff) << 24U);
+ rtempbuff++;
+ byte_count++;
+ (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
+ if (byte_count < MMC_RPMB_KEYMAC_POSITION)
+ {
+ rtempbuff = zero_pack;
+ }
+ else if (byte_count == MMC_RPMB_KEYMAC_POSITION)
+ {
+ rtempbuff = pKey;
+ }
+ else if ((byte_count < MMC_RPMB_WRITE_COUNTER_POSITION) && \
+ (byte_count >= MMC_RPMB_DATA_POSITION))
+ {
+ rtempbuff = zero_pack;
+ }
+ else if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
+ {
+ rtempbuff = tail_pack;
+ }
+ else
+ {
+ /* Nothing to do */
+ }
+
+ }
+ dataremaining -= SDMMC_FIFO_SIZE;
+ }
+
+ if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U))
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_TIMEOUT;
+ }
+ }
+ __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
+
+ /* Read Response Packet */
+ errorstate = SDMMC_CmdBlockCount(hmmc->Instance, 0x00000001);
+ if (errorstate != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Configure the MMC DPSM (Data Path State Machine) */
+ config.DataTimeOut = SDMMC_DATATIMEOUT;
+ config.DataLength = MMC_BLOCKSIZE;
+ config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
+ config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
+ config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
+ config.DPSM = SDMMC_DPSM_DISABLE;
+ (void)SDMMC_ConfigData(hmmc->Instance, &config);
+ __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
+
+ /* Write Blocks in Polling mode */
+ hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK;
+
+ /* Write Multi Block command */
+ errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, 0);
+
+ if (errorstate != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
+ /* Poll on SDMMC flags */
+ tempbuff = zero_pack;
+ byte_count = 0;
+
+ dataremaining = config.DataLength;
+ while (!__HAL_MMC_GET_FLAG(hmmc,
+ SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
+ {
+ if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) && (dataremaining >= SDMMC_FIFO_SIZE))
+ {
+ /* Read data from SDMMC Rx FIFO */
+ for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
+ {
+ data = SDMMC_ReadFIFO(hmmc->Instance);
+ *tempbuff = (uint8_t)(data & 0xFFU);
+ tempbuff++;
+ byte_count++;
+ *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
+ tempbuff++;
+ byte_count++;
+ *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
+ tempbuff++;
+ byte_count++;
+ *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
+ tempbuff++;
+ byte_count++;
+ if (byte_count < MMC_RPMB_WRITE_COUNTER_POSITION)
+ {
+ tempbuff = zero_pack;
+ }
+ else if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
+ {
+ tempbuff = tail_pack;
+ }
+ else
+ {
+ /* Nothing to do */
+ }
+ }
+ dataremaining -= SDMMC_FIFO_SIZE;
+ }
+
+ if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U))
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_TIMEOUT;
+ }
+ }
+ __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
+
+ /* Get error state */
+ if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+ else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+ else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR))
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+ else
+ {
+ /* Nothing to do */
+ }
+
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
+
+ hmmc->State = HAL_MMC_STATE_READY;
+
+ /* Check result of operation */
+ if ((tail_pack[9] != 0x00U) || (tail_pack[10] != 0x01U))
+ {
+ hmmc->RPMBErrorCode |= tail_pack[9];
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+ }
+ else
+ {
+ hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
+ return HAL_ERROR;
+ }
+}
+
+/**
+ * @brief Allows to get the value of write counter within the RPMB partition.
+ * @param hmmc: Pointer to MMC handle
+ * @param pNonce: pointer to the value of nonce (16 bytes)
+ * @param Timeout: Specify timeout value
+ * @retval write counter value.
+ */
+uint32_t HAL_MMC_RPMB_GetWriteCounter(MMC_HandleTypeDef *hmmc, uint8_t *pNonce, uint32_t Timeout)
+{
+ SDMMC_DataInitTypeDef config;
+ uint32_t errorstate;
+ uint32_t tickstart = HAL_GetTick();
+ uint32_t count;
+ uint32_t byte_count = 0;
+ uint32_t data;
+ uint32_t dataremaining;
+ uint8_t tail_pack[12] = {0};
+ uint8_t zero_pack[4] = {0};
+ uint8_t echo_nonce[16] = {0};
+ uint8_t *tempbuff = zero_pack;
+
+ tail_pack[11] = 0x02;
+
+ if (NULL == pNonce)
+ {
+ hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
+ hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
+ return 0;
+ }
+
+ if (hmmc->State == HAL_MMC_STATE_READY)
+ {
+ hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
+ hmmc->State = HAL_MMC_STATE_BUSY;
+
+ /* Initialize data control register */
+ hmmc->Instance->DCTRL = 0U;
+
+ errorstate = SDMMC_CmdBlockCount(hmmc->Instance, 0x00000001U);
+ if (errorstate != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
+ return 0;
+ }
+
+ /* Send Request Packet */
+
+ /* Configure the MMC DPSM (Data Path State Machine) */
+ config.DataTimeOut = SDMMC_DATATIMEOUT;
+ config.DataLength = MMC_BLOCKSIZE;
+ config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
+ config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD;
+ config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
+ config.DPSM = SDMMC_DPSM_DISABLE;
+ (void)SDMMC_ConfigData(hmmc->Instance, &config);
+ __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
+
+ /* Write Blocks in Polling mode */
+ hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
+
+ /* Write Multi Block command */
+ errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, 0);
+
+ if (errorstate != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
+ return 0;
+ }
+
+ /* Write block(s) in polling mode */
+ dataremaining = config.DataLength;
+ while (!__HAL_MMC_GET_FLAG(hmmc,
+ SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
+ {
+ if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) && (dataremaining >= SDMMC_FIFO_SIZE))
+ {
+
+ /* Write data to SDMMC Tx FIFO */
+ for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
+ {
+ data = (uint32_t)(*tempbuff);
+ tempbuff++;
+ byte_count++;
+ data |= ((uint32_t)(*tempbuff) << 8U);
+ tempbuff++;
+ byte_count++;
+ data |= ((uint32_t)(*tempbuff) << 16U);
+ tempbuff++;
+ byte_count++;
+ data |= ((uint32_t)(*tempbuff) << 24U);
+ tempbuff++;
+ byte_count++;
+ (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
+ if (byte_count < MMC_RPMB_NONCE_POSITION)
+ {
+ tempbuff = zero_pack;
+ }
+ else if (byte_count == MMC_RPMB_NONCE_POSITION)
+ {
+ tempbuff = (uint8_t *)pNonce;
+ }
+ else if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
+ {
+ tempbuff = tail_pack;
+ }
+ else
+ {
+ /* Nothing to do */
+ }
+
+ }
+ dataremaining -= SDMMC_FIFO_SIZE;
+ }
+
+ if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U))
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
+ return 0;
+ }
+ }
+ __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
+
+ /* Read Response Packt */
+ errorstate = SDMMC_CmdBlockCount(hmmc->Instance, 0x00000001U);
+ if (errorstate != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
+ return 0;
+ }
+
+ /* Configure the MMC DPSM (Data Path State Machine) */
+ config.DataTimeOut = SDMMC_DATATIMEOUT;
+ config.DataLength = MMC_BLOCKSIZE;
+ config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
+ config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
+ config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
+ config.DPSM = SDMMC_DPSM_DISABLE;
+ (void)SDMMC_ConfigData(hmmc->Instance, &config);
+ __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
+
+ /* Write Blocks in Polling mode */
+ hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK;
+
+ /* Write Multi Block command */
+ errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, 0);
+
+ if (errorstate != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
+ return 0;
+ }
+
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
+ /* Poll on SDMMC flags */
+ tempbuff = zero_pack;
+
+ byte_count = 0;
+ dataremaining = config.DataLength;
+ while (!__HAL_MMC_GET_FLAG(hmmc,
+ SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
+ {
+ if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) && (dataremaining >= SDMMC_FIFO_SIZE))
+ {
+ /* Read data from SDMMC Rx FIFO */
+ for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
+ {
+ data = SDMMC_ReadFIFO(hmmc->Instance);
+ *tempbuff = (uint8_t)(data & 0xFFU);
+ tempbuff++;
+ byte_count++;
+ *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
+ tempbuff++;
+ byte_count++;
+ *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
+ tempbuff++;
+ byte_count++;
+ *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
+ tempbuff++;
+ byte_count++;
+ if (byte_count < MMC_RPMB_NONCE_POSITION)
+ {
+ tempbuff = zero_pack;
+ }
+ else if (byte_count == MMC_RPMB_NONCE_POSITION)
+ {
+ tempbuff = echo_nonce;
+ }
+ else if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
+ {
+ tempbuff = tail_pack;
+ }
+ else
+ {
+ /* Nothing to do */
+ }
+ }
+ dataremaining -= SDMMC_FIFO_SIZE;
+ }
+
+ if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U))
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
+ hmmc->State = HAL_MMC_STATE_READY;
+ hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
+ return 0;
+ }
+ }
+ __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
+
+ /* Get error state */
+ if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
+ hmmc->State = HAL_MMC_STATE_READY;
+ hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
+ return 0;
+ }
+ else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
+ hmmc->State = HAL_MMC_STATE_READY;
+ hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
+ return 0;
+ }
+ else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR))
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
+ hmmc->State = HAL_MMC_STATE_READY;
+ hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
+ return 0;
+ }
+ else
+ {
+ /* Nothing to do */
+ }
+
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
+
+ hmmc->State = HAL_MMC_STATE_READY;
+
+ for (uint8_t i = 0; i < 16U; i++)
+ {
+ if (pNonce[i] != echo_nonce[i])
+ {
+ hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
+ return 0;
+ }
+ }
+
+ return ((uint32_t)tail_pack[3] | ((uint32_t)tail_pack[2] << 8) | ((uint32_t)tail_pack[1] << 16) | \
+ ((uint32_t)tail_pack[0] << 24));
+ }
+ else
+ {
+ hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
+ hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
+ return 0;
+ }
+}
+
+/**
+ * @brief Allows to write block(s) to a specified address in the RPMB partition. The Data
+ * transfer is managed by polling mode.
+ * @param hmmc: Pointer to MMC handle
+ * @param pData: Pointer to the buffer that will contain the data to transmit
+ * @param BlockAdd: Block Address where data will be written
+ * @param NumberOfBlocks: Number of blocks to write
+ * @param pMAC: Pointer to the authentication MAC buffer
+ * @param Timeout: Specify timeout value
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_MMC_RPMB_WriteBlocks(MMC_HandleTypeDef *hmmc, const uint8_t *pData, uint16_t BlockAdd,
+ uint16_t NumberOfBlocks, const uint8_t *pMAC, uint32_t Timeout)
+{
+
+ SDMMC_DataInitTypeDef config;
+ uint32_t errorstate;
+ uint32_t tickstart = HAL_GetTick();
+ uint32_t count;
+ uint32_t byte_count = 0;
+ uint32_t data;
+ uint32_t dataremaining;
+ uint8_t tail_pack[12] = {0};
+ uint8_t zero_pack[4] = {0};
+ uint8_t echo_nonce[16] = {0};
+ const uint8_t local_nonce[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x00, 0x01, 0x02,
+ 0x03, 0x04, 0x00, 0x01, 0x02, 0x03, 0x04, 0x08
+ };
+ const uint8_t *rtempbuff;
+ uint8_t *tempbuff;
+ uint32_t arg = 0x80000000U;
+ uint32_t offset = 0;
+
+ if ((NumberOfBlocks != 0x1U) && (NumberOfBlocks != 0x2U) && (NumberOfBlocks != 0x20U))
+ {
+ hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
+ return HAL_ERROR;
+ }
+
+ if ((NULL == pData) || (NULL == pMAC))
+ {
+ hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
+ return HAL_ERROR;
+ }
+
+ tail_pack[11] = 0x02;
+
+ if (hmmc->State == HAL_MMC_STATE_READY)
+ {
+ hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
+ hmmc->State = HAL_MMC_STATE_BUSY;
+
+ /* Initialize data control register */
+ hmmc->Instance->DCTRL = 0U;
+
+ errorstate = SDMMC_CmdBlockCount(hmmc->Instance, 0x00000001U);
+ if (errorstate != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Send Request Packet */
+
+ /* Configure the MMC DPSM (Data Path State Machine) */
+ config.DataTimeOut = SDMMC_DATATIMEOUT;
+ config.DataLength = MMC_BLOCKSIZE;
+ config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
+ config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD;
+ config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
+ config.DPSM = SDMMC_DPSM_DISABLE;
+ (void)SDMMC_ConfigData(hmmc->Instance, &config);
+ __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
+
+ /* Write Blocks in Polling mode */
+ hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
+
+ /* Write Multi Block command */
+ errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, 0);
+
+ if (errorstate != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Write block(s) in polling mode */
+ rtempbuff = zero_pack;
+ dataremaining = config.DataLength;
+ while (!__HAL_MMC_GET_FLAG(hmmc,
+ SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
+ {
+ if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) && (dataremaining >= SDMMC_FIFO_SIZE))
+ {
+
+ /* Write data to SDMMC Tx FIFO */
+ for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
+ {
+ data = (uint32_t)(*rtempbuff);
+ rtempbuff++;
+ byte_count++;
+ data |= ((uint32_t)(*rtempbuff) << 8U);
+ rtempbuff++;
+ byte_count++;
+ data |= ((uint32_t)(*rtempbuff) << 16U);
+ rtempbuff++;
+ byte_count++;
+ data |= ((uint32_t)(*rtempbuff) << 24U);
+ rtempbuff++;
+ byte_count++;
+ (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
+ if (byte_count < MMC_RPMB_NONCE_POSITION)
+ {
+ rtempbuff = zero_pack;
+ }
+ else if (byte_count == MMC_RPMB_NONCE_POSITION)
+ {
+ rtempbuff = local_nonce;
+ }
+ else if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
+ {
+ rtempbuff = tail_pack;
+ }
+ else
+ {
+ /* Nothing to do */
+ }
+ }
+ dataremaining -= SDMMC_FIFO_SIZE;
+ }
+
+ if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U))
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_TIMEOUT;
+ }
+ }
+ __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
+
+ /* Read Response Packt */
+ errorstate = SDMMC_CmdBlockCount(hmmc->Instance, 0x00000001);
+ if (errorstate != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Configure the MMC DPSM (Data Path State Machine) */
+ config.DataTimeOut = SDMMC_DATATIMEOUT;
+ config.DataLength = MMC_BLOCKSIZE;
+ config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
+ config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
+ config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
+ config.DPSM = SDMMC_DPSM_DISABLE;
+ (void)SDMMC_ConfigData(hmmc->Instance, &config);
+ __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
+
+ /* Write Blocks in Polling mode */
+ hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK;
+
+ /* Write Multi Block command */
+ errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, 0);
+
+ if (errorstate != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
+ /* Poll on SDMMC flags */
+ tempbuff = zero_pack;
+
+ byte_count = 0;
+ dataremaining = config.DataLength;
+ while (!__HAL_MMC_GET_FLAG(hmmc,
+ SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
+ {
+ if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) && (dataremaining >= SDMMC_FIFO_SIZE))
+ {
+ /* Read data from SDMMC Rx FIFO */
+ for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
+ {
+ data = SDMMC_ReadFIFO(hmmc->Instance);
+ *tempbuff = (uint8_t)(data & 0xFFU);
+ tempbuff++;
+ byte_count++;
+ *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
+ tempbuff++;
+ byte_count++;
+ *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
+ tempbuff++;
+ byte_count++;
+ *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
+ tempbuff++;
+ byte_count++;
+ if (byte_count < MMC_RPMB_NONCE_POSITION)
+ {
+ tempbuff = zero_pack;
+ }
+ else if (byte_count == MMC_RPMB_NONCE_POSITION)
+ {
+ tempbuff = echo_nonce;
+ }
+ else if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
+ {
+ tempbuff = tail_pack;
+ }
+ else
+ {
+ /* Nothing to do */
+ }
+ }
+ dataremaining -= SDMMC_FIFO_SIZE;
+ }
+
+ if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U))
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_TIMEOUT;
+ }
+ }
+ __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
+
+ /* Get error state */
+ if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+ else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+ else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR))
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+ else
+ {
+ /* Nothing to do */
+ }
+
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
+
+ hmmc->State = HAL_MMC_STATE_READY;
+
+ for (uint8_t i = 0; i < 16U; i++)
+ {
+ if (local_nonce[i] != echo_nonce[i])
+ {
+ return HAL_ERROR;
+ }
+ }
+ }
+ else
+ {
+ hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
+ return HAL_ERROR;
+ }
+ tail_pack[11] = 0x03;
+ tail_pack[10] = 0x00;
+ tail_pack[7] = (uint8_t)(NumberOfBlocks) & 0xFFU;
+ tail_pack[6] = (uint8_t)(NumberOfBlocks >> 8) & 0xFFU;
+ tail_pack[5] = (uint8_t)(BlockAdd) & 0xFFU;
+ tail_pack[4] = (uint8_t)(BlockAdd >> 8) & 0xFFU;
+
+ rtempbuff = zero_pack;
+ byte_count = 0;
+ arg |= NumberOfBlocks;
+
+ if (hmmc->State == HAL_MMC_STATE_READY)
+ {
+ hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
+
+
+ hmmc->State = HAL_MMC_STATE_BUSY;
+
+ /* Initialize data control register */
+ hmmc->Instance->DCTRL = 0U;
+
+ errorstate = SDMMC_CmdBlockCount(hmmc->Instance, arg);
+ if (errorstate != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Send Request Packet */
+ /* Configure the MMC DPSM (Data Path State Machine) */
+ config.DataTimeOut = SDMMC_DATATIMEOUT;
+ config.DataLength = NumberOfBlocks * MMC_BLOCKSIZE;
+ config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
+ config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD;
+ config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
+ config.DPSM = SDMMC_DPSM_DISABLE;
+ (void)SDMMC_ConfigData(hmmc->Instance, &config);
+ __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
+
+ /* Write Blocks in Polling mode */
+
+ {
+ hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
+
+ /* Write Multi Block command */
+ errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, 0);
+ }
+
+ if (errorstate != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+
+
+ /* Write block(s) in polling mode */
+ dataremaining = config.DataLength;
+ while (!__HAL_MMC_GET_FLAG(hmmc,
+ SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
+ {
+ if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) && (dataremaining >= SDMMC_FIFO_SIZE))
+ {
+
+ /* Write data to SDMMC Tx FIFO */
+ for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
+ {
+ data = (uint32_t)(*rtempbuff);
+ rtempbuff++;
+ byte_count++;
+ data |= ((uint32_t)(*rtempbuff) << 8U);
+ rtempbuff++;
+ byte_count++;
+ data |= ((uint32_t)(*rtempbuff) << 16U);
+ rtempbuff++;
+ byte_count++;
+ data |= ((uint32_t)(*rtempbuff) << 24U);
+ rtempbuff++;
+ byte_count++;
+ (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
+ if (byte_count == MMC_RPMB_KEYMAC_POSITION)
+ {
+ rtempbuff = pMAC;
+ }
+ if (byte_count == MMC_RPMB_DATA_POSITION)
+ {
+ rtempbuff = &pData[offset];
+ }
+ if ((byte_count >= MMC_RPMB_NONCE_POSITION) && \
+ (byte_count < MMC_RPMB_WRITE_COUNTER_POSITION))
+ {
+ rtempbuff = zero_pack;
+ }
+ if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
+ {
+ rtempbuff = tail_pack;
+ }
+ else if (byte_count == MMC_BLOCKSIZE)
+ {
+ offset += (uint32_t)256U;
+ byte_count = 0;
+ }
+ else
+ {
+ /* Nothing to do */
+ }
+ }
+ dataremaining -= SDMMC_FIFO_SIZE;
+ }
+
+ if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U))
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_TIMEOUT;
+ }
+ }
+ __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
+
+ /* Response Packet */
+
+ errorstate = SDMMC_CmdBlockCount(hmmc->Instance, arg);
+ if (errorstate != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Configure the MMC DPSM (Data Path State Machine) */
+ config.DataTimeOut = SDMMC_DATATIMEOUT;
+ config.DataLength = MMC_BLOCKSIZE;
+ config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
+ config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
+ config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
+ config.DPSM = SDMMC_DPSM_DISABLE;
+ (void)SDMMC_ConfigData(hmmc->Instance, &config);
+ __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
+
+ /* Write Blocks in Polling mode */
+
+ {
+ hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK;
+
+ /* Write Multi Block command */
+ errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, 0);
+ }
+
+ if (errorstate != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+
+
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
+ /* Poll on SDMMC flags */
+ tempbuff = zero_pack;
+ byte_count = 0;
+ dataremaining = config.DataLength;
+ while (!__HAL_MMC_GET_FLAG(hmmc,
+ SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
+ {
+ if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) && (dataremaining >= SDMMC_FIFO_SIZE))
+ {
+ /* Read data from SDMMC Rx FIFO */
+ for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
+ {
+ data = SDMMC_ReadFIFO(hmmc->Instance);
+ *tempbuff = (uint8_t)(data & 0xFFU);
+ tempbuff++;
+ byte_count++;
+ *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
+ tempbuff++;
+ byte_count++;
+ *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
+ tempbuff++;
+ byte_count++;
+ *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
+ tempbuff++;
+ byte_count++;
+ if (byte_count < MMC_RPMB_WRITE_COUNTER_POSITION)
+ {
+ tempbuff = zero_pack;
+ }
+ else if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
+ {
+ tempbuff = tail_pack;
+ }
+ else
+ {
+ /* Nothing to do */
+ }
+ }
+ dataremaining -= SDMMC_FIFO_SIZE;
+ }
+
+ if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U))
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_TIMEOUT;
+ }
+ }
+ __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
+
+ /* Get error state */
+ if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+ else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+ else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR))
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+ else
+ {
+ /* Nothing to do */
+ }
+
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
+
+ hmmc->State = HAL_MMC_STATE_READY;
+
+ /* Check result of operation */
+ if (((tail_pack[9] & (uint8_t)0xFEU) != 0x00U) || (tail_pack[10] != 0x03U))
+ {
+ hmmc->RPMBErrorCode |= tail_pack[9];
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+ }
+ else
+ {
+ hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
+ return HAL_ERROR;
+ }
+}
+
+/**
+ * @brief Allows to read block(s) to a specified address in the RPMB partition. The Data
+ * transfer is managed by polling mode.
+ * @param hmmc: Pointer to MMC handle
+ * @param pData: Pointer to the buffer that will contain the data to transmit
+ * @param BlockAdd: Block Address where data will be written
+ * @param NumberOfBlocks: Number of blocks to write
+ * @param pNonce: Pointer to the buffer that will contain the nonce to transmit
+ * @param pMAC: Pointer to the authentication MAC buffer
+ * @param Timeout: Specify timeout value
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_MMC_RPMB_ReadBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint16_t BlockAdd,
+ uint16_t NumberOfBlocks, const uint8_t *pNonce, uint8_t *pMAC,
+ uint32_t Timeout)
+{
+ SDMMC_DataInitTypeDef config;
+ uint32_t errorstate;
+ uint32_t tickstart = HAL_GetTick();
+ uint32_t count;
+ uint32_t byte_count = 0;
+ uint32_t data;
+ uint8_t tail_pack[12] = {0};
+ uint8_t zero_pack[4] = {0};
+ uint8_t echo_nonce[16] = {0};
+ uint32_t dataremaining;
+ const uint8_t *rtempbuff;
+ uint8_t *tempbuff;
+ uint32_t arg = 0;
+ uint32_t offset = 0;
+
+ arg |= NumberOfBlocks;
+
+ tail_pack[11] = 0x04;
+ tail_pack[10] = 0x00;
+ tail_pack[7] = 0x00;
+ tail_pack[6] = 0x00;
+ tail_pack[5] = (uint8_t)(BlockAdd) & 0xFFU;
+ tail_pack[4] = (uint8_t)(BlockAdd >> 8) & 0xFFU;
+ tail_pack[3] = 0x00;
+ tail_pack[2] = 0x00;
+ tail_pack[1] = 0x00;
+ tail_pack[0] = 0x00;
+
+ if (hmmc->State == HAL_MMC_STATE_READY)
+ {
+ hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
+ hmmc->State = HAL_MMC_STATE_BUSY;
+
+ /* Initialize data control register */
+ hmmc->Instance->DCTRL = 0U;
+
+ errorstate = SDMMC_CmdBlockCount(hmmc->Instance, 1);
+ if (errorstate != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Send Request Packet */
+
+ /* Configure the MMC DPSM (Data Path State Machine) */
+ config.DataTimeOut = SDMMC_DATATIMEOUT;
+ config.DataLength = MMC_BLOCKSIZE;
+ config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
+ config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD;
+ config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
+ config.DPSM = SDMMC_DPSM_DISABLE;
+ (void)SDMMC_ConfigData(hmmc->Instance, &config);
+ __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
+
+ /* Write Blocks in Polling mode */
+ hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
+
+ /* Write Multi Block command */
+ errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, 0);
+
+ if (errorstate != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Write block(s) in polling mode */
+ rtempbuff = zero_pack;
+ dataremaining = config.DataLength;
+ while (!__HAL_MMC_GET_FLAG(hmmc,
+ SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
+ {
+ if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) && (dataremaining >= SDMMC_FIFO_SIZE))
+ {
+
+ /* Write data to SDMMC Tx FIFO */
+ for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
+ {
+ data = (uint32_t)(*rtempbuff);
+ rtempbuff++;
+ byte_count++;
+ data |= ((uint32_t)(*rtempbuff) << 8U);
+ rtempbuff++;
+ byte_count++;
+ data |= ((uint32_t)(*rtempbuff) << 16U);
+ rtempbuff++;
+ byte_count++;
+ data |= ((uint32_t)(*rtempbuff) << 24U);
+ rtempbuff++;
+ byte_count++;
+ (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
+ if (byte_count < MMC_RPMB_NONCE_POSITION)
+ {
+ rtempbuff = zero_pack;
+ }
+ else if (byte_count == MMC_RPMB_NONCE_POSITION)
+ {
+ rtempbuff = pNonce;
+ }
+ else if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
+ {
+ rtempbuff = tail_pack;
+ }
+ else
+ {
+ /* Nothing to do */
+ }
+ }
+ dataremaining -= SDMMC_FIFO_SIZE;
+ }
+
+ if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U))
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_TIMEOUT;
+ }
+ }
+ __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
+
+ /* Read Response Packet */
+ errorstate = SDMMC_CmdBlockCount(hmmc->Instance, arg);
+ if (errorstate != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Configure the MMC DPSM (Data Path State Machine) */
+ config.DataTimeOut = SDMMC_DATATIMEOUT;
+ config.DataLength = NumberOfBlocks * MMC_BLOCKSIZE;
+ config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
+ config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
+ config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
+ config.DPSM = SDMMC_DPSM_DISABLE;
+ (void)SDMMC_ConfigData(hmmc->Instance, &config);
+ __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
+
+ /* Write Blocks in Polling mode */
+ hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK;
+
+ /* Write Multi Block command */
+ errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, 0);
+
+ if (errorstate != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
+ /* Poll on SDMMC flags */
+ tempbuff = zero_pack;
+ byte_count = 0;
+
+ dataremaining = config.DataLength;
+ while (!__HAL_MMC_GET_FLAG(hmmc,
+ SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
+ {
+ if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) && (dataremaining >= SDMMC_FIFO_SIZE))
+ {
+ /* Read data from SDMMC Rx FIFO */
+ for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
+ {
+ data = SDMMC_ReadFIFO(hmmc->Instance);
+ *tempbuff = (uint8_t)(data & 0xFFU);
+ tempbuff++;
+ byte_count++;
+ *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
+ tempbuff++;
+ byte_count++;
+ *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
+ tempbuff++;
+ byte_count++;
+ *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
+ tempbuff++;
+ byte_count++;
+ if (byte_count < MMC_RPMB_KEYMAC_POSITION)
+ {
+ tempbuff = zero_pack;
+ }
+ else if (byte_count == MMC_RPMB_KEYMAC_POSITION)
+ {
+ tempbuff = (uint8_t *)pMAC;
+ }
+ else if (byte_count == MMC_RPMB_DATA_POSITION)
+ {
+ tempbuff = &pData[offset];
+ }
+ else if (byte_count == MMC_RPMB_NONCE_POSITION)
+ {
+ tempbuff = echo_nonce;
+ }
+ else if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
+ {
+ tempbuff = tail_pack;
+ }
+ else if (byte_count == MMC_BLOCKSIZE)
+ {
+ byte_count = 0;
+ offset += (uint32_t)256U;
+ }
+ else
+ {
+ /* Nothing to do */
+ }
+ }
+ dataremaining -= SDMMC_FIFO_SIZE;
+ }
+
+ if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U))
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_TIMEOUT;
+ }
+ }
+ __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
+
+ /* Get error state */
+ if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+ else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+ else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR))
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
+ hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+ else
+ {
+ /* Nothing to do */
+ }
+
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
+
+ hmmc->State = HAL_MMC_STATE_READY;
+
+ for (uint8_t i = 0; i < 16U; i++)
+ {
+ if (pNonce[i] != echo_nonce[i])
+ {
+ return HAL_ERROR;
+ }
+ }
+
+ /* Check result of operation */
+ if ((tail_pack[9] != 0x00U) || (tail_pack[10] != 0x04U))
+ {
+ hmmc->RPMBErrorCode |= tail_pack[9];
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+ }
+ else
+ {
+ hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
+ return HAL_ERROR;
+ }
+}
+
+
/**
* @brief Read DMA Linked list node Transfer completed callbacks
* @param hmmc: MMC handle
diff --git a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_mmc_ex.c b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_mmc_ex.c
index a40a12bfee..14b601220c 100644
--- a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_mmc_ex.c
+++ b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_mmc_ex.c
@@ -60,7 +60,6 @@
*/
-
/** @addtogroup MMCEx_Exported_Functions_Group1
* @brief Linked List management functions
*
@@ -218,7 +217,8 @@ HAL_StatusTypeDef HAL_MMCEx_DMALinkedList_DisableCircularMode(MMC_DMALinkedListT
* @param NumberOfBlocks: Total number of blocks to read
* @retval HAL status
*/
-HAL_StatusTypeDef HAL_MMCEx_DMALinkedList_ReadBlocks(MMC_HandleTypeDef *hmmc, MMC_DMALinkedListTypeDef *pLinkedList,
+HAL_StatusTypeDef HAL_MMCEx_DMALinkedList_ReadBlocks(MMC_HandleTypeDef *hmmc,
+ const MMC_DMALinkedListTypeDef *pLinkedList,
uint32_t BlockAdd, uint32_t NumberOfBlocks)
{
SDMMC_DataInitTypeDef config;
@@ -327,7 +327,8 @@ HAL_StatusTypeDef HAL_MMCEx_DMALinkedList_ReadBlocks(MMC_HandleTypeDef *hmmc, MM
* @param NumberOfBlocks: Total number of blocks to read
* @retval HAL status
*/
-HAL_StatusTypeDef HAL_MMCEx_DMALinkedList_WriteBlocks(MMC_HandleTypeDef *hmmc, MMC_DMALinkedListTypeDef *pLinkedList,
+HAL_StatusTypeDef HAL_MMCEx_DMALinkedList_WriteBlocks(MMC_HandleTypeDef *hmmc,
+ const MMC_DMALinkedListTypeDef *pLinkedList,
uint32_t BlockAdd, uint32_t NumberOfBlocks)
{
SDMMC_DataInitTypeDef config;
@@ -427,7 +428,6 @@ HAL_StatusTypeDef HAL_MMCEx_DMALinkedList_WriteBlocks(MMC_HandleTypeDef *hmmc, M
}
-
/**
* @}
*/
diff --git a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_pcd.c b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_pcd.c
index b1f98c349e..bc69dacfb6 100644
--- a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_pcd.c
+++ b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_pcd.c
@@ -1485,7 +1485,7 @@ void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
if ((hpcd->OUT_ep[epnum].type == EP_TYPE_ISOC) &&
((RegVal & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA) &&
- ((RegVal & (0x1U << 16)) == (hpcd->FrameNumber & 0x1U)))
+ (((RegVal & (0x1U << 16)) >> 16U) == (hpcd->FrameNumber & 0x1U)))
{
hpcd->OUT_ep[epnum].is_iso_incomplete = 1U;
@@ -2301,6 +2301,7 @@ HAL_StatusTypeDef HAL_PCD_SetTestMode(const PCD_HandleTypeDef *hpcd, uint8_t tes
case TEST_SE0_NAK:
case TEST_PACKET:
case TEST_FORCE_EN:
+ USBx_DEVICE->DCTL &= ~(0x7U << 4);
USBx_DEVICE->DCTL |= (uint32_t)testmode << 4;
break;
@@ -2602,6 +2603,18 @@ static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd)
/* Get SETUP Packet */
ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
+ if (ep->xfer_count != 8U)
+ {
+ /* Set Stall condition for EP0 IN/OUT */
+ PCD_SET_EP_RX_STATUS(hpcd->Instance, PCD_ENDP0, USB_EP_RX_STALL);
+ PCD_SET_EP_TX_STATUS(hpcd->Instance, PCD_ENDP0, USB_EP_TX_STALL);
+
+ /* SETUP bit kept frozen while CTR_RX = 1 */
+ PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
+
+ return HAL_OK;
+ }
+
USB_ReadPMA(hpcd->Instance, (uint8_t *)hpcd->Setup,
ep->pmaadress, (uint16_t)ep->xfer_count);
@@ -2622,27 +2635,27 @@ static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd)
/* Get Control Data OUT Packet */
ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
- if ((ep->xfer_count != 0U) && (ep->xfer_buff != 0U))
+ if (ep->xfer_count == 0U)
{
- USB_ReadPMA(hpcd->Instance, ep->xfer_buff,
- ep->pmaadress, (uint16_t)ep->xfer_count);
+ /* Status phase re-arm for next setup */
+ PCD_SET_EP_RX_STATUS(hpcd->Instance, PCD_ENDP0, USB_EP_RX_VALID);
+ }
+ else
+ {
+ if (ep->xfer_buff != 0U)
+ {
+ USB_ReadPMA(hpcd->Instance, ep->xfer_buff,
+ ep->pmaadress, (uint16_t)ep->xfer_count); /* max 64bytes */
- ep->xfer_buff += ep->xfer_count;
+ ep->xfer_buff += ep->xfer_count;
- /* Process Control Data OUT Packet */
+ /* Process Control Data OUT Packet */
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
- hpcd->DataOutStageCallback(hpcd, 0U);
+ hpcd->DataOutStageCallback(hpcd, 0U);
#else
- HAL_PCD_DataOutStageCallback(hpcd, 0U);
+ HAL_PCD_DataOutStageCallback(hpcd, 0U);
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
- }
-
- wEPVal = (uint16_t)PCD_GET_ENDPOINT(hpcd->Instance, PCD_ENDP0);
-
- if (((wEPVal & USB_EP_SETUP) == 0U) && ((wEPVal & USB_EP_RX_STRX) != USB_EP_RX_VALID))
- {
- PCD_SET_EP_RX_CNT(hpcd->Instance, PCD_ENDP0, ep->maxpacket);
- PCD_SET_EP_RX_STATUS(hpcd->Instance, PCD_ENDP0, USB_EP_RX_VALID);
+ }
}
}
}
@@ -2708,7 +2721,6 @@ static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd)
/* multi-packet on the NON control OUT endpoint */
ep->xfer_count += count;
- ep->xfer_buff += count;
if ((ep->xfer_len == 0U) || (count < ep->maxpacket))
{
@@ -2721,6 +2733,7 @@ static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd)
}
else
{
+ ep->xfer_buff += count;
(void)USB_EPStartXfer(hpcd->Instance, ep);
}
}
@@ -2762,7 +2775,7 @@ static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd)
/* Manage Single Buffer Transaction */
if ((wEPVal & USB_EP_KIND) == 0U)
{
- /* multi-packet on the NON control IN endpoint */
+ /* Multi-packet on the NON control IN endpoint */
TxPctSize = (uint16_t)PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
if (ep->xfer_len > TxPctSize)
@@ -2838,7 +2851,7 @@ static uint16_t HAL_PCD_EP_DB_Receive(PCD_HandleTypeDef *hpcd,
if (ep->xfer_len == 0U)
{
- /* set NAK to OUT endpoint since double buffer is enabled */
+ /* Set NAK to OUT endpoint since double buffer is enabled */
PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_NAK);
}
@@ -2870,11 +2883,11 @@ static uint16_t HAL_PCD_EP_DB_Receive(PCD_HandleTypeDef *hpcd,
if (ep->xfer_len == 0U)
{
- /* set NAK on the current endpoint */
+ /* Set NAK on the current endpoint */
PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_NAK);
}
- /*Need to FreeUser Buffer*/
+ /* Need to FreeUser Buffer */
if ((wEPVal & USB_EP_DTOG_TX) == 0U)
{
PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 0U);
@@ -2924,6 +2937,12 @@ static HAL_StatusTypeDef HAL_PCD_EP_DB_Transmit(PCD_HandleTypeDef *hpcd,
PCD_SET_EP_DBUF0_CNT(hpcd->Instance, ep->num, ep->is_in, 0U);
PCD_SET_EP_DBUF1_CNT(hpcd->Instance, ep->num, ep->is_in, 0U);
+ if (ep->type == EP_TYPE_BULK)
+ {
+ /* Set Bulk endpoint in NAK state */
+ PCD_SET_EP_TX_STATUS(hpcd->Instance, ep->num, USB_EP_TX_NAK);
+ }
+
/* TX COMPLETE */
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
hpcd->DataInStageCallback(hpcd, ep->num);
@@ -2935,10 +2954,12 @@ static HAL_StatusTypeDef HAL_PCD_EP_DB_Transmit(PCD_HandleTypeDef *hpcd,
{
PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 1U);
}
+
+ return HAL_OK;
}
else /* Transfer is not yet Done */
{
- /* need to Free USB Buff */
+ /* Need to Free USB Buffer */
if ((wEPVal & USB_EP_DTOG_RX) != 0U)
{
PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 1U);
@@ -2969,7 +2990,7 @@ static HAL_StatusTypeDef HAL_PCD_EP_DB_Transmit(PCD_HandleTypeDef *hpcd,
}
/* Write remaining Data to Buffer */
- /* Set the Double buffer counter for pma buffer1 */
+ /* Set the Double buffer counter for pma buffer0 */
PCD_SET_EP_DBUF0_CNT(hpcd->Instance, ep->num, ep->is_in, len);
/* Copy user buffer to USB PMA */
@@ -2997,6 +3018,12 @@ static HAL_StatusTypeDef HAL_PCD_EP_DB_Transmit(PCD_HandleTypeDef *hpcd,
PCD_SET_EP_DBUF0_CNT(hpcd->Instance, ep->num, ep->is_in, 0U);
PCD_SET_EP_DBUF1_CNT(hpcd->Instance, ep->num, ep->is_in, 0U);
+ if (ep->type == EP_TYPE_BULK)
+ {
+ /* Set Bulk endpoint in NAK state */
+ PCD_SET_EP_TX_STATUS(hpcd->Instance, ep->num, USB_EP_TX_NAK);
+ }
+
/* TX COMPLETE */
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
hpcd->DataInStageCallback(hpcd, ep->num);
@@ -3009,10 +3036,12 @@ static HAL_StatusTypeDef HAL_PCD_EP_DB_Transmit(PCD_HandleTypeDef *hpcd,
{
PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 1U);
}
+
+ return HAL_OK;
}
else /* Transfer is not yet Done */
{
- /* need to Free USB Buff */
+ /* Need to Free USB Buffer */
if ((wEPVal & USB_EP_DTOG_RX) == 0U)
{
PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 1U);
@@ -3042,7 +3071,7 @@ static HAL_StatusTypeDef HAL_PCD_EP_DB_Transmit(PCD_HandleTypeDef *hpcd,
ep->xfer_fill_db = 0;
}
- /* Set the Double buffer counter for pmabuffer1 */
+ /* Set the Double buffer counter for pma buffer1 */
PCD_SET_EP_DBUF1_CNT(hpcd->Instance, ep->num, ep->is_in, len);
/* Copy the user buffer to USB PMA */
@@ -3051,7 +3080,7 @@ static HAL_StatusTypeDef HAL_PCD_EP_DB_Transmit(PCD_HandleTypeDef *hpcd,
}
}
- /*enable endpoint IN*/
+ /* Enable endpoint IN */
PCD_SET_EP_TX_STATUS(hpcd->Instance, ep->num, USB_EP_TX_VALID);
return HAL_OK;
diff --git a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_rcc_ex.c b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_rcc_ex.c
index 84eb931fe2..71a018305c 100644
--- a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_rcc_ex.c
+++ b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_rcc_ex.c
@@ -141,6 +141,7 @@ static HAL_StatusTypeDef RCCEx_PLL3_Config(const RCC_PLL3InitTypeDef *Pll3);
* @arg @ref RCC_PERIPHCLK_LPTIM6 LPTIM6 peripheral clock (*)
* @arg @ref RCC_PERIPHCLK_DAC_LP DAC peripheral low-power clock
* @arg @ref RCC_PERIPHCLK_TIM TIM peripheral clock
+ * @arg @ref RCC_PERIPHCLK_ETH ETH peripheral clock
*
* @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
* the RTC clock source: in this case the access to Backup domain is enabled.
diff --git a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sd.c b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sd.c
index a2bfe629b0..d4ef96223f 100644
--- a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sd.c
+++ b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sd.c
@@ -2120,7 +2120,7 @@ HAL_StatusTypeDef HAL_SD_UnRegisterTransceiverCallback(SD_HandleTypeDef *hsd)
* contains all CID register parameters
* @retval HAL status
*/
-HAL_StatusTypeDef HAL_SD_GetCardCID(SD_HandleTypeDef *hsd, HAL_SD_CardCIDTypeDef *pCID)
+HAL_StatusTypeDef HAL_SD_GetCardCID(const SD_HandleTypeDef *hsd, HAL_SD_CardCIDTypeDef *pCID)
{
pCID->ManufacturerID = (uint8_t)((hsd->CID[0] & 0xFF000000U) >> 24U);
@@ -2336,7 +2336,7 @@ HAL_StatusTypeDef HAL_SD_GetCardStatus(SD_HandleTypeDef *hsd, HAL_SD_CardStatusT
* will contain the SD card status information
* @retval HAL status
*/
-HAL_StatusTypeDef HAL_SD_GetCardInfo(SD_HandleTypeDef *hsd, HAL_SD_CardInfoTypeDef *pCardInfo)
+HAL_StatusTypeDef HAL_SD_GetCardInfo(const SD_HandleTypeDef *hsd, HAL_SD_CardInfoTypeDef *pCardInfo)
{
pCardInfo->CardType = (uint32_t)(hsd->SdCard.CardType);
pCardInfo->CardVersion = (uint32_t)(hsd->SdCard.CardVersion);
diff --git a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sd_ex.c b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sd_ex.c
index 7689a0b70c..96d7ef5491 100644
--- a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sd_ex.c
+++ b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sd_ex.c
@@ -196,7 +196,8 @@ HAL_StatusTypeDef HAL_SDEx_DMALinkedList_DisableCircularMode(SD_DMALinkedListTyp
* @param NumberOfBlocks: Total number of blocks to read
* @retval HAL status
*/
-HAL_StatusTypeDef HAL_SDEx_DMALinkedList_ReadBlocks(SD_HandleTypeDef *hsd, SDMMC_DMALinkedListTypeDef *pLinkedList,
+HAL_StatusTypeDef HAL_SDEx_DMALinkedList_ReadBlocks(SD_HandleTypeDef *hsd,
+ const SDMMC_DMALinkedListTypeDef *pLinkedList,
uint32_t BlockAdd, uint32_t NumberOfBlocks)
{
SDMMC_DataInitTypeDef config;
@@ -290,7 +291,8 @@ HAL_StatusTypeDef HAL_SDEx_DMALinkedList_ReadBlocks(SD_HandleTypeDef *hsd, SDMMC
* @param NumberOfBlocks: Total number of blocks to read
* @retval HAL status
*/
-HAL_StatusTypeDef HAL_SDEx_DMALinkedList_WriteBlocks(SD_HandleTypeDef *hsd, SDMMC_DMALinkedListTypeDef *pLinkedList,
+HAL_StatusTypeDef HAL_SDEx_DMALinkedList_WriteBlocks(SD_HandleTypeDef *hsd,
+ const SDMMC_DMALinkedListTypeDef *pLinkedList,
uint32_t BlockAdd, uint32_t NumberOfBlocks)
{
diff --git a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sdio.c b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sdio.c
new file mode 100644
index 0000000000..b0d2bd1acb
--- /dev/null
+++ b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sdio.c
@@ -0,0 +1,2900 @@
+/**
+ ******************************************************************************
+ * @file stm32h5xx_hal_sdio.c
+ * @author MCD Application Team
+ * @brief SDIO HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the Secure Digital Input Output (SDIO) peripheral:
+ * + Initialization and de-initialization functions
+ * + IO operation functions
+ * + Peripheral Control functions
+ * + Peripheral State functions
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2023 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ This driver implements a high level communication layer for read and write from/to
+ this SDIO card. The needed STM32 hardware resources (SDMMC and GPIO) are performed by
+ the user in HAL_SDIO_MspInit() function (MSP layer).
+ Basically, the MSP layer configuration should be the same as we provide in the
+ examples.
+ You can easily tailor this configuration according to hardware resources.
+
+ [..]
+ This driver is a generic layered driver for SDMMC memories which uses the HAL
+ SDMMC driver functions to interface with SDIO cards devices.
+ It is used as follows:
+
+ (#)Initialize the SDMMC low level resources by implementing the HAL_SDIO_MspInit() API:
+ (##) Enable the SDMMC interface clock using __HAL_RCC_SDMMC_CLK_ENABLE();
+ (##) SDMMC pins configuration for SDIO card
+ (+++) Enable the clock for the SDMMC GPIOs using the functions __HAL_RCC_GPIOx_CLK_ENABLE();
+ (+++) Configure these SDMMC pins as alternate function pull-up using HAL_GPIO_Init()
+ and according to your pin assignment;
+ (##) NVIC configuration if you need to use interrupt process (HAL_SDIO_ReadExtended_DMA()
+ and HAL_SDIO_WriteExtended_DMA() APIs).
+ (+++) Configure the SDMMC interrupt priorities using function HAL_NVIC_SetPriority();
+ (+++) Enable the NVIC SDMMC IRQs using function HAL_NVIC_EnableIRQ()
+ (+++) SDMMC interrupts are managed using the macros __HAL_SDIO_ENABLE_IT()
+ and __HAL_SDIO_DISABLE_IT() inside the communication process.
+ (+++) SDMMC interrupts pending bits are managed using the macros __HAL_SDIO_GET_IT().
+ (##) No general propose DMA Configuration is needed, an Internal DMA for SDMMC Peripheral are used.
+
+ (#) At this stage, you can perform SDIO read/write/erase operations after SDIO card initialization.
+
+ *** SDIO Card Initialization and configuration ***
+ ================================================
+ [..]
+ To initialize the SDIO Card, use the HAL_SDIO_Init() function. It Initializes
+ SDMMC Peripheral(STM32 side) and the SDIO Card, and put it into StandBy State (Ready for data transfer).
+ This function provide the following operations:
+
+ (#) Apply the SDIO Card initialization process at 400KHz. You can change or adapt this
+ frequency by adjusting the "ClockDiv" field.
+ The SDIO Card frequency (SDMMC_CK) is computed as follows:
+
+ SDMMC_CK = SDMMCCLK / (2 * ClockDiv)
+
+ In initialization mode and according to the SDIO Card standard,
+ make sure that the SDMMC_CK frequency doesn't exceed 400KHz.
+
+ This phase of initialization is done through SDMMC_Init() and
+ SDMMC_PowerState_ON() SDMMC low level APIs.
+
+ (#) Initialize the SDIO card. The API used is HAL_SDIO_Init().
+ This phase allows the card initialization and identification.
+
+ (#) Configure the SDIO Card Data transfer frequency. You can change or adapt this
+ frequency by adjusting the "ClockDiv" field by the API HAL_SDIO_ConfigFrequency().
+
+ (#) Configure the SDIO Card in wide bus mode: 4-bits data by the API HAL_SDIO_SetDataBusWidth().
+
+ (#) Configure the SDIO Card data block size by the API : HAL_SDIO_SetBlockSize().
+
+ (#) Configure the SDIO Card speed mode by the API : HAL_SDIO_SetSpeedMode().
+
+ (#) To custumize the SDIO Init card function for the enumeration card sequence, you can register a user callback
+ function by calling the HAL_SDIO_RegisterIdentifyCardCallback before the HAL_SDIO_Init() function.
+
+ *** SDIO Card Read operation ***
+ ==============================
+ [..]
+ (+) You can read from SDIO card in polling mode by using function HAL_SDIO_ReadExtended().
+ This function support only 2048-bytes block length (the block size should be
+ chosen by using the API HAL_SDIO_SetBlockSize).
+
+ (+) You can read from SDIO card in DMA mode by using function HAL_SDIO_ReadExtended_DMA().
+ This function support only 2048-bytes block length (the block size should be
+ chosen by using the API HAL_SDIO_SetBlockSize).
+ After this, you have to ensure that the transfer is done correctly.
+ You could also check the DMA transfer process through the SDIO Rx interrupt event.
+
+ *** SDIO Card Write operation ***
+ ===============================
+ [..]
+ (+) You can write to SDIO card in polling mode by using function HAL_SDIO_WriteExtended().
+ This function support only 2048-bytes block length (the block size should be
+ chosen by using the API HAL_SDIO_SetBlockSize).
+
+ (+) You can write to SDIO card in DMA mode by using function HAL_SDIO_WriteExtended_DMA().
+ This function support only 2048-bytes block length (the block size should be
+ chosen by using the API HAL_SDIO_SetBlockSize).
+ You could also check the DMA transfer process through the SDIO Tx interrupt event.
+
+
+ *** SDIO card common control register (CCCR) ***
+ ======================
+ [..]
+ (+) The SDIO CCCR allow for quick host checking and control of an IO card's enable and interrupts on a per card and
+ per function basis.
+ To get the Card common control registers field, you can use the API HAL_SDIO_GetCardCommonControlRegister().
+
+ *** SDIO card Function basic register (FBR) ***
+ ===========================
+ [..]
+ (+) The SDIO card function basic register are used to allow the host to quickly determine the abilities and
+ requirements of each function.
+ (+) To get the SDIO function basic register information, you can use the API HAL_SDIO_GetCardFBRRegister().
+
+ *** SDIO HAL driver macros list ***
+ ==================================
+ [..]
+ Below the list of most used macros in SDIO HAL driver.
+
+ (+) __HAL_SDIO_ENABLE_IT: Enable the SDIO device interrupt
+ (+) __HAL_SDIO_DISABLE_IT: Disable the SDIO device interrupt
+ (+) __HAL_SDIO_GET_FLAG: Check whether the specified SDIO flag is set or not
+ (+) __HAL_SDIO_CLEAR_FLAG: Clear the SDIO's pending flags
+ (+) __HAL_SDIO_GET_IT: Check whether the specified SDIO interrupt has occurred or not
+ (+) __HAL_SDIO_GET_IT_SOURCE: Checks whether the specified SDIO interrupt is enabled or not
+
+ (@) You can refer to the SDIO HAL driver header file for more useful macros
+
+ *** Callback registration ***
+ =============================================
+ [..]
+ The compilation define USE_HAL_SDIO_REGISTER_CALLBACKS when set to 1
+ allows the user to configure dynamically the driver callbacks.
+
+ Use Functions HAL_SDIO_RegisterCallback() to register a user callback,
+ it allows to register following callbacks:
+ (+) TxCpltCallback : callback when a transmission transfer is completed.
+ (+) RxCpltCallback : callback when a reception transfer is completed.
+ (+) ErrorCallback : callback when error occurs.
+ (+) MspInitCallback : SDIO MspInit.
+ (+) MspDeInitCallback : SDIO MspDeInit.
+ This function takes as parameters the HAL peripheral handle, the Callback ID
+ and a pointer to the user callback function.
+ For specific callbacks TransceiverCallback use dedicated register callbacks:
+ respectively HAL_SDIO_RegisterTransceiverCallback().
+
+ Use function HAL_SDIO_UnRegisterCallback() to reset a callback to the default
+ weak (overridden) function. It allows to reset following callbacks:
+ (+) TxCpltCallback : callback when a transmission transfer is completed.
+ (+) RxCpltCallback : callback when a reception transfer is completed.
+ (+) ErrorCallback : callback when error occurs.
+ (+) MspInitCallback : SDIO MspInit.
+ (+) MspDeInitCallback : SDIO MspDeInit.
+ This function) takes as parameters the HAL peripheral handle and the Callback ID.
+ For specific callbacks TransceiverCallback use dedicated unregister callbacks:
+ respectively HAL_SDIO_UnRegisterTransceiverCallback().
+
+ By default, after the HAL_SDIO_Init and if the state is HAL_SDIO_STATE_RESET
+ all callbacks are reset to the corresponding legacy weak (overridden) functions.
+ Exception done for MspInit and MspDeInit callbacks that are respectively
+ reset to the legacy weak (overridden) functions in the HAL_SDIO_Init
+ and HAL_SDIO_DeInit only when these callbacks are null (not registered beforehand).
+ If not, MspInit or MspDeInit are not null, the HAL_SDIO_Init and HAL_SDIO_DeInit
+ keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
+
+ Callbacks can be registered/unregistered in READY state only.
+ Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
+ in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
+ during the Init/DeInit.
+ In that case first register the MspInit/MspDeInit user callbacks
+ using HAL_SDIO_RegisterCallback before calling HAL_SDIO_DeInit
+ or HAL_SDIO_Init function.
+
+ When The compilation define USE_HAL_SDIO_REGISTER_CALLBACKS is set to 0 or
+ not defined, the callback registering feature is not available
+ and weak (overridden) callbacks are used.
+
+ *** SDIO peripheral IO interrupt ***
+ =============================================
+ [..]
+ (+) Below the list of most used SDIO function to check and control the IO card's enable and interrupts on a per
+ functions basis.
+
+ (+) HAL_SDIO_EnableIOFunctionInterrupt: Enable SDIO IO interrupt.
+ (+) HAL_SDIO_DisableIOFunctionInterrupt: Disable SDIO IO interrupt.
+ (+) HAL_SDIO_EnableIOFunction: Enable Function number(0-7)
+ (+) HAL_SDIO_DisableIOFunction: Disable Function number(0-7)
+ (+) HAL_SDIO_SelectIOFunction: Select a function number(0-7)
+ (+) HAL_SDIO_AbortIOFunction: Abort an IO read or write operation and free the SDIO bus.
+ (+) HAL_SDIO_EnableIOAsynInterrupt: Enable Bit of asynchronous interrupt
+ (+) HAL_SDIO_DisableIOAsynInterrupt: Disable Bit of asynchronous interrupt
+
+ @endverbatim
+ ******************************************************************************
+ */
+
+/* Includes ----------------------------------------------------------------------------------------------------------*/
+#include "stm32h5xx_hal.h"
+
+/** @addtogroup STM32H5xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup SDIO
+ * @{
+ */
+#if defined (SDMMC1) || defined (SDMMC2)
+#ifdef HAL_SDIO_MODULE_ENABLED
+
+/* Private define ----------------------------------------------------------------------------------------------------*/
+/** @addtogroup SDIO_Private_Defines
+ * @{
+ */
+#define SDIO_INIT_FREQ 400000U /*!< Initialization phase : 400 kHz max */
+#define SDIO_TIMEOUT 1000U /*!< SDIO timeout millisecond */
+
+#define SDIO_FUNCTION_0 0x00U /*!< SDIO_Functions 0 */
+#define SDIO_FUNCTION_1 0x01U /*!< SDIO_Functions 1 */
+
+#define SDIO_READ 0x0U /*!< Read flag for cmd52 and cmd53 */
+#define SDIO_WRITE 0x1U /*!< Write flag for cmd52 and cmd53 */
+
+#define SDIO_BUS_SPEED_SDR12 0x00U /*!< SDIO bus speed mode SDR12 */
+#define SDIO_BUS_SPEED_SDR25 0x02U /*!< SDIO bus speed mode SDR25 */
+#define SDIO_BUS_SPEED_SDR50 0x04U /*!< SDIO bus speed mode SDR50 */
+#define SDIO_BUS_SPEED_DDR50 0x08U /*!< SDIO bus speed mode DDR50 */
+
+#define SDIO_CCCR_REG_NUMBER 0x16U /*!< SDIO card cccr register number */
+
+#define SDIO_OCR_VDD_32_33 (1U << 20U)
+#define SDIO_OCR_SDIO_S18R (1U << 24U)
+/**
+ * @}
+ */
+
+/* Private macro -----------------------------------------------------------------------------------------------------*/
+#define IS_SDIO_RAW_FLAG(ReadAfterWrite) (((ReadAfterWrite) == HAL_SDIO_WRITE_ONLY) || \
+ ((ReadAfterWrite) == HAL_SDIO_READ_AFTER_WRITE))
+
+#define IS_SDIO_FUNCTION(FN) (((FN) >= HAL_SDIO_FUNCTION_1) && ((FN) <= HAL_SDIO_FUNCTION_7))
+
+#define IS_SDIO_SUPPORTED_BLOCK_SIZE(SDIO_BLOCKSIZE) (((SDIO_BLOCKSIZE) == HAL_SDIO_DATA_BLOCK_SIZE_1BYTE) || \
+ ((SDIO_BLOCKSIZE) == HAL_SDIO_DATA_BLOCK_SIZE_2BYTE) || \
+ ((SDIO_BLOCKSIZE) == HAL_SDIO_DATA_BLOCK_SIZE_4BYTE) || \
+ ((SDIO_BLOCKSIZE) == HAL_SDIO_DATA_BLOCK_SIZE_8BYTE) || \
+ ((SDIO_BLOCKSIZE) == HAL_SDIO_DATA_BLOCK_SIZE_16BYTE) || \
+ ((SDIO_BLOCKSIZE) == HAL_SDIO_DATA_BLOCK_SIZE_32BYTE) || \
+ ((SDIO_BLOCKSIZE) == HAL_SDIO_DATA_BLOCK_SIZE_64BYTE) || \
+ ((SDIO_BLOCKSIZE) == HAL_SDIO_DATA_BLOCK_SIZE_128BYTE) || \
+ ((SDIO_BLOCKSIZE) == HAL_SDIO_DATA_BLOCK_SIZE_256BYTE) || \
+ ((SDIO_BLOCKSIZE) == HAL_SDIO_DATA_BLOCK_SIZE_512BYTE) || \
+ ((SDIO_BLOCKSIZE) == HAL_SDIO_DATA_BLOCK_SIZE_1024BYTE) || \
+ ((SDIO_BLOCKSIZE) == HAL_SDIO_DATA_BLOCK_SIZE_2048BYTE))
+
+/* Private functions -------------------------------------------------------------------------------------------------*/
+/** @defgroup SDIO_Private_Functions SDIO Private Functions
+ * @{
+ */
+static HAL_StatusTypeDef SDIO_InitCard(SDIO_HandleTypeDef *hsdio);
+static HAL_StatusTypeDef SDIO_ReadDirect(SDIO_HandleTypeDef *hsdio, uint32_t addr, uint32_t raw, uint32_t function_nbr,
+ uint8_t *pData);
+static HAL_StatusTypeDef SDIO_WriteDirect(SDIO_HandleTypeDef *hsdio, uint32_t addr, uint32_t raw, uint32_t function_nbr,
+ const uint8_t *pData);
+static HAL_StatusTypeDef SDIO_WriteExtended(SDIO_HandleTypeDef *hsdio, HAL_SDIO_ExtendedCmd_TypeDef *cmd_arg,
+ uint8_t *pData, uint16_t Size_byte);
+static uint8_t SDIO_Convert_Block_Size(const SDIO_HandleTypeDef *hsdio, uint32_t block_size);
+static HAL_StatusTypeDef SDIO_IOFunction_IRQHandler(SDIO_HandleTypeDef *hsdio);
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup SDIO_Exported_Functions
+ * @{
+ */
+/** @addtogroup SDIO_Exported_Functions_Group1
+ * @brief Initialization and de-initialization functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Initialization and de-initialization functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to initialize/de-initialize the SDIO
+ device to be ready for use.
+
+@endverbatim
+ * @{
+ */
+/**
+ * @brief Initializes the SDIO according to the specified parameters in the
+ SDIO_HandleTypeDef and create the associated handle.
+ * @param hsdio: Pointer to the SDIO handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SDIO_Init(SDIO_HandleTypeDef *hsdio)
+{
+ SDIO_InitTypeDef Init;
+ uint32_t sdmmc_clk = 0U;
+ uint8_t data;
+
+ /* Check the parameters */
+ assert_param(hsdio != NULL);
+ assert_param(IS_SDMMC_ALL_INSTANCE(hsdio->Instance));
+ assert_param(IS_SDMMC_CLOCK_EDGE(hsdio->Init.ClockEdge));
+ assert_param(IS_SDMMC_CLOCK_POWER_SAVE(hsdio->Init.ClockPowerSave));
+ assert_param(IS_SDMMC_BUS_WIDE(hsdio->Init.BusWide));
+ assert_param(IS_SDMMC_HARDWARE_FLOW_CONTROL(hsdio->Init.HardwareFlowControl));
+ assert_param(IS_SDMMC_CLKDIV(hsdio->Init.ClockDiv));
+
+ /* Check the SDIO handle allocation */
+ if (hsdio == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ if (hsdio->State == HAL_SDIO_STATE_RESET)
+ {
+#if defined (USE_HAL_SDIO_REGISTER_CALLBACKS) && (USE_HAL_SDIO_REGISTER_CALLBACKS == 1U)
+ /* Reset Callback pointers in HAL_SDIO_STATE_RESET only */
+ hsdio->TxCpltCallback = HAL_SDIO_TxCpltCallback;
+ hsdio->RxCpltCallback = HAL_SDIO_RxCpltCallback;
+ hsdio->ErrorCallback = HAL_SDIO_ErrorCallback;
+#if (USE_SDIO_TRANSCEIVER != 0U)
+ if (hsdio->Init.TranceiverPresent == SDMMC_TRANSCEIVER_PRESENT)
+ {
+ hsdio->DriveTransceiver_1_8V_Callback = HAL_SDIO_DriveTransceiver_1_8V_Callback;
+ }
+#endif /* USE_SDIO_TRANSCEIVER */
+
+ if (hsdio->MspInitCallback == NULL)
+ {
+ hsdio->MspInitCallback = HAL_SDIO_MspInit;
+ }
+ /* Init the low level hardware */
+ hsdio->MspInitCallback(hsdio);
+#else
+ /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
+ HAL_SDIO_MspInit(hsdio);
+#endif /* USE_HAL_SDIO_REGISTER_CALLBACKS */
+ }
+
+ Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
+ Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
+ Init.BusWide = SDMMC_BUS_WIDE_1B;
+ Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
+
+ if (hsdio->Instance == SDMMC1)
+ {
+ sdmmc_clk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC1);
+ }
+#if defined(SDMMC2)
+ if (hsdio->Instance == SDMMC2)
+ {
+ sdmmc_clk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC2);
+ }
+#endif /* SDMMC2 */
+ if (sdmmc_clk == 0U)
+ {
+ hsdio->ErrorCode = SDMMC_ERROR_INVALID_PARAMETER;
+ return HAL_ERROR;
+ }
+ Init.ClockDiv = sdmmc_clk / (2U * SDIO_INIT_FREQ);
+ /* Initialize SDMMC peripheral interface with default configuration */
+ (void)SDMMC_Init(hsdio->Instance, Init);
+
+ /* Set Power State to ON */
+ (void)SDMMC_PowerState_ON(hsdio->Instance);
+
+ /* wait 74 Cycles: required power up waiting time before starting the SDIO initialization sequence */
+ sdmmc_clk = sdmmc_clk / (2U * Init.ClockDiv);
+ HAL_Delay(1U + (74U * 1000U / (sdmmc_clk)));
+
+ if (hsdio->SDIO_IdentifyCard == NULL)
+ {
+ hsdio->SDIO_IdentifyCard = SDIO_InitCard;
+ }
+ /* SDIO enumeration sequence */
+ if (hsdio->SDIO_IdentifyCard(hsdio) != HAL_OK)
+ {
+ hsdio->State = HAL_SDIO_STATE_RESET;
+ return HAL_ERROR;
+ }
+
+ /* Configure the SDMMC user parameters */
+ Init.ClockEdge = hsdio->Init.ClockEdge;
+ Init.ClockPowerSave = hsdio->Init.ClockPowerSave;
+ Init.BusWide = hsdio->Init.BusWide;
+ Init.HardwareFlowControl = hsdio->Init.HardwareFlowControl;
+ Init.ClockDiv = hsdio->Init.ClockDiv;
+ (void)SDMMC_Init(hsdio->Instance, Init);
+
+ data = (hsdio->Init.BusWide == HAL_SDIO_4_WIRES_MODE) ? 2U : 0U;
+ if (SDIO_WriteDirect(hsdio, SDMMC_SDIO_CCCR4_SD_BYTE3, HAL_SDIO_WRITE_ONLY, SDIO_FUNCTION_0, &data) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ hsdio->Context = SDIO_CONTEXT_NONE;
+ hsdio->State = HAL_SDIO_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief De-Initializes the SDIO device.
+ * @param hsdio: Pointer to the SDIO handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SDIO_DeInit(SDIO_HandleTypeDef *hsdio)
+{
+ /* Check the parameters */
+ assert_param(IS_SDMMC_ALL_INSTANCE(hsdio->Instance));
+
+ /* Check the SDIO handle allocation */
+ if (hsdio == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Set Power State to OFF */
+ (void)SDMMC_PowerState_OFF(hsdio->Instance);
+
+#if defined (USE_HAL_SDIO_REGISTER_CALLBACKS) && (USE_HAL_SDIO_REGISTER_CALLBACKS == 1U)
+ if (hsdio->MspDeInitCallback == NULL)
+ {
+ hsdio->MspDeInitCallback = HAL_SDIO_MspDeInit;
+ }
+
+ /* DeInit the low level hardware */
+ hsdio->MspDeInitCallback(hsdio);
+#else
+ /* De-Initialize the MSP layer */
+ HAL_SDIO_MspDeInit(hsdio);
+#endif /* USE_HAL_SDIO_REGISTER_CALLBACKS */
+
+ hsdio->ErrorCode = HAL_SDIO_ERROR_NONE;
+ hsdio->State = HAL_SDIO_STATE_RESET;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the SDIO MSP.
+ * @param hsdio: Pointer to SDIO handle
+ * @retval None
+ */
+__weak void HAL_SDIO_MspInit(SDIO_HandleTypeDef *hsdio)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hsdio);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_SDIO_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief De-Initialize SDIO MSP.
+ * @param hsdio: Pointer to SDIO handle
+ * @retval None
+ */
+__weak void HAL_SDIO_MspDeInit(SDIO_HandleTypeDef *hsdio)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hsdio);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_SDIO_MspDeInit could be implemented in the user file
+ */
+}
+/**
+ * @}
+ */
+
+/** @addtogroup SDIO_Exported_Functions_Group2
+ * @brief
+ *
+@verbatim
+ ==============================================================================
+ ##### Initialization and de-initialization functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to re-configure the SDIO peripheral.
+
+@endverbatim
+ * @{
+ */
+/**
+ * @brief Enables wide bus operation for the requested card if supported by card.
+ * @param hsdio: Pointer to SDIO handle
+ * @param BusWide: Specifies the SDIO card wide bus mode
+ * This parameter can be one of the following values:
+ * @arg SDMMC_BUS_WIDE_8B: 8-bit data transfer
+ * @arg SDMMC_BUS_WIDE_4B: 4-bit data transfer
+ * @arg SDMMC_BUS_WIDE_1B: 1-bit data transfer
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SDIO_SetDataBusWidth(SDIO_HandleTypeDef *hsdio, uint32_t BusWide)
+{
+ uint8_t data;
+ HAL_StatusTypeDef error_state = HAL_OK;
+
+ /* Check the parameters */
+ assert_param(hsdio != NULL);
+
+ /* Check the SDIO peripheral handle parameter */
+ if (hsdio == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ if (hsdio->State == HAL_SDIO_STATE_READY)
+ {
+ data = (BusWide == HAL_SDIO_4_WIRES_MODE) ? 2U : 0U;
+ MODIFY_REG(hsdio->Instance->CLKCR, SDMMC_CLKCR_WIDBUS,
+ (BusWide == HAL_SDIO_4_WIRES_MODE) ? SDMMC_BUS_WIDE_4B : SDMMC_BUS_WIDE_1B);
+
+ if (SDIO_WriteDirect(hsdio, SDMMC_SDIO_CCCR4_SD_BYTE3, HAL_SDIO_WRITE_ONLY, SDIO_FUNCTION_0, &data) != HAL_OK)
+ {
+ error_state = HAL_ERROR;
+ }
+ }
+ else
+ {
+ error_state = HAL_ERROR;
+ }
+
+ return error_state;
+}
+
+/**
+ * @brief Update the SDIO Clock.
+ * @param hsdio: Pointer to SDIO handle.
+ * @param ClockSpeed: SDIO Clock speed.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SDIO_ConfigFrequency(SDIO_HandleTypeDef *hsdio, uint32_t ClockSpeed)
+{
+ uint32_t ClockDiv = 0U;
+
+ /* Check the parameters */
+ assert_param(hsdio != NULL);
+
+ /* Check the SDIO peripheral handle parameter */
+ if (hsdio == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ if (hsdio->State == HAL_SDIO_STATE_READY)
+ {
+ if (hsdio->Instance == SDMMC1)
+ {
+ ClockDiv = (HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC1)) / (2U * ClockSpeed);
+ }
+#if defined(SDMMC2)
+ if (hsdio->Instance == SDMMC2)
+ {
+ ClockDiv = (HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC2)) / (2U * ClockSpeed);
+ }
+#endif /* SDMMC2 */
+ MODIFY_REG(hsdio->Instance->CLKCR, SDMMC_CLKCR_CLKDIV, ClockDiv);
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Set the SDIO block size.
+ * @param hsdio: Pointer to SDIO handle
+ * @param function_nbr: Specifies the SDIO function number.
+ * @param BlockSize: Specifies the SDIO Block size to set.
+ * This parameter can be one of the following values @ref SDIO_Exported_Constansts_Group7.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SDIO_SetBlockSize(SDIO_HandleTypeDef *hsdio, uint8_t function_nbr, uint16_t BlockSize)
+{
+ HAL_SDIO_ExtendedCmd_TypeDef cmd53;
+
+ /* Check the parameters */
+ assert_param(hsdio != NULL);
+ assert_param(IS_SDIO_FUNCTION(function_nbr));
+ assert_param(IS_SDIO_SUPPORTED_BLOCK_SIZE(BlockSize));
+
+ /* Check the SDIO peripheral handle parameter */
+ if (hsdio == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Set SDIO F1 block size */
+ cmd53.IOFunctionNbr = SDIO_FUNCTION_0;
+ cmd53.OpCode = HAL_SDIO_OP_CODE_AUTO_INC;
+ cmd53.Block_Mode = HAL_SDIO_MODE_BYTE;
+ cmd53.Reg_Addr = (function_nbr * 0x100UL) + 0x10UL;
+ if (SDIO_WriteExtended(hsdio, &cmd53, (uint8_t *)(&BlockSize), 2U) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ hsdio->block_size = BlockSize;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Configure the data rate.
+ * @param hsdio: Pointer to SDIO handle
+ * @param DataRate: Specifies the SDIO data rate to set.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SDIO_SetSpeedMode(SDIO_HandleTypeDef *hsdio, uint32_t DataRate)
+{
+ HAL_StatusTypeDef errorstate = HAL_OK;
+ uint8_t data;
+
+ /* Check the parameters */
+ assert_param(hsdio != NULL);
+
+ /* Check the SDIO peripheral handle parameter */
+ if (hsdio == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ switch (DataRate)
+ {
+ case HAL_SDIOS_DATA_RATE_SDR25:
+ data = SDIO_BUS_SPEED_SDR25;
+ errorstate = SDIO_WriteDirect(hsdio, SDMMC_SDIO_CCCR16_SD_BYTE3, HAL_SDIO_WRITE_ONLY, SDIO_FUNCTION_0, &data);
+ break;
+
+ case HAL_SDIOS_DATA_RATE_SDR50:
+ data = SDIO_BUS_SPEED_SDR50;
+ errorstate = SDIO_WriteDirect(hsdio, ((SDIO_FUNCTION_0 << 2U) | (SDIO_FUNCTION_0 << 1U) | (SDIO_FUNCTION_0 << 14U)
+ | SDMMC_SDIO_CCCR16_SD_BYTE3), HAL_SDIO_WRITE_ONLY, SDIO_FUNCTION_0, &data);
+ MODIFY_REG(hsdio->Instance->CLKCR, SDMMC_CLKCR_BUSSPEED, SDMMC_CLKCR_BUSSPEED);
+ break;
+
+ case HAL_SDIOS_DATA_RATE_DDR50:
+ data = SDIO_BUS_SPEED_DDR50;
+ errorstate = SDIO_WriteDirect(hsdio, ((SDIO_FUNCTION_0 << 2) | (SDIO_FUNCTION_0 << 1) | (SDIO_FUNCTION_0 << 14) |
+ SDMMC_SDIO_CCCR16_SD_BYTE3), HAL_SDIO_WRITE_ONLY, SDIO_FUNCTION_0, &data);
+ MODIFY_REG(hsdio->Instance->CLKCR, SDMMC_CLKCR_DDR | SDMMC_CLKCR_BUSSPEED,
+ SDMMC_CLKCR_DDR | SDMMC_CLKCR_BUSSPEED);
+ break;
+ default: /* SDR12 */
+ break;
+ }
+
+ return (errorstate != HAL_OK) ? HAL_ERROR : HAL_OK;
+}
+
+/**
+ * @brief Reset SDIO Card
+ * @param hsdio: Pointer to SDIO handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SDIO_CardReset(SDIO_HandleTypeDef *hsdio)
+{
+ uint8_t data = 0U;
+
+ /* Check the parameters */
+ assert_param(hsdio != NULL);
+
+ /* Check the SDIO peripheral handle parameter */
+ if (hsdio == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /** To reset the SDIO module by CMD52 with writing to RES in CCCR or send CMD0 the card shall change the speed mode
+ * default speed mode.
+ * The reset cmd (cmd0) is only used for memory. In order to reset an I/O card or the I/O portion of a combo card,
+ * Use CMD52 to write 1 to the RES bit in the CCC(bit3 of register 6).
+ */
+ if (SDIO_WriteDirect(hsdio, ((SDIO_FUNCTION_0 << 2) | (SDIO_FUNCTION_0 << 1) | (SDIO_FUNCTION_0 << 14) |
+ SDMMC_SDIO_CCCR4_SD_BYTE2),
+ HAL_SDIO_WRITE_ONLY,
+ 0U,
+ &data) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ hsdio->State = HAL_SDIO_STATE_RESET;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Get Card Common Control register (CCCR).
+ * @param hsdio: Pointer to SDIO handle.
+ * @param pCccr: Pointer to Cccr register.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SDIO_GetCardCommonControlRegister(SDIO_HandleTypeDef *hsdio, HAL_SDIO_CCCR_TypeDef *pCccr)
+{
+ uint8_t tempBuffer[256] = {0U};
+ uint32_t count;
+
+ assert_param(hsdio != NULL);
+ assert_param(pCccr != NULL);
+
+ if ((hsdio == NULL) || (pCccr == NULL))
+ {
+ return HAL_ERROR;
+ }
+
+ for (count = 0U; count <= SDIO_CCCR_REG_NUMBER; count++)
+ {
+ if (SDIO_ReadDirect(hsdio, SDMMC_SDIO_CCCR0 + count, HAL_SDIO_WRITE_ONLY, SDIO_FUNCTION_0, &tempBuffer[count]) !=
+ HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+ }
+
+ pCccr->cccr_revision = tempBuffer[0] & 0x0FU;
+ pCccr->sdio_revision = (tempBuffer[0] & 0xF0U) >> 4U;
+ pCccr->sd_spec_revision = tempBuffer[0x01U] & 0x0FU;
+ pCccr->bus_width_8Bit = ((tempBuffer[0x07U] & 0x04U) != 0U) ? HAL_SDIO_BUS_WIDTH_8BIT_SUPPORTED
+ : HAL_SDIO_BUS_WIDTH_8BIT_NOT_SUPPORTED;
+ pCccr->card_capability = (tempBuffer[0x08U] & 0xDFUL);
+ /* common CIS pointer */
+ pCccr->commonCISPointer = tempBuffer[0x09U] | ((uint32_t)tempBuffer[(uint32_t)0x09U + 1U] << 8U) |
+ ((uint32_t)tempBuffer[(uint32_t)0x09U + 2U] << 16U);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Get Card Function Basic register(FBR).
+ * @param hsdio: Pointer to SDIO handle.
+ * @param pFbr: Pointer to Fbr register.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SDIO_GetCardFBRRegister(SDIO_HandleTypeDef *hsdio, HAL_SDIO_FBR_t *pFbr)
+{
+ uint8_t tempBuffer[256] = {0U};
+ uint32_t count;
+ uint8_t func_idx;
+
+ assert_param(hsdio != NULL);
+ assert_param(pFbr != NULL);
+
+ if ((hsdio == NULL) || (pFbr == NULL))
+ {
+ return HAL_ERROR;
+ }
+
+ for (func_idx = 2U; func_idx <= SDIO_MAX_IO_NUMBER; func_idx++)
+ {
+ for (count = 0U; count <= SDIO_CCCR_REG_NUMBER; count++)
+ {
+ if (SDIO_ReadDirect(hsdio, (((uint32_t)SDMMC_SDIO_F1BR0 * (uint32_t)func_idx) + count),
+ HAL_SDIO_WRITE_ONLY, SDIO_FUNCTION_0, &tempBuffer[count]) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+ }
+ pFbr[(uint32_t)func_idx - 1U].ioStdFunctionCode = tempBuffer[0U] & 0x0FU;
+ pFbr[(uint32_t)func_idx - 1U].ioExtFunctionCode = tempBuffer[1U];
+ pFbr[(uint32_t)func_idx - 1U].ioPointerToCIS = tempBuffer[9U] | ((uint32_t)tempBuffer[10U] << 8U) |
+ ((uint32_t)tempBuffer[11U] << 16U);
+ pFbr[(uint32_t)func_idx - 1U].ioPointerToCSA = tempBuffer[12U] | ((uint32_t)tempBuffer[13U] << 8U) |
+ ((uint32_t)tempBuffer[14U] << 16U);
+ if ((tempBuffer[2U] & 0x01U) != 0U)
+ {
+ pFbr[(uint32_t)func_idx - 1U].flags |= (uint8_t)HAL_SDIO_FBR_SUPPORT_POWER_SELECTION;
+ }
+ if ((tempBuffer[0U] & 0x40U) != 0U)
+ {
+ pFbr[(uint32_t)func_idx - 1U].flags |= (uint8_t)HAL_SDIO_FBR_SUPPORT_CSA;
+ }
+ }
+
+ return HAL_OK;
+}
+/**
+ * @}
+ */
+
+/** @addtogroup SDIO_Exported_Functions_Group3
+ * @brief
+ *
+@verbatim
+ ==============================================================================
+ ##### Data management functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to manage the data transfer from/to SDIO card.
+
+@endverbatim
+ * @{
+ */
+/**
+ * @brief Read data from a specified address using the direct mode through cmd52.
+ * @param hsdio: Pointer to SDIO handle
+ * @param Argument: Specifies the SDIO Argument.
+ * @param pData: pointer to the buffer that will contain the received data.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SDIO_ReadDirect(SDIO_HandleTypeDef *hsdio, const HAL_SDIO_DirectCmd_TypeDef *Argument,
+ uint8_t *pData)
+{
+ uint32_t cmd;
+ uint32_t errorstate;
+
+ /* Check the parameters */
+ assert_param(hsdio != NULL);
+ assert_param(Argument != NULL);
+ assert_param(pData != NULL);
+ assert_param(IS_SDIO_RAW_FLAG(Argument->ReadAfterWrite));
+
+ if ((hsdio == NULL) || (Argument == NULL) || (NULL == pData))
+ {
+ return HAL_ERROR;
+ }
+
+ if (hsdio->State == HAL_SDIO_STATE_READY)
+ {
+ hsdio->ErrorCode = HAL_SDIO_ERROR_NONE;
+ hsdio->State = HAL_SDIO_STATE_BUSY;
+
+ cmd = SDIO_READ << 31U;
+ cmd |= (((uint32_t)Argument->IOFunctionNbr) << 28U);
+ cmd |= (((uint32_t)Argument->ReadAfterWrite) << 27U);
+ cmd |= (Argument->Reg_Addr & 0x1FFFFU) << 9U;
+ cmd |= 0U;
+ errorstate = SDMMC_SDIO_CmdReadWriteDirect(hsdio->Instance, cmd, pData);
+
+ if (errorstate != HAL_SDIO_ERROR_NONE)
+ {
+ hsdio->ErrorCode |= errorstate;
+ if (errorstate != (SDMMC_ERROR_ADDR_OUT_OF_RANGE | SDMMC_ERROR_ILLEGAL_CMD | SDMMC_ERROR_COM_CRC_FAILED |
+ SDMMC_ERROR_GENERAL_UNKNOWN_ERR))
+ {
+ /* Clear all the static flags */
+ __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
+ hsdio->State = HAL_SDIO_STATE_READY;
+ hsdio->Context = SDIO_CONTEXT_NONE;
+ return HAL_ERROR;
+ }
+ }
+
+ __SDMMC_CMDTRANS_DISABLE(hsdio->Instance);
+
+ /* Clear all the static flags */
+ __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_DATA_FLAGS);
+
+ hsdio->State = HAL_SDIO_STATE_READY;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+
+ return HAL_OK;
+}
+
+
+/**
+ * @brief Read data from a specified address using the direct mode through cmd52.
+ * @param hsdio: Pointer to SDIO handle
+ * @param Argument: Specifies the SDIO Argument.
+ * @param Data: pointer to the buffer that will contain the received data.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SDIO_WriteDirect(SDIO_HandleTypeDef *hsdio, const HAL_SDIO_DirectCmd_TypeDef *Argument,
+ uint8_t Data)
+{
+ uint32_t cmd;
+ uint32_t errorstate;
+
+ /* Check the parameters */
+ assert_param(hsdio != NULL);
+ assert_param(Argument != NULL);
+ assert_param(IS_SDIO_RAW_FLAG(Argument->ReadAfterWrite));
+
+ if ((hsdio == NULL) || (Argument == NULL))
+ {
+ return HAL_ERROR;
+ }
+
+ if (hsdio->State == HAL_SDIO_STATE_READY)
+ {
+ hsdio->ErrorCode = HAL_SDIO_ERROR_NONE;
+ hsdio->State = HAL_SDIO_STATE_BUSY;
+
+ cmd = SDIO_WRITE << 31U;
+ cmd |= ((uint32_t)Argument->IOFunctionNbr) << 28U;
+ cmd |= ((uint32_t)Argument->ReadAfterWrite) << 27U;
+ cmd |= (Argument->Reg_Addr & 0x1FFFFU) << 9U;
+ cmd |= Data;
+ errorstate = SDMMC_SDIO_CmdReadWriteDirect(hsdio->Instance, cmd, &Data);
+ if (errorstate != HAL_SDIO_ERROR_NONE)
+ {
+ hsdio->ErrorCode |= errorstate;
+ if (errorstate != (SDMMC_ERROR_ADDR_OUT_OF_RANGE | SDMMC_ERROR_ILLEGAL_CMD | SDMMC_ERROR_COM_CRC_FAILED |
+ SDMMC_ERROR_GENERAL_UNKNOWN_ERR))
+ {
+ /* Clear all the static flags */
+ __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
+ hsdio->State = HAL_SDIO_STATE_READY;
+ hsdio->Context = SDIO_CONTEXT_NONE;
+ return HAL_ERROR;
+ }
+ }
+
+ __SDMMC_CMDTRANS_DISABLE(hsdio->Instance);
+
+ /* Clear all the static flags */
+ __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_DATA_FLAGS);
+
+ hsdio->State = HAL_SDIO_STATE_READY;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Read data from a specified address using extended mode through cmd53.
+ * @param hsdio: Pointer to SDIO handle
+ * @param Argument: Pointer to SDIO argument
+ * @param pData: pointer to the buffer that will contain the data to transmit
+ * @param Size_byte: size to read.
+ * @param Timeout_Ms: Specify timeout value
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SDIO_ReadExtended(SDIO_HandleTypeDef *hsdio, const HAL_SDIO_ExtendedCmd_TypeDef *Argument,
+ uint8_t *pData, uint32_t Size_byte, uint32_t Timeout_Ms)
+{
+ uint32_t cmd;
+ SDMMC_DataInitTypeDef config;
+ uint32_t errorstate;
+ uint32_t tickstart = HAL_GetTick();
+ uint32_t regCount;
+ uint8_t byteCount;
+ uint32_t data;
+ uint32_t dataremaining;
+ uint8_t *tempbuff = pData;
+ uint32_t nbr_of_block;
+
+ /* Check the parameters */
+ assert_param(hsdio != NULL);
+ assert_param(Argument != NULL);
+ assert_param(pData != NULL);
+
+ if ((hsdio == NULL) || (Argument == NULL) || (pData == NULL))
+ {
+ return HAL_ERROR;
+ }
+
+ if (hsdio->State == HAL_SDIO_STATE_READY)
+ {
+ hsdio->ErrorCode = HAL_SDIO_ERROR_NONE;
+ hsdio->State = HAL_SDIO_STATE_BUSY;
+
+ /* Compute how many blocks are to be send for pData of length data_size to be send */
+ nbr_of_block = (Size_byte & ~(hsdio->block_size & 1U)) >> __CLZ(__RBIT(hsdio->block_size));
+
+ /* Initialize data control register */
+ if ((hsdio->Instance->DCTRL & SDMMC_DCTRL_SDIOEN) != 0U)
+ {
+ hsdio->Instance->DCTRL = SDMMC_DCTRL_SDIOEN;
+ }
+ else
+ {
+ hsdio->Instance->DCTRL = 0U;
+ }
+
+ /* Configure the SDIO DPSM (Data Path State Machine) */
+ config.DataTimeOut = SDMMC_DATATIMEOUT;
+ /* (HAL_SDIO_MODE_BLOCK << 27) corresponds to the block mode bit of the CMD argument */
+ if (Argument->Block_Mode == HAL_SDIO_MODE_BLOCK)
+ {
+ /* (Argument & 0x1FFU) is to get the 9 bits of Block/Byte counts */
+ config.DataLength = (uint32_t)(nbr_of_block * hsdio->block_size);
+ config.DataBlockSize = SDIO_Convert_Block_Size(hsdio, hsdio->block_size);
+ }
+ else
+ {
+ /* (Argument & 0x1FFU) is to get the 9 bits of Block/Byte counts */
+ config.DataLength = (Size_byte > 0U) ? Size_byte : HAL_SDIO_DATA_BLOCK_SIZE_512BYTE;
+ config.DataBlockSize = SDMMC_DATABLOCK_SIZE_1B;
+ }
+
+ config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC ;
+ /* (HAL_SDIO_MODE_BLOCK << 27) corresponds to the block mode bit of the CMD argument */
+ config.TransferMode = (Argument->Block_Mode == HAL_SDIO_MODE_BLOCK) ? SDMMC_TRANSFER_MODE_BLOCK :
+ SDMMC_TRANSFER_MODE_SDIO;
+ config.DPSM = SDMMC_DPSM_DISABLE;
+ (void)SDMMC_ConfigData(hsdio->Instance, &config);
+ __SDMMC_CMDTRANS_ENABLE(hsdio->Instance);
+
+ /* Correspond to the write or read bit of the CMD argument */
+ /* Read */
+ hsdio->Context = (Argument->Block_Mode == HAL_SDIO_MODE_BLOCK) ? SDIO_CONTEXT_READ_MULTIPLE_BLOCK :
+ SDIO_CONTEXT_READ_SINGLE_BLOCK;
+ cmd = SDIO_READ << 31U;
+ cmd |= Argument->IOFunctionNbr << 28U;
+ cmd |= Argument->Block_Mode << 27U;
+ cmd |= Argument->OpCode << 26U;
+ cmd |= (Argument->Reg_Addr & 0x1FFFFU) << 9U;
+ cmd |= (Size_byte & 0x1FFU);
+ errorstate = SDMMC_SDIO_CmdReadWriteExtended(hsdio->Instance, cmd);
+ if (errorstate != HAL_SDIO_ERROR_NONE)
+ {
+ hsdio->ErrorCode |= errorstate;
+ if (errorstate != (SDMMC_ERROR_ADDR_OUT_OF_RANGE | SDMMC_ERROR_ILLEGAL_CMD | SDMMC_ERROR_COM_CRC_FAILED |
+ SDMMC_ERROR_GENERAL_UNKNOWN_ERR))
+ {
+ MODIFY_REG(hsdio->Instance->DCTRL, SDMMC_DCTRL_FIFORST, SDMMC_DCTRL_FIFORST);
+ __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
+ __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_DATA_FLAGS);
+ hsdio->State = HAL_SDIO_STATE_READY;
+ hsdio->Context = SDIO_CONTEXT_NONE;
+ return HAL_ERROR;
+ }
+ }
+ /* (SDIO_WRITE << 31) correspond to the write or read bit of the CMD argument */
+ /* Poll on SDMMC flags */
+ dataremaining = config.DataLength;
+
+ while (!__HAL_SDIO_GET_FLAG(hsdio, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL |
+ SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
+ {
+ if (__HAL_SDIO_GET_FLAG(hsdio, SDMMC_FLAG_RXFIFOHF) && (dataremaining >= SDMMC_FIFO_SIZE))
+ {
+ /* Read data from SDMMC Rx FIFO */
+ for (regCount = 0U; regCount < (SDMMC_FIFO_SIZE / 4U); regCount++)
+ {
+ data = SDMMC_ReadFIFO(hsdio->Instance);
+ *tempbuff = (uint8_t)(data & 0xFFU);
+ tempbuff++;
+ *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
+ tempbuff++;
+ *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
+ tempbuff++;
+ *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
+ tempbuff++;
+ }
+ dataremaining -= SDMMC_FIFO_SIZE;
+ }
+ else if (dataremaining < SDMMC_FIFO_SIZE)
+ {
+ while (!(__HAL_SDIO_GET_FLAG(hsdio, SDMMC_FLAG_RXFIFOE)) && (dataremaining > 0U))
+ {
+ data = SDMMC_ReadFIFO(hsdio->Instance);
+ for (byteCount = 0U; byteCount < 4U; byteCount++)
+ {
+ if (dataremaining > 0U)
+ {
+ *tempbuff = (uint8_t)((data >> (byteCount * 8U)) & 0xFFU);
+ tempbuff++;
+ dataremaining--;
+ }
+ }
+ }
+ }
+ else
+ {
+ /* Nothing to do */
+ }
+ if ((HAL_GetTick() - tickstart) >= Timeout_Ms)
+ {
+ /* Clear all the static flags */
+ __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
+ hsdio->ErrorCode |= HAL_SDIO_ERROR_TIMEOUT;
+ hsdio->State = HAL_SDIO_STATE_READY;
+ hsdio->Context = SDIO_CONTEXT_NONE;
+ return HAL_TIMEOUT;
+ }
+ }
+ __SDMMC_CMDTRANS_DISABLE(hsdio->Instance);
+ /* Get error state */
+ if (__HAL_SDIO_GET_FLAG(hsdio, SDMMC_FLAG_DTIMEOUT))
+ {
+ /* Clear all the static flags */
+ __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
+ hsdio->ErrorCode |= HAL_SDIO_ERROR_DATA_TIMEOUT;
+ hsdio->State = HAL_SDIO_STATE_READY;
+ hsdio->Context = SDIO_CONTEXT_NONE;
+ return HAL_ERROR;
+ }
+ else if (__HAL_SDIO_GET_FLAG(hsdio, SDMMC_FLAG_DCRCFAIL))
+ {
+ /* Clear all the static flags */
+ __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
+ hsdio->ErrorCode |= HAL_SDIO_ERROR_DATA_CRC_FAIL;
+ hsdio->State = HAL_SDIO_STATE_READY;
+ hsdio->Context = SDIO_CONTEXT_NONE;
+ return HAL_ERROR;
+ }
+ else if (__HAL_SDIO_GET_FLAG(hsdio, SDMMC_FLAG_RXOVERR))
+ {
+ /* Clear all the static flags */
+ __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
+ /* (SDIO_WRITE << 31) correspond to the write or read bit of the CMD argument */
+ hsdio->ErrorCode |= HAL_SDIO_ERROR_RX_OVERRUN;
+ hsdio->State = HAL_SDIO_STATE_READY;
+ hsdio->Context = SDIO_CONTEXT_NONE;
+ return HAL_ERROR;
+ }
+ else if (hsdio->ErrorCode == SDMMC_ERROR_INVALID_PARAMETER)
+ {
+ __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_DATA_FLAGS);
+ hsdio->State = HAL_SDIO_STATE_READY;
+ hsdio->Context = SDIO_CONTEXT_NONE;
+ return HAL_ERROR;
+ }
+ else
+ {
+ /* Nothing to do */
+ }
+
+ /* Clear all the static flags */
+ __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_DATA_FLAGS);
+
+ hsdio->State = HAL_SDIO_STATE_READY;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Write data from a specified address using extended mode through cmd53.
+ * @param hsdio: Pointer to SDIO handle
+ * @param Argument: Pointer to SDIO argument
+ * @param pData: pointer to the buffer that will contain the data to transmit
+ * @param Size_byte: Block size to write.
+ * @param Timeout_Ms: Specify timeout value
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SDIO_WriteExtended(SDIO_HandleTypeDef *hsdio, const HAL_SDIO_ExtendedCmd_TypeDef *Argument,
+ uint8_t *pData, uint32_t Size_byte, uint32_t Timeout_Ms)
+{
+ uint32_t cmd;
+ SDMMC_DataInitTypeDef config;
+ uint32_t errorstate;
+ uint32_t tickstart = HAL_GetTick();
+ uint32_t regCount;
+ uint8_t byteCount;
+ uint32_t data;
+ uint32_t dataremaining;
+ uint8_t *u32tempbuff = pData;
+ uint32_t nbr_of_block;
+
+ /* Check the parameters */
+ assert_param(hsdio != NULL);
+ assert_param(Argument != NULL);
+ assert_param(pData != NULL);
+
+ if ((hsdio == NULL) || (Argument == NULL) || (pData == NULL))
+ {
+ return HAL_ERROR;
+ }
+
+ if (hsdio->State == HAL_SDIO_STATE_READY)
+ {
+ hsdio->ErrorCode = HAL_SDIO_ERROR_NONE;
+ hsdio->State = HAL_SDIO_STATE_BUSY;
+
+ /* Compute how many blocks are to be send for pData of length data_size to be send */
+ nbr_of_block = (Size_byte & ~(hsdio->block_size & 1U)) >> __CLZ(__RBIT(hsdio->block_size));
+
+ /* Initialize data control register */
+ if ((hsdio->Instance->DCTRL & SDMMC_DCTRL_SDIOEN) != 0U)
+ {
+ hsdio->Instance->DCTRL = SDMMC_DCTRL_SDIOEN;
+ }
+ else
+ {
+ hsdio->Instance->DCTRL = 0U;
+ }
+
+ /* Configure the SDIO DPSM (Data Path State Machine) */
+ config.DataTimeOut = SDMMC_DATATIMEOUT;
+ if (Argument->Block_Mode == HAL_SDIO_MODE_BLOCK)
+ {
+ config.DataLength = (uint32_t)(nbr_of_block * hsdio->block_size);
+ config.DataBlockSize = SDIO_Convert_Block_Size(hsdio, hsdio->block_size);
+ }
+ else
+ {
+ config.DataLength = (Size_byte > 0U) ? Size_byte : HAL_SDIO_DATA_BLOCK_SIZE_512BYTE;
+ config.DataBlockSize = SDMMC_DATABLOCK_SIZE_1B;
+ }
+
+ config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD;
+ /* (HAL_SDIO_MODE_BLOCK << 27) corresponds to the block mode bit of the CMD argument */
+ config.TransferMode = (Argument->Block_Mode == HAL_SDIO_MODE_BLOCK) ? SDMMC_TRANSFER_MODE_BLOCK :
+ SDMMC_TRANSFER_MODE_SDIO;
+ config.DPSM = SDMMC_DPSM_DISABLE;
+ (void)SDMMC_ConfigData(hsdio->Instance, &config);
+ __SDMMC_CMDTRANS_ENABLE(hsdio->Instance);
+
+ /* Correspond to the write or read bit of the CMD argument */
+ hsdio->Context = (Argument->Block_Mode == HAL_SDIO_MODE_BLOCK) ? SDIO_CONTEXT_WRITE_MULTIPLE_BLOCK :
+ SDIO_CONTEXT_WRITE_SINGLE_BLOCK;
+ cmd = SDIO_WRITE << 31U;
+ cmd |= Argument->IOFunctionNbr << 28U;
+ cmd |= Argument->Block_Mode << 27U;
+ cmd |= Argument->OpCode << 26U;
+ cmd |= (Argument->Reg_Addr & 0x1FFFFU) << 9U;
+ cmd |= (Size_byte & 0x1FFU);
+ errorstate = SDMMC_SDIO_CmdReadWriteExtended(hsdio->Instance, cmd);
+ if (errorstate != HAL_SDIO_ERROR_NONE)
+ {
+ hsdio->ErrorCode |= errorstate;
+ if (errorstate != (SDMMC_ERROR_ADDR_OUT_OF_RANGE | SDMMC_ERROR_ILLEGAL_CMD | SDMMC_ERROR_COM_CRC_FAILED |
+ SDMMC_ERROR_GENERAL_UNKNOWN_ERR))
+ {
+ MODIFY_REG(hsdio->Instance->DCTRL, SDMMC_DCTRL_FIFORST, SDMMC_DCTRL_FIFORST);
+ __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
+ __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_DATA_FLAGS);
+ hsdio->State = HAL_SDIO_STATE_READY;
+ hsdio->Context = SDIO_CONTEXT_NONE;
+ return HAL_ERROR;
+ }
+ }
+ /* Write block(s) in polling mode */
+ dataremaining = config.DataLength;
+ while (!__HAL_SDIO_GET_FLAG(hsdio, SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT |
+ SDMMC_FLAG_DATAEND))
+ {
+
+ if (__HAL_SDIO_GET_FLAG(hsdio, SDMMC_FLAG_TXFIFOHE) && (dataremaining >= SDMMC_FIFO_SIZE))
+ {
+ /* Read data from SDMMC Rx FIFO */
+ for (regCount = 0U; regCount < (SDMMC_FIFO_SIZE / 4U); regCount++)
+ {
+ hsdio->Instance->FIFO = *u32tempbuff;
+ u32tempbuff++;
+ }
+ dataremaining -= SDMMC_FIFO_SIZE;
+ }
+ else if ((__HAL_SDIO_GET_FLAG(hsdio, SDMMC_FLAG_TXFIFOHE | SDMMC_FLAG_TXFIFOE)) &&
+ (dataremaining < SDMMC_FIFO_SIZE))
+ {
+ const uint8_t *u8buff = (uint8_t *)u32tempbuff;
+ while (dataremaining > 0U)
+ {
+ data = 0U;
+ for (byteCount = 0U; (byteCount < 4U) && (dataremaining > 0U); byteCount++)
+ {
+ data |= ((uint32_t)(*u8buff) << (byteCount << 3U));
+ u8buff++;
+ dataremaining--;
+ }
+ hsdio->Instance->FIFO = data;
+ }
+ }
+ if (((HAL_GetTick() - tickstart) >= Timeout_Ms))
+ {
+ /* Clear all the static flags */
+ __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
+ hsdio->ErrorCode |= HAL_SDIO_ERROR_TIMEOUT;
+ hsdio->State = HAL_SDIO_STATE_READY;
+ hsdio->Context = SDIO_CONTEXT_NONE;
+ return HAL_TIMEOUT;
+ }
+ }
+
+ __SDMMC_CMDTRANS_DISABLE(hsdio->Instance);
+ /* Get error state */
+ if (__HAL_SDIO_GET_FLAG(hsdio, SDMMC_FLAG_DTIMEOUT))
+ {
+ /* Clear all the static flags */
+ __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
+ hsdio->ErrorCode |= HAL_SDIO_ERROR_DATA_TIMEOUT;
+ hsdio->State = HAL_SDIO_STATE_READY;
+ hsdio->Context = SDIO_CONTEXT_NONE;
+ return HAL_ERROR;
+ }
+ else if (__HAL_SDIO_GET_FLAG(hsdio, SDMMC_FLAG_DCRCFAIL))
+ {
+ /* Clear all the static flags */
+ __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
+ hsdio->ErrorCode |= HAL_SDIO_ERROR_DATA_CRC_FAIL;
+ hsdio->State = HAL_SDIO_STATE_READY;
+ hsdio->Context = SDIO_CONTEXT_NONE;
+ return HAL_ERROR;
+ }
+ else if (__HAL_SDIO_GET_FLAG(hsdio, SDMMC_FLAG_TXUNDERR))
+ {
+ /* Clear all the static flags */
+ __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
+ /* (SDIO_WRITE << 31) correspond to the write or read bit of the CMD argument */
+ hsdio->ErrorCode |= HAL_SDIO_ERROR_TX_UNDERRUN;
+ hsdio->State = HAL_SDIO_STATE_READY;
+ hsdio->Context = SDIO_CONTEXT_NONE;
+ return HAL_ERROR;
+ }
+ else if (hsdio->ErrorCode == SDMMC_ERROR_INVALID_PARAMETER)
+ {
+ __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_DATA_FLAGS);
+ hsdio->State = HAL_SDIO_STATE_READY;
+ hsdio->Context = SDIO_CONTEXT_NONE;
+ return HAL_ERROR;
+ }
+ else
+ {
+ /* Nothing to do */
+ }
+
+ /* Clear all the static flags */
+ __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_DATA_FLAGS);
+
+ hsdio->State = HAL_SDIO_STATE_READY;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Read data from a specified address using extended mode through cmd53 in DMA mode.
+ * @param hsdio: Pointer to SDIO handle
+ * @param Argument: Pointer to SDIO argument
+ * @param pData: pointer to the buffer that will contain the data to transmit
+ * @param Size_byte: Block size to write.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SDIO_ReadExtended_DMA(SDIO_HandleTypeDef *hsdio, const HAL_SDIO_ExtendedCmd_TypeDef *Argument,
+ uint8_t *pData, uint32_t Size_byte)
+{
+ SDMMC_DataInitTypeDef config;
+ uint32_t errorstate;
+ uint8_t *p_dma_buffer;
+ uint32_t cmd;
+ uint32_t nbr_of_block;
+
+ /* Check the parameters */
+ assert_param(hsdio != NULL);
+ assert_param(Argument != NULL);
+ assert_param(pData != NULL);
+
+ if ((hsdio == NULL) || (Argument == NULL) || (pData == NULL))
+ {
+ return HAL_ERROR;
+ }
+
+ if (hsdio->State == HAL_SDIO_STATE_READY)
+ {
+ hsdio->ErrorCode = HAL_SDIO_ERROR_NONE;
+ hsdio->State = HAL_SDIO_STATE_BUSY;
+
+ /* Initialize data control register */
+ if ((hsdio->Instance->DCTRL & SDMMC_DCTRL_SDIOEN) != 0U)
+ {
+ hsdio->Instance->DCTRL = SDMMC_DCTRL_SDIOEN;
+ }
+ else
+ {
+ hsdio->Instance->DCTRL = 0U;
+ }
+
+ p_dma_buffer = (uint8_t *)pData;
+ hsdio->pRxBuffPtr = (uint8_t *)pData;
+ hsdio->RxXferSize = Size_byte;
+ hsdio->next_data_addr = (uint32_t)pData;
+
+ /* Compute how many blocks are to be send for pData of length data_size to be send */
+ nbr_of_block = (Size_byte & ~(hsdio->block_size & 1U)) >> __CLZ(__RBIT(hsdio->block_size));
+
+ if (nbr_of_block != 0U)
+ {
+ hsdio->remaining_data = (Size_byte - (hsdio->block_size * nbr_of_block));
+ hsdio->next_reg_addr = (Argument->Reg_Addr) | ((((nbr_of_block * hsdio->block_size) >> 1U) & 0x3FFFU) << 1U)
+ | ((hsdio->remaining_data <= HAL_SDIO_DATA_BLOCK_SIZE_512BYTE) ? 1U : 0U);
+ hsdio->next_data_addr += (nbr_of_block * hsdio->block_size);
+ }
+ else
+ {
+ hsdio->next_data_addr += (Size_byte < HAL_SDIO_DATA_BLOCK_SIZE_512BYTE) ? Size_byte :
+ HAL_SDIO_DATA_BLOCK_SIZE_512BYTE;
+ if (hsdio->remaining_data != 0U)
+ {
+ hsdio->remaining_data = (Size_byte >= HAL_SDIO_DATA_BLOCK_SIZE_512BYTE) ?
+ (Size_byte - HAL_SDIO_DATA_BLOCK_SIZE_512BYTE) :
+ (Size_byte - hsdio->remaining_data);
+ hsdio->next_reg_addr += (Size_byte >= HAL_SDIO_DATA_BLOCK_SIZE_512BYTE) ? \
+ (HAL_SDIO_DATA_BLOCK_SIZE_512BYTE + 1U) : (Size_byte + 1U);
+ }
+ }
+
+ /* DMA configuration (use single buffer) */
+ hsdio->Instance->IDMACTRL = SDMMC_ENABLE_IDMA_SINGLE_BUFF;
+ hsdio->Instance->IDMABASER = (uint32_t)p_dma_buffer;
+
+ /* Configure the SD DPSM (Data Path State Machine) */
+ config.DataTimeOut = SDMMC_DATATIMEOUT;
+ if (Argument->Block_Mode == HAL_SDIO_MODE_BLOCK)
+ {
+ config.DataLength = (uint32_t)(nbr_of_block * hsdio->block_size);
+ config.DataBlockSize = SDIO_Convert_Block_Size(hsdio, hsdio->block_size);
+ }
+ else
+ {
+ config.DataLength = (Size_byte > 0U) ? Size_byte : HAL_SDIO_DATA_BLOCK_SIZE_512BYTE;
+ config.DataBlockSize = SDMMC_DATABLOCK_SIZE_1B;
+ }
+
+ config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC ;
+ config.TransferMode = (Argument->Block_Mode == HAL_SDIO_MODE_BLOCK) ? SDMMC_TRANSFER_MODE_BLOCK :
+ SDMMC_TRANSFER_MODE_SDIO;
+ config.DPSM = SDMMC_DPSM_DISABLE;
+ (void)SDMMC_ConfigData(hsdio->Instance, &config);
+
+ __SDMMC_CMDTRANS_ENABLE(hsdio->Instance);
+
+ /* Read */
+ hsdio->Context = (uint32_t)((Argument->Block_Mode == HAL_SDIO_MODE_BLOCK) ? SDIO_CONTEXT_READ_MULTIPLE_BLOCK :
+ SDIO_CONTEXT_READ_SINGLE_BLOCK) | SDIO_CONTEXT_DMA;
+
+ cmd = SDIO_READ << 31U;
+ cmd |= Argument->IOFunctionNbr << 28U;
+ cmd |= Argument->Block_Mode << 27U;
+ cmd |= Argument->OpCode << 26U;
+ cmd |= (Argument->Reg_Addr & 0x1FFFFU) << 9U;
+ cmd |= ((nbr_of_block == 0U) ? Size_byte : nbr_of_block) & 0x1FFU;
+ errorstate = SDMMC_SDIO_CmdReadWriteExtended(hsdio->Instance, cmd);
+ if (errorstate != HAL_SDIO_ERROR_NONE)
+ {
+ hsdio->ErrorCode |= errorstate;
+ if (errorstate != (SDMMC_ERROR_ADDR_OUT_OF_RANGE | SDMMC_ERROR_ILLEGAL_CMD | SDMMC_ERROR_COM_CRC_FAILED |
+ SDMMC_ERROR_GENERAL_UNKNOWN_ERR))
+ {
+ MODIFY_REG(hsdio->Instance->DCTRL, SDMMC_DCTRL_FIFORST, SDMMC_DCTRL_FIFORST);
+ __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
+ __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_DATA_FLAGS);
+ hsdio->State = HAL_SDIO_STATE_READY;
+ hsdio->Context = SDIO_CONTEXT_NONE;
+ return HAL_ERROR;
+ }
+ }
+ /* Enable interrupt */
+ __HAL_SDIO_ENABLE_IT(hsdio, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND));
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Write data from a specified address using extended mode through cmd53 in DMA mode.
+ * @param hsdio: Pointer to SDIO handle
+ * @param Argument: Pointer to SDIO argument
+ * @param pData: pointer to the buffer that will contain the data to transmit
+ * @param Size_byte: Block size to write.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SDIO_WriteExtended_DMA(SDIO_HandleTypeDef *hsdio, const HAL_SDIO_ExtendedCmd_TypeDef *Argument,
+ uint8_t *pData, uint32_t Size_byte)
+{
+ uint32_t cmd;
+ SDMMC_DataInitTypeDef config;
+ uint32_t errorstate;
+ uint8_t *p_dma_buffer;
+ uint32_t nbr_of_block;
+
+ /* Check the parameters */
+ assert_param(hsdio != NULL);
+ assert_param(Argument != NULL);
+ assert_param(pData != NULL);
+
+ if ((hsdio == NULL) || (Argument == NULL) || (pData == NULL))
+ {
+ return HAL_ERROR;
+ }
+
+ if (hsdio->State == HAL_SDIO_STATE_READY)
+ {
+ hsdio->ErrorCode = HAL_SDIO_ERROR_NONE;
+ hsdio->State = HAL_SDIO_STATE_BUSY;
+
+ /* Initialize data control register */
+ if ((hsdio->Instance->DCTRL & SDMMC_DCTRL_SDIOEN) != 0U)
+ {
+ hsdio->Instance->DCTRL = SDMMC_DCTRL_SDIOEN;
+ }
+ else
+ {
+ hsdio->Instance->DCTRL = 0U;
+ }
+
+ p_dma_buffer = (uint8_t *)pData;
+ hsdio->pTxBuffPtr = (uint8_t *)pData;
+ hsdio->TxXferSize = Size_byte;
+ hsdio->next_data_addr = (uint32_t)pData;
+
+ nbr_of_block = (Size_byte & ~(hsdio->block_size & 1U)) >> __CLZ(__RBIT(hsdio->block_size));
+
+ if (nbr_of_block != 0U)
+ {
+ hsdio->remaining_data = (Size_byte - (hsdio->block_size * nbr_of_block));
+ if (hsdio->block_size <= 128U)
+ {
+ hsdio->next_reg_addr = (Argument->Reg_Addr) |
+ ((((nbr_of_block * hsdio->block_size) >> 1U) & 0x3FFFU) << 1U) |
+ ((hsdio->remaining_data <= HAL_SDIO_DATA_BLOCK_SIZE_512BYTE) ? 1U : 0U);
+ }
+ else
+ {
+ hsdio->next_reg_addr = (nbr_of_block * hsdio->block_size) >> 1U;
+ }
+ hsdio->next_data_addr += (nbr_of_block * hsdio->block_size);
+ }
+ else
+ {
+ hsdio->remaining_data = (Size_byte >= HAL_SDIO_DATA_BLOCK_SIZE_512BYTE) ?
+ (Size_byte - HAL_SDIO_DATA_BLOCK_SIZE_512BYTE) :
+ (Size_byte - hsdio->remaining_data);
+ if (hsdio->remaining_data != 0U)
+ {
+ hsdio->remaining_data = (Size_byte >= HAL_SDIO_DATA_BLOCK_SIZE_512BYTE) ?
+ (Size_byte - HAL_SDIO_DATA_BLOCK_SIZE_512BYTE) :
+ (Size_byte - hsdio->remaining_data);
+ hsdio->next_reg_addr += ((Size_byte >= HAL_SDIO_DATA_BLOCK_SIZE_512BYTE) ? \
+ (HAL_SDIO_DATA_BLOCK_SIZE_512BYTE >> 1U) : (Size_byte >> 1U)) |
+ (((hsdio->remaining_data > 0U) ? 0U : 1U));
+ }
+ hsdio->next_data_addr += (Size_byte < HAL_SDIO_DATA_BLOCK_SIZE_512BYTE) ? Size_byte :
+ HAL_SDIO_DATA_BLOCK_SIZE_512BYTE;
+ }
+
+ /* DMA configuration (use single buffer) */
+ hsdio->Instance->IDMACTRL = SDMMC_ENABLE_IDMA_SINGLE_BUFF;
+ hsdio->Instance->IDMABASER = (uint32_t)p_dma_buffer;
+
+ /* Configure the SDIO DPSM (Data Path State Machine) */
+ config.DataTimeOut = SDMMC_DATATIMEOUT;
+ if (Argument->Block_Mode == HAL_SDIO_MODE_BLOCK)
+ {
+ config.DataLength = (uint32_t)(nbr_of_block * hsdio->block_size);
+ config.DataBlockSize = SDIO_Convert_Block_Size(hsdio, hsdio->block_size);
+ }
+ else
+ {
+ config.DataLength = (Size_byte > HAL_SDIO_DATA_BLOCK_SIZE_512BYTE) ? HAL_SDIO_DATA_BLOCK_SIZE_512BYTE : Size_byte;
+ config.DataBlockSize = SDMMC_DATABLOCK_SIZE_1B;
+ }
+
+ config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD;
+ config.TransferMode = (Argument->Block_Mode == HAL_SDIO_MODE_BLOCK) ? SDMMC_TRANSFER_MODE_BLOCK
+ : SDMMC_TRANSFER_MODE_SDIO;
+ config.DPSM = SDMMC_DPSM_DISABLE;
+ (void)SDMMC_ConfigData(hsdio->Instance, &config);
+
+ __SDMMC_CMDTRANS_ENABLE(hsdio->Instance);
+
+ /* Write */
+ hsdio->Context = (uint32_t)((Argument->Block_Mode == HAL_SDIO_MODE_BLOCK) ?
+ SDIO_CONTEXT_WRITE_MULTIPLE_BLOCK :
+ SDIO_CONTEXT_WRITE_SINGLE_BLOCK) | SDIO_CONTEXT_DMA;
+ cmd = SDIO_WRITE << 31U;
+ cmd |= Argument->IOFunctionNbr << 28U;
+ cmd |= Argument->Block_Mode << 27U;
+ cmd |= Argument->OpCode << 26U;
+ cmd |= (Argument->Reg_Addr & 0x1FFFFU) << 9U;
+ cmd |= ((nbr_of_block == 0U) ? ((Size_byte > HAL_SDIO_DATA_BLOCK_SIZE_512BYTE) ?
+ HAL_SDIO_DATA_BLOCK_SIZE_512BYTE : Size_byte) : nbr_of_block) & 0x1FFU;
+ errorstate = SDMMC_SDIO_CmdReadWriteExtended(hsdio->Instance, cmd);
+ if (errorstate != HAL_SDIO_ERROR_NONE)
+ {
+ hsdio->ErrorCode |= errorstate;
+ if (errorstate != (SDMMC_ERROR_ADDR_OUT_OF_RANGE | SDMMC_ERROR_ILLEGAL_CMD | SDMMC_ERROR_COM_CRC_FAILED |
+ SDMMC_ERROR_GENERAL_UNKNOWN_ERR))
+ {
+ MODIFY_REG(hsdio->Instance->DCTRL, SDMMC_DCTRL_FIFORST, SDMMC_DCTRL_FIFORST);
+ __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
+ __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_DATA_FLAGS);
+ hsdio->State = HAL_SDIO_STATE_READY;
+ hsdio->Context = SDIO_CONTEXT_NONE;
+ return HAL_ERROR;
+ }
+ }
+ /* Enable interrupt */
+ __HAL_SDIO_ENABLE_IT(hsdio, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND));
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @addtogroup SDIO_Exported_Functions_Group4
+ * @brief
+ *
+@verbatim
+ ==============================================================================
+ ##### IO operation functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set callback functions allowing to manage the data transfer from/to SDIO card.
+
+@endverbatim
+ * @{
+ */
+/**
+ * @brief This function handles SDIO device interrupt request.
+ * @param hsdio: Pointer to SDIO handle
+ * @retval None
+ */
+void HAL_SDIO_IRQHandler(SDIO_HandleTypeDef *hsdio)
+{
+ HAL_SDIO_ExtendedCmd_TypeDef CMD53_desc;
+ HAL_StatusTypeDef errorstate;
+ uint32_t ctx = hsdio->Context;
+ uint32_t flags;
+
+ flags = READ_REG(((SDMMC_TypeDef *)((uint32_t)(hsdio)->Instance))->STA);
+
+ if (READ_BIT(flags, SDMMC_FLAG_SDIOIT) != 0U)
+ {
+ (void)SDIO_IOFunction_IRQHandler(hsdio);
+ }
+
+ if (READ_BIT(flags, SDMMC_FLAG_DATAEND) != 0U)
+ {
+ __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_FLAG_DATAEND);
+
+ hsdio->State = HAL_SDIO_STATE_READY;
+
+ __HAL_SDIO_DISABLE_IT(hsdio, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR |
+ SDMMC_IT_RXOVERR | SDMMC_IT_TXFIFOHE | SDMMC_IT_RXFIFOHF);
+
+ __HAL_SDIO_DISABLE_IT(hsdio, SDMMC_IT_IDMABTC);
+ __SDMMC_CMDTRANS_DISABLE(hsdio->Instance);
+
+ if ((ctx & SDIO_CONTEXT_DMA) != 0U)
+ {
+ hsdio->Instance->DLEN = 0;
+ hsdio->Instance->IDMACTRL = SDMMC_DISABLE_IDMA;
+ if ((hsdio->Instance->DCTRL & SDMMC_DCTRL_SDIOEN) != 0U)
+ {
+ hsdio->Instance->DCTRL = SDMMC_DCTRL_SDIOEN;
+ }
+ else
+ {
+ hsdio->Instance->DCTRL = 0U;
+ }
+
+ hsdio->Context = SDIO_CONTEXT_NONE;
+ hsdio->State = HAL_SDIO_STATE_READY;
+ }
+
+ if (hsdio->remaining_data != 0U)
+ {
+ CMD53_desc.Block_Mode = HAL_SDIO_MODE_BYTE;
+ CMD53_desc.Reg_Addr = hsdio->next_reg_addr;
+ CMD53_desc.IOFunctionNbr = 1;
+ CMD53_desc.OpCode = 1;
+ if (((ctx & SDIO_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((ctx & SDIO_CONTEXT_READ_MULTIPLE_BLOCK) != 0U))
+ {
+ hsdio->pRxBuffPtr = (uint8_t *)hsdio->next_data_addr;
+ errorstate = HAL_SDIO_ReadExtended_DMA(hsdio, &CMD53_desc, hsdio->pRxBuffPtr, hsdio->remaining_data);
+ }
+ else
+ {
+ hsdio->pTxBuffPtr = (uint8_t *)hsdio->next_data_addr;
+ errorstate = HAL_SDIO_WriteExtended_DMA(hsdio, &CMD53_desc, hsdio->pTxBuffPtr, hsdio->remaining_data);
+ }
+ if (errorstate != HAL_OK)
+ {
+#if defined (USE_HAL_SDIO_REGISTER_CALLBACKS) && (USE_HAL_SDIO_REGISTER_CALLBACKS == 1)
+ hsdio->ErrorCallback(hsdio);
+#else
+ HAL_SDIO_ErrorCallback(hsdio);
+#endif /* USE_HAL_SDIO_REGISTER_CALLBACKS */
+ }
+ }
+ else if (((ctx & SDIO_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((ctx & SDIO_CONTEXT_READ_MULTIPLE_BLOCK) != 0U))
+ {
+#if defined (USE_HAL_SDIO_REGISTER_CALLBACKS) && (USE_HAL_SDIO_REGISTER_CALLBACKS == 1U)
+ hsdio->RxCpltCallback(hsdio);
+#else
+ HAL_SDIO_RxCpltCallback(hsdio);
+#endif /* USE_HAL_SDIO_REGISTER_CALLBACKS */
+ }
+ else
+ {
+#if defined (USE_HAL_SDIO_REGISTER_CALLBACKS) && (USE_HAL_SDIO_REGISTER_CALLBACKS == 1U)
+ hsdio->TxCpltCallback(hsdio);
+#else
+ HAL_SDIO_TxCpltCallback(hsdio);
+#endif /* USE_HAL_SDIO_REGISTER_CALLBACKS */
+ }
+ }
+
+ if (__HAL_SDIO_GET_FLAG(hsdio, SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_RXOVERR | SDMMC_FLAG_TXUNDERR))
+ {
+#if defined (USE_HAL_SDIO_REGISTER_CALLBACKS) && (USE_HAL_SDIO_REGISTER_CALLBACKS == 1)
+ hsdio->ErrorCallback(hsdio);
+#else
+ HAL_SDIO_ErrorCallback(hsdio);
+#endif /* USE_HAL_SDIO_REGISTER_CALLBACKS */
+ }
+}
+
+/**
+ * @brief Tx Transfer completed callbacks
+ * @param hsdio: Pointer to SDIO handle
+ * @retval None
+ */
+__weak void HAL_SDIO_TxCpltCallback(SDIO_HandleTypeDef *hsdio)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hsdio);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_SDIO_TxCpltCallback can be implemented in the user file
+ */
+}
+
+/**
+ * @brief Rx Transfer completed callbacks
+ * @param hsdio: Pointer SDIO handle
+ * @retval None
+ */
+__weak void HAL_SDIO_RxCpltCallback(SDIO_HandleTypeDef *hsdio)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hsdio);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_SDIO_RxCpltCallback can be implemented in the user file
+ */
+}
+
+/**
+ * @brief SDIO error callbacks
+ * @param hsdio: Pointer SDIO handle
+ * @retval None
+ */
+__weak void HAL_SDIO_ErrorCallback(SDIO_HandleTypeDef *hsdio)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hsdio);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_SDIO_ErrorCallback can be implemented in the user file
+ */
+}
+
+/**
+ * @brief SDIO IO Function complete callback
+ * @param hsdio: Pointer SDIO handle
+ * @param func: SDIO IO Function
+ * @retval None
+ */
+__weak void HAL_SDIO_IOFunctionCallback(SDIO_HandleTypeDef *hsdio, uint32_t func)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hsdio);
+ UNUSED(func);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_SDIO_ErrorCallback can be implemented in the user file
+ */
+}
+
+#if (USE_SDIO_TRANSCEIVER != 0U)
+/**
+ * @brief Enable/Disable the SDIO Transceiver 1.8V Mode Callback.
+ * @param hsdio: Pointer SDIO handle
+ * @param status: Voltage Switch State
+ * @retval None
+ */
+__weak void HAL_SDIO_DriveTransceiver_1_8V_Callback(SDIO_HandleTypeDef *hsdio, FlagStatus status)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hsdio);
+ UNUSED(status);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_SDIO_EnableTransceiver could be implemented in the user file
+ */
+}
+#endif /* USE_SDIO_TRANSCEIVER */
+
+#if defined (USE_HAL_SDIO_REGISTER_CALLBACKS) && (USE_HAL_SDIO_REGISTER_CALLBACKS == 1U)
+/**
+ * @brief Register a User SDIO Callback
+ * To be used instead of the weak (overridden) predefined callback
+ * @param hsdio : SDIO handle
+ * @param CallbackID : ID of the callback to be registered
+ * This parameter can be one of the following values:
+ * @arg @ref HAL_SDIO_TX_CPLT_CB_ID SDIO Tx Complete Callback ID
+ * @arg @ref HAL_SDIO_RX_CPLT_CB_ID SDIO Rx Complete Callback ID
+ * @arg @ref HAL_SDIO_ERROR_CB_ID SDIO Error Callback ID
+ * @arg @ref HAL_SDIO_MSP_INIT_CB_ID SDIO MspInit Callback ID
+ * @arg @ref HAL_SDIO_MSP_DEINIT_CB_ID SDIO MspDeInit Callback ID
+ * @param pCallback : pointer to the Callback function
+ * @retval status
+ */
+HAL_StatusTypeDef HAL_SDIO_RegisterCallback(SDIO_HandleTypeDef *hsdio, HAL_SDIO_CallbackIDTypeDef CallbackID,
+ pSDIO_CallbackTypeDef pCallback)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Check the parameters */
+ assert_param(hsdio != NULL);
+ assert_param(pCallback != NULL);
+
+ if (pCallback == NULL)
+ {
+ /* Update the error code */
+ hsdio->ErrorCode |= HAL_SDIO_ERROR_INVALID_CALLBACK;
+ return HAL_ERROR;
+ }
+
+ if (hsdio->State == HAL_SDIO_STATE_READY)
+ {
+ switch (CallbackID)
+ {
+ case HAL_SDIO_TX_CPLT_CB_ID :
+ hsdio->TxCpltCallback = pCallback;
+ break;
+ case HAL_SDIO_RX_CPLT_CB_ID :
+ hsdio->RxCpltCallback = pCallback;
+ break;
+ case HAL_SDIO_ERROR_CB_ID :
+ hsdio->ErrorCallback = pCallback;
+ break;
+ case HAL_SDIO_MSP_INIT_CB_ID :
+ hsdio->MspInitCallback = pCallback;
+ break;
+ case HAL_SDIO_MSP_DEINIT_CB_ID :
+ hsdio->MspDeInitCallback = pCallback;
+ break;
+ default :
+ /* Update the error code */
+ hsdio->ErrorCode |= HAL_SDIO_ERROR_INVALID_CALLBACK;
+ /* update return status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else if (hsdio->State == HAL_SDIO_STATE_RESET)
+ {
+ switch (CallbackID)
+ {
+ case HAL_SDIO_MSP_INIT_CB_ID :
+ hsdio->MspInitCallback = pCallback;
+ break;
+ case HAL_SDIO_MSP_DEINIT_CB_ID :
+ hsdio->MspDeInitCallback = pCallback;
+ break;
+ default :
+ /* Update the error code */
+ hsdio->ErrorCode |= HAL_SDIO_ERROR_INVALID_CALLBACK;
+ /* update return status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ /* Update the error code */
+ hsdio->ErrorCode |= HAL_SDIO_ERROR_INVALID_CALLBACK;
+ /* update return status */
+ status = HAL_ERROR;
+ }
+
+ return status;
+}
+
+/**
+ * @brief Unregister a User SDIO Callback
+ * SDIO Callback is redirected to the weak (overridden) predefined callback.
+ * @note The HAL_SDIO_UnRegisterCallback() may be called before HAL_SDIO_Init() in
+ * HAL_SDIO_STATE_RESET to register callbacks for HAL_SDIO_MSP_INIT_CB_ID
+ * and HAL_SDIO_MSP_DEINIT_CB_ID.
+ * @param hsdio : SDIO handle
+ * @param CallbackID : ID of the callback to be unregistered
+ * This parameter can be one of the following values @ref SDIO_Exported_Types_Group3.
+ * @retval status
+ */
+HAL_StatusTypeDef HAL_SDIO_UnRegisterCallback(SDIO_HandleTypeDef *hsdio, HAL_SDIO_CallbackIDTypeDef CallbackID)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ assert_param(hsdio != NULL);
+
+ /* Check the SDIO peripheral handle parameter */
+ if (hsdio == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ if (hsdio->State == HAL_SDIO_STATE_READY)
+ {
+ switch (CallbackID)
+ {
+ case HAL_SDIO_TX_CPLT_CB_ID :
+ hsdio->TxCpltCallback = HAL_SDIO_TxCpltCallback;
+ break;
+ case HAL_SDIO_RX_CPLT_CB_ID :
+ hsdio->RxCpltCallback = HAL_SDIO_RxCpltCallback;
+ break;
+ case HAL_SDIO_ERROR_CB_ID :
+ hsdio->ErrorCallback = HAL_SDIO_ErrorCallback;
+ break;
+ case HAL_SDIO_MSP_INIT_CB_ID :
+ hsdio->MspInitCallback = HAL_SDIO_MspInit;
+ break;
+ case HAL_SDIO_MSP_DEINIT_CB_ID :
+ hsdio->MspDeInitCallback = HAL_SDIO_MspDeInit;
+ break;
+ default :
+ hsdio->ErrorCode |= HAL_SDIO_ERROR_INVALID_CALLBACK;
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else if (hsdio->State == HAL_SDIO_STATE_RESET)
+ {
+ switch (CallbackID)
+ {
+ case HAL_SDIO_MSP_INIT_CB_ID :
+ hsdio->MspInitCallback = HAL_SDIO_MspInit;
+ break;
+ case HAL_SDIO_MSP_DEINIT_CB_ID :
+ hsdio->MspDeInitCallback = HAL_SDIO_MspDeInit;
+ break;
+ default :
+ hsdio->ErrorCode |= HAL_SDIO_ERROR_INVALID_CALLBACK;
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ hsdio->ErrorCode |= HAL_SDIO_ERROR_INVALID_CALLBACK;
+ status = HAL_ERROR;
+ }
+
+ return status;
+}
+#endif /* USE_HAL_SDIO_REGISTER_CALLBACKS */
+
+#if (USE_SDIO_TRANSCEIVER != 0U)
+/**
+ * @brief Register a User SDIO Transceiver Callback
+ * To be used instead of the weak (overridden) predefined callback
+ * @param hsdio : SDIO handle
+ * @param pCallback : pointer to the Callback function
+ * @retval status
+ */
+HAL_StatusTypeDef HAL_SDIO_RegisterTransceiverCallback(SDIO_HandleTypeDef *hsdio,
+ pSDIO_TransceiverCallbackTypeDef pCallback)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ if (pCallback == NULL)
+ {
+ /* Update the error code */
+ hsdio->ErrorCode |= HAL_SDIO_ERROR_INVALID_CALLBACK;
+ return HAL_ERROR;
+ }
+
+ if (hsdio->State == HAL_SDIO_STATE_READY)
+ {
+ hsdio->DriveTransceiver_1_8V_Callback = pCallback;
+ }
+ else
+ {
+ /* Update the error code */
+ hsdio->ErrorCode |= HAL_SDIO_ERROR_INVALID_CALLBACK;
+ /* update return status */
+ status = HAL_ERROR;
+ }
+
+ return status;
+}
+
+/**
+ * @brief Unregister a User SDIO Transceiver Callback
+ * SDIO Callback is redirected to the weak (overridden) predefined callback
+ * @param hsdio : SDIO handle
+ * @retval status
+ */
+HAL_StatusTypeDef HAL_SDIO_UnRegisterTransceiverCallback(SDIO_HandleTypeDef *hsdio)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ if (hsdio->State == HAL_SDIO_STATE_READY)
+ {
+ hsdio->DriveTransceiver_1_8V_Callback = HAL_SDIO_DriveTransceiver_1_8V_Callback;
+ }
+ else
+ {
+ /* Update the error code */
+ hsdio->ErrorCode |= HAL_SDIO_ERROR_INVALID_CALLBACK;
+ /* update return status */
+ status = HAL_ERROR;
+ }
+
+ return status;
+}
+#endif /* USE_SDIO_TRANSCEIVER */
+
+/**
+ * @brief Register a User SDIO Identification Callback
+ * @param hsdio: Pointer to SDIO handle
+ * @param pCallback: pointer to the Callback function
+ * @retval status
+ */
+HAL_StatusTypeDef HAL_SDIO_RegisterIdentifyCardCallback(SDIO_HandleTypeDef *hsdio,
+ pSDIO_IdentifyCardCallbackTypeDef pCallback)
+{
+ /* Check the parameters */
+ assert_param(hsdio != NULL);
+ assert_param(pCallback != NULL);
+
+ if (pCallback == NULL)
+ {
+ /* Update the error code */
+ hsdio->ErrorCode |= HAL_SDIO_ERROR_INVALID_CALLBACK;
+ return HAL_ERROR;
+ }
+
+ hsdio->SDIO_IdentifyCard = pCallback;
+
+ return HAL_OK;
+}
+/**
+ * @}
+ */
+
+/** @addtogroup SDIO_Exported_Functions_Group5
+ * @brief
+ *
+@verbatim
+ ==============================================================================
+ ##### Peripheral State and Errors functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control the SDIO card operations.
+
+@endverbatim
+ * @{
+ */
+/**
+ * @brief return the SDIO state
+ * @param hsdio: Pointer to SDIO handle
+ * @retval HAL state
+ */
+HAL_SDIO_StateTypeDef HAL_SDIO_GetState(const SDIO_HandleTypeDef *hsdio)
+{
+ return hsdio->State;
+}
+
+/**
+ * @brief Return the SDIO error code
+ * @param hsdio : Pointer to a SDIO_HandleTypeDef structure that contains the configuration information.
+ * @retval SDIO Error Code
+ */
+uint32_t HAL_SDIO_GetError(const SDIO_HandleTypeDef *hsdio)
+{
+ return hsdio->ErrorCode;
+}
+
+/**
+ * @}
+ */
+
+/** @addtogroup SDIO_Exported_Functions_Group6
+ * @brief
+ *
+@verbatim
+ ==============================================================================
+ ##### Peripheral IO interrupt #####
+ ==============================================================================
+ [..]
+ This subsection provides a set functions allowing to enable/disable IO functions interrupt features
+ on the SDIO card.
+
+@endverbatim
+ * @{
+ */
+/**
+ * @brief Enable SDIO IO interrupt.
+ * @param hsdio: Pointer to SDIO handle
+ * @param IOFunction: Specifies the SDIO IO function.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SDIO_EnableIOFunctionInterrupt(SDIO_HandleTypeDef *hsdio, uint32_t IOFunction)
+{
+ uint8_t intEn = 0U;
+
+ /* Check the parameters */
+ assert_param(hsdio != NULL);
+ assert_param(IS_SDIO_FUNCTION(IOFunction));
+
+ /* Check the SDIO peripheral handle parameter */
+ if (hsdio == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ if (SDIO_ReadDirect(hsdio, SDMMC_SDIO_CCCR4, HAL_SDIO_WRITE_ONLY, SDIO_FUNCTION_0, &intEn) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ /* if already enable , do not need enable again */
+ if ((((intEn >> (uint32_t)IOFunction) & 0x01U) == 0x01U) && ((intEn & 0x01U) != 0U))
+ {
+ return HAL_OK;
+ }
+ else
+ {
+ intEn |= (1U << (uint32_t)IOFunction) | 0x01U;
+ hsdio->IOInterruptNbr++;
+ }
+
+ if (SDIO_WriteDirect(hsdio, SDMMC_SDIO_CCCR4, HAL_SDIO_WRITE_ONLY, SDIO_FUNCTION_0,
+ &intEn) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ __HAL_SDIO_ENABLE_IT(hsdio, SDMMC_IT_SDIOIT);
+
+ /* Enable host SDIO interrupt operations */
+ __SDMMC_OPERATION_ENABLE(hsdio->Instance);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Enable SDIO IO interrupt.
+ * @param hsdio: Pointer to SDIO handle
+ * @param IOFunction: Specifies the SDIO IO function.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SDIO_DisableIOFunctionInterrupt(SDIO_HandleTypeDef *hsdio, uint32_t IOFunction)
+{
+ uint8_t intEn = 0U;
+
+ /* Check the parameters */
+ assert_param(hsdio != NULL);
+ assert_param(IS_SDIO_FUNCTION(IOFunction));
+
+ /* Check the SDIO peripheral handle parameter */
+ if (hsdio == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ if (SDIO_ReadDirect(hsdio, SDMMC_SDIO_CCCR4, HAL_SDIO_WRITE_ONLY, SDIO_FUNCTION_0, &intEn) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ /* if already disable , do not need enable again */
+ if (((intEn >> (uint32_t)IOFunction) & 0x01U) == 0x00U)
+ {
+ return HAL_OK;
+ }
+ else
+ {
+ /* disable the interrupt, don't disable the interrupt master here */
+ intEn &= ~(1U << (uint32_t)IOFunction);
+ }
+
+ if (SDIO_WriteDirect(hsdio, SDMMC_SDIO_CCCR4, HAL_SDIO_READ_AFTER_WRITE, SDIO_FUNCTION_0,
+ &intEn) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ if (hsdio->IOInterruptNbr > 1U)
+ {
+ hsdio->IOInterruptNbr--;
+ }
+ else
+ {
+ hsdio->IOInterruptNbr = 0U;
+ __HAL_SDIO_DISABLE_IT(hsdio, SDMMC_IT_SDIOIT);
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief Enable SDIO IO Enable.
+ * @param hsdio: Pointer to SDIO handle
+ * @param IOFunction: Specifies the SDIO IO function.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SDIO_EnableIOFunction(SDIO_HandleTypeDef *hsdio, uint32_t IOFunction)
+{
+ uint8_t ioEn = 0U;
+ uint8_t ioReady = 0U;
+
+ /* Check the parameters */
+ assert_param(hsdio != NULL);
+ assert_param(IS_SDIO_FUNCTION(IOFunction));
+
+ /* Check the SDIO peripheral handle parameter */
+ if (hsdio == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ if (SDIO_ReadDirect(hsdio, SDMMC_SDIO_CCCR0_SD_BYTE2, HAL_SDIO_WRITE_ONLY, SDIO_FUNCTION_0, &ioEn) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ /* if already enable , do not need to enable again */
+ if (((ioEn >> (uint32_t)IOFunction) & 0x01U) == 0x01U)
+ {
+ return HAL_OK;
+ }
+ else
+ {
+ ioEn |= (1U << (uint32_t)IOFunction);
+ }
+
+ if (SDIO_WriteDirect(hsdio, SDMMC_SDIO_CCCR0_SD_BYTE2, HAL_SDIO_READ_AFTER_WRITE, SDIO_FUNCTION_0, &ioEn) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ if (SDIO_ReadDirect(hsdio, SDMMC_SDIO_CCCR0_SD_BYTE3, HAL_SDIO_WRITE_ONLY, SDIO_FUNCTION_0, &ioReady) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+ /* check if IO ready */
+ if ((ioReady & (1U << (uint32_t)IOFunction)) != 0U)
+ {
+ return HAL_OK;
+ }
+
+ return HAL_ERROR;
+}
+
+/**
+ * @brief Disable SDIO IO Enable.
+ * @param hsdio: Pointer to SDIO handle
+ * @param IOFunction: Specifies the SDIO IO function.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SDIO_DisableIOFunction(SDIO_HandleTypeDef *hsdio, uint32_t IOFunction)
+{
+ uint8_t ioEn = 0U;
+
+ /* Check the parameters */
+ assert_param(hsdio != NULL);
+ assert_param(IS_SDIO_FUNCTION(IOFunction));
+
+ /* Check the SDIO peripheral handle parameter */
+ if (hsdio == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ if (SDIO_ReadDirect(hsdio, SDMMC_SDIO_CCCR0_SD_BYTE2, HAL_SDIO_WRITE_ONLY, SDIO_FUNCTION_0, &ioEn) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ /* if already enable , do not need enable again */
+ if (((ioEn >> (uint32_t)IOFunction) & 0x01U) == 0x00U)
+ {
+ return HAL_OK;
+ }
+ else
+ {
+ ioEn &= ~(1U << (uint32_t)IOFunction);
+ }
+
+ if (SDIO_WriteDirect(hsdio, SDMMC_SDIO_CCCR0_SD_BYTE2, HAL_SDIO_READ_AFTER_WRITE, SDIO_FUNCTION_0, &ioEn) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Select SDIO IO Enable.
+ * @param hsdio: Pointer to SDIO handle
+ * @param IOFunction: Specifies the SDIO IO function.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SDIO_SelectIOFunction(SDIO_HandleTypeDef *hsdio, uint32_t IOFunction)
+{
+ /* Check the parameters */
+ assert_param(hsdio != NULL);
+ assert_param(IS_SDIO_FUNCTION(IOFunction));
+
+ /* Check the SDIO peripheral handle parameter */
+ if (hsdio == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ if (SDIO_WriteDirect(hsdio, SDMMC_SDIO_CCCR12_SD_BYTE1, HAL_SDIO_READ_AFTER_WRITE, SDIO_FUNCTION_0,
+ (uint8_t *)&IOFunction) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Abort IO transfer.
+ * @param hsdio: Pointer to SDIO handle
+ * @param IOFunction IO number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SDIO_AbortIOFunction(SDIO_HandleTypeDef *hsdio, uint32_t IOFunction)
+{
+ /* Check the parameters */
+ assert_param(hsdio != NULL);
+ assert_param(IS_SDIO_FUNCTION(IOFunction));
+
+ /* Check the SDIO peripheral handle parameter */
+ if (hsdio == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ if (SDIO_WriteDirect(hsdio, SDMMC_SDIO_CCCR4_SD_BYTE2, HAL_SDIO_READ_AFTER_WRITE, SDIO_FUNCTION_0,
+ (uint8_t *)&IOFunction) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Enable Assynchrone interrupt.
+ * @param hsdio: Pointer to SDIO handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SDIO_EnableIOAsynInterrupt(SDIO_HandleTypeDef *hsdio)
+{
+ uint8_t enable_asyn_it = 0U;
+
+ /* Check the parameters */
+ assert_param(hsdio != NULL);
+
+ /* Check the SDIO peripheral handle parameter */
+ if (hsdio == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ if (SDIO_ReadDirect(hsdio, SDMMC_SDIO_CCCR20_SD_BYTE2, HAL_SDIO_WRITE_ONLY, SDIO_FUNCTION_0, &enable_asyn_it)
+ != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ /* if already enable , do not need enable again */
+ if ((enable_asyn_it & 0x02U) == 0x02U)
+ {
+ return HAL_OK;
+ }
+ else
+ {
+ enable_asyn_it |= 0x02U;
+ }
+
+ if (SDIO_WriteDirect(hsdio, SDMMC_SDIO_CCCR20_SD_BYTE2, HAL_SDIO_READ_AFTER_WRITE, SDIO_FUNCTION_0,
+ &enable_asyn_it) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Disable Assynchrone interrupt.
+ * @param hsdio: Pointer to SDIO handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SDIO_DisableIOAsynInterrupt(SDIO_HandleTypeDef *hsdio)
+{
+ uint8_t enable_asyn_it = 0U;
+
+ /* Check the parameters */
+ assert_param(hsdio != NULL);
+
+ /* Check the SDIO peripheral handle parameter */
+ if (hsdio == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ if (SDIO_ReadDirect(hsdio, SDMMC_SDIO_CCCR20_SD_BYTE2, HAL_SDIO_WRITE_ONLY, SDIO_FUNCTION_0, &enable_asyn_it)
+ != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ /* if already disable , do not need disable again */
+ if ((enable_asyn_it & 0x02U) == 0x00U)
+ {
+ return HAL_OK;
+ }
+ else
+ {
+ enable_asyn_it &= (uint8_t) ~(0x02U);
+ }
+
+ if (SDIO_WriteDirect(hsdio, SDMMC_SDIO_CCCR20_SD_BYTE2, HAL_SDIO_READ_AFTER_WRITE, SDIO_FUNCTION_0,
+ &enable_asyn_it) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief sdio set io IRQ handler.
+ * @param hsdio Pointer to SDIO handle
+ * @param IOFunction IO function io number.
+ * @param Callback io IRQ handler.
+ */
+HAL_StatusTypeDef HAL_SDIO_RegisterIOFunctionCallback(SDIO_HandleTypeDef *hsdio, uint32_t IOFunction,
+ HAL_SDIO_IOFunction_CallbackTypeDef pCallback)
+{
+ /* Check the parameters */
+ assert_param(hsdio != NULL);
+ assert_param(IS_SDIO_FUNCTION(IOFunction));
+
+ /* Check the SDIO peripheral handle parameter */
+ if (hsdio == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ hsdio->SDIO_IOFunction_Callback[(uint32_t)IOFunction] = pCallback;
+ hsdio->IOFunctionMask |= (1U << (uint8_t)IOFunction);
+
+ return HAL_OK;
+}
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Private function --------------------------------------------------------------------------------------------------*/
+/** @addtogroup SDIO_Private_Functions
+ * @{
+ */
+/**
+ * @brief Initializes the SDIO device.
+ * @param hsdio: Pointer to the SDIO handle
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef SDIO_InitCard(SDIO_HandleTypeDef *hsdio)
+{
+ uint32_t errorstate;
+ uint32_t timeout = 0U;
+ uint16_t sdio_rca = 1U;
+ uint32_t Resp4;
+ uint32_t nbr_of_func;
+
+ /* Identify card operating voltage */
+ errorstate = SDMMC_CmdGoIdleState(hsdio->Instance);
+ if (errorstate != HAL_SDIO_ERROR_NONE)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the power State */
+ if (SDMMC_GetPowerState(hsdio->Instance) == 0U)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Send CMD5 */
+ errorstate = SDMMC_CmdSendOperationcondition(hsdio->Instance, 0U, &Resp4);
+ if (errorstate != HAL_SDIO_ERROR_NONE)
+ {
+ return HAL_ERROR;
+ }
+
+ nbr_of_func = ((Resp4 & 0x70000000U) >> 28U);
+ /* Check if Nbr of function > 0 and OCR valid */
+ if (nbr_of_func > 0U)
+ {
+ /* Send CMD5 with arg= S18R, WV*/
+ if (SDMMC_CmdSendOperationcondition(hsdio->Instance, (SDIO_OCR_VDD_32_33 | SDIO_OCR_SDIO_S18R), &Resp4)
+ != HAL_SDIO_ERROR_NONE)
+ {
+ return HAL_ERROR;
+ }
+ /* Check if IORDY = 1 and S18A = 1 */
+ if ((((Resp4 & 0x80000000U) >> 31U) != 0U) && (((Resp4 & 0x1000000U) >> 24U) != 0U))
+ {
+ /* Send CMD11 to switch 1.8V mode */
+ errorstate = SDMMC_CmdVoltageSwitch(hsdio->Instance);
+ if (errorstate != HAL_SDIO_ERROR_NONE)
+ {
+ return HAL_ERROR;
+ }
+ }
+ else
+ {
+ /* S18A is not supported */
+ }
+ }
+
+ /** Cmd3 is sent while response is SDMMC_ERROR_ILLEGAL_CMD, due to the partial init test done before
+ * (sending cmd0 after the sequence cmd0/cmd3 is sent is considered illegal).
+ */
+ do
+ {
+ errorstate = SDMMC_CmdSetRelAdd(hsdio->Instance, &sdio_rca);
+ timeout++;
+ HAL_Delay(1);
+ } while ((errorstate == SDMMC_ERROR_ILLEGAL_CMD) && (timeout != SDIO_TIMEOUT));
+
+ if ((timeout == SDIO_TIMEOUT) || (errorstate != HAL_SDIO_ERROR_NONE))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Select the Card ( Sending CMD7)*/
+ errorstate = SDMMC_CmdSelDesel(hsdio->Instance, (uint32_t)(((uint32_t)sdio_rca) << 16U));
+ if (errorstate != HAL_SDIO_ERROR_NONE)
+ {
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Read 1 byte data.
+ * @param hsdio: Pointer to SDIO handle
+ * @param cmd_arg: formatted CMD52 structure
+ * @param pData: pointer to write or read data
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef SDIO_ReadDirect(SDIO_HandleTypeDef *hsdio, uint32_t addr, uint32_t raw,
+ uint32_t function_nbr, uint8_t *pData)
+{
+ uint32_t errorstate;
+ uint32_t cmd;
+
+ cmd = SDIO_READ << 31U;
+ cmd |= function_nbr << 28U;
+ cmd |= raw << 27U;
+ cmd |= (addr & 0x1FFFFU) << 9U;
+ errorstate = SDMMC_SDIO_CmdReadWriteDirect(hsdio->Instance, cmd, pData);
+ if (errorstate != HAL_SDIO_ERROR_NONE)
+ {
+ hsdio->ErrorCode |= errorstate;
+ /* Clear all the static flags */
+ __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
+ hsdio->State = HAL_SDIO_STATE_READY;
+ hsdio->Context = SDIO_CONTEXT_NONE;
+ return HAL_ERROR;
+ }
+ __SDMMC_CMDTRANS_DISABLE(hsdio->Instance);
+
+ /* Clear all the static flags */
+ __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_DATA_FLAGS);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Write 1 byte data.
+ * @param hsdio: Pointer to SDIO handle
+ * @param cmd_arg: formatted CMD52 structure
+ * @param pData: pointer to write or read data
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef SDIO_WriteDirect(SDIO_HandleTypeDef *hsdio, uint32_t addr, uint32_t raw,
+ uint32_t function_nbr, const uint8_t *pData)
+{
+ uint32_t errorstate;
+ uint32_t cmd;
+ uint8_t response;
+
+ cmd = SDIO_WRITE << 31U;
+ cmd |= function_nbr << 28U;
+ cmd |= raw << 27U;
+ cmd |= (addr & 0x1FFFFU) << 9U;
+ cmd |= ((uint32_t) * pData & 0x000000FFU);
+ errorstate = SDMMC_SDIO_CmdReadWriteDirect(hsdio->Instance, cmd, &response);
+
+ if (errorstate != HAL_SDIO_ERROR_NONE)
+ {
+ hsdio->ErrorCode |= errorstate;
+ /* Clear all the static flags */
+ __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
+ hsdio->State = HAL_SDIO_STATE_READY;
+ hsdio->Context = SDIO_CONTEXT_NONE;
+ return HAL_ERROR;
+ }
+ __SDMMC_CMDTRANS_DISABLE(hsdio->Instance);
+
+ /* Clear all the static flags */
+ __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_DATA_FLAGS);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Write multiple data with a single command.
+ * @param hsdio: Pointer to SDIO handle
+ * @param cmd_arg: formatted cmd53 structure
+ * @param Size_byte: block size if CMD53 defined in HAL_SDIO_MODE_BLOCK
+ * @param pData: pointer to write or read data
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef SDIO_WriteExtended(SDIO_HandleTypeDef *hsdio, HAL_SDIO_ExtendedCmd_TypeDef *cmd_arg,
+ uint8_t *pData, uint16_t Size_byte)
+{
+ SDMMC_DataInitTypeDef config;
+ uint32_t errorstate;
+ uint32_t tickstart = HAL_GetTick();
+ uint32_t regCount;
+ uint8_t byteCount;
+ uint32_t data;
+ uint32_t dataremaining;
+ uint32_t *u32tempbuff = (uint32_t *)(uint32_t)pData;
+ SDMMC_TypeDef *SDMMCx;
+ uint32_t cmd;
+ uint32_t nbr_of_block;
+
+ hsdio->ErrorCode = HAL_SDIO_ERROR_NONE;
+
+ /* Compute how many blocks are to be send for pData of length data_size to be send */
+ nbr_of_block = (((uint32_t)Size_byte & ~((uint32_t)hsdio->block_size & 1U))) >> __CLZ(__RBIT(hsdio->block_size));
+
+ /* Initialize data control register */
+ if ((hsdio->Instance->DCTRL & SDMMC_DCTRL_SDIOEN) != 0U)
+ {
+ hsdio->Instance->DCTRL = SDMMC_DCTRL_SDIOEN;
+ }
+ else
+ {
+ hsdio->Instance->DCTRL = 0U;
+ }
+
+ /* Configure the SDIO DPSM (Data Path State Machine) */
+ config.DataTimeOut = SDMMC_DATATIMEOUT;
+ if (cmd_arg->Block_Mode == HAL_SDIO_MODE_BLOCK)
+ {
+ config.DataLength = (uint32_t)(nbr_of_block * hsdio->block_size);
+ config.DataBlockSize = SDIO_Convert_Block_Size(hsdio, hsdio->block_size);
+ }
+ else
+ {
+ config.DataLength = Size_byte;
+ config.DataBlockSize = SDMMC_DATABLOCK_SIZE_1B;
+ }
+
+ config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD;
+ config.TransferMode = (cmd_arg->Block_Mode == HAL_SDIO_MODE_BLOCK) ? SDMMC_TRANSFER_MODE_BLOCK :
+ SDMMC_TRANSFER_MODE_SDIO;
+ config.DPSM = SDMMC_DPSM_DISABLE;
+ (void)SDMMC_ConfigData(hsdio->Instance, &config);
+ __SDMMC_CMDTRANS_ENABLE(hsdio->Instance);
+
+ hsdio->Context = (cmd_arg->Block_Mode == HAL_SDIO_MODE_BLOCK) ? SDIO_CONTEXT_WRITE_MULTIPLE_BLOCK :
+ SDIO_CONTEXT_WRITE_SINGLE_BLOCK;
+ cmd = SDIO_WRITE << 31U;
+ cmd |= cmd_arg->IOFunctionNbr << 28U;
+ cmd |= cmd_arg->Block_Mode << 27U;
+ cmd |= cmd_arg->OpCode << 26U;
+ cmd |= (cmd_arg->Reg_Addr & 0x1FFFFU) << 9U;
+ cmd |= (((uint32_t)Size_byte) & 0x1FFU);
+ errorstate = SDMMC_SDIO_CmdReadWriteExtended(hsdio->Instance, cmd);
+ if (errorstate != HAL_SDIO_ERROR_NONE)
+ {
+ MODIFY_REG(hsdio->Instance->DCTRL, SDMMC_DCTRL_FIFORST, SDMMC_DCTRL_FIFORST);
+ __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
+ __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_DATA_FLAGS);
+ hsdio->ErrorCode |= errorstate;
+ hsdio->State = HAL_SDIO_STATE_READY;
+ hsdio->Context = SDIO_CONTEXT_NONE;
+ return HAL_ERROR;
+ }
+
+ SDMMCx = hsdio->Instance;
+ dataremaining = config.DataLength;
+ while (!__HAL_SDIO_GET_FLAG(hsdio, SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT |
+ SDMMC_FLAG_DATAEND))
+ {
+ if (__HAL_SDIO_GET_FLAG(hsdio, SDMMC_FLAG_TXFIFOHE) &&
+ (dataremaining >= SDMMC_FIFO_SIZE))
+ {
+ for (regCount = SDMMC_FIFO_SIZE / 4U; regCount > 0U; regCount--)
+ {
+ SDMMCx->FIFO = *u32tempbuff;
+ u32tempbuff++;
+ }
+ dataremaining -= SDMMC_FIFO_SIZE;
+ }
+ else if ((__HAL_SDIO_GET_FLAG(hsdio, SDMMC_FLAG_TXFIFOHE | SDMMC_FLAG_TXFIFOE)) &&
+ (dataremaining < SDMMC_FIFO_SIZE))
+ {
+ const uint8_t *u8buff = (uint8_t *)u32tempbuff;
+ while (dataremaining > 0U)
+ {
+ data = 0U;
+ for (byteCount = 0U; (byteCount < 4U) && (dataremaining > 0U); byteCount++)
+ {
+ data |= ((uint32_t)(*u8buff) << (byteCount << 3U));
+ u8buff++;
+ dataremaining--;
+ }
+ SDMMCx->FIFO = data;
+ }
+ }
+ if ((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT)
+ {
+ __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
+ hsdio->ErrorCode |= HAL_SDIO_ERROR_TIMEOUT;
+ hsdio->State = HAL_SDIO_STATE_READY;
+ hsdio->Context = SDIO_CONTEXT_NONE;
+ return HAL_TIMEOUT;
+ }
+ }
+
+ __SDMMC_CMDTRANS_DISABLE(hsdio->Instance);
+ if (__HAL_SDIO_GET_FLAG(hsdio, SDMMC_FLAG_DTIMEOUT))
+ {
+ __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
+ hsdio->ErrorCode |= HAL_SDIO_ERROR_DATA_TIMEOUT;
+ hsdio->State = HAL_SDIO_STATE_READY;
+ hsdio->Context = SDIO_CONTEXT_NONE;
+ return HAL_ERROR;
+ }
+ else if (__HAL_SDIO_GET_FLAG(hsdio, SDMMC_FLAG_DCRCFAIL))
+ {
+ __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
+ hsdio->ErrorCode |= HAL_SDIO_ERROR_DATA_CRC_FAIL;
+ hsdio->State = HAL_SDIO_STATE_READY;
+ hsdio->Context = SDIO_CONTEXT_NONE;
+ return HAL_ERROR;
+ }
+ else if (__HAL_SDIO_GET_FLAG(hsdio, SDMMC_FLAG_TXUNDERR))
+ {
+ __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_FLAGS);
+ hsdio->ErrorCode |= HAL_SDIO_ERROR_TX_UNDERRUN;
+ hsdio->State = HAL_SDIO_STATE_READY;
+ hsdio->Context = SDIO_CONTEXT_NONE;
+ return HAL_ERROR;
+ }
+ else if (hsdio->ErrorCode == SDMMC_ERROR_INVALID_PARAMETER)
+ {
+ __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_DATA_FLAGS);
+ hsdio->State = HAL_SDIO_STATE_READY;
+ hsdio->Context = SDIO_CONTEXT_NONE;
+ return HAL_ERROR;
+ }
+ else
+ {
+ /* Nothing to do */
+ }
+
+ __HAL_SDIO_CLEAR_FLAG(hsdio, SDMMC_STATIC_DATA_FLAGS);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Allows to convert a block size in the according SDMMC value for configuring the SDMMC when doing a CMD53
+ * @param hsdio: Pointer to the SDIO handle.
+ * @param block_size: block size in bytes
+ * @retval block size as DBLOCKSIZE[3:0] bits format
+ */
+static uint8_t SDIO_Convert_Block_Size(const SDIO_HandleTypeDef *hsdio, uint32_t block_size)
+{
+ UNUSED(hsdio);
+
+ uint8_t most_bit = (uint8_t)__CLZ(__RBIT(block_size));
+ /*(1 << most_bit) - 1) is the mask used for blocksize*/
+ if (((uint8_t)block_size & ((1U << most_bit) - 1U)) != 0U)
+ {
+ return (uint8_t)SDMMC_DATABLOCK_SIZE_4B;
+ }
+ return most_bit << SDMMC_DCTRL_DBLOCKSIZE_Pos;
+}
+
+/*!
+ * @brief SDIO card io pending interrupt handle function.
+ * @note This function is used to handle the pending io interrupt.
+ * To register a IO IRQ handler, Use HAL_SDIO_EnableIOInterrupt and HAL_SDIO_SetIOIRQHandler
+ * @param hsdio: Pointer to SDIO handle
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef SDIO_IOFunction_IRQHandler(SDIO_HandleTypeDef *hsdio)
+{
+ uint8_t count;
+ uint8_t pendingInt;
+
+ if (hsdio->IOInterruptNbr == 1U)
+ {
+ if ((hsdio->SDIO_IOFunction_Callback[hsdio->IOFunctionMask - 1U]) != NULL)
+ {
+ (hsdio->SDIO_IOFunction_Callback[hsdio->IOFunctionMask - 1U])(hsdio, hsdio->IOFunctionMask - 1U);
+ }
+ }
+ else if ((hsdio->IOInterruptNbr > 1U) && (hsdio->IOFunctionMask != 0U))
+ {
+ /* Get pending int firstly */
+ if (SDIO_ReadDirect(hsdio, SDMMC_SDIO_CCCR4_SD_BYTE1, HAL_SDIO_WRITE_ONLY, SDIO_FUNCTION_0, &pendingInt) !=
+ HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ if ((pendingInt != 0U) && (hsdio->IOFunctionMask != 0U))
+ {
+ for (count = 1; count <= SDIO_MAX_IO_NUMBER; count++)
+ {
+ if (((pendingInt & (1U << count)) != 0U) && (((1U << count) & hsdio->IOFunctionMask) != 0U))
+ {
+ if ((hsdio->SDIO_IOFunction_Callback[count - 1U]) != NULL)
+ {
+ (hsdio->SDIO_IOFunction_Callback[count - 1U])(hsdio, count);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ /* Nothing to do */
+ }
+
+ return HAL_OK;
+}
+/**
+ * @}
+ */
+#endif /* HAL_SDIO_MODULE_ENABLED */
+#endif /* SDMMC1 || SDMMC2 */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
diff --git a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_uart.c b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_uart.c
index c0f6fb8dc2..922c2db45f 100644
--- a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_uart.c
+++ b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_uart.c
@@ -1024,75 +1024,79 @@ HAL_StatusTypeDef HAL_UART_UnRegisterRxEventCallback(UART_HandleTypeDef *huart)
===============================================================================
##### IO operation functions #####
===============================================================================
+ [..]
This subsection provides a set of functions allowing to manage the UART asynchronous
and Half duplex data transfers.
- (#) There are two mode of transfer:
- (+) Blocking mode: The communication is performed in polling mode.
- The HAL status of all data processing is returned by the same function
- after finishing transfer.
- (+) Non-Blocking mode: The communication is performed using Interrupts
- or DMA, These API's return the HAL status.
- The end of the data processing will be indicated through the
- dedicated UART IRQ when using Interrupt mode or the DMA IRQ when
- using DMA mode.
- The HAL_UART_TxCpltCallback(), HAL_UART_RxCpltCallback() user callbacks
- will be executed respectively at the end of the transmit or Receive process
- The HAL_UART_ErrorCallback()user callback will be executed when a communication error is detected
+ (#) There are two modes of transfer:
+ (++) Blocking mode: The communication is performed in polling mode.
+ The HAL status of all data processing is returned by the same function
+ after finishing transfer.
+ (++) Non-Blocking mode: The communication is performed using Interrupts
+ or DMA, These API's return the HAL status.
+ The end of the data processing will be indicated through the
+ dedicated UART IRQ when using Interrupt mode or the DMA IRQ when
+ using DMA mode.
+ The HAL_UART_TxCpltCallback(), HAL_UART_RxCpltCallback() user callbacks
+ will be executed respectively at the end of the transmit or Receive process
+ The HAL_UART_ErrorCallback()user callback will be executed when a communication error is detected
(#) Blocking mode API's are :
- (+) HAL_UART_Transmit()
- (+) HAL_UART_Receive()
+ (++) HAL_UART_Transmit()
+ (++) HAL_UART_Receive()
(#) Non-Blocking mode API's with Interrupt are :
- (+) HAL_UART_Transmit_IT()
- (+) HAL_UART_Receive_IT()
- (+) HAL_UART_IRQHandler()
+ (++) HAL_UART_Transmit_IT()
+ (++) HAL_UART_Receive_IT()
+ (++) HAL_UART_IRQHandler()
(#) Non-Blocking mode API's with DMA are :
- (+) HAL_UART_Transmit_DMA()
- (+) HAL_UART_Receive_DMA()
- (+) HAL_UART_DMAPause()
- (+) HAL_UART_DMAResume()
- (+) HAL_UART_DMAStop()
+ (++) HAL_UART_Transmit_DMA()
+ (++) HAL_UART_Receive_DMA()
+ (++) HAL_UART_DMAPause()
+ (++) HAL_UART_DMAResume()
+ (++) HAL_UART_DMAStop()
(#) A set of Transfer Complete Callbacks are provided in Non_Blocking mode:
- (+) HAL_UART_TxHalfCpltCallback()
- (+) HAL_UART_TxCpltCallback()
- (+) HAL_UART_RxHalfCpltCallback()
- (+) HAL_UART_RxCpltCallback()
- (+) HAL_UART_ErrorCallback()
+ (++) HAL_UART_TxHalfCpltCallback()
+ (++) HAL_UART_TxCpltCallback()
+ (++) HAL_UART_RxHalfCpltCallback()
+ (++) HAL_UART_RxCpltCallback()
+ (++) HAL_UART_ErrorCallback()
(#) Non-Blocking mode transfers could be aborted using Abort API's :
- (+) HAL_UART_Abort()
- (+) HAL_UART_AbortTransmit()
- (+) HAL_UART_AbortReceive()
- (+) HAL_UART_Abort_IT()
- (+) HAL_UART_AbortTransmit_IT()
- (+) HAL_UART_AbortReceive_IT()
+ (++) HAL_UART_Abort()
+ (++) HAL_UART_AbortTransmit()
+ (++) HAL_UART_AbortReceive()
+ (++) HAL_UART_Abort_IT()
+ (++) HAL_UART_AbortTransmit_IT()
+ (++) HAL_UART_AbortReceive_IT()
(#) For Abort services based on interrupts (HAL_UART_Abortxxx_IT), a set of Abort Complete Callbacks are provided:
- (+) HAL_UART_AbortCpltCallback()
- (+) HAL_UART_AbortTransmitCpltCallback()
- (+) HAL_UART_AbortReceiveCpltCallback()
+ (++) HAL_UART_AbortCpltCallback()
+ (++) HAL_UART_AbortTransmitCpltCallback()
+ (++) HAL_UART_AbortReceiveCpltCallback()
(#) A Rx Event Reception Callback (Rx event notification) is available for Non_Blocking modes of enhanced
reception services:
- (+) HAL_UARTEx_RxEventCallback()
+ (++) HAL_UARTEx_RxEventCallback()
+
+ (#) Wakeup from Stop mode Callback:
+ (++) HAL_UARTEx_WakeupCallback()
(#) In Non-Blocking mode transfers, possible errors are split into 2 categories.
Errors are handled as follows :
- (+) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is
- to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error
- in Interrupt mode reception .
- Received character is then retrieved and stored in Rx buffer, Error code is set to allow user
- to identify error type, and HAL_UART_ErrorCallback() user callback is executed.
- Transfer is kept ongoing on UART side.
- If user wants to abort it, Abort services should be called by user.
- (+) Error is considered as Blocking : Transfer could not be completed properly and is aborted.
- This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode.
- Error code is set to allow user to identify error type, and HAL_UART_ErrorCallback()
- user callback is executed.
+ (++) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is
+ to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error
+ in Interrupt mode reception .
+ Received character is then retrieved and stored in Rx buffer, Error code is set to allow user
+ to identify error type, and HAL_UART_ErrorCallback() user callback is executed.
+ Transfer is kept ongoing on UART side.
+ If user wants to abort it, Abort services should be called by user.
+ (++) Error is considered as Blocking : Transfer could not be completed properly and is aborted.
+ This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode.
+ Error code is set to allow user to identify error type, and HAL_UART_ErrorCallback()
+ user callback is executed.
-@- In the Half duplex communication, it is forbidden to run the transmit
and receive process in parallel, the UART state HAL_UART_STATE_BUSY_TX_RX can't be useful.
@@ -3867,12 +3871,24 @@ static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
If Reception till IDLE event has been selected : use Rx Event callback */
if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
{
+ huart->RxXferCount = 0;
+
+ /* Check current nb of data still to be received on DMA side.
+ DMA Normal mode, remaining nb of data will be 0
+ DMA Circular mode, remaining nb of data is reset to RxXferSize */
+ uint16_t nb_remaining_rx_data = (uint16_t) __HAL_DMA_GET_COUNTER(hdma);
+ if (nb_remaining_rx_data < huart->RxXferSize)
+ {
+ /* Update nb of remaining data */
+ huart->RxXferCount = nb_remaining_rx_data;
+ }
+
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered Rx Event callback*/
- huart->RxEventCallback(huart, huart->RxXferSize);
+ huart->RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount));
#else
/*Call legacy weak Rx Event callback*/
- HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
+ HAL_UARTEx_RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount));
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
else
@@ -3905,12 +3921,22 @@ static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
If Reception till IDLE event has been selected : use Rx Event callback */
if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
{
+ huart->RxXferCount = huart->RxXferSize / 2U;
+
+ /* Check current nb of data still to be received on DMA side. */
+ uint16_t nb_remaining_rx_data = (uint16_t) __HAL_DMA_GET_COUNTER(hdma);
+ if (nb_remaining_rx_data <= huart->RxXferSize)
+ {
+ /* Update nb of remaining data */
+ huart->RxXferCount = nb_remaining_rx_data;
+ }
+
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered Rx Event callback*/
- huart->RxEventCallback(huart, huart->RxXferSize / 2U);
+ huart->RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount));
#else
/*Call legacy weak Rx Event callback*/
- HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize / 2U);
+ HAL_UARTEx_RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount));
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
else
diff --git a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_uart_ex.c b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_uart_ex.c
index f1aa6d9e93..33ffdbeaa2 100644
--- a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_uart_ex.c
+++ b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_uart_ex.c
@@ -24,7 +24,7 @@
==============================================================================
##### UART peripheral extended features #####
==============================================================================
-
+ [..]
(#) Declare a UART_HandleTypeDef handle structure.
(#) For the UART RS485 Driver Enable mode, initialize the UART registers
@@ -253,15 +253,13 @@ HAL_StatusTypeDef HAL_RS485Ex_Init(UART_HandleTypeDef *huart, uint32_t Polarity,
===============================================================================
##### IO operation functions #####
===============================================================================
+ [..]
This subsection provides a set of Wakeup and FIFO mode related callback functions.
-
(#) Wakeup from Stop mode Callback:
- (+) HAL_UARTEx_WakeupCallback()
-
+ (++) HAL_UARTEx_WakeupCallback()
(#) TX/RX Fifos Callbacks:
- (+) HAL_UARTEx_RxFifoFullCallback()
- (+) HAL_UARTEx_TxFifoEmptyCallback()
-
+ (++) HAL_UARTEx_RxFifoFullCallback()
+ (++) HAL_UARTEx_TxFifoEmptyCallback()
@endverbatim
* @{
*/
@@ -341,19 +339,19 @@ __weak void HAL_UARTEx_TxFifoEmptyCallback(UART_HandleTypeDef *huart)
(#) Compared to standard reception services which only consider number of received
data elements as reception completion criteria, these functions also consider additional events
as triggers for updating reception status to caller :
- (+) Detection of inactivity period (RX line has not been active for a given period).
- (++) RX inactivity detected by IDLE event, i.e. RX line has been in idle state (normally high state)
+ (++) Detection of inactivity period (RX line has not been active for a given period).
+ (+++) RX inactivity detected by IDLE event, i.e. RX line has been in idle state (normally high state)
for 1 frame time, after last received byte.
- (++) RX inactivity detected by RTO, i.e. line has been in idle state
+ (+++) RX inactivity detected by RTO, i.e. line has been in idle state
for a programmable time, after last received byte.
- (+) Detection that a specific character has been received.
+ (++) Detection that a specific character has been received.
- (#) There are two mode of transfer:
- (+) Blocking mode: The reception is performed in polling mode, until either expected number of data is received,
+ (#) There are two modes of transfer:
+ (++) Blocking mode: The reception is performed in polling mode, until either expected number of data is received,
or till IDLE event occurs. Reception is handled only during function execution.
When function exits, no data reception could occur. HAL status and number of actually received data elements,
are returned by function after finishing transfer.
- (+) Non-Blocking mode: The reception is performed using Interrupts or DMA.
+ (++) Non-Blocking mode: The reception is performed using Interrupts or DMA.
These API's return the HAL status.
The end of the data processing will be indicated through the
dedicated UART IRQ when using Interrupt mode or the DMA IRQ when using DMA mode.
@@ -361,13 +359,13 @@ __weak void HAL_UARTEx_TxFifoEmptyCallback(UART_HandleTypeDef *huart)
The HAL_UART_ErrorCallback()user callback will be executed when a reception error is detected.
(#) Blocking mode API:
- (+) HAL_UARTEx_ReceiveToIdle()
+ (++) HAL_UARTEx_ReceiveToIdle()
(#) Non-Blocking mode API with Interrupt:
- (+) HAL_UARTEx_ReceiveToIdle_IT()
+ (++) HAL_UARTEx_ReceiveToIdle_IT()
(#) Non-Blocking mode API with DMA:
- (+) HAL_UARTEx_ReceiveToIdle_DMA()
+ (++) HAL_UARTEx_ReceiveToIdle_DMA()
@endverbatim
* @{
@@ -960,17 +958,15 @@ HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_
* Half Transfer, or Transfer Complete), this function allows to retrieve the Rx Event type that has lead
* to Rx Event callback execution.
* @note This function is expected to be called within the user implementation of Rx Event Callback,
- * in order to provide the accurate value :
- * In Interrupt Mode :
- * - HAL_UART_RXEVENT_TC : when Reception has been completed (expected nb of data has been received)
- * - HAL_UART_RXEVENT_IDLE : when Idle event occurred prior reception has been completed (nb of
- * received data is lower than expected one)
- * In DMA Mode :
- * - HAL_UART_RXEVENT_TC : when Reception has been completed (expected nb of data has been received)
- * - HAL_UART_RXEVENT_HT : when half of expected nb of data has been received
- * - HAL_UART_RXEVENT_IDLE : when Idle event occurred prior reception has been completed (nb of
- * received data is lower than expected one).
- * In DMA mode, RxEvent callback could be called several times;
+ * in order to provide the accurate value.
+ * @note In Interrupt Mode:
+ * - HAL_UART_RXEVENT_TC : when Reception has been completed (expected nb of data has been received).
+ * - HAL_UART_RXEVENT_IDLE : when Idle event occurred prior reception has been completed.
+ * @note In DMA Mode:
+ * - HAL_UART_RXEVENT_TC : when Reception has been completed (expected nb of data has been received).
+ * - HAL_UART_RXEVENT_HT : when half of expected nb of data has been received.
+ * - HAL_UART_RXEVENT_IDLE : when Idle event occurred prior reception has been completed.
+ * @note In DMA mode, RxEvent callback could be called several times;
* When DMA is configured in Normal Mode, HT event does not stop Reception process;
* When DMA is configured in Circular Mode, HT, TC or IDLE events don't stop Reception process;
* @param huart UART handle.
diff --git a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_xspi.c b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_xspi.c
index 466490ba4b..45458511fa 100644
--- a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_xspi.c
+++ b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_xspi.c
@@ -865,7 +865,7 @@ HAL_StatusTypeDef HAL_XSPI_Command(XSPI_HandleTypeDef *hxspi, XSPI_RegularCmdTyp
if (pCmd->DataMode == HAL_XSPI_DATA_NONE)
{
/* When there is no data phase, the transfer start as soon as the configuration is done
- so wait until BUSY flag is reset to go back in idle state */
+ so wait until BUSY flag is reset to go back in idle state. */
status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_BUSY, RESET, tickstart, Timeout);
/* Clear TC flag */
diff --git a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_dma.c b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_dma.c
index d2d784ac70..3a82fd84f4 100644
--- a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_dma.c
+++ b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_dma.c
@@ -807,7 +807,7 @@ void LL_DMA_NodeStructInit(LL_DMA_InitNodeTypeDef *DMA_InitNodeStruct)
* LL_DMA_LinkNodeTypeDef parameters.
* @retval None
*/
-uint32_t LL_DMA_CreateLinkNode(LL_DMA_InitNodeTypeDef *DMA_InitNodeStruct, LL_DMA_LinkNodeTypeDef *pNode)
+uint32_t LL_DMA_CreateLinkNode(const LL_DMA_InitNodeTypeDef *DMA_InitNodeStruct, LL_DMA_LinkNodeTypeDef *pNode)
{
uint32_t reg_counter = 0U;
@@ -847,7 +847,6 @@ uint32_t LL_DMA_CreateLinkNode(LL_DMA_InitNodeTypeDef *DMA_InitNodeStruct, LL_DM
assert_param(IS_LL_DMA_TRIGGER_SELECTION(DMA_InitNodeStruct->TriggerSelection));
}
- /* Check non 2D addressing settings */
{
assert_param(IS_LL_DMA_BURST_LENGTH(DMA_InitNodeStruct->SrcBurstLength));
assert_param(IS_LL_DMA_BURST_LENGTH(DMA_InitNodeStruct->DestBurstLength));
@@ -1015,7 +1014,6 @@ uint32_t LL_DMA_CreateLinkNode(LL_DMA_InitNodeTypeDef *DMA_InitNodeStruct, LL_DM
reg_counter++;
}
-
/* Update CTR3 register fields for 2D addressing channels */
if (DMA_InitNodeStruct->NodeType == LL_DMA_GPDMA_2D_NODE)
{
@@ -1091,6 +1089,7 @@ uint32_t LL_DMA_CreateLinkNode(LL_DMA_InitNodeTypeDef *DMA_InitNodeStruct, LL_DM
/* Reset of the CLLR of the node being created */
pNode->LinkRegisters[reg_counter] = 0U;
}
+
return (uint32_t)SUCCESS;
}
diff --git a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_exti.c b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_exti.c
index 5029fdbcf2..6180cf7830 100644
--- a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_exti.c
+++ b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_exti.c
@@ -259,6 +259,7 @@ ErrorStatus LL_EXTI_Init(LL_EXTI_InitTypeDef *EXTI_InitStruct)
/* De-configure EXTI Lines in range from 32 to 63 */
LL_EXTI_DisableIT_32_63(EXTI_InitStruct->Line_32_63);
LL_EXTI_DisableEvent_32_63(EXTI_InitStruct->Line_32_63);
+
}
return status;
}
diff --git a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_rcc.c b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_rcc.c
index 3930068f2a..bd2c619f6e 100644
--- a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_rcc.c
+++ b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_rcc.c
@@ -2098,7 +2098,6 @@ uint32_t LL_RCC_GetI3CClockFreq(uint32_t I3CxSource)
}
break;
-
case LL_RCC_I3C2_CLKSOURCE_NONE: /* No Clock used for I3C2 */
break;
diff --git a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_sdmmc.c b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_sdmmc.c
index 5ecc55c77b..646f0abde3 100644
--- a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_sdmmc.c
+++ b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_sdmmc.c
@@ -163,7 +163,7 @@
*/
#if defined (SDMMC1) || defined (SDMMC2)
-#if defined (HAL_SD_MODULE_ENABLED) || defined (HAL_MMC_MODULE_ENABLED)
+#if defined (HAL_SD_MODULE_ENABLED) || defined (HAL_MMC_MODULE_ENABLED) || defined (HAL_SDIO_MODULE_ENABLED)
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
@@ -349,7 +349,7 @@ uint32_t SDMMC_GetPowerState(const SDMMC_TypeDef *SDMMCx)
* the configuration information for the SDMMC command
* @retval HAL status
*/
-HAL_StatusTypeDef SDMMC_SendCommand(SDMMC_TypeDef *SDMMCx, SDMMC_CmdInitTypeDef *Command)
+HAL_StatusTypeDef SDMMC_SendCommand(SDMMC_TypeDef *SDMMCx, const SDMMC_CmdInitTypeDef *Command)
{
uint32_t tmpreg = 0;
@@ -417,7 +417,7 @@ uint32_t SDMMC_GetResponse(const SDMMC_TypeDef *SDMMCx, uint32_t Response)
* that contains the configuration information for the SDMMC data.
* @retval HAL status
*/
-HAL_StatusTypeDef SDMMC_ConfigData(SDMMC_TypeDef *SDMMCx, SDMMC_DataInitTypeDef *Data)
+HAL_StatusTypeDef SDMMC_ConfigData(SDMMC_TypeDef *SDMMCx, const SDMMC_DataInitTypeDef *Data)
{
uint32_t tmpreg = 0;
@@ -530,6 +530,30 @@ uint32_t SDMMC_CmdBlockLength(SDMMC_TypeDef *SDMMCx, uint32_t BlockSize)
return errorstate;
}
+/**
+ * @brief Send the Data Block number command and check the response
+ * @param SDMMCx: Pointer to SDMMC register base
+ * @retval HAL status
+ */
+uint32_t SDMMC_CmdBlockCount(SDMMC_TypeDef *SDMMCx, uint32_t BlockCount)
+{
+ SDMMC_CmdInitTypeDef sdmmc_cmdinit;
+ uint32_t errorstate;
+
+ /* Set Block Size for Card */
+ sdmmc_cmdinit.Argument = (uint32_t)BlockCount;
+ sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SET_BLOCK_COUNT;
+ sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
+ sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
+ sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
+ (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
+
+ /* Check for error conditions */
+ errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SET_BLOCK_COUNT, SDMMC_CMDTIMEOUT);
+
+ return errorstate;
+}
+
/**
* @brief Send the Read Single Block command and check the response
* @param SDMMCx: Pointer to SDMMC register base
@@ -1232,6 +1256,78 @@ uint32_t SDMMC_CmdSendEXTCSD(SDMMC_TypeDef *SDMMCx, uint32_t Argument)
return errorstate;
}
+/**
+ * @brief Execute a cmd52 to write single byte data and read single byte data if needed
+ * @param SDMMCx: Pointer to SDMMC register base
+ * @param Argument: SDMMC command argument which is sent to a card as part of a command message
+ * @param pData: pointer to read response if needed
+ * @retval SD Card error state
+ */
+uint32_t SDMMC_SDIO_CmdReadWriteDirect(SDMMC_TypeDef *SDMMCx, uint32_t Argument, uint8_t *pResponse)
+{
+ SDMMC_CmdInitTypeDef sdmmc_cmdinit;
+ uint32_t errorstate;
+
+ sdmmc_cmdinit.Argument = Argument;
+ sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SDMMC_RW_DIRECT;
+ sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
+ sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
+ sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
+ (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
+
+ /* Check for error conditions */
+ errorstate = SDMMC_GetCmdResp5(SDMMCx, SDMMC_CMD_SDMMC_RW_DIRECT, pResponse);
+
+ return errorstate;
+}
+
+/**
+ * @brief Execute a cmd53 to write or read multiple data with a single command
+ * @param SDMMCx: Pointer to SDMMC register base
+ * @param Argument: SDMMC command argument which is sent to a card as part of a command message
+ * @retval SD Card error state
+ */
+uint32_t SDMMC_SDIO_CmdReadWriteExtended(SDMMC_TypeDef *SDMMCx, uint32_t Argument)
+{
+ SDMMC_CmdInitTypeDef sdmmc_cmdinit;
+ uint32_t errorstate;
+
+ sdmmc_cmdinit.Argument = Argument;
+ sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SDMMC_RW_EXTENDED;
+ sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
+ sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
+ sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
+ (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
+
+ /* Check for error conditions */
+ errorstate = SDMMC_GetCmdResp5(SDMMCx, SDMMC_CMD_SDMMC_RW_EXTENDED, NULL);
+
+ return errorstate;
+}
+
+/**
+ * @brief Execute a cmd5 to write or read multiple data with a single command
+ * @param SDMMCx: Pointer to SDMMC register base
+ * @param Argument: SDMMC command argument which is sent to a card as part of a command message
+ * @retval SD Card error state
+ */
+uint32_t SDMMC_CmdSendOperationcondition(SDMMC_TypeDef *SDMMCx, uint32_t Argument, uint32_t *pResp)
+{
+ SDMMC_CmdInitTypeDef sdmmc_cmdinit;
+ uint32_t errorstate;
+
+ sdmmc_cmdinit.Argument = Argument;
+ sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SDMMC_SEN_OP_COND;
+ sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
+ sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
+ sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
+ (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
+
+ /* Check for error conditions */
+ errorstate = SDMMC_GetCmdResp4(SDMMCx, pResp);
+
+ return errorstate;
+}
/**
* @}
*/
@@ -1467,6 +1563,138 @@ uint32_t SDMMC_GetCmdResp3(SDMMC_TypeDef *SDMMCx)
return SDMMC_ERROR_NONE;
}
+/**
+ * @brief Checks for error conditions for R4 response.
+ * @param SDMMCx: Pointer to SDMMC register base
+ * @param pResp: pointer to response
+ * @retval error state
+ */
+uint32_t SDMMC_GetCmdResp4(SDMMC_TypeDef *SDMMCx, uint32_t *pResp)
+{
+ uint32_t sta_reg;
+
+ /* 8 is the number of required instructions cycles for the below loop statement.
+ The SDMMC_CMDTIMEOUT is expressed in ms */
+ uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U / 1000U);
+
+ do
+ {
+ if (count-- == 0U)
+ {
+ return SDMMC_ERROR_TIMEOUT;
+ }
+ sta_reg = SDMMCx->STA;
+ } while (((sta_reg & (SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT)) == 0U) ||
+ ((sta_reg & SDMMC_FLAG_CMDACT) != 0U));
+
+ if (__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT))
+ {
+ __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT);
+
+ return SDMMC_ERROR_CMD_RSP_TIMEOUT;
+ }
+ else
+ {
+ /* Clear all the static flags */
+ __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_CMD_FLAGS);
+ }
+
+ /* Clear all the static flags */
+ __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_CMD_FLAGS);
+
+ /* We have received response, retrieve it. */
+ *pResp = SDMMC_GetResponse(SDMMCx, SDMMC_RESP1);
+
+ return SDMMC_ERROR_NONE;
+}
+
+/**
+ * @brief Checks for error conditions for R5 (cmd52/cmd53) response.
+ * @param SDMMCx: Pointer to SDMMC register base
+ * @param SDIO_CMD: The sent command index
+ * @param pData: pointer to the read/write buffer needed for cmd52
+ * @retval SDIO Card error state
+ */
+uint32_t SDMMC_GetCmdResp5(SDMMC_TypeDef *SDMMCx, uint8_t SDIO_CMD, uint8_t *pData)
+{
+ uint32_t response_r5;
+ uint32_t sta_reg;
+
+ /* 8 is the number of required instructions cycles for the below loop statement.
+ The SDMMC_CMDTIMEOUT is expressed in ms */
+ uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U / 1000U);
+
+ do
+ {
+ if (count-- == 0U)
+ {
+ return SDMMC_ERROR_TIMEOUT;
+ }
+ sta_reg = SDMMCx->STA;
+ } while (((sta_reg & (SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT)) == 0U) ||
+ ((sta_reg & SDMMC_FLAG_CMDACT) != 0U));
+
+ if (__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT))
+ {
+ __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT);
+
+ return SDMMC_ERROR_CMD_RSP_TIMEOUT;
+ }
+ else if (__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL))
+ {
+ __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL);
+
+ return SDMMC_ERROR_CMD_CRC_FAIL;
+ }
+ else
+ {
+ /* Nothing to do */
+ }
+
+ /* Check response received is of desired command */
+ if (SDMMC_GetCommandResponse(SDMMCx) != SDIO_CMD)
+ {
+ return SDMMC_ERROR_CMD_CRC_FAIL;
+ }
+
+ /* Clear all the static flags */
+ __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_CMD_FLAGS);
+
+ /* We have received response, retrieve it. */
+ response_r5 = SDMMC_GetResponse(SDMMCx, SDMMC_RESP1);
+
+ if ((response_r5 & SDMMC_SDIO_R5_ERRORBITS) == SDMMC_ALLZERO)
+ {
+ /* we only want 8 bit read or write data and the 8 bit response flags are masked in the data pointer */
+ if (pData != NULL)
+ {
+ *pData = (uint8_t)(response_r5 & 0xFFU);
+ }
+
+ return SDMMC_ERROR_NONE;
+ }
+ else if ((response_r5 & SDMMC_SDIO_R5_OUT_OF_RANGE) == SDMMC_SDIO_R5_OUT_OF_RANGE)
+ {
+ return SDMMC_ERROR_ADDR_OUT_OF_RANGE;
+ }
+ else if ((response_r5 & SDMMC_SDIO_R5_INVALID_FUNCTION_NUMBER) == SDMMC_SDIO_R5_INVALID_FUNCTION_NUMBER)
+ {
+ return SDMMC_ERROR_INVALID_PARAMETER;
+ }
+ else if ((response_r5 & SDMMC_SDIO_R5_ILLEGAL_CMD) == SDMMC_SDIO_R5_ILLEGAL_CMD)
+ {
+ return SDMMC_ERROR_ILLEGAL_CMD;
+ }
+ else if ((response_r5 & SDMMC_SDIO_R5_COM_CRC_FAILED) == SDMMC_SDIO_R5_COM_CRC_FAILED)
+ {
+ return SDMMC_ERROR_COM_CRC_FAILED;
+ }
+ else
+ {
+ return SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
+ }
+}
+
/**
* @brief Checks for error conditions for R6 (RCA) response.
* @param hsd: SD handle
@@ -1621,7 +1849,7 @@ uint32_t SDMMC_GetCmdResp7(SDMMC_TypeDef *SDMMCx)
* @param pNodeConf: Pointer to configuration parameters for new node to add.
* @retval Error status
*/
-uint32_t SDMMC_DMALinkedList_BuildNode(SDMMC_DMALinkNodeTypeDef *pNode, SDMMC_DMALinkNodeConfTypeDef *pNodeConf)
+uint32_t SDMMC_DMALinkedList_BuildNode(SDMMC_DMALinkNodeTypeDef *pNode, const SDMMC_DMALinkNodeConfTypeDef *pNodeConf)
{
if ((pNode == NULL) || (pNodeConf == NULL))
diff --git a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_usb.c b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_usb.c
index 7904b05e68..950f815432 100644
--- a/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_usb.c
+++ b/system/Drivers/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_usb.c
@@ -799,12 +799,12 @@ HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef
else
{
pktcnt = (uint16_t)((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket);
- USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (pktcnt << 19));
+ USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & ((uint32_t)pktcnt << 19));
if (ep->type == EP_TYPE_ISOC)
{
USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_MULCNT);
- USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & (pktcnt << 29));
+ USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & ((uint32_t)pktcnt << 29));
}
}
@@ -1335,8 +1335,8 @@ void USB_ClearInterrupts(USB_OTG_GlobalTypeDef *USBx, uint32_t interrupt)
* @param USBx Selected device
* @retval return core mode : Host or Device
* This parameter can be one of these values:
- * 0 : Host
- * 1 : Device
+ * 1 : Host
+ * 0 : Device
*/
uint32_t USB_GetMode(const USB_OTG_GlobalTypeDef *USBx)
{
@@ -2616,6 +2616,10 @@ HAL_StatusTypeDef USB_ActivateEndpoint(USB_DRD_TypeDef *USBx, USB_DRD_EPTypeDef
PCD_CLEAR_RX_DTOG(USBx, ep->num);
PCD_CLEAR_TX_DTOG(USBx, ep->num);
+ /* Set endpoint RX count */
+ PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, ep->maxpacket);
+
+ /* Set endpoint RX to valid state */
PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
}
@@ -2720,7 +2724,7 @@ HAL_StatusTypeDef USB_EPStartXfer(USB_DRD_TypeDef *USBx, USB_DRD_EPTypeDef *ep)
/* IN endpoint */
if (ep->is_in == 1U)
{
- /*Multi packet transfer*/
+ /* Multi packet transfer */
if (ep->xfer_len > ep->maxpacket)
{
len = ep->maxpacket;
@@ -2822,9 +2826,9 @@ HAL_StatusTypeDef USB_EPStartXfer(USB_DRD_TypeDef *USBx, USB_DRD_EPTypeDef *ep)
USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
}
}
- else /* manage isochronous double buffer IN mode */
+ else /* Manage isochronous double buffer IN mode */
{
- /* each Time to write in PMA xfer_len_db will */
+ /* Each Time to write in PMA xfer_len_db will */
ep->xfer_len_db -= len;
/* Fill the data buffer */
@@ -2856,19 +2860,25 @@ HAL_StatusTypeDef USB_EPStartXfer(USB_DRD_TypeDef *USBx, USB_DRD_EPTypeDef *ep)
{
if (ep->doublebuffer == 0U)
{
+ if ((ep->xfer_len == 0U) && (ep->type == EP_TYPE_CTRL))
+ {
+ /* This is a status out stage set the OUT_STATUS */
+ PCD_SET_OUT_STATUS(USBx, ep->num);
+ }
+ else
+ {
+ PCD_CLEAR_OUT_STATUS(USBx, ep->num);
+ }
+
/* Multi packet transfer */
if (ep->xfer_len > ep->maxpacket)
{
- len = ep->maxpacket;
- ep->xfer_len -= len;
+ ep->xfer_len -= ep->maxpacket;
}
else
{
- len = ep->xfer_len;
ep->xfer_len = 0U;
}
- /* configure and validate Rx endpoint */
- PCD_SET_EP_RX_CNT(USBx, ep->num, len);
}
#if (USE_USB_DOUBLE_BUFFER == 1U)
else
@@ -2877,15 +2887,13 @@ HAL_StatusTypeDef USB_EPStartXfer(USB_DRD_TypeDef *USBx, USB_DRD_EPTypeDef *ep)
/* Set the Double buffer counter */
if (ep->type == EP_TYPE_BULK)
{
- PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, ep->maxpacket);
-
/* Coming from ISR */
if (ep->xfer_count != 0U)
{
- /* update last value to check if there is blocking state */
+ /* Update last value to check if there is blocking state */
wEPVal = (uint16_t)PCD_GET_ENDPOINT(USBx, ep->num);
- /*Blocking State */
+ /* Blocking State */
if ((((wEPVal & USB_EP_DTOG_RX) != 0U) && ((wEPVal & USB_EP_DTOG_TX) != 0U)) ||
(((wEPVal & USB_EP_DTOG_RX) == 0U) && ((wEPVal & USB_EP_DTOG_TX) == 0U)))
{
@@ -2896,18 +2904,8 @@ HAL_StatusTypeDef USB_EPStartXfer(USB_DRD_TypeDef *USBx, USB_DRD_EPTypeDef *ep)
/* iso out double */
else if (ep->type == EP_TYPE_ISOC)
{
- /* Multi packet transfer */
- if (ep->xfer_len > ep->maxpacket)
- {
- len = ep->maxpacket;
- ep->xfer_len -= len;
- }
- else
- {
- len = ep->xfer_len;
- ep->xfer_len = 0U;
- }
- PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, len);
+ /* Only single packet transfer supported in FS */
+ ep->xfer_len = 0U;
}
else
{
@@ -2951,26 +2949,23 @@ HAL_StatusTypeDef USB_EPSetStall(USB_DRD_TypeDef *USBx, USB_DRD_EPTypeDef *ep)
*/
HAL_StatusTypeDef USB_EPClearStall(USB_DRD_TypeDef *USBx, USB_DRD_EPTypeDef *ep)
{
- if (ep->doublebuffer == 0U)
+ if (ep->is_in != 0U)
{
- if (ep->is_in != 0U)
- {
- PCD_CLEAR_TX_DTOG(USBx, ep->num);
+ PCD_CLEAR_TX_DTOG(USBx, ep->num);
- if (ep->type != EP_TYPE_ISOC)
- {
- /* Configure NAK status for the Endpoint */
- PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
- }
- }
- else
+ if (ep->type != EP_TYPE_ISOC)
{
- PCD_CLEAR_RX_DTOG(USBx, ep->num);
-
- /* Configure VALID status for the Endpoint */
- PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
+ /* Configure NAK status for the Endpoint */
+ PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
}
}
+ else
+ {
+ PCD_CLEAR_RX_DTOG(USBx, ep->num);
+
+ /* Configure VALID status for the Endpoint */
+ PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
+ }
return HAL_OK;
}
diff --git a/system/Drivers/STM32YYxx_HAL_Driver_version.md b/system/Drivers/STM32YYxx_HAL_Driver_version.md
index fee8a5af5e..582b6088df 100644
--- a/system/Drivers/STM32YYxx_HAL_Driver_version.md
+++ b/system/Drivers/STM32YYxx_HAL_Driver_version.md
@@ -9,7 +9,7 @@
* STM32F7: 1.3.1
* STM32G0: 1.4.6
* STM32G4: 1.2.5
- * STM32H5: 1.4.0
+ * STM32H5: 1.5.0
* STM32H7: 1.11.5
* STM32L0: 1.10.6
* STM32L1: 1.4.5
diff --git a/system/STM32H5xx/stm32h5xx_hal_conf_default.h b/system/STM32H5xx/stm32h5xx_hal_conf_default.h
index 4eef816c84..e94a3cc697 100644
--- a/system/STM32H5xx/stm32h5xx_hal_conf_default.h
+++ b/system/STM32H5xx/stm32h5xx_hal_conf_default.h
@@ -82,6 +82,7 @@ extern "C" {
#define HAL_RTC_MODULE_ENABLED
#define HAL_SAI_MODULE_ENABLED
#define HAL_SD_MODULE_ENABLED
+#define HAL_SDIO_MODULE_ENABLED
#define HAL_SDRAM_MODULE_ENABLED
#define HAL_SMARTCARD_MODULE_ENABLED
#define HAL_SMBUS_MODULE_ENABLED
@@ -200,6 +201,14 @@ in voltage and temperature.*/
*/
/* #define USE_FULL_ASSERT 1U */
+/* ############################################ Max IO function number for SDIO device ############################## */
+#if !defined(SDIO_MAX_IO_NUMBER)
+#define SDIO_MAX_IO_NUMBER 7U /*!< SDIO device support maximum IO number */
+#endif
+#if !defined(USE_SDIO_TRANSCEIVER)
+#define USE_SDIO_TRANSCEIVER 0U /*!< SDIO Transceiver */
+#endif
+
/* ############################################ Register callback feature configuration ############################# */
/**
* @brief Set below the peripheral configuration to "1U" to add the support
@@ -303,6 +312,9 @@ in voltage and temperature.*/
#if !defined(USE_HAL_SD_REGISTER_CALLBACKS)
#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */
#endif
+#if !defined(USE_HAL_SDIO_REGISTER_CALLBACKS)
+#define USE_HAL_SDIO_REGISTER_CALLBACKS 0U /* SDIO register callback disabled */
+#endif
#if !defined(USE_HAL_SDRAM_REGISTER_CALLBACKS)
#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */
#endif
@@ -472,6 +484,10 @@ in voltage and temperature.*/
#include "stm32h5xx_hal_sd.h"
#endif /* HAL_SD_MODULE_ENABLED */
+#ifdef HAL_SDIO_MODULE_ENABLED
+#include "stm32h5xx_hal_sdio.h"
+#endif /* HAL_SDIO_MODULE_ENABLED */
+
#ifdef HAL_SMBUS_MODULE_ENABLED
#include "stm32h5xx_hal_smbus.h"
#endif /* HAL_SMBUS_MODULE_ENABLED */