Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:07

0001 /**
0002   ******************************************************************************
0003   * @file    stm32h7xx_hal_dsi.c
0004   * @author  MCD Application Team
0005   * @brief   DSI HAL module driver.
0006   *          This file provides firmware functions to manage the following
0007   *          functionalities of the DSI peripheral:
0008   *           + Initialization and de-initialization functions
0009   *           + IO operation functions
0010   *           + Peripheral Control functions
0011   *           + Peripheral State and Errors functions
0012   ******************************************************************************
0013   * @attention
0014   *
0015   * Copyright (c) 2017 STMicroelectronics.
0016   * All rights reserved.
0017   *
0018   * This software is licensed under terms that can be found in the LICENSE file
0019   * in the root directory of this software component.
0020   * If no LICENSE file comes with this software, it is provided AS-IS.
0021   *
0022   ******************************************************************************
0023   @verbatim
0024   ==============================================================================
0025                         ##### How to use this driver #####
0026   ==============================================================================
0027   [..]
0028     The DSI HAL driver can be used as follows:
0029 
0030     (#) Declare a DSI_HandleTypeDef handle structure, for example: DSI_HandleTypeDef  hdsi;
0031 
0032     (#) Initialize the DSI low level resources by implementing the HAL_DSI_MspInit() API:
0033         (##) Enable the DSI interface clock
0034         (##) NVIC configuration if you need to use interrupt process
0035             (+++) Configure the DSI interrupt priority
0036             (+++) Enable the NVIC DSI IRQ Channel
0037 
0038     (#) Initialize the DSI Host peripheral, the required PLL parameters, number of lances and
0039         TX Escape clock divider by calling the HAL_DSI_Init() API which calls HAL_DSI_MspInit().
0040 
0041     *** Configuration ***
0042     =========================
0043     [..]
0044     (#) Use HAL_DSI_ConfigAdaptedCommandMode() function to configure the DSI host in adapted
0045         command mode.
0046 
0047     (#) When operating in video mode , use HAL_DSI_ConfigVideoMode() to configure the DSI host.
0048 
0049     (#) Function HAL_DSI_ConfigCommand() is used to configure the DSI commands behavior in low power mode.
0050 
0051     (#) To configure the DSI PHY timings parameters, use function HAL_DSI_ConfigPhyTimer().
0052 
0053     (#) The DSI Host can be started/stopped using respectively functions HAL_DSI_Start() and HAL_DSI_Stop().
0054         Functions HAL_DSI_ShortWrite(), HAL_DSI_LongWrite() and HAL_DSI_Read() allows respectively
0055         to write DSI short packets, long packets and to read DSI packets.
0056 
0057     (#) The DSI Host Offers two Low power modes :
0058         (++) Low Power Mode on data lanes only: Only DSI data lanes are shut down.
0059             It is possible to enter/exit from this mode using respectively functions HAL_DSI_EnterULPMData()
0060             and HAL_DSI_ExitULPMData()
0061 
0062         (++) Low Power Mode on data and clock lanes : All DSI lanes are shut down including data and clock lanes.
0063             It is possible to enter/exit from this mode using respectively functions HAL_DSI_EnterULPM()
0064             and HAL_DSI_ExitULPM()
0065 
0066     (#) To control DSI state you can use the following function: HAL_DSI_GetState()
0067 
0068     *** Error management ***
0069     ========================
0070     [..]
0071     (#) User can select the DSI errors to be reported/monitored using function HAL_DSI_ConfigErrorMonitor()
0072         When an error occurs, the callback HAL_DSI_ErrorCallback() is asserted and then user can retrieve
0073         the error code by calling function HAL_DSI_GetError()
0074 
0075     *** DSI HAL driver macros list ***
0076     =============================================
0077     [..]
0078        Below the list of most used macros in DSI HAL driver.
0079 
0080       (+) __HAL_DSI_ENABLE: Enable the DSI Host.
0081       (+) __HAL_DSI_DISABLE: Disable the DSI Host.
0082       (+) __HAL_DSI_WRAPPER_ENABLE: Enables the DSI wrapper.
0083       (+) __HAL_DSI_WRAPPER_DISABLE: Disable the DSI wrapper.
0084       (+) __HAL_DSI_PLL_ENABLE: Enables the DSI PLL.
0085       (+) __HAL_DSI_PLL_DISABLE: Disables the DSI PLL.
0086       (+) __HAL_DSI_REG_ENABLE: Enables the DSI regulator.
0087       (+) __HAL_DSI_REG_DISABLE: Disables the DSI regulator.
0088       (+) __HAL_DSI_GET_FLAG: Get the DSI pending flags.
0089       (+) __HAL_DSI_CLEAR_FLAG: Clears the DSI pending flags.
0090       (+) __HAL_DSI_ENABLE_IT: Enables the specified DSI interrupts.
0091       (+) __HAL_DSI_DISABLE_IT: Disables the specified DSI interrupts.
0092       (+) __HAL_DSI_GET_IT_SOURCE: Checks whether the specified DSI interrupt source is enabled or not.
0093 
0094     [..]
0095       (@) You can refer to the DSI HAL driver header file for more useful macros
0096 
0097     *** Callback registration ***
0098     =============================================
0099     [..]
0100     The compilation define  USE_HAL_DSI_REGISTER_CALLBACKS when set to 1
0101     allows the user to configure dynamically the driver callbacks.
0102     Use Function HAL_DSI_RegisterCallback() to register a callback.
0103 
0104     [..]
0105     Function HAL_DSI_RegisterCallback() allows to register following callbacks:
0106       (+) TearingEffectCallback : DSI Tearing Effect Callback.
0107       (+) EndOfRefreshCallback  : DSI End Of Refresh Callback.
0108       (+) ErrorCallback         : DSI Error Callback
0109       (+) MspInitCallback       : DSI MspInit.
0110       (+) MspDeInitCallback     : DSI MspDeInit.
0111     [..]
0112     This function takes as parameters the HAL peripheral handle, the callback ID
0113     and a pointer to the user callback function.
0114 
0115     [..]
0116     Use function HAL_DSI_UnRegisterCallback() to reset a callback to the default
0117     weak function.
0118     HAL_DSI_UnRegisterCallback takes as parameters the HAL peripheral handle,
0119     and the callback ID.
0120     [..]
0121     This function allows to reset following callbacks:
0122       (+) TearingEffectCallback : DSI Tearing Effect Callback.
0123       (+) EndOfRefreshCallback  : DSI End Of Refresh Callback.
0124       (+) ErrorCallback         : DSI Error Callback
0125       (+) MspInitCallback       : DSI MspInit.
0126       (+) MspDeInitCallback     : DSI MspDeInit.
0127 
0128     [..]
0129     By default, after the HAL_DSI_Init and when the state is HAL_DSI_STATE_RESET
0130     all callbacks are set to the corresponding weak functions:
0131     examples HAL_DSI_TearingEffectCallback(), HAL_DSI_EndOfRefreshCallback().
0132     Exception done for MspInit and MspDeInit functions that are respectively
0133     reset to the legacy weak (overridden) functions in the HAL_DSI_Init()
0134     and HAL_DSI_DeInit() only when these callbacks are null (not registered beforehand).
0135     If not, MspInit or MspDeInit are not null, the HAL_DSI_Init() and HAL_DSI_DeInit()
0136     keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
0137 
0138     [..]
0139     Callbacks can be registered/unregistered in HAL_DSI_STATE_READY state only.
0140     Exception done MspInit/MspDeInit that can be registered/unregistered
0141     in HAL_DSI_STATE_READY or HAL_DSI_STATE_RESET state,
0142     thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
0143     In that case first register the MspInit/MspDeInit user callbacks
0144     using HAL_DSI_RegisterCallback() before calling HAL_DSI_DeInit()
0145     or HAL_DSI_Init() function.
0146 
0147     [..]
0148     When The compilation define USE_HAL_DSI_REGISTER_CALLBACKS is set to 0 or
0149     not defined, the callback registration feature is not available and all callbacks
0150     are set to the corresponding weak functions.
0151 
0152   @endverbatim
0153   ******************************************************************************
0154   */
0155 
0156 /* Includes ------------------------------------------------------------------*/
0157 #include "stm32h7xx_hal.h"
0158 
0159 /** @addtogroup STM32H7xx_HAL_Driver
0160   * @{
0161   */
0162 
0163 #ifdef HAL_DSI_MODULE_ENABLED
0164 
0165 #if defined(DSI)
0166 
0167 /** @addtogroup DSI
0168   * @{
0169   */
0170 
0171 /* Private types -------------------------------------------------------------*/
0172 /* Private defines -----------------------------------------------------------*/
0173 /** @addtogroup DSI_Private_Constants
0174   * @{
0175   */
0176 #define DSI_TIMEOUT_VALUE ((uint32_t)1000U)  /* 1s */
0177 
0178 #define DSI_ERROR_ACK_MASK (DSI_ISR0_AE0 | DSI_ISR0_AE1 | DSI_ISR0_AE2 | DSI_ISR0_AE3 | \
0179                             DSI_ISR0_AE4 | DSI_ISR0_AE5 | DSI_ISR0_AE6 | DSI_ISR0_AE7 | \
0180                             DSI_ISR0_AE8 | DSI_ISR0_AE9 | DSI_ISR0_AE10 | DSI_ISR0_AE11 | \
0181                             DSI_ISR0_AE12 | DSI_ISR0_AE13 | DSI_ISR0_AE14 | DSI_ISR0_AE15)
0182 #define DSI_ERROR_PHY_MASK (DSI_ISR0_PE0 | DSI_ISR0_PE1 | DSI_ISR0_PE2 | DSI_ISR0_PE3 | DSI_ISR0_PE4)
0183 #define DSI_ERROR_TX_MASK  DSI_ISR1_TOHSTX
0184 #define DSI_ERROR_RX_MASK  DSI_ISR1_TOLPRX
0185 #define DSI_ERROR_ECC_MASK (DSI_ISR1_ECCSE | DSI_ISR1_ECCME)
0186 #define DSI_ERROR_CRC_MASK DSI_ISR1_CRCE
0187 #define DSI_ERROR_PSE_MASK DSI_ISR1_PSE
0188 #define DSI_ERROR_EOT_MASK DSI_ISR1_EOTPE
0189 #define DSI_ERROR_OVF_MASK DSI_ISR1_LPWRE
0190 #define DSI_ERROR_GEN_MASK (DSI_ISR1_GCWRE | DSI_ISR1_GPWRE | DSI_ISR1_GPTXE | DSI_ISR1_GPRDE | DSI_ISR1_GPRXE)
0191 /**
0192   * @}
0193   */
0194 
0195 /* Private variables ---------------------------------------------------------*/
0196 /* Private constants ---------------------------------------------------------*/
0197 /* Private macros ------------------------------------------------------------*/
0198 /* Private function prototypes -----------------------------------------------*/
0199 static void DSI_ConfigPacketHeader(DSI_TypeDef *DSIx, uint32_t ChannelID, uint32_t DataType, uint32_t Data0,
0200                                    uint32_t Data1);
0201 
0202 static HAL_StatusTypeDef DSI_ShortWrite(DSI_HandleTypeDef *hdsi,
0203                                         uint32_t ChannelID,
0204                                         uint32_t Mode,
0205                                         uint32_t Param1,
0206                                         uint32_t Param2);
0207 /* Private functions ---------------------------------------------------------*/
0208 /** @defgroup DSI_Private_Functions DSI Private Functions
0209   * @ingroup RTEMSBSPsARMSTM32H7
0210   * @{
0211   */
0212 /**
0213   * @brief  Generic DSI packet header configuration
0214   * @param  DSIx  Pointer to DSI register base
0215   * @param  ChannelID Virtual channel ID of the header packet
0216   * @param  DataType  Packet data type of the header packet
0217   *                   This parameter can be any value of :
0218   *                      @arg DSI_SHORT_WRITE_PKT_Data_Type
0219   *                      @arg DSI_LONG_WRITE_PKT_Data_Type
0220   *                      @arg DSI_SHORT_READ_PKT_Data_Type
0221   *                      @arg DSI_MAX_RETURN_PKT_SIZE
0222   * @param  Data0  Word count LSB
0223   * @param  Data1  Word count MSB
0224   * @retval None
0225   */
0226 static void DSI_ConfigPacketHeader(DSI_TypeDef *DSIx,
0227                                    uint32_t ChannelID,
0228                                    uint32_t DataType,
0229                                    uint32_t Data0,
0230                                    uint32_t Data1)
0231 {
0232   /* Update the DSI packet header with new information */
0233   DSIx->GHCR = (DataType | (ChannelID << 6U) | (Data0 << 8U) | (Data1 << 16U));
0234 }
0235 
0236 /**
0237   * @brief  write short DCS or short Generic command
0238   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
0239   *               the configuration information for the DSI.
0240   * @param  ChannelID  Virtual channel ID.
0241   * @param  Mode  DSI short packet data type.
0242   *               This parameter can be any value of @arg DSI_SHORT_WRITE_PKT_Data_Type.
0243   * @param  Param1  DSC command or first generic parameter.
0244   *                 This parameter can be any value of @arg DSI_DCS_Command or a
0245   *                 generic command code.
0246   * @param  Param2  DSC parameter or second generic parameter.
0247   * @retval HAL status
0248   */
0249 static HAL_StatusTypeDef DSI_ShortWrite(DSI_HandleTypeDef *hdsi,
0250                                         uint32_t ChannelID,
0251                                         uint32_t Mode,
0252                                         uint32_t Param1,
0253                                         uint32_t Param2)
0254 {
0255   uint32_t tickstart;
0256 
0257   /* Get tick */
0258   tickstart = HAL_GetTick();
0259 
0260   /* Wait for Command FIFO Empty */
0261   while ((hdsi->Instance->GPSR & DSI_GPSR_CMDFE) == 0U)
0262   {
0263     /* Check for the Timeout */
0264     if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
0265     {
0266       return HAL_TIMEOUT;
0267     }
0268   }
0269 
0270   /* Configure the packet to send a short DCS command with 0 or 1 parameter */
0271   /* Update the DSI packet header with new information */
0272   hdsi->Instance->GHCR = (Mode | (ChannelID << 6U) | (Param1 << 8U) | (Param2 << 16U));
0273 
0274   return HAL_OK;
0275 }
0276 
0277 /**
0278   * @}
0279   */
0280 
0281 /* Exported functions --------------------------------------------------------*/
0282 /** @addtogroup DSI_Exported_Functions
0283   * @{
0284   */
0285 
0286 /** @defgroup DSI_Group1 Initialization and Configuration functions
0287   * @ingroup RTEMSBSPsARMSTM32H7
0288   *  @brief   Initialization and Configuration functions
0289   *
0290 @verbatim
0291  ===============================================================================
0292                 ##### Initialization and Configuration functions #####
0293  ===============================================================================
0294     [..]  This section provides functions allowing to:
0295       (+) Initialize and configure the DSI
0296       (+) De-initialize the DSI
0297 
0298 @endverbatim
0299   * @{
0300   */
0301 
0302 /**
0303   * @brief  Initializes the DSI according to the specified
0304   *         parameters in the DSI_InitTypeDef and create the associated handle.
0305   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
0306   *               the configuration information for the DSI.
0307   * @param  PLLInit  pointer to a DSI_PLLInitTypeDef structure that contains
0308   *                  the PLL Clock structure definition for the DSI.
0309   * @retval HAL status
0310   */
0311 HAL_StatusTypeDef HAL_DSI_Init(DSI_HandleTypeDef *hdsi, DSI_PLLInitTypeDef *PLLInit)
0312 {
0313   uint32_t tickstart;
0314   uint32_t unitIntervalx4;
0315   uint32_t tempIDF;
0316 
0317   /* Check the DSI handle allocation */
0318   if (hdsi == NULL)
0319   {
0320     return HAL_ERROR;
0321   }
0322 
0323   /* Check function parameters */
0324   assert_param(IS_DSI_PLL_NDIV(PLLInit->PLLNDIV));
0325   assert_param(IS_DSI_PLL_IDF(PLLInit->PLLIDF));
0326   assert_param(IS_DSI_PLL_ODF(PLLInit->PLLODF));
0327   assert_param(IS_DSI_AUTO_CLKLANE_CONTROL(hdsi->Init.AutomaticClockLaneControl));
0328   assert_param(IS_DSI_NUMBER_OF_LANES(hdsi->Init.NumberOfLanes));
0329 
0330 #if (USE_HAL_DSI_REGISTER_CALLBACKS == 1)
0331   if (hdsi->State == HAL_DSI_STATE_RESET)
0332   {
0333     /* Reset the DSI callback to the legacy weak callbacks */
0334     hdsi->TearingEffectCallback = HAL_DSI_TearingEffectCallback; /* Legacy weak TearingEffectCallback */
0335     hdsi->EndOfRefreshCallback  = HAL_DSI_EndOfRefreshCallback;  /* Legacy weak EndOfRefreshCallback  */
0336     hdsi->ErrorCallback         = HAL_DSI_ErrorCallback;         /* Legacy weak ErrorCallback         */
0337 
0338     if (hdsi->MspInitCallback == NULL)
0339     {
0340       hdsi->MspInitCallback = HAL_DSI_MspInit;
0341     }
0342     /* Initialize the low level hardware */
0343     hdsi->MspInitCallback(hdsi);
0344   }
0345 #else
0346   if (hdsi->State == HAL_DSI_STATE_RESET)
0347   {
0348     /* Initialize the low level hardware */
0349     HAL_DSI_MspInit(hdsi);
0350   }
0351 #endif /* USE_HAL_DSI_REGISTER_CALLBACKS */
0352 
0353   /* Change DSI peripheral state */
0354   hdsi->State = HAL_DSI_STATE_BUSY;
0355 
0356   /**************** Turn on the regulator and enable the DSI PLL ****************/
0357 
0358   /* Enable the regulator */
0359   __HAL_DSI_REG_ENABLE(hdsi);
0360 
0361   /* Get tick */
0362   tickstart = HAL_GetTick();
0363 
0364   /* Wait until the regulator is ready */
0365   while (__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_RRS) == 0U)
0366   {
0367     /* Check for the Timeout */
0368     if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
0369     {
0370       return HAL_TIMEOUT;
0371     }
0372   }
0373 
0374   /* Set the PLL division factors */
0375   hdsi->Instance->WRPCR &= ~(DSI_WRPCR_PLL_NDIV | DSI_WRPCR_PLL_IDF | DSI_WRPCR_PLL_ODF);
0376   hdsi->Instance->WRPCR |= (((PLLInit->PLLNDIV) << DSI_WRPCR_PLL_NDIV_Pos) | \
0377                             ((PLLInit->PLLIDF) << DSI_WRPCR_PLL_IDF_Pos) | \
0378                             ((PLLInit->PLLODF) << DSI_WRPCR_PLL_ODF_Pos));
0379 
0380   /* Enable the DSI PLL */
0381   __HAL_DSI_PLL_ENABLE(hdsi);
0382 
0383   /* Requires min of 400us delay before reading the PLLLS flag */
0384   /* 1ms delay is inserted that is the minimum HAL delay granularity */
0385   HAL_Delay(1);
0386 
0387   /* Get tick */
0388   tickstart = HAL_GetTick();
0389 
0390   /* Wait for the lock of the PLL */
0391   while (__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_PLLLS) == 0U)
0392   {
0393     /* Check for the Timeout */
0394     if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
0395     {
0396       return HAL_TIMEOUT;
0397     }
0398   }
0399 
0400   __HAL_DSI_ENABLE(hdsi);
0401 
0402   /************************ Set the DSI clock parameters ************************/
0403   /* Set the TX escape clock division factor */
0404   hdsi->Instance->CCR &= ~DSI_CCR_TXECKDIV;
0405   hdsi->Instance->CCR |= hdsi->Init.TXEscapeCkdiv;
0406 
0407   /*************************** Set the PHY parameters ***************************/
0408   /* D-PHY clock and digital enable*/
0409   hdsi->Instance->PCTLR |= DSI_PCTLR_DEN;
0410 
0411   hdsi->Instance->PCTLR |= DSI_PCTLR_CKE;
0412 
0413 
0414   /* Configure the number of active data lanes */
0415   hdsi->Instance->PCONFR &= ~DSI_PCONFR_NL;
0416   hdsi->Instance->PCONFR |= hdsi->Init.NumberOfLanes;
0417 
0418   /* Get tick */
0419   tickstart = HAL_GetTick();
0420   if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
0421   {
0422     while ((hdsi->Instance->PSR & (DSI_PSR_PSS0 | DSI_PSR_PSSC)) != (DSI_PSR_PSS0 | DSI_PSR_PSSC))
0423     {
0424       if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
0425       {
0426         /* Process Unlocked */
0427         __HAL_UNLOCK(hdsi);
0428 
0429         return HAL_TIMEOUT;
0430       }
0431     }
0432   }
0433   else
0434   {
0435     while ((hdsi->Instance->PSR & (DSI_PSR_PSS0 | DSI_PSR_PSS1 | DSI_PSR_PSSC)) != (DSI_PSR_PSS0 | \
0436                                                                                     DSI_PSR_PSS1 | DSI_PSR_PSSC))
0437     {
0438       if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
0439       {
0440         /* Process Unlocked */
0441         __HAL_UNLOCK(hdsi);
0442 
0443         return HAL_TIMEOUT;
0444       }
0445     }
0446   }
0447 
0448   /* Calculate the bit period in high-speed mode in unit of 0.25 ns (UIX4) */
0449   /* The equation is : UIX4 = IntegerPart( (1000/F_PHY_Mhz) * 4 )          */
0450   /* Where : F_PHY_Mhz = (NDIV * HSE_Mhz) / (IDF * ODF)                    */
0451   tempIDF = (PLLInit->PLLIDF > 0U) ? PLLInit->PLLIDF : 1U;
0452   unitIntervalx4 = (4000000U * tempIDF * ((1UL << (0x3U & PLLInit->PLLODF)))) / ((HSE_VALUE / 1000U) * PLLInit->PLLNDIV);
0453 
0454   /* Set the bit period in high-speed mode */
0455   hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_UIX4;
0456   hdsi->Instance->WPCR[0U] |= unitIntervalx4;
0457 
0458   /****************************** Error management *****************************/
0459 
0460   /* Disable all error interrupts and reset the Error Mask */
0461   hdsi->Instance->IER[0U] = 0U;
0462   hdsi->Instance->IER[1U] = 0U;
0463   hdsi->ErrorMsk = 0U;
0464 
0465   __HAL_DSI_DISABLE(hdsi);
0466 
0467   /* Clock lane configuration */
0468   hdsi->Instance->CLCR &= ~(DSI_CLCR_DPCC | DSI_CLCR_ACR);
0469   hdsi->Instance->CLCR |= (DSI_CLCR_DPCC | hdsi->Init.AutomaticClockLaneControl);
0470 
0471   /* Initialize the error code */
0472   hdsi->ErrorCode = HAL_DSI_ERROR_NONE;
0473 
0474   /* Initialize the DSI state*/
0475   hdsi->State = HAL_DSI_STATE_READY;
0476 
0477   return HAL_OK;
0478 }
0479 
0480 /**
0481   * @brief  De-initializes the DSI peripheral registers to their default reset
0482   *         values.
0483   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
0484   *               the configuration information for the DSI.
0485   * @retval HAL status
0486   */
0487 HAL_StatusTypeDef HAL_DSI_DeInit(DSI_HandleTypeDef *hdsi)
0488 {
0489   /* Check the DSI handle allocation */
0490   if (hdsi == NULL)
0491   {
0492     return HAL_ERROR;
0493   }
0494 
0495   /* Change DSI peripheral state */
0496   hdsi->State = HAL_DSI_STATE_BUSY;
0497 
0498   /* Disable the DSI wrapper */
0499   __HAL_DSI_WRAPPER_DISABLE(hdsi);
0500 
0501   /* Disable the DSI host */
0502   __HAL_DSI_DISABLE(hdsi);
0503 
0504   /* D-PHY clock and digital disable */
0505   hdsi->Instance->PCTLR &= ~(DSI_PCTLR_CKE | DSI_PCTLR_DEN);
0506 
0507   /* Turn off the DSI PLL */
0508   __HAL_DSI_PLL_DISABLE(hdsi);
0509 
0510   /* Disable the regulator */
0511   __HAL_DSI_REG_DISABLE(hdsi);
0512 
0513 #if (USE_HAL_DSI_REGISTER_CALLBACKS == 1)
0514   if (hdsi->MspDeInitCallback == NULL)
0515   {
0516     hdsi->MspDeInitCallback = HAL_DSI_MspDeInit;
0517   }
0518   /* DeInit the low level hardware */
0519   hdsi->MspDeInitCallback(hdsi);
0520 #else
0521   /* DeInit the low level hardware */
0522   HAL_DSI_MspDeInit(hdsi);
0523 #endif /* USE_HAL_DSI_REGISTER_CALLBACKS */
0524 
0525   /* Initialize the error code */
0526   hdsi->ErrorCode = HAL_DSI_ERROR_NONE;
0527 
0528   /* Initialize the DSI state*/
0529   hdsi->State = HAL_DSI_STATE_RESET;
0530 
0531   /* Release Lock */
0532   __HAL_UNLOCK(hdsi);
0533 
0534   return HAL_OK;
0535 }
0536 
0537 /**
0538   * @brief  Enable the error monitor flags
0539   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
0540   *               the configuration information for the DSI.
0541   * @param  ActiveErrors  indicates which error interrupts will be enabled.
0542   *                      This parameter can be any combination of @arg DSI_Error_Data_Type.
0543   * @retval HAL status
0544   */
0545 HAL_StatusTypeDef HAL_DSI_ConfigErrorMonitor(DSI_HandleTypeDef *hdsi, uint32_t ActiveErrors)
0546 {
0547   /* Process locked */
0548   __HAL_LOCK(hdsi);
0549 
0550   hdsi->Instance->IER[0U] = 0U;
0551   hdsi->Instance->IER[1U] = 0U;
0552 
0553   /* Store active errors to the handle */
0554   hdsi->ErrorMsk = ActiveErrors;
0555 
0556   if ((ActiveErrors & HAL_DSI_ERROR_ACK) != 0U)
0557   {
0558     /* Enable the interrupt generation on selected errors */
0559     hdsi->Instance->IER[0U] |= DSI_ERROR_ACK_MASK;
0560   }
0561 
0562   if ((ActiveErrors & HAL_DSI_ERROR_PHY) != 0U)
0563   {
0564     /* Enable the interrupt generation on selected errors */
0565     hdsi->Instance->IER[0U] |= DSI_ERROR_PHY_MASK;
0566   }
0567 
0568   if ((ActiveErrors & HAL_DSI_ERROR_TX) != 0U)
0569   {
0570     /* Enable the interrupt generation on selected errors */
0571     hdsi->Instance->IER[1U] |= DSI_ERROR_TX_MASK;
0572   }
0573 
0574   if ((ActiveErrors & HAL_DSI_ERROR_RX) != 0U)
0575   {
0576     /* Enable the interrupt generation on selected errors */
0577     hdsi->Instance->IER[1U] |= DSI_ERROR_RX_MASK;
0578   }
0579 
0580   if ((ActiveErrors & HAL_DSI_ERROR_ECC) != 0U)
0581   {
0582     /* Enable the interrupt generation on selected errors */
0583     hdsi->Instance->IER[1U] |= DSI_ERROR_ECC_MASK;
0584   }
0585 
0586   if ((ActiveErrors & HAL_DSI_ERROR_CRC) != 0U)
0587   {
0588     /* Enable the interrupt generation on selected errors */
0589     hdsi->Instance->IER[1U] |= DSI_ERROR_CRC_MASK;
0590   }
0591 
0592   if ((ActiveErrors & HAL_DSI_ERROR_PSE) != 0U)
0593   {
0594     /* Enable the interrupt generation on selected errors */
0595     hdsi->Instance->IER[1U] |= DSI_ERROR_PSE_MASK;
0596   }
0597 
0598   if ((ActiveErrors & HAL_DSI_ERROR_EOT) != 0U)
0599   {
0600     /* Enable the interrupt generation on selected errors */
0601     hdsi->Instance->IER[1U] |= DSI_ERROR_EOT_MASK;
0602   }
0603 
0604   if ((ActiveErrors & HAL_DSI_ERROR_OVF) != 0U)
0605   {
0606     /* Enable the interrupt generation on selected errors */
0607     hdsi->Instance->IER[1U] |= DSI_ERROR_OVF_MASK;
0608   }
0609 
0610   if ((ActiveErrors & HAL_DSI_ERROR_GEN) != 0U)
0611   {
0612     /* Enable the interrupt generation on selected errors */
0613     hdsi->Instance->IER[1U] |= DSI_ERROR_GEN_MASK;
0614   }
0615 
0616   /* Process Unlocked */
0617   __HAL_UNLOCK(hdsi);
0618 
0619   return HAL_OK;
0620 }
0621 
0622 /**
0623   * @brief  Initializes the DSI MSP.
0624   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
0625   *               the configuration information for the DSI.
0626   * @retval None
0627   */
0628 __weak void HAL_DSI_MspInit(DSI_HandleTypeDef *hdsi)
0629 {
0630   /* Prevent unused argument(s) compilation warning */
0631   UNUSED(hdsi);
0632   /* NOTE : This function Should not be modified, when the callback is needed,
0633             the HAL_DSI_MspInit could be implemented in the user file
0634    */
0635 }
0636 
0637 /**
0638   * @brief  De-initializes the DSI MSP.
0639   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
0640   *               the configuration information for the DSI.
0641   * @retval None
0642   */
0643 __weak void HAL_DSI_MspDeInit(DSI_HandleTypeDef *hdsi)
0644 {
0645   /* Prevent unused argument(s) compilation warning */
0646   UNUSED(hdsi);
0647   /* NOTE : This function Should not be modified, when the callback is needed,
0648             the HAL_DSI_MspDeInit could be implemented in the user file
0649    */
0650 }
0651 
0652 #if (USE_HAL_DSI_REGISTER_CALLBACKS == 1)
0653 /**
0654   * @brief  Register a User DSI Callback
0655   *         To be used instead of the weak predefined callback
0656   * @param hdsi dsi handle
0657   * @param CallbackID ID of the callback to be registered
0658   *        This parameter can be one of the following values:
0659   *          @arg HAL_DSI_TEARING_EFFECT_CB_ID Tearing Effect Callback ID
0660   *          @arg HAL_DSI_ENDOF_REFRESH_CB_ID End Of Refresh Callback ID
0661   *          @arg HAL_DSI_ERROR_CB_ID Error Callback ID
0662   *          @arg HAL_DSI_MSPINIT_CB_ID MspInit callback ID
0663   *          @arg HAL_DSI_MSPDEINIT_CB_ID MspDeInit callback ID
0664   * @param pCallback pointer to the Callback function
0665   * @retval status
0666   */
0667 HAL_StatusTypeDef HAL_DSI_RegisterCallback(DSI_HandleTypeDef *hdsi, HAL_DSI_CallbackIDTypeDef CallbackID,
0668                                            pDSI_CallbackTypeDef pCallback)
0669 {
0670   HAL_StatusTypeDef status = HAL_OK;
0671 
0672   if (pCallback == NULL)
0673   {
0674     /* Update the error code */
0675     hdsi->ErrorCode |= HAL_DSI_ERROR_INVALID_CALLBACK;
0676 
0677     return HAL_ERROR;
0678   }
0679   /* Process locked */
0680   __HAL_LOCK(hdsi);
0681 
0682   if (hdsi->State == HAL_DSI_STATE_READY)
0683   {
0684     switch (CallbackID)
0685     {
0686       case HAL_DSI_TEARING_EFFECT_CB_ID :
0687         hdsi->TearingEffectCallback = pCallback;
0688         break;
0689 
0690       case HAL_DSI_ENDOF_REFRESH_CB_ID :
0691         hdsi->EndOfRefreshCallback = pCallback;
0692         break;
0693 
0694       case HAL_DSI_ERROR_CB_ID :
0695         hdsi->ErrorCallback = pCallback;
0696         break;
0697 
0698       case HAL_DSI_MSPINIT_CB_ID :
0699         hdsi->MspInitCallback = pCallback;
0700         break;
0701 
0702       case HAL_DSI_MSPDEINIT_CB_ID :
0703         hdsi->MspDeInitCallback = pCallback;
0704         break;
0705 
0706       default :
0707         /* Update the error code */
0708         hdsi->ErrorCode |= HAL_DSI_ERROR_INVALID_CALLBACK;
0709         /* Return error status */
0710         status =  HAL_ERROR;
0711         break;
0712     }
0713   }
0714   else if (hdsi->State == HAL_DSI_STATE_RESET)
0715   {
0716     switch (CallbackID)
0717     {
0718       case HAL_DSI_MSPINIT_CB_ID :
0719         hdsi->MspInitCallback = pCallback;
0720         break;
0721 
0722       case HAL_DSI_MSPDEINIT_CB_ID :
0723         hdsi->MspDeInitCallback = pCallback;
0724         break;
0725 
0726       default :
0727         /* Update the error code */
0728         hdsi->ErrorCode |= HAL_DSI_ERROR_INVALID_CALLBACK;
0729         /* Return error status */
0730         status =  HAL_ERROR;
0731         break;
0732     }
0733   }
0734   else
0735   {
0736     /* Update the error code */
0737     hdsi->ErrorCode |= HAL_DSI_ERROR_INVALID_CALLBACK;
0738     /* Return error status */
0739     status =  HAL_ERROR;
0740   }
0741 
0742   /* Release Lock */
0743   __HAL_UNLOCK(hdsi);
0744 
0745   return status;
0746 }
0747 
0748 /**
0749   * @brief  Unregister a DSI Callback
0750   *         DSI callback is redirected to the weak predefined callback
0751   * @param hdsi dsi handle
0752   * @param CallbackID ID of the callback to be unregistered
0753   *        This parameter can be one of the following values:
0754   *          @arg HAL_DSI_TEARING_EFFECT_CB_ID Tearing Effect Callback ID
0755   *          @arg HAL_DSI_ENDOF_REFRESH_CB_ID End Of Refresh Callback ID
0756   *          @arg HAL_DSI_ERROR_CB_ID Error Callback ID
0757   *          @arg HAL_DSI_MSPINIT_CB_ID MspInit callback ID
0758   *          @arg HAL_DSI_MSPDEINIT_CB_ID MspDeInit callback ID
0759   * @retval status
0760   */
0761 HAL_StatusTypeDef HAL_DSI_UnRegisterCallback(DSI_HandleTypeDef *hdsi, HAL_DSI_CallbackIDTypeDef CallbackID)
0762 {
0763   HAL_StatusTypeDef status = HAL_OK;
0764 
0765   /* Process locked */
0766   __HAL_LOCK(hdsi);
0767 
0768   if (hdsi->State == HAL_DSI_STATE_READY)
0769   {
0770     switch (CallbackID)
0771     {
0772       case HAL_DSI_TEARING_EFFECT_CB_ID :
0773         hdsi->TearingEffectCallback = HAL_DSI_TearingEffectCallback; /* Legacy weak TearingEffectCallback */
0774         break;
0775 
0776       case HAL_DSI_ENDOF_REFRESH_CB_ID :
0777         hdsi->EndOfRefreshCallback = HAL_DSI_EndOfRefreshCallback;   /* Legacy weak EndOfRefreshCallback  */
0778         break;
0779 
0780       case HAL_DSI_ERROR_CB_ID :
0781         hdsi->ErrorCallback        = HAL_DSI_ErrorCallback;          /* Legacy weak ErrorCallback        */
0782         break;
0783 
0784       case HAL_DSI_MSPINIT_CB_ID :
0785         hdsi->MspInitCallback = HAL_DSI_MspInit;                     /* Legacy weak MspInit Callback     */
0786         break;
0787 
0788       case HAL_DSI_MSPDEINIT_CB_ID :
0789         hdsi->MspDeInitCallback = HAL_DSI_MspDeInit;                 /* Legacy weak MspDeInit Callback   */
0790         break;
0791 
0792       default :
0793         /* Update the error code */
0794         hdsi->ErrorCode |= HAL_DSI_ERROR_INVALID_CALLBACK;
0795         /* Return error status */
0796         status =  HAL_ERROR;
0797         break;
0798     }
0799   }
0800   else if (hdsi->State == HAL_DSI_STATE_RESET)
0801   {
0802     switch (CallbackID)
0803     {
0804       case HAL_DSI_MSPINIT_CB_ID :
0805         hdsi->MspInitCallback = HAL_DSI_MspInit;                  /* Legacy weak MspInit Callback   */
0806         break;
0807 
0808       case HAL_DSI_MSPDEINIT_CB_ID :
0809         hdsi->MspDeInitCallback = HAL_DSI_MspDeInit;              /* Legacy weak MspDeInit Callback */
0810         break;
0811 
0812       default :
0813         /* Update the error code */
0814         hdsi->ErrorCode |= HAL_DSI_ERROR_INVALID_CALLBACK;
0815         /* Return error status */
0816         status =  HAL_ERROR;
0817         break;
0818     }
0819   }
0820   else
0821   {
0822     /* Update the error code */
0823     hdsi->ErrorCode |= HAL_DSI_ERROR_INVALID_CALLBACK;
0824     /* Return error status */
0825     status =  HAL_ERROR;
0826   }
0827 
0828   /* Release Lock */
0829   __HAL_UNLOCK(hdsi);
0830 
0831   return status;
0832 }
0833 #endif /* USE_HAL_DSI_REGISTER_CALLBACKS */
0834 
0835 /**
0836   * @}
0837   */
0838 
0839 /** @defgroup DSI_Group2 IO operation functions
0840   * @ingroup RTEMSBSPsARMSTM32H7
0841   *  @brief    IO operation functions
0842   *
0843 @verbatim
0844  ===============================================================================
0845                       #####  IO operation functions  #####
0846  ===============================================================================
0847     [..]  This section provides function allowing to:
0848       (+) Handle DSI interrupt request
0849 
0850 @endverbatim
0851   * @{
0852   */
0853 /**
0854   * @brief  Handles DSI interrupt request.
0855   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
0856   *               the configuration information for the DSI.
0857   * @retval HAL status
0858   */
0859 void HAL_DSI_IRQHandler(DSI_HandleTypeDef *hdsi)
0860 {
0861   uint32_t ErrorStatus0;
0862   uint32_t ErrorStatus1;
0863 
0864   /* Tearing Effect Interrupt management ***************************************/
0865   if (__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_TE) != 0U)
0866   {
0867     if (__HAL_DSI_GET_IT_SOURCE(hdsi, DSI_IT_TE) != 0U)
0868     {
0869       /* Clear the Tearing Effect Interrupt Flag */
0870       __HAL_DSI_CLEAR_FLAG(hdsi, DSI_FLAG_TE);
0871 
0872       /* Tearing Effect Callback */
0873 #if (USE_HAL_DSI_REGISTER_CALLBACKS == 1)
0874       /*Call registered Tearing Effect callback */
0875       hdsi->TearingEffectCallback(hdsi);
0876 #else
0877       /*Call legacy Tearing Effect callback*/
0878       HAL_DSI_TearingEffectCallback(hdsi);
0879 #endif /* USE_HAL_DSI_REGISTER_CALLBACKS */
0880     }
0881   }
0882 
0883   /* End of Refresh Interrupt management ***************************************/
0884   if (__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_ER) != 0U)
0885   {
0886     if (__HAL_DSI_GET_IT_SOURCE(hdsi, DSI_IT_ER) != 0U)
0887     {
0888       /* Clear the End of Refresh Interrupt Flag */
0889       __HAL_DSI_CLEAR_FLAG(hdsi, DSI_FLAG_ER);
0890 
0891       /* End of Refresh Callback */
0892 #if (USE_HAL_DSI_REGISTER_CALLBACKS == 1)
0893       /*Call registered End of refresh callback */
0894       hdsi->EndOfRefreshCallback(hdsi);
0895 #else
0896       /*Call Legacy End of refresh callback */
0897       HAL_DSI_EndOfRefreshCallback(hdsi);
0898 #endif /* USE_HAL_DSI_REGISTER_CALLBACKS */
0899     }
0900   }
0901 
0902   /* Error Interrupts management ***********************************************/
0903   if (hdsi->ErrorMsk != 0U)
0904   {
0905     ErrorStatus0 = hdsi->Instance->ISR[0U];
0906     ErrorStatus0 &= hdsi->Instance->IER[0U];
0907     ErrorStatus1 = hdsi->Instance->ISR[1U];
0908     ErrorStatus1 &= hdsi->Instance->IER[1U];
0909 
0910     if ((ErrorStatus0 & DSI_ERROR_ACK_MASK) != 0U)
0911     {
0912       hdsi->ErrorCode |= HAL_DSI_ERROR_ACK;
0913     }
0914 
0915     if ((ErrorStatus0 & DSI_ERROR_PHY_MASK) != 0U)
0916     {
0917       hdsi->ErrorCode |= HAL_DSI_ERROR_PHY;
0918     }
0919 
0920     if ((ErrorStatus1 & DSI_ERROR_TX_MASK) != 0U)
0921     {
0922       hdsi->ErrorCode |= HAL_DSI_ERROR_TX;
0923     }
0924 
0925     if ((ErrorStatus1 & DSI_ERROR_RX_MASK) != 0U)
0926     {
0927       hdsi->ErrorCode |= HAL_DSI_ERROR_RX;
0928     }
0929 
0930     if ((ErrorStatus1 & DSI_ERROR_ECC_MASK) != 0U)
0931     {
0932       hdsi->ErrorCode |= HAL_DSI_ERROR_ECC;
0933     }
0934 
0935     if ((ErrorStatus1 & DSI_ERROR_CRC_MASK) != 0U)
0936     {
0937       hdsi->ErrorCode |= HAL_DSI_ERROR_CRC;
0938     }
0939 
0940     if ((ErrorStatus1 & DSI_ERROR_PSE_MASK) != 0U)
0941     {
0942       hdsi->ErrorCode |= HAL_DSI_ERROR_PSE;
0943     }
0944 
0945     if ((ErrorStatus1 & DSI_ERROR_EOT_MASK) != 0U)
0946     {
0947       hdsi->ErrorCode |= HAL_DSI_ERROR_EOT;
0948     }
0949 
0950     if ((ErrorStatus1 & DSI_ERROR_OVF_MASK) != 0U)
0951     {
0952       hdsi->ErrorCode |= HAL_DSI_ERROR_OVF;
0953     }
0954 
0955     if ((ErrorStatus1 & DSI_ERROR_GEN_MASK) != 0U)
0956     {
0957       hdsi->ErrorCode |= HAL_DSI_ERROR_GEN;
0958     }
0959 
0960     /* Check only selected errors */
0961     if (hdsi->ErrorCode != HAL_DSI_ERROR_NONE)
0962     {
0963       /* DSI error interrupt callback */
0964 #if (USE_HAL_DSI_REGISTER_CALLBACKS == 1)
0965       /*Call registered Error callback */
0966       hdsi->ErrorCallback(hdsi);
0967 #else
0968       /*Call Legacy Error callback */
0969       HAL_DSI_ErrorCallback(hdsi);
0970 #endif /* USE_HAL_DSI_REGISTER_CALLBACKS */
0971     }
0972   }
0973 }
0974 
0975 /**
0976   * @brief  Tearing Effect DSI callback.
0977   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
0978   *               the configuration information for the DSI.
0979   * @retval None
0980   */
0981 __weak void HAL_DSI_TearingEffectCallback(DSI_HandleTypeDef *hdsi)
0982 {
0983   /* Prevent unused argument(s) compilation warning */
0984   UNUSED(hdsi);
0985   /* NOTE : This function Should not be modified, when the callback is needed,
0986             the HAL_DSI_TearingEffectCallback could be implemented in the user file
0987    */
0988 }
0989 
0990 /**
0991   * @brief  End of Refresh DSI callback.
0992   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
0993   *               the configuration information for the DSI.
0994   * @retval None
0995   */
0996 __weak void HAL_DSI_EndOfRefreshCallback(DSI_HandleTypeDef *hdsi)
0997 {
0998   /* Prevent unused argument(s) compilation warning */
0999   UNUSED(hdsi);
1000   /* NOTE : This function Should not be modified, when the callback is needed,
1001             the HAL_DSI_EndOfRefreshCallback could be implemented in the user file
1002    */
1003 }
1004 
1005 /**
1006   * @brief  Operation Error DSI callback.
1007   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1008   *               the configuration information for the DSI.
1009   * @retval None
1010   */
1011 __weak void HAL_DSI_ErrorCallback(DSI_HandleTypeDef *hdsi)
1012 {
1013   /* Prevent unused argument(s) compilation warning */
1014   UNUSED(hdsi);
1015   /* NOTE : This function Should not be modified, when the callback is needed,
1016             the HAL_DSI_ErrorCallback could be implemented in the user file
1017    */
1018 }
1019 
1020 /**
1021   * @}
1022   */
1023 
1024 /** @defgroup DSI_Group3 Peripheral Control functions
1025   * @ingroup RTEMSBSPsARMSTM32H7
1026   *  @brief    Peripheral Control functions
1027   *
1028 @verbatim
1029  ===============================================================================
1030                     ##### Peripheral Control functions #####
1031  ===============================================================================
1032     [..]  This section provides functions allowing to:
1033       (+) Configure the Generic interface read-back Virtual Channel ID
1034       (+) Select video mode and configure the corresponding parameters
1035       (+) Configure command transmission mode: High-speed or Low-power
1036       (+) Configure the flow control
1037       (+) Configure the DSI PHY timer
1038       (+) Configure the DSI HOST timeout
1039       (+) Configure the DSI HOST timeout
1040       (+) Start/Stop the DSI module
1041       (+) Refresh the display in command mode
1042       (+) Controls the display color mode in Video mode
1043       (+) Control the display shutdown in Video mode
1044       (+) write short DCS or short Generic command
1045       (+) write long DCS or long Generic command
1046       (+) Read command (DCS or generic)
1047       (+) Enter/Exit the Ultra Low Power Mode on data only (D-PHY PLL running)
1048       (+) Enter/Exit the Ultra Low Power Mode on data only and clock (D-PHY PLL turned off)
1049       (+) Start/Stop test pattern generation
1050       (+) Slew-Rate And Delay Tuning
1051       (+) Low-Power Reception Filter Tuning
1052       (+) Activate an additional current path on all lanes to meet the SDDTx parameter
1053       (+) Custom lane pins configuration
1054       (+) Set custom timing for the PHY
1055       (+) Force the Clock/Data Lane in TX Stop Mode
1056       (+) Force LP Receiver in Low-Power Mode
1057       (+) Force Data Lanes in RX Mode after a BTA
1058       (+) Enable a pull-down on the lanes to prevent from floating states when unused
1059       (+) Switch off the contention detection on data lanes
1060 
1061 @endverbatim
1062   * @{
1063   */
1064 
1065 /**
1066   * @brief  Configure the Generic interface read-back Virtual Channel ID.
1067   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1068   *               the configuration information for the DSI.
1069   * @param  VirtualChannelID  Virtual channel ID
1070   * @retval HAL status
1071   */
1072 HAL_StatusTypeDef HAL_DSI_SetGenericVCID(DSI_HandleTypeDef *hdsi, uint32_t VirtualChannelID)
1073 {
1074   /* Process locked */
1075   __HAL_LOCK(hdsi);
1076 
1077   /* Update the GVCID register */
1078   hdsi->Instance->GVCIDR &= ~DSI_GVCIDR_VCID;
1079   hdsi->Instance->GVCIDR |= VirtualChannelID;
1080 
1081   /* Process unlocked */
1082   __HAL_UNLOCK(hdsi);
1083 
1084   return HAL_OK;
1085 }
1086 
1087 /**
1088   * @brief  Select video mode and configure the corresponding parameters
1089   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1090   *               the configuration information for the DSI.
1091   * @param  VidCfg pointer to a DSI_VidCfgTypeDef structure that contains
1092   *                the DSI video mode configuration parameters
1093   * @retval HAL status
1094   */
1095 HAL_StatusTypeDef HAL_DSI_ConfigVideoMode(DSI_HandleTypeDef *hdsi, DSI_VidCfgTypeDef *VidCfg)
1096 {
1097   /* Process locked */
1098   __HAL_LOCK(hdsi);
1099 
1100   /* Check the parameters */
1101   assert_param(IS_DSI_COLOR_CODING(VidCfg->ColorCoding));
1102   assert_param(IS_DSI_VIDEO_MODE_TYPE(VidCfg->Mode));
1103   assert_param(IS_DSI_LP_COMMAND(VidCfg->LPCommandEnable));
1104   assert_param(IS_DSI_LP_HFP(VidCfg->LPHorizontalFrontPorchEnable));
1105   assert_param(IS_DSI_LP_HBP(VidCfg->LPHorizontalBackPorchEnable));
1106   assert_param(IS_DSI_LP_VACTIVE(VidCfg->LPVerticalActiveEnable));
1107   assert_param(IS_DSI_LP_VFP(VidCfg->LPVerticalFrontPorchEnable));
1108   assert_param(IS_DSI_LP_VBP(VidCfg->LPVerticalBackPorchEnable));
1109   assert_param(IS_DSI_LP_VSYNC(VidCfg->LPVerticalSyncActiveEnable));
1110   assert_param(IS_DSI_FBTAA(VidCfg->FrameBTAAcknowledgeEnable));
1111   assert_param(IS_DSI_DE_POLARITY(VidCfg->DEPolarity));
1112   assert_param(IS_DSI_VSYNC_POLARITY(VidCfg->VSPolarity));
1113   assert_param(IS_DSI_HSYNC_POLARITY(VidCfg->HSPolarity));
1114   /* Check the LooselyPacked variant only in 18-bit mode */
1115   if (VidCfg->ColorCoding == DSI_RGB666)
1116   {
1117     assert_param(IS_DSI_LOOSELY_PACKED(VidCfg->LooselyPacked));
1118   }
1119 
1120   /* Select video mode by resetting CMDM and DSIM bits */
1121   hdsi->Instance->MCR &= ~DSI_MCR_CMDM;
1122   hdsi->Instance->WCFGR &= ~DSI_WCFGR_DSIM;
1123 
1124   /* Configure the video mode transmission type */
1125   hdsi->Instance->VMCR &= ~DSI_VMCR_VMT;
1126   hdsi->Instance->VMCR |= VidCfg->Mode;
1127 
1128   /* Configure the video packet size */
1129   hdsi->Instance->VPCR &= ~DSI_VPCR_VPSIZE;
1130   hdsi->Instance->VPCR |= VidCfg->PacketSize;
1131 
1132   /* Set the chunks number to be transmitted through the DSI link */
1133   hdsi->Instance->VCCR &= ~DSI_VCCR_NUMC;
1134   hdsi->Instance->VCCR |= VidCfg->NumberOfChunks;
1135 
1136   /* Set the size of the null packet */
1137   hdsi->Instance->VNPCR &= ~DSI_VNPCR_NPSIZE;
1138   hdsi->Instance->VNPCR |= VidCfg->NullPacketSize;
1139 
1140   /* Select the virtual channel for the LTDC interface traffic */
1141   hdsi->Instance->LVCIDR &= ~DSI_LVCIDR_VCID;
1142   hdsi->Instance->LVCIDR |= VidCfg->VirtualChannelID;
1143 
1144   /* Configure the polarity of control signals */
1145   hdsi->Instance->LPCR &= ~(DSI_LPCR_DEP | DSI_LPCR_VSP | DSI_LPCR_HSP);
1146   hdsi->Instance->LPCR |= (VidCfg->DEPolarity | VidCfg->VSPolarity | VidCfg->HSPolarity);
1147 
1148   /* Select the color coding for the host */
1149   hdsi->Instance->LCOLCR &= ~DSI_LCOLCR_COLC;
1150   hdsi->Instance->LCOLCR |= VidCfg->ColorCoding;
1151 
1152   /* Select the color coding for the wrapper */
1153   hdsi->Instance->WCFGR &= ~DSI_WCFGR_COLMUX;
1154   hdsi->Instance->WCFGR |= ((VidCfg->ColorCoding) << 1U);
1155 
1156   /* Enable/disable the loosely packed variant to 18-bit configuration */
1157   if (VidCfg->ColorCoding == DSI_RGB666)
1158   {
1159     hdsi->Instance->LCOLCR &= ~DSI_LCOLCR_LPE;
1160     hdsi->Instance->LCOLCR |= VidCfg->LooselyPacked;
1161   }
1162 
1163   /* Set the Horizontal Synchronization Active (HSA) in lane byte clock cycles */
1164   hdsi->Instance->VHSACR &= ~DSI_VHSACR_HSA;
1165   hdsi->Instance->VHSACR |= VidCfg->HorizontalSyncActive;
1166 
1167   /* Set the Horizontal Back Porch (HBP) in lane byte clock cycles */
1168   hdsi->Instance->VHBPCR &= ~DSI_VHBPCR_HBP;
1169   hdsi->Instance->VHBPCR |= VidCfg->HorizontalBackPorch;
1170 
1171   /* Set the total line time (HLINE=HSA+HBP+HACT+HFP) in lane byte clock cycles */
1172   hdsi->Instance->VLCR &= ~DSI_VLCR_HLINE;
1173   hdsi->Instance->VLCR |= VidCfg->HorizontalLine;
1174 
1175   /* Set the Vertical Synchronization Active (VSA) */
1176   hdsi->Instance->VVSACR &= ~DSI_VVSACR_VSA;
1177   hdsi->Instance->VVSACR |= VidCfg->VerticalSyncActive;
1178 
1179   /* Set the Vertical Back Porch (VBP)*/
1180   hdsi->Instance->VVBPCR &= ~DSI_VVBPCR_VBP;
1181   hdsi->Instance->VVBPCR |= VidCfg->VerticalBackPorch;
1182 
1183   /* Set the Vertical Front Porch (VFP)*/
1184   hdsi->Instance->VVFPCR &= ~DSI_VVFPCR_VFP;
1185   hdsi->Instance->VVFPCR |= VidCfg->VerticalFrontPorch;
1186 
1187   /* Set the Vertical Active period*/
1188   hdsi->Instance->VVACR &= ~DSI_VVACR_VA;
1189   hdsi->Instance->VVACR |= VidCfg->VerticalActive;
1190 
1191   /* Configure the command transmission mode */
1192   hdsi->Instance->VMCR &= ~DSI_VMCR_LPCE;
1193   hdsi->Instance->VMCR |= VidCfg->LPCommandEnable;
1194 
1195   /* Low power largest packet size */
1196   hdsi->Instance->LPMCR &= ~DSI_LPMCR_LPSIZE;
1197   hdsi->Instance->LPMCR |= ((VidCfg->LPLargestPacketSize) << 16U);
1198 
1199   /* Low power VACT largest packet size */
1200   hdsi->Instance->LPMCR &= ~DSI_LPMCR_VLPSIZE;
1201   hdsi->Instance->LPMCR |= VidCfg->LPVACTLargestPacketSize;
1202 
1203   /* Enable LP transition in HFP period */
1204   hdsi->Instance->VMCR &= ~DSI_VMCR_LPHFPE;
1205   hdsi->Instance->VMCR |= VidCfg->LPHorizontalFrontPorchEnable;
1206 
1207   /* Enable LP transition in HBP period */
1208   hdsi->Instance->VMCR &= ~DSI_VMCR_LPHBPE;
1209   hdsi->Instance->VMCR |= VidCfg->LPHorizontalBackPorchEnable;
1210 
1211   /* Enable LP transition in VACT period */
1212   hdsi->Instance->VMCR &= ~DSI_VMCR_LPVAE;
1213   hdsi->Instance->VMCR |= VidCfg->LPVerticalActiveEnable;
1214 
1215   /* Enable LP transition in VFP period */
1216   hdsi->Instance->VMCR &= ~DSI_VMCR_LPVFPE;
1217   hdsi->Instance->VMCR |= VidCfg->LPVerticalFrontPorchEnable;
1218 
1219   /* Enable LP transition in VBP period */
1220   hdsi->Instance->VMCR &= ~DSI_VMCR_LPVBPE;
1221   hdsi->Instance->VMCR |= VidCfg->LPVerticalBackPorchEnable;
1222 
1223   /* Enable LP transition in vertical sync period */
1224   hdsi->Instance->VMCR &= ~DSI_VMCR_LPVSAE;
1225   hdsi->Instance->VMCR |= VidCfg->LPVerticalSyncActiveEnable;
1226 
1227   /* Enable the request for an acknowledge response at the end of a frame */
1228   hdsi->Instance->VMCR &= ~DSI_VMCR_FBTAAE;
1229   hdsi->Instance->VMCR |= VidCfg->FrameBTAAcknowledgeEnable;
1230 
1231   /* Process unlocked */
1232   __HAL_UNLOCK(hdsi);
1233 
1234   return HAL_OK;
1235 }
1236 
1237 /**
1238   * @brief  Select adapted command mode and configure the corresponding parameters
1239   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1240   *               the configuration information for the DSI.
1241   * @param  CmdCfg  pointer to a DSI_CmdCfgTypeDef structure that contains
1242   *                 the DSI command mode configuration parameters
1243   * @retval HAL status
1244   */
1245 HAL_StatusTypeDef HAL_DSI_ConfigAdaptedCommandMode(DSI_HandleTypeDef *hdsi, DSI_CmdCfgTypeDef *CmdCfg)
1246 {
1247   /* Process locked */
1248   __HAL_LOCK(hdsi);
1249 
1250   /* Check the parameters */
1251   assert_param(IS_DSI_COLOR_CODING(CmdCfg->ColorCoding));
1252   assert_param(IS_DSI_TE_SOURCE(CmdCfg->TearingEffectSource));
1253   assert_param(IS_DSI_TE_POLARITY(CmdCfg->TearingEffectPolarity));
1254   assert_param(IS_DSI_AUTOMATIC_REFRESH(CmdCfg->AutomaticRefresh));
1255   assert_param(IS_DSI_VS_POLARITY(CmdCfg->VSyncPol));
1256   assert_param(IS_DSI_TE_ACK_REQUEST(CmdCfg->TEAcknowledgeRequest));
1257   assert_param(IS_DSI_DE_POLARITY(CmdCfg->DEPolarity));
1258   assert_param(IS_DSI_VSYNC_POLARITY(CmdCfg->VSPolarity));
1259   assert_param(IS_DSI_HSYNC_POLARITY(CmdCfg->HSPolarity));
1260 
1261   /* Select command mode by setting CMDM and DSIM bits */
1262   hdsi->Instance->MCR |= DSI_MCR_CMDM;
1263   hdsi->Instance->WCFGR &= ~DSI_WCFGR_DSIM;
1264   hdsi->Instance->WCFGR |= DSI_WCFGR_DSIM;
1265 
1266   /* Select the virtual channel for the LTDC interface traffic */
1267   hdsi->Instance->LVCIDR &= ~DSI_LVCIDR_VCID;
1268   hdsi->Instance->LVCIDR |= CmdCfg->VirtualChannelID;
1269 
1270   /* Configure the polarity of control signals */
1271   hdsi->Instance->LPCR &= ~(DSI_LPCR_DEP | DSI_LPCR_VSP | DSI_LPCR_HSP);
1272   hdsi->Instance->LPCR |= (CmdCfg->DEPolarity | CmdCfg->VSPolarity | CmdCfg->HSPolarity);
1273 
1274   /* Select the color coding for the host */
1275   hdsi->Instance->LCOLCR &= ~DSI_LCOLCR_COLC;
1276   hdsi->Instance->LCOLCR |= CmdCfg->ColorCoding;
1277 
1278   /* Select the color coding for the wrapper */
1279   hdsi->Instance->WCFGR &= ~DSI_WCFGR_COLMUX;
1280   hdsi->Instance->WCFGR |= ((CmdCfg->ColorCoding) << 1U);
1281 
1282   /* Configure the maximum allowed size for write memory command */
1283   hdsi->Instance->LCCR &= ~DSI_LCCR_CMDSIZE;
1284   hdsi->Instance->LCCR |= CmdCfg->CommandSize;
1285 
1286   /* Configure the tearing effect source and polarity and select the refresh mode */
1287   hdsi->Instance->WCFGR &= ~(DSI_WCFGR_TESRC | DSI_WCFGR_TEPOL | DSI_WCFGR_AR | DSI_WCFGR_VSPOL);
1288   hdsi->Instance->WCFGR |= (CmdCfg->TearingEffectSource | CmdCfg->TearingEffectPolarity | CmdCfg->AutomaticRefresh |
1289                             CmdCfg->VSyncPol);
1290 
1291   /* Configure the tearing effect acknowledge request */
1292   hdsi->Instance->CMCR &= ~DSI_CMCR_TEARE;
1293   hdsi->Instance->CMCR |= CmdCfg->TEAcknowledgeRequest;
1294 
1295   /* Enable the Tearing Effect interrupt */
1296   __HAL_DSI_ENABLE_IT(hdsi, DSI_IT_TE);
1297 
1298   /* Enable the End of Refresh interrupt */
1299   __HAL_DSI_ENABLE_IT(hdsi, DSI_IT_ER);
1300 
1301   /* Process unlocked */
1302   __HAL_UNLOCK(hdsi);
1303 
1304   return HAL_OK;
1305 }
1306 
1307 /**
1308   * @brief  Configure command transmission mode: High-speed or Low-power
1309   *         and enable/disable acknowledge request after packet transmission
1310   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1311   *               the configuration information for the DSI.
1312   * @param  LPCmd  pointer to a DSI_LPCmdTypeDef structure that contains
1313   *                the DSI command transmission mode configuration parameters
1314   * @retval HAL status
1315   */
1316 HAL_StatusTypeDef HAL_DSI_ConfigCommand(DSI_HandleTypeDef *hdsi, DSI_LPCmdTypeDef *LPCmd)
1317 {
1318   /* Process locked */
1319   __HAL_LOCK(hdsi);
1320 
1321   assert_param(IS_DSI_LP_GSW0P(LPCmd->LPGenShortWriteNoP));
1322   assert_param(IS_DSI_LP_GSW1P(LPCmd->LPGenShortWriteOneP));
1323   assert_param(IS_DSI_LP_GSW2P(LPCmd->LPGenShortWriteTwoP));
1324   assert_param(IS_DSI_LP_GSR0P(LPCmd->LPGenShortReadNoP));
1325   assert_param(IS_DSI_LP_GSR1P(LPCmd->LPGenShortReadOneP));
1326   assert_param(IS_DSI_LP_GSR2P(LPCmd->LPGenShortReadTwoP));
1327   assert_param(IS_DSI_LP_GLW(LPCmd->LPGenLongWrite));
1328   assert_param(IS_DSI_LP_DSW0P(LPCmd->LPDcsShortWriteNoP));
1329   assert_param(IS_DSI_LP_DSW1P(LPCmd->LPDcsShortWriteOneP));
1330   assert_param(IS_DSI_LP_DSR0P(LPCmd->LPDcsShortReadNoP));
1331   assert_param(IS_DSI_LP_DLW(LPCmd->LPDcsLongWrite));
1332   assert_param(IS_DSI_LP_MRDP(LPCmd->LPMaxReadPacket));
1333   assert_param(IS_DSI_ACK_REQUEST(LPCmd->AcknowledgeRequest));
1334 
1335   /* Select High-speed or Low-power for command transmission */
1336   hdsi->Instance->CMCR &= ~(DSI_CMCR_GSW0TX | \
1337                             DSI_CMCR_GSW1TX | \
1338                             DSI_CMCR_GSW2TX | \
1339                             DSI_CMCR_GSR0TX | \
1340                             DSI_CMCR_GSR1TX | \
1341                             DSI_CMCR_GSR2TX | \
1342                             DSI_CMCR_GLWTX  | \
1343                             DSI_CMCR_DSW0TX | \
1344                             DSI_CMCR_DSW1TX | \
1345                             DSI_CMCR_DSR0TX | \
1346                             DSI_CMCR_DLWTX  | \
1347                             DSI_CMCR_MRDPS);
1348   hdsi->Instance->CMCR |= (LPCmd->LPGenShortWriteNoP  | \
1349                            LPCmd->LPGenShortWriteOneP | \
1350                            LPCmd->LPGenShortWriteTwoP | \
1351                            LPCmd->LPGenShortReadNoP   | \
1352                            LPCmd->LPGenShortReadOneP  | \
1353                            LPCmd->LPGenShortReadTwoP  | \
1354                            LPCmd->LPGenLongWrite      | \
1355                            LPCmd->LPDcsShortWriteNoP  | \
1356                            LPCmd->LPDcsShortWriteOneP | \
1357                            LPCmd->LPDcsShortReadNoP   | \
1358                            LPCmd->LPDcsLongWrite      | \
1359                            LPCmd->LPMaxReadPacket);
1360 
1361   /* Configure the acknowledge request after each packet transmission */
1362   hdsi->Instance->CMCR &= ~DSI_CMCR_ARE;
1363   hdsi->Instance->CMCR |= LPCmd->AcknowledgeRequest;
1364 
1365   /* Process unlocked */
1366   __HAL_UNLOCK(hdsi);
1367 
1368   return HAL_OK;
1369 }
1370 
1371 /**
1372   * @brief  Configure the flow control parameters
1373   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1374   *               the configuration information for the DSI.
1375   * @param  FlowControl  flow control feature(s) to be enabled.
1376   *                      This parameter can be any combination of @arg DSI_FlowControl.
1377   * @retval HAL status
1378   */
1379 HAL_StatusTypeDef HAL_DSI_ConfigFlowControl(DSI_HandleTypeDef *hdsi, uint32_t FlowControl)
1380 {
1381   /* Process locked */
1382   __HAL_LOCK(hdsi);
1383 
1384   /* Check the parameters */
1385   assert_param(IS_DSI_FLOW_CONTROL(FlowControl));
1386 
1387   /* Set the DSI Host Protocol Configuration Register */
1388   hdsi->Instance->PCR &= ~DSI_FLOW_CONTROL_ALL;
1389   hdsi->Instance->PCR |= FlowControl;
1390 
1391   /* Process unlocked */
1392   __HAL_UNLOCK(hdsi);
1393 
1394   return HAL_OK;
1395 }
1396 
1397 /**
1398   * @brief  Configure the DSI PHY timer parameters
1399   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1400   *               the configuration information for the DSI.
1401   * @param  PhyTimers  DSI_PHY_TimerTypeDef structure that contains
1402   *                    the DSI PHY timing parameters
1403   * @retval HAL status
1404   */
1405 HAL_StatusTypeDef HAL_DSI_ConfigPhyTimer(DSI_HandleTypeDef *hdsi, DSI_PHY_TimerTypeDef *PhyTimers)
1406 {
1407   uint32_t maxTime;
1408   /* Process locked */
1409   __HAL_LOCK(hdsi);
1410 
1411   maxTime = (PhyTimers->ClockLaneLP2HSTime > PhyTimers->ClockLaneHS2LPTime) ? PhyTimers->ClockLaneLP2HSTime :
1412             PhyTimers->ClockLaneHS2LPTime;
1413 
1414   /* Clock lane timer configuration */
1415 
1416   /* In Automatic Clock Lane control mode, the DSI Host can turn off the clock lane between two
1417      High-Speed transmission.
1418      To do so, the DSI Host calculates the time required for the clock lane to change from HighSpeed
1419      to Low-Power and from Low-Power to High-Speed.
1420      This timings are configured by the HS2LP_TIME and LP2HS_TIME in the DSI Host Clock Lane Timer Configuration
1421      Register (DSI_CLTCR).
1422      But the DSI Host is not calculating LP2HS_TIME + HS2LP_TIME but 2 x HS2LP_TIME.
1423 
1424      Workaround : Configure HS2LP_TIME and LP2HS_TIME with the same value being the max of HS2LP_TIME or LP2HS_TIME.
1425     */
1426   hdsi->Instance->CLTCR &= ~(DSI_CLTCR_LP2HS_TIME | DSI_CLTCR_HS2LP_TIME);
1427   hdsi->Instance->CLTCR |= (maxTime | ((maxTime) << 16U));
1428 
1429   /* Data lane timer configuration */
1430   hdsi->Instance->DLTCR &= ~(DSI_DLTCR_MRD_TIME | DSI_DLTCR_LP2HS_TIME | DSI_DLTCR_HS2LP_TIME);
1431   hdsi->Instance->DLTCR |= (PhyTimers->DataLaneMaxReadTime | ((PhyTimers->DataLaneLP2HSTime) << 16U) | ((
1432                               PhyTimers->DataLaneHS2LPTime) << 24U));
1433 
1434   /* Configure the wait period to request HS transmission after a stop state */
1435   hdsi->Instance->PCONFR &= ~DSI_PCONFR_SW_TIME;
1436   hdsi->Instance->PCONFR |= ((PhyTimers->StopWaitTime) << 8U);
1437 
1438   /* Process unlocked */
1439   __HAL_UNLOCK(hdsi);
1440 
1441   return HAL_OK;
1442 }
1443 
1444 /**
1445   * @brief  Configure the DSI HOST timeout parameters
1446   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1447   *               the configuration information for the DSI.
1448   * @param  HostTimeouts  DSI_HOST_TimeoutTypeDef structure that contains
1449   *                       the DSI host timeout parameters
1450   * @retval HAL status
1451   */
1452 HAL_StatusTypeDef HAL_DSI_ConfigHostTimeouts(DSI_HandleTypeDef *hdsi, DSI_HOST_TimeoutTypeDef *HostTimeouts)
1453 {
1454   /* Process locked */
1455   __HAL_LOCK(hdsi);
1456 
1457   /* Set the timeout clock division factor */
1458   hdsi->Instance->CCR &= ~DSI_CCR_TOCKDIV;
1459   hdsi->Instance->CCR |= ((HostTimeouts->TimeoutCkdiv) << 8U);
1460 
1461   /* High-speed transmission timeout */
1462   hdsi->Instance->TCCR[0U] &= ~DSI_TCCR0_HSTX_TOCNT;
1463   hdsi->Instance->TCCR[0U] |= ((HostTimeouts->HighSpeedTransmissionTimeout) << 16U);
1464 
1465   /* Low-power reception timeout */
1466   hdsi->Instance->TCCR[0U] &= ~DSI_TCCR0_LPRX_TOCNT;
1467   hdsi->Instance->TCCR[0U] |= HostTimeouts->LowPowerReceptionTimeout;
1468 
1469   /* High-speed read timeout */
1470   hdsi->Instance->TCCR[1U] &= ~DSI_TCCR1_HSRD_TOCNT;
1471   hdsi->Instance->TCCR[1U] |= HostTimeouts->HighSpeedReadTimeout;
1472 
1473   /* Low-power read timeout */
1474   hdsi->Instance->TCCR[2U] &= ~DSI_TCCR2_LPRD_TOCNT;
1475   hdsi->Instance->TCCR[2U] |= HostTimeouts->LowPowerReadTimeout;
1476 
1477   /* High-speed write timeout */
1478   hdsi->Instance->TCCR[3U] &= ~DSI_TCCR3_HSWR_TOCNT;
1479   hdsi->Instance->TCCR[3U] |= HostTimeouts->HighSpeedWriteTimeout;
1480 
1481   /* High-speed write presp mode */
1482   hdsi->Instance->TCCR[3U] &= ~DSI_TCCR3_PM;
1483   hdsi->Instance->TCCR[3U] |= HostTimeouts->HighSpeedWritePrespMode;
1484 
1485   /* Low-speed write timeout */
1486   hdsi->Instance->TCCR[4U] &= ~DSI_TCCR4_LPWR_TOCNT;
1487   hdsi->Instance->TCCR[4U] |= HostTimeouts->LowPowerWriteTimeout;
1488 
1489   /* BTA timeout */
1490   hdsi->Instance->TCCR[5U] &= ~DSI_TCCR5_BTA_TOCNT;
1491   hdsi->Instance->TCCR[5U] |= HostTimeouts->BTATimeout;
1492 
1493   /* Process unlocked */
1494   __HAL_UNLOCK(hdsi);
1495 
1496   return HAL_OK;
1497 }
1498 
1499 /**
1500   * @brief  Start the DSI module
1501   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1502   *               the configuration information for the DSI.
1503   * @retval HAL status
1504   */
1505 HAL_StatusTypeDef HAL_DSI_Start(DSI_HandleTypeDef *hdsi)
1506 {
1507   /* Process locked */
1508   __HAL_LOCK(hdsi);
1509 
1510   /* Enable the DSI host */
1511   __HAL_DSI_ENABLE(hdsi);
1512 
1513   /* Enable the DSI wrapper */
1514   __HAL_DSI_WRAPPER_ENABLE(hdsi);
1515 
1516   /* Process unlocked */
1517   __HAL_UNLOCK(hdsi);
1518 
1519   return HAL_OK;
1520 }
1521 
1522 /**
1523   * @brief  Stop the DSI module
1524   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1525   *               the configuration information for the DSI.
1526   * @retval HAL status
1527   */
1528 HAL_StatusTypeDef HAL_DSI_Stop(DSI_HandleTypeDef *hdsi)
1529 {
1530   /* Process locked */
1531   __HAL_LOCK(hdsi);
1532 
1533   /* Disable the DSI host */
1534   __HAL_DSI_DISABLE(hdsi);
1535 
1536   /* Disable the DSI wrapper */
1537   __HAL_DSI_WRAPPER_DISABLE(hdsi);
1538 
1539   /* Process unlocked */
1540   __HAL_UNLOCK(hdsi);
1541 
1542   return HAL_OK;
1543 }
1544 
1545 /**
1546   * @brief  Refresh the display in command mode
1547   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1548   *               the configuration information for the DSI.
1549   * @retval HAL status
1550   */
1551 HAL_StatusTypeDef HAL_DSI_Refresh(DSI_HandleTypeDef *hdsi)
1552 {
1553   /* Process locked */
1554   __HAL_LOCK(hdsi);
1555 
1556   /* Update the display */
1557   hdsi->Instance->WCR |= DSI_WCR_LTDCEN;
1558 
1559   /* Process unlocked */
1560   __HAL_UNLOCK(hdsi);
1561 
1562   return HAL_OK;
1563 }
1564 
1565 /**
1566   * @brief  Controls the display color mode in Video mode
1567   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1568   *               the configuration information for the DSI.
1569   * @param  ColorMode  Color mode (full or 8-colors).
1570   *                    This parameter can be any value of @arg DSI_Color_Mode
1571   * @retval HAL status
1572   */
1573 HAL_StatusTypeDef HAL_DSI_ColorMode(DSI_HandleTypeDef *hdsi, uint32_t ColorMode)
1574 {
1575   /* Process locked */
1576   __HAL_LOCK(hdsi);
1577 
1578   /* Check the parameters */
1579   assert_param(IS_DSI_COLOR_MODE(ColorMode));
1580 
1581   /* Update the display color mode */
1582   hdsi->Instance->WCR &= ~DSI_WCR_COLM;
1583   hdsi->Instance->WCR |= ColorMode;
1584 
1585   /* Process unlocked */
1586   __HAL_UNLOCK(hdsi);
1587 
1588   return HAL_OK;
1589 }
1590 
1591 /**
1592   * @brief  Control the display shutdown in Video mode
1593   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1594   *               the configuration information for the DSI.
1595   * @param  Shutdown  Shut-down (Display-ON or Display-OFF).
1596   *                   This parameter can be any value of @arg DSI_ShutDown
1597   * @retval HAL status
1598   */
1599 HAL_StatusTypeDef HAL_DSI_Shutdown(DSI_HandleTypeDef *hdsi, uint32_t Shutdown)
1600 {
1601   /* Process locked */
1602   __HAL_LOCK(hdsi);
1603 
1604   /* Check the parameters */
1605   assert_param(IS_DSI_SHUT_DOWN(Shutdown));
1606 
1607   /* Update the display Shutdown */
1608   hdsi->Instance->WCR &= ~DSI_WCR_SHTDN;
1609   hdsi->Instance->WCR |= Shutdown;
1610 
1611   /* Process unlocked */
1612   __HAL_UNLOCK(hdsi);
1613 
1614   return HAL_OK;
1615 }
1616 
1617 /**
1618   * @brief  write short DCS or short Generic command
1619   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1620   *               the configuration information for the DSI.
1621   * @param  ChannelID  Virtual channel ID.
1622   * @param  Mode  DSI short packet data type.
1623   *               This parameter can be any value of @arg DSI_SHORT_WRITE_PKT_Data_Type.
1624   * @param  Param1  DSC command or first generic parameter.
1625   *                 This parameter can be any value of @arg DSI_DCS_Command or a
1626   *                 generic command code.
1627   * @param  Param2  DSC parameter or second generic parameter.
1628   * @retval HAL status
1629   */
1630 HAL_StatusTypeDef HAL_DSI_ShortWrite(DSI_HandleTypeDef *hdsi,
1631                                      uint32_t ChannelID,
1632                                      uint32_t Mode,
1633                                      uint32_t Param1,
1634                                      uint32_t Param2)
1635 {
1636   HAL_StatusTypeDef status;
1637   /* Check the parameters */
1638   assert_param(IS_DSI_SHORT_WRITE_PACKET_TYPE(Mode));
1639 
1640   /* Process locked */
1641   __HAL_LOCK(hdsi);
1642 
1643   status = DSI_ShortWrite(hdsi, ChannelID, Mode, Param1, Param2);
1644 
1645   /* Process unlocked */
1646   __HAL_UNLOCK(hdsi);
1647 
1648   return status;
1649 }
1650 
1651 /**
1652   * @brief  write long DCS or long Generic command
1653   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1654   *               the configuration information for the DSI.
1655   * @param  ChannelID  Virtual channel ID.
1656   * @param  Mode  DSI long packet data type.
1657   *               This parameter can be any value of @arg DSI_LONG_WRITE_PKT_Data_Type.
1658   * @param  NbParams  Number of parameters.
1659   * @param  Param1  DSC command or first generic parameter.
1660   *                 This parameter can be any value of @arg DSI_DCS_Command or a
1661   *                 generic command code
1662   * @param  ParametersTable  Pointer to parameter values table.
1663   * @retval HAL status
1664   */
1665 HAL_StatusTypeDef HAL_DSI_LongWrite(DSI_HandleTypeDef *hdsi,
1666                                     uint32_t ChannelID,
1667                                     uint32_t Mode,
1668                                     uint32_t NbParams,
1669                                     uint32_t Param1,
1670                                     const uint8_t *ParametersTable)
1671 {
1672   uint32_t uicounter;
1673   uint32_t nbBytes;
1674   uint32_t count;
1675   uint32_t tickstart;
1676   uint32_t fifoword;
1677   const uint8_t *pparams = ParametersTable;
1678 
1679   /* Process locked */
1680   __HAL_LOCK(hdsi);
1681 
1682   /* Check the parameters */
1683   assert_param(IS_DSI_LONG_WRITE_PACKET_TYPE(Mode));
1684 
1685   /* Get tick */
1686   tickstart = HAL_GetTick();
1687 
1688   /* Wait for Command FIFO Empty */
1689   while ((hdsi->Instance->GPSR & DSI_GPSR_CMDFE) == 0U)
1690   {
1691     /* Check for the Timeout */
1692     if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
1693     {
1694       /* Process Unlocked */
1695       __HAL_UNLOCK(hdsi);
1696 
1697       return HAL_TIMEOUT;
1698     }
1699   }
1700 
1701   /* Set the DCS code on payload byte 1, and the other parameters on the write FIFO command*/
1702   fifoword = Param1;
1703   nbBytes = (NbParams < 3U) ? NbParams : 3U;
1704 
1705   for (count = 0U; count < nbBytes; count++)
1706   {
1707     fifoword |= (((uint32_t)(*(pparams + count))) << (8U + (8U * count)));
1708   }
1709   hdsi->Instance->GPDR = fifoword;
1710 
1711   uicounter = NbParams - nbBytes;
1712   pparams += nbBytes;
1713   /* Set the Next parameters on the write FIFO command*/
1714   while (uicounter != 0U)
1715   {
1716     nbBytes = (uicounter < 4U) ? uicounter : 4U;
1717     fifoword = 0U;
1718     for (count = 0U; count < nbBytes; count++)
1719     {
1720       fifoword |= (((uint32_t)(*(pparams + count))) << (8U * count));
1721     }
1722     hdsi->Instance->GPDR = fifoword;
1723 
1724     uicounter -= nbBytes;
1725     pparams += nbBytes;
1726   }
1727 
1728   /* Configure the packet to send a long DCS command */
1729   DSI_ConfigPacketHeader(hdsi->Instance,
1730                          ChannelID,
1731                          Mode,
1732                          ((NbParams + 1U) & 0x00FFU),
1733                          (((NbParams + 1U) & 0xFF00U) >> 8U));
1734 
1735   /* Process unlocked */
1736   __HAL_UNLOCK(hdsi);
1737 
1738   return HAL_OK;
1739 }
1740 
1741 /**
1742   * @brief  Read command (DCS or generic)
1743   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1744   *               the configuration information for the DSI.
1745   * @param  ChannelNbr  Virtual channel ID
1746   * @param  Array pointer to a buffer to store the payload of a read back operation.
1747   * @param  Size  Data size to be read (in byte).
1748   * @param  Mode  DSI read packet data type.
1749   *               This parameter can be any value of @arg DSI_SHORT_READ_PKT_Data_Type.
1750   * @param  DCSCmd  DCS get/read command.
1751   * @param  ParametersTable  Pointer to parameter values table.
1752   * @retval HAL status
1753   */
1754 HAL_StatusTypeDef HAL_DSI_Read(DSI_HandleTypeDef *hdsi,
1755                                uint32_t ChannelNbr,
1756                                uint8_t *Array,
1757                                uint32_t Size,
1758                                uint32_t Mode,
1759                                uint32_t DCSCmd,
1760                                uint8_t *ParametersTable)
1761 {
1762   uint32_t tickstart;
1763   uint8_t *pdata = Array;
1764   uint32_t datasize = Size;
1765   uint32_t fifoword;
1766   uint32_t nbbytes;
1767   uint32_t count;
1768 
1769   /* Process locked */
1770   __HAL_LOCK(hdsi);
1771 
1772   /* Check the parameters */
1773   assert_param(IS_DSI_READ_PACKET_TYPE(Mode));
1774 
1775   if (datasize > 2U)
1776   {
1777     /* set max return packet size */
1778     if (DSI_ShortWrite(hdsi, ChannelNbr, DSI_MAX_RETURN_PKT_SIZE, ((datasize) & 0xFFU),
1779                        (((datasize) >> 8U) & 0xFFU)) != HAL_OK)
1780     {
1781       /* Process Unlocked */
1782       __HAL_UNLOCK(hdsi);
1783 
1784       return HAL_ERROR;
1785     }
1786   }
1787 
1788   /* Configure the packet to read command */
1789   if (Mode == DSI_DCS_SHORT_PKT_READ)
1790   {
1791     DSI_ConfigPacketHeader(hdsi->Instance, ChannelNbr, Mode, DCSCmd, 0U);
1792   }
1793   else if (Mode == DSI_GEN_SHORT_PKT_READ_P0)
1794   {
1795     DSI_ConfigPacketHeader(hdsi->Instance, ChannelNbr, Mode, 0U, 0U);
1796   }
1797   else if (Mode == DSI_GEN_SHORT_PKT_READ_P1)
1798   {
1799     DSI_ConfigPacketHeader(hdsi->Instance, ChannelNbr, Mode, ParametersTable[0U], 0U);
1800   }
1801   else if (Mode == DSI_GEN_SHORT_PKT_READ_P2)
1802   {
1803     DSI_ConfigPacketHeader(hdsi->Instance, ChannelNbr, Mode, ParametersTable[0U], ParametersTable[1U]);
1804   }
1805   else
1806   {
1807     /* Process Unlocked */
1808     __HAL_UNLOCK(hdsi);
1809 
1810     return HAL_ERROR;
1811   }
1812 
1813   /* Get tick */
1814   tickstart = HAL_GetTick();
1815 
1816   /* If DSI fifo is not empty, read requested bytes */
1817   while (((int32_t)(datasize)) > 0)
1818   {
1819     if ((hdsi->Instance->GPSR & DSI_GPSR_PRDFE) == 0U)
1820     {
1821       fifoword = hdsi->Instance->GPDR;
1822       nbbytes = (datasize < 4U) ? datasize : 4U;
1823 
1824       for (count = 0U; count < nbbytes; count++)
1825       {
1826         *pdata = (uint8_t)(fifoword >> (8U * count));
1827         pdata++;
1828         datasize--;
1829       }
1830     }
1831 
1832     /* Check for the Timeout */
1833     if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
1834     {
1835       /* Process Unlocked */
1836       __HAL_UNLOCK(hdsi);
1837 
1838       return HAL_TIMEOUT;
1839     }
1840 
1841     /* Software workaround to avoid HAL_TIMEOUT when a DSI read command is   */
1842     /* issued to the panel and the read data is not captured by the DSI Host */
1843     /* which returns Packet Size Error.                                      */
1844     /* Need to ensure that the Read command has finished before checking PSE */
1845     if ((hdsi->Instance->GPSR & DSI_GPSR_RCB) == 0U)
1846     {
1847       if ((hdsi->Instance->ISR[1U] & DSI_ISR1_PSE) == DSI_ISR1_PSE)
1848       {
1849         /* Process Unlocked */
1850         __HAL_UNLOCK(hdsi);
1851 
1852         return HAL_ERROR;
1853       }
1854     }
1855   }
1856 
1857   /* Process unlocked */
1858   __HAL_UNLOCK(hdsi);
1859 
1860   return HAL_OK;
1861 }
1862 
1863 /**
1864   * @brief  Enter the ULPM (Ultra Low Power Mode) with the D-PHY PLL running
1865   *         (only data lanes are in ULPM)
1866   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1867   *               the configuration information for the DSI.
1868   * @retval HAL status
1869   */
1870 HAL_StatusTypeDef HAL_DSI_EnterULPMData(DSI_HandleTypeDef *hdsi)
1871 {
1872   uint32_t tickstart;
1873 
1874   /* Process locked */
1875   __HAL_LOCK(hdsi);
1876 
1877   /* Verify the initial status of the DSI Host */
1878 
1879   /* Verify that the clock lane and the digital section of the D-PHY are enabled */
1880   if ((hdsi->Instance->PCTLR & (DSI_PCTLR_CKE | DSI_PCTLR_DEN)) != (DSI_PCTLR_CKE | DSI_PCTLR_DEN))
1881   {
1882     /* Process Unlocked */
1883     __HAL_UNLOCK(hdsi);
1884     return HAL_ERROR;
1885   }
1886 
1887   /* Verify that the D-PHY PLL and the reference bias are enabled */
1888   if ((hdsi->Instance->WRPCR & DSI_WRPCR_PLLEN) != DSI_WRPCR_PLLEN)
1889   {
1890     /* Process Unlocked */
1891     __HAL_UNLOCK(hdsi);
1892     return HAL_ERROR;
1893   }
1894   else if ((hdsi->Instance->WRPCR & DSI_WRPCR_REGEN) != DSI_WRPCR_REGEN)
1895   {
1896     /* Process Unlocked */
1897     __HAL_UNLOCK(hdsi);
1898     return HAL_ERROR;
1899   }
1900   else
1901   {
1902     /* Nothing to do */
1903   }
1904 
1905   /* Verify that there are no ULPS exit or request on data lanes */
1906   if ((hdsi->Instance->PUCR & (DSI_PUCR_UEDL | DSI_PUCR_URDL)) != 0U)
1907   {
1908     /* Process Unlocked */
1909     __HAL_UNLOCK(hdsi);
1910     return HAL_ERROR;
1911   }
1912 
1913   /* Verify that there are no Transmission trigger */
1914   if ((hdsi->Instance->PTTCR & DSI_PTTCR_TX_TRIG) != 0U)
1915   {
1916     /* Process Unlocked */
1917     __HAL_UNLOCK(hdsi);
1918     return HAL_ERROR;
1919   }
1920 
1921   /* Requires min of 400us delay before reading the PLLLS flag */
1922   /* 1ms delay is inserted that is the minimum HAL delay granularity */
1923   HAL_Delay(1);
1924 
1925   /* Verify that D-PHY PLL is locked */
1926   tickstart = HAL_GetTick();
1927 
1928   while ((__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_PLLLS) == 0U))
1929   {
1930     /* Check for the Timeout */
1931     if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
1932     {
1933       /* Process Unlocked */
1934       __HAL_UNLOCK(hdsi);
1935 
1936       return HAL_TIMEOUT;
1937     }
1938   }
1939 
1940   /* Verify that all active lanes are in Stop state */
1941   if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
1942   {
1943     if ((hdsi->Instance->PSR & DSI_PSR_UAN0) != DSI_PSR_UAN0)
1944     {
1945       /* Process Unlocked */
1946       __HAL_UNLOCK(hdsi);
1947       return HAL_ERROR;
1948     }
1949   }
1950   else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
1951   {
1952     if ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1)) != (DSI_PSR_UAN0 | DSI_PSR_UAN1))
1953     {
1954       /* Process Unlocked */
1955       __HAL_UNLOCK(hdsi);
1956       return HAL_ERROR;
1957     }
1958   }
1959   else
1960   {
1961     /* Process unlocked */
1962     __HAL_UNLOCK(hdsi);
1963     return HAL_ERROR;
1964   }
1965 
1966   /* ULPS Request on Data Lanes */
1967   hdsi->Instance->PUCR |= DSI_PUCR_URDL;
1968 
1969   /* Get tick */
1970   tickstart = HAL_GetTick();
1971 
1972   /* Wait until the D-PHY active lanes enter into ULPM */
1973   if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
1974   {
1975     while ((hdsi->Instance->PSR & DSI_PSR_UAN0) != 0U)
1976     {
1977       /* Check for the Timeout */
1978       if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
1979       {
1980         /* Process Unlocked */
1981         __HAL_UNLOCK(hdsi);
1982 
1983         return HAL_TIMEOUT;
1984       }
1985     }
1986   }
1987   else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
1988   {
1989     while ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1)) != 0U)
1990     {
1991       /* Check for the Timeout */
1992       if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
1993       {
1994         /* Process Unlocked */
1995         __HAL_UNLOCK(hdsi);
1996 
1997         return HAL_TIMEOUT;
1998       }
1999     }
2000   }
2001   else
2002   {
2003     /* Process unlocked */
2004     __HAL_UNLOCK(hdsi);
2005 
2006     return HAL_ERROR;
2007   }
2008 
2009   /* Process unlocked */
2010   __HAL_UNLOCK(hdsi);
2011 
2012   return HAL_OK;
2013 }
2014 
2015 /**
2016   * @brief  Exit the ULPM (Ultra Low Power Mode) with the D-PHY PLL running
2017   *         (only data lanes are in ULPM)
2018   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2019   *               the configuration information for the DSI.
2020   * @retval HAL status
2021   */
2022 HAL_StatusTypeDef HAL_DSI_ExitULPMData(DSI_HandleTypeDef *hdsi)
2023 {
2024   uint32_t tickstart;
2025 
2026   /* Process locked */
2027   __HAL_LOCK(hdsi);
2028 
2029   /* Verify that all active lanes are in ULPM */
2030   if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
2031   {
2032     if ((hdsi->Instance->PSR &  DSI_PSR_UAN0) != 0U)
2033     {
2034       /* Process Unlocked */
2035       __HAL_UNLOCK(hdsi);
2036 
2037       return HAL_ERROR;
2038     }
2039   }
2040   else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
2041   {
2042     if ((hdsi->Instance->PSR & (DSI_PSR_UAN0  | DSI_PSR_UAN1)) != 0U)
2043     {
2044       /* Process Unlocked */
2045       __HAL_UNLOCK(hdsi);
2046 
2047       return HAL_ERROR;
2048     }
2049   }
2050   else
2051   {
2052     /* Process unlocked */
2053     __HAL_UNLOCK(hdsi);
2054 
2055     return HAL_ERROR;
2056   }
2057 
2058   /* Turn on the DSI PLL */
2059   __HAL_DSI_PLL_ENABLE(hdsi);
2060 
2061   /* Requires min of 400us delay before reading the PLLLS flag */
2062   /* 1ms delay is inserted that is the minimum HAL delay granularity */
2063   HAL_Delay(1);
2064 
2065   /* Get tick */
2066   tickstart = HAL_GetTick();
2067 
2068   /* Wait for the lock of the PLL */
2069   while (__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_PLLLS) == 0U)
2070   {
2071     /* Check for the Timeout */
2072     if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2073     {
2074       /* Process Unlocked */
2075       __HAL_UNLOCK(hdsi);
2076 
2077       return HAL_TIMEOUT;
2078     }
2079   }
2080 
2081   /* Exit ULPS on Data Lanes */
2082   hdsi->Instance->PUCR |= DSI_PUCR_UEDL;
2083 
2084   /* Get tick */
2085   tickstart = HAL_GetTick();
2086 
2087   /* Wait until all active lanes exit ULPM */
2088   if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
2089   {
2090     while ((hdsi->Instance->PSR & DSI_PSR_UAN0) != DSI_PSR_UAN0)
2091     {
2092       /* Check for the Timeout */
2093       if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2094       {
2095         /* Process Unlocked */
2096         __HAL_UNLOCK(hdsi);
2097 
2098         return HAL_TIMEOUT;
2099       }
2100     }
2101   }
2102   else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
2103   {
2104     while ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1)) != (DSI_PSR_UAN0 | DSI_PSR_UAN1))
2105     {
2106       /* Check for the Timeout */
2107       if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2108       {
2109         /* Process Unlocked */
2110         __HAL_UNLOCK(hdsi);
2111 
2112         return HAL_TIMEOUT;
2113       }
2114     }
2115   }
2116   else
2117   {
2118     /* Process unlocked */
2119     __HAL_UNLOCK(hdsi);
2120 
2121     return HAL_ERROR;
2122   }
2123 
2124   /* wait for 1 ms*/
2125   HAL_Delay(1U);
2126 
2127   /* De-assert the ULPM requests and the ULPM exit bits */
2128   hdsi->Instance->PUCR = 0U;
2129 
2130   /* Verify that D-PHY PLL is enabled */
2131   if ((hdsi->Instance->WRPCR & DSI_WRPCR_PLLEN) != DSI_WRPCR_PLLEN)
2132   {
2133     /* Process Unlocked */
2134     __HAL_UNLOCK(hdsi);
2135     return HAL_ERROR;
2136   }
2137 
2138   /* Verify that all active lanes are in Stop state */
2139   if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
2140   {
2141     if ((hdsi->Instance->PSR & DSI_PSR_UAN0) != DSI_PSR_UAN0)
2142     {
2143       /* Process Unlocked */
2144       __HAL_UNLOCK(hdsi);
2145       return HAL_ERROR;
2146     }
2147   }
2148   else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
2149   {
2150     if ((hdsi->Instance->PSR & (DSI_PSR_UAN0  |  DSI_PSR_UAN1)) != (DSI_PSR_UAN0 | DSI_PSR_UAN1))
2151     {
2152       /* Process Unlocked */
2153       __HAL_UNLOCK(hdsi);
2154       return HAL_ERROR;
2155     }
2156   }
2157   else
2158   {
2159     /* Process unlocked */
2160     __HAL_UNLOCK(hdsi);
2161     return HAL_ERROR;
2162   }
2163 
2164   /* Verify that D-PHY PLL is locked */
2165   /* Requires min of 400us delay before reading the PLLLS flag */
2166   /* 1ms delay is inserted that is the minimum HAL delay granularity */
2167   HAL_Delay(1);
2168 
2169   /* Get tick */
2170   tickstart = HAL_GetTick();
2171 
2172   /* Wait for the lock of the PLL */
2173   while (__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_PLLLS) == 0U)
2174   {
2175     /* Check for the Timeout */
2176     if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2177     {
2178       /* Process Unlocked */
2179       __HAL_UNLOCK(hdsi);
2180 
2181       return HAL_TIMEOUT;
2182     }
2183   }
2184 
2185   /* Process unlocked */
2186   __HAL_UNLOCK(hdsi);
2187 
2188   return HAL_OK;
2189 }
2190 
2191 /**
2192   * @brief  Enter the ULPM (Ultra Low Power Mode) with the D-PHY PLL turned off
2193   *         (both data and clock lanes are in ULPM)
2194   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2195   *               the configuration information for the DSI.
2196   * @retval HAL status
2197   */
2198 HAL_StatusTypeDef HAL_DSI_EnterULPM(DSI_HandleTypeDef *hdsi)
2199 {
2200   uint32_t tickstart;
2201 
2202   /* Process locked */
2203   __HAL_LOCK(hdsi);
2204 
2205   /* Verify the initial status of the DSI Host */
2206 
2207   /* Verify that the clock lane and the digital section of the D-PHY are enabled */
2208   if ((hdsi->Instance->PCTLR & (DSI_PCTLR_CKE | DSI_PCTLR_DEN)) != (DSI_PCTLR_CKE | DSI_PCTLR_DEN))
2209   {
2210     /* Process Unlocked */
2211     __HAL_UNLOCK(hdsi);
2212     return HAL_ERROR;
2213   }
2214 
2215   /* Verify that the D-PHY PLL and the reference bias are enabled */
2216   if ((hdsi->Instance->WRPCR & DSI_WRPCR_PLLEN) != DSI_WRPCR_PLLEN)
2217   {
2218     /* Process Unlocked */
2219     __HAL_UNLOCK(hdsi);
2220     return HAL_ERROR;
2221   }
2222   else if ((hdsi->Instance->WRPCR & DSI_WRPCR_REGEN) != DSI_WRPCR_REGEN)
2223   {
2224     /* Process Unlocked */
2225     __HAL_UNLOCK(hdsi);
2226     return HAL_ERROR;
2227   }
2228   else
2229   {
2230     /* Nothing to do */
2231   }
2232 
2233   /* Verify that there are no ULPS exit or request on both data and clock lanes */
2234   if ((hdsi->Instance->PUCR & (DSI_PUCR_UEDL | DSI_PUCR_URDL | DSI_PUCR_UECL | DSI_PUCR_URCL)) != 0U)
2235   {
2236     /* Process Unlocked */
2237     __HAL_UNLOCK(hdsi);
2238     return HAL_ERROR;
2239   }
2240 
2241   /* Verify that there are no Transmission trigger */
2242   if ((hdsi->Instance->PTTCR & DSI_PTTCR_TX_TRIG) != 0U)
2243   {
2244     /* Process Unlocked */
2245     __HAL_UNLOCK(hdsi);
2246     return HAL_ERROR;
2247   }
2248 
2249   /* Requires min of 400us delay before reading the PLLLS flag */
2250   /* 1ms delay is inserted that is the minimum HAL delay granularity */
2251   HAL_Delay(1);
2252 
2253   /* Verify that D-PHY PLL is locked */
2254   tickstart = HAL_GetTick();
2255 
2256   while ((__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_PLLLS) == 0U))
2257   {
2258     /* Check for the Timeout */
2259     if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2260     {
2261       /* Process Unlocked */
2262       __HAL_UNLOCK(hdsi);
2263 
2264       return HAL_TIMEOUT;
2265     }
2266   }
2267 
2268   /* Verify that all active lanes are in Stop state */
2269   if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
2270   {
2271     if ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_PSS0)) != (DSI_PSR_UAN0 | DSI_PSR_PSS0))
2272     {
2273       /* Process Unlocked */
2274       __HAL_UNLOCK(hdsi);
2275       return HAL_ERROR;
2276     }
2277   }
2278   else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
2279   {
2280     if ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_PSS0 | DSI_PSR_PSS1 | \
2281                                 DSI_PSR_UAN1)) != (DSI_PSR_UAN0 | DSI_PSR_PSS0 | DSI_PSR_PSS1 | DSI_PSR_UAN1))
2282     {
2283       /* Process Unlocked */
2284       __HAL_UNLOCK(hdsi);
2285       return HAL_ERROR;
2286     }
2287   }
2288   else
2289   {
2290     /* Process unlocked */
2291     __HAL_UNLOCK(hdsi);
2292     return HAL_ERROR;
2293   }
2294 
2295   /* Clock lane configuration: no more HS request */
2296   hdsi->Instance->CLCR &= ~DSI_CLCR_DPCC;
2297 
2298   /* Use system PLL as byte lane clock source before stopping DSIPHY clock source */
2299   __HAL_RCC_DSI_CONFIG(RCC_DSICLKSOURCE_PLL2);
2300 
2301   /* ULPS Request on Clock and Data Lanes */
2302   hdsi->Instance->PUCR |= (DSI_PUCR_URCL | DSI_PUCR_URDL);
2303 
2304   /* Get tick */
2305   tickstart = HAL_GetTick();
2306 
2307   /* Wait until all active lanes enter ULPM */
2308   if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
2309   {
2310     while ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UANC)) != 0U)
2311     {
2312       /* Check for the Timeout */
2313       if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2314       {
2315         /* Process Unlocked */
2316         __HAL_UNLOCK(hdsi);
2317 
2318         return HAL_TIMEOUT;
2319       }
2320     }
2321   }
2322   else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
2323   {
2324     while ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1 | DSI_PSR_UANC)) != 0U)
2325     {
2326       /* Check for the Timeout */
2327       if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2328       {
2329         /* Process Unlocked */
2330         __HAL_UNLOCK(hdsi);
2331 
2332         return HAL_TIMEOUT;
2333       }
2334     }
2335   }
2336   else
2337   {
2338     /* Process unlocked */
2339     __HAL_UNLOCK(hdsi);
2340 
2341     return HAL_ERROR;
2342   }
2343 
2344   /* Turn off the DSI PLL */
2345   __HAL_DSI_PLL_DISABLE(hdsi);
2346 
2347   /* Process unlocked */
2348   __HAL_UNLOCK(hdsi);
2349 
2350   return HAL_OK;
2351 }
2352 
2353 /**
2354   * @brief  Exit the ULPM (Ultra Low Power Mode) with the D-PHY PLL turned off
2355   *         (both data and clock lanes are in ULPM)
2356   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2357   *               the configuration information for the DSI.
2358   * @retval HAL status
2359   */
2360 HAL_StatusTypeDef HAL_DSI_ExitULPM(DSI_HandleTypeDef *hdsi)
2361 {
2362   uint32_t tickstart;
2363 
2364   /* Process locked */
2365   __HAL_LOCK(hdsi);
2366 
2367   /* Verify that all active lanes are in ULPM */
2368   if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
2369   {
2370     if ((hdsi->Instance->PSR & (DSI_PSR_RUE0 | DSI_PSR_UAN0 | DSI_PSR_PSS0 | \
2371                                 DSI_PSR_UANC | DSI_PSR_PSSC | DSI_PSR_PD)) != 0U)
2372     {
2373       /* Process Unlocked */
2374       __HAL_UNLOCK(hdsi);
2375 
2376       return HAL_ERROR;
2377     }
2378   }
2379   else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
2380   {
2381     if ((hdsi->Instance->PSR & (DSI_PSR_RUE0 | DSI_PSR_UAN0 | DSI_PSR_PSS0 | DSI_PSR_UAN1 | \
2382                                 DSI_PSR_PSS1 | DSI_PSR_UANC | DSI_PSR_PSSC | DSI_PSR_PD)) != 0U)
2383     {
2384       /* Process Unlocked */
2385       __HAL_UNLOCK(hdsi);
2386 
2387       return HAL_ERROR;
2388     }
2389   }
2390   else
2391   {
2392     /* Process unlocked */
2393     __HAL_UNLOCK(hdsi);
2394 
2395     return HAL_ERROR;
2396   }
2397 
2398   /* Turn on the DSI PLL */
2399   __HAL_DSI_PLL_ENABLE(hdsi);
2400 
2401   /* Requires min of 400us delay before reading the PLLLS flag */
2402   /* 1ms delay is inserted that is the minimum HAL delay granularity */
2403   HAL_Delay(1);
2404 
2405   /* Get tick */
2406   tickstart = HAL_GetTick();
2407 
2408   /* Wait for the lock of the PLL */
2409   while (__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_PLLLS) == 0U)
2410   {
2411     /* Check for the Timeout */
2412     if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2413     {
2414       /* Process Unlocked */
2415       __HAL_UNLOCK(hdsi);
2416 
2417       return HAL_TIMEOUT;
2418     }
2419   }
2420 
2421   /* Exit ULPS on Clock and Data Lanes */
2422   hdsi->Instance->PUCR |= (DSI_PUCR_UECL | DSI_PUCR_UEDL);
2423 
2424   /* Get tick */
2425   tickstart = HAL_GetTick();
2426 
2427   /* Wait until all active lanes exit ULPM */
2428   if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
2429   {
2430     while ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UANC)) != (DSI_PSR_UAN0 | DSI_PSR_UANC))
2431     {
2432       /* Check for the Timeout */
2433       if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2434       {
2435         /* Process Unlocked */
2436         __HAL_UNLOCK(hdsi);
2437 
2438         return HAL_TIMEOUT;
2439       }
2440     }
2441   }
2442   else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
2443   {
2444     while ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1 | DSI_PSR_UANC)) != (DSI_PSR_UAN0 | DSI_PSR_UAN1 |
2445                                                                                     DSI_PSR_UANC))
2446     {
2447       /* Check for the Timeout */
2448       if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2449       {
2450         /* Process Unlocked */
2451         __HAL_UNLOCK(hdsi);
2452 
2453         return HAL_TIMEOUT;
2454       }
2455     }
2456   }
2457   else
2458   {
2459     /* Process unlocked */
2460     __HAL_UNLOCK(hdsi);
2461 
2462     return HAL_ERROR;
2463   }
2464 
2465   /* wait for 1 ms */
2466   HAL_Delay(1U);
2467 
2468   /* De-assert the ULPM requests and the ULPM exit bits */
2469   hdsi->Instance->PUCR = 0U;
2470 
2471   /* Switch the lane byte clock source in the RCC from system PLL to D-PHY */
2472   __HAL_RCC_DSI_CONFIG(RCC_DSICLKSOURCE_PHY);
2473 
2474   /* Restore clock lane configuration to HS */
2475   hdsi->Instance->CLCR |= DSI_CLCR_DPCC;
2476 
2477   /* Verify that D-PHY PLL is enabled */
2478   if ((hdsi->Instance->WRPCR & DSI_WRPCR_PLLEN) != DSI_WRPCR_PLLEN)
2479   {
2480     /* Process Unlocked */
2481     __HAL_UNLOCK(hdsi);
2482     return HAL_ERROR;
2483   }
2484 
2485   /* Verify that all active lanes are in Stop state */
2486   if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
2487   {
2488     if ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_PSS0)) != (DSI_PSR_UAN0 | DSI_PSR_PSS0))
2489     {
2490       /* Process Unlocked */
2491       __HAL_UNLOCK(hdsi);
2492       return HAL_ERROR;
2493     }
2494   }
2495   else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
2496   {
2497     if ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_PSS0 | DSI_PSR_PSS1 | \
2498                                 DSI_PSR_UAN1)) != (DSI_PSR_UAN0 | DSI_PSR_PSS0 | DSI_PSR_PSS1 | DSI_PSR_UAN1))
2499     {
2500       /* Process Unlocked */
2501       __HAL_UNLOCK(hdsi);
2502       return HAL_ERROR;
2503     }
2504   }
2505   else
2506   {
2507     /* Process unlocked */
2508     __HAL_UNLOCK(hdsi);
2509     return HAL_ERROR;
2510   }
2511 
2512   /* Verify that D-PHY PLL is locked */
2513   /* Requires min of 400us delay before reading the PLLLS flag */
2514   /* 1ms delay is inserted that is the minimum HAL delay granularity */
2515   HAL_Delay(1);
2516 
2517   /* Get tick */
2518   tickstart = HAL_GetTick();
2519 
2520   /* Wait for the lock of the PLL */
2521   while (__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_PLLLS) == 0U)
2522   {
2523     /* Check for the Timeout */
2524     if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2525     {
2526       /* Process Unlocked */
2527       __HAL_UNLOCK(hdsi);
2528 
2529       return HAL_TIMEOUT;
2530     }
2531   }
2532 
2533   /* Process unlocked */
2534   __HAL_UNLOCK(hdsi);
2535 
2536   return HAL_OK;
2537 }
2538 
2539 /**
2540   * @brief  Start test pattern generation
2541   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2542   *               the configuration information for the DSI.
2543   * @param  Mode  Pattern generator mode
2544   *          This parameter can be one of the following values:
2545   *           0 : Color bars (horizontal or vertical)
2546   *           1 : BER pattern (vertical only)
2547   * @param  Orientation  Pattern generator orientation
2548   *          This parameter can be one of the following values:
2549   *           0 : Vertical color bars
2550   *           1 : Horizontal color bars
2551   * @retval HAL status
2552   */
2553 HAL_StatusTypeDef HAL_DSI_PatternGeneratorStart(DSI_HandleTypeDef *hdsi, uint32_t Mode, uint32_t Orientation)
2554 {
2555   /* Process locked */
2556   __HAL_LOCK(hdsi);
2557 
2558   /* Configure pattern generator mode and orientation */
2559   hdsi->Instance->VMCR &= ~(DSI_VMCR_PGM | DSI_VMCR_PGO);
2560   hdsi->Instance->VMCR |= ((Mode << 20U) | (Orientation << 24U));
2561 
2562   /* Enable pattern generator by setting PGE bit */
2563   hdsi->Instance->VMCR |= DSI_VMCR_PGE;
2564 
2565   /* Process unlocked */
2566   __HAL_UNLOCK(hdsi);
2567 
2568   return HAL_OK;
2569 }
2570 
2571 /**
2572   * @brief  Stop test pattern generation
2573   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2574   *               the configuration information for the DSI.
2575   * @retval HAL status
2576   */
2577 HAL_StatusTypeDef HAL_DSI_PatternGeneratorStop(DSI_HandleTypeDef *hdsi)
2578 {
2579   /* Process locked */
2580   __HAL_LOCK(hdsi);
2581 
2582   /* Disable pattern generator by clearing PGE bit */
2583   hdsi->Instance->VMCR &= ~DSI_VMCR_PGE;
2584 
2585   /* Process unlocked */
2586   __HAL_UNLOCK(hdsi);
2587 
2588   return HAL_OK;
2589 }
2590 
2591 /**
2592   * @brief  Set Slew-Rate And Delay Tuning
2593   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2594   *               the configuration information for the DSI.
2595   * @param  CommDelay  Communication delay to be adjusted.
2596   *                    This parameter can be any value of @arg DSI_Communication_Delay
2597   * @param  Lane  select between clock or data lanes.
2598   *               This parameter can be any value of @arg DSI_Lane_Group
2599   * @param  Value  Custom value of the slew-rate or delay
2600   * @retval HAL status
2601   */
2602 HAL_StatusTypeDef HAL_DSI_SetSlewRateAndDelayTuning(DSI_HandleTypeDef *hdsi, uint32_t CommDelay, uint32_t Lane,
2603                                                     uint32_t Value)
2604 {
2605   /* Process locked */
2606   __HAL_LOCK(hdsi);
2607 
2608   /* Check function parameters */
2609   assert_param(IS_DSI_COMMUNICATION_DELAY(CommDelay));
2610   assert_param(IS_DSI_LANE_GROUP(Lane));
2611 
2612   switch (CommDelay)
2613   {
2614     case DSI_SLEW_RATE_HSTX:
2615       if (Lane == DSI_CLOCK_LANE)
2616       {
2617         /* High-Speed Transmission Slew Rate Control on Clock Lane */
2618         hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_HSTXSRCCL;
2619         hdsi->Instance->WPCR[1U] |= Value << 16U;
2620       }
2621       else if (Lane == DSI_DATA_LANES)
2622       {
2623         /* High-Speed Transmission Slew Rate Control on Data Lanes */
2624         hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_HSTXSRCDL;
2625         hdsi->Instance->WPCR[1U] |= Value << 18U;
2626       }
2627       else
2628       {
2629         /* Process unlocked */
2630         __HAL_UNLOCK(hdsi);
2631 
2632         return HAL_ERROR;
2633       }
2634       break;
2635     case DSI_SLEW_RATE_LPTX:
2636       if (Lane == DSI_CLOCK_LANE)
2637       {
2638         /* Low-Power transmission Slew Rate Compensation on Clock Lane */
2639         hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_LPSRCCL;
2640         hdsi->Instance->WPCR[1U] |= Value << 6U;
2641       }
2642       else if (Lane == DSI_DATA_LANES)
2643       {
2644         /* Low-Power transmission Slew Rate Compensation on Data Lanes */
2645         hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_LPSRCDL;
2646         hdsi->Instance->WPCR[1U] |= Value << 8U;
2647       }
2648       else
2649       {
2650         /* Process unlocked */
2651         __HAL_UNLOCK(hdsi);
2652 
2653         return HAL_ERROR;
2654       }
2655       break;
2656     case DSI_HS_DELAY:
2657       if (Lane == DSI_CLOCK_LANE)
2658       {
2659         /* High-Speed Transmission Delay on Clock Lane */
2660         hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_HSTXDCL;
2661         hdsi->Instance->WPCR[1U] |= Value;
2662       }
2663       else if (Lane == DSI_DATA_LANES)
2664       {
2665         /* High-Speed Transmission Delay on Data Lanes */
2666         hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_HSTXDDL;
2667         hdsi->Instance->WPCR[1U] |= Value << 2U;
2668       }
2669       else
2670       {
2671         /* Process unlocked */
2672         __HAL_UNLOCK(hdsi);
2673 
2674         return HAL_ERROR;
2675       }
2676       break;
2677     default:
2678       break;
2679   }
2680 
2681   /* Process unlocked */
2682   __HAL_UNLOCK(hdsi);
2683 
2684   return HAL_OK;
2685 }
2686 
2687 /**
2688   * @brief  Low-Power Reception Filter Tuning
2689   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2690   *               the configuration information for the DSI.
2691   * @param  Frequency  cutoff frequency of low-pass filter at the input of LPRX
2692   * @retval HAL status
2693   */
2694 HAL_StatusTypeDef HAL_DSI_SetLowPowerRXFilter(DSI_HandleTypeDef *hdsi, uint32_t Frequency)
2695 {
2696   /* Process locked */
2697   __HAL_LOCK(hdsi);
2698 
2699   /* Low-Power RX low-pass Filtering Tuning */
2700   hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_LPRXFT;
2701   hdsi->Instance->WPCR[1U] |= Frequency << 25U;
2702 
2703   /* Process unlocked */
2704   __HAL_UNLOCK(hdsi);
2705 
2706   return HAL_OK;
2707 }
2708 
2709 /**
2710   * @brief  Activate an additional current path on all lanes to meet the SDDTx parameter
2711   *         defined in the MIPI D-PHY specification
2712   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2713   *               the configuration information for the DSI.
2714   * @param  State  ENABLE or DISABLE
2715   * @retval HAL status
2716   */
2717 HAL_StatusTypeDef HAL_DSI_SetSDD(DSI_HandleTypeDef *hdsi, FunctionalState State)
2718 {
2719   /* Process locked */
2720   __HAL_LOCK(hdsi);
2721 
2722   /* Check function parameters */
2723   assert_param(IS_FUNCTIONAL_STATE(State));
2724 
2725   /* Activate/Disactivate additional current path on all lanes */
2726   hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_SDDC;
2727   hdsi->Instance->WPCR[1U] |= ((uint32_t)State << 12U);
2728 
2729   /* Process unlocked */
2730   __HAL_UNLOCK(hdsi);
2731 
2732   return HAL_OK;
2733 }
2734 
2735 /**
2736   * @brief  Custom lane pins configuration
2737   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2738   *               the configuration information for the DSI.
2739   * @param  CustomLane  Function to be applied on selected lane.
2740   *                     This parameter can be any value of @arg DSI_CustomLane
2741   * @param  Lane  select between clock or data lane 0 or data lane 1.
2742   *               This parameter can be any value of @arg DSI_Lane_Select
2743   * @param  State  ENABLE or DISABLE
2744   * @retval HAL status
2745   */
2746 HAL_StatusTypeDef HAL_DSI_SetLanePinsConfiguration(DSI_HandleTypeDef *hdsi, uint32_t CustomLane, uint32_t Lane,
2747                                                    FunctionalState State)
2748 {
2749   /* Process locked */
2750   __HAL_LOCK(hdsi);
2751 
2752   /* Check function parameters */
2753   assert_param(IS_DSI_CUSTOM_LANE(CustomLane));
2754   assert_param(IS_DSI_LANE(Lane));
2755   assert_param(IS_FUNCTIONAL_STATE(State));
2756 
2757   switch (CustomLane)
2758   {
2759     case DSI_SWAP_LANE_PINS:
2760       if (Lane == DSI_CLK_LANE)
2761       {
2762         /* Swap pins on clock lane */
2763         hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_SWCL;
2764         hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 6U);
2765       }
2766       else if (Lane == DSI_DATA_LANE0)
2767       {
2768         /* Swap pins on data lane 0 */
2769         hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_SWDL0;
2770         hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 7U);
2771       }
2772       else if (Lane == DSI_DATA_LANE1)
2773       {
2774         /* Swap pins on data lane 1 */
2775         hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_SWDL1;
2776         hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 8U);
2777       }
2778       else
2779       {
2780         /* Process unlocked */
2781         __HAL_UNLOCK(hdsi);
2782 
2783         return HAL_ERROR;
2784       }
2785       break;
2786     case DSI_INVERT_HS_SIGNAL:
2787       if (Lane == DSI_CLK_LANE)
2788       {
2789         /* Invert HS signal on clock lane */
2790         hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_HSICL;
2791         hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 9U);
2792       }
2793       else if (Lane == DSI_DATA_LANE0)
2794       {
2795         /* Invert HS signal on data lane 0 */
2796         hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_HSIDL0;
2797         hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 10U);
2798       }
2799       else if (Lane == DSI_DATA_LANE1)
2800       {
2801         /* Invert HS signal on data lane 1 */
2802         hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_HSIDL1;
2803         hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 11U);
2804       }
2805       else
2806       {
2807         /* Process unlocked */
2808         __HAL_UNLOCK(hdsi);
2809 
2810         return HAL_ERROR;
2811       }
2812       break;
2813     default:
2814       break;
2815   }
2816 
2817   /* Process unlocked */
2818   __HAL_UNLOCK(hdsi);
2819 
2820   return HAL_OK;
2821 }
2822 
2823 /**
2824   * @brief  Set custom timing for the PHY
2825   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2826   *               the configuration information for the DSI.
2827   * @param  Timing  PHY timing to be adjusted.
2828   *                 This parameter can be any value of @arg DSI_PHY_Timing
2829   * @param  State  ENABLE or DISABLE
2830   * @param  Value  Custom value of the timing
2831   * @retval HAL status
2832   */
2833 HAL_StatusTypeDef HAL_DSI_SetPHYTimings(DSI_HandleTypeDef *hdsi, uint32_t Timing, FunctionalState State, uint32_t Value)
2834 {
2835   /* Process locked */
2836   __HAL_LOCK(hdsi);
2837 
2838   /* Check function parameters */
2839   assert_param(IS_DSI_PHY_TIMING(Timing));
2840   assert_param(IS_FUNCTIONAL_STATE(State));
2841 
2842   switch (Timing)
2843   {
2844     case DSI_TCLK_POST:
2845       /* Enable/Disable custom timing setting */
2846       hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_TCLKPOSTEN;
2847       hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 27U);
2848 
2849       if (State != DISABLE)
2850       {
2851         /* Set custom value */
2852         hdsi->Instance->WPCR[4U] &= ~DSI_WPCR4_TCLKPOST;
2853         hdsi->Instance->WPCR[4U] |= Value & DSI_WPCR4_TCLKPOST;
2854       }
2855 
2856       break;
2857     case DSI_TLPX_CLK:
2858       /* Enable/Disable custom timing setting */
2859       hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_TLPXCEN;
2860       hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 26U);
2861 
2862       if (State != DISABLE)
2863       {
2864         /* Set custom value */
2865         hdsi->Instance->WPCR[3U] &= ~DSI_WPCR3_TLPXC;
2866         hdsi->Instance->WPCR[3U] |= (Value << 24U) & DSI_WPCR3_TLPXC;
2867       }
2868 
2869       break;
2870     case DSI_THS_EXIT:
2871       /* Enable/Disable custom timing setting */
2872       hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_THSEXITEN;
2873       hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 25U);
2874 
2875       if (State != DISABLE)
2876       {
2877         /* Set custom value */
2878         hdsi->Instance->WPCR[3U] &= ~DSI_WPCR3_THSEXIT;
2879         hdsi->Instance->WPCR[3U] |= (Value << 16U) & DSI_WPCR3_THSEXIT;
2880       }
2881 
2882       break;
2883     case DSI_TLPX_DATA:
2884       /* Enable/Disable custom timing setting */
2885       hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_TLPXDEN;
2886       hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 24U);
2887 
2888       if (State != DISABLE)
2889       {
2890         /* Set custom value */
2891         hdsi->Instance->WPCR[3U] &= ~DSI_WPCR3_TLPXD;
2892         hdsi->Instance->WPCR[3U] |= (Value << 8U) & DSI_WPCR3_TLPXD;
2893       }
2894 
2895       break;
2896     case DSI_THS_ZERO:
2897       /* Enable/Disable custom timing setting */
2898       hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_THSZEROEN;
2899       hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 23U);
2900 
2901       if (State != DISABLE)
2902       {
2903         /* Set custom value */
2904         hdsi->Instance->WPCR[3U] &= ~DSI_WPCR3_THSZERO;
2905         hdsi->Instance->WPCR[3U] |= Value & DSI_WPCR3_THSZERO;
2906       }
2907 
2908       break;
2909     case DSI_THS_TRAIL:
2910       /* Enable/Disable custom timing setting */
2911       hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_THSTRAILEN;
2912       hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 22U);
2913 
2914       if (State != DISABLE)
2915       {
2916         /* Set custom value */
2917         hdsi->Instance->WPCR[2U] &= ~DSI_WPCR2_THSTRAIL;
2918         hdsi->Instance->WPCR[2U] |= (Value << 24U) & DSI_WPCR2_THSTRAIL;
2919       }
2920 
2921       break;
2922     case DSI_THS_PREPARE:
2923       /* Enable/Disable custom timing setting */
2924       hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_THSPREPEN;
2925       hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 21U);
2926 
2927       if (State != DISABLE)
2928       {
2929         /* Set custom value */
2930         hdsi->Instance->WPCR[2U] &= ~DSI_WPCR2_THSPREP;
2931         hdsi->Instance->WPCR[2U] |= (Value << 16U) & DSI_WPCR2_THSPREP;
2932       }
2933 
2934       break;
2935     case DSI_TCLK_ZERO:
2936       /* Enable/Disable custom timing setting */
2937       hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_TCLKZEROEN;
2938       hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 20U);
2939 
2940       if (State != DISABLE)
2941       {
2942         /* Set custom value */
2943         hdsi->Instance->WPCR[2U] &= ~DSI_WPCR2_TCLKZERO;
2944         hdsi->Instance->WPCR[2U] |= (Value << 8U) & DSI_WPCR2_TCLKZERO;
2945       }
2946 
2947       break;
2948     case DSI_TCLK_PREPARE:
2949       /* Enable/Disable custom timing setting */
2950       hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_TCLKPREPEN;
2951       hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 19U);
2952 
2953       if (State != DISABLE)
2954       {
2955         /* Set custom value */
2956         hdsi->Instance->WPCR[2U] &= ~DSI_WPCR2_TCLKPREP;
2957         hdsi->Instance->WPCR[2U] |= Value & DSI_WPCR2_TCLKPREP;
2958       }
2959 
2960       break;
2961     default:
2962       break;
2963   }
2964 
2965   /* Process unlocked */
2966   __HAL_UNLOCK(hdsi);
2967 
2968   return HAL_OK;
2969 }
2970 
2971 /**
2972   * @brief  Force the Clock/Data Lane in TX Stop Mode
2973   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2974   *               the configuration information for the DSI.
2975   * @param  Lane  select between clock or data lanes.
2976   *               This parameter can be any value of @arg DSI_Lane_Group
2977   * @param  State  ENABLE or DISABLE
2978   * @retval HAL status
2979   */
2980 HAL_StatusTypeDef HAL_DSI_ForceTXStopMode(DSI_HandleTypeDef *hdsi, uint32_t Lane, FunctionalState State)
2981 {
2982   /* Process locked */
2983   __HAL_LOCK(hdsi);
2984 
2985   /* Check function parameters */
2986   assert_param(IS_DSI_LANE_GROUP(Lane));
2987   assert_param(IS_FUNCTIONAL_STATE(State));
2988 
2989   if (Lane == DSI_CLOCK_LANE)
2990   {
2991     /* Force/Unforce the Clock Lane in TX Stop Mode */
2992     hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_FTXSMCL;
2993     hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 12U);
2994   }
2995   else if (Lane == DSI_DATA_LANES)
2996   {
2997     /* Force/Unforce the Data Lanes in TX Stop Mode */
2998     hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_FTXSMDL;
2999     hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 13U);
3000   }
3001   else
3002   {
3003     /* Process unlocked */
3004     __HAL_UNLOCK(hdsi);
3005 
3006     return HAL_ERROR;
3007   }
3008 
3009   /* Process unlocked */
3010   __HAL_UNLOCK(hdsi);
3011 
3012   return HAL_OK;
3013 }
3014 
3015 /**
3016   * @brief  Force LP Receiver in Low-Power Mode
3017   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
3018   *               the configuration information for the DSI.
3019   * @param  State  ENABLE or DISABLE
3020   * @retval HAL status
3021   */
3022 HAL_StatusTypeDef HAL_DSI_ForceRXLowPower(DSI_HandleTypeDef *hdsi, FunctionalState State)
3023 {
3024   /* Process locked */
3025   __HAL_LOCK(hdsi);
3026 
3027   /* Check function parameters */
3028   assert_param(IS_FUNCTIONAL_STATE(State));
3029 
3030   /* Force/Unforce LP Receiver in Low-Power Mode */
3031   hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_FLPRXLPM;
3032   hdsi->Instance->WPCR[1U] |= ((uint32_t)State << 22U);
3033 
3034   /* Process unlocked */
3035   __HAL_UNLOCK(hdsi);
3036 
3037   return HAL_OK;
3038 }
3039 
3040 /**
3041   * @brief  Force Data Lanes in RX Mode after a BTA
3042   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
3043   *               the configuration information for the DSI.
3044   * @param  State  ENABLE or DISABLE
3045   * @retval HAL status
3046   */
3047 HAL_StatusTypeDef HAL_DSI_ForceDataLanesInRX(DSI_HandleTypeDef *hdsi, FunctionalState State)
3048 {
3049   /* Process locked */
3050   __HAL_LOCK(hdsi);
3051 
3052   /* Check function parameters */
3053   assert_param(IS_FUNCTIONAL_STATE(State));
3054 
3055   /* Force Data Lanes in RX Mode */
3056   hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_TDDL;
3057   hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 16U);
3058 
3059   /* Process unlocked */
3060   __HAL_UNLOCK(hdsi);
3061 
3062   return HAL_OK;
3063 }
3064 
3065 /**
3066   * @brief  Enable a pull-down on the lanes to prevent from floating states when unused
3067   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
3068   *               the configuration information for the DSI.
3069   * @param  State  ENABLE or DISABLE
3070   * @retval HAL status
3071   */
3072 HAL_StatusTypeDef HAL_DSI_SetPullDown(DSI_HandleTypeDef *hdsi, FunctionalState State)
3073 {
3074   /* Process locked */
3075   __HAL_LOCK(hdsi);
3076 
3077   /* Check function parameters */
3078   assert_param(IS_FUNCTIONAL_STATE(State));
3079 
3080   /* Enable/Disable pull-down on lanes */
3081   hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_PDEN;
3082   hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 18U);
3083 
3084   /* Process unlocked */
3085   __HAL_UNLOCK(hdsi);
3086 
3087   return HAL_OK;
3088 }
3089 
3090 /**
3091   * @brief  Switch off the contention detection on data lanes
3092   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
3093   *               the configuration information for the DSI.
3094   * @param  State  ENABLE or DISABLE
3095   * @retval HAL status
3096   */
3097 HAL_StatusTypeDef HAL_DSI_SetContentionDetectionOff(DSI_HandleTypeDef *hdsi, FunctionalState State)
3098 {
3099   /* Process locked */
3100   __HAL_LOCK(hdsi);
3101 
3102   /* Check function parameters */
3103   assert_param(IS_FUNCTIONAL_STATE(State));
3104 
3105   /* Contention Detection on Data Lanes OFF */
3106   hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_CDOFFDL;
3107   hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 14U);
3108 
3109   /* Process unlocked */
3110   __HAL_UNLOCK(hdsi);
3111 
3112   return HAL_OK;
3113 }
3114 
3115 /**
3116   * @}
3117   */
3118 
3119 /** @defgroup DSI_Group4 Peripheral State and Errors functions
3120   * @ingroup RTEMSBSPsARMSTM32H7
3121   *  @brief    Peripheral State and Errors functions
3122   *
3123 @verbatim
3124  ===============================================================================
3125                   ##### Peripheral State and Errors functions #####
3126  ===============================================================================
3127     [..]
3128     This subsection provides functions allowing to
3129       (+) Check the DSI state.
3130       (+) Get error code.
3131 
3132 @endverbatim
3133   * @{
3134   */
3135 
3136 /**
3137   * @brief  Return the DSI state
3138   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
3139   *               the configuration information for the DSI.
3140   * @retval HAL state
3141   */
3142 HAL_DSI_StateTypeDef HAL_DSI_GetState(const DSI_HandleTypeDef *hdsi)
3143 {
3144   return hdsi->State;
3145 }
3146 
3147 /**
3148   * @brief  Return the DSI error code
3149   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
3150   *               the configuration information for the DSI.
3151   * @retval DSI Error Code
3152   */
3153 uint32_t HAL_DSI_GetError(const DSI_HandleTypeDef *hdsi)
3154 {
3155   /* Get the error code */
3156   return hdsi->ErrorCode;
3157 }
3158 
3159 /**
3160   * @}
3161   */
3162 
3163 /**
3164   * @}
3165   */
3166 
3167 /**
3168   * @}
3169   */
3170 
3171 #endif /* DSI */
3172 
3173 #endif /* HAL_DSI_MODULE_ENABLED */
3174 
3175 /**
3176   * @}
3177   */