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