aboutsummaryrefslogtreecommitdiff
path: root/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_STM32F4/stm32f4xx_hal_cortex.h
blob: 93b2d5c9e272db5c43219624e4cbbdd3ca26c8e9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
/**
  ******************************************************************************
  * @file    stm32f4xx_hal_cortex.h
  * @author  MCD Application Team
  * @version V1.4.1
  * @date    09-October-2015
  * @brief   Header file of CORTEX HAL module.
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *   1. Redistributions of source code must retain the above copyright notice,
  *      this list of conditions and the following disclaimer.
  *   2. Redistributions in binary form must reproduce the above copyright notice,
  *      this list of conditions and the following disclaimer in the documentation
  *      and/or other materials provided with the distribution.
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
  *      may be used to endorse or promote products derived from this software
  *      without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ******************************************************************************
  */ 

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32F4xx_HAL_CORTEX_H
#define __STM32F4xx_HAL_CORTEX_H

#ifdef __cplusplus
 extern "C" {
#endif

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

/** @addtogroup STM32F4xx_HAL_Driver
  * @{
  */

/** @addtogroup CORTEX
  * @{
  */ 
/* Exported types ------------------------------------------------------------*/
/** @defgroup CORTEX_Exported_Types Cortex Exported Types
  * @{
  */

#if (__MPU_PRESENT == 1)
/** @defgroup CORTEX_MPU_Region_Initialization_Structure_definition MPU Region Initialization Structure Definition
  * @brief  MPU Region initialization structure 
  * @{
  */
typedef struct
{
  uint8_t                Enable;                /*!< Specifies the status of the region. 
                                                     This parameter can be a value of @ref CORTEX_MPU_Region_Enable                 */
  uint8_t                Number;                /*!< Specifies the number of the region to protect. 
                                                     This parameter can be a value of @ref CORTEX_MPU_Region_Number                 */
  uint32_t               BaseAddress;           /*!< Specifies the base address of the region to protect.                           */
  uint8_t                Size;                  /*!< Specifies the size of the region to protect. 
                                                     This parameter can be a value of @ref CORTEX_MPU_Region_Size                   */
  uint8_t                SubRegionDisable;      /*!< Specifies the number of the subregion protection to disable. 
                                                     This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF    */         
  uint8_t                TypeExtField;          /*!< Specifies the TEX field level.
                                                     This parameter can be a value of @ref CORTEX_MPU_TEX_Levels                    */                 
  uint8_t                AccessPermission;      /*!< Specifies the region access permission type. 
                                                     This parameter can be a value of @ref CORTEX_MPU_Region_Permission_Attributes  */
  uint8_t                DisableExec;           /*!< Specifies the instruction access status. 
                                                     This parameter can be a value of @ref CORTEX_MPU_Instruction_Access            */
  uint8_t                IsShareable;           /*!< Specifies the shareability status of the protected region. 
                                                     This parameter can be a value of @ref CORTEX_MPU_Access_Shareable              */
  uint8_t                IsCacheable;           /*!< Specifies the cacheable status of the region protected. 
                                                     This parameter can be a value of @ref CORTEX_MPU_Access_Cacheable              */
  uint8_t                IsBufferable;          /*!< Specifies the bufferable status of the protected region. 
                                                     This parameter can be a value of @ref CORTEX_MPU_Access_Bufferable             */
}MPU_Region_InitTypeDef;
/**
  * @}
  */
#endif /* __MPU_PRESENT */

/**
  * @}
  */

/* Exported constants --------------------------------------------------------*/

/** @defgroup CORTEX_Exported_Constants CORTEX Exported Constants
  * @{
  */

/** @defgroup CORTEX_Preemption_Priority_Group CORTEX Preemption Priority Group
  * @{
  */
#define NVIC_PRIORITYGROUP_0         ((uint32_t)0x00000007) /*!< 0 bits for pre-emption priority
                                                                 4 bits for subpriority */
#define NVIC_PRIORITYGROUP_1         ((uint32_t)0x00000006) /*!< 1 bits for pre-emption priority
                                                                 3 bits for subpriority */
#define NVIC_PRIORITYGROUP_2         ((uint32_t)0x00000005) /*!< 2 bits for pre-emption priority
                                                                 2 bits for subpriority */
#define NVIC_PRIORITYGROUP_3         ((uint32_t)0x00000004) /*!< 3 bits for pre-emption priority
                                                                 1 bits for subpriority */
#define NVIC_PRIORITYGROUP_4         ((uint32_t)0x00000003) /*!< 4 bits for pre-emption priority
                                                                 0 bits for subpriority */
/**
  * @}
  */

/** @defgroup CORTEX_SysTick_clock_source CORTEX _SysTick clock source 
  * @{
  */
#define SYSTICK_CLKSOURCE_HCLK_DIV8    ((uint32_t)0x00000000)
#define SYSTICK_CLKSOURCE_HCLK         ((uint32_t)0x00000004)

/**
  * @}
  */

#if (__MPU_PRESENT == 1)
/** @defgroup CORTEX_MPU_HFNMI_PRIVDEF_Control MPU HFNMI and PRIVILEGED Access control
  * @{
  */
#define  MPU_HFNMI_PRIVDEF_NONE      ((uint32_t)0x00000000)  
#define  MPU_HARDFAULT_NMI           ((uint32_t)0x00000002)
#define  MPU_PRIVILEGED_DEFAULT      ((uint32_t)0x00000004)
#define  MPU_HFNMI_PRIVDEF           ((uint32_t)0x00000006)
/**
  * @}
  */

/** @defgroup CORTEX_MPU_Region_Enable CORTEX MPU Region Enable
  * @{
  */
#define  MPU_REGION_ENABLE     ((uint8_t)0x01)
#define  MPU_REGION_DISABLE    ((uint8_t)0x00)
/**
  * @}
  */

/** @defgroup CORTEX_MPU_Instruction_Access CORTEX MPU Instruction Access
  * @{
  */
#define  MPU_INSTRUCTION_ACCESS_ENABLE      ((uint8_t)0x00)
#define  MPU_INSTRUCTION_ACCESS_DISABLE     ((uint8_t)0x01)
/**
  * @}
  */

/** @defgroup CORTEX_MPU_Access_Shareable CORTEX MPU Instruction Access Shareable
  * @{
  */
#define  MPU_ACCESS_SHAREABLE        ((uint8_t)0x01)
#define  MPU_ACCESS_NOT_SHAREABLE    ((uint8_t)0x00)
/**
  * @}
  */

/** @defgroup CORTEX_MPU_Access_Cacheable CORTEX MPU Instruction Access Cacheable
  * @{
  */
#define  MPU_ACCESS_CACHEABLE         ((uint8_t)0x01)
#define  MPU_ACCESS_NOT_CACHEABLE     ((uint8_t)0x00)
/**
  * @}
  */

/** @defgroup CORTEX_MPU_Access_Bufferable CORTEX MPU Instruction Access Bufferable
  * @{
  */
#define  MPU_ACCESS_BUFFERABLE         ((uint8_t)0x01)
#define  MPU_ACCESS_NOT_BUFFERABLE     ((uint8_t)0x00)
/**
  * @}
  */

/** @defgroup CORTEX_MPU_TEX_Levels MPU TEX Levels
  * @{
  */
#define  MPU_TEX_LEVEL0    ((uint8_t)0x00)
#define  MPU_TEX_LEVEL1    ((uint8_t)0x01)
#define  MPU_TEX_LEVEL2    ((uint8_t)0x02)
/**
  * @}
  */

/** @defgroup CORTEX_MPU_Region_Size CORTEX MPU Region Size
  * @{
  */
#define   MPU_REGION_SIZE_32B      ((uint8_t)0x04)
#define   MPU_REGION_SIZE_64B      ((uint8_t)0x05)
#define   MPU_REGION_SIZE_128B     ((uint8_t)0x06) 
#define   MPU_REGION_SIZE_256B     ((uint8_t)0x07) 
#define   MPU_REGION_SIZE_512B     ((uint8_t)0x08) 
#define   MPU_REGION_SIZE_1KB      ((uint8_t)0x09)  
#define   MPU_REGION_SIZE_2KB      ((uint8_t)0x0A)
#define   MPU_REGION_SIZE_4KB      ((uint8_t)0x0B) 
#define   MPU_REGION_SIZE_8KB      ((uint8_t)0x0C) 
#define   MPU_REGION_SIZE_16KB     ((uint8_t)0x0D) 
#define   MPU_REGION_SIZE_32KB     ((uint8_t)0x0E) 
#define   MPU_REGION_SIZE_64KB     ((uint8_t)0x0F) 
#define   MPU_REGION_SIZE_128KB    ((uint8_t)0x10)
#define   MPU_REGION_SIZE_256KB    ((uint8_t)0x11)
#define   MPU_REGION_SIZE_512KB    ((uint8_t)0x12)
#define   MPU_REGION_SIZE_1MB      ((uint8_t)0x13) 
#define   MPU_REGION_SIZE_2MB      ((uint8_t)0x14) 
#define   MPU_REGION_SIZE_4MB      ((uint8_t)0x15) 
#define   MPU_REGION_SIZE_8MB      ((uint8_t)0x16) 
#define   MPU_REGION_SIZE_16MB     ((uint8_t)0x17)
#define   MPU_REGION_SIZE_32MB     ((uint8_t)0x18)
#define   MPU_REGION_SIZE_64MB     ((uint8_t)0x19)
#define   MPU_REGION_SIZE_128MB    ((uint8_t)0x1A)
#define   MPU_REGION_SIZE_256MB    ((uint8_t)0x1B)
#define   MPU_REGION_SIZE_512MB    ((uint8_t)0x1C)
#define   MPU_REGION_SIZE_1GB      ((uint8_t)0x1D) 
#define   MPU_REGION_SIZE_2GB      ((uint8_t)0x1E) 
#define   MPU_REGION_SIZE_4GB      ((uint8_t)0x1F)
/**                                
  * @}
  */
   
/** @defgroup CORTEX_MPU_Region_Permission_Attributes CORTEX MPU Region Permission Attributes 
  * @{
  */
#define  MPU_REGION_NO_ACCESS      ((uint8_t)0x00)  
#define  MPU_REGION_PRIV_RW        ((uint8_t)0x01) 
#define  MPU_REGION_PRIV_RW_URO    ((uint8_t)0x02)  
#define  MPU_REGION_FULL_ACCESS    ((uint8_t)0x03)  
#define  MPU_REGION_PRIV_RO        ((uint8_t)0x05) 
#define  MPU_REGION_PRIV_RO_URO    ((uint8_t)0x06)
/**
  * @}
  */

/** @defgroup CORTEX_MPU_Region_Number CORTEX MPU Region Number
  * @{
  */
#define  MPU_REGION_NUMBER0    ((uint8_t)0x00)  
#define  MPU_REGION_NUMBER1    ((uint8_t)0x01) 
#define  MPU_REGION_NUMBER2    ((uint8_t)0x02)  
#define  MPU_REGION_NUMBER3    ((uint8_t)0x03)  
#define  MPU_REGION_NUMBER4    ((uint8_t)0x04) 
#define  MPU_REGION_NUMBER5    ((uint8_t)0x05)
#define  MPU_REGION_NUMBER6    ((uint8_t)0x06)
#define  MPU_REGION_NUMBER7    ((uint8_t)0x07)
/**
  * @}
  */
#endif /* __MPU_PRESENT */

/**
  * @}
  */


/* Exported Macros -----------------------------------------------------------*/
/** @defgroup CORTEX_Exported_Macros CORTEX Exported Macros
  * @{
  */

/** @brief Configures the SysTick clock source.
  * @param __CLKSRC__: specifies the SysTick clock source.
  *   This parameter can be one of the following values:
  *     @arg SYSTICK_CLKSOURCE_HCLK_DIV8: AHB clock divided by 8 selected as SysTick clock source.
  *     @arg SYSTICK_CLKSOURCE_HCLK: AHB clock selected as SysTick clock source.
  * @retval None
  */
#define __HAL_CORTEX_SYSTICKCLK_CONFIG(__CLKSRC__)                             \
                            do {                                               \
                                 if ((__CLKSRC__) == SYSTICK_CLKSOURCE_HCLK)   \
                                  {                                            \
                                    SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK;   \
                                  }                                            \
                                 else                                          \
                                    SysTick->CTRL &= ~SYSTICK_CLKSOURCE_HCLK;  \
                                } while(0)
/**
  * @}
  */

/* Exported functions --------------------------------------------------------*/
/** @addtogroup CORTEX_Exported_Functions
  * @{
  */
  
/** @addtogroup CORTEX_Exported_Functions_Group1
 * @{
 */
/* Initialization and de-initialization functions *****************************/
void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup);
void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority);
void HAL_NVIC_EnableIRQ(IRQn_Type IRQn);
void HAL_NVIC_DisableIRQ(IRQn_Type IRQn);
void HAL_NVIC_SystemReset(void);
uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb);
/**
  * @}
  */

/** @addtogroup CORTEX_Exported_Functions_Group2
 * @{
 */
/* Peripheral Control functions ***********************************************/
#if (__MPU_PRESENT == 1)
void HAL_MPU_ConfigRegion(MPU_Region_InitTypeDef *MPU_Init);
#endif /* __MPU_PRESENT */
uint32_t HAL_NVIC_GetPriorityGrouping(void);
void HAL_NVIC_GetPriority(IRQn_Type IRQn, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority);
uint32_t HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn);
void HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn);
void HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn);
uint32_t HAL_NVIC_GetActive(IRQn_Type IRQn);
void HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource);
void HAL_SYSTICK_IRQHandler(void);
void HAL_SYSTICK_Callback(void);
/**
  * @}
  */

/**
  * @}
  */

/* Private types -------------------------------------------------------------*/ 
/* Private variables ---------------------------------------------------------*/
/* Private constants ---------------------------------------------------------*/
/* Private macros ------------------------------------------------------------*/
/** @defgroup CORTEX_Private_Macros CORTEX Private Macros
  * @{
  */
#define IS_NVIC_PRIORITY_GROUP(GROUP) (((GROUP) == NVIC_PRIORITYGROUP_0) || \
                                       ((GROUP) == NVIC_PRIORITYGROUP_1) || \
                                       ((GROUP) == NVIC_PRIORITYGROUP_2) || \
                                       ((GROUP) == NVIC_PRIORITYGROUP_3) || \
                                       ((GROUP) == NVIC_PRIORITYGROUP_4))

#define IS_NVIC_PREEMPTION_PRIORITY(PRIORITY)  ((PRIORITY) < 0x10)

#define IS_NVIC_SUB_PRIORITY(PRIORITY)         ((PRIORITY) < 0x10)

#define IS_NVIC_DEVICE_IRQ(IRQ)                ((IRQ) >= 0x00)

#define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SYSTICK_CLKSOURCE_HCLK) || \
                                       ((SOURCE) == SYSTICK_CLKSOURCE_HCLK_DIV8))

#if (__MPU_PRESENT == 1)
#define IS_MPU_REGION_ENABLE(STATE) (((STATE) == MPU_REGION_ENABLE) || \
                                     ((STATE) == MPU_REGION_DISABLE))

#define IS_MPU_INSTRUCTION_ACCESS(STATE) (((STATE) == MPU_INSTRUCTION_ACCESS_ENABLE) || \
                                          ((STATE) == MPU_INSTRUCTION_ACCESS_DISABLE))

#define IS_MPU_ACCESS_SHAREABLE(STATE)   (((STATE) == MPU_ACCESS_SHAREABLE) || \
                                          ((STATE) == MPU_ACCESS_NOT_SHAREABLE))

#define IS_MPU_ACCESS_CACHEABLE(STATE)   (((STATE) == MPU_ACCESS_CACHEABLE) || \
                                          ((STATE) == MPU_ACCESS_NOT_CACHEABLE))

#define IS_MPU_ACCESS_BUFFERABLE(STATE)   (((STATE) == MPU_ACCESS_BUFFERABLE) || \
                                          ((STATE) == MPU_ACCESS_NOT_BUFFERABLE))

#define IS_MPU_TEX_LEVEL(TYPE) (((TYPE) == MPU_TEX_LEVEL0)  || \
                                ((TYPE) == MPU_TEX_LEVEL1)  || \
                                ((TYPE) == MPU_TEX_LEVEL2))

#define IS_MPU_REGION_PERMISSION_ATTRIBUTE(TYPE) (((TYPE) == MPU_REGION_NO_ACCESS)   || \
                                                  ((TYPE) == MPU_REGION_PRIV_RW)     || \
                                                  ((TYPE) == MPU_REGION_PRIV_RW_URO) || \
                                                  ((TYPE) == MPU_REGION_FULL_ACCESS) || \
                                                  ((TYPE) == MPU_REGION_PRIV_RO)     || \
                                                  ((TYPE) == MPU_REGION_PRIV_RO_URO))

#define IS_MPU_REGION_NUMBER(NUMBER)    (((NUMBER) == MPU_REGION_NUMBER0) || \
                                         ((NUMBER) == MPU_REGION_NUMBER1) || \
                                         ((NUMBER) == MPU_REGION_NUMBER2) || \
                                         ((NUMBER) == MPU_REGION_NUMBER3) || \
                                         ((NUMBER) == MPU_REGION_NUMBER4) || \
                                         ((NUMBER) == MPU_REGION_NUMBER5) || \
                                         ((NUMBER) == MPU_REGION_NUMBER6) || \
                                         ((NUMBER) == MPU_REGION_NUMBER7))

#define IS_MPU_REGION_SIZE(SIZE)    (((SIZE) == MPU_REGION_SIZE_32B)   || \
                                     ((SIZE) == MPU_REGION_SIZE_64B)   || \
                                     ((SIZE) == MPU_REGION_SIZE_128B)  || \
                                     ((SIZE) == MPU_REGION_SIZE_256B)  || \
                                     ((SIZE) == MPU_REGION_SIZE_512B)  || \
                                     ((SIZE) == MPU_REGION_SIZE_1KB)   || \
                                     ((SIZE) == MPU_REGION_SIZE_2KB)   || \
                                     ((SIZE) == MPU_REGION_SIZE_4KB)   || \
                                     ((SIZE) == MPU_REGION_SIZE_8KB)   || \
                                     ((SIZE) == MPU_REGION_SIZE_16KB)  || \
                                     ((SIZE) == MPU_REGION_SIZE_32KB)  || \
                                     ((SIZE) == MPU_REGION_SIZE_64KB)  || \
                                     ((SIZE) == MPU_REGION_SIZE_128KB) || \
                                     ((SIZE) == MPU_REGION_SIZE_256KB) || \
                                     ((SIZE) == MPU_REGION_SIZE_512KB) || \
                                     ((SIZE) == MPU_REGION_SIZE_1MB)   || \
                                     ((SIZE) == MPU_REGION_SIZE_2MB)   || \
                                     ((SIZE) == MPU_REGION_SIZE_4MB)   || \
                                     ((SIZE) == MPU_REGION_SIZE_8MB)   || \
                                     ((SIZE) == MPU_REGION_SIZE_16MB)  || \
                                     ((SIZE) == MPU_REGION_SIZE_32MB)  || \
                                     ((SIZE) == MPU_REGION_SIZE_64MB)  || \
                                     ((SIZE) == MPU_REGION_SIZE_128MB) || \
                                     ((SIZE) == MPU_REGION_SIZE_256MB) || \
                                     ((SIZE) == MPU_REGION_SIZE_512MB) || \
                                     ((SIZE) == MPU_REGION_SIZE_1GB)   || \
                                     ((SIZE) == MPU_REGION_SIZE_2GB)   || \
                                     ((SIZE) == MPU_REGION_SIZE_4GB))

#define IS_MPU_SUB_REGION_DISABLE(SUBREGION)  ((SUBREGION) < (uint16_t)0x00FF)
#endif /* __MPU_PRESENT */

/**                                                                          
  * @}                                                                  
  */                                                                            
                                                                                   
/* Private functions ---------------------------------------------------------*/   
/** @defgroup CORTEX_Private_Functions CORTEX Private Functions
  * @brief    CORTEX private  functions 
  * @{
  */

#if (__MPU_PRESENT == 1)
/**
  * @brief  Disables the MPU
  * @retval None
  */
__STATIC_INLINE void HAL_MPU_Disable(void)
{
  /* Disable fault exceptions */
  SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
  
  /* Disable the MPU */
  MPU->CTRL  &= ~MPU_CTRL_ENABLE_Msk;
}

/**
  * @brief  Enables the MPU
  * @param  MPU_Control: Specifies the control mode of the MPU during hard fault, 
  *          NMI, FAULTMASK and privileged access to the default memory 
  *          This parameter can be one of the following values:
  *            @arg MPU_HFNMI_PRIVDEF_NONE
  *            @arg MPU_HARDFAULT_NMI
  *            @arg MPU_PRIVILEGED_DEFAULT
  *            @arg MPU_HFNMI_PRIVDEF
  * @retval None
  */
__STATIC_INLINE void HAL_MPU_Enable(uint32_t MPU_Control)
{
  /* Enable the MPU */
  MPU->CTRL   = MPU_Control | MPU_CTRL_ENABLE_Msk;
  
  /* Enable fault exceptions */
  SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
}
#endif /* __MPU_PRESENT */

/**
  * @}
  */

/**
  * @}
  */ 

/**
  * @}
  */
  
#ifdef __cplusplus
}
#endif

#endif /* __STM32F4xx_HAL_CORTEX_H */
 

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
href='#n1719'>1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244
/**
  ******************************************************************************
  * @file    stm32f4xx_hal_dsi.c
  * @author  MCD Application Team
  * @version V1.4.1
  * @date    09-October-2015
  * @brief   DSI HAL module driver.
  *          This file provides firmware functions to manage the following 
  *          functionalities of the DSI peripheral:
  *           + Initialization and de-initialization functions
  *           + IO operation functions
  *           + Peripheral Control functions  
  *           + Peripheral State and Errors functions
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *   1. Redistributions of source code must retain the above copyright notice,
  *      this list of conditions and the following disclaimer.
  *   2. Redistributions in binary form must reproduce the above copyright notice,
  *      this list of conditions and the following disclaimer in the documentation
  *      and/or other materials provided with the distribution.
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
  *      may be used to endorse or promote products derived from this software
  *      without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ******************************************************************************
  */ 

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

/** @addtogroup STM32F4xx_HAL_Driver
  * @{
  */
/** @addtogroup DSI
  * @{
  */

#ifdef HAL_DSI_MODULE_ENABLED

#if defined(STM32F469xx) || defined(STM32F479xx)

/* Private types -------------------------------------------------------------*/
/* Private defines -----------------------------------------------------------*/
/** @addtogroup DSI_Private_Constants
  * @{
  */
#define DSI_TIMEOUT_VALUE ((uint32_t)1000)  /* 1s */

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

/* Private variables ---------------------------------------------------------*/
/* Private constants ---------------------------------------------------------*/
/* Private macros ------------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
static void DSI_ConfigPacketHeader(DSI_TypeDef *DSIx, uint32_t ChannelID, uint32_t DataType, uint32_t Data0, uint32_t Data1);

/* Private functions ---------------------------------------------------------*/
/**
  * @brief  Generic DSI packet header configuration
  * @param  DSIx: Pointer to DSI register base
  * @param  ChannelID: Virtual channel ID of the header packet
  * @param  DataType: Packet data type of the header packet
  *                   This parameter can be any value of :
  *                      @ref DSI_SHORT_WRITE_PKT_Data_Type
  *                   or @ref DSI_LONG_WRITE_PKT_Data_Type
  *                   or @ref DSI_SHORT_READ_PKT_Data_Type
  *                   or DSI_MAX_RETURN_PKT_SIZE
  * @param  Data0: Word count LSB
  * @param  Data1: Word count MSB
  * @retval None
  */
static void DSI_ConfigPacketHeader(DSI_TypeDef *DSIx,
                                   uint32_t ChannelID,
                                   uint32_t DataType,
                                   uint32_t Data0,
                                   uint32_t Data1)
{
  /* Update the DSI packet header with new information */
  DSIx->GHCR = (DataType | (ChannelID<<6) | (Data0<<8) | (Data1<<16));
}

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

/** @defgroup DSI_Group1 Initialization and Configuration functions
 *  @brief   Initialization and Configuration functions
 *
@verbatim   
 ===============================================================================
                ##### Initialization and Configuration functions #####
 ===============================================================================  
    [..]  This section provides functions allowing to:
      (+) Initialize and configure the DSI
      (+) De-initialize the DSI 

@endverbatim
  * @{
  */
  
/**
  * @brief  Initializes the DSI according to the specified
  *         parameters in the DSI_InitTypeDef and create the associated handle.
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @param  PLLInit: pointer to a DSI_PLLInitTypeDef structure that contains
  *               the PLL Clock structure definition for the DSI.  
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_Init(DSI_HandleTypeDef *hdsi, DSI_PLLInitTypeDef *PLLInit)
{
  uint32_t tickstart = 0;
  uint32_t unitIntervalx4 = 0;
  uint32_t tempIDF = 0;
  
  /* Check the DSI handle allocation */
  if(hdsi == NULL)
  {
    return HAL_ERROR;
  }
  
  /* Check function parameters */
  assert_param(IS_DSI_PLL_NDIV(PLLInit->PLLNDIV));
  assert_param(IS_DSI_PLL_IDF(PLLInit->PLLIDF));
  assert_param(IS_DSI_PLL_ODF(PLLInit->PLLODF));
  assert_param(IS_DSI_AUTO_CLKLANE_CONTROL(hdsi->Init.AutomaticClockLaneControl));
  assert_param(IS_DSI_NUMBER_OF_LANES(hdsi->Init.NumberOfLanes));
  
  if(hdsi->State == HAL_DSI_STATE_RESET)
  {
    /* Initialize the low level hardware */
    HAL_DSI_MspInit(hdsi);
  }
  
  /* Change DSI peripheral state */
  hdsi->State = HAL_DSI_STATE_BUSY;
  
  /**************** Turn on the regulator and enable the DSI PLL ****************/
  
    /* Enable the regulator */
    __HAL_DSI_REG_ENABLE(hdsi);
    
	/* Get tick */ 
    tickstart = HAL_GetTick();
	
    /* Wait until the regulator is ready */
	while(__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_RRS) == RESET)
    {
      /* Check for the Timeout */
      if((HAL_GetTick() - tickstart ) > DSI_TIMEOUT_VALUE)
      {
        return HAL_TIMEOUT;
      }
    }
    
    /* Set the PLL division factors */
    hdsi->Instance->WRPCR &= ~(DSI_WRPCR_PLL_NDIV | DSI_WRPCR_PLL_IDF | DSI_WRPCR_PLL_ODF);
    hdsi->Instance->WRPCR |= (((PLLInit->PLLNDIV)<<2) | ((PLLInit->PLLIDF)<<11) | ((PLLInit->PLLODF)<<16));
    
    /* Enable the DSI PLL */
    __HAL_DSI_PLL_ENABLE(hdsi);
    
	/* Get tick */ 
    tickstart = HAL_GetTick();
	
    /* Wait for the lock of the PLL */
    while(__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_PLLLS) == RESET)
    {
      /* Check for the Timeout */
      if((HAL_GetTick() - tickstart ) > DSI_TIMEOUT_VALUE)
      {
        return HAL_TIMEOUT;
      }
    }
  
  /*************************** Set the PHY parameters ***************************/
  
    /* D-PHY clock and digital enable*/
    hdsi->Instance->PCTLR |= (DSI_PCTLR_CKE | DSI_PCTLR_DEN);
    
    /* Clock lane configuration */
    hdsi->Instance->CLCR &= ~(DSI_CLCR_DPCC | DSI_CLCR_ACR);
    hdsi->Instance->CLCR |= (DSI_CLCR_DPCC | hdsi->Init.AutomaticClockLaneControl);
    
    /* Configure the number of active data lanes */
    hdsi->Instance->PCONFR &= ~DSI_PCONFR_NL;
    hdsi->Instance->PCONFR |= hdsi->Init.NumberOfLanes;
  
  /************************ Set the DSI clock parameters ************************/
  
    /* Set the TX escape clock division factor */
    hdsi->Instance->CCR &= ~DSI_CCR_TXECKDIV;
    hdsi->Instance->CCR = hdsi->Init.TXEscapeCkdiv;
    
    /* Calculate the bit period in high-speed mode in unit of 0.25 ns (UIX4) */
    /* The equation is : UIX4 = IntegerPart( (1000/F_PHY_Mhz) * 4 )          */
    /* Where : F_PHY_Mhz = (NDIV * HSE_Mhz) / (IDF * ODF)                    */
    tempIDF = (PLLInit->PLLIDF > 0) ? PLLInit->PLLIDF : 1;
    unitIntervalx4 = (4000000 * tempIDF * (1 << PLLInit->PLLODF)) / ((HSE_VALUE/1000) * PLLInit->PLLNDIV);
	
    /* Set the bit period in high-speed mode */
    hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_UIX4;
    hdsi->Instance->WPCR[0] |= unitIntervalx4;
  
  /****************************** Error management *****************************/
  
    /* Disable all error interrupts and reset the Error Mask */
    hdsi->Instance->IER[0] = 0;
    hdsi->Instance->IER[1] = 0;
    hdsi->ErrorMsk = 0;
    
    /* Initialise the error code */
    hdsi->ErrorCode = HAL_DSI_ERROR_NONE;
  
  /* Initialize the DSI state*/
  hdsi->State = HAL_DSI_STATE_READY;
  
  return HAL_OK;
}

/**
  * @brief  De-initializes the DSI peripheral registers to their default reset
  *         values.
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_DeInit(DSI_HandleTypeDef *hdsi)
{
  /* Check the DSI handle allocation */
  if(hdsi == NULL)
  {
    return HAL_ERROR;
  }
  
  /* Change DSI peripheral state */
  hdsi->State = HAL_DSI_STATE_BUSY;
  
  /* Disable the DSI wrapper */
  __HAL_DSI_WRAPPER_DISABLE(hdsi);
  
  /* Disable the DSI host */
  __HAL_DSI_DISABLE(hdsi);
  
  /* D-PHY clock and digital disable */
  hdsi->Instance->PCTLR &= ~(DSI_PCTLR_CKE | DSI_PCTLR_DEN);
  
  /* Turn off the DSI PLL */
  __HAL_DSI_PLL_DISABLE(hdsi);
  
  /* Disable the regulator */
  __HAL_DSI_REG_DISABLE(hdsi);
  
  /* DeInit the low level hardware */
  HAL_DSI_MspDeInit(hdsi); 
  
  /* Initialise the error code */
  hdsi->ErrorCode = HAL_DSI_ERROR_NONE;
  
  /* Initialize the DSI state*/
  hdsi->State = HAL_DSI_STATE_RESET;
  
  /* Release Lock */
  __HAL_UNLOCK(hdsi);
  
  return HAL_OK;
}

/**
  * @brief  Return the DSI error code
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @retval DSI Error Code
  */
uint32_t HAL_DSI_GetError(DSI_HandleTypeDef *hdsi)
{
  /* Get the error code */
  return hdsi->ErrorCode;
}

/**
  * @brief  Enable the error monitor flags 
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @param  ActiveErrors: indicates which error interrupts will be enabled.
  *                      This parameter can be any combination of @ref DSI_Error_Data_Type.
  * @retval HAL status 
  */
HAL_StatusTypeDef HAL_DSI_ConfigErrorMonitor(DSI_HandleTypeDef *hdsi, uint32_t ActiveErrors)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
  
  hdsi->Instance->IER[0] = 0;
  hdsi->Instance->IER[1] = 0;
  
  /* Store active errors to the handle */
  hdsi->ErrorMsk = ActiveErrors;
  
  if(ActiveErrors & HAL_DSI_ERROR_ACK)
  {
    /* Enable the interrupt generation on selected errors */
    hdsi->Instance->IER[0] |= DSI_ERROR_ACK_MASK;
  }
  
  if(ActiveErrors & HAL_DSI_ERROR_PHY)
  {
    /* Enable the interrupt generation on selected errors */
    hdsi->Instance->IER[0] |= DSI_ERROR_PHY_MASK;
  }
  
  if(ActiveErrors & HAL_DSI_ERROR_TX)
  {
    /* Enable the interrupt generation on selected errors */
    hdsi->Instance->IER[1] |= DSI_ERROR_TX_MASK;
  }
  
  if(ActiveErrors & HAL_DSI_ERROR_RX)
  {
    /* Enable the interrupt generation on selected errors */
    hdsi->Instance->IER[1] |= DSI_ERROR_RX_MASK;
  }
  
  if(ActiveErrors & HAL_DSI_ERROR_ECC)
  {
    /* Enable the interrupt generation on selected errors */
    hdsi->Instance->IER[1] |= DSI_ERROR_ECC_MASK;
  }
  
  if(ActiveErrors & HAL_DSI_ERROR_CRC)
  {
    /* Enable the interrupt generation on selected errors */
    hdsi->Instance->IER[1] |= DSI_ERROR_CRC_MASK;
  }
  
  if(ActiveErrors & HAL_DSI_ERROR_PSE)
  {
    /* Enable the interrupt generation on selected errors */
    hdsi->Instance->IER[1] |= DSI_ERROR_PSE_MASK;
  }
  
  if(ActiveErrors & HAL_DSI_ERROR_EOT)
  {
    /* Enable the interrupt generation on selected errors */
    hdsi->Instance->IER[1] |= DSI_ERROR_EOT_MASK;
  }
  
  if(ActiveErrors & HAL_DSI_ERROR_OVF)
  {
    /* Enable the interrupt generation on selected errors */
    hdsi->Instance->IER[1] |= DSI_ERROR_OVF_MASK;
  }
  
  if(ActiveErrors & HAL_DSI_ERROR_GEN)
  {
    /* Enable the interrupt generation on selected errors */
    hdsi->Instance->IER[1] |= DSI_ERROR_GEN_MASK;
  }
  
  /* Process Unlocked */
  __HAL_UNLOCK(hdsi);
  
  return HAL_OK;
}

/**
  * @brief  Initializes the DSI MSP.
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @retval None
  */
__weak void HAL_DSI_MspInit(DSI_HandleTypeDef* hdsi)
{
  /* NOTE : This function Should not be modified, when the callback is needed,
            the HAL_DSI_MspInit could be implemented in the user file
   */ 
}

/**
  * @brief  De-initializes the DSI MSP.
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @retval None
  */
__weak void HAL_DSI_MspDeInit(DSI_HandleTypeDef* hdsi)
{
  /* NOTE : This function Should not be modified, when the callback is needed,
            the HAL_DSI_MspDeInit could be implemented in the user file
   */
}

/**
  * @}
  */
  
/** @defgroup DSI_Group2 IO operation functions 
 *  @brief    IO operation functions  
 *
@verbatim
 ===============================================================================
                      #####  IO operation functions  #####
 ===============================================================================  
    [..]  This section provides function allowing to:
      (+) Handle DSI interrupt request

@endverbatim
  * @{
  */
/**
  * @brief  Handles DSI interrupt request.
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.  
  * @retval HAL status
  */
void HAL_DSI_IRQHandler(DSI_HandleTypeDef *hdsi)
{
  uint32_t ErrorStatus0, ErrorStatus1;
  
  /* Tearing Effect Interrupt management ***************************************/
  if(__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_TE) != RESET)
  {
    if(__HAL_DSI_GET_IT_SOURCE(hdsi, DSI_IT_TE) != RESET)
    {
      /* Clear the Tearing Effect Interrupt Flag */
      __HAL_DSI_CLEAR_FLAG(hdsi, DSI_FLAG_TE);
      
      /* Tearing Effect Callback */
      HAL_DSI_TearingEffectCallback(hdsi);
    }
  }
  
  /* End of Refresh Interrupt management ***************************************/
  if(__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_ER) != RESET)
  {
    if(__HAL_DSI_GET_IT_SOURCE(hdsi, DSI_IT_ER) != RESET)
    {
      /* Clear the End of Refresh Interrupt Flag */
      __HAL_DSI_CLEAR_FLAG(hdsi, DSI_FLAG_ER);
      
      /* End of Refresh Callback */
      HAL_DSI_EndOfRefreshCallback(hdsi);
    }
  }
  
  /* Error Interrupts management ***********************************************/
  if(hdsi->ErrorMsk != 0)
  {
    ErrorStatus0 = hdsi->Instance->ISR[0];
    ErrorStatus0 &= hdsi->Instance->IER[0];
    ErrorStatus1 = hdsi->Instance->ISR[1];
    ErrorStatus1 &= hdsi->Instance->IER[1];
    
    if(ErrorStatus0 & DSI_ERROR_ACK_MASK)
    {
      hdsi->ErrorCode |= HAL_DSI_ERROR_ACK;
    }
    
    if(ErrorStatus0 & DSI_ERROR_PHY_MASK)
    {
      hdsi->ErrorCode |= HAL_DSI_ERROR_PHY;
    }
    
    if(ErrorStatus1 & DSI_ERROR_TX_MASK)
    {
      hdsi->ErrorCode |= HAL_DSI_ERROR_TX;
    }
    
    if(ErrorStatus1 & DSI_ERROR_RX_MASK)
    {
      hdsi->ErrorCode |= HAL_DSI_ERROR_RX;
    }
    
    if(ErrorStatus1 & DSI_ERROR_ECC_MASK)
    {
      hdsi->ErrorCode |= HAL_DSI_ERROR_ECC;
    }
    
    if(ErrorStatus1 & DSI_ERROR_CRC_MASK)
    {
      hdsi->ErrorCode |= HAL_DSI_ERROR_CRC;
    }
    
    if(ErrorStatus1 & DSI_ERROR_PSE_MASK)
    {
      hdsi->ErrorCode |= HAL_DSI_ERROR_PSE;
    }
    
    if(ErrorStatus1 & DSI_ERROR_EOT_MASK)
    {
      hdsi->ErrorCode |= HAL_DSI_ERROR_EOT;
    }
    
    if(ErrorStatus1 & DSI_ERROR_OVF_MASK)
    {
      hdsi->ErrorCode |= HAL_DSI_ERROR_OVF;
    }
    
    if(ErrorStatus1 & DSI_ERROR_GEN_MASK)
    {
      hdsi->ErrorCode |= HAL_DSI_ERROR_GEN;
    }
    
    /* Check only selected errors */
    if(hdsi->ErrorCode != HAL_DSI_ERROR_NONE)
    {
      /* DSI error interrupt user callback */
      HAL_DSI_ErrorCallback(hdsi);
    }
  }
}

/**
  * @brief  Tearing Effect DSI callback.
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @retval None
  */
__weak void HAL_DSI_TearingEffectCallback(DSI_HandleTypeDef *hdsi)
{
  /* NOTE : This function Should not be modified, when the callback is needed,
            the HAL_DSI_TearingEffectCallback could be implemented in the user file
   */
}

/**
  * @brief  End of Refresh DSI callback.
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @retval None
  */
__weak void HAL_DSI_EndOfRefreshCallback(DSI_HandleTypeDef *hdsi)
{
  /* NOTE : This function Should not be modified, when the callback is needed,
            the HAL_DSI_EndOfRefreshCallback could be implemented in the user file
   */
}

/**
  * @brief  Operation Error DSI callback.
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @retval None
  */
__weak void HAL_DSI_ErrorCallback(DSI_HandleTypeDef *hdsi)
{
  /* NOTE : This function Should not be modified, when the callback is needed,
            the HAL_DSI_ErrorCallback could be implemented in the user file
   */
}

/**
  * @}
  */

/** @defgroup DSI_Group3 Peripheral Control functions
 *  @brief    Peripheral Control functions 
 *
@verbatim
 ===============================================================================
                    ##### Peripheral Control functions #####
 ===============================================================================  
    [..]  This section provides functions allowing to:
      (+) 
      (+) 
      (+) 

@endverbatim
  * @{
  */

/**
  * @brief  Configure the Generic interface read-back Virtual Channel ID.
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @param  VirtualChannelID: Virtual channel ID
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_SetGenericVCID(DSI_HandleTypeDef *hdsi, uint32_t VirtualChannelID)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
  
  /* Update the GVCID register */
  hdsi->Instance->GVCIDR &= ~DSI_GVCIDR_VCID;
  hdsi->Instance->GVCIDR |= VirtualChannelID;
  
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
  
  return HAL_OK;
}

/**
  * @brief  Select video mode and configure the corresponding parameters
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @param  VidCfg: pointer to a DSI_VidCfgTypeDef structure that contains
  *                 the DSI video mode configuration parameters
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_ConfigVideoMode(DSI_HandleTypeDef *hdsi, DSI_VidCfgTypeDef *VidCfg)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
  
  /* Check the parameters */
  assert_param(IS_DSI_COLOR_CODING(VidCfg->ColorCoding));
  assert_param(IS_DSI_VIDEO_MODE_TYPE(VidCfg->Mode));
  assert_param(IS_DSI_LP_COMMAND(VidCfg->LPCommandEnable));
  assert_param(IS_DSI_LP_HFP(VidCfg->LPHorizontalFrontPorchEnable));
  assert_param(IS_DSI_LP_HBP(VidCfg->LPHorizontalBackPorchEnable));
  assert_param(IS_DSI_LP_VACTIVE(VidCfg->LPVerticalActiveEnable));
  assert_param(IS_DSI_LP_VFP(VidCfg->LPVerticalFrontPorchEnable));
  assert_param(IS_DSI_LP_VBP(VidCfg->LPVerticalBackPorchEnable));
  assert_param(IS_DSI_LP_VSYNC(VidCfg->LPVerticalSyncActiveEnable));
  assert_param(IS_DSI_FBTAA(VidCfg->FrameBTAAcknowledgeEnable));
  assert_param(IS_DSI_DE_POLARITY(VidCfg->DEPolarity));
  assert_param(IS_DSI_VSYNC_POLARITY(VidCfg->VSPolarity));
  assert_param(IS_DSI_HSYNC_POLARITY(VidCfg->HSPolarity));
  /* Check the LooselyPacked variant only in 18-bit mode */
  if(VidCfg->ColorCoding == DSI_RGB666)
  {
    assert_param(IS_DSI_LOOSELY_PACKED(VidCfg->LooselyPacked));
  }
  
  /* Select video mode by resetting CMDM and DSIM bits */
  hdsi->Instance->MCR &= ~DSI_MCR_CMDM;
  hdsi->Instance->WCFGR &= ~DSI_WCFGR_DSIM;
  
  /* Configure the video mode transmission type */
  hdsi->Instance->VMCR &= ~DSI_VMCR_VMT;
  hdsi->Instance->VMCR |= VidCfg->Mode;
  
  /* Configure the video packet size */
  hdsi->Instance->VPCR &= ~DSI_VPCR_VPSIZE;
  hdsi->Instance->VPCR |= VidCfg->PacketSize;
  
  /* Set the chunks number to be transmitted through the DSI link */
  hdsi->Instance->VCCR &= ~DSI_VCCR_NUMC;
  hdsi->Instance->VCCR |= VidCfg->NumberOfChunks;
  
  /* Set the size of the null packet */
  hdsi->Instance->VNPCR &= ~DSI_VNPCR_NPSIZE;
  hdsi->Instance->VNPCR |= VidCfg->NullPacketSize;
  
  /* Select the virtual channel for the LTDC interface traffic */
  hdsi->Instance->LVCIDR &= ~DSI_LVCIDR_VCID;
  hdsi->Instance->LVCIDR |= VidCfg->VirtualChannelID;
  
  /* Configure the polarity of control signals */
  hdsi->Instance->LPCR &= ~(DSI_LPCR_DEP | DSI_LPCR_VSP | DSI_LPCR_HSP);
  hdsi->Instance->LPCR |= (VidCfg->DEPolarity | VidCfg->VSPolarity | VidCfg->HSPolarity);
  
  /* Select the color coding for the host */
  hdsi->Instance->LCOLCR &= ~DSI_LCOLCR_COLC;
  hdsi->Instance->LCOLCR |= VidCfg->ColorCoding;
    
  /* Select the color coding for the wrapper */
  hdsi->Instance->WCFGR &= ~DSI_WCFGR_COLMUX;
  hdsi->Instance->WCFGR |= ((VidCfg->ColorCoding)<<1);
  
  /* Enable/disable the loosely packed variant to 18-bit configuration */
  if(VidCfg->ColorCoding == DSI_RGB666)
  {
    hdsi->Instance->LCOLCR &= ~DSI_LCOLCR_LPE;
    hdsi->Instance->LCOLCR |= VidCfg->LooselyPacked;
  }
  
  /* Set the Horizontal Synchronization Active (HSA) in lane byte clock cycles */
  hdsi->Instance->VHSACR &= ~DSI_VHSACR_HSA;
  hdsi->Instance->VHSACR |= VidCfg->HorizontalSyncActive;
  
  /* Set the Horizontal Back Porch (HBP) in lane byte clock cycles */
  hdsi->Instance->VHBPCR &= ~DSI_VHBPCR_HBP;
  hdsi->Instance->VHBPCR |= VidCfg->HorizontalBackPorch;
  
  /* Set the total line time (HLINE=HSA+HBP+HACT+HFP) in lane byte clock cycles */
  hdsi->Instance->VLCR &= ~DSI_VLCR_HLINE;
  hdsi->Instance->VLCR |= VidCfg->HorizontalLine;
  
  /* Set the Vertical Synchronization Active (VSA) */
  hdsi->Instance->VVSACR &= ~DSI_VVSACR_VSA;
  hdsi->Instance->VVSACR |= VidCfg->VerticalSyncActive;
  
  /* Set the Vertical Back Porch (VBP)*/
  hdsi->Instance->VVBPCR &= ~DSI_VVBPCR_VBP;
  hdsi->Instance->VVBPCR |= VidCfg->VerticalBackPorch;
  
  /* Set the Vertical Front Porch (VFP)*/
  hdsi->Instance->VVFPCR &= ~DSI_VVFPCR_VFP;
  hdsi->Instance->VVFPCR |= VidCfg->VerticalFrontPorch;
  
  /* Set the Vertical Active period*/
  hdsi->Instance->VVACR &= ~DSI_VVACR_VA;
  hdsi->Instance->VVACR |= VidCfg->VerticalActive;
  
  /* Configure the command transmission mode */
  hdsi->Instance->VMCR &= ~DSI_VMCR_LPCE;
  hdsi->Instance->VMCR |= VidCfg->LPCommandEnable;
  
  /* Low power largest packet size */
  hdsi->Instance->LPMCR &= ~DSI_LPMCR_LPSIZE;
  hdsi->Instance->LPMCR |= ((VidCfg->LPLargestPacketSize)<<16);
  
  /* Low power VACT largest packet size */
  hdsi->Instance->LPMCR &= ~DSI_LPMCR_VLPSIZE;
  hdsi->Instance->LPMCR |= VidCfg->LPVACTLargestPacketSize;
  
  /* Enable LP transition in HFP period */
  hdsi->Instance->VMCR &= ~DSI_VMCR_LPHFPE;
  hdsi->Instance->VMCR |= VidCfg->LPHorizontalFrontPorchEnable;
  
  /* Enable LP transition in HBP period */
  hdsi->Instance->VMCR &= ~DSI_VMCR_LPHBPE;
  hdsi->Instance->VMCR |= VidCfg->LPHorizontalBackPorchEnable;
  
  /* Enable LP transition in VACT period */
  hdsi->Instance->VMCR &= ~DSI_VMCR_LPVAE;
  hdsi->Instance->VMCR |= VidCfg->LPVerticalActiveEnable;
  
  /* Enable LP transition in VFP period */
  hdsi->Instance->VMCR &= ~DSI_VMCR_LPVFPE;
  hdsi->Instance->VMCR |= VidCfg->LPVerticalFrontPorchEnable;
  
  /* Enable LP transition in VBP period */
  hdsi->Instance->VMCR &= ~DSI_VMCR_LPVBPE;
  hdsi->Instance->VMCR |= VidCfg->LPVerticalBackPorchEnable;
  
  /* Enable LP transition in vertical sync period */
  hdsi->Instance->VMCR &= ~DSI_VMCR_LPVSAE;
  hdsi->Instance->VMCR |= VidCfg->LPVerticalSyncActiveEnable;
  
  /* Enable the request for an acknowledge response at the end of a frame */
  hdsi->Instance->VMCR &= ~DSI_VMCR_FBTAAE;
  hdsi->Instance->VMCR |= VidCfg->FrameBTAAcknowledgeEnable;
  
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
  
  return HAL_OK;
}

/**
  * @brief  Select adapted command mode and configure the corresponding parameters
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @param  CmdCfg: pointer to a DSI_CmdCfgTypeDef structure that contains
  *                 the DSI command mode configuration parameters
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_ConfigAdaptedCommandMode(DSI_HandleTypeDef *hdsi, DSI_CmdCfgTypeDef *CmdCfg)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
  
  /* Check the parameters */
  assert_param(IS_DSI_COLOR_CODING(CmdCfg->ColorCoding));
  assert_param(IS_DSI_TE_SOURCE(CmdCfg->TearingEffectSource));
  assert_param(IS_DSI_TE_POLARITY(CmdCfg->TearingEffectPolarity));
  assert_param(IS_DSI_AUTOMATIC_REFRESH(CmdCfg->AutomaticRefresh));
  assert_param(IS_DSI_VS_POLARITY(CmdCfg->VSyncPol));
  assert_param(IS_DSI_TE_ACK_REQUEST(CmdCfg->TEAcknowledgeRequest));
  assert_param(IS_DSI_DE_POLARITY(CmdCfg->DEPolarity));
  assert_param(IS_DSI_VSYNC_POLARITY(CmdCfg->VSPolarity));
  assert_param(IS_DSI_HSYNC_POLARITY(CmdCfg->HSPolarity));
  
  /* Select command mode by setting CMDM and DSIM bits */
  hdsi->Instance->MCR |= DSI_MCR_CMDM;
  hdsi->Instance->WCFGR &= ~DSI_WCFGR_DSIM;
  hdsi->Instance->WCFGR |= DSI_WCFGR_DSIM;
  
  /* Select the virtual channel for the LTDC interface traffic */
  hdsi->Instance->LVCIDR &= ~DSI_LVCIDR_VCID;
  hdsi->Instance->LVCIDR |= CmdCfg->VirtualChannelID;
  
  /* Configure the polarity of control signals */
  hdsi->Instance->LPCR &= ~(DSI_LPCR_DEP | DSI_LPCR_VSP | DSI_LPCR_HSP);
  hdsi->Instance->LPCR |= (CmdCfg->DEPolarity | CmdCfg->VSPolarity | CmdCfg->HSPolarity);
  
  /* Select the color coding for the host */
  hdsi->Instance->LCOLCR &= ~DSI_LCOLCR_COLC;
  hdsi->Instance->LCOLCR |= CmdCfg->ColorCoding;
    
  /* Select the color coding for the wrapper */
  hdsi->Instance->WCFGR &= ~DSI_WCFGR_COLMUX;
  hdsi->Instance->WCFGR |= ((CmdCfg->ColorCoding)<<1);
  
  /* Configure the maximum allowed size for write memory command */
  hdsi->Instance->LCCR &= ~DSI_LCCR_CMDSIZE;
  hdsi->Instance->LCCR |= CmdCfg->CommandSize;
  
  /* Configure the tearing effect source and polarity and select the refresh mode */
  hdsi->Instance->WCFGR &= ~(DSI_WCFGR_TESRC | DSI_WCFGR_TEPOL | DSI_WCFGR_AR | DSI_WCFGR_VSPOL);
  hdsi->Instance->WCFGR |= (CmdCfg->TearingEffectSource | CmdCfg->TearingEffectPolarity | CmdCfg->AutomaticRefresh | CmdCfg->VSyncPol);
  
  /* Configure the tearing effect acknowledge request */
  hdsi->Instance->CMCR &= ~DSI_CMCR_TEARE;
  hdsi->Instance->CMCR |= CmdCfg->TEAcknowledgeRequest;
  
  /* Enable the Tearing Effect interrupt */
  __HAL_DSI_ENABLE_IT(hdsi, DSI_IT_TE);
  
  /* Enable the End of Refresh interrupt */
  __HAL_DSI_ENABLE_IT(hdsi, DSI_IT_ER);
  
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
  
  return HAL_OK;
}

/**
  * @brief  Configure command transmission mode: High-speed or Low-power
  *         and enable/disable acknowledge request after packet transmission
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @param  LPCmd: pointer to a DSI_LPCmdTypeDef structure that contains
  *                the DSI command transmission mode configuration parameters
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_ConfigCommand(DSI_HandleTypeDef *hdsi, DSI_LPCmdTypeDef *LPCmd)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
  
  assert_param(IS_DSI_LP_GSW0P(LPCmd->LPGenShortWriteNoP));
  assert_param(IS_DSI_LP_GSW1P(LPCmd->LPGenShortWriteOneP));
  assert_param(IS_DSI_LP_GSW2P(LPCmd->LPGenShortWriteTwoP));
  assert_param(IS_DSI_LP_GSR0P(LPCmd->LPGenShortReadNoP));
  assert_param(IS_DSI_LP_GSR1P(LPCmd->LPGenShortReadOneP));
  assert_param(IS_DSI_LP_GSR2P(LPCmd->LPGenShortReadTwoP));
  assert_param(IS_DSI_LP_GLW(LPCmd->LPGenLongWrite));
  assert_param(IS_DSI_LP_DSW0P(LPCmd->LPDcsShortWriteNoP));
  assert_param(IS_DSI_LP_DSW1P(LPCmd->LPDcsShortWriteOneP));
  assert_param(IS_DSI_LP_DSR0P(LPCmd->LPDcsShortReadNoP));
  assert_param(IS_DSI_LP_DLW(LPCmd->LPDcsLongWrite));
  assert_param(IS_DSI_LP_MRDP(LPCmd->LPMaxReadPacket));
  assert_param(IS_DSI_ACK_REQUEST(LPCmd->AcknowledgeRequest));
  
  /* Select High-speed or Low-power for command transmission */
  hdsi->Instance->CMCR &= ~(DSI_CMCR_GSW0TX |\
                            DSI_CMCR_GSW1TX |\
                            DSI_CMCR_GSW2TX |\
                            DSI_CMCR_GSR0TX |\
                            DSI_CMCR_GSR1TX |\
                            DSI_CMCR_GSR2TX |\
                            DSI_CMCR_GLWTX  |\
                            DSI_CMCR_DSW0TX |\
                            DSI_CMCR_DSW1TX |\
                            DSI_CMCR_DSR0TX |\
                            DSI_CMCR_DLWTX  |\
                            DSI_CMCR_MRDPS);
  hdsi->Instance->CMCR |= (LPCmd->LPGenShortWriteNoP  |\
                           LPCmd->LPGenShortWriteOneP |\
                           LPCmd->LPGenShortWriteTwoP |\
                           LPCmd->LPGenShortReadNoP   |\
                           LPCmd->LPGenShortReadOneP  |\
                           LPCmd->LPGenShortReadTwoP  |\
                           LPCmd->LPGenLongWrite      |\
                           LPCmd->LPDcsShortWriteNoP  |\
                           LPCmd->LPDcsShortWriteOneP |\
                           LPCmd->LPDcsShortReadNoP   |\
                           LPCmd->LPDcsLongWrite      |\
                           LPCmd->LPMaxReadPacket);
  
  /* Configure the acknowledge request after each packet transmission */
  hdsi->Instance->CMCR &= ~DSI_CMCR_ARE;
  hdsi->Instance->CMCR |= LPCmd->AcknowledgeRequest;
  
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
  
  return HAL_OK;
}

/**
  * @brief  Configure the flow control parameters
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @param  FlowControl: flow control feature(s) to be enabled.
  *                      This parameter can be any combination of @ref DSI_FlowControl.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_ConfigFlowControl(DSI_HandleTypeDef *hdsi, uint32_t FlowControl)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
  
  /* Check the parameters */
  assert_param(IS_DSI_FLOW_CONTROL(FlowControl));
  
  /* Set the DSI Host Protocol Configuration Register */
  hdsi->Instance->PCR &= ~DSI_FLOW_CONTROL_ALL;
  hdsi->Instance->PCR |= FlowControl;
  
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
  
  return HAL_OK;
}

/**
  * @brief  Configure the DSI PHY timer parameters
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @param  PhyTimers: DSI_PHY_TimerTypeDef structure that contains
  *                    the DSI PHY timing parameters
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_ConfigPhyTimer(DSI_HandleTypeDef *hdsi, DSI_PHY_TimerTypeDef *PhyTimers)
{
  uint32_t maxTime;
  /* Process locked */
  __HAL_LOCK(hdsi);
  
  maxTime = (PhyTimers->ClockLaneLP2HSTime > PhyTimers->ClockLaneHS2LPTime)? PhyTimers->ClockLaneLP2HSTime: PhyTimers->ClockLaneHS2LPTime;

  /* Clock lane timer configuration */

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

     Workaround : Configure HS2LP_TIME and LP2HS_TIME with the same value being the max of HS2LP_TIME or LP2HS_TIME.
  */
  hdsi->Instance->CLTCR &= ~(DSI_CLTCR_LP2HS_TIME | DSI_CLTCR_HS2LP_TIME);
  hdsi->Instance->CLTCR |= (maxTime | ((maxTime)<<16));
  
  /* Data lane timer configuration */
  hdsi->Instance->DLTCR &= ~(DSI_DLTCR_MRD_TIME | DSI_DLTCR_LP2HS_TIME | DSI_DLTCR_HS2LP_TIME);
  hdsi->Instance->DLTCR |= (PhyTimers->DataLaneMaxReadTime | ((PhyTimers->DataLaneLP2HSTime)<<16) | ((PhyTimers->DataLaneHS2LPTime)<<24));
  
  /* Configure the wait period to request HS transmission after a stop state */
  hdsi->Instance->PCONFR &= ~DSI_PCONFR_SW_TIME;
  hdsi->Instance->PCONFR |= ((PhyTimers->StopWaitTime)<<8);
  
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
  
  return HAL_OK;
}

/**
  * @brief  Configure the DSI HOST timeout parameters
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @param  HostTimeouts: DSI_HOST_TimeoutTypeDef structure that contains
  *                       the DSI host timeout parameters
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_ConfigHostTimeouts(DSI_HandleTypeDef *hdsi, DSI_HOST_TimeoutTypeDef *HostTimeouts)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
  
  /* Set the timeout clock division factor */
  hdsi->Instance->CCR &= ~DSI_CCR_TOCKDIV;
  hdsi->Instance->CCR = ((HostTimeouts->TimeoutCkdiv)<<8);
  
  /* High-speed transmission timeout */
  hdsi->Instance->TCCR[0] &= ~DSI_TCCR0_HSTX_TOCNT;
  hdsi->Instance->TCCR[0] |= ((HostTimeouts->HighSpeedTransmissionTimeout)<<16);
  
  /* Low-power reception timeout */
  hdsi->Instance->TCCR[0] &= ~DSI_TCCR0_LPRX_TOCNT;
  hdsi->Instance->TCCR[0] |= HostTimeouts->LowPowerReceptionTimeout;
  
  /* High-speed read timeout */
  hdsi->Instance->TCCR[1] &= ~DSI_TCCR1_HSRD_TOCNT;
  hdsi->Instance->TCCR[1] |= HostTimeouts->HighSpeedReadTimeout;
  
  /* Low-power read timeout */
  hdsi->Instance->TCCR[2] &= ~DSI_TCCR2_LPRD_TOCNT;
  hdsi->Instance->TCCR[2] |= HostTimeouts->LowPowerReadTimeout;
  
  /* High-speed write timeout */
  hdsi->Instance->TCCR[3] &= ~DSI_TCCR3_HSWR_TOCNT;
  hdsi->Instance->TCCR[3] |= HostTimeouts->HighSpeedWriteTimeout;
  
  /* High-speed write presp mode */
  hdsi->Instance->TCCR[3] &= ~DSI_TCCR3_PM;
  hdsi->Instance->TCCR[3] |= HostTimeouts->HighSpeedWritePrespMode;
  
  /* Low-speed write timeout */
  hdsi->Instance->TCCR[4] &= ~DSI_TCCR4_LPWR_TOCNT;
  hdsi->Instance->TCCR[4] |= HostTimeouts->LowPowerWriteTimeout;
  
  /* BTA timeout */
  hdsi->Instance->TCCR[5] &= ~DSI_TCCR5_BTA_TOCNT;
  hdsi->Instance->TCCR[5] |= HostTimeouts->BTATimeout;
  
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
  
  return HAL_OK;
}

/**
  * @brief  Start the DSI module
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_Start(DSI_HandleTypeDef *hdsi)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
  
  /* Enable the DSI host */
  __HAL_DSI_ENABLE(hdsi);
  
  /* Enable the DSI wrapper */
  __HAL_DSI_WRAPPER_ENABLE(hdsi);
  
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
  
  return HAL_OK;
}

/**
  * @brief  Stop the DSI module
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_Stop(DSI_HandleTypeDef *hdsi)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
  
  /* Disable the DSI host */
  __HAL_DSI_DISABLE(hdsi);
  
  /* Disable the DSI wrapper */
  __HAL_DSI_WRAPPER_DISABLE(hdsi);
  
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
  
  return HAL_OK;
}

/**
  * @brief  Refresh the display in command mode
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_Refresh(DSI_HandleTypeDef *hdsi)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
  
  /* Update the display */
  hdsi->Instance->WCR |= DSI_WCR_LTDCEN;
  
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
  
  return HAL_OK;
}

/**
  * @brief  Controls the display color mode in Video mode
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @param  ColorMode: Color mode (full or 8-colors).
  *                    This parameter can be any value of @ref DSI_Color_Mode
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_ColorMode(DSI_HandleTypeDef *hdsi, uint32_t ColorMode)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
  
  /* Check the parameters */
  assert_param(IS_DSI_COLOR_MODE(ColorMode));
  
  /* Update the display color mode */
  hdsi->Instance->WCR &= ~DSI_WCR_COLM;
  hdsi->Instance->WCR |= ColorMode;
  
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
  
  return HAL_OK;
}

/**
  * @brief  Control the display shutdown in Video mode
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @param  Shutdown: Shut-down (Display-ON or Display-OFF).
  *                   This parameter can be any value of @ref DSI_ShutDown
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_Shutdown(DSI_HandleTypeDef *hdsi, uint32_t Shutdown)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
  
  /* Check the parameters */
  assert_param(IS_DSI_SHUT_DOWN(Shutdown));
  
  /* Update the display Shutdown */
  hdsi->Instance->WCR &= ~DSI_WCR_SHTDN;
  hdsi->Instance->WCR |= Shutdown;
  
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
  
  return HAL_OK;
}

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

  /* Process locked */
  __HAL_LOCK(hdsi);
  
  /* Check the parameters */
  assert_param(IS_DSI_SHORT_WRITE_PACKET_TYPE(Mode));
  
  /* Get tick */ 
  tickstart = HAL_GetTick();
  
  /* Wait for Command FIFO Empty */
  while((hdsi->Instance->GPSR & DSI_GPSR_CMDFE) == 0)
  {
    /* Check for the Timeout */
    if((HAL_GetTick() - tickstart ) > DSI_TIMEOUT_VALUE)
    {
      /* Process Unlocked */
      __HAL_UNLOCK(hdsi);
      
      return HAL_TIMEOUT;
    }
  }
  
  /* Configure the packet to send a short DCS command with 0 or 1 parameter */
  DSI_ConfigPacketHeader(hdsi->Instance,
                         ChannelID,
                         Mode,
                         Param1,
                         Param2);
  
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
  
  return HAL_OK;
}

/**
  * @brief  DCS or Generic long write command
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @param  ChannelID: Virtual channel ID.
  * @param  Mode: DSI long packet data type.
  *               This parameter can be any value of @ref DSI_LONG_WRITE_PKT_Data_Type.
  * @param  NbParams: Number of parameters.
  * @param  Param1: DSC command or first generic parameter.
  *                 This parameter can be any value of @ref DSI_DCS_Command or a 
  *                 generic command code
  * @param  ParametersTable: Pointer to parameter values table.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_LongWrite(DSI_HandleTypeDef *hdsi,
                                    uint32_t ChannelID,
                                    uint32_t Mode,
                                    uint32_t NbParams,
                                    uint32_t Param1,
                                    uint8_t* ParametersTable)
{
  uint32_t uicounter = 0;
  uint32_t tickstart = 0;
  
  /* Process locked */
  __HAL_LOCK(hdsi);
  
  /* Check the parameters */
  assert_param(IS_DSI_LONG_WRITE_PACKET_TYPE(Mode));
  
  /* Get tick */ 
  tickstart = HAL_GetTick();
  
  /* Wait for Command FIFO Empty */
  while((hdsi->Instance->GPSR & DSI_GPSR_CMDFE) == RESET)
  {
    /* Check for the Timeout */
    if((HAL_GetTick() - tickstart ) > DSI_TIMEOUT_VALUE)
    {
      /* Process Unlocked */
      __HAL_UNLOCK(hdsi);
      
      return HAL_TIMEOUT;
    }
  }
  
  /* Set the DCS code hexadecimal on payload byte 1, and the other parameters on the write FIFO command*/
  while(uicounter < NbParams)
  {
    if(uicounter == 0x00)
    {
      hdsi->Instance->GPDR=(Param1 | \
                            ((*(ParametersTable+uicounter))<<8) | \
                            ((*(ParametersTable+uicounter+1))<<16) | \
                            ((*(ParametersTable+uicounter+2))<<24));
      uicounter += 3;
    }
    else
    {
      hdsi->Instance->GPDR=((*(ParametersTable+uicounter)) | \
                            ((*(ParametersTable+uicounter+1))<<8) | \
                            ((*(ParametersTable+uicounter+2))<<16) | \
                            ((*(ParametersTable+uicounter+3))<<24));
      uicounter+=4;
    }
  }
  
  /* Configure the packet to send a long DCS command */
  DSI_ConfigPacketHeader(hdsi->Instance,
                         ChannelID,
                         Mode,
                         ((NbParams+1)&0x00FF),
                         (((NbParams+1)&0xFF00)>>8));
  
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
  
  return HAL_OK;
}

/**
  * @brief  Read command (DCS or generic)
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @param  ChannelNbr: Virtual channel ID
  * @param  Array: pointer to a buffer to store the payload of a read back operation.
  * @param  Size: Data size to be read (in byte).
  * @param  Mode: DSI read packet data type.
  *               This parameter can be any value of @ref DSI_SHORT_READ_PKT_Data_Type.
  * @param  DCSCmd: DCS get/read command.
  * @param  ParametersTable: Pointer to parameter values table.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_Read(DSI_HandleTypeDef *hdsi,
                               uint32_t ChannelNbr,
                               uint8_t* Array,
                               uint32_t Size,
                               uint32_t Mode,
                               uint32_t DCSCmd,
                               uint8_t* ParametersTable)
{
  uint32_t tickstart = 0;
  
  /* Process locked */
  __HAL_LOCK(hdsi);
  
  /* Check the parameters */
  assert_param(IS_DSI_READ_PACKET_TYPE(Mode));
  
  if(Size > 2)
  {
    /* set max return packet size */
    HAL_DSI_ShortWrite(hdsi, ChannelNbr, DSI_MAX_RETURN_PKT_SIZE, ((Size)&0xFF), (((Size)>>8)&0xFF));
  }
  
  /* Configure the packet to read command */
  if (Mode == DSI_DCS_SHORT_PKT_READ)
  {
    DSI_ConfigPacketHeader(hdsi->Instance, ChannelNbr, Mode, DCSCmd, 0);
  }
  else if (Mode == DSI_GEN_SHORT_PKT_READ_P0)
  {
    DSI_ConfigPacketHeader(hdsi->Instance, ChannelNbr, Mode, 0, 0);
  }
  else if (Mode == DSI_GEN_SHORT_PKT_READ_P1)
  {
    DSI_ConfigPacketHeader(hdsi->Instance, ChannelNbr, Mode, ParametersTable[0], 0);
  }
  else if (Mode == DSI_GEN_SHORT_PKT_READ_P2)
  {
    DSI_ConfigPacketHeader(hdsi->Instance, ChannelNbr, Mode, ParametersTable[0], ParametersTable[1]);
  }
  
  /* Get tick */ 
  tickstart = HAL_GetTick();
  
  /* Check that the payload read FIFO is not empty */
  while((hdsi->Instance->GPSR & DSI_GPSR_PRDFE) == DSI_GPSR_PRDFE)
  {
    /* Check for the Timeout */
    if((HAL_GetTick() - tickstart ) > DSI_TIMEOUT_VALUE)
    {
      /* Process Unlocked */
      __HAL_UNLOCK(hdsi);
      
      return HAL_TIMEOUT;
    }
  }
  
  /* Get the first byte */
  *((uint32_t *)Array) = (hdsi->Instance->GPDR);
  if (Size > 4)
  {
    Size -= 4;
    Array += 4;
  }
  else
  {
    /* Process unlocked */
    __HAL_UNLOCK(hdsi);
    
    return HAL_OK;
  }
  
  /* Get tick */ 
  tickstart = HAL_GetTick();
  
  /* Get the remaining bytes if any */
  while(((int)(Size)) > 0)
  {
    if((hdsi->Instance->GPSR & DSI_GPSR_PRDFE) == 0)
    {
      *((uint32_t *)Array) = (hdsi->Instance->GPDR);
      Size -= 4;
      Array += 4;
    }
    
    /* Check for the Timeout */
    if((HAL_GetTick() - tickstart ) > DSI_TIMEOUT_VALUE)
    {
      /* Process Unlocked */
      __HAL_UNLOCK(hdsi);
      
      return HAL_TIMEOUT;
    }    
  }
  
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
  
  return HAL_OK;
}

/**
  * @brief  Enter the ULPM (Ultra Low Power Mode) with the D-PHY PLL running
  *         (only data lanes are in ULPM)
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_EnterULPMData(DSI_HandleTypeDef *hdsi)
{
  uint32_t tickstart = 0;
  
  /* Process locked */
  __HAL_LOCK(hdsi);
  
  /* ULPS Request on Data Lanes */
  hdsi->Instance->PUCR |= DSI_PUCR_URDL;
  
  /* Get tick */ 
  tickstart = HAL_GetTick();
  
  /* Wait until the D-PHY active lanes enter into ULPM */
  if((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
  {
	while((hdsi->Instance->PSR & DSI_PSR_UAN0) != RESET)
    {
      /* Check for the Timeout */
      if((HAL_GetTick() - tickstart ) > DSI_TIMEOUT_VALUE)
      {
        /* Process Unlocked */
        __HAL_UNLOCK(hdsi);
        
        return HAL_TIMEOUT;
      }
    }
  }
  else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
  {
	while((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1)) != RESET)
    {
      /* Check for the Timeout */
      if((HAL_GetTick() - tickstart ) > DSI_TIMEOUT_VALUE)
      {
        /* Process Unlocked */
        __HAL_UNLOCK(hdsi);
        
        return HAL_TIMEOUT;
      }
    }
  }
  
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
  
  return HAL_OK;
}

/**
  * @brief  Exit the ULPM (Ultra Low Power Mode) with the D-PHY PLL running
  *         (only data lanes are in ULPM)
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_ExitULPMData(DSI_HandleTypeDef *hdsi)
{
  uint32_t tickstart = 0;
  
  /* Process locked */
  __HAL_LOCK(hdsi);
  
  /* Exit ULPS on Data Lanes */
  hdsi->Instance->PUCR |= DSI_PUCR_UEDL;
  
  /* Get tick */ 
  tickstart = HAL_GetTick();
  
  /* Wait until all active lanes exit ULPM */
  if((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
  {
	while((hdsi->Instance->PSR & DSI_PSR_UAN0) != DSI_PSR_UAN0)
    {
      /* Check for the Timeout */
      if((HAL_GetTick() - tickstart ) > DSI_TIMEOUT_VALUE)
      {
        /* Process Unlocked */
        __HAL_UNLOCK(hdsi);
        
        return HAL_TIMEOUT;
      }
    }
  }
  else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
  {
	while((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1)) != (DSI_PSR_UAN0 | DSI_PSR_UAN1))
    {
      /* Check for the Timeout */
      if((HAL_GetTick() - tickstart ) > DSI_TIMEOUT_VALUE)
      {
        /* Process Unlocked */
        __HAL_UNLOCK(hdsi);
        
        return HAL_TIMEOUT;
      }
    }
  }
  
  /* De-assert the ULPM requests and the ULPM exit bits */
  hdsi->Instance->PUCR = 0;
  
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
  
  return HAL_OK;
}

/**
  * @brief  Enter the ULPM (Ultra Low Power Mode) with the D-PHY PLL turned off
  *         (both data and clock lanes are in ULPM)
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_EnterULPM(DSI_HandleTypeDef *hdsi)
{
  uint32_t tickstart = 0;
  
  /* Process locked */
  __HAL_LOCK(hdsi);
  
  /* Clock lane configuration: no more HS request */
  hdsi->Instance->CLCR &= ~DSI_CLCR_DPCC;
  
  /* Use system PLL as byte lane clock source before stopping DSIPHY clock source */
  __HAL_RCC_DSI_CONFIG(RCC_DSICLKSOURCE_PLLR);
  
  /* ULPS Request on Clock and Data Lanes */
  hdsi->Instance->PUCR |= (DSI_PUCR_URCL | DSI_PUCR_URDL);
  
  /* Get tick */ 
  tickstart = HAL_GetTick();
  
  /* Wait until all active lanes exit ULPM */
  if((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
  {
	while((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UANC)) != RESET)
    {
      /* Check for the Timeout */
      if((HAL_GetTick() - tickstart ) > DSI_TIMEOUT_VALUE)
      {
        /* Process Unlocked */
        __HAL_UNLOCK(hdsi);
        
        return HAL_TIMEOUT;
      }
    }
  }
  else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
  {
	while((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1 | DSI_PSR_UANC)) != RESET)
    {
      /* Check for the Timeout */
      if((HAL_GetTick() - tickstart ) > DSI_TIMEOUT_VALUE)
      {
        /* Process Unlocked */
        __HAL_UNLOCK(hdsi);
        
        return HAL_TIMEOUT;
      }
    }
  }
  
  /* Turn off the DSI PLL */
  __HAL_DSI_PLL_DISABLE(hdsi);
  
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
  
  return HAL_OK;
}

/**
  * @brief  Exit the ULPM (Ultra Low Power Mode) with the D-PHY PLL turned off
  *         (both data and clock lanes are in ULPM)
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_ExitULPM(DSI_HandleTypeDef *hdsi)
{
  uint32_t tickstart = 0;
  
  /* Process locked */
  __HAL_LOCK(hdsi);
  
  /* Turn on the DSI PLL */
  __HAL_DSI_PLL_ENABLE(hdsi);
  
  /* Get tick */ 
  tickstart = HAL_GetTick();
  
  /* Wait for the lock of the PLL */
  while(__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_PLLLS) == RESET)
  {
    /* Check for the Timeout */
    if((HAL_GetTick() - tickstart ) > DSI_TIMEOUT_VALUE)
    {
      /* Process Unlocked */
      __HAL_UNLOCK(hdsi);
      
      return HAL_TIMEOUT;
    }
  }
  
  /* Exit ULPS on Clock and Data Lanes */
  hdsi->Instance->PUCR |= (DSI_PUCR_UECL | DSI_PUCR_UEDL);
  
  /* Get tick */ 
  tickstart = HAL_GetTick();
  
  /* Wait until all active lanes exit ULPM */
  if((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
  {
	while((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UANC)) != (DSI_PSR_UAN0 | DSI_PSR_UANC))
    {
      /* Check for the Timeout */
      if((HAL_GetTick() - tickstart ) > DSI_TIMEOUT_VALUE)
      {
        /* Process Unlocked */
        __HAL_UNLOCK(hdsi);
        
        return HAL_TIMEOUT;
      }
    }
  }
  else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
  {
	while((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1 | DSI_PSR_UANC)) != (DSI_PSR_UAN0 | DSI_PSR_UAN1 | DSI_PSR_UANC))
    {
      /* Check for the Timeout */
      if((HAL_GetTick() - tickstart ) > DSI_TIMEOUT_VALUE)
      {
        /* Process Unlocked */
        __HAL_UNLOCK(hdsi);
        
        return HAL_TIMEOUT;
      }
    }
  }
  
  /* De-assert the ULPM requests and the ULPM exit bits */
  hdsi->Instance->PUCR = 0;
  
  /* Switch the lanbyteclock source in the RCC from system PLL to D-PHY */
  __HAL_RCC_DSI_CONFIG(RCC_DSICLKSOURCE_DSIPHY);
  
  /* Restore clock lane configuration to HS */
  hdsi->Instance->CLCR |= DSI_CLCR_DPCC;
  
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
  
  return HAL_OK;
}

/**
  * @brief  Start test pattern generation
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @param  Mode: Pattern generator mode
  *          This parameter can be one of the following values:
  *           0 : Color bars (horizontal or vertical)
  *           1 : BER pattern (vertical only)
  * @param  Orientation: Pattern generator orientation
  *          This parameter can be one of the following values:
  *           0 : Vertical color bars
  *           1 : Horizontal color bars
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_PatternGeneratorStart(DSI_HandleTypeDef *hdsi, uint32_t Mode, uint32_t Orientation)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
  
  /* Configure pattern generator mode and orientation */
  hdsi->Instance->VMCR &= ~(DSI_VMCR_PGM | DSI_VMCR_PGO);
  hdsi->Instance->VMCR |= ((Mode<<20) | (Orientation<<24));
  
  /* Enable pattern generator by setting PGE bit */
  hdsi->Instance->VMCR |= DSI_VMCR_PGE;
  
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
  
  return HAL_OK;
}

/**
  * @brief  Stop test pattern generation
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_PatternGeneratorStop(DSI_HandleTypeDef *hdsi)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
  
  /* Disable pattern generator by clearing PGE bit */
  hdsi->Instance->VMCR &= ~DSI_VMCR_PGE;
  
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
  
  return HAL_OK;
}

/**
  * @brief  Set Slew-Rate And Delay Tuning
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @param  CommDelay: Communication delay to be adjusted.
  *                    This parameter can be any value of @ref DSI_Communication_Delay
  * @param  Lane: select between clock or data lanes.
  *               This parameter can be any value of @ref DSI_Lane_Group
  * @param  Value: Custom value of the slew-rate or delay
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_SetSlewRateAndDelayTuning(DSI_HandleTypeDef *hdsi, uint32_t CommDelay, uint32_t Lane, uint32_t Value)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
  
  /* Check function parameters */
  assert_param(IS_DSI_COMMUNICATION_DELAY(CommDelay));
  assert_param(IS_DSI_LANE_GROUP(Lane));
  
  switch(CommDelay)
  {
  case DSI_SLEW_RATE_HSTX:
    if(Lane == DSI_CLOCK_LANE)
    {
      /* High-Speed Transmission Slew Rate Control on Clock Lane */
      hdsi->Instance->WPCR[1] &= ~DSI_WPCR1_HSTXSRCCL;
      hdsi->Instance->WPCR[1] |= Value<<16;
    }
    else if(Lane == DSI_DATA_LANES)
    {
      /* High-Speed Transmission Slew Rate Control on Data Lanes */
      hdsi->Instance->WPCR[1] &= ~DSI_WPCR1_HSTXSRCDL;
      hdsi->Instance->WPCR[1] |= Value<<18;
    }
    break;
  case DSI_SLEW_RATE_LPTX:
    if(Lane == DSI_CLOCK_LANE)
    {
      /* Low-Power transmission Slew Rate Compensation on Clock Lane */
      hdsi->Instance->WPCR[1] &= ~DSI_WPCR1_LPSRCCL;
      hdsi->Instance->WPCR[1] |= Value<<6;
    }
    else if(Lane == DSI_DATA_LANES)
    {
      /* Low-Power transmission Slew Rate Compensation on Data Lanes */
      hdsi->Instance->WPCR[1] &= ~DSI_WPCR1_LPSRCDL;
      hdsi->Instance->WPCR[1] |= Value<<8;
    }
    break;
  case DSI_HS_DELAY:
    if(Lane == DSI_CLOCK_LANE)
    {
      /* High-Speed Transmission Delay on Clock Lane */
      hdsi->Instance->WPCR[1] &= ~DSI_WPCR1_HSTXDCL;
      hdsi->Instance->WPCR[1] |= Value;
    }
    else if(Lane == DSI_DATA_LANES)
    {
      /* High-Speed Transmission Delay on Data Lanes */
      hdsi->Instance->WPCR[1] &= ~DSI_WPCR1_HSTXDDL;
      hdsi->Instance->WPCR[1] |= Value<<2;
    }
    break;
  default:
    break;
  }
  
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
  
  return HAL_OK;
}

/**
  * @brief  Low-Power Reception Filter Tuning
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @param  Frequency: cutoff frequency of low-pass filter at the input of LPRX
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_SetLowPowerRXFilter(DSI_HandleTypeDef *hdsi, uint32_t Frequency)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
  
  /* Low-Power RX low-pass Filtering Tuning */
  hdsi->Instance->WPCR[1] &= ~DSI_WPCR1_LPRXFT;
  hdsi->Instance->WPCR[1] |= Frequency<<25;
  
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
  
  return HAL_OK;
}

/**
  * @brief  Activate an additional current path on all lanes to meet the SDDTx parameter
  *         defined in the MIPI D-PHY specification
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @param  State: ENABLE or DISABLE
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_SetSDD(DSI_HandleTypeDef *hdsi, FunctionalState State)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
  
  /* Check function parameters */
  assert_param(IS_FUNCTIONAL_STATE(State));
  
  /* Activate/Disactivate additional current path on all lanes */
  hdsi->Instance->WPCR[1] &= ~DSI_WPCR1_SDDC;
  hdsi->Instance->WPCR[1] |= State<<12;
  
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
  
  return HAL_OK;
}

/**
  * @brief  Custom lane pins configuration
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @param  CustomLane: Function to be applyed on selected lane.
  *                     This parameter can be any value of @ref DSI_CustomLane
  * @param  Lane: select between clock or data lane 0 or data lane 1.
  *               This parameter can be any value of @ref DSI_Lane_Select
  * @param  State: ENABLE or DISABLE
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_SetLanePinsConfiguration(DSI_HandleTypeDef *hdsi, uint32_t CustomLane, uint32_t Lane, FunctionalState State)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
  
  /* Check function parameters */
  assert_param(IS_DSI_CUSTOM_LANE(CustomLane));
  assert_param(IS_DSI_LANE(Lane));
  assert_param(IS_FUNCTIONAL_STATE(State));
  
  switch(CustomLane)
  {
  case DSI_SWAP_LANE_PINS:
    if(Lane == DSI_CLOCK_LANE)
    {
      /* Swap pins on clock lane */
      hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_SWCL;
      hdsi->Instance->WPCR[0] |= (State<<6);
    }
    else if(Lane == DSI_DATA_LANE0)
    {
      /* Swap pins on data lane 0 */
      hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_SWDL0;
      hdsi->Instance->WPCR[0] |= (State<<7);
    }
    else if(Lane == DSI_DATA_LANE1)
    {
      /* Swap pins on data lane 1 */
      hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_SWDL1;
      hdsi->Instance->WPCR[0] |= (State<<8);
    }
    break;
  case DSI_INVERT_HS_SIGNAL:
    if(Lane == DSI_CLOCK_LANE)
    {
      /* Invert HS signal on clock lane */
      hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_HSICL;
      hdsi->Instance->WPCR[0] |= (State<<9);
    }
    else if(Lane == DSI_DATA_LANE0)
    {
      /* Invert HS signal on data lane 0 */
      hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_HSIDL0;
      hdsi->Instance->WPCR[0] |= (State<<10);
    }
    else if(Lane == DSI_DATA_LANE1)
    {
      /* Invert HS signal on data lane 1 */
      hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_HSIDL1;
      hdsi->Instance->WPCR[0] |= (State<<11);
    }
    break;
  default:
    break;
  }
  
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
  
  return HAL_OK;
}

/**
  * @brief  Set custom timing for the PHY
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @param  Timing: PHY timing to be adjusted.
  *                 This parameter can be any value of @ref DSI_PHY_Timing
  * @param  State: ENABLE or DISABLE
  * @param  Value: Custom value of the timing
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_SetPHYTimings(DSI_HandleTypeDef *hdsi, uint32_t Timing, FunctionalState State, uint32_t Value)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
  
  /* Check function parameters */
  assert_param(IS_DSI_PHY_TIMING(Timing));
  assert_param(IS_FUNCTIONAL_STATE(State));
  
  switch(Timing)
  {
  case DSI_TCLK_POST:
    /* Enable/Disable custom timing setting */
    hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_TCLKPOSTEN;
    hdsi->Instance->WPCR[0] |= (State<<27);
    
    if(State)
    {
      /* Set custom value */
      hdsi->Instance->WPCR[4] &= ~DSI_WPCR4_TCLKPOST;
      hdsi->Instance->WPCR[4] |= Value;
    }
    
    break;
  case DSI_TLPX_CLK:
    /* Enable/Disable custom timing setting */
    hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_TLPXCEN;
    hdsi->Instance->WPCR[0] |= (State<<26);
    
    if(State)
    {
      /* Set custom value */
      hdsi->Instance->WPCR[3] &= ~DSI_WPCR3_TLPXC;
      hdsi->Instance->WPCR[3] |= Value;
    }
    
    break;
  case DSI_THS_EXIT:
    /* Enable/Disable custom timing setting */
    hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_THSEXITEN;
    hdsi->Instance->WPCR[0] |= (State<<25);
    
    if(State)
    {
      /* Set custom value */
      hdsi->Instance->WPCR[3] &= ~DSI_WPCR3_THSEXIT;
      hdsi->Instance->WPCR[3] |= Value;
    }
    
    break;
  case DSI_TLPX_DATA:
    /* Enable/Disable custom timing setting */
    hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_TLPXDEN;
    hdsi->Instance->WPCR[0] |= (State<<24);
    
    if(State)
    {
      /* Set custom value */
      hdsi->Instance->WPCR[3] &= ~DSI_WPCR3_TLPXD;
      hdsi->Instance->WPCR[3] |= Value;
    }
    
    break;
  case DSI_THS_ZERO:
    /* Enable/Disable custom timing setting */
    hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_THSZEROEN;
    hdsi->Instance->WPCR[0] |= (State<<23);
    
    if(State)
    {
      /* Set custom value */
      hdsi->Instance->WPCR[3] &= ~DSI_WPCR3_THSZERO;
      hdsi->Instance->WPCR[3] |= Value;
    }
    
    break;
  case DSI_THS_TRAIL:
    /* Enable/Disable custom timing setting */
    hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_THSTRAILEN;
    hdsi->Instance->WPCR[0] |= (State<<22);
    
    if(State)
    {
      /* Set custom value */
      hdsi->Instance->WPCR[2] &= ~DSI_WPCR2_THSTRAIL;
      hdsi->Instance->WPCR[2] |= Value;
    }
    
    break;
  case DSI_THS_PREPARE:
    /* Enable/Disable custom timing setting */
    hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_THSPREPEN;
    hdsi->Instance->WPCR[0] |= (State<<21);
    
    if(State)
    {
      /* Set custom value */
      hdsi->Instance->WPCR[2] &= ~DSI_WPCR2_THSPREP;
      hdsi->Instance->WPCR[2] |= Value;
    }
    
    break;
  case DSI_TCLK_ZERO:
    /* Enable/Disable custom timing setting */
    hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_TCLKZEROEN;
    hdsi->Instance->WPCR[0] |= (State<<20);
    
    if(State)
    {
      /* Set custom value */
      hdsi->Instance->WPCR[2] &= ~DSI_WPCR2_TCLKZERO;
      hdsi->Instance->WPCR[2] |= Value;
    }
    
    break;
  case DSI_TCLK_PREPARE:
    /* Enable/Disable custom timing setting */
    hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_TCLKPREPEN;
    hdsi->Instance->WPCR[0] |= (State<<19);
    
    if(State)
    {
      /* Set custom value */
      hdsi->Instance->WPCR[2] &= ~DSI_WPCR2_TCLKPREP;
      hdsi->Instance->WPCR[2] |= Value;
    }
    
    break;
  default:
    break;
  }
  
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
  
  return HAL_OK;
}

/**
  * @brief  Force the Clock/Data Lane in TX Stop Mode
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @param  Lane: select between clock or data lanes.
  *               This parameter can be any value of @ref DSI_Lane_Group
  * @param  State: ENABLE or DISABLE
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_ForceTXStopMode(DSI_HandleTypeDef *hdsi, uint32_t Lane, FunctionalState State)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
  
  /* Check function parameters */
  assert_param(IS_DSI_LANE_GROUP(Lane));
  assert_param(IS_FUNCTIONAL_STATE(State));
  
  if(Lane == DSI_CLOCK_LANE)
  {
    /* Force/Unforce the Clock Lane in TX Stop Mode */
    hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_FTXSMCL;
    hdsi->Instance->WPCR[0] |= (State<<12);
  }
  else if(Lane == DSI_DATA_LANES)
  {
    /* Force/Unforce the Data Lanes in TX Stop Mode */
    hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_FTXSMDL;
    hdsi->Instance->WPCR[0] |= (State<<13);
  }
  
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
  
  return HAL_OK;
}

/**
  * @brief  Forces LP Receiver in Low-Power Mode
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @param  State: ENABLE or DISABLE
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_ForceRXLowPower(DSI_HandleTypeDef *hdsi, FunctionalState State)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
  
  /* Check function parameters */
  assert_param(IS_FUNCTIONAL_STATE(State));
  
  /* Force/Unforce LP Receiver in Low-Power Mode */
  hdsi->Instance->WPCR[1] &= ~DSI_WPCR1_FLPRXLPM;
  hdsi->Instance->WPCR[1] |= State<<22;
  
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
  
  return HAL_OK;
}

/**
  * @brief  Force Data Lanes in RX Mode after a BTA
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @param  State: ENABLE or DISABLE
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_ForceDataLanesInRX(DSI_HandleTypeDef *hdsi, FunctionalState State)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
  
  /* Check function parameters */
  assert_param(IS_FUNCTIONAL_STATE(State));
  
  /* Force Data Lanes in RX Mode */
  hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_TDDL;
  hdsi->Instance->WPCR[0] |= State<<16;
  
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
  
  return HAL_OK;
}

/**
  * @brief  Enable a pull-down on the lanes to prevent from floating states when unused
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @param  State: ENABLE or DISABLE
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_SetPullDown(DSI_HandleTypeDef *hdsi, FunctionalState State)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
  
  /* Check function parameters */
  assert_param(IS_FUNCTIONAL_STATE(State));
  
  /* Enable/Disable pull-down on lanes */
  hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_PDEN;
  hdsi->Instance->WPCR[0] |= State<<18;
  
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
  
  return HAL_OK;
}

/**
  * @brief  Switch off the contention detection on data lanes
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @param  State: ENABLE or DISABLE
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DSI_SetContentionDetectionOff(DSI_HandleTypeDef *hdsi, FunctionalState State)
{
  /* Process locked */
  __HAL_LOCK(hdsi);
  
  /* Check function parameters */
  assert_param(IS_FUNCTIONAL_STATE(State));
  
  /* Contention Detection on Data Lanes OFF */
  hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_CDOFFDL;
  hdsi->Instance->WPCR[0] |= State<<14;
  
  /* Process unlocked */
  __HAL_UNLOCK(hdsi);
  
  return HAL_OK;
}

/**
  * @}
  */

/** @defgroup DSI_Group4 Peripheral State and Errors functions
 *  @brief    Peripheral State and Errors functions 
 *
@verbatim   
 ===============================================================================
                  ##### Peripheral State and Errors functions #####
 ===============================================================================  
    [..]
    This subsection provides functions allowing to
      (+) Check the DSI state.
      (+) Get error code.  

@endverbatim
  * @{
  */ 

/**
  * @brief  Return the DSI state
  * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
  *               the configuration information for the DSI.
  * @retval HAL state
  */
HAL_DSI_StateTypeDef HAL_DSI_GetState(DSI_HandleTypeDef *hdsi)
{
  return hdsi->State;
}

/**
  * @}
  */

/**
  * @}
  */
#endif /* STM32F469xx || STM32F479xx */  
#endif /* HAL_DSI_MODULE_ENABLED */
/**
  * @}
  */

/**
  * @}
  */

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