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