[HAL][DSI] Align DSI ULPS entry and exit sequences with the reference manual
diff --git a/Src/stm32f7xx_hal_dsi.c b/Src/stm32f7xx_hal_dsi.c
index d498938..fc69d9e 100644
--- a/Src/stm32f7xx_hal_dsi.c
+++ b/Src/stm32f7xx_hal_dsi.c
@@ -173,7 +173,7 @@
/** @addtogroup DSI_Private_Constants
* @{
*/
-#define DSI_TIMEOUT_VALUE ((uint32_t)100U) /* 100ms */
+#define DSI_TIMEOUT_VALUE ((uint32_t)1000U) /* 1s */
#define DSI_ERROR_ACK_MASK (DSI_ISR0_AE0 | DSI_ISR0_AE1 | DSI_ISR0_AE2 | DSI_ISR0_AE3 | \
DSI_ISR0_AE4 | DSI_ISR0_AE5 | DSI_ISR0_AE6 | DSI_ISR0_AE7 | \
@@ -378,7 +378,7 @@
/* Enable the DSI PLL */
__HAL_DSI_PLL_ENABLE(hdsi);
- /* Requires min of 400µs delay before reading the PLLLS flag */
+ /* Requires min of 400us delay before reading the PLLLS flag */
/* 1ms delay is inserted that is the minimum HAL delay granularity */
HAL_Delay(1);
@@ -710,7 +710,7 @@
/**
* @brief Unregister a DSI Callback
- * DSI callabck is redirected to the weak predefined callback
+ * DSI callback is redirected to the weak predefined callback
* @param hdsi dsi handle
* @param CallbackID ID of the callback to be unregistered
* This parameter can be one of the following values:
@@ -1798,6 +1798,21 @@
return HAL_TIMEOUT;
}
+
+ /* Software workaround to avoid HAL_TIMEOUT when a DSI read command is */
+ /* issued to the panel and the read data is not captured by the DSI Host */
+ /* which returns Packet Size Error. */
+ /* Need to ensure that the Read command has finished before checking PSE */
+ if ((hdsi->Instance->GPSR & DSI_GPSR_RCB) == 0U)
+ {
+ if ((hdsi->Instance->ISR[1U] & DSI_ISR1_PSE) == DSI_ISR1_PSE)
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdsi);
+
+ return HAL_ERROR;
+ }
+ }
}
/* Process unlocked */
@@ -1820,6 +1835,85 @@
/* Process locked */
__HAL_LOCK(hdsi);
+ /* Verify the initial status of the DSI Host */
+
+ /* Verify that the clock lane and the digital section of the D-PHY are enabled */
+ if ((hdsi->Instance->PCTLR & (DSI_PCTLR_CKE | DSI_PCTLR_DEN)) != (DSI_PCTLR_CKE | DSI_PCTLR_DEN))
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdsi);
+ return HAL_ERROR;
+ }
+
+ /* Verify that the D-PHY PLL and the reference bias are enabled */
+ if ((hdsi->Instance->WRPCR & DSI_WRPCR_PLLEN) != DSI_WRPCR_PLLEN)
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdsi);
+ return HAL_ERROR;
+ }
+
+ /* Verify that there are no ULPS exit or request on data lanes */
+ if ((hdsi->Instance->PUCR & (DSI_PUCR_UEDL | DSI_PUCR_URDL)) != 0U)
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdsi);
+ return HAL_ERROR;
+ }
+
+ /* Verify that there are no Transmission trigger */
+ if ((hdsi->Instance->PTTCR & DSI_PTTCR_TX_TRIG) != 0U)
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdsi);
+ return HAL_ERROR;
+ }
+
+ /* Requires min of 400us delay before reading the PLLLS flag */
+ /* 1ms delay is inserted that is the minimum HAL delay granularity */
+ HAL_Delay(1);
+
+ /* Verify that D-PHY PLL is locked */
+ tickstart = HAL_GetTick();
+
+ while ((__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_PLLLS) == 0U))
+ {
+ /* Check for the Timeout */
+ if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdsi);
+
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Verify that all active lanes are in Stop state */
+ if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
+ {
+ if ((hdsi->Instance->PSR & DSI_PSR_UAN0) != DSI_PSR_UAN0)
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdsi);
+ return HAL_ERROR;
+ }
+ }
+ else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
+ {
+ if ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1)) != (DSI_PSR_UAN0 | DSI_PSR_UAN1))
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdsi);
+ return HAL_ERROR;
+ }
+ }
+ else
+ {
+ /* Process unlocked */
+ __HAL_UNLOCK(hdsi);
+ return HAL_ERROR;
+ }
+
/* ULPS Request on Data Lanes */
hdsi->Instance->PUCR |= DSI_PUCR_URDL;
@@ -1883,6 +1977,58 @@
/* Process locked */
__HAL_LOCK(hdsi);
+ /* Verify that all active lanes are in ULPM */
+ if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
+ {
+ if ((hdsi->Instance->PSR & DSI_PSR_UAN0) != 0U)
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdsi);
+
+ return HAL_ERROR;
+ }
+ }
+ else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
+ {
+ if ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1)) != 0U)
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdsi);
+
+ return HAL_ERROR;
+ }
+ }
+ else
+ {
+ /* Process unlocked */
+ __HAL_UNLOCK(hdsi);
+
+ return HAL_ERROR;
+ }
+
+ /* Turn on the DSI PLL */
+ __HAL_DSI_PLL_ENABLE(hdsi);
+
+ /* Requires min of 400us delay before reading the PLLLS flag */
+ /* 1ms delay is inserted that is the minimum HAL delay granularity */
+ HAL_Delay(1);
+
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait for the lock of the PLL */
+ while (__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_PLLLS) == 0U)
+ {
+ /* Check for the Timeout */
+ if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdsi);
+
+ return HAL_TIMEOUT;
+ }
+ }
+
/* Exit ULPS on Data Lanes */
hdsi->Instance->PUCR |= DSI_PUCR_UEDL;
@@ -1932,6 +2078,61 @@
/* De-assert the ULPM requests and the ULPM exit bits */
hdsi->Instance->PUCR = 0U;
+ /* Verify that D-PHY PLL is enabled */
+ if ((hdsi->Instance->WRPCR & DSI_WRPCR_PLLEN) != DSI_WRPCR_PLLEN)
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdsi);
+ return HAL_ERROR;
+ }
+
+ /* Verify that all active lanes are in Stop state */
+ if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
+ {
+ if ((hdsi->Instance->PSR & DSI_PSR_UAN0) != DSI_PSR_UAN0)
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdsi);
+ return HAL_ERROR;
+ }
+ }
+ else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
+ {
+ if ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1)) != (DSI_PSR_UAN0 | DSI_PSR_UAN1))
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdsi);
+ return HAL_ERROR;
+ }
+ }
+ else
+ {
+ /* Process unlocked */
+ __HAL_UNLOCK(hdsi);
+ return HAL_ERROR;
+ }
+
+ /* Verify that D-PHY PLL is locked */
+ /* Requires min of 400us delay before reading the PLLLS flag */
+ /* 1ms delay is inserted that is the minimum HAL delay granularity */
+ HAL_Delay(1);
+
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait for the lock of the PLL */
+ while (__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_PLLLS) == 0U)
+ {
+ /* Check for the Timeout */
+ if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdsi);
+
+ return HAL_TIMEOUT;
+ }
+ }
+
/* Process unlocked */
__HAL_UNLOCK(hdsi);
@@ -1952,6 +2153,86 @@
/* Process locked */
__HAL_LOCK(hdsi);
+ /* Verify the initial status of the DSI Host */
+
+ /* Verify that the clock lane and the digital section of the D-PHY are enabled */
+ if ((hdsi->Instance->PCTLR & (DSI_PCTLR_CKE | DSI_PCTLR_DEN)) != (DSI_PCTLR_CKE | DSI_PCTLR_DEN))
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdsi);
+ return HAL_ERROR;
+ }
+
+ /* Verify that the D-PHY PLL and the reference bias are enabled */
+ if ((hdsi->Instance->WRPCR & DSI_WRPCR_PLLEN) != DSI_WRPCR_PLLEN)
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdsi);
+ return HAL_ERROR;
+ }
+
+ /* Verify that there are no ULPS exit or request on both data and clock lanes */
+ if ((hdsi->Instance->PUCR & (DSI_PUCR_UEDL | DSI_PUCR_URDL | DSI_PUCR_UECL | DSI_PUCR_URCL)) != 0U)
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdsi);
+ return HAL_ERROR;
+ }
+
+ /* Verify that there are no Transmission trigger */
+ if ((hdsi->Instance->PTTCR & DSI_PTTCR_TX_TRIG) != 0U)
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdsi);
+ return HAL_ERROR;
+ }
+
+ /* Requires min of 400us delay before reading the PLLLS flag */
+ /* 1ms delay is inserted that is the minimum HAL delay granularity */
+ HAL_Delay(1);
+
+ /* Verify that D-PHY PLL is locked */
+ tickstart = HAL_GetTick();
+
+ while ((__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_PLLLS) == 0U))
+ {
+ /* Check for the Timeout */
+ if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdsi);
+
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Verify that all active lanes are in Stop state */
+ if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
+ {
+ if ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_PSS0)) != (DSI_PSR_UAN0 | DSI_PSR_PSS0))
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdsi);
+ return HAL_ERROR;
+ }
+ }
+ else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
+ {
+ if ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_PSS0 | DSI_PSR_PSS1 | \
+ DSI_PSR_UAN1)) != (DSI_PSR_UAN0 | DSI_PSR_PSS0 | DSI_PSR_PSS1 | DSI_PSR_UAN1))
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdsi);
+ return HAL_ERROR;
+ }
+ }
+ else
+ {
+ /* Process unlocked */
+ __HAL_UNLOCK(hdsi);
+ return HAL_ERROR;
+ }
+
/* Clock lane configuration: no more HS request */
hdsi->Instance->CLCR &= ~DSI_CLCR_DPCC;
@@ -1964,7 +2245,7 @@
/* Get tick */
tickstart = HAL_GetTick();
- /* Wait until all active lanes exit ULPM */
+ /* Wait until all active lanes enter ULPM */
if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
{
while ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UANC)) != 0U)
@@ -2024,9 +2305,44 @@
/* Process locked */
__HAL_LOCK(hdsi);
+ /* Verify that all active lanes are in ULPM */
+ if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
+ {
+ if ((hdsi->Instance->PSR & (DSI_PSR_RUE0 | DSI_PSR_UAN0 | DSI_PSR_PSS0 | \
+ DSI_PSR_UANC | DSI_PSR_PSSC | DSI_PSR_PD)) != 0U)
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdsi);
+
+ return HAL_ERROR;
+ }
+ }
+ else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
+ {
+ if ((hdsi->Instance->PSR & (DSI_PSR_RUE0 | DSI_PSR_UAN0 | DSI_PSR_PSS0 | DSI_PSR_UAN1 | \
+ DSI_PSR_PSS1 | DSI_PSR_UANC | DSI_PSR_PSSC | DSI_PSR_PD)) != 0U)
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdsi);
+
+ return HAL_ERROR;
+ }
+ }
+ else
+ {
+ /* Process unlocked */
+ __HAL_UNLOCK(hdsi);
+
+ return HAL_ERROR;
+ }
+
/* Turn on the DSI PLL */
__HAL_DSI_PLL_ENABLE(hdsi);
+ /* Requires min of 400us delay before reading the PLLLS flag */
+ /* 1ms delay is inserted that is the minimum HAL delay granularity */
+ HAL_Delay(1);
+
/* Get tick */
tickstart = HAL_GetTick();
@@ -2099,6 +2415,62 @@
/* Restore clock lane configuration to HS */
hdsi->Instance->CLCR |= DSI_CLCR_DPCC;
+ /* Verify that D-PHY PLL is enabled */
+ if ((hdsi->Instance->WRPCR & DSI_WRPCR_PLLEN) != DSI_WRPCR_PLLEN)
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdsi);
+ return HAL_ERROR;
+ }
+
+ /* Verify that all active lanes are in Stop state */
+ if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
+ {
+ if ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_PSS0)) != (DSI_PSR_UAN0 | DSI_PSR_PSS0))
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdsi);
+ return HAL_ERROR;
+ }
+ }
+ else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
+ {
+ if ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_PSS0 | DSI_PSR_PSS1 | \
+ DSI_PSR_UAN1)) != (DSI_PSR_UAN0 | DSI_PSR_PSS0 | DSI_PSR_PSS1 | DSI_PSR_UAN1))
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdsi);
+ return HAL_ERROR;
+ }
+ }
+ else
+ {
+ /* Process unlocked */
+ __HAL_UNLOCK(hdsi);
+ return HAL_ERROR;
+ }
+
+ /* Verify that D-PHY PLL is locked */
+ /* Requires min of 400us delay before reading the PLLLS flag */
+ /* 1ms delay is inserted that is the minimum HAL delay granularity */
+ HAL_Delay(1);
+
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait for the lock of the PLL */
+ while (__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_PLLLS) == 0U)
+ {
+ /* Check for the Timeout */
+ if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdsi);
+
+ return HAL_TIMEOUT;
+ }
+ }
+
/* Process unlocked */
__HAL_UNLOCK(hdsi);