stm32f7xx_hal_dsi.c 84.5 KB
Newer Older
1 2 3 4 5
/**
  ******************************************************************************
  * @file    stm32f7xx_hal_dsi.c
  * @author  MCD Application Team
  * @brief   DSI HAL module driver.
6
  *          This file provides firmware functions to manage the following
7 8 9
  *          functionalities of the DSI peripheral:
  *           + Initialization and de-initialization functions
  *           + IO operation functions
10
  *           + Peripheral Control functions
11
  *           + Peripheral State and Errors functions
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
  @verbatim
  ==============================================================================
                        ##### How to use this driver #####
  ==============================================================================
    [..]
    (#) Use @ref HAL_DSI_Init() function to initialize the DSI Host IP and program the required
        PLL parameters, number of lanes and TX Escape clock divider.
    (#) Use @ref HAL_DSI_ConfigAdaptedCommandMode() function to configure the DSI host in adapted
        command mode.
    (#) When operating in video mode , use @ref HAL_DSI_ConfigVideoMode() to configure the DSI host.
    (#) Function @ref HAL_DSI_ConfigCommand() is used to configure the DSI commands behavior in low power mode.
    (#) To configure the DSI PHY timings parameters, use function @ref HAL_DSI_ConfigPhyTimer().
    (#) The DSI Host can be started/stopped using respectively functions @ref HAL_DSI_Start() and @ref HAL_DSI_Stop().
        Functions @ref HAL_DSI_ShortWrite(), @ref HAL_DSI_LongWrite() and @ref HAL_DSI_Read() allows respectively
        to write DSI short packets, long packets and to read DSI packets.

    (#) The DSI Host Offers two Low power modes :
        (+) Low Power Mode on data lanes only: Only DSI data lanes are shut down.
            It is possible to enter/exit from this mode using respectively functions @ref HAL_DSI_EnterULPMData()
            and @ref HAL_DSI_ExitULPMData()

        (+) Low Power Mode on data and clock lanes : All DSI lanes are shut down including data and clock lanes.
            It is possible to enter/exit from this mode using respectively functions @ref HAL_DSI_EnterULPM()
            and @ref HAL_DSI_ExitULPM()

    (#) User can select the DSI errors to be reported/monitored using function @ref HAL_DSI_ConfigErrorMonitor()
        When an error occurs, the callback @ref HAL_DSI_ErrorCallback() is asserted and then user can retrieve
        the error code by calling function @ref HAL_DSI_GetError()

    (#) To control DSI state you can use the following function: HAL_DSI_GetState()

     *** DSI HAL driver macros list ***
     =============================================
     [..]
       Below the list of most used macros in DSI HAL driver.

      (+) __HAL_DSI_ENABLE: Enable the DSI Host.
      (+) __HAL_DSI_DISABLE: Disable the DSI Host.
      (+) __HAL_DSI_WRAPPER_ENABLE: Enables the DSI wrapper.
      (+) __HAL_DSI_WRAPPER_DISABLE: Disable the DSI wrapper.
      (+) __HAL_DSI_PLL_ENABLE: Enables the DSI PLL.
      (+) __HAL_DSI_PLL_DISABLE: Disables the DSI PLL.
      (+) __HAL_DSI_REG_ENABLE: Enables the DSI regulator.
      (+) __HAL_DSI_REG_DISABLE: Disables the DSI regulator.
      (+) __HAL_DSI_GET_FLAG: Get the DSI pending flags.
      (+) __HAL_DSI_CLEAR_FLAG: Clears the DSI pending flags.
      (+) __HAL_DSI_ENABLE_IT: Enables the specified DSI interrupts.
      (+) __HAL_DSI_DISABLE_IT: Disables the specified DSI interrupts.
      (+) __HAL_DSI_GET_IT_SOURCE: Checks whether the specified DSI interrupt source is enabled or not.



  *** Callback registration ***
  =============================================

  The compilation define  USE_HAL_DSI_REGISTER_CALLBACKS when set to 1
  allows the user to configure dynamically the driver callbacks.
  Use Function @ref HAL_DSI_RegisterCallback() to register a callback.

  Function @ref HAL_DSI_RegisterCallback() allows to register following callbacks:
    (+) TearingEffectCallback : DSI Tearing Effect Callback.
    (+) EndOfRefreshCallback  : DSI End Of Refresh Callback.
    (+) ErrorCallback         : DSI Error Callback
    (+) MspInitCallback       : DSI MspInit.
    (+) MspDeInitCallback     : DSI MspDeInit.
  This function takes as parameters the HAL peripheral handle, the Callback ID
  and a pointer to the user callback function.

  Use function @ref HAL_DSI_UnRegisterCallback() to reset a callback to the default
  weak function.
  @ref HAL_DSI_UnRegisterCallback takes as parameters the HAL peripheral handle,
  and the Callback ID.
  This function allows to reset following callbacks:
    (+) TearingEffectCallback : DSI Tearing Effect Callback.
    (+) EndOfRefreshCallback  : DSI End Of Refresh Callback.
    (+) ErrorCallback         : DSI Error Callback
    (+) MspInitCallback       : DSI MspInit.
    (+) MspDeInitCallback     : DSI MspDeInit.

  By default, after the HAL_DSI_Init and when the state is HAL_DSI_STATE_RESET
  all callbacks are set to the corresponding weak functions:
  examples @ref HAL_DSI_TearingEffectCallback(), @ref HAL_DSI_EndOfRefreshCallback().
  Exception done for MspInit and MspDeInit functions that are
  reset to the legacy weak function in the HAL_DSI_Init/ @ref HAL_DSI_DeInit only when
  these callbacks are null (not registered beforehand).
  if not, MspInit or MspDeInit are not null, the @ref HAL_DSI_Init/ @ref HAL_DSI_DeInit
  keep and use the user MspInit/MspDeInit callbacks (registered beforehand)

  Callbacks can be registered/unregistered in HAL_DSI_STATE_READY state only.
  Exception done MspInit/MspDeInit that can be registered/unregistered
  in HAL_DSI_STATE_READY or HAL_DSI_STATE_RESET state,
  thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
  In that case first register the MspInit/MspDeInit user callbacks
  using @ref HAL_DSI_RegisterCallback() before calling @ref HAL_DSI_DeInit
  or HAL_DSI_Init function.

  When The compilation define USE_HAL_DSI_REGISTER_CALLBACKS is set to 0 or
  not defined, the callback registration feature is not available and all callbacks
  are set to the corresponding weak functions.

     [..]
       (@) You can refer to the DSI HAL driver header file for more useful macros

  @endverbatim
116 117 118
  ******************************************************************************
  * @attention
  *
119 120
  * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
  * All rights reserved.</center></h2>
121
  *
122 123 124 125
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
126 127
  *
  ******************************************************************************
128
  */
129 130 131 132 133 134 135 136 137 138

/* Includes ------------------------------------------------------------------*/
#include "stm32f7xx_hal.h"

/** @addtogroup STM32F7xx_HAL_Driver
  * @{
  */

#ifdef HAL_DSI_MODULE_ENABLED

139 140 141 142 143
#if defined(DSI)

/** @addtogroup DSI
  * @{
  */
144 145 146 147 148 149

/* Private types -------------------------------------------------------------*/
/* Private defines -----------------------------------------------------------*/
/** @addtogroup DSI_Private_Constants
  * @{
  */
150
#define DSI_TIMEOUT_VALUE ((uint32_t)1000U)  /* 1s */
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172

#define DSI_ERROR_ACK_MASK (DSI_ISR0_AE0 | DSI_ISR0_AE1 | DSI_ISR0_AE2 | DSI_ISR0_AE3 | \
                            DSI_ISR0_AE4 | DSI_ISR0_AE5 | DSI_ISR0_AE6 | DSI_ISR0_AE7 | \
                            DSI_ISR0_AE8 | DSI_ISR0_AE9 | DSI_ISR0_AE10 | DSI_ISR0_AE11 | \
                            DSI_ISR0_AE12 | DSI_ISR0_AE13 | DSI_ISR0_AE14 | DSI_ISR0_AE15)
#define DSI_ERROR_PHY_MASK (DSI_ISR0_PE0 | DSI_ISR0_PE1 | DSI_ISR0_PE2 | DSI_ISR0_PE3 | DSI_ISR0_PE4)
#define DSI_ERROR_TX_MASK  DSI_ISR1_TOHSTX
#define DSI_ERROR_RX_MASK  DSI_ISR1_TOLPRX
#define DSI_ERROR_ECC_MASK (DSI_ISR1_ECCSE | DSI_ISR1_ECCME)
#define DSI_ERROR_CRC_MASK DSI_ISR1_CRCE
#define DSI_ERROR_PSE_MASK DSI_ISR1_PSE
#define DSI_ERROR_EOT_MASK DSI_ISR1_EOTPE
#define DSI_ERROR_OVF_MASK DSI_ISR1_LPWRE
#define DSI_ERROR_GEN_MASK (DSI_ISR1_GCWRE | DSI_ISR1_GPWRE | DSI_ISR1_GPTXE | DSI_ISR1_GPRDE | DSI_ISR1_GPRXE)
/**
  * @}
  */

/* Private variables ---------------------------------------------------------*/
/* Private constants ---------------------------------------------------------*/
/* Private macros ------------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
173 174 175 176 177 178 179 180
static void DSI_ConfigPacketHeader(DSI_TypeDef *DSIx, uint32_t ChannelID, uint32_t DataType, uint32_t Data0,
                                   uint32_t Data1);

static HAL_StatusTypeDef DSI_ShortWrite(DSI_HandleTypeDef *hdsi,
                                     uint32_t ChannelID,
                                     uint32_t Mode,
                                     uint32_t Param1,
                                     uint32_t Param2);
181 182 183 184

/* Private functions ---------------------------------------------------------*/
/**
  * @brief  Generic DSI packet header configuration
185
  * @param  DSIx  Pointer to DSI register base
186
  * @param  ChannelID Virtual channel ID of the header packet
187
  * @param  DataType  Packet data type of the header packet
188 189 190 191 192
  *                   This parameter can be any value of :
  *                      @ref DSI_SHORT_WRITE_PKT_Data_Type
  *                   or @ref DSI_LONG_WRITE_PKT_Data_Type
  *                   or @ref DSI_SHORT_READ_PKT_Data_Type
  *                   or DSI_MAX_RETURN_PKT_SIZE
193 194
  * @param  Data0  Word count LSB
  * @param  Data1  Word count MSB
195 196 197 198 199 200 201 202 203
  * @retval None
  */
static void DSI_ConfigPacketHeader(DSI_TypeDef *DSIx,
                                   uint32_t ChannelID,
                                   uint32_t DataType,
                                   uint32_t Data0,
                                   uint32_t Data1)
{
  /* Update the DSI packet header with new information */
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
  DSIx->GHCR = (DataType | (ChannelID << 6U) | (Data0 << 8U) | (Data1 << 16U));
}

/**
  * @brief  write short DCS or short Generic command
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @param  ChannelID  Virtual channel ID.
  * @param  Mode  DSI short packet data type.
  *               This parameter can be any value of @ref DSI_SHORT_WRITE_PKT_Data_Type.
  * @param  Param1  DSC command or first generic parameter.
  *                 This parameter can be any value of @ref DSI_DCS_Command or a
  *                 generic command code.
  * @param  Param2  DSC parameter or second generic parameter.
  * @retval HAL status
  */
static HAL_StatusTypeDef DSI_ShortWrite(DSI_HandleTypeDef *hdsi,
                                        uint32_t ChannelID,
                                        uint32_t Mode,
                                        uint32_t Param1,
                                        uint32_t Param2)
{
  uint32_t tickstart;

  /* Get tick */
  tickstart = HAL_GetTick();

  /* Wait for Command FIFO Empty */
  while((hdsi->Instance->GPSR & DSI_GPSR_CMDFE) == 0U)
  {
    /* Check for the Timeout */
    if((HAL_GetTick() - tickstart ) > DSI_TIMEOUT_VALUE)
    {
      return HAL_TIMEOUT;
    }
  }

  /* Configure the packet to send a short DCS command with 0 or 1 parameter */
  /* Update the DSI packet header with new information */
  hdsi->Instance->GHCR = (Mode | (ChannelID << 6U) | (Param1 << 8U) | (Param2 << 16U));

  return HAL_OK;
246 247 248 249 250 251 252 253
}

/* Exported functions --------------------------------------------------------*/
/** @addtogroup DSI_Exported_Functions
  * @{
  */

/** @defgroup DSI_Group1 Initialization and Configuration functions
254 255 256
  *  @brief   Initialization and Configuration functions
  *
@verbatim
257 258
 ===============================================================================
                ##### Initialization and Configuration functions #####
259
 ===============================================================================
260 261
    [..]  This section provides functions allowing to:
      (+) Initialize and configure the DSI
262
      (+) De-initialize the DSI
263 264 265 266

@endverbatim
  * @{
  */
267

268 269 270
/**
  * @brief  Initializes the DSI according to the specified
  *         parameters in the DSI_InitTypeDef and create the associated handle.
271
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
272
  *               the configuration information for the DSI.
273 274
  * @param  PLLInit  pointer to a DSI_PLLInitTypeDef structure that contains
  *                  the PLL Clock structure definition for the DSI.
275 276 277 278
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_Init(DSI_HandleTypeDef *hdsi, DSI_PLLInitTypeDef *PLLInit)
{
279 280 281 282
  uint32_t tickstart;
  uint32_t unitIntervalx4;
  uint32_t tempIDF;

283
  /* Check the DSI handle allocation */
284
  if (hdsi == NULL)
285 286 287
  {
    return HAL_ERROR;
  }
288

289 290 291 292 293 294
  /* Check function parameters */
  assert_param(IS_DSI_PLL_NDIV(PLLInit->PLLNDIV));
  assert_param(IS_DSI_PLL_IDF(PLLInit->PLLIDF));
  assert_param(IS_DSI_PLL_ODF(PLLInit->PLLODF));
  assert_param(IS_DSI_AUTO_CLKLANE_CONTROL(hdsi->Init.AutomaticClockLaneControl));
  assert_param(IS_DSI_NUMBER_OF_LANES(hdsi->Init.NumberOfLanes));
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312

#if (USE_HAL_DSI_REGISTER_CALLBACKS == 1)
  if (hdsi->State == HAL_DSI_STATE_RESET)
  {
    /* Reset the DSI callback to the legacy weak callbacks */
    hdsi->TearingEffectCallback = HAL_DSI_TearingEffectCallback; /* Legacy weak TearingEffectCallback */
    hdsi->EndOfRefreshCallback  = HAL_DSI_EndOfRefreshCallback;  /* Legacy weak EndOfRefreshCallback  */
    hdsi->ErrorCallback         = HAL_DSI_ErrorCallback;         /* Legacy weak ErrorCallback         */

    if (hdsi->MspInitCallback == NULL)
    {
      hdsi->MspInitCallback = HAL_DSI_MspInit;
    }
    /* Initialize the low level hardware */
    hdsi->MspInitCallback(hdsi);
  }
#else
  if (hdsi->State == HAL_DSI_STATE_RESET)
313 314 315 316
  {
    /* Initialize the low level hardware */
    HAL_DSI_MspInit(hdsi);
  }
317 318
#endif /* USE_HAL_DSI_REGISTER_CALLBACKS */

319 320
  /* Change DSI peripheral state */
  hdsi->State = HAL_DSI_STATE_BUSY;
321

322
  /**************** Turn on the regulator and enable the DSI PLL ****************/
323 324 325 326 327 328 329 330 331 332 333 334

  /* Enable the regulator */
  __HAL_DSI_REG_ENABLE(hdsi);

  /* Get tick */
  tickstart = HAL_GetTick();

  /* Wait until the regulator is ready */
  while (__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_RRS) == 0U)
  {
    /* Check for the Timeout */
    if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
335
    {
336
      return HAL_TIMEOUT;
337
    }
338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354
  }

  /* Set the PLL division factors */
  hdsi->Instance->WRPCR &= ~(DSI_WRPCR_PLL_NDIV | DSI_WRPCR_PLL_IDF | DSI_WRPCR_PLL_ODF);
  hdsi->Instance->WRPCR |= (((PLLInit->PLLNDIV) << 2U) | ((PLLInit->PLLIDF) << 11U) | ((PLLInit->PLLODF) << 16U));

  /* Enable the DSI PLL */
  __HAL_DSI_PLL_ENABLE(hdsi);

  /* Get tick */
  tickstart = HAL_GetTick();

  /* Wait for the lock of the PLL */
  while (__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_PLLLS) == 0U)
  {
    /* Check for the Timeout */
    if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
355
    {
356
      return HAL_TIMEOUT;
357
    }
358 359
  }

360
  /*************************** Set the PHY parameters ***************************/
361 362 363 364 365 366 367 368 369 370 371 372

  /* D-PHY clock and digital enable*/
  hdsi->Instance->PCTLR |= (DSI_PCTLR_CKE | DSI_PCTLR_DEN);

  /* Clock lane configuration */
  hdsi->Instance->CLCR &= ~(DSI_CLCR_DPCC | DSI_CLCR_ACR);
  hdsi->Instance->CLCR |= (DSI_CLCR_DPCC | hdsi->Init.AutomaticClockLaneControl);

  /* Configure the number of active data lanes */
  hdsi->Instance->PCONFR &= ~DSI_PCONFR_NL;
  hdsi->Instance->PCONFR |= hdsi->Init.NumberOfLanes;

373
  /************************ Set the DSI clock parameters ************************/
374 375 376 377 378 379 380 381 382 383 384 385 386 387 388

  /* Set the TX escape clock division factor */
  hdsi->Instance->CCR &= ~DSI_CCR_TXECKDIV;
  hdsi->Instance->CCR |= hdsi->Init.TXEscapeCkdiv;

  /* Calculate the bit period in high-speed mode in unit of 0.25 ns (UIX4) */
  /* The equation is : UIX4 = IntegerPart( (1000/F_PHY_Mhz) * 4 )          */
  /* Where : F_PHY_Mhz = (NDIV * HSE_Mhz) / (IDF * ODF)                    */
  tempIDF = (PLLInit->PLLIDF > 0U) ? PLLInit->PLLIDF : 1U;
  unitIntervalx4 = (4000000U * tempIDF * ((1UL << (0x3U & PLLInit->PLLODF)))) / ((HSE_VALUE / 1000U) * PLLInit->PLLNDIV);

  /* Set the bit period in high-speed mode */
  hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_UIX4;
  hdsi->Instance->WPCR[0U] |= unitIntervalx4;

389
  /****************************** Error management *****************************/
390 391 392 393 394 395 396 397 398

  /* Disable all error interrupts and reset the Error Mask */
  hdsi->Instance->IER[0U] = 0U;
  hdsi->Instance->IER[1U] = 0U;
  hdsi->ErrorMsk = 0U;

  /* Initialise the error code */
  hdsi->ErrorCode = HAL_DSI_ERROR_NONE;

399 400
  /* Initialize the DSI state*/
  hdsi->State = HAL_DSI_STATE_READY;
401

402 403 404 405 406 407
  return HAL_OK;
}

/**
  * @brief  De-initializes the DSI peripheral registers to their default reset
  *         values.
408
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
409 410 411 412 413 414
  *               the configuration information for the DSI.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_DeInit(DSI_HandleTypeDef *hdsi)
{
  /* Check the DSI handle allocation */
415
  if (hdsi == NULL)
416 417 418
  {
    return HAL_ERROR;
  }
419

420 421
  /* Change DSI peripheral state */
  hdsi->State = HAL_DSI_STATE_BUSY;
422

423 424
  /* Disable the DSI wrapper */
  __HAL_DSI_WRAPPER_DISABLE(hdsi);
425

426 427
  /* Disable the DSI host */
  __HAL_DSI_DISABLE(hdsi);
428

429 430
  /* D-PHY clock and digital disable */
  hdsi->Instance->PCTLR &= ~(DSI_PCTLR_CKE | DSI_PCTLR_DEN);
431

432 433
  /* Turn off the DSI PLL */
  __HAL_DSI_PLL_DISABLE(hdsi);
434

435 436
  /* Disable the regulator */
  __HAL_DSI_REG_DISABLE(hdsi);
437 438 439 440 441 442

#if (USE_HAL_DSI_REGISTER_CALLBACKS == 1)
  if (hdsi->MspDeInitCallback == NULL)
  {
    hdsi->MspDeInitCallback = HAL_DSI_MspDeInit;
  }
443
  /* DeInit the low level hardware */
444 445 446 447 448 449
  hdsi->MspDeInitCallback(hdsi);
#else
  /* DeInit the low level hardware */
  HAL_DSI_MspDeInit(hdsi);
#endif /* USE_HAL_DSI_REGISTER_CALLBACKS */

450 451
  /* Initialise the error code */
  hdsi->ErrorCode = HAL_DSI_ERROR_NONE;
452

453 454
  /* Initialize the DSI state*/
  hdsi->State = HAL_DSI_STATE_RESET;
455

456 457 458
  /* Release Lock */
  __HAL_UNLOCK(hdsi);

459
  return HAL_OK;
460 461 462
}

/**
463 464
  * @brief  Enable the error monitor flags
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
465
  *               the configuration information for the DSI.
466
  * @param  ActiveErrors  indicates which error interrupts will be enabled.
467
  *                      This parameter can be any combination of @ref DSI_Error_Data_Type.
468
  * @retval HAL status
469 470 471 472 473
  */
HAL_StatusTypeDef HAL_DSI_ConfigErrorMonitor(DSI_HandleTypeDef *hdsi, uint32_t ActiveErrors)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
474 475 476 477

  hdsi->Instance->IER[0U] = 0U;
  hdsi->Instance->IER[1U] = 0U;

478 479
  /* Store active errors to the handle */
  hdsi->ErrorMsk = ActiveErrors;
480 481

  if ((ActiveErrors & HAL_DSI_ERROR_ACK) != 0U)
482 483
  {
    /* Enable the interrupt generation on selected errors */
484
    hdsi->Instance->IER[0U] |= DSI_ERROR_ACK_MASK;
485
  }
486 487

  if ((ActiveErrors & HAL_DSI_ERROR_PHY) != 0U)
488 489
  {
    /* Enable the interrupt generation on selected errors */
490
    hdsi->Instance->IER[0U] |= DSI_ERROR_PHY_MASK;
491
  }
492 493

  if ((ActiveErrors & HAL_DSI_ERROR_TX) != 0U)
494 495
  {
    /* Enable the interrupt generation on selected errors */
496
    hdsi->Instance->IER[1U] |= DSI_ERROR_TX_MASK;
497
  }
498 499

  if ((ActiveErrors & HAL_DSI_ERROR_RX) != 0U)
500 501
  {
    /* Enable the interrupt generation on selected errors */
502
    hdsi->Instance->IER[1U] |= DSI_ERROR_RX_MASK;
503
  }
504 505

  if ((ActiveErrors & HAL_DSI_ERROR_ECC) != 0U)
506 507
  {
    /* Enable the interrupt generation on selected errors */
508
    hdsi->Instance->IER[1U] |= DSI_ERROR_ECC_MASK;
509
  }
510 511

  if ((ActiveErrors & HAL_DSI_ERROR_CRC) != 0U)
512 513
  {
    /* Enable the interrupt generation on selected errors */
514
    hdsi->Instance->IER[1U] |= DSI_ERROR_CRC_MASK;
515
  }
516 517

  if ((ActiveErrors & HAL_DSI_ERROR_PSE) != 0U)
518 519
  {
    /* Enable the interrupt generation on selected errors */
520
    hdsi->Instance->IER[1U] |= DSI_ERROR_PSE_MASK;
521
  }
522 523

  if ((ActiveErrors & HAL_DSI_ERROR_EOT) != 0U)
524 525
  {
    /* Enable the interrupt generation on selected errors */
526
    hdsi->Instance->IER[1U] |= DSI_ERROR_EOT_MASK;
527
  }
528 529

  if ((ActiveErrors & HAL_DSI_ERROR_OVF) != 0U)
530 531
  {
    /* Enable the interrupt generation on selected errors */
532
    hdsi->Instance->IER[1U] |= DSI_ERROR_OVF_MASK;
533
  }
534 535

  if ((ActiveErrors & HAL_DSI_ERROR_GEN) != 0U)
536 537
  {
    /* Enable the interrupt generation on selected errors */
538
    hdsi->Instance->IER[1U] |= DSI_ERROR_GEN_MASK;
539
  }
540

541 542
  /* Process Unlocked */
  __HAL_UNLOCK(hdsi);
543

544 545 546 547 548
  return HAL_OK;
}

/**
  * @brief  Initializes the DSI MSP.
549
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
550 551 552
  *               the configuration information for the DSI.
  * @retval None
  */
553
__weak void HAL_DSI_MspInit(DSI_HandleTypeDef *hdsi)
554 555 556 557 558
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hdsi);
  /* NOTE : This function Should not be modified, when the callback is needed,
            the HAL_DSI_MspInit could be implemented in the user file
559
   */
560 561 562 563
}

/**
  * @brief  De-initializes the DSI MSP.
564
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
565 566 567
  *               the configuration information for the DSI.
  * @retval None
  */
568
__weak void HAL_DSI_MspDeInit(DSI_HandleTypeDef *hdsi)
569 570 571 572 573 574 575 576
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hdsi);
  /* NOTE : This function Should not be modified, when the callback is needed,
            the HAL_DSI_MspDeInit could be implemented in the user file
   */
}

577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759
#if (USE_HAL_DSI_REGISTER_CALLBACKS == 1)
/**
  * @brief  Register a User DSI Callback
  *         To be used instead of the weak predefined callback
  * @param hdsi dsi handle
  * @param CallbackID ID of the callback to be registered
  *        This parameter can be one of the following values:
  *          @arg @ref HAL_DSI_TEARING_EFFECT_CB_ID Tearing Effect Callback ID
  *          @arg @ref HAL_DSI_ENDOF_REFRESH_CB_ID End Of Refresh Callback ID
  *          @arg @ref HAL_DSI_ERROR_CB_ID Error Callback ID
  *          @arg @ref HAL_DSI_MSPINIT_CB_ID MspInit callback ID
  *          @arg @ref HAL_DSI_MSPDEINIT_CB_ID MspDeInit callback ID
  * @param pCallback pointer to the Callback function
  * @retval status
  */
HAL_StatusTypeDef HAL_DSI_RegisterCallback(DSI_HandleTypeDef *hdsi, HAL_DSI_CallbackIDTypeDef CallbackID,
                                           pDSI_CallbackTypeDef pCallback)
{
  HAL_StatusTypeDef status = HAL_OK;

  if (pCallback == NULL)
  {
    /* Update the error code */
    hdsi->ErrorCode |= HAL_DSI_ERROR_INVALID_CALLBACK;

    return HAL_ERROR;
  }
  /* Process locked */
  __HAL_LOCK(hdsi);

  if (hdsi->State == HAL_DSI_STATE_READY)
  {
    switch (CallbackID)
    {
      case HAL_DSI_TEARING_EFFECT_CB_ID :
        hdsi->TearingEffectCallback = pCallback;
        break;

      case HAL_DSI_ENDOF_REFRESH_CB_ID :
        hdsi->EndOfRefreshCallback = pCallback;
        break;

      case HAL_DSI_ERROR_CB_ID :
        hdsi->ErrorCallback = pCallback;
        break;

      case HAL_DSI_MSPINIT_CB_ID :
        hdsi->MspInitCallback = pCallback;
        break;

      case HAL_DSI_MSPDEINIT_CB_ID :
        hdsi->MspDeInitCallback = pCallback;
        break;

      default :
        /* Update the error code */
        hdsi->ErrorCode |= HAL_DSI_ERROR_INVALID_CALLBACK;
        /* Return error status */
        status =  HAL_ERROR;
        break;
    }
  }
  else if (hdsi->State == HAL_DSI_STATE_RESET)
  {
    switch (CallbackID)
    {
      case HAL_DSI_MSPINIT_CB_ID :
        hdsi->MspInitCallback = pCallback;
        break;

      case HAL_DSI_MSPDEINIT_CB_ID :
        hdsi->MspDeInitCallback = pCallback;
        break;

      default :
        /* Update the error code */
        hdsi->ErrorCode |= HAL_DSI_ERROR_INVALID_CALLBACK;
        /* Return error status */
        status =  HAL_ERROR;
        break;
    }
  }
  else
  {
    /* Update the error code */
    hdsi->ErrorCode |= HAL_DSI_ERROR_INVALID_CALLBACK;
    /* Return error status */
    status =  HAL_ERROR;
  }

  /* Release Lock */
  __HAL_UNLOCK(hdsi);

  return status;
}

/**
  * @brief  Unregister a DSI Callback
  *         DSI callabck is redirected to the weak predefined callback
  * @param hdsi dsi handle
  * @param CallbackID ID of the callback to be unregistered
  *        This parameter can be one of the following values:
  *          @arg @ref HAL_DSI_TEARING_EFFECT_CB_ID Tearing Effect Callback ID
  *          @arg @ref HAL_DSI_ENDOF_REFRESH_CB_ID End Of Refresh Callback ID
  *          @arg @ref HAL_DSI_ERROR_CB_ID Error Callback ID
  *          @arg @ref HAL_DSI_MSPINIT_CB_ID MspInit callback ID
  *          @arg @ref HAL_DSI_MSPDEINIT_CB_ID MspDeInit callback ID
  * @retval status
  */
HAL_StatusTypeDef HAL_DSI_UnRegisterCallback(DSI_HandleTypeDef *hdsi, HAL_DSI_CallbackIDTypeDef CallbackID)
{
  HAL_StatusTypeDef status = HAL_OK;

  /* Process locked */
  __HAL_LOCK(hdsi);

  if (hdsi->State == HAL_DSI_STATE_READY)
  {
    switch (CallbackID)
    {
      case HAL_DSI_TEARING_EFFECT_CB_ID :
        hdsi->TearingEffectCallback = HAL_DSI_TearingEffectCallback; /* Legacy weak TearingEffectCallback */
        break;

      case HAL_DSI_ENDOF_REFRESH_CB_ID :
        hdsi->EndOfRefreshCallback = HAL_DSI_EndOfRefreshCallback;   /* Legacy weak EndOfRefreshCallback  */
        break;

      case HAL_DSI_ERROR_CB_ID :
        hdsi->ErrorCallback        = HAL_DSI_ErrorCallback;          /* Legacy weak ErrorCallback        */
        break;

      case HAL_DSI_MSPINIT_CB_ID :
        hdsi->MspInitCallback = HAL_DSI_MspInit;                     /* Legcay weak MspInit Callback     */
        break;

      case HAL_DSI_MSPDEINIT_CB_ID :
        hdsi->MspDeInitCallback = HAL_DSI_MspDeInit;                 /* Legcay weak MspDeInit Callback   */
        break;

      default :
        /* Update the error code */
        hdsi->ErrorCode |= HAL_DSI_ERROR_INVALID_CALLBACK;
        /* Return error status */
        status =  HAL_ERROR;
        break;
    }
  }
  else if (hdsi->State == HAL_DSI_STATE_RESET)
  {
    switch (CallbackID)
    {
      case HAL_DSI_MSPINIT_CB_ID :
        hdsi->MspInitCallback = HAL_DSI_MspInit;                  /* Legcay weak MspInit Callback   */
        break;

      case HAL_DSI_MSPDEINIT_CB_ID :
        hdsi->MspDeInitCallback = HAL_DSI_MspDeInit;              /* Legcay weak MspDeInit Callback */
        break;

      default :
        /* Update the error code */
        hdsi->ErrorCode |= HAL_DSI_ERROR_INVALID_CALLBACK;
        /* Return error status */
        status =  HAL_ERROR;
        break;
    }
  }
  else
  {
    /* Update the error code */
    hdsi->ErrorCode |= HAL_DSI_ERROR_INVALID_CALLBACK;
    /* Return error status */
    status =  HAL_ERROR;
  }

  /* Release Lock */
  __HAL_UNLOCK(hdsi);

  return status;
}
#endif /* USE_HAL_DSI_REGISTER_CALLBACKS */

760 761 762
/**
  * @}
  */
763 764 765 766

/** @defgroup DSI_Group2 IO operation functions
  *  @brief    IO operation functions
  *
767 768 769
@verbatim
 ===============================================================================
                      #####  IO operation functions  #####
770
 ===============================================================================
771 772 773 774 775 776 777 778
    [..]  This section provides function allowing to:
      (+) Handle DSI interrupt request

@endverbatim
  * @{
  */
/**
  * @brief  Handles DSI interrupt request.
779 780
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
781 782 783 784 785
  * @retval HAL status
  */
void HAL_DSI_IRQHandler(DSI_HandleTypeDef *hdsi)
{
  uint32_t ErrorStatus0, ErrorStatus1;
786

787
  /* Tearing Effect Interrupt management ***************************************/
788
  if (__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_TE) != 0U)
789
  {
790
    if (__HAL_DSI_GET_IT_SOURCE(hdsi, DSI_IT_TE) != 0U)
791 792 793
    {
      /* Clear the Tearing Effect Interrupt Flag */
      __HAL_DSI_CLEAR_FLAG(hdsi, DSI_FLAG_TE);
794

795
      /* Tearing Effect Callback */
796 797 798 799 800
#if (USE_HAL_DSI_REGISTER_CALLBACKS == 1)
      /*Call registered Tearing Effect callback */
      hdsi->TearingEffectCallback(hdsi);
#else
      /*Call legacy Tearing Effect callback*/
801
      HAL_DSI_TearingEffectCallback(hdsi);
802
#endif /* USE_HAL_DSI_REGISTER_CALLBACKS */
803 804
    }
  }
805

806
  /* End of Refresh Interrupt management ***************************************/
807
  if (__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_ER) != 0U)
808
  {
809
    if (__HAL_DSI_GET_IT_SOURCE(hdsi, DSI_IT_ER) != 0U)
810 811 812
    {
      /* Clear the End of Refresh Interrupt Flag */
      __HAL_DSI_CLEAR_FLAG(hdsi, DSI_FLAG_ER);
813

814
      /* End of Refresh Callback */
815 816 817 818 819
#if (USE_HAL_DSI_REGISTER_CALLBACKS == 1)
      /*Call registered End of refresh callback */
      hdsi->EndOfRefreshCallback(hdsi);
#else
      /*Call Legacy End of refresh callback */
820
      HAL_DSI_EndOfRefreshCallback(hdsi);
821
#endif /* USE_HAL_DSI_REGISTER_CALLBACKS */
822 823
    }
  }
824

825
  /* Error Interrupts management ***********************************************/
826
  if (hdsi->ErrorMsk != 0U)
827
  {
828 829 830 831 832 833
    ErrorStatus0 = hdsi->Instance->ISR[0U];
    ErrorStatus0 &= hdsi->Instance->IER[0U];
    ErrorStatus1 = hdsi->Instance->ISR[1U];
    ErrorStatus1 &= hdsi->Instance->IER[1U];

    if ((ErrorStatus0 & DSI_ERROR_ACK_MASK) != 0U)
834 835 836
    {
      hdsi->ErrorCode |= HAL_DSI_ERROR_ACK;
    }
837 838

    if ((ErrorStatus0 & DSI_ERROR_PHY_MASK) != 0U)
839 840 841
    {
      hdsi->ErrorCode |= HAL_DSI_ERROR_PHY;
    }
842 843

    if ((ErrorStatus1 & DSI_ERROR_TX_MASK) != 0U)
844 845 846
    {
      hdsi->ErrorCode |= HAL_DSI_ERROR_TX;
    }
847 848

    if ((ErrorStatus1 & DSI_ERROR_RX_MASK) != 0U)
849 850 851
    {
      hdsi->ErrorCode |= HAL_DSI_ERROR_RX;
    }
852 853

    if ((ErrorStatus1 & DSI_ERROR_ECC_MASK) != 0U)
854 855 856
    {
      hdsi->ErrorCode |= HAL_DSI_ERROR_ECC;
    }
857 858

    if ((ErrorStatus1 & DSI_ERROR_CRC_MASK) != 0U)
859 860 861
    {
      hdsi->ErrorCode |= HAL_DSI_ERROR_CRC;
    }
862 863

    if ((ErrorStatus1 & DSI_ERROR_PSE_MASK) != 0U)
864 865 866
    {
      hdsi->ErrorCode |= HAL_DSI_ERROR_PSE;
    }
867 868

    if ((ErrorStatus1 & DSI_ERROR_EOT_MASK) != 0U)
869 870 871
    {
      hdsi->ErrorCode |= HAL_DSI_ERROR_EOT;
    }
872 873

    if ((ErrorStatus1 & DSI_ERROR_OVF_MASK) != 0U)
874 875 876
    {
      hdsi->ErrorCode |= HAL_DSI_ERROR_OVF;
    }
877 878

    if ((ErrorStatus1 & DSI_ERROR_GEN_MASK) != 0U)
879 880 881
    {
      hdsi->ErrorCode |= HAL_DSI_ERROR_GEN;
    }
882

883
    /* Check only selected errors */
884
    if (hdsi->ErrorCode != HAL_DSI_ERROR_NONE)
885
    {
886 887 888 889 890 891
      /* DSI error interrupt callback */
#if (USE_HAL_DSI_REGISTER_CALLBACKS == 1)
      /*Call registered Error callback */
      hdsi->ErrorCallback(hdsi);
#else
      /*Call Legacy Error callback */
892
      HAL_DSI_ErrorCallback(hdsi);
893
#endif /* USE_HAL_DSI_REGISTER_CALLBACKS */
894 895 896 897 898 899
    }
  }
}

/**
  * @brief  Tearing Effect DSI callback.
900
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
901 902 903 904 905 906 907 908 909 910 911 912 913 914
  *               the configuration information for the DSI.
  * @retval None
  */
__weak void HAL_DSI_TearingEffectCallback(DSI_HandleTypeDef *hdsi)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hdsi);
  /* NOTE : This function Should not be modified, when the callback is needed,
            the HAL_DSI_TearingEffectCallback could be implemented in the user file
   */
}

/**
  * @brief  End of Refresh DSI callback.
915
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
916 917 918 919 920 921 922 923 924 925 926 927 928 929
  *               the configuration information for the DSI.
  * @retval None
  */
__weak void HAL_DSI_EndOfRefreshCallback(DSI_HandleTypeDef *hdsi)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hdsi);
  /* NOTE : This function Should not be modified, when the callback is needed,
            the HAL_DSI_EndOfRefreshCallback could be implemented in the user file
   */
}

/**
  * @brief  Operation Error DSI callback.
930
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947
  *               the configuration information for the DSI.
  * @retval None
  */
__weak void HAL_DSI_ErrorCallback(DSI_HandleTypeDef *hdsi)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hdsi);
  /* NOTE : This function Should not be modified, when the callback is needed,
            the HAL_DSI_ErrorCallback could be implemented in the user file
   */
}

/**
  * @}
  */

/** @defgroup DSI_Group3 Peripheral Control functions
948 949
  *  @brief    Peripheral Control functions
  *
950 951 952 953
@verbatim
 ===============================================================================
                    ##### Peripheral Control functions #####
 ===============================================================================
954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981
    [..]  This section provides functions allowing to:
      (+) Configure the Generic interface read-back Virtual Channel ID
      (+) Select video mode and configure the corresponding parameters
      (+) Configure command transmission mode: High-speed or Low-power
      (+) Configure the flow control
      (+) Configure the DSI PHY timer
      (+) Configure the DSI HOST timeout
      (+) Configure the DSI HOST timeout
      (+) Start/Stop the DSI module
      (+) Refresh the display in command mode
      (+) Controls the display color mode in Video mode
      (+) Control the display shutdown in Video mode
      (+) write short DCS or short Generic command
      (+) write long DCS or long Generic command
      (+) Read command (DCS or generic)
      (+) Enter/Exit the Ultra Low Power Mode on data only (D-PHY PLL running)
      (+) Enter/Exit the Ultra Low Power Mode on data only and clock (D-PHY PLL turned off)
      (+) Start/Stop test pattern generation
      (+) Slew-Rate And Delay Tuning
      (+) Low-Power Reception Filter Tuning
      (+) Activate an additional current path on all lanes to meet the SDDTx parameter
      (+) Custom lane pins configuration
      (+) Set custom timing for the PHY
      (+) Force the Clock/Data Lane in TX Stop Mode
      (+) Force LP Receiver in Low-Power Mode
      (+) Force Data Lanes in RX Mode after a BTA
      (+) Enable a pull-down on the lanes to prevent from floating states when unused
      (+) Switch off the contention detection on data lanes
982 983 984 985 986 987 988

@endverbatim
  * @{
  */

/**
  * @brief  Configure the Generic interface read-back Virtual Channel ID.
989
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
990
  *               the configuration information for the DSI.
991
  * @param  VirtualChannelID  Virtual channel ID
992 993 994 995 996 997
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_SetGenericVCID(DSI_HandleTypeDef *hdsi, uint32_t VirtualChannelID)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
998

999 1000 1001
  /* Update the GVCID register */
  hdsi->Instance->GVCIDR &= ~DSI_GVCIDR_VCID;
  hdsi->Instance->GVCIDR |= VirtualChannelID;
1002

1003 1004
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
1005

1006 1007 1008 1009 1010
  return HAL_OK;
}

/**
  * @brief  Select video mode and configure the corresponding parameters
1011
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1012 1013
  *               the configuration information for the DSI.
  * @param  VidCfg pointer to a DSI_VidCfgTypeDef structure that contains
1014
  *                the DSI video mode configuration parameters
1015 1016 1017 1018 1019 1020
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_ConfigVideoMode(DSI_HandleTypeDef *hdsi, DSI_VidCfgTypeDef *VidCfg)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
1021

1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036
  /* Check the parameters */
  assert_param(IS_DSI_COLOR_CODING(VidCfg->ColorCoding));
  assert_param(IS_DSI_VIDEO_MODE_TYPE(VidCfg->Mode));
  assert_param(IS_DSI_LP_COMMAND(VidCfg->LPCommandEnable));
  assert_param(IS_DSI_LP_HFP(VidCfg->LPHorizontalFrontPorchEnable));
  assert_param(IS_DSI_LP_HBP(VidCfg->LPHorizontalBackPorchEnable));
  assert_param(IS_DSI_LP_VACTIVE(VidCfg->LPVerticalActiveEnable));
  assert_param(IS_DSI_LP_VFP(VidCfg->LPVerticalFrontPorchEnable));
  assert_param(IS_DSI_LP_VBP(VidCfg->LPVerticalBackPorchEnable));
  assert_param(IS_DSI_LP_VSYNC(VidCfg->LPVerticalSyncActiveEnable));
  assert_param(IS_DSI_FBTAA(VidCfg->FrameBTAAcknowledgeEnable));
  assert_param(IS_DSI_DE_POLARITY(VidCfg->DEPolarity));
  assert_param(IS_DSI_VSYNC_POLARITY(VidCfg->VSPolarity));
  assert_param(IS_DSI_HSYNC_POLARITY(VidCfg->HSPolarity));
  /* Check the LooselyPacked variant only in 18-bit mode */
1037
  if (VidCfg->ColorCoding == DSI_RGB666)
1038 1039 1040
  {
    assert_param(IS_DSI_LOOSELY_PACKED(VidCfg->LooselyPacked));
  }
1041

1042 1043 1044
  /* Select video mode by resetting CMDM and DSIM bits */
  hdsi->Instance->MCR &= ~DSI_MCR_CMDM;
  hdsi->Instance->WCFGR &= ~DSI_WCFGR_DSIM;
1045

1046 1047 1048
  /* Configure the video mode transmission type */
  hdsi->Instance->VMCR &= ~DSI_VMCR_VMT;
  hdsi->Instance->VMCR |= VidCfg->Mode;
1049

1050 1051 1052
  /* Configure the video packet size */
  hdsi->Instance->VPCR &= ~DSI_VPCR_VPSIZE;
  hdsi->Instance->VPCR |= VidCfg->PacketSize;
1053

1054 1055 1056
  /* Set the chunks number to be transmitted through the DSI link */
  hdsi->Instance->VCCR &= ~DSI_VCCR_NUMC;
  hdsi->Instance->VCCR |= VidCfg->NumberOfChunks;
1057

1058 1059 1060
  /* Set the size of the null packet */
  hdsi->Instance->VNPCR &= ~DSI_VNPCR_NPSIZE;
  hdsi->Instance->VNPCR |= VidCfg->NullPacketSize;
1061

1062 1063 1064
  /* Select the virtual channel for the LTDC interface traffic */
  hdsi->Instance->LVCIDR &= ~DSI_LVCIDR_VCID;
  hdsi->Instance->LVCIDR |= VidCfg->VirtualChannelID;
1065

1066 1067 1068
  /* Configure the polarity of control signals */
  hdsi->Instance->LPCR &= ~(DSI_LPCR_DEP | DSI_LPCR_VSP | DSI_LPCR_HSP);
  hdsi->Instance->LPCR |= (VidCfg->DEPolarity | VidCfg->VSPolarity | VidCfg->HSPolarity);
1069

1070 1071 1072
  /* Select the color coding for the host */
  hdsi->Instance->LCOLCR &= ~DSI_LCOLCR_COLC;
  hdsi->Instance->LCOLCR |= VidCfg->ColorCoding;
1073

1074 1075
  /* Select the color coding for the wrapper */
  hdsi->Instance->WCFGR &= ~DSI_WCFGR_COLMUX;
1076 1077
  hdsi->Instance->WCFGR |= ((VidCfg->ColorCoding) << 1U);

1078
  /* Enable/disable the loosely packed variant to 18-bit configuration */
1079
  if (VidCfg->ColorCoding == DSI_RGB666)
1080 1081 1082 1083
  {
    hdsi->Instance->LCOLCR &= ~DSI_LCOLCR_LPE;
    hdsi->Instance->LCOLCR |= VidCfg->LooselyPacked;
  }
1084

1085 1086 1087
  /* Set the Horizontal Synchronization Active (HSA) in lane byte clock cycles */
  hdsi->Instance->VHSACR &= ~DSI_VHSACR_HSA;
  hdsi->Instance->VHSACR |= VidCfg->HorizontalSyncActive;
1088

1089 1090 1091
  /* Set the Horizontal Back Porch (HBP) in lane byte clock cycles */
  hdsi->Instance->VHBPCR &= ~DSI_VHBPCR_HBP;
  hdsi->Instance->VHBPCR |= VidCfg->HorizontalBackPorch;
1092

1093 1094 1095
  /* Set the total line time (HLINE=HSA+HBP+HACT+HFP) in lane byte clock cycles */
  hdsi->Instance->VLCR &= ~DSI_VLCR_HLINE;
  hdsi->Instance->VLCR |= VidCfg->HorizontalLine;
1096

1097 1098 1099
  /* Set the Vertical Synchronization Active (VSA) */
  hdsi->Instance->VVSACR &= ~DSI_VVSACR_VSA;
  hdsi->Instance->VVSACR |= VidCfg->VerticalSyncActive;
1100

1101 1102 1103
  /* Set the Vertical Back Porch (VBP)*/
  hdsi->Instance->VVBPCR &= ~DSI_VVBPCR_VBP;
  hdsi->Instance->VVBPCR |= VidCfg->VerticalBackPorch;
1104

1105 1106 1107
  /* Set the Vertical Front Porch (VFP)*/
  hdsi->Instance->VVFPCR &= ~DSI_VVFPCR_VFP;
  hdsi->Instance->VVFPCR |= VidCfg->VerticalFrontPorch;
1108

1109 1110 1111
  /* Set the Vertical Active period*/
  hdsi->Instance->VVACR &= ~DSI_VVACR_VA;
  hdsi->Instance->VVACR |= VidCfg->VerticalActive;
1112

1113 1114 1115
  /* Configure the command transmission mode */
  hdsi->Instance->VMCR &= ~DSI_VMCR_LPCE;
  hdsi->Instance->VMCR |= VidCfg->LPCommandEnable;
1116

1117 1118
  /* Low power largest packet size */
  hdsi->Instance->LPMCR &= ~DSI_LPMCR_LPSIZE;
1119 1120
  hdsi->Instance->LPMCR |= ((VidCfg->LPLargestPacketSize) << 16U);

1121 1122 1123
  /* Low power VACT largest packet size */
  hdsi->Instance->LPMCR &= ~DSI_LPMCR_VLPSIZE;
  hdsi->Instance->LPMCR |= VidCfg->LPVACTLargestPacketSize;
1124

1125 1126 1127
  /* Enable LP transition in HFP period */
  hdsi->Instance->VMCR &= ~DSI_VMCR_LPHFPE;
  hdsi->Instance->VMCR |= VidCfg->LPHorizontalFrontPorchEnable;
1128

1129 1130 1131
  /* Enable LP transition in HBP period */
  hdsi->Instance->VMCR &= ~DSI_VMCR_LPHBPE;
  hdsi->Instance->VMCR |= VidCfg->LPHorizontalBackPorchEnable;
1132

1133 1134 1135
  /* Enable LP transition in VACT period */
  hdsi->Instance->VMCR &= ~DSI_VMCR_LPVAE;
  hdsi->Instance->VMCR |= VidCfg->LPVerticalActiveEnable;
1136

1137 1138 1139
  /* Enable LP transition in VFP period */
  hdsi->Instance->VMCR &= ~DSI_VMCR_LPVFPE;
  hdsi->Instance->VMCR |= VidCfg->LPVerticalFrontPorchEnable;
1140

1141 1142 1143
  /* Enable LP transition in VBP period */
  hdsi->Instance->VMCR &= ~DSI_VMCR_LPVBPE;
  hdsi->Instance->VMCR |= VidCfg->LPVerticalBackPorchEnable;
1144

1145 1146 1147
  /* Enable LP transition in vertical sync period */
  hdsi->Instance->VMCR &= ~DSI_VMCR_LPVSAE;
  hdsi->Instance->VMCR |= VidCfg->LPVerticalSyncActiveEnable;
1148

1149 1150 1151
  /* Enable the request for an acknowledge response at the end of a frame */
  hdsi->Instance->VMCR &= ~DSI_VMCR_FBTAAE;
  hdsi->Instance->VMCR |= VidCfg->FrameBTAAcknowledgeEnable;
1152

1153 1154
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
1155

1156 1157 1158 1159 1160
  return HAL_OK;
}

/**
  * @brief  Select adapted command mode and configure the corresponding parameters
1161
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1162
  *               the configuration information for the DSI.
1163
  * @param  CmdCfg  pointer to a DSI_CmdCfgTypeDef structure that contains
1164 1165 1166 1167 1168 1169 1170
  *                 the DSI command mode configuration parameters
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_ConfigAdaptedCommandMode(DSI_HandleTypeDef *hdsi, DSI_CmdCfgTypeDef *CmdCfg)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
1171

1172 1173 1174 1175 1176 1177 1178 1179 1180 1181
  /* Check the parameters */
  assert_param(IS_DSI_COLOR_CODING(CmdCfg->ColorCoding));
  assert_param(IS_DSI_TE_SOURCE(CmdCfg->TearingEffectSource));
  assert_param(IS_DSI_TE_POLARITY(CmdCfg->TearingEffectPolarity));
  assert_param(IS_DSI_AUTOMATIC_REFRESH(CmdCfg->AutomaticRefresh));
  assert_param(IS_DSI_VS_POLARITY(CmdCfg->VSyncPol));
  assert_param(IS_DSI_TE_ACK_REQUEST(CmdCfg->TEAcknowledgeRequest));
  assert_param(IS_DSI_DE_POLARITY(CmdCfg->DEPolarity));
  assert_param(IS_DSI_VSYNC_POLARITY(CmdCfg->VSPolarity));
  assert_param(IS_DSI_HSYNC_POLARITY(CmdCfg->HSPolarity));
1182

1183 1184 1185 1186
  /* Select command mode by setting CMDM and DSIM bits */
  hdsi->Instance->MCR |= DSI_MCR_CMDM;
  hdsi->Instance->WCFGR &= ~DSI_WCFGR_DSIM;
  hdsi->Instance->WCFGR |= DSI_WCFGR_DSIM;
1187

1188 1189 1190
  /* Select the virtual channel for the LTDC interface traffic */
  hdsi->Instance->LVCIDR &= ~DSI_LVCIDR_VCID;
  hdsi->Instance->LVCIDR |= CmdCfg->VirtualChannelID;
1191

1192 1193 1194
  /* Configure the polarity of control signals */
  hdsi->Instance->LPCR &= ~(DSI_LPCR_DEP | DSI_LPCR_VSP | DSI_LPCR_HSP);
  hdsi->Instance->LPCR |= (CmdCfg->DEPolarity | CmdCfg->VSPolarity | CmdCfg->HSPolarity);
1195

1196 1197 1198
  /* Select the color coding for the host */
  hdsi->Instance->LCOLCR &= ~DSI_LCOLCR_COLC;
  hdsi->Instance->LCOLCR |= CmdCfg->ColorCoding;
1199

1200 1201
  /* Select the color coding for the wrapper */
  hdsi->Instance->WCFGR &= ~DSI_WCFGR_COLMUX;
1202 1203
  hdsi->Instance->WCFGR |= ((CmdCfg->ColorCoding) << 1U);

1204 1205 1206
  /* Configure the maximum allowed size for write memory command */
  hdsi->Instance->LCCR &= ~DSI_LCCR_CMDSIZE;
  hdsi->Instance->LCCR |= CmdCfg->CommandSize;
1207

1208 1209
  /* Configure the tearing effect source and polarity and select the refresh mode */
  hdsi->Instance->WCFGR &= ~(DSI_WCFGR_TESRC | DSI_WCFGR_TEPOL | DSI_WCFGR_AR | DSI_WCFGR_VSPOL);
1210 1211 1212
  hdsi->Instance->WCFGR |= (CmdCfg->TearingEffectSource | CmdCfg->TearingEffectPolarity | CmdCfg->AutomaticRefresh |
                            CmdCfg->VSyncPol);

1213 1214 1215
  /* Configure the tearing effect acknowledge request */
  hdsi->Instance->CMCR &= ~DSI_CMCR_TEARE;
  hdsi->Instance->CMCR |= CmdCfg->TEAcknowledgeRequest;
1216

1217 1218
  /* Enable the Tearing Effect interrupt */
  __HAL_DSI_ENABLE_IT(hdsi, DSI_IT_TE);
1219

1220 1221
  /* Enable the End of Refresh interrupt */
  __HAL_DSI_ENABLE_IT(hdsi, DSI_IT_ER);
1222

1223 1224
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
1225

1226 1227 1228 1229 1230 1231
  return HAL_OK;
}

/**
  * @brief  Configure command transmission mode: High-speed or Low-power
  *         and enable/disable acknowledge request after packet transmission
1232
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1233
  *               the configuration information for the DSI.
1234
  * @param  LPCmd  pointer to a DSI_LPCmdTypeDef structure that contains
1235 1236 1237 1238 1239 1240 1241
  *                the DSI command transmission mode configuration parameters
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_ConfigCommand(DSI_HandleTypeDef *hdsi, DSI_LPCmdTypeDef *LPCmd)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
1242

1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255
  assert_param(IS_DSI_LP_GSW0P(LPCmd->LPGenShortWriteNoP));
  assert_param(IS_DSI_LP_GSW1P(LPCmd->LPGenShortWriteOneP));
  assert_param(IS_DSI_LP_GSW2P(LPCmd->LPGenShortWriteTwoP));
  assert_param(IS_DSI_LP_GSR0P(LPCmd->LPGenShortReadNoP));
  assert_param(IS_DSI_LP_GSR1P(LPCmd->LPGenShortReadOneP));
  assert_param(IS_DSI_LP_GSR2P(LPCmd->LPGenShortReadTwoP));
  assert_param(IS_DSI_LP_GLW(LPCmd->LPGenLongWrite));
  assert_param(IS_DSI_LP_DSW0P(LPCmd->LPDcsShortWriteNoP));
  assert_param(IS_DSI_LP_DSW1P(LPCmd->LPDcsShortWriteOneP));
  assert_param(IS_DSI_LP_DSR0P(LPCmd->LPDcsShortReadNoP));
  assert_param(IS_DSI_LP_DLW(LPCmd->LPDcsLongWrite));
  assert_param(IS_DSI_LP_MRDP(LPCmd->LPMaxReadPacket));
  assert_param(IS_DSI_ACK_REQUEST(LPCmd->AcknowledgeRequest));
1256

1257
  /* Select High-speed or Low-power for command transmission */
1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268
  hdsi->Instance->CMCR &= ~(DSI_CMCR_GSW0TX | \
                            DSI_CMCR_GSW1TX | \
                            DSI_CMCR_GSW2TX | \
                            DSI_CMCR_GSR0TX | \
                            DSI_CMCR_GSR1TX | \
                            DSI_CMCR_GSR2TX | \
                            DSI_CMCR_GLWTX  | \
                            DSI_CMCR_DSW0TX | \
                            DSI_CMCR_DSW1TX | \
                            DSI_CMCR_DSR0TX | \
                            DSI_CMCR_DLWTX  | \
1269
                            DSI_CMCR_MRDPS);
1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280
  hdsi->Instance->CMCR |= (LPCmd->LPGenShortWriteNoP  | \
                           LPCmd->LPGenShortWriteOneP | \
                           LPCmd->LPGenShortWriteTwoP | \
                           LPCmd->LPGenShortReadNoP   | \
                           LPCmd->LPGenShortReadOneP  | \
                           LPCmd->LPGenShortReadTwoP  | \
                           LPCmd->LPGenLongWrite      | \
                           LPCmd->LPDcsShortWriteNoP  | \
                           LPCmd->LPDcsShortWriteOneP | \
                           LPCmd->LPDcsShortReadNoP   | \
                           LPCmd->LPDcsLongWrite      | \
1281
                           LPCmd->LPMaxReadPacket);
1282

1283 1284 1285
  /* Configure the acknowledge request after each packet transmission */
  hdsi->Instance->CMCR &= ~DSI_CMCR_ARE;
  hdsi->Instance->CMCR |= LPCmd->AcknowledgeRequest;
1286

1287 1288
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
1289

1290 1291 1292 1293 1294
  return HAL_OK;
}

/**
  * @brief  Configure the flow control parameters
1295
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1296
  *               the configuration information for the DSI.
1297
  * @param  FlowControl  flow control feature(s) to be enabled.
1298 1299 1300 1301 1302 1303 1304
  *                      This parameter can be any combination of @ref DSI_FlowControl.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_ConfigFlowControl(DSI_HandleTypeDef *hdsi, uint32_t FlowControl)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
1305

1306 1307
  /* Check the parameters */
  assert_param(IS_DSI_FLOW_CONTROL(FlowControl));
1308

1309 1310 1311
  /* Set the DSI Host Protocol Configuration Register */
  hdsi->Instance->PCR &= ~DSI_FLOW_CONTROL_ALL;
  hdsi->Instance->PCR |= FlowControl;
1312

1313 1314
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
1315

1316 1317 1318 1319 1320
  return HAL_OK;
}

/**
  * @brief  Configure the DSI PHY timer parameters
1321
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1322
  *               the configuration information for the DSI.
1323
  * @param  PhyTimers  DSI_PHY_TimerTypeDef structure that contains
1324 1325 1326 1327 1328 1329 1330 1331
  *                    the DSI PHY timing parameters
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_ConfigPhyTimer(DSI_HandleTypeDef *hdsi, DSI_PHY_TimerTypeDef *PhyTimers)
{
  uint32_t maxTime;
  /* Process locked */
  __HAL_LOCK(hdsi);
1332 1333 1334

  maxTime = (PhyTimers->ClockLaneLP2HSTime > PhyTimers->ClockLaneHS2LPTime) ? PhyTimers->ClockLaneLP2HSTime :
            PhyTimers->ClockLaneHS2LPTime;
1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345

  /* Clock lane timer configuration */

  /* In Automatic Clock Lane control mode, the DSI Host can turn off the clock lane between two
     High-Speed transmission.
     To do so, the DSI Host calculates the time required for the clock lane to change from HighSpeed
     to Low-Power and from Low-Power to High-Speed.
     This timings are configured by the HS2LP_TIME and LP2HS_TIME in the DSI Host Clock Lane Timer Configuration Register (DSI_CLTCR).
     But the DSI Host is not calculating LP2HS_TIME + HS2LP_TIME but 2 x HS2LP_TIME.

     Workaround : Configure HS2LP_TIME and LP2HS_TIME with the same value being the max of HS2LP_TIME or LP2HS_TIME.
1346
    */
1347
  hdsi->Instance->CLTCR &= ~(DSI_CLTCR_LP2HS_TIME | DSI_CLTCR_HS2LP_TIME);
1348 1349
  hdsi->Instance->CLTCR |= (maxTime | ((maxTime) << 16U));

1350 1351
  /* Data lane timer configuration */
  hdsi->Instance->DLTCR &= ~(DSI_DLTCR_MRD_TIME | DSI_DLTCR_LP2HS_TIME | DSI_DLTCR_HS2LP_TIME);
1352 1353 1354
  hdsi->Instance->DLTCR |= (PhyTimers->DataLaneMaxReadTime | ((PhyTimers->DataLaneLP2HSTime) << 16U) | ((
                              PhyTimers->DataLaneHS2LPTime) << 24U));

1355 1356
  /* Configure the wait period to request HS transmission after a stop state */
  hdsi->Instance->PCONFR &= ~DSI_PCONFR_SW_TIME;
1357 1358
  hdsi->Instance->PCONFR |= ((PhyTimers->StopWaitTime) << 8U);

1359 1360
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
1361

1362 1363 1364 1365 1366
  return HAL_OK;
}

/**
  * @brief  Configure the DSI HOST timeout parameters
1367
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1368
  *               the configuration information for the DSI.
1369
  * @param  HostTimeouts  DSI_HOST_TimeoutTypeDef structure that contains
1370 1371 1372 1373 1374 1375 1376
  *                       the DSI host timeout parameters
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_ConfigHostTimeouts(DSI_HandleTypeDef *hdsi, DSI_HOST_TimeoutTypeDef *HostTimeouts)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
1377

1378 1379
  /* Set the timeout clock division factor */
  hdsi->Instance->CCR &= ~DSI_CCR_TOCKDIV;
1380 1381
  hdsi->Instance->CCR |= ((HostTimeouts->TimeoutCkdiv) << 8U);

1382
  /* High-speed transmission timeout */
1383 1384 1385
  hdsi->Instance->TCCR[0U] &= ~DSI_TCCR0_HSTX_TOCNT;
  hdsi->Instance->TCCR[0U] |= ((HostTimeouts->HighSpeedTransmissionTimeout) << 16U);

1386
  /* Low-power reception timeout */
1387 1388 1389
  hdsi->Instance->TCCR[0U] &= ~DSI_TCCR0_LPRX_TOCNT;
  hdsi->Instance->TCCR[0U] |= HostTimeouts->LowPowerReceptionTimeout;

1390
  /* High-speed read timeout */
1391 1392 1393
  hdsi->Instance->TCCR[1U] &= ~DSI_TCCR1_HSRD_TOCNT;
  hdsi->Instance->TCCR[1U] |= HostTimeouts->HighSpeedReadTimeout;

1394
  /* Low-power read timeout */
1395 1396 1397
  hdsi->Instance->TCCR[2U] &= ~DSI_TCCR2_LPRD_TOCNT;
  hdsi->Instance->TCCR[2U] |= HostTimeouts->LowPowerReadTimeout;

1398
  /* High-speed write timeout */
1399 1400 1401
  hdsi->Instance->TCCR[3U] &= ~DSI_TCCR3_HSWR_TOCNT;
  hdsi->Instance->TCCR[3U] |= HostTimeouts->HighSpeedWriteTimeout;

1402
  /* High-speed write presp mode */
1403 1404 1405
  hdsi->Instance->TCCR[3U] &= ~DSI_TCCR3_PM;
  hdsi->Instance->TCCR[3U] |= HostTimeouts->HighSpeedWritePrespMode;

1406
  /* Low-speed write timeout */
1407 1408 1409
  hdsi->Instance->TCCR[4U] &= ~DSI_TCCR4_LPWR_TOCNT;
  hdsi->Instance->TCCR[4U] |= HostTimeouts->LowPowerWriteTimeout;

1410
  /* BTA timeout */
1411 1412 1413
  hdsi->Instance->TCCR[5U] &= ~DSI_TCCR5_BTA_TOCNT;
  hdsi->Instance->TCCR[5U] |= HostTimeouts->BTATimeout;

1414 1415
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
1416

1417 1418 1419 1420 1421
  return HAL_OK;
}

/**
  * @brief  Start the DSI module
1422
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1423 1424 1425 1426 1427 1428 1429
  *               the configuration information for the DSI.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_Start(DSI_HandleTypeDef *hdsi)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
1430

1431 1432
  /* Enable the DSI host */
  __HAL_DSI_ENABLE(hdsi);
1433

1434 1435
  /* Enable the DSI wrapper */
  __HAL_DSI_WRAPPER_ENABLE(hdsi);
1436

1437 1438
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
1439

1440 1441 1442 1443 1444
  return HAL_OK;
}

/**
  * @brief  Stop the DSI module
1445
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1446 1447 1448 1449 1450 1451 1452
  *               the configuration information for the DSI.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_Stop(DSI_HandleTypeDef *hdsi)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
1453

1454 1455
  /* Disable the DSI host */
  __HAL_DSI_DISABLE(hdsi);
1456

1457 1458
  /* Disable the DSI wrapper */
  __HAL_DSI_WRAPPER_DISABLE(hdsi);
1459

1460 1461
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
1462

1463 1464 1465 1466 1467
  return HAL_OK;
}

/**
  * @brief  Refresh the display in command mode
1468
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1469 1470 1471 1472 1473 1474 1475
  *               the configuration information for the DSI.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_Refresh(DSI_HandleTypeDef *hdsi)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
1476

1477 1478
  /* Update the display */
  hdsi->Instance->WCR |= DSI_WCR_LTDCEN;
1479

1480 1481
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
1482

1483 1484 1485 1486 1487
  return HAL_OK;
}

/**
  * @brief  Controls the display color mode in Video mode
1488
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1489
  *               the configuration information for the DSI.
1490
  * @param  ColorMode  Color mode (full or 8-colors).
1491 1492 1493 1494 1495 1496 1497
  *                    This parameter can be any value of @ref DSI_Color_Mode
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_ColorMode(DSI_HandleTypeDef *hdsi, uint32_t ColorMode)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
1498

1499 1500
  /* Check the parameters */
  assert_param(IS_DSI_COLOR_MODE(ColorMode));
1501

1502 1503 1504
  /* Update the display color mode */
  hdsi->Instance->WCR &= ~DSI_WCR_COLM;
  hdsi->Instance->WCR |= ColorMode;
1505

1506 1507
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
1508

1509 1510 1511 1512 1513
  return HAL_OK;
}

/**
  * @brief  Control the display shutdown in Video mode
1514
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1515
  *               the configuration information for the DSI.
1516
  * @param  Shutdown  Shut-down (Display-ON or Display-OFF).
1517 1518 1519 1520 1521 1522 1523
  *                   This parameter can be any value of @ref DSI_ShutDown
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_Shutdown(DSI_HandleTypeDef *hdsi, uint32_t Shutdown)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
1524

1525 1526
  /* Check the parameters */
  assert_param(IS_DSI_SHUT_DOWN(Shutdown));
1527

1528 1529 1530
  /* Update the display Shutdown */
  hdsi->Instance->WCR &= ~DSI_WCR_SHTDN;
  hdsi->Instance->WCR |= Shutdown;
1531

1532 1533
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
1534

1535 1536 1537 1538
  return HAL_OK;
}

/**
1539 1540
  * @brief  write short DCS or short Generic command
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1541
  *               the configuration information for the DSI.
1542 1543
  * @param  ChannelID  Virtual channel ID.
  * @param  Mode  DSI short packet data type.
1544
  *               This parameter can be any value of @ref DSI_SHORT_WRITE_PKT_Data_Type.
1545
  * @param  Param1  DSC command or first generic parameter.
1546 1547
  *                 This parameter can be any value of @ref DSI_DCS_Command or a
  *                 generic command code.
1548
  * @param  Param2  DSC parameter or second generic parameter.
1549 1550 1551 1552 1553 1554 1555 1556
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_ShortWrite(DSI_HandleTypeDef *hdsi,
                                     uint32_t ChannelID,
                                     uint32_t Mode,
                                     uint32_t Param1,
                                     uint32_t Param2)
{
1557 1558 1559
  HAL_StatusTypeDef status;
  /* Check the parameters */
  assert_param(IS_DSI_SHORT_WRITE_PACKET_TYPE(Mode));
1560 1561 1562

  /* Process locked */
  __HAL_LOCK(hdsi);
1563 1564 1565

   status = DSI_ShortWrite(hdsi, ChannelID, Mode, Param1, Param2);

1566 1567
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
1568 1569

  return status;
1570 1571 1572
}

/**
1573 1574
  * @brief  write long DCS or long Generic command
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1575
  *               the configuration information for the DSI.
1576 1577
  * @param  ChannelID  Virtual channel ID.
  * @param  Mode  DSI long packet data type.
1578
  *               This parameter can be any value of @ref DSI_LONG_WRITE_PKT_Data_Type.
1579 1580 1581
  * @param  NbParams  Number of parameters.
  * @param  Param1  DSC command or first generic parameter.
  *                 This parameter can be any value of @ref DSI_DCS_Command or a
1582
  *                 generic command code
1583
  * @param  ParametersTable  Pointer to parameter values table.
1584 1585 1586 1587 1588 1589 1590
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_LongWrite(DSI_HandleTypeDef *hdsi,
                                    uint32_t ChannelID,
                                    uint32_t Mode,
                                    uint32_t NbParams,
                                    uint32_t Param1,
1591
                                    uint8_t *ParametersTable)
1592
{
1593 1594 1595 1596 1597
  uint32_t uicounter, nbBytes, count;
  uint32_t tickstart;
  uint32_t fifoword;
  uint8_t *pparams = ParametersTable;

1598 1599
  /* Process locked */
  __HAL_LOCK(hdsi);
1600

1601 1602
  /* Check the parameters */
  assert_param(IS_DSI_LONG_WRITE_PACKET_TYPE(Mode));
1603 1604

  /* Get tick */
1605
  tickstart = HAL_GetTick();
1606

1607
  /* Wait for Command FIFO Empty */
1608
  while ((hdsi->Instance->GPSR & DSI_GPSR_CMDFE) == 0U)
1609 1610
  {
    /* Check for the Timeout */
1611
    if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
1612 1613 1614
    {
      /* Process Unlocked */
      __HAL_UNLOCK(hdsi);
1615

1616 1617 1618
      return HAL_TIMEOUT;
    }
  }
1619 1620 1621 1622 1623 1624

  /* Set the DCS code on payload byte 1, and the other parameters on the write FIFO command*/
  fifoword = Param1;
  nbBytes = (NbParams < 3U) ? NbParams : 3U;

  for (count = 0U; count < nbBytes; count++)
1625
  {
1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637
    fifoword |= (((uint32_t)(*(pparams + count))) << (8U + (8U * count)));
  }
  hdsi->Instance->GPDR = fifoword;

  uicounter = NbParams - nbBytes;
  pparams += nbBytes;
  /* Set the Next parameters on the write FIFO command*/
  while (uicounter != 0U)
  {
    nbBytes = (uicounter < 4U) ? uicounter : 4U;
    fifoword = 0U;
    for (count = 0U; count < nbBytes; count++)
1638
    {
1639
      fifoword |= (((uint32_t)(*(pparams + count))) << (8U * count));
1640
    }
1641 1642 1643 1644
    hdsi->Instance->GPDR = fifoword;

    uicounter -= nbBytes;
    pparams += nbBytes;
1645
  }
1646

1647 1648 1649 1650
  /* Configure the packet to send a long DCS command */
  DSI_ConfigPacketHeader(hdsi->Instance,
                         ChannelID,
                         Mode,
1651 1652 1653
                         ((NbParams + 1U) & 0x00FFU),
                         (((NbParams + 1U) & 0xFF00U) >> 8U));

1654 1655
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
1656

1657 1658 1659 1660 1661
  return HAL_OK;
}

/**
  * @brief  Read command (DCS or generic)
1662
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1663
  *               the configuration information for the DSI.
1664
  * @param  ChannelNbr  Virtual channel ID
1665
  * @param  Array pointer to a buffer to store the payload of a read back operation.
1666 1667
  * @param  Size  Data size to be read (in byte).
  * @param  Mode  DSI read packet data type.
1668
  *               This parameter can be any value of @ref DSI_SHORT_READ_PKT_Data_Type.
1669 1670
  * @param  DCSCmd  DCS get/read command.
  * @param  ParametersTable  Pointer to parameter values table.
1671 1672 1673 1674
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_Read(DSI_HandleTypeDef *hdsi,
                               uint32_t ChannelNbr,
1675
                               uint8_t *Array,
1676 1677 1678
                               uint32_t Size,
                               uint32_t Mode,
                               uint32_t DCSCmd,
1679
                               uint8_t *ParametersTable)
1680
{
1681 1682 1683 1684 1685 1686 1687
  uint32_t tickstart;
  uint8_t *pdata = Array;
  uint32_t datasize = Size;
  uint32_t fifoword;
  uint32_t nbbytes;
  uint32_t count;

1688 1689
  /* Process locked */
  __HAL_LOCK(hdsi);
1690

1691 1692
  /* Check the parameters */
  assert_param(IS_DSI_READ_PACKET_TYPE(Mode));
1693 1694

  if (datasize > 2U)
1695 1696
  {
    /* set max return packet size */
1697 1698 1699 1700 1701 1702 1703 1704
    if (DSI_ShortWrite(hdsi, ChannelNbr, DSI_MAX_RETURN_PKT_SIZE, ((datasize) & 0xFFU),
                           (((datasize) >> 8U) & 0xFFU)) != HAL_OK)
    {
      /* Process Unlocked */
      __HAL_UNLOCK(hdsi);

      return HAL_ERROR;
    }
1705
  }
1706

1707 1708 1709
  /* Configure the packet to read command */
  if (Mode == DSI_DCS_SHORT_PKT_READ)
  {
1710
    DSI_ConfigPacketHeader(hdsi->Instance, ChannelNbr, Mode, DCSCmd, 0U);
1711 1712 1713
  }
  else if (Mode == DSI_GEN_SHORT_PKT_READ_P0)
  {
1714
    DSI_ConfigPacketHeader(hdsi->Instance, ChannelNbr, Mode, 0U, 0U);
1715 1716 1717
  }
  else if (Mode == DSI_GEN_SHORT_PKT_READ_P1)
  {
1718
    DSI_ConfigPacketHeader(hdsi->Instance, ChannelNbr, Mode, ParametersTable[0U], 0U);
1719 1720 1721
  }
  else if (Mode == DSI_GEN_SHORT_PKT_READ_P2)
  {
1722
    DSI_ConfigPacketHeader(hdsi->Instance, ChannelNbr, Mode, ParametersTable[0U], ParametersTable[1U]);
1723 1724 1725 1726 1727
  }
  else
  {
    /* Process Unlocked */
    __HAL_UNLOCK(hdsi);
1728 1729

    return HAL_ERROR;
1730
  }
1731 1732

  /* Get tick */
1733
  tickstart = HAL_GetTick();
1734 1735 1736

  /* If DSI fifo is not empty, read requested bytes */
  while (((int32_t)(datasize)) > 0)
1737
  {
1738
    if ((hdsi->Instance->GPSR & DSI_GPSR_PRDFE) == 0U)
1739
    {
1740 1741 1742 1743 1744 1745 1746 1747 1748
      fifoword = hdsi->Instance->GPDR;
      nbbytes = (datasize < 4U) ? datasize : 4U;

      for (count = 0U; count < nbbytes; count++)
      {
        *pdata = (uint8_t)(fifoword >> (8U * count));
        pdata++;
        datasize--;
      }
1749
    }
1750

1751
    /* Check for the Timeout */
1752
    if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
1753 1754 1755
    {
      /* Process Unlocked */
      __HAL_UNLOCK(hdsi);
1756

1757
      return HAL_TIMEOUT;
1758
    }
1759
  }
1760

1761 1762
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
1763

1764 1765 1766 1767 1768 1769
  return HAL_OK;
}

/**
  * @brief  Enter the ULPM (Ultra Low Power Mode) with the D-PHY PLL running
  *         (only data lanes are in ULPM)
1770
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1771 1772 1773 1774 1775
  *               the configuration information for the DSI.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_EnterULPMData(DSI_HandleTypeDef *hdsi)
{
1776 1777
  uint32_t tickstart;

1778 1779
  /* Process locked */
  __HAL_LOCK(hdsi);
1780

1781 1782
  /* ULPS Request on Data Lanes */
  hdsi->Instance->PUCR |= DSI_PUCR_URDL;
1783 1784

  /* Get tick */
1785
  tickstart = HAL_GetTick();
1786

1787
  /* Wait until the D-PHY active lanes enter into ULPM */
1788
  if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
1789
  {
1790
    while ((hdsi->Instance->PSR & DSI_PSR_UAN0) != 0U)
1791 1792
    {
      /* Check for the Timeout */
1793
      if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
1794 1795 1796
      {
        /* Process Unlocked */
        __HAL_UNLOCK(hdsi);
1797

1798 1799 1800 1801 1802 1803
        return HAL_TIMEOUT;
      }
    }
  }
  else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
  {
1804
    while ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1)) != 0U)
1805 1806
    {
      /* Check for the Timeout */
1807
      if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
1808 1809 1810
      {
        /* Process Unlocked */
        __HAL_UNLOCK(hdsi);
1811

1812 1813 1814 1815
        return HAL_TIMEOUT;
      }
    }
  }
1816 1817 1818 1819 1820 1821 1822 1823
  else
  {
    /* Process unlocked */
    __HAL_UNLOCK(hdsi);

    return HAL_ERROR;
  }

1824 1825
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
1826

1827 1828 1829 1830 1831 1832
  return HAL_OK;
}

/**
  * @brief  Exit the ULPM (Ultra Low Power Mode) with the D-PHY PLL running
  *         (only data lanes are in ULPM)
1833
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1834 1835 1836 1837 1838
  *               the configuration information for the DSI.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_ExitULPMData(DSI_HandleTypeDef *hdsi)
{
1839 1840
  uint32_t tickstart;

1841 1842
  /* Process locked */
  __HAL_LOCK(hdsi);
1843

1844 1845
  /* Exit ULPS on Data Lanes */
  hdsi->Instance->PUCR |= DSI_PUCR_UEDL;
1846 1847

  /* Get tick */
1848
  tickstart = HAL_GetTick();
1849

1850
  /* Wait until all active lanes exit ULPM */
1851
  if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
1852
  {
1853
    while ((hdsi->Instance->PSR & DSI_PSR_UAN0) != DSI_PSR_UAN0)
1854 1855
    {
      /* Check for the Timeout */
1856
      if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
1857 1858 1859
      {
        /* Process Unlocked */
        __HAL_UNLOCK(hdsi);
1860

1861 1862 1863 1864 1865 1866
        return HAL_TIMEOUT;
      }
    }
  }
  else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
  {
1867
    while ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1)) != (DSI_PSR_UAN0 | DSI_PSR_UAN1))
1868 1869
    {
      /* Check for the Timeout */
1870
      if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
1871 1872 1873
      {
        /* Process Unlocked */
        __HAL_UNLOCK(hdsi);
1874

1875 1876 1877 1878
        return HAL_TIMEOUT;
      }
    }
  }
1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889
  else
  {
    /* Process unlocked */
    __HAL_UNLOCK(hdsi);

    return HAL_ERROR;
  }

  /* wait for 1 ms*/
  HAL_Delay(1U);

1890
  /* De-assert the ULPM requests and the ULPM exit bits */
1891 1892
  hdsi->Instance->PUCR = 0U;

1893 1894
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
1895

1896 1897 1898 1899 1900 1901
  return HAL_OK;
}

/**
  * @brief  Enter the ULPM (Ultra Low Power Mode) with the D-PHY PLL turned off
  *         (both data and clock lanes are in ULPM)
1902
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1903 1904 1905 1906 1907
  *               the configuration information for the DSI.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_EnterULPM(DSI_HandleTypeDef *hdsi)
{
1908 1909
  uint32_t tickstart;

1910 1911
  /* Process locked */
  __HAL_LOCK(hdsi);
1912

1913 1914
  /* Clock lane configuration: no more HS request */
  hdsi->Instance->CLCR &= ~DSI_CLCR_DPCC;
1915

1916 1917
  /* Use system PLL as byte lane clock source before stopping DSIPHY clock source */
  __HAL_RCC_DSI_CONFIG(RCC_DSICLKSOURCE_PLLR);
1918

1919 1920
  /* ULPS Request on Clock and Data Lanes */
  hdsi->Instance->PUCR |= (DSI_PUCR_URCL | DSI_PUCR_URDL);
1921 1922

  /* Get tick */
1923
  tickstart = HAL_GetTick();
1924

1925
  /* Wait until all active lanes exit ULPM */
1926
  if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
1927
  {
1928
    while ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UANC)) != 0U)
1929 1930
    {
      /* Check for the Timeout */
1931
      if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
1932 1933 1934
      {
        /* Process Unlocked */
        __HAL_UNLOCK(hdsi);
1935

1936 1937 1938 1939 1940 1941
        return HAL_TIMEOUT;
      }
    }
  }
  else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
  {
1942
    while ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1 | DSI_PSR_UANC)) != 0U)
1943 1944
    {
      /* Check for the Timeout */
1945
      if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
1946 1947 1948
      {
        /* Process Unlocked */
        __HAL_UNLOCK(hdsi);
1949

1950 1951 1952 1953
        return HAL_TIMEOUT;
      }
    }
  }
1954 1955 1956 1957 1958 1959 1960 1961
  else
  {
    /* Process unlocked */
    __HAL_UNLOCK(hdsi);

    return HAL_ERROR;
  }

1962 1963
  /* Turn off the DSI PLL */
  __HAL_DSI_PLL_DISABLE(hdsi);
1964

1965 1966
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
1967

1968 1969 1970 1971 1972 1973
  return HAL_OK;
}

/**
  * @brief  Exit the ULPM (Ultra Low Power Mode) with the D-PHY PLL turned off
  *         (both data and clock lanes are in ULPM)
1974
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1975 1976 1977 1978 1979
  *               the configuration information for the DSI.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_ExitULPM(DSI_HandleTypeDef *hdsi)
{
1980 1981
  uint32_t tickstart;

1982 1983
  /* Process locked */
  __HAL_LOCK(hdsi);
1984

1985 1986
  /* Turn on the DSI PLL */
  __HAL_DSI_PLL_ENABLE(hdsi);
1987 1988

  /* Get tick */
1989
  tickstart = HAL_GetTick();
1990

1991
  /* Wait for the lock of the PLL */
1992
  while (__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_PLLLS) == 0U)
1993 1994
  {
    /* Check for the Timeout */
1995
    if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
1996 1997 1998
    {
      /* Process Unlocked */
      __HAL_UNLOCK(hdsi);
1999

2000 2001 2002
      return HAL_TIMEOUT;
    }
  }
2003

2004 2005
  /* Exit ULPS on Clock and Data Lanes */
  hdsi->Instance->PUCR |= (DSI_PUCR_UECL | DSI_PUCR_UEDL);
2006 2007

  /* Get tick */
2008
  tickstart = HAL_GetTick();
2009

2010
  /* Wait until all active lanes exit ULPM */
2011
  if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
2012
  {
2013
    while ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UANC)) != (DSI_PSR_UAN0 | DSI_PSR_UANC))
2014 2015
    {
      /* Check for the Timeout */
2016
      if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2017 2018 2019
      {
        /* Process Unlocked */
        __HAL_UNLOCK(hdsi);
2020

2021 2022 2023 2024 2025 2026
        return HAL_TIMEOUT;
      }
    }
  }
  else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
  {
2027 2028
    while ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1 | DSI_PSR_UANC)) != (DSI_PSR_UAN0 | DSI_PSR_UAN1 |
                                                                                    DSI_PSR_UANC))
2029 2030
    {
      /* Check for the Timeout */
2031
      if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2032 2033 2034
      {
        /* Process Unlocked */
        __HAL_UNLOCK(hdsi);
2035

2036 2037 2038 2039
        return HAL_TIMEOUT;
      }
    }
  }
2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050
  else
  {
    /* Process unlocked */
    __HAL_UNLOCK(hdsi);

    return HAL_ERROR;
  }

  /* wait for 1 ms */
  HAL_Delay(1U);

2051
  /* De-assert the ULPM requests and the ULPM exit bits */
2052 2053
  hdsi->Instance->PUCR = 0U;

2054 2055
  /* Switch the lanbyteclock source in the RCC from system PLL to D-PHY */
  __HAL_RCC_DSI_CONFIG(RCC_DSICLKSOURCE_DSIPHY);
2056

2057 2058
  /* Restore clock lane configuration to HS */
  hdsi->Instance->CLCR |= DSI_CLCR_DPCC;
2059

2060 2061
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
2062

2063 2064 2065 2066 2067
  return HAL_OK;
}

/**
  * @brief  Start test pattern generation
2068
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2069
  *               the configuration information for the DSI.
2070
  * @param  Mode  Pattern generator mode
2071 2072 2073
  *          This parameter can be one of the following values:
  *           0 : Color bars (horizontal or vertical)
  *           1 : BER pattern (vertical only)
2074
  * @param  Orientation  Pattern generator orientation
2075 2076 2077 2078 2079 2080 2081 2082 2083
  *          This parameter can be one of the following values:
  *           0 : Vertical color bars
  *           1 : Horizontal color bars
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_PatternGeneratorStart(DSI_HandleTypeDef *hdsi, uint32_t Mode, uint32_t Orientation)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
2084

2085 2086
  /* Configure pattern generator mode and orientation */
  hdsi->Instance->VMCR &= ~(DSI_VMCR_PGM | DSI_VMCR_PGO);
2087 2088
  hdsi->Instance->VMCR |= ((Mode << 20U) | (Orientation << 24U));

2089 2090
  /* Enable pattern generator by setting PGE bit */
  hdsi->Instance->VMCR |= DSI_VMCR_PGE;
2091

2092 2093
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
2094

2095 2096 2097 2098 2099
  return HAL_OK;
}

/**
  * @brief  Stop test pattern generation
2100
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2101 2102 2103 2104 2105 2106 2107
  *               the configuration information for the DSI.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_PatternGeneratorStop(DSI_HandleTypeDef *hdsi)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
2108

2109 2110
  /* Disable pattern generator by clearing PGE bit */
  hdsi->Instance->VMCR &= ~DSI_VMCR_PGE;
2111

2112 2113
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
2114

2115 2116 2117 2118 2119
  return HAL_OK;
}

/**
  * @brief  Set Slew-Rate And Delay Tuning
2120
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2121
  *               the configuration information for the DSI.
2122
  * @param  CommDelay  Communication delay to be adjusted.
2123
  *                    This parameter can be any value of @ref DSI_Communication_Delay
2124
  * @param  Lane  select between clock or data lanes.
2125
  *               This parameter can be any value of @ref DSI_Lane_Group
2126
  * @param  Value  Custom value of the slew-rate or delay
2127 2128
  * @retval HAL status
  */
2129 2130
HAL_StatusTypeDef HAL_DSI_SetSlewRateAndDelayTuning(DSI_HandleTypeDef *hdsi, uint32_t CommDelay, uint32_t Lane,
                                                    uint32_t Value)
2131 2132 2133
{
  /* Process locked */
  __HAL_LOCK(hdsi);
2134

2135 2136 2137
  /* Check function parameters */
  assert_param(IS_DSI_COMMUNICATION_DELAY(CommDelay));
  assert_param(IS_DSI_LANE_GROUP(Lane));
2138 2139

  switch (CommDelay)
2140
  {
2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205
    case DSI_SLEW_RATE_HSTX:
      if (Lane == DSI_CLOCK_LANE)
      {
        /* High-Speed Transmission Slew Rate Control on Clock Lane */
        hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_HSTXSRCCL;
        hdsi->Instance->WPCR[1U] |= Value << 16U;
      }
      else if (Lane == DSI_DATA_LANES)
      {
        /* High-Speed Transmission Slew Rate Control on Data Lanes */
        hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_HSTXSRCDL;
        hdsi->Instance->WPCR[1U] |= Value << 18U;
      }
      else
      {
        /* Process unlocked */
        __HAL_UNLOCK(hdsi);

        return HAL_ERROR;
      }
      break;
    case DSI_SLEW_RATE_LPTX:
      if (Lane == DSI_CLOCK_LANE)
      {
        /* Low-Power transmission Slew Rate Compensation on Clock Lane */
        hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_LPSRCCL;
        hdsi->Instance->WPCR[1U] |= Value << 6U;
      }
      else if (Lane == DSI_DATA_LANES)
      {
        /* Low-Power transmission Slew Rate Compensation on Data Lanes */
        hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_LPSRCDL;
        hdsi->Instance->WPCR[1U] |= Value << 8U;
      }
      else
      {
        /* Process unlocked */
        __HAL_UNLOCK(hdsi);

        return HAL_ERROR;
      }
      break;
    case DSI_HS_DELAY:
      if (Lane == DSI_CLOCK_LANE)
      {
        /* High-Speed Transmission Delay on Clock Lane */
        hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_HSTXDCL;
        hdsi->Instance->WPCR[1U] |= Value;
      }
      else if (Lane == DSI_DATA_LANES)
      {
        /* High-Speed Transmission Delay on Data Lanes */
        hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_HSTXDDL;
        hdsi->Instance->WPCR[1U] |= Value << 2U;
      }
      else
      {
        /* Process unlocked */
        __HAL_UNLOCK(hdsi);

        return HAL_ERROR;
      }
      break;
    default:
      break;
2206
  }
2207

2208 2209
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
2210

2211 2212 2213 2214 2215
  return HAL_OK;
}

/**
  * @brief  Low-Power Reception Filter Tuning
2216
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2217
  *               the configuration information for the DSI.
2218
  * @param  Frequency  cutoff frequency of low-pass filter at the input of LPRX
2219 2220 2221 2222 2223 2224
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_SetLowPowerRXFilter(DSI_HandleTypeDef *hdsi, uint32_t Frequency)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
2225

2226
  /* Low-Power RX low-pass Filtering Tuning */
2227 2228 2229
  hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_LPRXFT;
  hdsi->Instance->WPCR[1U] |= Frequency << 25U;

2230 2231
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
2232

2233 2234 2235 2236 2237 2238
  return HAL_OK;
}

/**
  * @brief  Activate an additional current path on all lanes to meet the SDDTx parameter
  *         defined in the MIPI D-PHY specification
2239
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2240
  *               the configuration information for the DSI.
2241
  * @param  State  ENABLE or DISABLE
2242 2243 2244 2245 2246 2247
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_SetSDD(DSI_HandleTypeDef *hdsi, FunctionalState State)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
2248

2249 2250
  /* Check function parameters */
  assert_param(IS_FUNCTIONAL_STATE(State));
2251

2252
  /* Activate/Disactivate additional current path on all lanes */
2253 2254 2255
  hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_SDDC;
  hdsi->Instance->WPCR[1U] |= ((uint32_t)State << 12U);

2256 2257
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
2258

2259 2260 2261 2262 2263
  return HAL_OK;
}

/**
  * @brief  Custom lane pins configuration
2264
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2265
  *               the configuration information for the DSI.
2266
  * @param  CustomLane  Function to be applyed on selected lane.
2267
  *                     This parameter can be any value of @ref DSI_CustomLane
2268
  * @param  Lane  select between clock or data lane 0 or data lane 1.
2269
  *               This parameter can be any value of @ref DSI_Lane_Select
2270
  * @param  State  ENABLE or DISABLE
2271 2272
  * @retval HAL status
  */
2273 2274
HAL_StatusTypeDef HAL_DSI_SetLanePinsConfiguration(DSI_HandleTypeDef *hdsi, uint32_t CustomLane, uint32_t Lane,
                                                   FunctionalState State)
2275 2276 2277
{
  /* Process locked */
  __HAL_LOCK(hdsi);
2278

2279 2280 2281 2282
  /* Check function parameters */
  assert_param(IS_DSI_CUSTOM_LANE(CustomLane));
  assert_param(IS_DSI_LANE(Lane));
  assert_param(IS_FUNCTIONAL_STATE(State));
2283 2284

  switch (CustomLane)
2285
  {
2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341
    case DSI_SWAP_LANE_PINS:
      if (Lane == DSI_CLK_LANE)
      {
        /* Swap pins on clock lane */
        hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_SWCL;
        hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 6U);
      }
      else if (Lane == DSI_DATA_LANE0)
      {
        /* Swap pins on data lane 0 */
        hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_SWDL0;
        hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 7U);
      }
      else if (Lane == DSI_DATA_LANE1)
      {
        /* Swap pins on data lane 1 */
        hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_SWDL1;
        hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 8U);
      }
      else
      {
        /* Process unlocked */
        __HAL_UNLOCK(hdsi);

        return HAL_ERROR;
      }
      break;
    case DSI_INVERT_HS_SIGNAL:
      if (Lane == DSI_CLK_LANE)
      {
        /* Invert HS signal on clock lane */
        hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_HSICL;
        hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 9U);
      }
      else if (Lane == DSI_DATA_LANE0)
      {
        /* Invert HS signal on data lane 0 */
        hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_HSIDL0;
        hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 10U);
      }
      else if (Lane == DSI_DATA_LANE1)
      {
        /* Invert HS signal on data lane 1 */
        hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_HSIDL1;
        hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 11U);
      }
      else
      {
        /* Process unlocked */
        __HAL_UNLOCK(hdsi);

        return HAL_ERROR;
      }
      break;
    default:
      break;
2342
  }
2343

2344 2345
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
2346

2347 2348 2349 2350 2351
  return HAL_OK;
}

/**
  * @brief  Set custom timing for the PHY
2352
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2353
  *               the configuration information for the DSI.
2354
  * @param  Timing  PHY timing to be adjusted.
2355
  *                 This parameter can be any value of @ref DSI_PHY_Timing
2356 2357
  * @param  State  ENABLE or DISABLE
  * @param  Value  Custom value of the timing
2358 2359 2360 2361 2362 2363
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_SetPHYTimings(DSI_HandleTypeDef *hdsi, uint32_t Timing, FunctionalState State, uint32_t Value)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
2364

2365 2366 2367
  /* Check function parameters */
  assert_param(IS_DSI_PHY_TIMING(Timing));
  assert_param(IS_FUNCTIONAL_STATE(State));
2368 2369

  switch (Timing)
2370
  {
2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489
    case DSI_TCLK_POST:
      /* Enable/Disable custom timing setting */
      hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_TCLKPOSTEN;
      hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 27U);

      if (State != DISABLE)
      {
        /* Set custom value */
        hdsi->Instance->WPCR[4U] &= ~DSI_WPCR4_TCLKPOST;
        hdsi->Instance->WPCR[4U] |= Value & DSI_WPCR4_TCLKPOST;
      }

      break;
    case DSI_TLPX_CLK:
      /* Enable/Disable custom timing setting */
      hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_TLPXCEN;
      hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 26U);

      if (State != DISABLE)
      {
        /* Set custom value */
        hdsi->Instance->WPCR[3U] &= ~DSI_WPCR3_TLPXC;
        hdsi->Instance->WPCR[3U] |= (Value << 24U) & DSI_WPCR3_TLPXC;
      }

      break;
    case DSI_THS_EXIT:
      /* Enable/Disable custom timing setting */
      hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_THSEXITEN;
      hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 25U);

      if (State != DISABLE)
      {
        /* Set custom value */
        hdsi->Instance->WPCR[3U] &= ~DSI_WPCR3_THSEXIT;
        hdsi->Instance->WPCR[3U] |= (Value << 16U) & DSI_WPCR3_THSEXIT;
      }

      break;
    case DSI_TLPX_DATA:
      /* Enable/Disable custom timing setting */
      hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_TLPXDEN;
      hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 24U);

      if (State != DISABLE)
      {
        /* Set custom value */
        hdsi->Instance->WPCR[3U] &= ~DSI_WPCR3_TLPXD;
        hdsi->Instance->WPCR[3U] |= (Value << 8U) & DSI_WPCR3_TLPXD;
      }

      break;
    case DSI_THS_ZERO:
      /* Enable/Disable custom timing setting */
      hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_THSZEROEN;
      hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 23U);

      if (State != DISABLE)
      {
        /* Set custom value */
        hdsi->Instance->WPCR[3U] &= ~DSI_WPCR3_THSZERO;
        hdsi->Instance->WPCR[3U] |= Value & DSI_WPCR3_THSZERO;
      }

      break;
    case DSI_THS_TRAIL:
      /* Enable/Disable custom timing setting */
      hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_THSTRAILEN;
      hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 22U);

      if (State != DISABLE)
      {
        /* Set custom value */
        hdsi->Instance->WPCR[2U] &= ~DSI_WPCR2_THSTRAIL;
        hdsi->Instance->WPCR[2U] |= (Value << 24U) & DSI_WPCR2_THSTRAIL;
      }

      break;
    case DSI_THS_PREPARE:
      /* Enable/Disable custom timing setting */
      hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_THSPREPEN;
      hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 21U);

      if (State != DISABLE)
      {
        /* Set custom value */
        hdsi->Instance->WPCR[2U] &= ~DSI_WPCR2_THSPREP;
        hdsi->Instance->WPCR[2U] |= (Value << 16U) & DSI_WPCR2_THSPREP;
      }

      break;
    case DSI_TCLK_ZERO:
      /* Enable/Disable custom timing setting */
      hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_TCLKZEROEN;
      hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 20U);

      if (State != DISABLE)
      {
        /* Set custom value */
        hdsi->Instance->WPCR[2U] &= ~DSI_WPCR2_TCLKZERO;
        hdsi->Instance->WPCR[2U] |= (Value << 8U) & DSI_WPCR2_TCLKZERO;
      }

      break;
    case DSI_TCLK_PREPARE:
      /* Enable/Disable custom timing setting */
      hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_TCLKPREPEN;
      hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 19U);

      if (State != DISABLE)
      {
        /* Set custom value */
        hdsi->Instance->WPCR[2U] &= ~DSI_WPCR2_TCLKPREP;
        hdsi->Instance->WPCR[2U] |= Value & DSI_WPCR2_TCLKPREP;
      }

      break;
    default:
      break;
2490
  }
2491

2492 2493
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
2494

2495 2496 2497 2498 2499
  return HAL_OK;
}

/**
  * @brief  Force the Clock/Data Lane in TX Stop Mode
2500
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2501
  *               the configuration information for the DSI.
2502
  * @param  Lane  select between clock or data lanes.
2503
  *               This parameter can be any value of @ref DSI_Lane_Group
2504
  * @param  State  ENABLE or DISABLE
2505 2506 2507 2508 2509 2510
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_ForceTXStopMode(DSI_HandleTypeDef *hdsi, uint32_t Lane, FunctionalState State)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
2511

2512 2513 2514
  /* Check function parameters */
  assert_param(IS_DSI_LANE_GROUP(Lane));
  assert_param(IS_FUNCTIONAL_STATE(State));
2515 2516

  if (Lane == DSI_CLOCK_LANE)
2517 2518
  {
    /* Force/Unforce the Clock Lane in TX Stop Mode */
2519 2520
    hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_FTXSMCL;
    hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 12U);
2521
  }
2522
  else if (Lane == DSI_DATA_LANES)
2523 2524
  {
    /* Force/Unforce the Data Lanes in TX Stop Mode */
2525 2526
    hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_FTXSMDL;
    hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 13U);
2527
  }
2528 2529 2530 2531 2532 2533 2534 2535
  else
  {
    /* Process unlocked */
    __HAL_UNLOCK(hdsi);

    return HAL_ERROR;
  }

2536 2537
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
2538

2539 2540 2541 2542
  return HAL_OK;
}

/**
2543 2544
  * @brief  Force LP Receiver in Low-Power Mode
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2545
  *               the configuration information for the DSI.
2546
  * @param  State  ENABLE or DISABLE
2547 2548 2549 2550 2551 2552
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_ForceRXLowPower(DSI_HandleTypeDef *hdsi, FunctionalState State)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
2553

2554 2555
  /* Check function parameters */
  assert_param(IS_FUNCTIONAL_STATE(State));
2556

2557
  /* Force/Unforce LP Receiver in Low-Power Mode */
2558 2559 2560
  hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_FLPRXLPM;
  hdsi->Instance->WPCR[1U] |= ((uint32_t)State << 22U);

2561 2562
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
2563

2564 2565 2566 2567 2568
  return HAL_OK;
}

/**
  * @brief  Force Data Lanes in RX Mode after a BTA
2569
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2570
  *               the configuration information for the DSI.
2571
  * @param  State  ENABLE or DISABLE
2572 2573 2574 2575 2576 2577
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_ForceDataLanesInRX(DSI_HandleTypeDef *hdsi, FunctionalState State)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
2578

2579 2580
  /* Check function parameters */
  assert_param(IS_FUNCTIONAL_STATE(State));
2581

2582
  /* Force Data Lanes in RX Mode */
2583 2584 2585
  hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_TDDL;
  hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 16U);

2586 2587
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
2588

2589 2590 2591 2592 2593
  return HAL_OK;
}

/**
  * @brief  Enable a pull-down on the lanes to prevent from floating states when unused
2594
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2595
  *               the configuration information for the DSI.
2596
  * @param  State  ENABLE or DISABLE
2597 2598 2599 2600 2601 2602
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_SetPullDown(DSI_HandleTypeDef *hdsi, FunctionalState State)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
2603

2604 2605
  /* Check function parameters */
  assert_param(IS_FUNCTIONAL_STATE(State));
2606

2607
  /* Enable/Disable pull-down on lanes */
2608 2609 2610
  hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_PDEN;
  hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 18U);

2611 2612
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
2613

2614 2615 2616 2617 2618
  return HAL_OK;
}

/**
  * @brief  Switch off the contention detection on data lanes
2619
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2620
  *               the configuration information for the DSI.
2621
  * @param  State  ENABLE or DISABLE
2622 2623 2624 2625 2626 2627
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_SetContentionDetectionOff(DSI_HandleTypeDef *hdsi, FunctionalState State)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
2628

2629 2630
  /* Check function parameters */
  assert_param(IS_FUNCTIONAL_STATE(State));
2631

2632
  /* Contention Detection on Data Lanes OFF */
2633 2634 2635
  hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_CDOFFDL;
  hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 14U);

2636 2637
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
2638

2639 2640 2641 2642 2643 2644 2645 2646
  return HAL_OK;
}

/**
  * @}
  */

/** @defgroup DSI_Group4 Peripheral State and Errors functions
2647 2648 2649
  *  @brief    Peripheral State and Errors functions
  *
@verbatim
2650 2651
 ===============================================================================
                  ##### Peripheral State and Errors functions #####
2652
 ===============================================================================
2653 2654 2655
    [..]
    This subsection provides functions allowing to
      (+) Check the DSI state.
2656
      (+) Get error code.
2657 2658 2659

@endverbatim
  * @{
2660
  */
2661 2662 2663

/**
  * @brief  Return the DSI state
2664
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2665 2666 2667 2668 2669 2670 2671 2672
  *               the configuration information for the DSI.
  * @retval HAL state
  */
HAL_DSI_StateTypeDef HAL_DSI_GetState(DSI_HandleTypeDef *hdsi)
{
  return hdsi->State;
}

2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684
/**
  * @brief  Return the DSI error code
  * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @retval DSI Error Code
  */
uint32_t HAL_DSI_GetError(DSI_HandleTypeDef *hdsi)
{
  /* Get the error code */
  return hdsi->ErrorCode;
}

2685 2686 2687 2688 2689 2690 2691
/**
  * @}
  */

/**
  * @}
  */
2692

2693 2694 2695 2696
/**
  * @}
  */

2697 2698 2699 2700
#endif /* DSI */

#endif /* HAL_DSI_MODULE_ENABLED */

2701 2702 2703 2704 2705
/**
  * @}
  */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/