1 /**
2 ******************************************************************************
3 * @file stm32l4xx_hal_dsi.c
4 * @author MCD Application Team
5 * @brief DSI HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the DSI peripheral:
8 * + Initialization and de-initialization functions
9 * + IO operation functions
10 * + Peripheral Control functions
11 * + Peripheral State and Errors functions
12 ******************************************************************************
13 * @attention
14 *
15 * Copyright (c) 2017 STMicroelectronics.
16 * All rights reserved.
17 *
18 * This software is licensed under terms that can be found in the LICENSE file
19 * in the root directory of this software component.
20 * If no LICENSE file comes with this software, it is provided AS-IS.
21 *
22 ******************************************************************************
23 @verbatim
24 ==============================================================================
25 ##### How to use this driver #####
26 ==============================================================================
27 [..]
28 The DSI HAL driver can be used as follows:
29
30 (#) Declare a DSI_HandleTypeDef handle structure, for example: DSI_HandleTypeDef hdsi;
31
32 (#) Initialize the DSI low level resources by implementing the HAL_DSI_MspInit() API:
33 (##) Enable the DSI interface clock
34 (##) NVIC configuration if you need to use interrupt process
35 (+++) Configure the DSI interrupt priority
36 (+++) Enable the NVIC DSI IRQ Channel
37
38 (#) Initialize the DSI Host peripheral, the required PLL parameters, number of lances and
39 TX Escape clock divider by calling the HAL_DSI_Init() API which calls HAL_DSI_MspInit().
40
41 *** Configuration ***
42 =========================
43 [..]
44 (#) Use HAL_DSI_ConfigAdaptedCommandMode() function to configure the DSI host in adapted
45 command mode.
46
47 (#) When operating in video mode , use HAL_DSI_ConfigVideoMode() to configure the DSI host.
48
49 (#) Function HAL_DSI_ConfigCommand() is used to configure the DSI commands behavior in low power mode.
50
51 (#) To configure the DSI PHY timings parameters, use function HAL_DSI_ConfigPhyTimer().
52
53 (#) The DSI Host can be started/stopped using respectively functions HAL_DSI_Start() and HAL_DSI_Stop().
54 Functions HAL_DSI_ShortWrite(), HAL_DSI_LongWrite() and HAL_DSI_Read() allows respectively
55 to write DSI short packets, long packets and to read DSI packets.
56
57 (#) The DSI Host Offers two Low power modes :
58 (++) Low Power Mode on data lanes only: Only DSI data lanes are shut down.
59 It is possible to enter/exit from this mode using respectively functions HAL_DSI_EnterULPMData()
60 and HAL_DSI_ExitULPMData()
61
62 (++) Low Power Mode on data and clock lanes : All DSI lanes are shut down including data and clock lanes.
63 It is possible to enter/exit from this mode using respectively functions HAL_DSI_EnterULPM()
64 and HAL_DSI_ExitULPM()
65
66 (#) To control DSI state you can use the following function: HAL_DSI_GetState()
67
68 *** Error management ***
69 ========================
70 [..]
71 (#) User can select the DSI errors to be reported/monitored using function HAL_DSI_ConfigErrorMonitor()
72 When an error occurs, the callback HAL_DSI_ErrorCallback() is asserted and then user can retrieve
73 the error code by calling function HAL_DSI_GetError()
74
75 *** DSI HAL driver macros list ***
76 =============================================
77 [..]
78 Below the list of most used macros in DSI HAL driver.
79
80 (+) __HAL_DSI_ENABLE: Enable the DSI Host.
81 (+) __HAL_DSI_DISABLE: Disable the DSI Host.
82 (+) __HAL_DSI_WRAPPER_ENABLE: Enables the DSI wrapper.
83 (+) __HAL_DSI_WRAPPER_DISABLE: Disable the DSI wrapper.
84 (+) __HAL_DSI_PLL_ENABLE: Enables the DSI PLL.
85 (+) __HAL_DSI_PLL_DISABLE: Disables the DSI PLL.
86 (+) __HAL_DSI_REG_ENABLE: Enables the DSI regulator.
87 (+) __HAL_DSI_REG_DISABLE: Disables the DSI regulator.
88 (+) __HAL_DSI_GET_FLAG: Get the DSI pending flags.
89 (+) __HAL_DSI_CLEAR_FLAG: Clears the DSI pending flags.
90 (+) __HAL_DSI_ENABLE_IT: Enables the specified DSI interrupts.
91 (+) __HAL_DSI_DISABLE_IT: Disables the specified DSI interrupts.
92 (+) __HAL_DSI_GET_IT_SOURCE: Checks whether the specified DSI interrupt source is enabled or not.
93
94 [..]
95 (@) You can refer to the DSI HAL driver header file for more useful macros
96
97 *** Callback registration ***
98 =============================================
99 [..]
100 The compilation define USE_HAL_DSI_REGISTER_CALLBACKS when set to 1
101 allows the user to configure dynamically the driver callbacks.
102 Use Function HAL_DSI_RegisterCallback() to register a callback.
103
104 [..]
105 Function HAL_DSI_RegisterCallback() allows to register following callbacks:
106 (+) TearingEffectCallback : DSI Tearing Effect Callback.
107 (+) EndOfRefreshCallback : DSI End Of Refresh Callback.
108 (+) ErrorCallback : DSI Error Callback
109 (+) MspInitCallback : DSI MspInit.
110 (+) MspDeInitCallback : DSI MspDeInit.
111 [..]
112 This function takes as parameters the HAL peripheral handle, the callback ID
113 and a pointer to the user callback function.
114
115 [..]
116 Use function HAL_DSI_UnRegisterCallback() to reset a callback to the default
117 weak function.
118 HAL_DSI_UnRegisterCallback takes as parameters the HAL peripheral handle,
119 and the callback ID.
120 [..]
121 This function allows to reset following callbacks:
122 (+) TearingEffectCallback : DSI Tearing Effect Callback.
123 (+) EndOfRefreshCallback : DSI End Of Refresh Callback.
124 (+) ErrorCallback : DSI Error Callback
125 (+) MspInitCallback : DSI MspInit.
126 (+) MspDeInitCallback : DSI MspDeInit.
127
128 [..]
129 By default, after the HAL_DSI_Init and when the state is HAL_DSI_STATE_RESET
130 all callbacks are set to the corresponding weak functions:
131 examples HAL_DSI_TearingEffectCallback(), HAL_DSI_EndOfRefreshCallback().
132 Exception done for MspInit and MspDeInit functions that are respectively
133 reset to the legacy weak (surcharged) functions in the HAL_DSI_Init()
134 and HAL_DSI_DeInit() only when these callbacks are null (not registered beforehand).
135 If not, MspInit or MspDeInit are not null, the HAL_DSI_Init() and HAL_DSI_DeInit()
136 keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
137
138 [..]
139 Callbacks can be registered/unregistered in HAL_DSI_STATE_READY state only.
140 Exception done MspInit/MspDeInit that can be registered/unregistered
141 in HAL_DSI_STATE_READY or HAL_DSI_STATE_RESET state,
142 thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
143 In that case first register the MspInit/MspDeInit user callbacks
144 using HAL_DSI_RegisterCallback() before calling HAL_DSI_DeInit()
145 or HAL_DSI_Init() function.
146
147 [..]
148 When The compilation define USE_HAL_DSI_REGISTER_CALLBACKS is set to 0 or
149 not defined, the callback registration feature is not available and all callbacks
150 are set to the corresponding weak functions.
151
152 @endverbatim
153 ******************************************************************************
154 */
155
156 /* Includes ------------------------------------------------------------------*/
157 #include "stm32l4xx_hal.h"
158
159 /** @addtogroup STM32L4xx_HAL_Driver
160 * @{
161 */
162
163 #ifdef HAL_DSI_MODULE_ENABLED
164
165 #if defined(DSI)
166
167 /** @addtogroup DSI
168 * @{
169 */
170
171 /* Private types -------------------------------------------------------------*/
172 /* Private defines -----------------------------------------------------------*/
173 /** @addtogroup DSI_Private_Constants
174 * @{
175 */
176 #define DSI_TIMEOUT_VALUE ((uint32_t)1000U) /* 1s */
177
178 #define DSI_ERROR_ACK_MASK (DSI_ISR0_AE0 | DSI_ISR0_AE1 | DSI_ISR0_AE2 | DSI_ISR0_AE3 | \
179 DSI_ISR0_AE4 | DSI_ISR0_AE5 | DSI_ISR0_AE6 | DSI_ISR0_AE7 | \
180 DSI_ISR0_AE8 | DSI_ISR0_AE9 | DSI_ISR0_AE10 | DSI_ISR0_AE11 | \
181 DSI_ISR0_AE12 | DSI_ISR0_AE13 | DSI_ISR0_AE14 | DSI_ISR0_AE15)
182 #define DSI_ERROR_PHY_MASK (DSI_ISR0_PE0 | DSI_ISR0_PE1 | DSI_ISR0_PE2 | DSI_ISR0_PE3 | DSI_ISR0_PE4)
183 #define DSI_ERROR_TX_MASK DSI_ISR1_TOHSTX
184 #define DSI_ERROR_RX_MASK DSI_ISR1_TOLPRX
185 #define DSI_ERROR_ECC_MASK (DSI_ISR1_ECCSE | DSI_ISR1_ECCME)
186 #define DSI_ERROR_CRC_MASK DSI_ISR1_CRCE
187 #define DSI_ERROR_PSE_MASK DSI_ISR1_PSE
188 #define DSI_ERROR_EOT_MASK DSI_ISR1_EOTPE
189 #define DSI_ERROR_OVF_MASK DSI_ISR1_LPWRE
190 #define DSI_ERROR_GEN_MASK (DSI_ISR1_GCWRE | DSI_ISR1_GPWRE | DSI_ISR1_GPTXE | DSI_ISR1_GPRDE | DSI_ISR1_GPRXE)
191 /**
192 * @}
193 */
194
195 /* Private variables ---------------------------------------------------------*/
196 /* Private constants ---------------------------------------------------------*/
197 /* Private macros ------------------------------------------------------------*/
198 /* Private function prototypes -----------------------------------------------*/
199 static void DSI_ConfigPacketHeader(DSI_TypeDef *DSIx, uint32_t ChannelID, uint32_t DataType, uint32_t Data0,
200 uint32_t Data1);
201
202 static HAL_StatusTypeDef DSI_ShortWrite(DSI_HandleTypeDef *hdsi,
203 uint32_t ChannelID,
204 uint32_t Mode,
205 uint32_t Param1,
206 uint32_t Param2);
207 /* Private functions ---------------------------------------------------------*/
208 /** @defgroup DSI_Private_Functions DSI Private Functions
209 * @{
210 */
211 /**
212 * @brief Generic DSI packet header configuration
213 * @param DSIx Pointer to DSI register base
214 * @param ChannelID Virtual channel ID of the header packet
215 * @param DataType Packet data type of the header packet
216 * This parameter can be any value of :
217 * @arg DSI_SHORT_WRITE_PKT_Data_Type
218 * @arg DSI_LONG_WRITE_PKT_Data_Type
219 * @arg DSI_SHORT_READ_PKT_Data_Type
220 * @arg DSI_MAX_RETURN_PKT_SIZE
221 * @param Data0 Word count LSB
222 * @param Data1 Word count MSB
223 * @retval None
224 */
DSI_ConfigPacketHeader(DSI_TypeDef * DSIx,uint32_t ChannelID,uint32_t DataType,uint32_t Data0,uint32_t Data1)225 static void DSI_ConfigPacketHeader(DSI_TypeDef *DSIx,
226 uint32_t ChannelID,
227 uint32_t DataType,
228 uint32_t Data0,
229 uint32_t Data1)
230 {
231 /* Update the DSI packet header with new information */
232 DSIx->GHCR = (DataType | (ChannelID << 6U) | (Data0 << 8U) | (Data1 << 16U));
233 }
234
235 /**
236 * @brief write short DCS or short Generic command
237 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
238 * the configuration information for the DSI.
239 * @param ChannelID Virtual channel ID.
240 * @param Mode DSI short packet data type.
241 * This parameter can be any value of @arg DSI_SHORT_WRITE_PKT_Data_Type.
242 * @param Param1 DSC command or first generic parameter.
243 * This parameter can be any value of @arg DSI_DCS_Command or a
244 * generic command code.
245 * @param Param2 DSC parameter or second generic parameter.
246 * @retval HAL status
247 */
DSI_ShortWrite(DSI_HandleTypeDef * hdsi,uint32_t ChannelID,uint32_t Mode,uint32_t Param1,uint32_t Param2)248 static HAL_StatusTypeDef DSI_ShortWrite(DSI_HandleTypeDef *hdsi,
249 uint32_t ChannelID,
250 uint32_t Mode,
251 uint32_t Param1,
252 uint32_t Param2)
253 {
254 uint32_t tickstart;
255
256 /* Get tick */
257 tickstart = HAL_GetTick();
258
259 /* Wait for Command FIFO Empty */
260 while ((hdsi->Instance->GPSR & DSI_GPSR_CMDFE) == 0U)
261 {
262 /* Check for the Timeout */
263 if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
264 {
265 return HAL_TIMEOUT;
266 }
267 }
268
269 /* Configure the packet to send a short DCS command with 0 or 1 parameter */
270 /* Update the DSI packet header with new information */
271 hdsi->Instance->GHCR = (Mode | (ChannelID << 6U) | (Param1 << 8U) | (Param2 << 16U));
272
273 return HAL_OK;
274 }
275
276 /**
277 * @}
278 */
279
280 /* Exported functions --------------------------------------------------------*/
281 /** @addtogroup DSI_Exported_Functions
282 * @{
283 */
284
285 /** @defgroup DSI_Group1 Initialization and Configuration functions
286 * @brief Initialization and Configuration functions
287 *
288 @verbatim
289 ===============================================================================
290 ##### Initialization and Configuration functions #####
291 ===============================================================================
292 [..] This section provides functions allowing to:
293 (+) Initialize and configure the DSI
294 (+) De-initialize the DSI
295
296 @endverbatim
297 * @{
298 */
299
300 /**
301 * @brief Initializes the DSI according to the specified
302 * parameters in the DSI_InitTypeDef and create the associated handle.
303 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
304 * the configuration information for the DSI.
305 * @param PLLInit pointer to a DSI_PLLInitTypeDef structure that contains
306 * the PLL Clock structure definition for the DSI.
307 * @retval HAL status
308 */
HAL_DSI_Init(DSI_HandleTypeDef * hdsi,DSI_PLLInitTypeDef * PLLInit)309 HAL_StatusTypeDef HAL_DSI_Init(DSI_HandleTypeDef *hdsi, DSI_PLLInitTypeDef *PLLInit)
310 {
311 uint32_t tickstart;
312 uint32_t unitIntervalx4;
313 uint32_t tempIDF;
314
315 /* Check the DSI handle allocation */
316 if (hdsi == NULL)
317 {
318 return HAL_ERROR;
319 }
320
321 /* Check function parameters */
322 assert_param(IS_DSI_PLL_NDIV(PLLInit->PLLNDIV));
323 assert_param(IS_DSI_PLL_IDF(PLLInit->PLLIDF));
324 assert_param(IS_DSI_PLL_ODF(PLLInit->PLLODF));
325 assert_param(IS_DSI_AUTO_CLKLANE_CONTROL(hdsi->Init.AutomaticClockLaneControl));
326 assert_param(IS_DSI_NUMBER_OF_LANES(hdsi->Init.NumberOfLanes));
327
328 #if (USE_HAL_DSI_REGISTER_CALLBACKS == 1)
329 if (hdsi->State == HAL_DSI_STATE_RESET)
330 {
331 /* Reset the DSI callback to the legacy weak callbacks */
332 hdsi->TearingEffectCallback = HAL_DSI_TearingEffectCallback; /* Legacy weak TearingEffectCallback */
333 hdsi->EndOfRefreshCallback = HAL_DSI_EndOfRefreshCallback; /* Legacy weak EndOfRefreshCallback */
334 hdsi->ErrorCallback = HAL_DSI_ErrorCallback; /* Legacy weak ErrorCallback */
335
336 if (hdsi->MspInitCallback == NULL)
337 {
338 hdsi->MspInitCallback = HAL_DSI_MspInit;
339 }
340 /* Initialize the low level hardware */
341 hdsi->MspInitCallback(hdsi);
342 }
343 #else
344 if (hdsi->State == HAL_DSI_STATE_RESET)
345 {
346 /* Initialize the low level hardware */
347 HAL_DSI_MspInit(hdsi);
348 }
349 #endif /* USE_HAL_DSI_REGISTER_CALLBACKS */
350
351 /* Change DSI peripheral state */
352 hdsi->State = HAL_DSI_STATE_BUSY;
353
354 /**************** Turn on the regulator and enable the DSI PLL ****************/
355
356 /* Enable the regulator */
357 __HAL_DSI_REG_ENABLE(hdsi);
358
359 /* Get tick */
360 tickstart = HAL_GetTick();
361
362 /* Wait until the regulator is ready */
363 while (__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_RRS) == 0U)
364 {
365 /* Check for the Timeout */
366 if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
367 {
368 return HAL_TIMEOUT;
369 }
370 }
371
372 /* Set the PLL division factors */
373 hdsi->Instance->WRPCR &= ~(DSI_WRPCR_PLL_NDIV | DSI_WRPCR_PLL_IDF | DSI_WRPCR_PLL_ODF);
374 hdsi->Instance->WRPCR |= (((PLLInit->PLLNDIV) << DSI_WRPCR_PLL_NDIV_Pos) | \
375 ((PLLInit->PLLIDF) << DSI_WRPCR_PLL_IDF_Pos) | \
376 ((PLLInit->PLLODF) << DSI_WRPCR_PLL_ODF_Pos));
377
378 /* Enable the DSI PLL */
379 __HAL_DSI_PLL_ENABLE(hdsi);
380
381 /* Requires min of 400us delay before reading the PLLLS flag */
382 /* 1ms delay is inserted that is the minimum HAL delay granularity */
383 HAL_Delay(1);
384
385 /* Get tick */
386 tickstart = HAL_GetTick();
387
388 /* Wait for the lock of the PLL */
389 while (__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_PLLLS) == 0U)
390 {
391 /* Check for the Timeout */
392 if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
393 {
394 return HAL_TIMEOUT;
395 }
396 }
397
398 /*************************** Set the PHY parameters ***************************/
399
400 /* D-PHY clock and digital enable*/
401 hdsi->Instance->PCTLR |= (DSI_PCTLR_CKE | DSI_PCTLR_DEN);
402
403 /* Clock lane configuration */
404 hdsi->Instance->CLCR &= ~(DSI_CLCR_DPCC | DSI_CLCR_ACR);
405 hdsi->Instance->CLCR |= (DSI_CLCR_DPCC | hdsi->Init.AutomaticClockLaneControl);
406
407 /* Configure the number of active data lanes */
408 hdsi->Instance->PCONFR &= ~DSI_PCONFR_NL;
409 hdsi->Instance->PCONFR |= hdsi->Init.NumberOfLanes;
410
411 /************************ Set the DSI clock parameters ************************/
412
413 /* Set the TX escape clock division factor */
414 hdsi->Instance->CCR &= ~DSI_CCR_TXECKDIV;
415 hdsi->Instance->CCR |= hdsi->Init.TXEscapeCkdiv;
416
417 /* Calculate the bit period in high-speed mode in unit of 0.25 ns (UIX4) */
418 /* The equation is : UIX4 = IntegerPart( (1000/F_PHY_Mhz) * 4 ) */
419 /* Where : F_PHY_Mhz = (NDIV * HSE_Mhz) / (IDF * ODF) */
420 tempIDF = (PLLInit->PLLIDF > 0U) ? PLLInit->PLLIDF : 1U;
421 unitIntervalx4 = (4000000U * tempIDF * ((1UL << (0x3U & PLLInit->PLLODF)))) / ((HSE_VALUE / 1000U) * PLLInit->PLLNDIV);
422
423 /* Set the bit period in high-speed mode */
424 hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_UIX4;
425 hdsi->Instance->WPCR[0U] |= unitIntervalx4;
426
427 /****************************** Error management *****************************/
428
429 /* Disable all error interrupts and reset the Error Mask */
430 hdsi->Instance->IER[0U] = 0U;
431 hdsi->Instance->IER[1U] = 0U;
432 hdsi->ErrorMsk = 0U;
433
434 /* Initialize the error code */
435 hdsi->ErrorCode = HAL_DSI_ERROR_NONE;
436
437 /* Initialize the DSI state*/
438 hdsi->State = HAL_DSI_STATE_READY;
439
440 return HAL_OK;
441 }
442
443 /**
444 * @brief De-initializes the DSI peripheral registers to their default reset
445 * values.
446 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
447 * the configuration information for the DSI.
448 * @retval HAL status
449 */
HAL_DSI_DeInit(DSI_HandleTypeDef * hdsi)450 HAL_StatusTypeDef HAL_DSI_DeInit(DSI_HandleTypeDef *hdsi)
451 {
452 /* Check the DSI handle allocation */
453 if (hdsi == NULL)
454 {
455 return HAL_ERROR;
456 }
457
458 /* Change DSI peripheral state */
459 hdsi->State = HAL_DSI_STATE_BUSY;
460
461 /* Disable the DSI wrapper */
462 __HAL_DSI_WRAPPER_DISABLE(hdsi);
463
464 /* Disable the DSI host */
465 __HAL_DSI_DISABLE(hdsi);
466
467 /* D-PHY clock and digital disable */
468 hdsi->Instance->PCTLR &= ~(DSI_PCTLR_CKE | DSI_PCTLR_DEN);
469
470 /* Turn off the DSI PLL */
471 __HAL_DSI_PLL_DISABLE(hdsi);
472
473 /* Disable the regulator */
474 __HAL_DSI_REG_DISABLE(hdsi);
475
476 #if (USE_HAL_DSI_REGISTER_CALLBACKS == 1)
477 if (hdsi->MspDeInitCallback == NULL)
478 {
479 hdsi->MspDeInitCallback = HAL_DSI_MspDeInit;
480 }
481 /* DeInit the low level hardware */
482 hdsi->MspDeInitCallback(hdsi);
483 #else
484 /* DeInit the low level hardware */
485 HAL_DSI_MspDeInit(hdsi);
486 #endif /* USE_HAL_DSI_REGISTER_CALLBACKS */
487
488 /* Initialize the error code */
489 hdsi->ErrorCode = HAL_DSI_ERROR_NONE;
490
491 /* Initialize the DSI state*/
492 hdsi->State = HAL_DSI_STATE_RESET;
493
494 /* Release Lock */
495 __HAL_UNLOCK(hdsi);
496
497 return HAL_OK;
498 }
499
500 /**
501 * @brief Enable the error monitor flags
502 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
503 * the configuration information for the DSI.
504 * @param ActiveErrors indicates which error interrupts will be enabled.
505 * This parameter can be any combination of @arg DSI_Error_Data_Type.
506 * @retval HAL status
507 */
HAL_DSI_ConfigErrorMonitor(DSI_HandleTypeDef * hdsi,uint32_t ActiveErrors)508 HAL_StatusTypeDef HAL_DSI_ConfigErrorMonitor(DSI_HandleTypeDef *hdsi, uint32_t ActiveErrors)
509 {
510 /* Process locked */
511 __HAL_LOCK(hdsi);
512
513 hdsi->Instance->IER[0U] = 0U;
514 hdsi->Instance->IER[1U] = 0U;
515
516 /* Store active errors to the handle */
517 hdsi->ErrorMsk = ActiveErrors;
518
519 if ((ActiveErrors & HAL_DSI_ERROR_ACK) != 0U)
520 {
521 /* Enable the interrupt generation on selected errors */
522 hdsi->Instance->IER[0U] |= DSI_ERROR_ACK_MASK;
523 }
524
525 if ((ActiveErrors & HAL_DSI_ERROR_PHY) != 0U)
526 {
527 /* Enable the interrupt generation on selected errors */
528 hdsi->Instance->IER[0U] |= DSI_ERROR_PHY_MASK;
529 }
530
531 if ((ActiveErrors & HAL_DSI_ERROR_TX) != 0U)
532 {
533 /* Enable the interrupt generation on selected errors */
534 hdsi->Instance->IER[1U] |= DSI_ERROR_TX_MASK;
535 }
536
537 if ((ActiveErrors & HAL_DSI_ERROR_RX) != 0U)
538 {
539 /* Enable the interrupt generation on selected errors */
540 hdsi->Instance->IER[1U] |= DSI_ERROR_RX_MASK;
541 }
542
543 if ((ActiveErrors & HAL_DSI_ERROR_ECC) != 0U)
544 {
545 /* Enable the interrupt generation on selected errors */
546 hdsi->Instance->IER[1U] |= DSI_ERROR_ECC_MASK;
547 }
548
549 if ((ActiveErrors & HAL_DSI_ERROR_CRC) != 0U)
550 {
551 /* Enable the interrupt generation on selected errors */
552 hdsi->Instance->IER[1U] |= DSI_ERROR_CRC_MASK;
553 }
554
555 if ((ActiveErrors & HAL_DSI_ERROR_PSE) != 0U)
556 {
557 /* Enable the interrupt generation on selected errors */
558 hdsi->Instance->IER[1U] |= DSI_ERROR_PSE_MASK;
559 }
560
561 if ((ActiveErrors & HAL_DSI_ERROR_EOT) != 0U)
562 {
563 /* Enable the interrupt generation on selected errors */
564 hdsi->Instance->IER[1U] |= DSI_ERROR_EOT_MASK;
565 }
566
567 if ((ActiveErrors & HAL_DSI_ERROR_OVF) != 0U)
568 {
569 /* Enable the interrupt generation on selected errors */
570 hdsi->Instance->IER[1U] |= DSI_ERROR_OVF_MASK;
571 }
572
573 if ((ActiveErrors & HAL_DSI_ERROR_GEN) != 0U)
574 {
575 /* Enable the interrupt generation on selected errors */
576 hdsi->Instance->IER[1U] |= DSI_ERROR_GEN_MASK;
577 }
578
579 /* Process Unlocked */
580 __HAL_UNLOCK(hdsi);
581
582 return HAL_OK;
583 }
584
585 /**
586 * @brief Initializes the DSI MSP.
587 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
588 * the configuration information for the DSI.
589 * @retval None
590 */
HAL_DSI_MspInit(DSI_HandleTypeDef * hdsi)591 __weak void HAL_DSI_MspInit(DSI_HandleTypeDef *hdsi)
592 {
593 /* Prevent unused argument(s) compilation warning */
594 UNUSED(hdsi);
595 /* NOTE : This function Should not be modified, when the callback is needed,
596 the HAL_DSI_MspInit could be implemented in the user file
597 */
598 }
599
600 /**
601 * @brief De-initializes the DSI MSP.
602 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
603 * the configuration information for the DSI.
604 * @retval None
605 */
HAL_DSI_MspDeInit(DSI_HandleTypeDef * hdsi)606 __weak void HAL_DSI_MspDeInit(DSI_HandleTypeDef *hdsi)
607 {
608 /* Prevent unused argument(s) compilation warning */
609 UNUSED(hdsi);
610 /* NOTE : This function Should not be modified, when the callback is needed,
611 the HAL_DSI_MspDeInit could be implemented in the user file
612 */
613 }
614
615 #if (USE_HAL_DSI_REGISTER_CALLBACKS == 1)
616 /**
617 * @brief Register a User DSI Callback
618 * To be used instead of the weak predefined callback
619 * @param hdsi dsi handle
620 * @param CallbackID ID of the callback to be registered
621 * This parameter can be one of the following values:
622 * @arg HAL_DSI_TEARING_EFFECT_CB_ID Tearing Effect Callback ID
623 * @arg HAL_DSI_ENDOF_REFRESH_CB_ID End Of Refresh Callback ID
624 * @arg HAL_DSI_ERROR_CB_ID Error Callback ID
625 * @arg HAL_DSI_MSPINIT_CB_ID MspInit callback ID
626 * @arg HAL_DSI_MSPDEINIT_CB_ID MspDeInit callback ID
627 * @param pCallback pointer to the Callback function
628 * @retval status
629 */
HAL_DSI_RegisterCallback(DSI_HandleTypeDef * hdsi,HAL_DSI_CallbackIDTypeDef CallbackID,pDSI_CallbackTypeDef pCallback)630 HAL_StatusTypeDef HAL_DSI_RegisterCallback(DSI_HandleTypeDef *hdsi, HAL_DSI_CallbackIDTypeDef CallbackID,
631 pDSI_CallbackTypeDef pCallback)
632 {
633 HAL_StatusTypeDef status = HAL_OK;
634
635 if (pCallback == NULL)
636 {
637 /* Update the error code */
638 hdsi->ErrorCode |= HAL_DSI_ERROR_INVALID_CALLBACK;
639
640 return HAL_ERROR;
641 }
642 /* Process locked */
643 __HAL_LOCK(hdsi);
644
645 if (hdsi->State == HAL_DSI_STATE_READY)
646 {
647 switch (CallbackID)
648 {
649 case HAL_DSI_TEARING_EFFECT_CB_ID :
650 hdsi->TearingEffectCallback = pCallback;
651 break;
652
653 case HAL_DSI_ENDOF_REFRESH_CB_ID :
654 hdsi->EndOfRefreshCallback = pCallback;
655 break;
656
657 case HAL_DSI_ERROR_CB_ID :
658 hdsi->ErrorCallback = pCallback;
659 break;
660
661 case HAL_DSI_MSPINIT_CB_ID :
662 hdsi->MspInitCallback = pCallback;
663 break;
664
665 case HAL_DSI_MSPDEINIT_CB_ID :
666 hdsi->MspDeInitCallback = pCallback;
667 break;
668
669 default :
670 /* Update the error code */
671 hdsi->ErrorCode |= HAL_DSI_ERROR_INVALID_CALLBACK;
672 /* Return error status */
673 status = HAL_ERROR;
674 break;
675 }
676 }
677 else if (hdsi->State == HAL_DSI_STATE_RESET)
678 {
679 switch (CallbackID)
680 {
681 case HAL_DSI_MSPINIT_CB_ID :
682 hdsi->MspInitCallback = pCallback;
683 break;
684
685 case HAL_DSI_MSPDEINIT_CB_ID :
686 hdsi->MspDeInitCallback = pCallback;
687 break;
688
689 default :
690 /* Update the error code */
691 hdsi->ErrorCode |= HAL_DSI_ERROR_INVALID_CALLBACK;
692 /* Return error status */
693 status = HAL_ERROR;
694 break;
695 }
696 }
697 else
698 {
699 /* Update the error code */
700 hdsi->ErrorCode |= HAL_DSI_ERROR_INVALID_CALLBACK;
701 /* Return error status */
702 status = HAL_ERROR;
703 }
704
705 /* Release Lock */
706 __HAL_UNLOCK(hdsi);
707
708 return status;
709 }
710
711 /**
712 * @brief Unregister a DSI Callback
713 * DSI callback is redirected to the weak predefined callback
714 * @param hdsi dsi handle
715 * @param CallbackID ID of the callback to be unregistered
716 * This parameter can be one of the following values:
717 * @arg HAL_DSI_TEARING_EFFECT_CB_ID Tearing Effect Callback ID
718 * @arg HAL_DSI_ENDOF_REFRESH_CB_ID End Of Refresh Callback ID
719 * @arg HAL_DSI_ERROR_CB_ID Error Callback ID
720 * @arg HAL_DSI_MSPINIT_CB_ID MspInit callback ID
721 * @arg HAL_DSI_MSPDEINIT_CB_ID MspDeInit callback ID
722 * @retval status
723 */
HAL_DSI_UnRegisterCallback(DSI_HandleTypeDef * hdsi,HAL_DSI_CallbackIDTypeDef CallbackID)724 HAL_StatusTypeDef HAL_DSI_UnRegisterCallback(DSI_HandleTypeDef *hdsi, HAL_DSI_CallbackIDTypeDef CallbackID)
725 {
726 HAL_StatusTypeDef status = HAL_OK;
727
728 /* Process locked */
729 __HAL_LOCK(hdsi);
730
731 if (hdsi->State == HAL_DSI_STATE_READY)
732 {
733 switch (CallbackID)
734 {
735 case HAL_DSI_TEARING_EFFECT_CB_ID :
736 hdsi->TearingEffectCallback = HAL_DSI_TearingEffectCallback; /* Legacy weak TearingEffectCallback */
737 break;
738
739 case HAL_DSI_ENDOF_REFRESH_CB_ID :
740 hdsi->EndOfRefreshCallback = HAL_DSI_EndOfRefreshCallback; /* Legacy weak EndOfRefreshCallback */
741 break;
742
743 case HAL_DSI_ERROR_CB_ID :
744 hdsi->ErrorCallback = HAL_DSI_ErrorCallback; /* Legacy weak ErrorCallback */
745 break;
746
747 case HAL_DSI_MSPINIT_CB_ID :
748 hdsi->MspInitCallback = HAL_DSI_MspInit; /* Legacy weak MspInit Callback */
749 break;
750
751 case HAL_DSI_MSPDEINIT_CB_ID :
752 hdsi->MspDeInitCallback = HAL_DSI_MspDeInit; /* Legacy weak MspDeInit Callback */
753 break;
754
755 default :
756 /* Update the error code */
757 hdsi->ErrorCode |= HAL_DSI_ERROR_INVALID_CALLBACK;
758 /* Return error status */
759 status = HAL_ERROR;
760 break;
761 }
762 }
763 else if (hdsi->State == HAL_DSI_STATE_RESET)
764 {
765 switch (CallbackID)
766 {
767 case HAL_DSI_MSPINIT_CB_ID :
768 hdsi->MspInitCallback = HAL_DSI_MspInit; /* Legacy weak MspInit Callback */
769 break;
770
771 case HAL_DSI_MSPDEINIT_CB_ID :
772 hdsi->MspDeInitCallback = HAL_DSI_MspDeInit; /* Legacy weak MspDeInit Callback */
773 break;
774
775 default :
776 /* Update the error code */
777 hdsi->ErrorCode |= HAL_DSI_ERROR_INVALID_CALLBACK;
778 /* Return error status */
779 status = HAL_ERROR;
780 break;
781 }
782 }
783 else
784 {
785 /* Update the error code */
786 hdsi->ErrorCode |= HAL_DSI_ERROR_INVALID_CALLBACK;
787 /* Return error status */
788 status = HAL_ERROR;
789 }
790
791 /* Release Lock */
792 __HAL_UNLOCK(hdsi);
793
794 return status;
795 }
796 #endif /* USE_HAL_DSI_REGISTER_CALLBACKS */
797
798 /**
799 * @}
800 */
801
802 /** @defgroup DSI_Group2 IO operation functions
803 * @brief IO operation functions
804 *
805 @verbatim
806 ===============================================================================
807 ##### IO operation functions #####
808 ===============================================================================
809 [..] This section provides function allowing to:
810 (+) Handle DSI interrupt request
811
812 @endverbatim
813 * @{
814 */
815 /**
816 * @brief Handles DSI interrupt request.
817 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
818 * the configuration information for the DSI.
819 * @retval HAL status
820 */
HAL_DSI_IRQHandler(DSI_HandleTypeDef * hdsi)821 void HAL_DSI_IRQHandler(DSI_HandleTypeDef *hdsi)
822 {
823 uint32_t ErrorStatus0;
824 uint32_t ErrorStatus1;
825
826 /* Tearing Effect Interrupt management ***************************************/
827 if (__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_TE) != 0U)
828 {
829 if (__HAL_DSI_GET_IT_SOURCE(hdsi, DSI_IT_TE) != 0U)
830 {
831 /* Clear the Tearing Effect Interrupt Flag */
832 __HAL_DSI_CLEAR_FLAG(hdsi, DSI_FLAG_TE);
833
834 /* Tearing Effect Callback */
835 #if (USE_HAL_DSI_REGISTER_CALLBACKS == 1)
836 /*Call registered Tearing Effect callback */
837 hdsi->TearingEffectCallback(hdsi);
838 #else
839 /*Call legacy Tearing Effect callback*/
840 HAL_DSI_TearingEffectCallback(hdsi);
841 #endif /* USE_HAL_DSI_REGISTER_CALLBACKS */
842 }
843 }
844
845 /* End of Refresh Interrupt management ***************************************/
846 if (__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_ER) != 0U)
847 {
848 if (__HAL_DSI_GET_IT_SOURCE(hdsi, DSI_IT_ER) != 0U)
849 {
850 /* Clear the End of Refresh Interrupt Flag */
851 __HAL_DSI_CLEAR_FLAG(hdsi, DSI_FLAG_ER);
852
853 /* End of Refresh Callback */
854 #if (USE_HAL_DSI_REGISTER_CALLBACKS == 1)
855 /*Call registered End of refresh callback */
856 hdsi->EndOfRefreshCallback(hdsi);
857 #else
858 /*Call Legacy End of refresh callback */
859 HAL_DSI_EndOfRefreshCallback(hdsi);
860 #endif /* USE_HAL_DSI_REGISTER_CALLBACKS */
861 }
862 }
863
864 /* Error Interrupts management ***********************************************/
865 if (hdsi->ErrorMsk != 0U)
866 {
867 ErrorStatus0 = hdsi->Instance->ISR[0U];
868 ErrorStatus0 &= hdsi->Instance->IER[0U];
869 ErrorStatus1 = hdsi->Instance->ISR[1U];
870 ErrorStatus1 &= hdsi->Instance->IER[1U];
871
872 if ((ErrorStatus0 & DSI_ERROR_ACK_MASK) != 0U)
873 {
874 hdsi->ErrorCode |= HAL_DSI_ERROR_ACK;
875 }
876
877 if ((ErrorStatus0 & DSI_ERROR_PHY_MASK) != 0U)
878 {
879 hdsi->ErrorCode |= HAL_DSI_ERROR_PHY;
880 }
881
882 if ((ErrorStatus1 & DSI_ERROR_TX_MASK) != 0U)
883 {
884 hdsi->ErrorCode |= HAL_DSI_ERROR_TX;
885 }
886
887 if ((ErrorStatus1 & DSI_ERROR_RX_MASK) != 0U)
888 {
889 hdsi->ErrorCode |= HAL_DSI_ERROR_RX;
890 }
891
892 if ((ErrorStatus1 & DSI_ERROR_ECC_MASK) != 0U)
893 {
894 hdsi->ErrorCode |= HAL_DSI_ERROR_ECC;
895 }
896
897 if ((ErrorStatus1 & DSI_ERROR_CRC_MASK) != 0U)
898 {
899 hdsi->ErrorCode |= HAL_DSI_ERROR_CRC;
900 }
901
902 if ((ErrorStatus1 & DSI_ERROR_PSE_MASK) != 0U)
903 {
904 hdsi->ErrorCode |= HAL_DSI_ERROR_PSE;
905 }
906
907 if ((ErrorStatus1 & DSI_ERROR_EOT_MASK) != 0U)
908 {
909 hdsi->ErrorCode |= HAL_DSI_ERROR_EOT;
910 }
911
912 if ((ErrorStatus1 & DSI_ERROR_OVF_MASK) != 0U)
913 {
914 hdsi->ErrorCode |= HAL_DSI_ERROR_OVF;
915 }
916
917 if ((ErrorStatus1 & DSI_ERROR_GEN_MASK) != 0U)
918 {
919 hdsi->ErrorCode |= HAL_DSI_ERROR_GEN;
920 }
921
922 /* Check only selected errors */
923 if (hdsi->ErrorCode != HAL_DSI_ERROR_NONE)
924 {
925 /* DSI error interrupt callback */
926 #if (USE_HAL_DSI_REGISTER_CALLBACKS == 1)
927 /*Call registered Error callback */
928 hdsi->ErrorCallback(hdsi);
929 #else
930 /*Call Legacy Error callback */
931 HAL_DSI_ErrorCallback(hdsi);
932 #endif /* USE_HAL_DSI_REGISTER_CALLBACKS */
933 }
934 }
935 }
936
937 /**
938 * @brief Tearing Effect DSI callback.
939 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
940 * the configuration information for the DSI.
941 * @retval None
942 */
HAL_DSI_TearingEffectCallback(DSI_HandleTypeDef * hdsi)943 __weak void HAL_DSI_TearingEffectCallback(DSI_HandleTypeDef *hdsi)
944 {
945 /* Prevent unused argument(s) compilation warning */
946 UNUSED(hdsi);
947 /* NOTE : This function Should not be modified, when the callback is needed,
948 the HAL_DSI_TearingEffectCallback could be implemented in the user file
949 */
950 }
951
952 /**
953 * @brief End of Refresh DSI callback.
954 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
955 * the configuration information for the DSI.
956 * @retval None
957 */
HAL_DSI_EndOfRefreshCallback(DSI_HandleTypeDef * hdsi)958 __weak void HAL_DSI_EndOfRefreshCallback(DSI_HandleTypeDef *hdsi)
959 {
960 /* Prevent unused argument(s) compilation warning */
961 UNUSED(hdsi);
962 /* NOTE : This function Should not be modified, when the callback is needed,
963 the HAL_DSI_EndOfRefreshCallback could be implemented in the user file
964 */
965 }
966
967 /**
968 * @brief Operation Error DSI callback.
969 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
970 * the configuration information for the DSI.
971 * @retval None
972 */
HAL_DSI_ErrorCallback(DSI_HandleTypeDef * hdsi)973 __weak void HAL_DSI_ErrorCallback(DSI_HandleTypeDef *hdsi)
974 {
975 /* Prevent unused argument(s) compilation warning */
976 UNUSED(hdsi);
977 /* NOTE : This function Should not be modified, when the callback is needed,
978 the HAL_DSI_ErrorCallback could be implemented in the user file
979 */
980 }
981
982 /**
983 * @}
984 */
985
986 /** @defgroup DSI_Group3 Peripheral Control functions
987 * @brief Peripheral Control functions
988 *
989 @verbatim
990 ===============================================================================
991 ##### Peripheral Control functions #####
992 ===============================================================================
993 [..] This section provides functions allowing to:
994 (+) Configure the Generic interface read-back Virtual Channel ID
995 (+) Select video mode and configure the corresponding parameters
996 (+) Configure command transmission mode: High-speed or Low-power
997 (+) Configure the flow control
998 (+) Configure the DSI PHY timer
999 (+) Configure the DSI HOST timeout
1000 (+) Configure the DSI HOST timeout
1001 (+) Start/Stop the DSI module
1002 (+) Refresh the display in command mode
1003 (+) Controls the display color mode in Video mode
1004 (+) Control the display shutdown in Video mode
1005 (+) write short DCS or short Generic command
1006 (+) write long DCS or long Generic command
1007 (+) Read command (DCS or generic)
1008 (+) Enter/Exit the Ultra Low Power Mode on data only (D-PHY PLL running)
1009 (+) Enter/Exit the Ultra Low Power Mode on data only and clock (D-PHY PLL turned off)
1010 (+) Start/Stop test pattern generation
1011 (+) Slew-Rate And Delay Tuning
1012 (+) Low-Power Reception Filter Tuning
1013 (+) Activate an additional current path on all lanes to meet the SDDTx parameter
1014 (+) Custom lane pins configuration
1015 (+) Set custom timing for the PHY
1016 (+) Force the Clock/Data Lane in TX Stop Mode
1017 (+) Force LP Receiver in Low-Power Mode
1018 (+) Force Data Lanes in RX Mode after a BTA
1019 (+) Enable a pull-down on the lanes to prevent from floating states when unused
1020 (+) Switch off the contention detection on data lanes
1021
1022 @endverbatim
1023 * @{
1024 */
1025
1026 /**
1027 * @brief Configure the Generic interface read-back Virtual Channel ID.
1028 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
1029 * the configuration information for the DSI.
1030 * @param VirtualChannelID Virtual channel ID
1031 * @retval HAL status
1032 */
HAL_DSI_SetGenericVCID(DSI_HandleTypeDef * hdsi,uint32_t VirtualChannelID)1033 HAL_StatusTypeDef HAL_DSI_SetGenericVCID(DSI_HandleTypeDef *hdsi, uint32_t VirtualChannelID)
1034 {
1035 /* Process locked */
1036 __HAL_LOCK(hdsi);
1037
1038 /* Update the GVCID register */
1039 hdsi->Instance->GVCIDR &= ~DSI_GVCIDR_VCID;
1040 hdsi->Instance->GVCIDR |= VirtualChannelID;
1041
1042 /* Process unlocked */
1043 __HAL_UNLOCK(hdsi);
1044
1045 return HAL_OK;
1046 }
1047
1048 /**
1049 * @brief Select video mode and configure the corresponding parameters
1050 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
1051 * the configuration information for the DSI.
1052 * @param VidCfg pointer to a DSI_VidCfgTypeDef structure that contains
1053 * the DSI video mode configuration parameters
1054 * @retval HAL status
1055 */
HAL_DSI_ConfigVideoMode(DSI_HandleTypeDef * hdsi,DSI_VidCfgTypeDef * VidCfg)1056 HAL_StatusTypeDef HAL_DSI_ConfigVideoMode(DSI_HandleTypeDef *hdsi, DSI_VidCfgTypeDef *VidCfg)
1057 {
1058 /* Process locked */
1059 __HAL_LOCK(hdsi);
1060
1061 /* Check the parameters */
1062 assert_param(IS_DSI_COLOR_CODING(VidCfg->ColorCoding));
1063 assert_param(IS_DSI_VIDEO_MODE_TYPE(VidCfg->Mode));
1064 assert_param(IS_DSI_LP_COMMAND(VidCfg->LPCommandEnable));
1065 assert_param(IS_DSI_LP_HFP(VidCfg->LPHorizontalFrontPorchEnable));
1066 assert_param(IS_DSI_LP_HBP(VidCfg->LPHorizontalBackPorchEnable));
1067 assert_param(IS_DSI_LP_VACTIVE(VidCfg->LPVerticalActiveEnable));
1068 assert_param(IS_DSI_LP_VFP(VidCfg->LPVerticalFrontPorchEnable));
1069 assert_param(IS_DSI_LP_VBP(VidCfg->LPVerticalBackPorchEnable));
1070 assert_param(IS_DSI_LP_VSYNC(VidCfg->LPVerticalSyncActiveEnable));
1071 assert_param(IS_DSI_FBTAA(VidCfg->FrameBTAAcknowledgeEnable));
1072 assert_param(IS_DSI_DE_POLARITY(VidCfg->DEPolarity));
1073 assert_param(IS_DSI_VSYNC_POLARITY(VidCfg->VSPolarity));
1074 assert_param(IS_DSI_HSYNC_POLARITY(VidCfg->HSPolarity));
1075 /* Check the LooselyPacked variant only in 18-bit mode */
1076 if (VidCfg->ColorCoding == DSI_RGB666)
1077 {
1078 assert_param(IS_DSI_LOOSELY_PACKED(VidCfg->LooselyPacked));
1079 }
1080
1081 /* Select video mode by resetting CMDM and DSIM bits */
1082 hdsi->Instance->MCR &= ~DSI_MCR_CMDM;
1083 hdsi->Instance->WCFGR &= ~DSI_WCFGR_DSIM;
1084
1085 /* Configure the video mode transmission type */
1086 hdsi->Instance->VMCR &= ~DSI_VMCR_VMT;
1087 hdsi->Instance->VMCR |= VidCfg->Mode;
1088
1089 /* Configure the video packet size */
1090 hdsi->Instance->VPCR &= ~DSI_VPCR_VPSIZE;
1091 hdsi->Instance->VPCR |= VidCfg->PacketSize;
1092
1093 /* Set the chunks number to be transmitted through the DSI link */
1094 hdsi->Instance->VCCR &= ~DSI_VCCR_NUMC;
1095 hdsi->Instance->VCCR |= VidCfg->NumberOfChunks;
1096
1097 /* Set the size of the null packet */
1098 hdsi->Instance->VNPCR &= ~DSI_VNPCR_NPSIZE;
1099 hdsi->Instance->VNPCR |= VidCfg->NullPacketSize;
1100
1101 /* Select the virtual channel for the LTDC interface traffic */
1102 hdsi->Instance->LVCIDR &= ~DSI_LVCIDR_VCID;
1103 hdsi->Instance->LVCIDR |= VidCfg->VirtualChannelID;
1104
1105 /* Configure the polarity of control signals */
1106 hdsi->Instance->LPCR &= ~(DSI_LPCR_DEP | DSI_LPCR_VSP | DSI_LPCR_HSP);
1107 hdsi->Instance->LPCR |= (VidCfg->DEPolarity | VidCfg->VSPolarity | VidCfg->HSPolarity);
1108
1109 /* Select the color coding for the host */
1110 hdsi->Instance->LCOLCR &= ~DSI_LCOLCR_COLC;
1111 hdsi->Instance->LCOLCR |= VidCfg->ColorCoding;
1112
1113 /* Select the color coding for the wrapper */
1114 hdsi->Instance->WCFGR &= ~DSI_WCFGR_COLMUX;
1115 hdsi->Instance->WCFGR |= ((VidCfg->ColorCoding) << 1U);
1116
1117 /* Enable/disable the loosely packed variant to 18-bit configuration */
1118 if (VidCfg->ColorCoding == DSI_RGB666)
1119 {
1120 hdsi->Instance->LCOLCR &= ~DSI_LCOLCR_LPE;
1121 hdsi->Instance->LCOLCR |= VidCfg->LooselyPacked;
1122 }
1123
1124 /* Set the Horizontal Synchronization Active (HSA) in lane byte clock cycles */
1125 hdsi->Instance->VHSACR &= ~DSI_VHSACR_HSA;
1126 hdsi->Instance->VHSACR |= VidCfg->HorizontalSyncActive;
1127
1128 /* Set the Horizontal Back Porch (HBP) in lane byte clock cycles */
1129 hdsi->Instance->VHBPCR &= ~DSI_VHBPCR_HBP;
1130 hdsi->Instance->VHBPCR |= VidCfg->HorizontalBackPorch;
1131
1132 /* Set the total line time (HLINE=HSA+HBP+HACT+HFP) in lane byte clock cycles */
1133 hdsi->Instance->VLCR &= ~DSI_VLCR_HLINE;
1134 hdsi->Instance->VLCR |= VidCfg->HorizontalLine;
1135
1136 /* Set the Vertical Synchronization Active (VSA) */
1137 hdsi->Instance->VVSACR &= ~DSI_VVSACR_VSA;
1138 hdsi->Instance->VVSACR |= VidCfg->VerticalSyncActive;
1139
1140 /* Set the Vertical Back Porch (VBP)*/
1141 hdsi->Instance->VVBPCR &= ~DSI_VVBPCR_VBP;
1142 hdsi->Instance->VVBPCR |= VidCfg->VerticalBackPorch;
1143
1144 /* Set the Vertical Front Porch (VFP)*/
1145 hdsi->Instance->VVFPCR &= ~DSI_VVFPCR_VFP;
1146 hdsi->Instance->VVFPCR |= VidCfg->VerticalFrontPorch;
1147
1148 /* Set the Vertical Active period*/
1149 hdsi->Instance->VVACR &= ~DSI_VVACR_VA;
1150 hdsi->Instance->VVACR |= VidCfg->VerticalActive;
1151
1152 /* Configure the command transmission mode */
1153 hdsi->Instance->VMCR &= ~DSI_VMCR_LPCE;
1154 hdsi->Instance->VMCR |= VidCfg->LPCommandEnable;
1155
1156 /* Low power largest packet size */
1157 hdsi->Instance->LPMCR &= ~DSI_LPMCR_LPSIZE;
1158 hdsi->Instance->LPMCR |= ((VidCfg->LPLargestPacketSize) << 16U);
1159
1160 /* Low power VACT largest packet size */
1161 hdsi->Instance->LPMCR &= ~DSI_LPMCR_VLPSIZE;
1162 hdsi->Instance->LPMCR |= VidCfg->LPVACTLargestPacketSize;
1163
1164 /* Enable LP transition in HFP period */
1165 hdsi->Instance->VMCR &= ~DSI_VMCR_LPHFPE;
1166 hdsi->Instance->VMCR |= VidCfg->LPHorizontalFrontPorchEnable;
1167
1168 /* Enable LP transition in HBP period */
1169 hdsi->Instance->VMCR &= ~DSI_VMCR_LPHBPE;
1170 hdsi->Instance->VMCR |= VidCfg->LPHorizontalBackPorchEnable;
1171
1172 /* Enable LP transition in VACT period */
1173 hdsi->Instance->VMCR &= ~DSI_VMCR_LPVAE;
1174 hdsi->Instance->VMCR |= VidCfg->LPVerticalActiveEnable;
1175
1176 /* Enable LP transition in VFP period */
1177 hdsi->Instance->VMCR &= ~DSI_VMCR_LPVFPE;
1178 hdsi->Instance->VMCR |= VidCfg->LPVerticalFrontPorchEnable;
1179
1180 /* Enable LP transition in VBP period */
1181 hdsi->Instance->VMCR &= ~DSI_VMCR_LPVBPE;
1182 hdsi->Instance->VMCR |= VidCfg->LPVerticalBackPorchEnable;
1183
1184 /* Enable LP transition in vertical sync period */
1185 hdsi->Instance->VMCR &= ~DSI_VMCR_LPVSAE;
1186 hdsi->Instance->VMCR |= VidCfg->LPVerticalSyncActiveEnable;
1187
1188 /* Enable the request for an acknowledge response at the end of a frame */
1189 hdsi->Instance->VMCR &= ~DSI_VMCR_FBTAAE;
1190 hdsi->Instance->VMCR |= VidCfg->FrameBTAAcknowledgeEnable;
1191
1192 /* Process unlocked */
1193 __HAL_UNLOCK(hdsi);
1194
1195 return HAL_OK;
1196 }
1197
1198 /**
1199 * @brief Select adapted command mode and configure the corresponding parameters
1200 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
1201 * the configuration information for the DSI.
1202 * @param CmdCfg pointer to a DSI_CmdCfgTypeDef structure that contains
1203 * the DSI command mode configuration parameters
1204 * @retval HAL status
1205 */
HAL_DSI_ConfigAdaptedCommandMode(DSI_HandleTypeDef * hdsi,DSI_CmdCfgTypeDef * CmdCfg)1206 HAL_StatusTypeDef HAL_DSI_ConfigAdaptedCommandMode(DSI_HandleTypeDef *hdsi, DSI_CmdCfgTypeDef *CmdCfg)
1207 {
1208 /* Process locked */
1209 __HAL_LOCK(hdsi);
1210
1211 /* Check the parameters */
1212 assert_param(IS_DSI_COLOR_CODING(CmdCfg->ColorCoding));
1213 assert_param(IS_DSI_TE_SOURCE(CmdCfg->TearingEffectSource));
1214 assert_param(IS_DSI_TE_POLARITY(CmdCfg->TearingEffectPolarity));
1215 assert_param(IS_DSI_AUTOMATIC_REFRESH(CmdCfg->AutomaticRefresh));
1216 assert_param(IS_DSI_VS_POLARITY(CmdCfg->VSyncPol));
1217 assert_param(IS_DSI_TE_ACK_REQUEST(CmdCfg->TEAcknowledgeRequest));
1218 assert_param(IS_DSI_DE_POLARITY(CmdCfg->DEPolarity));
1219 assert_param(IS_DSI_VSYNC_POLARITY(CmdCfg->VSPolarity));
1220 assert_param(IS_DSI_HSYNC_POLARITY(CmdCfg->HSPolarity));
1221
1222 /* Select command mode by setting CMDM and DSIM bits */
1223 hdsi->Instance->MCR |= DSI_MCR_CMDM;
1224 hdsi->Instance->WCFGR &= ~DSI_WCFGR_DSIM;
1225 hdsi->Instance->WCFGR |= DSI_WCFGR_DSIM;
1226
1227 /* Select the virtual channel for the LTDC interface traffic */
1228 hdsi->Instance->LVCIDR &= ~DSI_LVCIDR_VCID;
1229 hdsi->Instance->LVCIDR |= CmdCfg->VirtualChannelID;
1230
1231 /* Configure the polarity of control signals */
1232 hdsi->Instance->LPCR &= ~(DSI_LPCR_DEP | DSI_LPCR_VSP | DSI_LPCR_HSP);
1233 hdsi->Instance->LPCR |= (CmdCfg->DEPolarity | CmdCfg->VSPolarity | CmdCfg->HSPolarity);
1234
1235 /* Select the color coding for the host */
1236 hdsi->Instance->LCOLCR &= ~DSI_LCOLCR_COLC;
1237 hdsi->Instance->LCOLCR |= CmdCfg->ColorCoding;
1238
1239 /* Select the color coding for the wrapper */
1240 hdsi->Instance->WCFGR &= ~DSI_WCFGR_COLMUX;
1241 hdsi->Instance->WCFGR |= ((CmdCfg->ColorCoding) << 1U);
1242
1243 /* Configure the maximum allowed size for write memory command */
1244 hdsi->Instance->LCCR &= ~DSI_LCCR_CMDSIZE;
1245 hdsi->Instance->LCCR |= CmdCfg->CommandSize;
1246
1247 /* Configure the tearing effect source and polarity and select the refresh mode */
1248 hdsi->Instance->WCFGR &= ~(DSI_WCFGR_TESRC | DSI_WCFGR_TEPOL | DSI_WCFGR_AR | DSI_WCFGR_VSPOL);
1249 hdsi->Instance->WCFGR |= (CmdCfg->TearingEffectSource | CmdCfg->TearingEffectPolarity | CmdCfg->AutomaticRefresh |
1250 CmdCfg->VSyncPol);
1251
1252 /* Configure the tearing effect acknowledge request */
1253 hdsi->Instance->CMCR &= ~DSI_CMCR_TEARE;
1254 hdsi->Instance->CMCR |= CmdCfg->TEAcknowledgeRequest;
1255
1256 /* Enable the Tearing Effect interrupt */
1257 __HAL_DSI_ENABLE_IT(hdsi, DSI_IT_TE);
1258
1259 /* Enable the End of Refresh interrupt */
1260 __HAL_DSI_ENABLE_IT(hdsi, DSI_IT_ER);
1261
1262 /* Process unlocked */
1263 __HAL_UNLOCK(hdsi);
1264
1265 return HAL_OK;
1266 }
1267
1268 /**
1269 * @brief Configure command transmission mode: High-speed or Low-power
1270 * and enable/disable acknowledge request after packet transmission
1271 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
1272 * the configuration information for the DSI.
1273 * @param LPCmd pointer to a DSI_LPCmdTypeDef structure that contains
1274 * the DSI command transmission mode configuration parameters
1275 * @retval HAL status
1276 */
HAL_DSI_ConfigCommand(DSI_HandleTypeDef * hdsi,DSI_LPCmdTypeDef * LPCmd)1277 HAL_StatusTypeDef HAL_DSI_ConfigCommand(DSI_HandleTypeDef *hdsi, DSI_LPCmdTypeDef *LPCmd)
1278 {
1279 /* Process locked */
1280 __HAL_LOCK(hdsi);
1281
1282 assert_param(IS_DSI_LP_GSW0P(LPCmd->LPGenShortWriteNoP));
1283 assert_param(IS_DSI_LP_GSW1P(LPCmd->LPGenShortWriteOneP));
1284 assert_param(IS_DSI_LP_GSW2P(LPCmd->LPGenShortWriteTwoP));
1285 assert_param(IS_DSI_LP_GSR0P(LPCmd->LPGenShortReadNoP));
1286 assert_param(IS_DSI_LP_GSR1P(LPCmd->LPGenShortReadOneP));
1287 assert_param(IS_DSI_LP_GSR2P(LPCmd->LPGenShortReadTwoP));
1288 assert_param(IS_DSI_LP_GLW(LPCmd->LPGenLongWrite));
1289 assert_param(IS_DSI_LP_DSW0P(LPCmd->LPDcsShortWriteNoP));
1290 assert_param(IS_DSI_LP_DSW1P(LPCmd->LPDcsShortWriteOneP));
1291 assert_param(IS_DSI_LP_DSR0P(LPCmd->LPDcsShortReadNoP));
1292 assert_param(IS_DSI_LP_DLW(LPCmd->LPDcsLongWrite));
1293 assert_param(IS_DSI_LP_MRDP(LPCmd->LPMaxReadPacket));
1294 assert_param(IS_DSI_ACK_REQUEST(LPCmd->AcknowledgeRequest));
1295
1296 /* Select High-speed or Low-power for command transmission */
1297 hdsi->Instance->CMCR &= ~(DSI_CMCR_GSW0TX | \
1298 DSI_CMCR_GSW1TX | \
1299 DSI_CMCR_GSW2TX | \
1300 DSI_CMCR_GSR0TX | \
1301 DSI_CMCR_GSR1TX | \
1302 DSI_CMCR_GSR2TX | \
1303 DSI_CMCR_GLWTX | \
1304 DSI_CMCR_DSW0TX | \
1305 DSI_CMCR_DSW1TX | \
1306 DSI_CMCR_DSR0TX | \
1307 DSI_CMCR_DLWTX | \
1308 DSI_CMCR_MRDPS);
1309 hdsi->Instance->CMCR |= (LPCmd->LPGenShortWriteNoP | \
1310 LPCmd->LPGenShortWriteOneP | \
1311 LPCmd->LPGenShortWriteTwoP | \
1312 LPCmd->LPGenShortReadNoP | \
1313 LPCmd->LPGenShortReadOneP | \
1314 LPCmd->LPGenShortReadTwoP | \
1315 LPCmd->LPGenLongWrite | \
1316 LPCmd->LPDcsShortWriteNoP | \
1317 LPCmd->LPDcsShortWriteOneP | \
1318 LPCmd->LPDcsShortReadNoP | \
1319 LPCmd->LPDcsLongWrite | \
1320 LPCmd->LPMaxReadPacket);
1321
1322 /* Configure the acknowledge request after each packet transmission */
1323 hdsi->Instance->CMCR &= ~DSI_CMCR_ARE;
1324 hdsi->Instance->CMCR |= LPCmd->AcknowledgeRequest;
1325
1326 /* Process unlocked */
1327 __HAL_UNLOCK(hdsi);
1328
1329 return HAL_OK;
1330 }
1331
1332 /**
1333 * @brief Configure the flow control parameters
1334 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
1335 * the configuration information for the DSI.
1336 * @param FlowControl flow control feature(s) to be enabled.
1337 * This parameter can be any combination of @arg DSI_FlowControl.
1338 * @retval HAL status
1339 */
HAL_DSI_ConfigFlowControl(DSI_HandleTypeDef * hdsi,uint32_t FlowControl)1340 HAL_StatusTypeDef HAL_DSI_ConfigFlowControl(DSI_HandleTypeDef *hdsi, uint32_t FlowControl)
1341 {
1342 /* Process locked */
1343 __HAL_LOCK(hdsi);
1344
1345 /* Check the parameters */
1346 assert_param(IS_DSI_FLOW_CONTROL(FlowControl));
1347
1348 /* Set the DSI Host Protocol Configuration Register */
1349 hdsi->Instance->PCR &= ~DSI_FLOW_CONTROL_ALL;
1350 hdsi->Instance->PCR |= FlowControl;
1351
1352 /* Process unlocked */
1353 __HAL_UNLOCK(hdsi);
1354
1355 return HAL_OK;
1356 }
1357
1358 /**
1359 * @brief Configure the DSI PHY timer parameters
1360 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
1361 * the configuration information for the DSI.
1362 * @param PhyTimers DSI_PHY_TimerTypeDef structure that contains
1363 * the DSI PHY timing parameters
1364 * @retval HAL status
1365 */
HAL_DSI_ConfigPhyTimer(DSI_HandleTypeDef * hdsi,DSI_PHY_TimerTypeDef * PhyTimers)1366 HAL_StatusTypeDef HAL_DSI_ConfigPhyTimer(DSI_HandleTypeDef *hdsi, DSI_PHY_TimerTypeDef *PhyTimers)
1367 {
1368 uint32_t maxTime;
1369 /* Process locked */
1370 __HAL_LOCK(hdsi);
1371
1372 maxTime = (PhyTimers->ClockLaneLP2HSTime > PhyTimers->ClockLaneHS2LPTime) ? PhyTimers->ClockLaneLP2HSTime :
1373 PhyTimers->ClockLaneHS2LPTime;
1374
1375 /* Clock lane timer configuration */
1376
1377 /* In Automatic Clock Lane control mode, the DSI Host can turn off the clock lane between two
1378 High-Speed transmission.
1379 To do so, the DSI Host calculates the time required for the clock lane to change from HighSpeed
1380 to Low-Power and from Low-Power to High-Speed.
1381 This timings are configured by the HS2LP_TIME and LP2HS_TIME in the DSI Host Clock Lane Timer Configuration
1382 Register (DSI_CLTCR).
1383 But the DSI Host is not calculating LP2HS_TIME + HS2LP_TIME but 2 x HS2LP_TIME.
1384
1385 Workaround : Configure HS2LP_TIME and LP2HS_TIME with the same value being the max of HS2LP_TIME or LP2HS_TIME.
1386 */
1387 hdsi->Instance->CLTCR &= ~(DSI_CLTCR_LP2HS_TIME | DSI_CLTCR_HS2LP_TIME);
1388 hdsi->Instance->CLTCR |= (maxTime | ((maxTime) << 16U));
1389
1390 /* Data lane timer configuration */
1391 hdsi->Instance->DLTCR &= ~(DSI_DLTCR_MRD_TIME | DSI_DLTCR_LP2HS_TIME | DSI_DLTCR_HS2LP_TIME);
1392 hdsi->Instance->DLTCR |= (PhyTimers->DataLaneMaxReadTime | ((PhyTimers->DataLaneLP2HSTime) << 16U) | ((
1393 PhyTimers->DataLaneHS2LPTime) << 24U));
1394
1395 /* Configure the wait period to request HS transmission after a stop state */
1396 hdsi->Instance->PCONFR &= ~DSI_PCONFR_SW_TIME;
1397 hdsi->Instance->PCONFR |= ((PhyTimers->StopWaitTime) << 8U);
1398
1399 /* Process unlocked */
1400 __HAL_UNLOCK(hdsi);
1401
1402 return HAL_OK;
1403 }
1404
1405 /**
1406 * @brief Configure the DSI HOST timeout parameters
1407 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
1408 * the configuration information for the DSI.
1409 * @param HostTimeouts DSI_HOST_TimeoutTypeDef structure that contains
1410 * the DSI host timeout parameters
1411 * @retval HAL status
1412 */
HAL_DSI_ConfigHostTimeouts(DSI_HandleTypeDef * hdsi,DSI_HOST_TimeoutTypeDef * HostTimeouts)1413 HAL_StatusTypeDef HAL_DSI_ConfigHostTimeouts(DSI_HandleTypeDef *hdsi, DSI_HOST_TimeoutTypeDef *HostTimeouts)
1414 {
1415 /* Process locked */
1416 __HAL_LOCK(hdsi);
1417
1418 /* Set the timeout clock division factor */
1419 hdsi->Instance->CCR &= ~DSI_CCR_TOCKDIV;
1420 hdsi->Instance->CCR |= ((HostTimeouts->TimeoutCkdiv) << 8U);
1421
1422 /* High-speed transmission timeout */
1423 hdsi->Instance->TCCR[0U] &= ~DSI_TCCR0_HSTX_TOCNT;
1424 hdsi->Instance->TCCR[0U] |= ((HostTimeouts->HighSpeedTransmissionTimeout) << 16U);
1425
1426 /* Low-power reception timeout */
1427 hdsi->Instance->TCCR[0U] &= ~DSI_TCCR0_LPRX_TOCNT;
1428 hdsi->Instance->TCCR[0U] |= HostTimeouts->LowPowerReceptionTimeout;
1429
1430 /* High-speed read timeout */
1431 hdsi->Instance->TCCR[1U] &= ~DSI_TCCR1_HSRD_TOCNT;
1432 hdsi->Instance->TCCR[1U] |= HostTimeouts->HighSpeedReadTimeout;
1433
1434 /* Low-power read timeout */
1435 hdsi->Instance->TCCR[2U] &= ~DSI_TCCR2_LPRD_TOCNT;
1436 hdsi->Instance->TCCR[2U] |= HostTimeouts->LowPowerReadTimeout;
1437
1438 /* High-speed write timeout */
1439 hdsi->Instance->TCCR[3U] &= ~DSI_TCCR3_HSWR_TOCNT;
1440 hdsi->Instance->TCCR[3U] |= HostTimeouts->HighSpeedWriteTimeout;
1441
1442 /* High-speed write presp mode */
1443 hdsi->Instance->TCCR[3U] &= ~DSI_TCCR3_PM;
1444 hdsi->Instance->TCCR[3U] |= HostTimeouts->HighSpeedWritePrespMode;
1445
1446 /* Low-speed write timeout */
1447 hdsi->Instance->TCCR[4U] &= ~DSI_TCCR4_LPWR_TOCNT;
1448 hdsi->Instance->TCCR[4U] |= HostTimeouts->LowPowerWriteTimeout;
1449
1450 /* BTA timeout */
1451 hdsi->Instance->TCCR[5U] &= ~DSI_TCCR5_BTA_TOCNT;
1452 hdsi->Instance->TCCR[5U] |= HostTimeouts->BTATimeout;
1453
1454 /* Process unlocked */
1455 __HAL_UNLOCK(hdsi);
1456
1457 return HAL_OK;
1458 }
1459
1460 /**
1461 * @brief Start the DSI module
1462 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
1463 * the configuration information for the DSI.
1464 * @retval HAL status
1465 */
HAL_DSI_Start(DSI_HandleTypeDef * hdsi)1466 HAL_StatusTypeDef HAL_DSI_Start(DSI_HandleTypeDef *hdsi)
1467 {
1468 /* Process locked */
1469 __HAL_LOCK(hdsi);
1470
1471 /* Enable the DSI host */
1472 __HAL_DSI_ENABLE(hdsi);
1473
1474 /* Enable the DSI wrapper */
1475 __HAL_DSI_WRAPPER_ENABLE(hdsi);
1476
1477 /* Process unlocked */
1478 __HAL_UNLOCK(hdsi);
1479
1480 return HAL_OK;
1481 }
1482
1483 /**
1484 * @brief Stop the DSI module
1485 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
1486 * the configuration information for the DSI.
1487 * @retval HAL status
1488 */
HAL_DSI_Stop(DSI_HandleTypeDef * hdsi)1489 HAL_StatusTypeDef HAL_DSI_Stop(DSI_HandleTypeDef *hdsi)
1490 {
1491 /* Process locked */
1492 __HAL_LOCK(hdsi);
1493
1494 /* Disable the DSI host */
1495 __HAL_DSI_DISABLE(hdsi);
1496
1497 /* Disable the DSI wrapper */
1498 __HAL_DSI_WRAPPER_DISABLE(hdsi);
1499
1500 /* Process unlocked */
1501 __HAL_UNLOCK(hdsi);
1502
1503 return HAL_OK;
1504 }
1505
1506 /**
1507 * @brief Refresh the display in command mode
1508 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
1509 * the configuration information for the DSI.
1510 * @retval HAL status
1511 */
HAL_DSI_Refresh(DSI_HandleTypeDef * hdsi)1512 HAL_StatusTypeDef HAL_DSI_Refresh(DSI_HandleTypeDef *hdsi)
1513 {
1514 /* Process locked */
1515 __HAL_LOCK(hdsi);
1516
1517 /* Update the display */
1518 hdsi->Instance->WCR |= DSI_WCR_LTDCEN;
1519
1520 /* Process unlocked */
1521 __HAL_UNLOCK(hdsi);
1522
1523 return HAL_OK;
1524 }
1525
1526 /**
1527 * @brief Controls the display color mode in Video mode
1528 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
1529 * the configuration information for the DSI.
1530 * @param ColorMode Color mode (full or 8-colors).
1531 * This parameter can be any value of @arg DSI_Color_Mode
1532 * @retval HAL status
1533 */
HAL_DSI_ColorMode(DSI_HandleTypeDef * hdsi,uint32_t ColorMode)1534 HAL_StatusTypeDef HAL_DSI_ColorMode(DSI_HandleTypeDef *hdsi, uint32_t ColorMode)
1535 {
1536 /* Process locked */
1537 __HAL_LOCK(hdsi);
1538
1539 /* Check the parameters */
1540 assert_param(IS_DSI_COLOR_MODE(ColorMode));
1541
1542 /* Update the display color mode */
1543 hdsi->Instance->WCR &= ~DSI_WCR_COLM;
1544 hdsi->Instance->WCR |= ColorMode;
1545
1546 /* Process unlocked */
1547 __HAL_UNLOCK(hdsi);
1548
1549 return HAL_OK;
1550 }
1551
1552 /**
1553 * @brief Control the display shutdown in Video mode
1554 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
1555 * the configuration information for the DSI.
1556 * @param Shutdown Shut-down (Display-ON or Display-OFF).
1557 * This parameter can be any value of @arg DSI_ShutDown
1558 * @retval HAL status
1559 */
HAL_DSI_Shutdown(DSI_HandleTypeDef * hdsi,uint32_t Shutdown)1560 HAL_StatusTypeDef HAL_DSI_Shutdown(DSI_HandleTypeDef *hdsi, uint32_t Shutdown)
1561 {
1562 /* Process locked */
1563 __HAL_LOCK(hdsi);
1564
1565 /* Check the parameters */
1566 assert_param(IS_DSI_SHUT_DOWN(Shutdown));
1567
1568 /* Update the display Shutdown */
1569 hdsi->Instance->WCR &= ~DSI_WCR_SHTDN;
1570 hdsi->Instance->WCR |= Shutdown;
1571
1572 /* Process unlocked */
1573 __HAL_UNLOCK(hdsi);
1574
1575 return HAL_OK;
1576 }
1577
1578 /**
1579 * @brief write short DCS or short Generic command
1580 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
1581 * the configuration information for the DSI.
1582 * @param ChannelID Virtual channel ID.
1583 * @param Mode DSI short packet data type.
1584 * This parameter can be any value of @arg DSI_SHORT_WRITE_PKT_Data_Type.
1585 * @param Param1 DSC command or first generic parameter.
1586 * This parameter can be any value of @arg DSI_DCS_Command or a
1587 * generic command code.
1588 * @param Param2 DSC parameter or second generic parameter.
1589 * @retval HAL status
1590 */
HAL_DSI_ShortWrite(DSI_HandleTypeDef * hdsi,uint32_t ChannelID,uint32_t Mode,uint32_t Param1,uint32_t Param2)1591 HAL_StatusTypeDef HAL_DSI_ShortWrite(DSI_HandleTypeDef *hdsi,
1592 uint32_t ChannelID,
1593 uint32_t Mode,
1594 uint32_t Param1,
1595 uint32_t Param2)
1596 {
1597 HAL_StatusTypeDef status;
1598 /* Check the parameters */
1599 assert_param(IS_DSI_SHORT_WRITE_PACKET_TYPE(Mode));
1600
1601 /* Process locked */
1602 __HAL_LOCK(hdsi);
1603
1604 status = DSI_ShortWrite(hdsi, ChannelID, Mode, Param1, Param2);
1605
1606 /* Process unlocked */
1607 __HAL_UNLOCK(hdsi);
1608
1609 return status;
1610 }
1611
1612 /**
1613 * @brief write long DCS or long Generic command
1614 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
1615 * the configuration information for the DSI.
1616 * @param ChannelID Virtual channel ID.
1617 * @param Mode DSI long packet data type.
1618 * This parameter can be any value of @arg DSI_LONG_WRITE_PKT_Data_Type.
1619 * @param NbParams Number of parameters.
1620 * @param Param1 DSC command or first generic parameter.
1621 * This parameter can be any value of @arg DSI_DCS_Command or a
1622 * generic command code
1623 * @param ParametersTable Pointer to parameter values table.
1624 * @retval HAL status
1625 */
HAL_DSI_LongWrite(DSI_HandleTypeDef * hdsi,uint32_t ChannelID,uint32_t Mode,uint32_t NbParams,uint32_t Param1,uint8_t * ParametersTable)1626 HAL_StatusTypeDef HAL_DSI_LongWrite(DSI_HandleTypeDef *hdsi,
1627 uint32_t ChannelID,
1628 uint32_t Mode,
1629 uint32_t NbParams,
1630 uint32_t Param1,
1631 uint8_t *ParametersTable)
1632 {
1633 uint32_t uicounter;
1634 uint32_t nbBytes;
1635 uint32_t count;
1636 uint32_t tickstart;
1637 uint32_t fifoword;
1638 uint8_t *pparams = ParametersTable;
1639
1640 /* Process locked */
1641 __HAL_LOCK(hdsi);
1642
1643 /* Check the parameters */
1644 assert_param(IS_DSI_LONG_WRITE_PACKET_TYPE(Mode));
1645
1646 /* Get tick */
1647 tickstart = HAL_GetTick();
1648
1649 /* Wait for Command FIFO Empty */
1650 while ((hdsi->Instance->GPSR & DSI_GPSR_CMDFE) == 0U)
1651 {
1652 /* Check for the Timeout */
1653 if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
1654 {
1655 /* Process Unlocked */
1656 __HAL_UNLOCK(hdsi);
1657
1658 return HAL_TIMEOUT;
1659 }
1660 }
1661
1662 /* Set the DCS code on payload byte 1, and the other parameters on the write FIFO command*/
1663 fifoword = Param1;
1664 nbBytes = (NbParams < 3U) ? NbParams : 3U;
1665
1666 for (count = 0U; count < nbBytes; count++)
1667 {
1668 fifoword |= (((uint32_t)(*(pparams + count))) << (8U + (8U * count)));
1669 }
1670 hdsi->Instance->GPDR = fifoword;
1671
1672 uicounter = NbParams - nbBytes;
1673 pparams += nbBytes;
1674 /* Set the Next parameters on the write FIFO command*/
1675 while (uicounter != 0U)
1676 {
1677 nbBytes = (uicounter < 4U) ? uicounter : 4U;
1678 fifoword = 0U;
1679 for (count = 0U; count < nbBytes; count++)
1680 {
1681 fifoword |= (((uint32_t)(*(pparams + count))) << (8U * count));
1682 }
1683 hdsi->Instance->GPDR = fifoword;
1684
1685 uicounter -= nbBytes;
1686 pparams += nbBytes;
1687 }
1688
1689 /* Configure the packet to send a long DCS command */
1690 DSI_ConfigPacketHeader(hdsi->Instance,
1691 ChannelID,
1692 Mode,
1693 ((NbParams + 1U) & 0x00FFU),
1694 (((NbParams + 1U) & 0xFF00U) >> 8U));
1695
1696 /* Process unlocked */
1697 __HAL_UNLOCK(hdsi);
1698
1699 return HAL_OK;
1700 }
1701
1702 /**
1703 * @brief Read command (DCS or generic)
1704 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
1705 * the configuration information for the DSI.
1706 * @param ChannelNbr Virtual channel ID
1707 * @param Array pointer to a buffer to store the payload of a read back operation.
1708 * @param Size Data size to be read (in byte).
1709 * @param Mode DSI read packet data type.
1710 * This parameter can be any value of @arg DSI_SHORT_READ_PKT_Data_Type.
1711 * @param DCSCmd DCS get/read command.
1712 * @param ParametersTable Pointer to parameter values table.
1713 * @retval HAL status
1714 */
HAL_DSI_Read(DSI_HandleTypeDef * hdsi,uint32_t ChannelNbr,uint8_t * Array,uint32_t Size,uint32_t Mode,uint32_t DCSCmd,uint8_t * ParametersTable)1715 HAL_StatusTypeDef HAL_DSI_Read(DSI_HandleTypeDef *hdsi,
1716 uint32_t ChannelNbr,
1717 uint8_t *Array,
1718 uint32_t Size,
1719 uint32_t Mode,
1720 uint32_t DCSCmd,
1721 uint8_t *ParametersTable)
1722 {
1723 uint32_t tickstart;
1724 uint8_t *pdata = Array;
1725 uint32_t datasize = Size;
1726 uint32_t fifoword;
1727 uint32_t nbbytes;
1728 uint32_t count;
1729
1730 /* Process locked */
1731 __HAL_LOCK(hdsi);
1732
1733 /* Check the parameters */
1734 assert_param(IS_DSI_READ_PACKET_TYPE(Mode));
1735
1736 if (datasize > 2U)
1737 {
1738 /* set max return packet size */
1739 if (DSI_ShortWrite(hdsi, ChannelNbr, DSI_MAX_RETURN_PKT_SIZE, ((datasize) & 0xFFU),
1740 (((datasize) >> 8U) & 0xFFU)) != HAL_OK)
1741 {
1742 /* Process Unlocked */
1743 __HAL_UNLOCK(hdsi);
1744
1745 return HAL_ERROR;
1746 }
1747 }
1748
1749 /* Configure the packet to read command */
1750 if (Mode == DSI_DCS_SHORT_PKT_READ)
1751 {
1752 DSI_ConfigPacketHeader(hdsi->Instance, ChannelNbr, Mode, DCSCmd, 0U);
1753 }
1754 else if (Mode == DSI_GEN_SHORT_PKT_READ_P0)
1755 {
1756 DSI_ConfigPacketHeader(hdsi->Instance, ChannelNbr, Mode, 0U, 0U);
1757 }
1758 else if (Mode == DSI_GEN_SHORT_PKT_READ_P1)
1759 {
1760 DSI_ConfigPacketHeader(hdsi->Instance, ChannelNbr, Mode, ParametersTable[0U], 0U);
1761 }
1762 else if (Mode == DSI_GEN_SHORT_PKT_READ_P2)
1763 {
1764 DSI_ConfigPacketHeader(hdsi->Instance, ChannelNbr, Mode, ParametersTable[0U], ParametersTable[1U]);
1765 }
1766 else
1767 {
1768 /* Process Unlocked */
1769 __HAL_UNLOCK(hdsi);
1770
1771 return HAL_ERROR;
1772 }
1773
1774 /* Get tick */
1775 tickstart = HAL_GetTick();
1776
1777 /* If DSI fifo is not empty, read requested bytes */
1778 while (((int32_t)(datasize)) > 0)
1779 {
1780 if ((hdsi->Instance->GPSR & DSI_GPSR_PRDFE) == 0U)
1781 {
1782 fifoword = hdsi->Instance->GPDR;
1783 nbbytes = (datasize < 4U) ? datasize : 4U;
1784
1785 for (count = 0U; count < nbbytes; count++)
1786 {
1787 *pdata = (uint8_t)(fifoword >> (8U * count));
1788 pdata++;
1789 datasize--;
1790 }
1791 }
1792
1793 /* Check for the Timeout */
1794 if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
1795 {
1796 /* Process Unlocked */
1797 __HAL_UNLOCK(hdsi);
1798
1799 return HAL_TIMEOUT;
1800 }
1801
1802 /* Software workaround to avoid HAL_TIMEOUT when a DSI read command is */
1803 /* issued to the panel and the read data is not captured by the DSI Host */
1804 /* which returns Packet Size Error. */
1805 /* Need to ensure that the Read command has finished before checking PSE */
1806 if ((hdsi->Instance->GPSR & DSI_GPSR_RCB) == 0U)
1807 {
1808 if ((hdsi->Instance->ISR[1U] & DSI_ISR1_PSE) == DSI_ISR1_PSE)
1809 {
1810 /* Process Unlocked */
1811 __HAL_UNLOCK(hdsi);
1812
1813 return HAL_ERROR;
1814 }
1815 }
1816 }
1817
1818 /* Process unlocked */
1819 __HAL_UNLOCK(hdsi);
1820
1821 return HAL_OK;
1822 }
1823
1824 /**
1825 * @brief Enter the ULPM (Ultra Low Power Mode) with the D-PHY PLL running
1826 * (only data lanes are in ULPM)
1827 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
1828 * the configuration information for the DSI.
1829 * @retval HAL status
1830 */
HAL_DSI_EnterULPMData(DSI_HandleTypeDef * hdsi)1831 HAL_StatusTypeDef HAL_DSI_EnterULPMData(DSI_HandleTypeDef *hdsi)
1832 {
1833 uint32_t tickstart;
1834
1835 /* Process locked */
1836 __HAL_LOCK(hdsi);
1837
1838 /* Verify the initial status of the DSI Host */
1839
1840 /* Verify that the clock lane and the digital section of the D-PHY are enabled */
1841 if ((hdsi->Instance->PCTLR & (DSI_PCTLR_CKE | DSI_PCTLR_DEN)) != (DSI_PCTLR_CKE | DSI_PCTLR_DEN))
1842 {
1843 /* Process Unlocked */
1844 __HAL_UNLOCK(hdsi);
1845 return HAL_ERROR;
1846 }
1847
1848 /* Verify that the D-PHY PLL and the reference bias are enabled */
1849 if ((hdsi->Instance->WRPCR & DSI_WRPCR_PLLEN) != DSI_WRPCR_PLLEN)
1850 {
1851 /* Process Unlocked */
1852 __HAL_UNLOCK(hdsi);
1853 return HAL_ERROR;
1854 }
1855
1856 /* Verify that there are no ULPS exit or request on data lanes */
1857 if ((hdsi->Instance->PUCR & (DSI_PUCR_UEDL | DSI_PUCR_URDL)) != 0U)
1858 {
1859 /* Process Unlocked */
1860 __HAL_UNLOCK(hdsi);
1861 return HAL_ERROR;
1862 }
1863
1864 /* Verify that there are no Transmission trigger */
1865 if ((hdsi->Instance->PTTCR & DSI_PTTCR_TX_TRIG) != 0U)
1866 {
1867 /* Process Unlocked */
1868 __HAL_UNLOCK(hdsi);
1869 return HAL_ERROR;
1870 }
1871
1872 /* Requires min of 400us delay before reading the PLLLS flag */
1873 /* 1ms delay is inserted that is the minimum HAL delay granularity */
1874 HAL_Delay(1);
1875
1876 /* Verify that D-PHY PLL is locked */
1877 tickstart = HAL_GetTick();
1878
1879 while ((__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_PLLLS) == 0U))
1880 {
1881 /* Check for the Timeout */
1882 if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
1883 {
1884 /* Process Unlocked */
1885 __HAL_UNLOCK(hdsi);
1886
1887 return HAL_TIMEOUT;
1888 }
1889 }
1890
1891 /* Verify that all active lanes are in Stop state */
1892 if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
1893 {
1894 if ((hdsi->Instance->PSR & DSI_PSR_UAN0) != DSI_PSR_UAN0)
1895 {
1896 /* Process Unlocked */
1897 __HAL_UNLOCK(hdsi);
1898 return HAL_ERROR;
1899 }
1900 }
1901 else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
1902 {
1903 if ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1)) != (DSI_PSR_UAN0 | DSI_PSR_UAN1))
1904 {
1905 /* Process Unlocked */
1906 __HAL_UNLOCK(hdsi);
1907 return HAL_ERROR;
1908 }
1909 }
1910 else
1911 {
1912 /* Process unlocked */
1913 __HAL_UNLOCK(hdsi);
1914 return HAL_ERROR;
1915 }
1916
1917 /* ULPS Request on Data Lanes */
1918 hdsi->Instance->PUCR |= DSI_PUCR_URDL;
1919
1920 /* Get tick */
1921 tickstart = HAL_GetTick();
1922
1923 /* Wait until the D-PHY active lanes enter into ULPM */
1924 if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
1925 {
1926 while ((hdsi->Instance->PSR & DSI_PSR_UAN0) != 0U)
1927 {
1928 /* Check for the Timeout */
1929 if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
1930 {
1931 /* Process Unlocked */
1932 __HAL_UNLOCK(hdsi);
1933
1934 return HAL_TIMEOUT;
1935 }
1936 }
1937 }
1938 else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
1939 {
1940 while ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1)) != 0U)
1941 {
1942 /* Check for the Timeout */
1943 if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
1944 {
1945 /* Process Unlocked */
1946 __HAL_UNLOCK(hdsi);
1947
1948 return HAL_TIMEOUT;
1949 }
1950 }
1951 }
1952 else
1953 {
1954 /* Process unlocked */
1955 __HAL_UNLOCK(hdsi);
1956
1957 return HAL_ERROR;
1958 }
1959
1960 /* Process unlocked */
1961 __HAL_UNLOCK(hdsi);
1962
1963 return HAL_OK;
1964 }
1965
1966 /**
1967 * @brief Exit the ULPM (Ultra Low Power Mode) with the D-PHY PLL running
1968 * (only data lanes are in ULPM)
1969 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
1970 * the configuration information for the DSI.
1971 * @retval HAL status
1972 */
HAL_DSI_ExitULPMData(DSI_HandleTypeDef * hdsi)1973 HAL_StatusTypeDef HAL_DSI_ExitULPMData(DSI_HandleTypeDef *hdsi)
1974 {
1975 uint32_t tickstart;
1976
1977 /* Process locked */
1978 __HAL_LOCK(hdsi);
1979
1980 /* Verify that all active lanes are in ULPM */
1981 if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
1982 {
1983 if ((hdsi->Instance->PSR & DSI_PSR_UAN0) != 0U)
1984 {
1985 /* Process Unlocked */
1986 __HAL_UNLOCK(hdsi);
1987
1988 return HAL_ERROR;
1989 }
1990 }
1991 else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
1992 {
1993 if ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1)) != 0U)
1994 {
1995 /* Process Unlocked */
1996 __HAL_UNLOCK(hdsi);
1997
1998 return HAL_ERROR;
1999 }
2000 }
2001 else
2002 {
2003 /* Process unlocked */
2004 __HAL_UNLOCK(hdsi);
2005
2006 return HAL_ERROR;
2007 }
2008
2009 /* Turn on the DSI PLL */
2010 __HAL_DSI_PLL_ENABLE(hdsi);
2011
2012 /* Requires min of 400us delay before reading the PLLLS flag */
2013 /* 1ms delay is inserted that is the minimum HAL delay granularity */
2014 HAL_Delay(1);
2015
2016 /* Get tick */
2017 tickstart = HAL_GetTick();
2018
2019 /* Wait for the lock of the PLL */
2020 while (__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_PLLLS) == 0U)
2021 {
2022 /* Check for the Timeout */
2023 if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2024 {
2025 /* Process Unlocked */
2026 __HAL_UNLOCK(hdsi);
2027
2028 return HAL_TIMEOUT;
2029 }
2030 }
2031
2032 /* Exit ULPS on Data Lanes */
2033 hdsi->Instance->PUCR |= DSI_PUCR_UEDL;
2034
2035 /* Get tick */
2036 tickstart = HAL_GetTick();
2037
2038 /* Wait until all active lanes exit ULPM */
2039 if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
2040 {
2041 while ((hdsi->Instance->PSR & DSI_PSR_UAN0) != DSI_PSR_UAN0)
2042 {
2043 /* Check for the Timeout */
2044 if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2045 {
2046 /* Process Unlocked */
2047 __HAL_UNLOCK(hdsi);
2048
2049 return HAL_TIMEOUT;
2050 }
2051 }
2052 }
2053 else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
2054 {
2055 while ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1)) != (DSI_PSR_UAN0 | DSI_PSR_UAN1))
2056 {
2057 /* Check for the Timeout */
2058 if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2059 {
2060 /* Process Unlocked */
2061 __HAL_UNLOCK(hdsi);
2062
2063 return HAL_TIMEOUT;
2064 }
2065 }
2066 }
2067 else
2068 {
2069 /* Process unlocked */
2070 __HAL_UNLOCK(hdsi);
2071
2072 return HAL_ERROR;
2073 }
2074
2075 /* wait for 1 ms*/
2076 HAL_Delay(1U);
2077
2078 /* De-assert the ULPM requests and the ULPM exit bits */
2079 hdsi->Instance->PUCR = 0U;
2080
2081 /* Verify that D-PHY PLL is enabled */
2082 if ((hdsi->Instance->WRPCR & DSI_WRPCR_PLLEN) != DSI_WRPCR_PLLEN)
2083 {
2084 /* Process Unlocked */
2085 __HAL_UNLOCK(hdsi);
2086 return HAL_ERROR;
2087 }
2088
2089 /* Verify that all active lanes are in Stop state */
2090 if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
2091 {
2092 if ((hdsi->Instance->PSR & DSI_PSR_UAN0) != DSI_PSR_UAN0)
2093 {
2094 /* Process Unlocked */
2095 __HAL_UNLOCK(hdsi);
2096 return HAL_ERROR;
2097 }
2098 }
2099 else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
2100 {
2101 if ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1)) != (DSI_PSR_UAN0 | DSI_PSR_UAN1))
2102 {
2103 /* Process Unlocked */
2104 __HAL_UNLOCK(hdsi);
2105 return HAL_ERROR;
2106 }
2107 }
2108 else
2109 {
2110 /* Process unlocked */
2111 __HAL_UNLOCK(hdsi);
2112 return HAL_ERROR;
2113 }
2114
2115 /* Verify that D-PHY PLL is locked */
2116 /* Requires min of 400us delay before reading the PLLLS flag */
2117 /* 1ms delay is inserted that is the minimum HAL delay granularity */
2118 HAL_Delay(1);
2119
2120 /* Get tick */
2121 tickstart = HAL_GetTick();
2122
2123 /* Wait for the lock of the PLL */
2124 while (__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_PLLLS) == 0U)
2125 {
2126 /* Check for the Timeout */
2127 if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2128 {
2129 /* Process Unlocked */
2130 __HAL_UNLOCK(hdsi);
2131
2132 return HAL_TIMEOUT;
2133 }
2134 }
2135
2136 /* Process unlocked */
2137 __HAL_UNLOCK(hdsi);
2138
2139 return HAL_OK;
2140 }
2141
2142 /**
2143 * @brief Enter the ULPM (Ultra Low Power Mode) with the D-PHY PLL turned off
2144 * (both data and clock lanes are in ULPM)
2145 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
2146 * the configuration information for the DSI.
2147 * @retval HAL status
2148 */
HAL_DSI_EnterULPM(DSI_HandleTypeDef * hdsi)2149 HAL_StatusTypeDef HAL_DSI_EnterULPM(DSI_HandleTypeDef *hdsi)
2150 {
2151 uint32_t tickstart;
2152
2153 /* Process locked */
2154 __HAL_LOCK(hdsi);
2155
2156 /* Verify the initial status of the DSI Host */
2157
2158 /* Verify that the clock lane and the digital section of the D-PHY are enabled */
2159 if ((hdsi->Instance->PCTLR & (DSI_PCTLR_CKE | DSI_PCTLR_DEN)) != (DSI_PCTLR_CKE | DSI_PCTLR_DEN))
2160 {
2161 /* Process Unlocked */
2162 __HAL_UNLOCK(hdsi);
2163 return HAL_ERROR;
2164 }
2165
2166 /* Verify that the D-PHY PLL and the reference bias are enabled */
2167 if ((hdsi->Instance->WRPCR & DSI_WRPCR_PLLEN) != DSI_WRPCR_PLLEN)
2168 {
2169 /* Process Unlocked */
2170 __HAL_UNLOCK(hdsi);
2171 return HAL_ERROR;
2172 }
2173
2174 /* Verify that there are no ULPS exit or request on both data and clock lanes */
2175 if ((hdsi->Instance->PUCR & (DSI_PUCR_UEDL | DSI_PUCR_URDL | DSI_PUCR_UECL | DSI_PUCR_URCL)) != 0U)
2176 {
2177 /* Process Unlocked */
2178 __HAL_UNLOCK(hdsi);
2179 return HAL_ERROR;
2180 }
2181
2182 /* Verify that there are no Transmission trigger */
2183 if ((hdsi->Instance->PTTCR & DSI_PTTCR_TX_TRIG) != 0U)
2184 {
2185 /* Process Unlocked */
2186 __HAL_UNLOCK(hdsi);
2187 return HAL_ERROR;
2188 }
2189
2190 /* Requires min of 400us delay before reading the PLLLS flag */
2191 /* 1ms delay is inserted that is the minimum HAL delay granularity */
2192 HAL_Delay(1);
2193
2194 /* Verify that D-PHY PLL is locked */
2195 tickstart = HAL_GetTick();
2196
2197 while ((__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_PLLLS) == 0U))
2198 {
2199 /* Check for the Timeout */
2200 if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2201 {
2202 /* Process Unlocked */
2203 __HAL_UNLOCK(hdsi);
2204
2205 return HAL_TIMEOUT;
2206 }
2207 }
2208
2209 /* Verify that all active lanes are in Stop state */
2210 if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
2211 {
2212 if ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_PSS0)) != (DSI_PSR_UAN0 | DSI_PSR_PSS0))
2213 {
2214 /* Process Unlocked */
2215 __HAL_UNLOCK(hdsi);
2216 return HAL_ERROR;
2217 }
2218 }
2219 else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
2220 {
2221 if ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_PSS0 | DSI_PSR_PSS1 | \
2222 DSI_PSR_UAN1)) != (DSI_PSR_UAN0 | DSI_PSR_PSS0 | DSI_PSR_PSS1 | DSI_PSR_UAN1))
2223 {
2224 /* Process Unlocked */
2225 __HAL_UNLOCK(hdsi);
2226 return HAL_ERROR;
2227 }
2228 }
2229 else
2230 {
2231 /* Process unlocked */
2232 __HAL_UNLOCK(hdsi);
2233 return HAL_ERROR;
2234 }
2235
2236 /* Clock lane configuration: no more HS request */
2237 hdsi->Instance->CLCR &= ~DSI_CLCR_DPCC;
2238
2239 /* Use system PLL as byte lane clock source before stopping DSIPHY clock source */
2240 __HAL_RCC_DSI_CONFIG(RCC_DSICLKSOURCE_PLLSAI2);
2241
2242 /* ULPS Request on Clock and Data Lanes */
2243 hdsi->Instance->PUCR |= (DSI_PUCR_URCL | DSI_PUCR_URDL);
2244
2245 /* Get tick */
2246 tickstart = HAL_GetTick();
2247
2248 /* Wait until all active lanes enter ULPM */
2249 if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
2250 {
2251 while ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UANC)) != 0U)
2252 {
2253 /* Check for the Timeout */
2254 if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2255 {
2256 /* Process Unlocked */
2257 __HAL_UNLOCK(hdsi);
2258
2259 return HAL_TIMEOUT;
2260 }
2261 }
2262 }
2263 else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
2264 {
2265 while ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1 | DSI_PSR_UANC)) != 0U)
2266 {
2267 /* Check for the Timeout */
2268 if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2269 {
2270 /* Process Unlocked */
2271 __HAL_UNLOCK(hdsi);
2272
2273 return HAL_TIMEOUT;
2274 }
2275 }
2276 }
2277 else
2278 {
2279 /* Process unlocked */
2280 __HAL_UNLOCK(hdsi);
2281
2282 return HAL_ERROR;
2283 }
2284
2285 /* Turn off the DSI PLL */
2286 __HAL_DSI_PLL_DISABLE(hdsi);
2287
2288 /* Process unlocked */
2289 __HAL_UNLOCK(hdsi);
2290
2291 return HAL_OK;
2292 }
2293
2294 /**
2295 * @brief Exit the ULPM (Ultra Low Power Mode) with the D-PHY PLL turned off
2296 * (both data and clock lanes are in ULPM)
2297 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
2298 * the configuration information for the DSI.
2299 * @retval HAL status
2300 */
HAL_DSI_ExitULPM(DSI_HandleTypeDef * hdsi)2301 HAL_StatusTypeDef HAL_DSI_ExitULPM(DSI_HandleTypeDef *hdsi)
2302 {
2303 uint32_t tickstart;
2304
2305 /* Process locked */
2306 __HAL_LOCK(hdsi);
2307
2308 /* Verify that all active lanes are in ULPM */
2309 if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
2310 {
2311 if ((hdsi->Instance->PSR & (DSI_PSR_RUE0 | DSI_PSR_UAN0 | DSI_PSR_PSS0 | \
2312 DSI_PSR_UANC | DSI_PSR_PSSC | DSI_PSR_PD)) != 0U)
2313 {
2314 /* Process Unlocked */
2315 __HAL_UNLOCK(hdsi);
2316
2317 return HAL_ERROR;
2318 }
2319 }
2320 else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
2321 {
2322 if ((hdsi->Instance->PSR & (DSI_PSR_RUE0 | DSI_PSR_UAN0 | DSI_PSR_PSS0 | DSI_PSR_UAN1 | \
2323 DSI_PSR_PSS1 | DSI_PSR_UANC | DSI_PSR_PSSC | DSI_PSR_PD)) != 0U)
2324 {
2325 /* Process Unlocked */
2326 __HAL_UNLOCK(hdsi);
2327
2328 return HAL_ERROR;
2329 }
2330 }
2331 else
2332 {
2333 /* Process unlocked */
2334 __HAL_UNLOCK(hdsi);
2335
2336 return HAL_ERROR;
2337 }
2338
2339 /* Turn on the DSI PLL */
2340 __HAL_DSI_PLL_ENABLE(hdsi);
2341
2342 /* Requires min of 400us delay before reading the PLLLS flag */
2343 /* 1ms delay is inserted that is the minimum HAL delay granularity */
2344 HAL_Delay(1);
2345
2346 /* Get tick */
2347 tickstart = HAL_GetTick();
2348
2349 /* Wait for the lock of the PLL */
2350 while (__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_PLLLS) == 0U)
2351 {
2352 /* Check for the Timeout */
2353 if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2354 {
2355 /* Process Unlocked */
2356 __HAL_UNLOCK(hdsi);
2357
2358 return HAL_TIMEOUT;
2359 }
2360 }
2361
2362 /* Exit ULPS on Clock and Data Lanes */
2363 hdsi->Instance->PUCR |= (DSI_PUCR_UECL | DSI_PUCR_UEDL);
2364
2365 /* Get tick */
2366 tickstart = HAL_GetTick();
2367
2368 /* Wait until all active lanes exit ULPM */
2369 if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
2370 {
2371 while ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UANC)) != (DSI_PSR_UAN0 | DSI_PSR_UANC))
2372 {
2373 /* Check for the Timeout */
2374 if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2375 {
2376 /* Process Unlocked */
2377 __HAL_UNLOCK(hdsi);
2378
2379 return HAL_TIMEOUT;
2380 }
2381 }
2382 }
2383 else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
2384 {
2385 while ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1 | DSI_PSR_UANC)) != (DSI_PSR_UAN0 | DSI_PSR_UAN1 |
2386 DSI_PSR_UANC))
2387 {
2388 /* Check for the Timeout */
2389 if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2390 {
2391 /* Process Unlocked */
2392 __HAL_UNLOCK(hdsi);
2393
2394 return HAL_TIMEOUT;
2395 }
2396 }
2397 }
2398 else
2399 {
2400 /* Process unlocked */
2401 __HAL_UNLOCK(hdsi);
2402
2403 return HAL_ERROR;
2404 }
2405
2406 /* wait for 1 ms */
2407 HAL_Delay(1U);
2408
2409 /* De-assert the ULPM requests and the ULPM exit bits */
2410 hdsi->Instance->PUCR = 0U;
2411
2412 /* Switch the lane byte clock source in the RCC from system PLL to D-PHY */
2413 __HAL_RCC_DSI_CONFIG(RCC_DSICLKSOURCE_DSIPHY);
2414
2415 /* Restore clock lane configuration to HS */
2416 hdsi->Instance->CLCR |= DSI_CLCR_DPCC;
2417
2418 /* Verify that D-PHY PLL is enabled */
2419 if ((hdsi->Instance->WRPCR & DSI_WRPCR_PLLEN) != DSI_WRPCR_PLLEN)
2420 {
2421 /* Process Unlocked */
2422 __HAL_UNLOCK(hdsi);
2423 return HAL_ERROR;
2424 }
2425
2426 /* Verify that all active lanes are in Stop state */
2427 if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
2428 {
2429 if ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_PSS0)) != (DSI_PSR_UAN0 | DSI_PSR_PSS0))
2430 {
2431 /* Process Unlocked */
2432 __HAL_UNLOCK(hdsi);
2433 return HAL_ERROR;
2434 }
2435 }
2436 else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
2437 {
2438 if ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_PSS0 | DSI_PSR_PSS1 | \
2439 DSI_PSR_UAN1)) != (DSI_PSR_UAN0 | DSI_PSR_PSS0 | DSI_PSR_PSS1 | DSI_PSR_UAN1))
2440 {
2441 /* Process Unlocked */
2442 __HAL_UNLOCK(hdsi);
2443 return HAL_ERROR;
2444 }
2445 }
2446 else
2447 {
2448 /* Process unlocked */
2449 __HAL_UNLOCK(hdsi);
2450 return HAL_ERROR;
2451 }
2452
2453 /* Verify that D-PHY PLL is locked */
2454 /* Requires min of 400us delay before reading the PLLLS flag */
2455 /* 1ms delay is inserted that is the minimum HAL delay granularity */
2456 HAL_Delay(1);
2457
2458 /* Get tick */
2459 tickstart = HAL_GetTick();
2460
2461 /* Wait for the lock of the PLL */
2462 while (__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_PLLLS) == 0U)
2463 {
2464 /* Check for the Timeout */
2465 if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2466 {
2467 /* Process Unlocked */
2468 __HAL_UNLOCK(hdsi);
2469
2470 return HAL_TIMEOUT;
2471 }
2472 }
2473
2474 /* Process unlocked */
2475 __HAL_UNLOCK(hdsi);
2476
2477 return HAL_OK;
2478 }
2479
2480 /**
2481 * @brief Start test pattern generation
2482 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
2483 * the configuration information for the DSI.
2484 * @param Mode Pattern generator mode
2485 * This parameter can be one of the following values:
2486 * 0 : Color bars (horizontal or vertical)
2487 * 1 : BER pattern (vertical only)
2488 * @param Orientation Pattern generator orientation
2489 * This parameter can be one of the following values:
2490 * 0 : Vertical color bars
2491 * 1 : Horizontal color bars
2492 * @retval HAL status
2493 */
HAL_DSI_PatternGeneratorStart(DSI_HandleTypeDef * hdsi,uint32_t Mode,uint32_t Orientation)2494 HAL_StatusTypeDef HAL_DSI_PatternGeneratorStart(DSI_HandleTypeDef *hdsi, uint32_t Mode, uint32_t Orientation)
2495 {
2496 /* Process locked */
2497 __HAL_LOCK(hdsi);
2498
2499 /* Configure pattern generator mode and orientation */
2500 hdsi->Instance->VMCR &= ~(DSI_VMCR_PGM | DSI_VMCR_PGO);
2501 hdsi->Instance->VMCR |= ((Mode << 20U) | (Orientation << 24U));
2502
2503 /* Enable pattern generator by setting PGE bit */
2504 hdsi->Instance->VMCR |= DSI_VMCR_PGE;
2505
2506 /* Process unlocked */
2507 __HAL_UNLOCK(hdsi);
2508
2509 return HAL_OK;
2510 }
2511
2512 /**
2513 * @brief Stop test pattern generation
2514 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
2515 * the configuration information for the DSI.
2516 * @retval HAL status
2517 */
HAL_DSI_PatternGeneratorStop(DSI_HandleTypeDef * hdsi)2518 HAL_StatusTypeDef HAL_DSI_PatternGeneratorStop(DSI_HandleTypeDef *hdsi)
2519 {
2520 /* Process locked */
2521 __HAL_LOCK(hdsi);
2522
2523 /* Disable pattern generator by clearing PGE bit */
2524 hdsi->Instance->VMCR &= ~DSI_VMCR_PGE;
2525
2526 /* Process unlocked */
2527 __HAL_UNLOCK(hdsi);
2528
2529 return HAL_OK;
2530 }
2531
2532 /**
2533 * @brief Set Slew-Rate And Delay Tuning
2534 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
2535 * the configuration information for the DSI.
2536 * @param CommDelay Communication delay to be adjusted.
2537 * This parameter can be any value of @arg DSI_Communication_Delay
2538 * @param Lane select between clock or data lanes.
2539 * This parameter can be any value of @arg DSI_Lane_Group
2540 * @param Value Custom value of the slew-rate or delay
2541 * @retval HAL status
2542 */
HAL_DSI_SetSlewRateAndDelayTuning(DSI_HandleTypeDef * hdsi,uint32_t CommDelay,uint32_t Lane,uint32_t Value)2543 HAL_StatusTypeDef HAL_DSI_SetSlewRateAndDelayTuning(DSI_HandleTypeDef *hdsi, uint32_t CommDelay, uint32_t Lane,
2544 uint32_t Value)
2545 {
2546 /* Process locked */
2547 __HAL_LOCK(hdsi);
2548
2549 /* Check function parameters */
2550 assert_param(IS_DSI_COMMUNICATION_DELAY(CommDelay));
2551 assert_param(IS_DSI_LANE_GROUP(Lane));
2552
2553 switch (CommDelay)
2554 {
2555 case DSI_SLEW_RATE_HSTX:
2556 if (Lane == DSI_CLOCK_LANE)
2557 {
2558 /* High-Speed Transmission Slew Rate Control on Clock Lane */
2559 hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_HSTXSRCCL;
2560 hdsi->Instance->WPCR[1U] |= Value << 16U;
2561 }
2562 else if (Lane == DSI_DATA_LANES)
2563 {
2564 /* High-Speed Transmission Slew Rate Control on Data Lanes */
2565 hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_HSTXSRCDL;
2566 hdsi->Instance->WPCR[1U] |= Value << 18U;
2567 }
2568 else
2569 {
2570 /* Process unlocked */
2571 __HAL_UNLOCK(hdsi);
2572
2573 return HAL_ERROR;
2574 }
2575 break;
2576 case DSI_SLEW_RATE_LPTX:
2577 if (Lane == DSI_CLOCK_LANE)
2578 {
2579 /* Low-Power transmission Slew Rate Compensation on Clock Lane */
2580 hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_LPSRCCL;
2581 hdsi->Instance->WPCR[1U] |= Value << 6U;
2582 }
2583 else if (Lane == DSI_DATA_LANES)
2584 {
2585 /* Low-Power transmission Slew Rate Compensation on Data Lanes */
2586 hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_LPSRCDL;
2587 hdsi->Instance->WPCR[1U] |= Value << 8U;
2588 }
2589 else
2590 {
2591 /* Process unlocked */
2592 __HAL_UNLOCK(hdsi);
2593
2594 return HAL_ERROR;
2595 }
2596 break;
2597 case DSI_HS_DELAY:
2598 if (Lane == DSI_CLOCK_LANE)
2599 {
2600 /* High-Speed Transmission Delay on Clock Lane */
2601 hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_HSTXDCL;
2602 hdsi->Instance->WPCR[1U] |= Value;
2603 }
2604 else if (Lane == DSI_DATA_LANES)
2605 {
2606 /* High-Speed Transmission Delay on Data Lanes */
2607 hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_HSTXDDL;
2608 hdsi->Instance->WPCR[1U] |= Value << 2U;
2609 }
2610 else
2611 {
2612 /* Process unlocked */
2613 __HAL_UNLOCK(hdsi);
2614
2615 return HAL_ERROR;
2616 }
2617 break;
2618 default:
2619 break;
2620 }
2621
2622 /* Process unlocked */
2623 __HAL_UNLOCK(hdsi);
2624
2625 return HAL_OK;
2626 }
2627
2628 /**
2629 * @brief Low-Power Reception Filter Tuning
2630 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
2631 * the configuration information for the DSI.
2632 * @param Frequency cutoff frequency of low-pass filter at the input of LPRX
2633 * @retval HAL status
2634 */
HAL_DSI_SetLowPowerRXFilter(DSI_HandleTypeDef * hdsi,uint32_t Frequency)2635 HAL_StatusTypeDef HAL_DSI_SetLowPowerRXFilter(DSI_HandleTypeDef *hdsi, uint32_t Frequency)
2636 {
2637 /* Process locked */
2638 __HAL_LOCK(hdsi);
2639
2640 /* Low-Power RX low-pass Filtering Tuning */
2641 hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_LPRXFT;
2642 hdsi->Instance->WPCR[1U] |= Frequency << 25U;
2643
2644 /* Process unlocked */
2645 __HAL_UNLOCK(hdsi);
2646
2647 return HAL_OK;
2648 }
2649
2650 /**
2651 * @brief Activate an additional current path on all lanes to meet the SDDTx parameter
2652 * defined in the MIPI D-PHY specification
2653 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
2654 * the configuration information for the DSI.
2655 * @param State ENABLE or DISABLE
2656 * @retval HAL status
2657 */
HAL_DSI_SetSDD(DSI_HandleTypeDef * hdsi,FunctionalState State)2658 HAL_StatusTypeDef HAL_DSI_SetSDD(DSI_HandleTypeDef *hdsi, FunctionalState State)
2659 {
2660 /* Process locked */
2661 __HAL_LOCK(hdsi);
2662
2663 /* Check function parameters */
2664 assert_param(IS_FUNCTIONAL_STATE(State));
2665
2666 /* Activate/Disactivate additional current path on all lanes */
2667 hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_SDDC;
2668 hdsi->Instance->WPCR[1U] |= ((uint32_t)State << 12U);
2669
2670 /* Process unlocked */
2671 __HAL_UNLOCK(hdsi);
2672
2673 return HAL_OK;
2674 }
2675
2676 /**
2677 * @brief Custom lane pins configuration
2678 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
2679 * the configuration information for the DSI.
2680 * @param CustomLane Function to be applied on selected lane.
2681 * This parameter can be any value of @arg DSI_CustomLane
2682 * @param Lane select between clock or data lane 0 or data lane 1.
2683 * This parameter can be any value of @arg DSI_Lane_Select
2684 * @param State ENABLE or DISABLE
2685 * @retval HAL status
2686 */
HAL_DSI_SetLanePinsConfiguration(DSI_HandleTypeDef * hdsi,uint32_t CustomLane,uint32_t Lane,FunctionalState State)2687 HAL_StatusTypeDef HAL_DSI_SetLanePinsConfiguration(DSI_HandleTypeDef *hdsi, uint32_t CustomLane, uint32_t Lane,
2688 FunctionalState State)
2689 {
2690 /* Process locked */
2691 __HAL_LOCK(hdsi);
2692
2693 /* Check function parameters */
2694 assert_param(IS_DSI_CUSTOM_LANE(CustomLane));
2695 assert_param(IS_DSI_LANE(Lane));
2696 assert_param(IS_FUNCTIONAL_STATE(State));
2697
2698 switch (CustomLane)
2699 {
2700 case DSI_SWAP_LANE_PINS:
2701 if (Lane == DSI_CLK_LANE)
2702 {
2703 /* Swap pins on clock lane */
2704 hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_SWCL;
2705 hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 6U);
2706 }
2707 else if (Lane == DSI_DATA_LANE0)
2708 {
2709 /* Swap pins on data lane 0 */
2710 hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_SWDL0;
2711 hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 7U);
2712 }
2713 else if (Lane == DSI_DATA_LANE1)
2714 {
2715 /* Swap pins on data lane 1 */
2716 hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_SWDL1;
2717 hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 8U);
2718 }
2719 else
2720 {
2721 /* Process unlocked */
2722 __HAL_UNLOCK(hdsi);
2723
2724 return HAL_ERROR;
2725 }
2726 break;
2727 case DSI_INVERT_HS_SIGNAL:
2728 if (Lane == DSI_CLK_LANE)
2729 {
2730 /* Invert HS signal on clock lane */
2731 hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_HSICL;
2732 hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 9U);
2733 }
2734 else if (Lane == DSI_DATA_LANE0)
2735 {
2736 /* Invert HS signal on data lane 0 */
2737 hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_HSIDL0;
2738 hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 10U);
2739 }
2740 else if (Lane == DSI_DATA_LANE1)
2741 {
2742 /* Invert HS signal on data lane 1 */
2743 hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_HSIDL1;
2744 hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 11U);
2745 }
2746 else
2747 {
2748 /* Process unlocked */
2749 __HAL_UNLOCK(hdsi);
2750
2751 return HAL_ERROR;
2752 }
2753 break;
2754 default:
2755 break;
2756 }
2757
2758 /* Process unlocked */
2759 __HAL_UNLOCK(hdsi);
2760
2761 return HAL_OK;
2762 }
2763
2764 /**
2765 * @brief Set custom timing for the PHY
2766 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
2767 * the configuration information for the DSI.
2768 * @param Timing PHY timing to be adjusted.
2769 * This parameter can be any value of @arg DSI_PHY_Timing
2770 * @param State ENABLE or DISABLE
2771 * @param Value Custom value of the timing
2772 * @retval HAL status
2773 */
HAL_DSI_SetPHYTimings(DSI_HandleTypeDef * hdsi,uint32_t Timing,FunctionalState State,uint32_t Value)2774 HAL_StatusTypeDef HAL_DSI_SetPHYTimings(DSI_HandleTypeDef *hdsi, uint32_t Timing, FunctionalState State, uint32_t Value)
2775 {
2776 /* Process locked */
2777 __HAL_LOCK(hdsi);
2778
2779 /* Check function parameters */
2780 assert_param(IS_DSI_PHY_TIMING(Timing));
2781 assert_param(IS_FUNCTIONAL_STATE(State));
2782
2783 switch (Timing)
2784 {
2785 case DSI_TCLK_POST:
2786 /* Enable/Disable custom timing setting */
2787 hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_TCLKPOSTEN;
2788 hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 27U);
2789
2790 if (State != DISABLE)
2791 {
2792 /* Set custom value */
2793 hdsi->Instance->WPCR[4U] &= ~DSI_WPCR4_TCLKPOST;
2794 hdsi->Instance->WPCR[4U] |= Value & DSI_WPCR4_TCLKPOST;
2795 }
2796
2797 break;
2798 case DSI_TLPX_CLK:
2799 /* Enable/Disable custom timing setting */
2800 hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_TLPXCEN;
2801 hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 26U);
2802
2803 if (State != DISABLE)
2804 {
2805 /* Set custom value */
2806 hdsi->Instance->WPCR[3U] &= ~DSI_WPCR3_TLPXC;
2807 hdsi->Instance->WPCR[3U] |= (Value << 24U) & DSI_WPCR3_TLPXC;
2808 }
2809
2810 break;
2811 case DSI_THS_EXIT:
2812 /* Enable/Disable custom timing setting */
2813 hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_THSEXITEN;
2814 hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 25U);
2815
2816 if (State != DISABLE)
2817 {
2818 /* Set custom value */
2819 hdsi->Instance->WPCR[3U] &= ~DSI_WPCR3_THSEXIT;
2820 hdsi->Instance->WPCR[3U] |= (Value << 16U) & DSI_WPCR3_THSEXIT;
2821 }
2822
2823 break;
2824 case DSI_TLPX_DATA:
2825 /* Enable/Disable custom timing setting */
2826 hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_TLPXDEN;
2827 hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 24U);
2828
2829 if (State != DISABLE)
2830 {
2831 /* Set custom value */
2832 hdsi->Instance->WPCR[3U] &= ~DSI_WPCR3_TLPXD;
2833 hdsi->Instance->WPCR[3U] |= (Value << 8U) & DSI_WPCR3_TLPXD;
2834 }
2835
2836 break;
2837 case DSI_THS_ZERO:
2838 /* Enable/Disable custom timing setting */
2839 hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_THSZEROEN;
2840 hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 23U);
2841
2842 if (State != DISABLE)
2843 {
2844 /* Set custom value */
2845 hdsi->Instance->WPCR[3U] &= ~DSI_WPCR3_THSZERO;
2846 hdsi->Instance->WPCR[3U] |= Value & DSI_WPCR3_THSZERO;
2847 }
2848
2849 break;
2850 case DSI_THS_TRAIL:
2851 /* Enable/Disable custom timing setting */
2852 hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_THSTRAILEN;
2853 hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 22U);
2854
2855 if (State != DISABLE)
2856 {
2857 /* Set custom value */
2858 hdsi->Instance->WPCR[2U] &= ~DSI_WPCR2_THSTRAIL;
2859 hdsi->Instance->WPCR[2U] |= (Value << 24U) & DSI_WPCR2_THSTRAIL;
2860 }
2861
2862 break;
2863 case DSI_THS_PREPARE:
2864 /* Enable/Disable custom timing setting */
2865 hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_THSPREPEN;
2866 hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 21U);
2867
2868 if (State != DISABLE)
2869 {
2870 /* Set custom value */
2871 hdsi->Instance->WPCR[2U] &= ~DSI_WPCR2_THSPREP;
2872 hdsi->Instance->WPCR[2U] |= (Value << 16U) & DSI_WPCR2_THSPREP;
2873 }
2874
2875 break;
2876 case DSI_TCLK_ZERO:
2877 /* Enable/Disable custom timing setting */
2878 hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_TCLKZEROEN;
2879 hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 20U);
2880
2881 if (State != DISABLE)
2882 {
2883 /* Set custom value */
2884 hdsi->Instance->WPCR[2U] &= ~DSI_WPCR2_TCLKZERO;
2885 hdsi->Instance->WPCR[2U] |= (Value << 8U) & DSI_WPCR2_TCLKZERO;
2886 }
2887
2888 break;
2889 case DSI_TCLK_PREPARE:
2890 /* Enable/Disable custom timing setting */
2891 hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_TCLKPREPEN;
2892 hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 19U);
2893
2894 if (State != DISABLE)
2895 {
2896 /* Set custom value */
2897 hdsi->Instance->WPCR[2U] &= ~DSI_WPCR2_TCLKPREP;
2898 hdsi->Instance->WPCR[2U] |= Value & DSI_WPCR2_TCLKPREP;
2899 }
2900
2901 break;
2902 default:
2903 break;
2904 }
2905
2906 /* Process unlocked */
2907 __HAL_UNLOCK(hdsi);
2908
2909 return HAL_OK;
2910 }
2911
2912 /**
2913 * @brief Force the Clock/Data Lane in TX Stop Mode
2914 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
2915 * the configuration information for the DSI.
2916 * @param Lane select between clock or data lanes.
2917 * This parameter can be any value of @arg DSI_Lane_Group
2918 * @param State ENABLE or DISABLE
2919 * @retval HAL status
2920 */
HAL_DSI_ForceTXStopMode(DSI_HandleTypeDef * hdsi,uint32_t Lane,FunctionalState State)2921 HAL_StatusTypeDef HAL_DSI_ForceTXStopMode(DSI_HandleTypeDef *hdsi, uint32_t Lane, FunctionalState State)
2922 {
2923 /* Process locked */
2924 __HAL_LOCK(hdsi);
2925
2926 /* Check function parameters */
2927 assert_param(IS_DSI_LANE_GROUP(Lane));
2928 assert_param(IS_FUNCTIONAL_STATE(State));
2929
2930 if (Lane == DSI_CLOCK_LANE)
2931 {
2932 /* Force/Unforce the Clock Lane in TX Stop Mode */
2933 hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_FTXSMCL;
2934 hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 12U);
2935 }
2936 else if (Lane == DSI_DATA_LANES)
2937 {
2938 /* Force/Unforce the Data Lanes in TX Stop Mode */
2939 hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_FTXSMDL;
2940 hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 13U);
2941 }
2942 else
2943 {
2944 /* Process unlocked */
2945 __HAL_UNLOCK(hdsi);
2946
2947 return HAL_ERROR;
2948 }
2949
2950 /* Process unlocked */
2951 __HAL_UNLOCK(hdsi);
2952
2953 return HAL_OK;
2954 }
2955
2956 /**
2957 * @brief Force LP Receiver in Low-Power Mode
2958 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
2959 * the configuration information for the DSI.
2960 * @param State ENABLE or DISABLE
2961 * @retval HAL status
2962 */
HAL_DSI_ForceRXLowPower(DSI_HandleTypeDef * hdsi,FunctionalState State)2963 HAL_StatusTypeDef HAL_DSI_ForceRXLowPower(DSI_HandleTypeDef *hdsi, FunctionalState State)
2964 {
2965 /* Process locked */
2966 __HAL_LOCK(hdsi);
2967
2968 /* Check function parameters */
2969 assert_param(IS_FUNCTIONAL_STATE(State));
2970
2971 /* Force/Unforce LP Receiver in Low-Power Mode */
2972 hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_FLPRXLPM;
2973 hdsi->Instance->WPCR[1U] |= ((uint32_t)State << 22U);
2974
2975 /* Process unlocked */
2976 __HAL_UNLOCK(hdsi);
2977
2978 return HAL_OK;
2979 }
2980
2981 /**
2982 * @brief Force Data Lanes in RX Mode after a BTA
2983 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
2984 * the configuration information for the DSI.
2985 * @param State ENABLE or DISABLE
2986 * @retval HAL status
2987 */
HAL_DSI_ForceDataLanesInRX(DSI_HandleTypeDef * hdsi,FunctionalState State)2988 HAL_StatusTypeDef HAL_DSI_ForceDataLanesInRX(DSI_HandleTypeDef *hdsi, FunctionalState State)
2989 {
2990 /* Process locked */
2991 __HAL_LOCK(hdsi);
2992
2993 /* Check function parameters */
2994 assert_param(IS_FUNCTIONAL_STATE(State));
2995
2996 /* Force Data Lanes in RX Mode */
2997 hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_TDDL;
2998 hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 16U);
2999
3000 /* Process unlocked */
3001 __HAL_UNLOCK(hdsi);
3002
3003 return HAL_OK;
3004 }
3005
3006 /**
3007 * @brief Enable a pull-down on the lanes to prevent from floating states when unused
3008 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
3009 * the configuration information for the DSI.
3010 * @param State ENABLE or DISABLE
3011 * @retval HAL status
3012 */
HAL_DSI_SetPullDown(DSI_HandleTypeDef * hdsi,FunctionalState State)3013 HAL_StatusTypeDef HAL_DSI_SetPullDown(DSI_HandleTypeDef *hdsi, FunctionalState State)
3014 {
3015 /* Process locked */
3016 __HAL_LOCK(hdsi);
3017
3018 /* Check function parameters */
3019 assert_param(IS_FUNCTIONAL_STATE(State));
3020
3021 /* Enable/Disable pull-down on lanes */
3022 hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_PDEN;
3023 hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 18U);
3024
3025 /* Process unlocked */
3026 __HAL_UNLOCK(hdsi);
3027
3028 return HAL_OK;
3029 }
3030
3031 /**
3032 * @brief Switch off the contention detection on data lanes
3033 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
3034 * the configuration information for the DSI.
3035 * @param State ENABLE or DISABLE
3036 * @retval HAL status
3037 */
HAL_DSI_SetContentionDetectionOff(DSI_HandleTypeDef * hdsi,FunctionalState State)3038 HAL_StatusTypeDef HAL_DSI_SetContentionDetectionOff(DSI_HandleTypeDef *hdsi, FunctionalState State)
3039 {
3040 /* Process locked */
3041 __HAL_LOCK(hdsi);
3042
3043 /* Check function parameters */
3044 assert_param(IS_FUNCTIONAL_STATE(State));
3045
3046 /* Contention Detection on Data Lanes OFF */
3047 hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_CDOFFDL;
3048 hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 14U);
3049
3050 /* Process unlocked */
3051 __HAL_UNLOCK(hdsi);
3052
3053 return HAL_OK;
3054 }
3055
3056 /**
3057 * @}
3058 */
3059
3060 /** @defgroup DSI_Group4 Peripheral State and Errors functions
3061 * @brief Peripheral State and Errors functions
3062 *
3063 @verbatim
3064 ===============================================================================
3065 ##### Peripheral State and Errors functions #####
3066 ===============================================================================
3067 [..]
3068 This subsection provides functions allowing to
3069 (+) Check the DSI state.
3070 (+) Get error code.
3071
3072 @endverbatim
3073 * @{
3074 */
3075
3076 /**
3077 * @brief Return the DSI state
3078 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
3079 * the configuration information for the DSI.
3080 * @retval HAL state
3081 */
HAL_DSI_GetState(DSI_HandleTypeDef * hdsi)3082 HAL_DSI_StateTypeDef HAL_DSI_GetState(DSI_HandleTypeDef *hdsi)
3083 {
3084 return hdsi->State;
3085 }
3086
3087 /**
3088 * @brief Return the DSI error code
3089 * @param hdsi pointer to a DSI_HandleTypeDef structure that contains
3090 * the configuration information for the DSI.
3091 * @retval DSI Error Code
3092 */
HAL_DSI_GetError(DSI_HandleTypeDef * hdsi)3093 uint32_t HAL_DSI_GetError(DSI_HandleTypeDef *hdsi)
3094 {
3095 /* Get the error code */
3096 return hdsi->ErrorCode;
3097 }
3098
3099 /**
3100 * @}
3101 */
3102
3103 /**
3104 * @}
3105 */
3106
3107 /**
3108 * @}
3109 */
3110
3111 #endif /* DSI */
3112
3113 #endif /* HAL_DSI_MODULE_ENABLED */
3114
3115 /**
3116 * @}
3117 */
3118