stm32f4xx_dsi.c 58 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762
  1. /**
  2. ******************************************************************************
  3. * @file stm32f4xx_dsi.c
  4. * @author MCD Application Team
  5. * @version V1.8.1
  6. * @date 27-January-2022
  7. * @brief This file provides firmware functions to manage the following
  8. * functionalities of the Display Serial Interface (DSI):
  9. * + Initialization and Configuration
  10. * + Data transfers management functions
  11. * + Low Power functions
  12. * + Interrupts and flags management
  13. *
  14. @verbatim
  15. ===================================================================
  16. ##### How to use this driver #####
  17. ===================================================================
  18. [..]
  19. @endverbatim
  20. *
  21. ******************************************************************************
  22. * @attention
  23. *
  24. * Copyright (c) 2016 STMicroelectronics.
  25. * All rights reserved.
  26. *
  27. * This software is licensed under terms that can be found in the LICENSE file
  28. * in the root directory of this software component.
  29. * If no LICENSE file comes with this software, it is provided AS-IS.
  30. *
  31. ******************************************************************************
  32. */
  33. /* Includes ------------------------------------------------------------------*/
  34. #include "stm32f4xx_dsi.h"
  35. /** @addtogroup STM32F4xx_StdPeriph_Driver
  36. * @{
  37. */
  38. /** @addtogroup DSI
  39. * @brief DSI driver modules
  40. * @{
  41. */
  42. #if defined(STM32F469_479xx)
  43. /* Private types -------------------------------------------------------------*/
  44. /* Private defines -----------------------------------------------------------*/
  45. /** @addtogroup DSI_Private_Constants
  46. * @{
  47. */
  48. #define DSI_TIMEOUT_VALUE ((uint32_t)1000) /* 1s */
  49. #define DSI_ERROR_ACK_MASK (DSI_ISR0_AE0 | DSI_ISR0_AE1 | DSI_ISR0_AE2 | DSI_ISR0_AE3 | \
  50. DSI_ISR0_AE4 | DSI_ISR0_AE5 | DSI_ISR0_AE6 | DSI_ISR0_AE7 | \
  51. DSI_ISR0_AE8 | DSI_ISR0_AE9 | DSI_ISR0_AE10 | DSI_ISR0_AE11 | \
  52. DSI_ISR0_AE12 | DSI_ISR0_AE13 | DSI_ISR0_AE14 | DSI_ISR0_AE15)
  53. #define DSI_ERROR_PHY_MASK (DSI_ISR0_PE0 | DSI_ISR0_PE1 | DSI_ISR0_PE2 | DSI_ISR0_PE3 | DSI_ISR0_PE4)
  54. #define DSI_ERROR_TX_MASK DSI_ISR1_TOHSTX
  55. #define DSI_ERROR_RX_MASK DSI_ISR1_TOLPRX
  56. #define DSI_ERROR_ECC_MASK (DSI_ISR1_ECCSE | DSI_ISR1_ECCME)
  57. #define DSI_ERROR_CRC_MASK DSI_ISR1_CRCE
  58. #define DSI_ERROR_PSE_MASK DSI_ISR1_PSE
  59. #define DSI_ERROR_EOT_MASK DSI_ISR1_EOTPE
  60. #define DSI_ERROR_OVF_MASK DSI_ISR1_LPWRE
  61. #define DSI_ERROR_GEN_MASK (DSI_ISR1_GCWRE | DSI_ISR1_GPWRE | DSI_ISR1_GPTXE | DSI_ISR1_GPRDE | DSI_ISR1_GPRXE)
  62. #define DSI_MAX_RETURN_PKT_SIZE ((uint32_t)0x00000037) /*!< Maximum return packet configuration */
  63. /**
  64. * @}
  65. */
  66. /* Private variables ---------------------------------------------------------*/
  67. /* Private constants ---------------------------------------------------------*/
  68. /* Private macros ------------------------------------------------------------*/
  69. /* Private function prototypes -----------------------------------------------*/
  70. static void DSI_ConfigPacketHeader(DSI_TypeDef *DSIx, uint32_t ChannelID, uint32_t DataType, uint32_t Data0, uint32_t Data1);
  71. /* Private functions ---------------------------------------------------------*/
  72. /* Exported functions --------------------------------------------------------*/
  73. /** @addtogroup DSI_Exported_Functions
  74. * @{
  75. */
  76. /** @defgroup DSI_Group1 Initialization and Configuration functions
  77. * @brief Initialization and Configuration functions
  78. *
  79. @verbatim
  80. ===============================================================================
  81. ##### Initialization and Configuration functions #####
  82. ===============================================================================
  83. [..] This section provides functions allowing to:
  84. (+) Initialize and configure the DSI
  85. (+) De-initialize the DSI
  86. @endverbatim
  87. * @{
  88. */
  89. /**
  90. * @brief De-initializes the DSI peripheral registers to their default reset
  91. * values.
  92. * @param DSIx: To select the DSIx peripheral, where x can be the different DSI instances
  93. * @retval None
  94. */
  95. void DSI_DeInit(DSI_TypeDef *DSIx)
  96. {
  97. /* Disable the DSI wrapper */
  98. DSIx->WCR &= ~DSI_WCR_DSIEN;
  99. /* Disable the DSI host */
  100. DSIx->CR &= ~DSI_CR_EN;
  101. /* D-PHY clock and digital disable */
  102. DSIx->PCTLR &= ~(DSI_PCTLR_CKE | DSI_PCTLR_DEN);
  103. /* Turn off the DSI PLL */
  104. DSIx->WRPCR &= ~DSI_WRPCR_PLLEN;
  105. /* Disable the regulator */
  106. DSIx->WRPCR &= ~DSI_WRPCR_REGEN;
  107. /* Check the parameters */
  108. assert_param(IS_DSI_ALL_PERIPH(DSIx));
  109. if(DSIx == DSI)
  110. {
  111. /* Enable DSI reset state */
  112. RCC_APB2PeriphResetCmd(RCC_APB2Periph_DSI, ENABLE);
  113. /* Release DSI from reset state */
  114. RCC_APB2PeriphResetCmd(RCC_APB2Periph_DSI, DISABLE);
  115. }
  116. }
  117. /**
  118. * @brief Deinitialize the DSIx peripheral registers to their default reset values.
  119. * @param DSIx: To select the DSIx peripheral, where x can be the different DSI instances
  120. * @param DSI_InitStruct: pointer to a DSI_InitTypeDef structure that
  121. * contains the configuration information for the specified DSI peripheral.
  122. * @param DSI_InitTIMStruct: pointer to a DSI_TIMTypeDef structure that
  123. * contains the configuration information for the specified DSI Timings.
  124. * @retval None
  125. */
  126. void DSI_Init(DSI_TypeDef *DSIx,DSI_InitTypeDef* DSI_InitStruct, DSI_PLLInitTypeDef *PLLInit)
  127. {
  128. uint32_t unitIntervalx4 = 0;
  129. uint32_t tempIDF = 0;
  130. /* Check function parameters */
  131. assert_param(IS_DSI_PLL_NDIV(PLLInit->PLLNDIV));
  132. assert_param(IS_DSI_PLL_IDF(PLLInit->PLLIDF));
  133. assert_param(IS_DSI_PLL_ODF(PLLInit->PLLODF));
  134. assert_param(IS_DSI_AUTO_CLKLANE_CONTROL(DSI_InitStruct->AutomaticClockLaneControl));
  135. assert_param(IS_DSI_NUMBER_OF_LANES(DSI_InitStruct->NumberOfLanes));
  136. /**************** Turn on the regulator and enable the DSI PLL ****************/
  137. /* Enable the regulator */
  138. DSIx->WRPCR |= DSI_WRPCR_REGEN;
  139. /* Wait until the regulator is ready */
  140. while(DSI_GetFlagStatus(DSIx, DSI_FLAG_RRS) == RESET )
  141. {}
  142. /* Set the PLL division factors */
  143. DSIx->WRPCR &= ~(DSI_WRPCR_PLL_NDIV | DSI_WRPCR_PLL_IDF | DSI_WRPCR_PLL_ODF);
  144. DSIx->WRPCR |= (((PLLInit->PLLNDIV)<<2) | ((PLLInit->PLLIDF)<<11) | ((PLLInit->PLLODF)<<16));
  145. /* Enable the DSI PLL */
  146. DSIx->WRPCR |= DSI_WRPCR_PLLEN;
  147. /* Wait for the lock of the PLL */
  148. while(DSI_GetFlagStatus(DSIx, DSI_FLAG_PLLLS) == RESET)
  149. {}
  150. /*************************** Set the PHY parameters ***************************/
  151. /* D-PHY clock and digital enable*/
  152. DSIx->PCTLR |= (DSI_PCTLR_CKE | DSI_PCTLR_DEN);
  153. /* Clock lane configuration */
  154. DSIx->CLCR &= ~(DSI_CLCR_DPCC | DSI_CLCR_ACR);
  155. DSIx->CLCR |= (DSI_CLCR_DPCC | DSI_InitStruct->AutomaticClockLaneControl);
  156. /* Configure the number of active data lanes */
  157. DSIx->PCONFR &= ~DSI_PCONFR_NL;
  158. DSIx->PCONFR |= DSI_InitStruct->NumberOfLanes;
  159. /************************ Set the DSI clock parameters ************************/
  160. /* Set the TX escape clock division factor */
  161. DSIx->CCR &= ~DSI_CCR_TXECKDIV;
  162. DSIx->CCR = DSI_InitStruct->TXEscapeCkdiv;
  163. /* Calculate the bit period in high-speed mode in unit of 0.25 ns (UIX4) */
  164. /* The equation is : UIX4 = IntegerPart( (1000/F_PHY_Mhz) * 4 ) */
  165. /* Where : F_PHY_Mhz = (NDIV * HSE_Mhz) / (IDF * ODF) */
  166. tempIDF = (PLLInit->PLLIDF > 0) ? PLLInit->PLLIDF : 1;
  167. unitIntervalx4 = (4000000 * tempIDF * (1 << PLLInit->PLLODF)) / ((HSE_VALUE/1000) * PLLInit->PLLNDIV);
  168. /* Set the bit period in high-speed mode */
  169. DSIx->WPCR[0] &= ~DSI_WPCR0_UIX4;
  170. DSIx->WPCR[0] |= unitIntervalx4;
  171. /****************************** Error management *****************************/
  172. /* Disable all error interrupts */
  173. DSIx->IER[0] = 0;
  174. DSIx->IER[1] = 0;
  175. }
  176. /**
  177. * @brief Fills each DSI_InitStruct member with its default value.
  178. * @param DSI_InitStruct: pointer to a DSI_InitTypeDef structure which will be initialized.
  179. * @retval None
  180. */
  181. void DSI_StructInit(DSI_InitTypeDef* DSI_InitStruct, DSI_HOST_TimeoutTypeDef* DSI_HOST_TimeoutInitStruct)
  182. {
  183. /*--------------- Reset DSI init structure parameters values ---------------*/
  184. /* Initialize the AutomaticClockLaneControl member */
  185. DSI_InitStruct->AutomaticClockLaneControl = DSI_AUTO_CLK_LANE_CTRL_DISABLE;
  186. /* Initialize the NumberOfLanes member */
  187. DSI_InitStruct->NumberOfLanes = DSI_ONE_DATA_LANE;
  188. /* Initialize the TX Escape clock division */
  189. DSI_InitStruct->TXEscapeCkdiv = 0;
  190. /*--------------- Reset DSI timings init structure parameters values -------*/
  191. /* Initialize the TimeoutCkdiv member */
  192. DSI_HOST_TimeoutInitStruct->TimeoutCkdiv = 0;
  193. /* Initialize the HighSpeedTransmissionTimeout member */
  194. DSI_HOST_TimeoutInitStruct->HighSpeedTransmissionTimeout = 0;
  195. /* Initialize the LowPowerReceptionTimeout member */
  196. DSI_HOST_TimeoutInitStruct->LowPowerReceptionTimeout = 0;
  197. /* Initialize the HighSpeedReadTimeout member */
  198. DSI_HOST_TimeoutInitStruct->HighSpeedReadTimeout = 0;
  199. /* Initialize the LowPowerReadTimeout member */
  200. DSI_HOST_TimeoutInitStruct->LowPowerReadTimeout = 0;
  201. /* Initialize the HighSpeedWriteTimeout member */
  202. DSI_HOST_TimeoutInitStruct->HighSpeedWriteTimeout = 0;
  203. /* Initialize the HighSpeedWritePrespMode member */
  204. DSI_HOST_TimeoutInitStruct->HighSpeedWritePrespMode = 0;
  205. /* Initialize the LowPowerWriteTimeout member */
  206. DSI_HOST_TimeoutInitStruct->LowPowerWriteTimeout = 0;
  207. /* Initialize the BTATimeout member */
  208. DSI_HOST_TimeoutInitStruct->BTATimeout = 0;
  209. }
  210. /**
  211. * @brief Configure the Generic interface read-back Virtual Channel ID.
  212. * @param DSIx: To select the DSIx peripheral, where x can be the different DSI instances
  213. * @param VirtualChannelID: Virtual channel ID
  214. * @retval None
  215. */
  216. void DSI_SetGenericVCID(DSI_TypeDef *DSIx, uint32_t VirtualChannelID)
  217. {
  218. /* Update the GVCID register */
  219. DSIx->GVCIDR &= ~DSI_GVCIDR_VCID;
  220. DSIx->GVCIDR |= VirtualChannelID;
  221. }
  222. /**
  223. * @brief Select video mode and configure the corresponding parameters
  224. * @param DSIx: To select the DSIx peripheral, where x can be the different DSI instances
  225. * @param VidCfg: pointer to a DSI_VidCfgTypeDef structure that contains
  226. * the DSI video mode configuration parameters
  227. * @retval None
  228. */
  229. void DSI_ConfigVideoMode(DSI_TypeDef *DSIx, DSI_VidCfgTypeDef *VidCfg)
  230. {
  231. /* Check the parameters */
  232. assert_param(IS_DSI_COLOR_CODING(VidCfg->ColorCoding));
  233. assert_param(IS_DSI_VIDEO_MODE_TYPE(VidCfg->Mode));
  234. assert_param(IS_DSI_LP_COMMAND(VidCfg->LPCommandEnable));
  235. assert_param(IS_DSI_LP_HFP(VidCfg->LPHorizontalFrontPorchEnable));
  236. assert_param(IS_DSI_LP_HBP(VidCfg->LPHorizontalBackPorchEnable));
  237. assert_param(IS_DSI_LP_VACTIVE(VidCfg->LPVerticalActiveEnable));
  238. assert_param(IS_DSI_LP_VFP(VidCfg->LPVerticalFrontPorchEnable));
  239. assert_param(IS_DSI_LP_VBP(VidCfg->LPVerticalBackPorchEnable));
  240. assert_param(IS_DSI_LP_VSYNC(VidCfg->LPVerticalSyncActiveEnable));
  241. assert_param(IS_DSI_FBTAA(VidCfg->FrameBTAAcknowledgeEnable));
  242. assert_param(IS_DSI_DE_POLARITY(VidCfg->DEPolarity));
  243. assert_param(IS_DSI_VSYNC_POLARITY(VidCfg->VSPolarity));
  244. assert_param(IS_DSI_HSYNC_POLARITY(VidCfg->HSPolarity));
  245. /* Check the LooselyPacked variant only in 18-bit mode */
  246. if(VidCfg->ColorCoding == DSI_RGB666)
  247. {
  248. assert_param(IS_DSI_LOOSELY_PACKED(VidCfg->LooselyPacked));
  249. }
  250. /* Select video mode by resetting CMDM and DSIM bits */
  251. DSIx->MCR &= ~DSI_MCR_CMDM;
  252. DSIx->WCFGR &= ~DSI_WCFGR_DSIM;
  253. /* Configure the video mode transmission type */
  254. DSIx->VMCR &= ~DSI_VMCR_VMT;
  255. DSIx->VMCR |= VidCfg->Mode;
  256. /* Configure the video packet size */
  257. DSIx->VPCR &= ~DSI_VPCR_VPSIZE;
  258. DSIx->VPCR |= VidCfg->PacketSize;
  259. /* Set the chunks number to be transmitted through the DSI link */
  260. DSIx->VCCR &= ~DSI_VCCR_NUMC;
  261. DSIx->VCCR |= VidCfg->NumberOfChunks;
  262. /* Set the size of the null packet */
  263. DSIx->VNPCR &= ~DSI_VNPCR_NPSIZE;
  264. DSIx->VNPCR |= VidCfg->NullPacketSize;
  265. /* Select the virtual channel for the LTDC interface traffic */
  266. DSIx->LVCIDR &= ~DSI_LVCIDR_VCID;
  267. DSIx->LVCIDR |= VidCfg->VirtualChannelID;
  268. /* Configure the polarity of control signals */
  269. DSIx->LPCR &= ~(DSI_LPCR_DEP | DSI_LPCR_VSP | DSI_LPCR_HSP);
  270. DSIx->LPCR |= (VidCfg->DEPolarity | VidCfg->VSPolarity | VidCfg->HSPolarity);
  271. /* Select the color coding for the host */
  272. DSIx->LCOLCR &= ~DSI_LCOLCR_COLC;
  273. DSIx->LCOLCR |= VidCfg->ColorCoding;
  274. /* Select the color coding for the wrapper */
  275. DSIx->WCFGR &= ~DSI_WCFGR_COLMUX;
  276. DSIx->WCFGR |= ((VidCfg->ColorCoding)<<1);
  277. /* Enable/disable the loosely packed variant to 18-bit configuration */
  278. if(VidCfg->ColorCoding == DSI_RGB666)
  279. {
  280. DSIx->LCOLCR &= ~DSI_LCOLCR_LPE;
  281. DSIx->LCOLCR |= VidCfg->LooselyPacked;
  282. }
  283. /* Set the Horizontal Synchronization Active (HSA) in lane byte clock cycles */
  284. DSIx->VHSACR &= ~DSI_VHSACR_HSA;
  285. DSIx->VHSACR |= VidCfg->HorizontalSyncActive;
  286. /* Set the Horizontal Back Porch (HBP) in lane byte clock cycles */
  287. DSIx->VHBPCR &= ~DSI_VHBPCR_HBP;
  288. DSIx->VHBPCR |= VidCfg->HorizontalBackPorch;
  289. /* Set the total line time (HLINE=HSA+HBP+HACT+HFP) in lane byte clock cycles */
  290. DSIx->VLCR &= ~DSI_VLCR_HLINE;
  291. DSIx->VLCR |= VidCfg->HorizontalLine;
  292. /* Set the Vertical Synchronization Active (VSA) */
  293. DSIx->VVSACR &= ~DSI_VVSACR_VSA;
  294. DSIx->VVSACR |= VidCfg->VerticalSyncActive;
  295. /* Set the Vertical Back Porch (VBP)*/
  296. DSIx->VVBPCR &= ~DSI_VVBPCR_VBP;
  297. DSIx->VVBPCR |= VidCfg->VerticalBackPorch;
  298. /* Set the Vertical Front Porch (VFP)*/
  299. DSIx->VVFPCR &= ~DSI_VVFPCR_VFP;
  300. DSIx->VVFPCR |= VidCfg->VerticalFrontPorch;
  301. /* Set the Vertical Active period*/
  302. DSIx->VVACR &= ~DSI_VVACR_VA;
  303. DSIx->VVACR |= VidCfg->VerticalActive;
  304. /* Configure the command transmission mode */
  305. DSIx->VMCR &= ~DSI_VMCR_LPCE;
  306. DSIx->VMCR |= VidCfg->LPCommandEnable;
  307. /* Low power largest packet size */
  308. DSIx->LPMCR &= ~DSI_LPMCR_LPSIZE;
  309. DSIx->LPMCR |= ((VidCfg->LPLargestPacketSize)<<16);
  310. /* Low power VACT largest packet size */
  311. DSIx->LPMCR &= ~DSI_LPMCR_VLPSIZE;
  312. DSIx->LPMCR |= VidCfg->LPVACTLargestPacketSize;
  313. /* Enable LP transition in HFP period */
  314. DSIx->VMCR &= ~DSI_VMCR_LPHFPE;
  315. DSIx->VMCR |= VidCfg->LPHorizontalFrontPorchEnable;
  316. /* Enable LP transition in HBP period */
  317. DSIx->VMCR &= ~DSI_VMCR_LPHBPE;
  318. DSIx->VMCR |= VidCfg->LPHorizontalBackPorchEnable;
  319. /* Enable LP transition in VACT period */
  320. DSIx->VMCR &= ~DSI_VMCR_LPVAE;
  321. DSIx->VMCR |= VidCfg->LPVerticalActiveEnable;
  322. /* Enable LP transition in VFP period */
  323. DSIx->VMCR &= ~DSI_VMCR_LPVFPE;
  324. DSIx->VMCR |= VidCfg->LPVerticalFrontPorchEnable;
  325. /* Enable LP transition in VBP period */
  326. DSIx->VMCR &= ~DSI_VMCR_LPVBPE;
  327. DSIx->VMCR |= VidCfg->LPVerticalBackPorchEnable;
  328. /* Enable LP transition in vertical sync period */
  329. DSIx->VMCR &= ~DSI_VMCR_LPVSAE;
  330. DSIx->VMCR |= VidCfg->LPVerticalSyncActiveEnable;
  331. /* Enable the request for an acknowledge response at the end of a frame */
  332. DSIx->VMCR &= ~DSI_VMCR_FBTAAE;
  333. DSIx->VMCR |= VidCfg->FrameBTAAcknowledgeEnable;
  334. }
  335. /**
  336. * @brief Select adapted command mode and configure the corresponding parameters
  337. * @param DSIx: To select the DSIx peripheral, where x can be the different DSI instances
  338. * @param CmdCfg: pointer to a DSI_CmdCfgTypeDef structure that contains
  339. * the DSI command mode configuration parameters
  340. * @retval None
  341. */
  342. void DSI_ConfigAdaptedCommandMode(DSI_TypeDef *DSIx, DSI_CmdCfgTypeDef *CmdCfg)
  343. {
  344. /* Check the parameters */
  345. assert_param(IS_DSI_COLOR_CODING(CmdCfg->ColorCoding));
  346. assert_param(IS_DSI_TE_SOURCE(CmdCfg->TearingEffectSource));
  347. assert_param(IS_DSI_TE_POLARITY(CmdCfg->TearingEffectPolarity));
  348. assert_param(IS_DSI_AUTOMATIC_REFRESH(CmdCfg->AutomaticRefresh));
  349. assert_param(IS_DSI_VS_POLARITY(CmdCfg->VSyncPol));
  350. assert_param(IS_DSI_TE_ACK_REQUEST(CmdCfg->TEAcknowledgeRequest));
  351. assert_param(IS_DSI_DE_POLARITY(CmdCfg->DEPolarity));
  352. assert_param(IS_DSI_VSYNC_POLARITY(CmdCfg->VSPolarity));
  353. assert_param(IS_DSI_HSYNC_POLARITY(CmdCfg->HSPolarity));
  354. /* Select command mode by setting CMDM and DSIM bits */
  355. DSIx->MCR |= DSI_MCR_CMDM;
  356. DSIx->WCFGR &= ~DSI_WCFGR_DSIM;
  357. DSIx->WCFGR |= DSI_WCFGR_DSIM;
  358. /* Select the virtual channel for the LTDC interface traffic */
  359. DSIx->LVCIDR &= ~DSI_LVCIDR_VCID;
  360. DSIx->LVCIDR |= CmdCfg->VirtualChannelID;
  361. /* Configure the polarity of control signals */
  362. DSIx->LPCR &= ~(DSI_LPCR_DEP | DSI_LPCR_VSP | DSI_LPCR_HSP);
  363. DSIx->LPCR |= (CmdCfg->DEPolarity | CmdCfg->VSPolarity | CmdCfg->HSPolarity);
  364. /* Select the color coding for the host */
  365. DSIx->LCOLCR &= ~DSI_LCOLCR_COLC;
  366. DSIx->LCOLCR |= CmdCfg->ColorCoding;
  367. /* Select the color coding for the wrapper */
  368. DSIx->WCFGR &= ~DSI_WCFGR_COLMUX;
  369. DSIx->WCFGR |= ((CmdCfg->ColorCoding)<<1);
  370. /* Configure the maximum allowed size for write memory command */
  371. DSIx->LCCR &= ~DSI_LCCR_CMDSIZE;
  372. DSIx->LCCR |= CmdCfg->CommandSize;
  373. /* Configure the tearing effect source and polarity and select the refresh mode */
  374. DSIx->WCFGR &= ~(DSI_WCFGR_TESRC | DSI_WCFGR_TEPOL | DSI_WCFGR_AR | DSI_WCFGR_VSPOL);
  375. DSIx->WCFGR |= (CmdCfg->TearingEffectSource | CmdCfg->TearingEffectPolarity | CmdCfg->AutomaticRefresh | CmdCfg->VSyncPol);
  376. /* Configure the tearing effect acknowledge request */
  377. DSIx->CMCR &= ~DSI_CMCR_TEARE;
  378. DSIx->CMCR |= CmdCfg->TEAcknowledgeRequest;
  379. /* Enable the Tearing Effect interrupt */
  380. DSI_ITConfig(DSIx, DSI_IT_TE, ENABLE);
  381. /* Enable the End of Refresh interrupt */
  382. DSI_ITConfig(DSIx, DSI_IT_ER, ENABLE);
  383. }
  384. /**
  385. * @brief Configure command transmission mode: High-speed or Low-power
  386. * and enable/disable acknowledge request after packet transmission
  387. * @param DSIx: To select the DSIx peripheral, where x can be the different DSI instances
  388. * @param LPCmd: pointer to a DSI_LPCmdTypeDef structure that contains
  389. * the DSI command transmission mode configuration parameters
  390. * @retval None
  391. */
  392. void DSI_ConfigCommand(DSI_TypeDef *DSIx, DSI_LPCmdTypeDef *LPCmd)
  393. {
  394. assert_param(IS_DSI_LP_GSW0P(LPCmd->LPGenShortWriteNoP));
  395. assert_param(IS_DSI_LP_GSW1P(LPCmd->LPGenShortWriteOneP));
  396. assert_param(IS_DSI_LP_GSW2P(LPCmd->LPGenShortWriteTwoP));
  397. assert_param(IS_DSI_LP_GSR0P(LPCmd->LPGenShortReadNoP));
  398. assert_param(IS_DSI_LP_GSR1P(LPCmd->LPGenShortReadOneP));
  399. assert_param(IS_DSI_LP_GSR2P(LPCmd->LPGenShortReadTwoP));
  400. assert_param(IS_DSI_LP_GLW(LPCmd->LPGenLongWrite));
  401. assert_param(IS_DSI_LP_DSW0P(LPCmd->LPDcsShortWriteNoP));
  402. assert_param(IS_DSI_LP_DSW1P(LPCmd->LPDcsShortWriteOneP));
  403. assert_param(IS_DSI_LP_DSR0P(LPCmd->LPDcsShortReadNoP));
  404. assert_param(IS_DSI_LP_DLW(LPCmd->LPDcsLongWrite));
  405. assert_param(IS_DSI_LP_MRDP(LPCmd->LPMaxReadPacket));
  406. assert_param(IS_DSI_ACK_REQUEST(LPCmd->AcknowledgeRequest));
  407. /* Select High-speed or Low-power for command transmission */
  408. DSIx->CMCR &= ~(DSI_CMCR_GSW0TX |\
  409. DSI_CMCR_GSW1TX |\
  410. DSI_CMCR_GSW2TX |\
  411. DSI_CMCR_GSR0TX |\
  412. DSI_CMCR_GSR1TX |\
  413. DSI_CMCR_GSR2TX |\
  414. DSI_CMCR_GLWTX |\
  415. DSI_CMCR_DSW0TX |\
  416. DSI_CMCR_DSW1TX |\
  417. DSI_CMCR_DSR0TX |\
  418. DSI_CMCR_DLWTX |\
  419. DSI_CMCR_MRDPS);
  420. DSIx->CMCR |= (LPCmd->LPGenShortWriteNoP |\
  421. LPCmd->LPGenShortWriteOneP |\
  422. LPCmd->LPGenShortWriteTwoP |\
  423. LPCmd->LPGenShortReadNoP |\
  424. LPCmd->LPGenShortReadOneP |\
  425. LPCmd->LPGenShortReadTwoP |\
  426. LPCmd->LPGenLongWrite |\
  427. LPCmd->LPDcsShortWriteNoP |\
  428. LPCmd->LPDcsShortWriteOneP |\
  429. LPCmd->LPDcsShortReadNoP |\
  430. LPCmd->LPDcsLongWrite |\
  431. LPCmd->LPMaxReadPacket);
  432. /* Configure the acknowledge request after each packet transmission */
  433. DSIx->CMCR &= ~DSI_CMCR_ARE;
  434. DSIx->CMCR |= LPCmd->AcknowledgeRequest;
  435. }
  436. /**
  437. * @brief Configure the flow control parameters
  438. * @param DSIx: To select the DSIx peripheral, where x can be the different DSI instances
  439. * @param FlowControl: flow control feature(s) to be enabled.
  440. * This parameter can be any combination of @ref DSI_FlowControl.
  441. * @retval None
  442. */
  443. void DSI_ConfigFlowControl(DSI_TypeDef *DSIx, uint32_t FlowControl)
  444. {
  445. /* Check the parameters */
  446. assert_param(IS_DSI_FLOW_CONTROL(FlowControl));
  447. /* Set the DSI Host Protocol Configuration Register */
  448. DSIx->PCR &= ~DSI_FLOW_CONTROL_ALL;
  449. DSIx->PCR |= FlowControl;
  450. }
  451. /**
  452. * @brief Configure the DSI PHY timer parameters
  453. * @param DSIx: To select the DSIx peripheral, where x can be the different DSI instances
  454. * @param PhyTimers: DSI_PHY_TimerTypeDef structure that contains
  455. * the DSI PHY timing parameters
  456. * @retval None
  457. */
  458. void DSI_ConfigPhyTimer(DSI_TypeDef *DSIx, DSI_PHY_TimerTypeDef *PhyTimers)
  459. {
  460. uint32_t maxTime = 0;
  461. maxTime = (PhyTimers->ClockLaneLP2HSTime > PhyTimers->ClockLaneHS2LPTime)? PhyTimers->ClockLaneLP2HSTime: PhyTimers->ClockLaneHS2LPTime;
  462. /* Clock lane timer configuration */
  463. /* In Automatic Clock Lane control mode, the DSI Host can turn off the clock lane between two
  464. High-Speed transmission.
  465. To do so, the DSI Host calculates the time required for the clock lane to change from HighSpeed
  466. to Low-Power and from Low-Power to High-Speed.
  467. This timings are configured by the HS2LP_TIME and LP2HS_TIME in the DSI Host Clock Lane Timer Configuration Register (DSI_CLTCR).
  468. But the DSI Host is not calculating LP2HS_TIME + HS2LP_TIME but 2 x HS2LP_TIME.
  469. Workaround : Configure HS2LP_TIME and LP2HS_TIME with the same value being the max of HS2LP_TIME or LP2HS_TIME.
  470. */
  471. DSIx->CLTCR &= ~(DSI_CLTCR_LP2HS_TIME | DSI_CLTCR_HS2LP_TIME);
  472. DSIx->CLTCR |= (maxTime | ((maxTime)<<16));
  473. /* Data lane timer configuration */
  474. DSIx->DLTCR &= ~(DSI_DLTCR_MRD_TIME | DSI_DLTCR_LP2HS_TIME | DSI_DLTCR_HS2LP_TIME);
  475. DSIx->DLTCR |= (PhyTimers->DataLaneMaxReadTime | ((PhyTimers->DataLaneLP2HSTime)<<16) | ((PhyTimers->DataLaneHS2LPTime)<<24));
  476. /* Configure the wait period to request HS transmission after a stop state */
  477. DSIx->PCONFR &= ~DSI_PCONFR_SW_TIME;
  478. DSIx->PCONFR |= ((PhyTimers->StopWaitTime)<<8);
  479. }
  480. /**
  481. * @brief Configure the DSI HOST timeout parameters
  482. * @param DSIx: To select the DSIx peripheral, where x can be the different DSI instances
  483. * @param HostTimeouts: DSI_HOST_TimeoutTypeDef structure that contains
  484. * the DSI host timeout parameters
  485. * @retval None
  486. */
  487. void DSI_ConfigHostTimeouts(DSI_TypeDef *DSIx, DSI_HOST_TimeoutTypeDef *HostTimeouts)
  488. {
  489. /* Set the timeout clock division factor */
  490. DSIx->CCR &= ~DSI_CCR_TOCKDIV;
  491. DSIx->CCR = ((HostTimeouts->TimeoutCkdiv)<<8);
  492. /* High-speed transmission timeout */
  493. DSIx->TCCR[0] &= ~DSI_TCCR0_HSTX_TOCNT;
  494. DSIx->TCCR[0] |= ((HostTimeouts->HighSpeedTransmissionTimeout)<<16);
  495. /* Low-power reception timeout */
  496. DSIx->TCCR[0] &= ~DSI_TCCR0_LPRX_TOCNT;
  497. DSIx->TCCR[0] |= HostTimeouts->LowPowerReceptionTimeout;
  498. /* High-speed read timeout */
  499. DSIx->TCCR[1] &= ~DSI_TCCR1_HSRD_TOCNT;
  500. DSIx->TCCR[1] |= HostTimeouts->HighSpeedReadTimeout;
  501. /* Low-power read timeout */
  502. DSIx->TCCR[2] &= ~DSI_TCCR2_LPRD_TOCNT;
  503. DSIx->TCCR[2] |= HostTimeouts->LowPowerReadTimeout;
  504. /* High-speed write timeout */
  505. DSIx->TCCR[3] &= ~DSI_TCCR3_HSWR_TOCNT;
  506. DSIx->TCCR[3] |= HostTimeouts->HighSpeedWriteTimeout;
  507. /* High-speed write presp mode */
  508. DSIx->TCCR[3] &= ~DSI_TCCR3_PM;
  509. DSIx->TCCR[3] |= HostTimeouts->HighSpeedWritePrespMode;
  510. /* Low-speed write timeout */
  511. DSIx->TCCR[4] &= ~DSI_TCCR4_LPWR_TOCNT;
  512. DSIx->TCCR[4] |= HostTimeouts->LowPowerWriteTimeout;
  513. /* BTA timeout */
  514. DSIx->TCCR[5] &= ~DSI_TCCR5_BTA_TOCNT;
  515. DSIx->TCCR[5] |= HostTimeouts->BTATimeout;
  516. }
  517. /**
  518. * @brief Start the DSI module
  519. * @param DSIx: To select the DSIx peripheral, where x can be the different DSI instances
  520. * the configuration information for the DSI.
  521. * @retval None
  522. */
  523. void DSI_Start(DSI_TypeDef *DSIx)
  524. {
  525. /* Enable the DSI host */
  526. DSIx->CR |= DSI_CR_EN;
  527. /* Enable the DSI wrapper */
  528. DSIx->WCR |= DSI_WCR_DSIEN;
  529. }
  530. /**
  531. * @brief Stop the DSI module
  532. * @param DSIx: To select the DSIx peripheral, where x can be the different DSI instances
  533. * @retval None
  534. */
  535. void DSI_Stop(DSI_TypeDef *DSIx)
  536. {
  537. /* Disable the DSI host */
  538. DSIx->CR &= ~DSI_CR_EN;
  539. /* Disable the DSI wrapper */
  540. DSIx->WCR &= ~DSI_WCR_DSIEN;
  541. }
  542. /**
  543. * @brief Refresh the display in command mode
  544. * @param DSIx: To select the DSIx peripheral, where x can be the different DSI instances
  545. * the configuration information for the DSI.
  546. * @retval None
  547. */
  548. void DSI_Refresh(DSI_TypeDef *DSIx)
  549. {
  550. /* Update the display */
  551. DSIx->WCR |= DSI_WCR_LTDCEN;
  552. }
  553. /**
  554. * @brief Controls the display color mode in Video mode
  555. * @param DSIx: To select the DSIx peripheral, where x can be the different DSI instances
  556. * @param ColorMode: Color mode (full or 8-colors).
  557. * This parameter can be any value of @ref DSI_Color_Mode
  558. * @retval None
  559. */
  560. void DSI_ColorMode(DSI_TypeDef *DSIx, uint32_t ColorMode)
  561. {
  562. /* Check the parameters */
  563. assert_param(IS_DSI_COLOR_MODE(ColorMode));
  564. /* Update the display color mode */
  565. DSIx->WCR &= ~DSI_WCR_COLM;
  566. DSIx->WCR |= ColorMode;
  567. }
  568. /**
  569. * @brief Control the display shutdown in Video mode
  570. * @param DSIx: To select the DSIx peripheral, where x can be the different DSI instances
  571. * @param Shutdown: Shut-down (Display-ON or Display-OFF).
  572. * This parameter can be any value of @ref DSI_ShutDown
  573. * @retval None
  574. */
  575. void DSI_Shutdown(DSI_TypeDef *DSIx, uint32_t Shutdown)
  576. {
  577. /* Check the parameters */
  578. assert_param(IS_DSI_SHUT_DOWN(Shutdown));
  579. /* Update the display Shutdown */
  580. DSIx->WCR &= ~DSI_WCR_SHTDN;
  581. DSIx->WCR |= Shutdown;
  582. }
  583. /**
  584. * @}
  585. */
  586. /** @defgroup Data transfers management functions
  587. * @brief DSI data transfers management functions
  588. *
  589. @verbatim
  590. ===============================================================================
  591. ##### Data transfers management functions #####
  592. ===============================================================================
  593. @endverbatim
  594. * @{
  595. */
  596. /**
  597. * @brief DCS or Generic short write command
  598. * @param DSIx: To select the DSIx peripheral, where x can be the different DSI instances
  599. * @param ChannelID: Virtual channel ID.
  600. * @param Mode: DSI short packet data type.
  601. * This parameter can be any value of @ref DSI_SHORT_WRITE_PKT_Data_Type.
  602. * @param Param1: DSC command or first generic parameter.
  603. * This parameter can be any value of @ref DSI_DCS_Command or a
  604. * generic command code.
  605. * @param Param2: DSC parameter or second generic parameter.
  606. * @retval None
  607. */
  608. void DSI_ShortWrite(DSI_TypeDef *DSIx,
  609. uint32_t ChannelID,
  610. uint32_t Mode,
  611. uint32_t Param1,
  612. uint32_t Param2)
  613. {
  614. /* Check the parameters */
  615. assert_param(IS_DSI_SHORT_WRITE_PACKET_TYPE(Mode));
  616. /* Wait for Command FIFO Empty */
  617. while((DSIx->GPSR & DSI_GPSR_CMDFE) == 0)
  618. {}
  619. /* Configure the packet to send a short DCS command with 0 or 1 parameter */
  620. DSI_ConfigPacketHeader(DSIx,
  621. ChannelID,
  622. Mode,
  623. Param1,
  624. Param2);
  625. }
  626. /**
  627. * @brief DCS or Generic long write command
  628. * @param DSIx: To select the DSIx peripheral, where x can be the different DSI instances
  629. * @param ChannelID: Virtual channel ID.
  630. * @param Mode: DSI long packet data type.
  631. * This parameter can be any value of @ref DSI_LONG_WRITE_PKT_Data_Type.
  632. * @param NbParams: Number of parameters.
  633. * @param Param1: DSC command or first generic parameter.
  634. * This parameter can be any value of @ref DSI_DCS_Command or a
  635. * generic command code
  636. * @param ParametersTable: Pointer to parameter values table.
  637. * @retval None
  638. */
  639. void DSI_LongWrite(DSI_TypeDef *DSIx,
  640. uint32_t ChannelID,
  641. uint32_t Mode,
  642. uint32_t NbParams,
  643. uint32_t Param1,
  644. uint8_t* ParametersTable)
  645. {
  646. uint32_t uicounter = 0;
  647. /* Check the parameters */
  648. assert_param(IS_DSI_LONG_WRITE_PACKET_TYPE(Mode));
  649. /* Wait for Command FIFO Empty */
  650. while((DSIx->GPSR & DSI_GPSR_CMDFE) == 0)
  651. {}
  652. /* Set the DCS code hexadecimal on payload byte 1, and the other parameters on the write FIFO command*/
  653. while(uicounter < NbParams)
  654. {
  655. if(uicounter == 0x00)
  656. {
  657. DSIx->GPDR=(Param1 | \
  658. ((uint32_t)(*(ParametersTable+uicounter))<<8) | \
  659. ((uint32_t)(*(ParametersTable+uicounter+1))<<16) | \
  660. ((uint32_t)(*(ParametersTable+uicounter+2))<<24));
  661. uicounter += 3;
  662. }
  663. else
  664. {
  665. DSIx->GPDR=((*(ParametersTable+uicounter)) | \
  666. ((uint32_t)(*(ParametersTable+uicounter+1))<<8) | \
  667. ((uint32_t)(*(ParametersTable+uicounter+2))<<16) | \
  668. ((uint32_t)(*(ParametersTable+uicounter+3))<<24));
  669. uicounter+=4;
  670. }
  671. }
  672. /* Configure the packet to send a long DCS command */
  673. DSI_ConfigPacketHeader(DSIx,
  674. ChannelID,
  675. Mode,
  676. ((NbParams+1)&0x00FF),
  677. (((NbParams+1)&0xFF00)>>8));
  678. }
  679. /**
  680. * @brief Read command (DCS or generic)
  681. * @param DSIx: To select the DSIx peripheral, where x can be the different DSI instances
  682. * @param ChannelNbr: Virtual channel ID
  683. * @param Array: pointer to a buffer to store the payload of a read back operation.
  684. * @param Size: Data size to be read (in byte).
  685. * @param Mode: DSI read packet data type.
  686. * This parameter can be any value of @ref DSI_SHORT_READ_PKT_Data_Type.
  687. * @param DCSCmd: DCS get/read command.
  688. * @param ParametersTable: Pointer to parameter values table.
  689. * @retval None
  690. */
  691. void DSI_Read(DSI_TypeDef *DSIx,
  692. uint32_t ChannelNbr,
  693. uint8_t* Array,
  694. uint32_t Size,
  695. uint32_t Mode,
  696. uint32_t DCSCmd,
  697. uint8_t* ParametersTable)
  698. {
  699. /* Check the parameters */
  700. assert_param(IS_DSI_READ_PACKET_TYPE(Mode));
  701. if(Size > 2)
  702. {
  703. /* set max return packet size */
  704. DSI_ShortWrite(DSIx, ChannelNbr, DSI_MAX_RETURN_PKT_SIZE, ((Size)&0xFF), (((Size)>>8)&0xFF));
  705. }
  706. /* Configure the packet to read command */
  707. if (Mode == DSI_DCS_SHORT_PKT_READ)
  708. {
  709. DSI_ConfigPacketHeader(DSIx, ChannelNbr, Mode, DCSCmd, 0);
  710. }
  711. else if (Mode == DSI_GEN_SHORT_PKT_READ_P0)
  712. {
  713. DSI_ConfigPacketHeader(DSIx, ChannelNbr, Mode, 0, 0);
  714. }
  715. else if (Mode == DSI_GEN_SHORT_PKT_READ_P1)
  716. {
  717. DSI_ConfigPacketHeader(DSIx, ChannelNbr, Mode, ParametersTable[0], 0);
  718. }
  719. else /* DSI_GEN_SHORT_PKT_READ_P2 */
  720. {
  721. DSI_ConfigPacketHeader(DSIx, ChannelNbr, Mode, ParametersTable[0], ParametersTable[1]);
  722. }
  723. /* Check that the payload read FIFO is not empty */
  724. while((DSIx->GPSR & DSI_GPSR_PRDFE) == DSI_GPSR_PRDFE)
  725. {}
  726. /* Get the first byte */
  727. *((uint32_t *)Array) = (DSIx->GPDR);
  728. if (Size > 4)
  729. {
  730. Size -= 4;
  731. Array += 4;
  732. }
  733. /* Get the remaining bytes if any */
  734. while(((int)(Size)) > 0)
  735. {
  736. if((DSIx->GPSR & DSI_GPSR_PRDFE) == 0)
  737. {
  738. *((uint32_t *)Array) = (DSIx->GPDR);
  739. Size -= 4;
  740. Array += 4;
  741. }
  742. }
  743. }
  744. /**
  745. * @brief Generic DSI packet header configuration
  746. * @param DSIx: Pointer to DSI register base
  747. * @param ChannelID: Virtual channel ID of the header packet
  748. * @param DataType: Packet data type of the header packet
  749. * This parameter can be any value of :
  750. * @ref DSI_SHORT_WRITE_PKT_Data_Type
  751. * or @ref DSI_LONG_WRITE_PKT_Data_Type
  752. * or @ref DSI_SHORT_READ_PKT_Data_Type
  753. * or DSI_MAX_RETURN_PKT_SIZE
  754. * @param Data0: Word count LSB
  755. * @param Data1: Word count MSB
  756. * @retval None
  757. */
  758. static void DSI_ConfigPacketHeader(DSI_TypeDef *DSIx,
  759. uint32_t ChannelID,
  760. uint32_t DataType,
  761. uint32_t Data0,
  762. uint32_t Data1)
  763. {
  764. /* Update the DSI packet header with new information */
  765. DSIx->GHCR = (DataType | (ChannelID<<6) | (Data0<<8) | (Data1<<16));
  766. }
  767. /**
  768. * @}
  769. */
  770. /** @defgroup DSI_Group3 Low Power functions
  771. * @brief DSI Low Power management functions
  772. *
  773. @verbatim
  774. ===============================================================================
  775. ##### DSI Low Power functions #####
  776. ===============================================================================
  777. @endverbatim
  778. * @{
  779. */
  780. /**
  781. * @brief Enter the ULPM (Ultra Low Power Mode) with the D-PHY PLL running
  782. * (only data lanes are in ULPM)
  783. * @param DSIx: Pointer to DSI register base
  784. * @retval None
  785. */
  786. void DSI_EnterULPMData(DSI_TypeDef *DSIx)
  787. {
  788. /* ULPS Request on Data Lanes */
  789. DSIx->PUCR |= DSI_PUCR_URDL;
  790. /* Wait until the D-PHY active lanes enter into ULPM */
  791. if((DSIx->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
  792. {
  793. while((DSIx->PSR & DSI_PSR_UAN0) != 0)
  794. {}
  795. }
  796. else /* DSI_TWO_DATA_LANES */
  797. {
  798. while((DSIx->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1)) != 0)
  799. {}
  800. }
  801. }
  802. /**
  803. * @brief Exit the ULPM (Ultra Low Power Mode) with the D-PHY PLL running
  804. * (only data lanes are in ULPM)
  805. * @param DSIx: Pointer to DSI register base
  806. * @retval None
  807. */
  808. void DSI_ExitULPMData(DSI_TypeDef *DSIx)
  809. {
  810. /* Exit ULPS on Data Lanes */
  811. DSIx->PUCR |= DSI_PUCR_UEDL;
  812. /* Wait until all active lanes exit ULPM */
  813. if((DSIx->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
  814. {
  815. while((DSIx->PSR & DSI_PSR_UAN0) != DSI_PSR_UAN0)
  816. {}
  817. }
  818. else /* DSI_TWO_DATA_LANES */
  819. {
  820. while((DSIx->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1)) != (DSI_PSR_UAN0 | DSI_PSR_UAN1))
  821. {}
  822. }
  823. /* De-assert the ULPM requests and the ULPM exit bits */
  824. DSIx->PUCR = 0;
  825. }
  826. /**
  827. * @brief Enter the ULPM (Ultra Low Power Mode) with the D-PHY PLL turned off
  828. * (both data and clock lanes are in ULPM)
  829. * @param DSIx: Pointer to DSI register base
  830. * @retval None
  831. */
  832. void DSI_EnterULPM(DSI_TypeDef *DSIx)
  833. {
  834. /* Clock lane configuration: no more HS request */
  835. DSIx->CLCR &= ~DSI_CLCR_DPCC;
  836. /* Use system PLL as byte lane clock source before stopping DSIPHY clock source */
  837. RCC_DSIClockSourceConfig(RCC_DSICLKSource_PLLR);
  838. /* ULPS Request on Clock and Data Lanes */
  839. DSIx->PUCR |= (DSI_PUCR_URCL | DSI_PUCR_URDL);
  840. /* Wait until all active lanes exit ULPM */
  841. if((DSIx->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
  842. {
  843. while((DSIx->PSR & (DSI_PSR_UAN0 | DSI_PSR_UANC)) != 0)
  844. {}
  845. }
  846. else /* DSI_TWO_DATA_LANES */
  847. {
  848. while((DSIx->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1 | DSI_PSR_UANC)) != 0)
  849. {}
  850. }
  851. /* Turn off the DSI PLL */
  852. DSIx->WRPCR &= ~DSI_WRPCR_PLLEN;
  853. }
  854. /**
  855. * @brief Exit the ULPM (Ultra Low Power Mode) with the D-PHY PLL turned off
  856. * (both data and clock lanes are in ULPM)
  857. * @param DSIx: Pointer to DSI register base
  858. * @retval None
  859. */
  860. void DSI_ExitULPM(DSI_TypeDef *DSIx)
  861. {
  862. /* Turn on the DSI PLL */
  863. DSIx->WRPCR |= DSI_WRPCR_PLLEN;
  864. /* Wait for the lock of the PLL */
  865. while(DSI_GetFlagStatus(DSIx, DSI_FLAG_PLLLS) == RESET)
  866. {}
  867. /* Exit ULPS on Clock and Data Lanes */
  868. DSIx->PUCR |= (DSI_PUCR_UECL | DSI_PUCR_UEDL);
  869. /* Wait until all active lanes exit ULPM */
  870. if((DSIx->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
  871. {
  872. while((DSIx->PSR & (DSI_PSR_UAN0 | DSI_PSR_UANC)) != (DSI_PSR_UAN0 | DSI_PSR_UANC))
  873. {}
  874. }
  875. else /* DSI_TWO_DATA_LANES */
  876. {
  877. while((DSIx->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1 | DSI_PSR_UANC)) != (DSI_PSR_UAN0 | DSI_PSR_UAN1 | DSI_PSR_UANC))
  878. {}
  879. }
  880. /* De-assert the ULPM requests and the ULPM exit bits */
  881. DSIx->PUCR = 0;
  882. /* Switch the lanbyteclock source in the RCC from system PLL to D-PHY */
  883. RCC_DSIClockSourceConfig(RCC_DSICLKSource_PHY);
  884. /* Restore clock lane configuration to HS */
  885. DSIx->CLCR |= DSI_CLCR_DPCC;
  886. }
  887. /**
  888. * @brief Start test pattern generation
  889. * @param DSIx: To select the DSIx peripheral, where x can be the different DSI instances
  890. * @param Mode: Pattern generator mode
  891. * This parameter can be one of the following values:
  892. * 0 : Color bars (horizontal or vertical)
  893. * 1 : BER pattern (vertical only)
  894. * @param Orientation: Pattern generator orientation
  895. * This parameter can be one of the following values:
  896. * 0 : Vertical color bars
  897. * 1 : Horizontal color bars
  898. * @retval None
  899. */
  900. void DSI_PatternGeneratorStart(DSI_TypeDef *DSIx, uint32_t Mode, uint32_t Orientation)
  901. {
  902. /* Configure pattern generator mode and orientation */
  903. DSIx->VMCR &= ~(DSI_VMCR_PGM | DSI_VMCR_PGO);
  904. DSIx->VMCR |= ((Mode<<20) | (Orientation<<24));
  905. /* Enable pattern generator by setting PGE bit */
  906. DSIx->VMCR |= DSI_VMCR_PGE;
  907. }
  908. /**
  909. * @brief Stop test pattern generation
  910. * @param DSIx: To select the DSIx peripheral, where x can be the different DSI instances
  911. * @retval None
  912. */
  913. void DSI_PatternGeneratorStop(DSI_TypeDef *DSIx)
  914. {
  915. /* Disable pattern generator by clearing PGE bit */
  916. DSIx->VMCR &= ~DSI_VMCR_PGE;
  917. }
  918. /**
  919. * @brief Set Slew-Rate And Delay Tuning
  920. * @param DSIx: Pointer to DSI register base
  921. * @param CommDelay: Communication delay to be adjusted.
  922. * This parameter can be any value of @ref DSI_Communication_Delay
  923. * @param Lane: select between clock or data lanes.
  924. * This parameter can be any value of @ref DSI_Lane_Group
  925. * @param Value: Custom value of the slew-rate or delay
  926. * @retval None
  927. */
  928. void DSI_SetSlewRateAndDelayTuning(DSI_TypeDef *DSIx, uint32_t CommDelay, uint32_t Lane, uint32_t Value)
  929. {
  930. /* Check function parameters */
  931. assert_param(IS_DSI_COMMUNICATION_DELAY(CommDelay));
  932. assert_param(IS_DSI_LANE_GROUP(Lane));
  933. switch(CommDelay)
  934. {
  935. case DSI_SLEW_RATE_HSTX:
  936. if(Lane == DSI_CLOCK_LANE)
  937. {
  938. /* High-Speed Transmission Slew Rate Control on Clock Lane */
  939. DSIx->WPCR[1] &= ~DSI_WPCR1_HSTXSRCCL;
  940. DSIx->WPCR[1] |= Value<<16;
  941. }
  942. else /* DSI_DATA_LANES */
  943. {
  944. /* High-Speed Transmission Slew Rate Control on Data Lanes */
  945. DSIx->WPCR[1] &= ~DSI_WPCR1_HSTXSRCDL;
  946. DSIx->WPCR[1] |= Value<<18;
  947. }
  948. break;
  949. case DSI_SLEW_RATE_LPTX:
  950. if(Lane == DSI_CLOCK_LANE)
  951. {
  952. /* Low-Power transmission Slew Rate Compensation on Clock Lane */
  953. DSIx->WPCR[1] &= ~DSI_WPCR1_LPSRCCL;
  954. DSIx->WPCR[1] |= Value<<6;
  955. }
  956. else /* DSI_DATA_LANES */
  957. {
  958. /* Low-Power transmission Slew Rate Compensation on Data Lanes */
  959. DSIx->WPCR[1] &= ~DSI_WPCR1_LPSRCDL;
  960. DSIx->WPCR[1] |= Value<<8;
  961. }
  962. break;
  963. case DSI_HS_DELAY:
  964. if(Lane == DSI_CLOCK_LANE)
  965. {
  966. /* High-Speed Transmission Delay on Clock Lane */
  967. DSIx->WPCR[1] &= ~DSI_WPCR1_HSTXDCL;
  968. DSIx->WPCR[1] |= Value;
  969. }
  970. else /* DSI_DATA_LANES */
  971. {
  972. /* High-Speed Transmission Delay on Data Lanes */
  973. DSIx->WPCR[1] &= ~DSI_WPCR1_HSTXDDL;
  974. DSIx->WPCR[1] |= Value<<2;
  975. }
  976. break;
  977. default:
  978. break;
  979. }
  980. }
  981. /**
  982. * @brief Low-Power Reception Filter Tuning
  983. * @param DSIx: Pointer to DSI register base
  984. * @param Frequency: cutoff frequency of low-pass filter at the input of LPRX
  985. * @retval None
  986. */
  987. void DSI_SetLowPowerRXFilter(DSI_TypeDef *DSIx, uint32_t Frequency)
  988. {
  989. /* Low-Power RX low-pass Filtering Tuning */
  990. DSIx->WPCR[1] &= ~DSI_WPCR1_LPRXFT;
  991. DSIx->WPCR[1] |= Frequency<<25;
  992. }
  993. /**
  994. * @brief Activate an additional current path on all lanes to meet the SDDTx parameter
  995. * defined in the MIPI D-PHY specification
  996. * @param hdsi: pointer to a DSI_HandleTypeDef structure that contains
  997. * the configuration information for the DSI.
  998. * @param State: ENABLE or DISABLE
  999. * @retval None
  1000. */
  1001. void DSI_SetSDD(DSI_TypeDef *DSIx, FunctionalState State)
  1002. {
  1003. /* Check function parameters */
  1004. assert_param(IS_FUNCTIONAL_STATE(State));
  1005. /* Activate/Disactivate additional current path on all lanes */
  1006. DSIx->WPCR[1] &= ~DSI_WPCR1_SDDC;
  1007. DSIx->WPCR[1] |= ((uint32_t)State<<12);
  1008. }
  1009. /**
  1010. * @brief Custom lane pins configuration
  1011. * @param DSIx: Pointer to DSI register base
  1012. * @param CustomLane: Function to be applyed on selected lane.
  1013. * This parameter can be any value of @ref DSI_CustomLane
  1014. * @param Lane: select between clock or data lane 0 or data lane 1.
  1015. * This parameter can be any value of @ref DSI_Lane_Select
  1016. * @param State: ENABLE or DISABLE
  1017. * @retval None
  1018. */
  1019. void DSI_SetLanePinsConfiguration(DSI_TypeDef *DSIx, uint32_t CustomLane, uint32_t Lane, FunctionalState State)
  1020. {
  1021. /* Check function parameters */
  1022. assert_param(IS_DSI_CUSTOM_LANE(CustomLane));
  1023. assert_param(IS_DSI_LANE(Lane));
  1024. assert_param(IS_FUNCTIONAL_STATE(State));
  1025. switch(CustomLane)
  1026. {
  1027. case DSI_SWAP_LANE_PINS:
  1028. if(Lane == DSI_CLOCK_LANE)
  1029. {
  1030. /* Swap pins on clock lane */
  1031. DSIx->WPCR[0] &= ~DSI_WPCR0_SWCL;
  1032. DSIx->WPCR[0] |= ((uint32_t)State<<6);
  1033. }
  1034. else if(Lane == DSI_DATA_LANE0)
  1035. {
  1036. /* Swap pins on data lane 0 */
  1037. DSIx->WPCR[0] &= ~DSI_WPCR0_SWDL0;
  1038. DSIx->WPCR[0] |= ((uint32_t)State<<7);
  1039. }
  1040. else /* DSI_DATA_LANE1 */
  1041. {
  1042. /* Swap pins on data lane 1 */
  1043. DSIx->WPCR[0] &= ~DSI_WPCR0_SWDL1;
  1044. DSIx->WPCR[0] |= ((uint32_t)State<<8);
  1045. }
  1046. break;
  1047. case DSI_INVERT_HS_SIGNAL:
  1048. if(Lane == DSI_CLOCK_LANE)
  1049. {
  1050. /* Invert HS signal on clock lane */
  1051. DSIx->WPCR[0] &= ~DSI_WPCR0_HSICL;
  1052. DSIx->WPCR[0] |= ((uint32_t)State<<9);
  1053. }
  1054. else if(Lane == DSI_DATA_LANE0)
  1055. {
  1056. /* Invert HS signal on data lane 0 */
  1057. DSIx->WPCR[0] &= ~DSI_WPCR0_HSIDL0;
  1058. DSIx->WPCR[0] |= ((uint32_t)State<<10);
  1059. }
  1060. else /* DSI_DATA_LANE1 */
  1061. {
  1062. /* Invert HS signal on data lane 1 */
  1063. DSIx->WPCR[0] &= ~DSI_WPCR0_HSIDL1;
  1064. DSIx->WPCR[0] |= ((uint32_t)State<<11);
  1065. }
  1066. break;
  1067. default:
  1068. break;
  1069. }
  1070. }
  1071. /**
  1072. * @brief Set custom timing for the PHY
  1073. * @param DSIx: Pointer to DSI register base
  1074. * @param Timing: PHY timing to be adjusted.
  1075. * This parameter can be any value of @ref DSI_PHY_Timing
  1076. * @param State: ENABLE or DISABLE
  1077. * @param Value: Custom value of the timing
  1078. * @retval None
  1079. */
  1080. void DSI_SetPHYTimings(DSI_TypeDef *DSIx, uint32_t Timing, FunctionalState State, uint32_t Value)
  1081. {
  1082. /* Check function parameters */
  1083. assert_param(IS_DSI_PHY_TIMING(Timing));
  1084. assert_param(IS_FUNCTIONAL_STATE(State));
  1085. switch(Timing)
  1086. {
  1087. case DSI_TCLK_POST:
  1088. /* Enable/Disable custom timing setting */
  1089. DSIx->WPCR[0] &= ~DSI_WPCR0_TCLKPOSTEN;
  1090. DSIx->WPCR[0] |= ((uint32_t)State<<27);
  1091. if(State)
  1092. {
  1093. /* Set custom value */
  1094. DSIx->WPCR[4] &= ~DSI_WPCR4_TCLKPOST;
  1095. DSIx->WPCR[4] |= Value;
  1096. }
  1097. break;
  1098. case DSI_TLPX_CLK:
  1099. /* Enable/Disable custom timing setting */
  1100. DSIx->WPCR[0] &= ~DSI_WPCR0_TLPXCEN;
  1101. DSIx->WPCR[0] |= ((uint32_t)State<<26);
  1102. if(State)
  1103. {
  1104. /* Set custom value */
  1105. DSIx->WPCR[3] &= ~DSI_WPCR3_TLPXC;
  1106. DSIx->WPCR[3] |= Value;
  1107. }
  1108. break;
  1109. case DSI_THS_EXIT:
  1110. /* Enable/Disable custom timing setting */
  1111. DSIx->WPCR[0] &= ~DSI_WPCR0_THSEXITEN;
  1112. DSIx->WPCR[0] |= ((uint32_t)State<<25);
  1113. if(State)
  1114. {
  1115. /* Set custom value */
  1116. DSIx->WPCR[3] &= ~DSI_WPCR3_THSEXIT;
  1117. DSIx->WPCR[3] |= Value;
  1118. }
  1119. break;
  1120. case DSI_TLPX_DATA:
  1121. /* Enable/Disable custom timing setting */
  1122. DSIx->WPCR[0] &= ~DSI_WPCR0_TLPXDEN;
  1123. DSIx->WPCR[0] |= ((uint32_t)State<<24);
  1124. if(State)
  1125. {
  1126. /* Set custom value */
  1127. DSIx->WPCR[3] &= ~DSI_WPCR3_TLPXD;
  1128. DSIx->WPCR[3] |= Value;
  1129. }
  1130. break;
  1131. case DSI_THS_ZERO:
  1132. /* Enable/Disable custom timing setting */
  1133. DSIx->WPCR[0] &= ~DSI_WPCR0_THSZEROEN;
  1134. DSIx->WPCR[0] |= ((uint32_t)State<<23);
  1135. if(State)
  1136. {
  1137. /* Set custom value */
  1138. DSIx->WPCR[3] &= ~DSI_WPCR3_THSZERO;
  1139. DSIx->WPCR[3] |= Value;
  1140. }
  1141. break;
  1142. case DSI_THS_TRAIL:
  1143. /* Enable/Disable custom timing setting */
  1144. DSIx->WPCR[0] &= ~DSI_WPCR0_THSTRAILEN;
  1145. DSIx->WPCR[0] |= ((uint32_t)State<<22);
  1146. if(State)
  1147. {
  1148. /* Set custom value */
  1149. DSIx->WPCR[2] &= ~DSI_WPCR2_THSTRAIL;
  1150. DSIx->WPCR[2] |= Value;
  1151. }
  1152. break;
  1153. case DSI_THS_PREPARE:
  1154. /* Enable/Disable custom timing setting */
  1155. DSIx->WPCR[0] &= ~DSI_WPCR0_THSPREPEN;
  1156. DSIx->WPCR[0] |= ((uint32_t)State<<21);
  1157. if(State)
  1158. {
  1159. /* Set custom value */
  1160. DSIx->WPCR[2] &= ~DSI_WPCR2_THSPREP;
  1161. DSIx->WPCR[2] |= Value;
  1162. }
  1163. break;
  1164. case DSI_TCLK_ZERO:
  1165. /* Enable/Disable custom timing setting */
  1166. DSIx->WPCR[0] &= ~DSI_WPCR0_TCLKZEROEN;
  1167. DSIx->WPCR[0] |= ((uint32_t)State<<20);
  1168. if(State)
  1169. {
  1170. /* Set custom value */
  1171. DSIx->WPCR[2] &= ~DSI_WPCR2_TCLKZERO;
  1172. DSIx->WPCR[2] |= Value;
  1173. }
  1174. break;
  1175. case DSI_TCLK_PREPARE:
  1176. /* Enable/Disable custom timing setting */
  1177. DSIx->WPCR[0] &= ~DSI_WPCR0_TCLKPREPEN;
  1178. DSIx->WPCR[0] |= ((uint32_t)State<<19);
  1179. if(State)
  1180. {
  1181. /* Set custom value */
  1182. DSIx->WPCR[2] &= ~DSI_WPCR2_TCLKPREP;
  1183. DSIx->WPCR[2] |= Value;
  1184. }
  1185. break;
  1186. default:
  1187. break;
  1188. }
  1189. }
  1190. /**
  1191. * @brief Force the Clock/Data Lane in TX Stop Mode
  1192. * @param DSIx: Pointer to DSI register base
  1193. * @param Lane: select between clock or data lanes.
  1194. * This parameter can be any value of @ref DSI_Lane_Group
  1195. * @param State: ENABLE or DISABLE
  1196. * @retval None
  1197. */
  1198. void DSI_ForceTXStopMode(DSI_TypeDef *DSIx, uint32_t Lane, FunctionalState State)
  1199. {
  1200. /* Check function parameters */
  1201. assert_param(IS_DSI_LANE_GROUP(Lane));
  1202. assert_param(IS_FUNCTIONAL_STATE(State));
  1203. if(Lane == DSI_CLOCK_LANE)
  1204. {
  1205. /* Force/Unforce the Clock Lane in TX Stop Mode */
  1206. DSIx->WPCR[0] &= ~DSI_WPCR0_FTXSMCL;
  1207. DSIx->WPCR[0] |= ((uint32_t)State<<12);
  1208. }
  1209. else /* DSI_DATA_LANES */
  1210. {
  1211. /* Force/Unforce the Data Lanes in TX Stop Mode */
  1212. DSIx->WPCR[0] &= ~DSI_WPCR0_FTXSMDL;
  1213. DSIx->WPCR[0] |= ((uint32_t)State<<13);
  1214. }
  1215. }
  1216. /**
  1217. * @brief Forces LP Receiver in Low-Power Mode
  1218. * @param hdsi: pointer to a DSI_HandleTypeDef structure that contains
  1219. * the configuration information for the DSI.
  1220. * @param State: ENABLE or DISABLE
  1221. * @retval None
  1222. */
  1223. void DSI_ForceRXLowPower(DSI_TypeDef *DSIx, FunctionalState State)
  1224. {
  1225. /* Check function parameters */
  1226. assert_param(IS_FUNCTIONAL_STATE(State));
  1227. /* Force/Unforce LP Receiver in Low-Power Mode */
  1228. DSIx->WPCR[1] &= ~DSI_WPCR1_FLPRXLPM;
  1229. DSIx->WPCR[1] |= ((uint32_t)State<<22);
  1230. }
  1231. /**
  1232. * @brief Force Data Lanes in RX Mode after a BTA
  1233. * @param hdsi: pointer to a DSI_HandleTypeDef structure that contains
  1234. * the configuration information for the DSI.
  1235. * @param State: ENABLE or DISABLE
  1236. * @retval None
  1237. */
  1238. void DSI_ForceDataLanesInRX(DSI_TypeDef *DSIx, FunctionalState State)
  1239. {
  1240. /* Check function parameters */
  1241. assert_param(IS_FUNCTIONAL_STATE(State));
  1242. /* Force Data Lanes in RX Mode */
  1243. DSIx->WPCR[0] &= ~DSI_WPCR0_TDDL;
  1244. DSIx->WPCR[0] |= ((uint32_t)State<<16);
  1245. }
  1246. /**
  1247. * @brief Enable a pull-down on the lanes to prevent from floating states when unused
  1248. * @param hdsi: pointer to a DSI_HandleTypeDef structure that contains
  1249. * the configuration information for the DSI.
  1250. * @param State: ENABLE or DISABLE
  1251. * @retval None
  1252. */
  1253. void DSI_SetPullDown(DSI_TypeDef *DSIx, FunctionalState State)
  1254. {
  1255. /* Check function parameters */
  1256. assert_param(IS_FUNCTIONAL_STATE(State));
  1257. /* Enable/Disable pull-down on lanes */
  1258. DSIx->WPCR[0] &= ~DSI_WPCR0_PDEN;
  1259. DSIx->WPCR[0] |= ((uint32_t)State<<18);
  1260. }
  1261. /**
  1262. * @brief Switch off the contention detection on data lanes
  1263. * @param hdsi: pointer to a DSI_HandleTypeDef structure that contains
  1264. * the configuration information for the DSI.
  1265. * @param State: ENABLE or DISABLE
  1266. * @retval None
  1267. */
  1268. void DSI_SetContentionDetectionOff(DSI_TypeDef *DSIx, FunctionalState State)
  1269. {
  1270. /* Check function parameters */
  1271. assert_param(IS_FUNCTIONAL_STATE(State));
  1272. /* Contention Detection on Data Lanes OFF */
  1273. DSIx->WPCR[0] &= ~DSI_WPCR0_CDOFFDL;
  1274. DSIx->WPCR[0] |= ((uint32_t)State<<14);
  1275. }
  1276. /**
  1277. * @}
  1278. */
  1279. /** @defgroup DSI_Group4 Interrupts and flags management functions
  1280. * @brief Interrupts and flags management functions
  1281. *
  1282. @verbatim
  1283. ===============================================================================
  1284. ##### Interrupts and flags management functions #####
  1285. ===============================================================================
  1286. [..] This section provides a set of functions allowing to configure the DSI Interrupts
  1287. sources and check or clear the flags or pending bits status.
  1288. The user should identify which mode will be used in his application to manage
  1289. the communication: Polling mode or Interrupt mode.
  1290. *** Polling Mode ***
  1291. ====================
  1292. [..] In Polling Mode, the DSI communication can be managed by 8 flags:
  1293. (#) DSI_FLAG_TE : Tearing Effect Interrupt Flag
  1294. (#) DSI_FLAG_ER : End of Refresh Interrupt Flag
  1295. (#) DSI_FLAG_BUSY : Busy Flag
  1296. (#) DSI_FLAG_PLLLS : PLL Lock Status
  1297. (#) DSI_FLAG_PLLL : PLL Lock Interrupt Flag
  1298. (#) DSI_FLAG_PLLU : PLL Unlock Interrupt Flag
  1299. (#) DSI_FLAG_RRS: Regulator Ready Status.
  1300. (#) DSI_FLAG_RR: Regulator Ready Interrupt Flag.
  1301. [..] In this Mode it is advised to use the following functions:
  1302. (+) FlagStatus DSI_GetFlagStatus(DSI_TypeDef* DSIx, uint32_t DSI_FLAG);
  1303. (+) void DSI_ClearFlag(DSI_TypeDef* DSIx, uint32_t DSI_FLAG);
  1304. *** Interrupt Mode ***
  1305. ======================
  1306. [..] In Interrupt Mode, the SPI communication can be managed by 3 interrupt sources
  1307. and 7 pending bits:
  1308. (+) Pending Bits:
  1309. (##) DSI_IT_TE : Tearing Effect Interrupt Flag
  1310. (##) DSI_IT_ER : End of Refresh Interrupt Flag
  1311. (##) DSI_IT_PLLL : PLL Lock Interrupt Flag
  1312. (##) DSI_IT_PLLU : PLL Unlock Interrupt Flag
  1313. (##) DSI_IT_RR: Regulator Ready Interrupt Flag.
  1314. (+) Interrupt Source:
  1315. (##) DSI_IT_TE : Tearing Effect Interrupt Enable
  1316. (##) DSI_IT_ER : End of Refresh Interrupt Enable
  1317. (##) DSI_IT_PLLL : PLL Lock Interrupt Enable
  1318. (##) DSI_IT_PLLU : PLL Unlock Interrupt Enable
  1319. (##) DSI_IT_RR: Regulator Ready Interrupt Enable
  1320. [..] In this Mode it is advised to use the following functions:
  1321. (+) void DSI_ITConfig(DSI_TypeDef* DSIx, uint32_t DSI_IT, FunctionalState NewState);
  1322. (+) ITStatus DSI_GetITStatus(DSI_TypeDef* DSIx, uint32_t DSI_IT);
  1323. (+) void DSI_ClearITPendingBit(DSI_TypeDef* DSIx, uint32_t DSI_IT);
  1324. @endverbatim
  1325. * @{
  1326. */
  1327. /**
  1328. * @brief Enables or disables the specified DSI interrupts.
  1329. * @param DSIx: To select the DSIx peripheral, where x can be the different DSI instances
  1330. * @param DSI_IT: specifies the DSI interrupt sources to be enabled or disabled.
  1331. * This parameter can be any combination of the following values:
  1332. * @arg DSI_IT_TE : Tearing Effect Interrupt
  1333. * @arg DSI_IT_ER : End of Refresh Interrupt
  1334. * @arg DSI_IT_PLLL: PLL Lock Interrupt
  1335. * @arg DSI_IT_PLLU: PLL Unlock Interrupt
  1336. * @arg DSI_IT_RR : Regulator Ready Interrupt
  1337. * @param NewState: new state of the specified DSI interrupt.
  1338. * This parameter can be: ENABLE or DISABLE.
  1339. * @retval None
  1340. */
  1341. void DSI_ITConfig(DSI_TypeDef* DSIx, uint32_t DSI_IT, FunctionalState NewState)
  1342. {
  1343. /* Check the parameters */
  1344. assert_param(IS_DSI_ALL_PERIPH(DSIx));
  1345. assert_param(IS_FUNCTIONAL_STATE(NewState));
  1346. assert_param(IS_DSI_IT(DSI_IT));
  1347. if(NewState != DISABLE)
  1348. {
  1349. /* Enable the selected DSI interrupt */
  1350. DSIx->WIER |= DSI_IT;
  1351. }
  1352. else
  1353. {
  1354. /* Disable the selected DSI interrupt */
  1355. DSIx->WIER &= ~DSI_IT;
  1356. }
  1357. }
  1358. /**
  1359. * @brief Checks whether the specified DSI flag is set or not.
  1360. * @param DSIx: To select the DSIx peripheral, where x can be the different DSI instances
  1361. * @param DSI_FLAG: specifies the SPI flag to be checked.
  1362. * This parameter can be one of the following values:
  1363. * @arg DSI_FLAG_TE : Tearing Effect Interrupt Flag
  1364. * @arg DSI_FLAG_ER : End of Refresh Interrupt Flag
  1365. * @arg DSI_FLAG_BUSY : Busy Flag
  1366. * @arg DSI_FLAG_PLLLS: PLL Lock Status
  1367. * @arg DSI_FLAG_PLLL : PLL Lock Interrupt Flag
  1368. * @arg DSI_FLAG_PLLU : PLL Unlock Interrupt Flag
  1369. * @arg DSI_FLAG_RRS : Regulator Ready Flag
  1370. * @arg DSI_FLAG_RR : Regulator Ready Interrupt Flag
  1371. * @retval The new state of DSI_FLAG (SET or RESET).
  1372. */
  1373. FlagStatus DSI_GetFlagStatus(DSI_TypeDef* DSIx, uint16_t DSI_FLAG)
  1374. {
  1375. FlagStatus bitstatus = RESET;
  1376. /* Check the parameters */
  1377. assert_param(IS_DSI_ALL_PERIPH(DSIx));
  1378. assert_param(IS_DSI_GET_FLAG(DSI_FLAG));
  1379. /* Check the status of the specified DSI flag */
  1380. if((DSIx->WISR & DSI_FLAG) != (uint32_t)RESET)
  1381. {
  1382. /* DSI_FLAG is set */
  1383. bitstatus = SET;
  1384. }
  1385. else
  1386. {
  1387. /* DSI_FLAG is reset */
  1388. bitstatus = RESET;
  1389. }
  1390. /* Return the DSI_FLAG status */
  1391. return bitstatus;
  1392. }
  1393. /**
  1394. * @brief Clears the specified DSI flag.
  1395. * @param DSIx: To select the DSIx peripheral, where x can be the different DSI instances
  1396. * @param DSI_FLAG: specifies the SPI flag to be cleared.
  1397. * This parameter can be one of the following values:
  1398. * @arg DSI_FLAG_TE : Tearing Effect Interrupt Flag
  1399. * @arg DSI_FLAG_ER : End of Refresh Interrupt Flag
  1400. * @arg DSI_FLAG_PLLL : PLL Lock Interrupt Flag
  1401. * @arg DSI_FLAG_PLLU : PLL Unlock Interrupt Flag
  1402. * @arg DSI_FLAG_RR : Regulator Ready Interrupt Flag
  1403. * @retval None
  1404. */
  1405. void DSI_ClearFlag(DSI_TypeDef* DSIx, uint16_t DSI_FLAG)
  1406. {
  1407. /* Check the parameters */
  1408. assert_param(IS_DSI_ALL_PERIPH(DSIx));
  1409. assert_param(IS_DSI_CLEAR_FLAG(DSI_FLAG));
  1410. /* Clear the selected DSI flag */
  1411. DSIx->WIFCR = (uint32_t)DSI_FLAG;
  1412. }
  1413. /**
  1414. * @brief Checks whether the specified DSIx interrupt has occurred or not.
  1415. * @param DSIx: To select the DSIx peripheral, where x can be the different DSI instances
  1416. * @param DSI_IT: specifies the DSI interrupt sources to be checked.
  1417. * This parameter can be one of the following values:
  1418. * @arg DSI_IT_TE : Tearing Effect Interrupt
  1419. * @arg DSI_IT_ER : End of Refresh Interrupt
  1420. * @arg DSI_IT_PLLL: PLL Lock Interrupt
  1421. * @arg DSI_IT_PLLU: PLL Unlock Interrupt
  1422. * @arg DSI_IT_RR : Regulator Ready Interrupt
  1423. * @retval The new state of SPI_I2S_IT (SET or RESET).
  1424. */
  1425. ITStatus DSI_GetITStatus(DSI_TypeDef* DSIx, uint32_t DSI_IT)
  1426. {
  1427. ITStatus bitstatus = RESET;
  1428. uint32_t enablestatus = 0;
  1429. /* Check the parameters */
  1430. assert_param(IS_DSI_ALL_PERIPH(DSIx));
  1431. assert_param(IS_DSI_IT(DSI_IT));
  1432. /* Get the DSI_IT enable bit status */
  1433. enablestatus = (DSIx->WIER & DSI_IT);
  1434. /* Check the status of the specified SPI interrupt */
  1435. if (((DSIx->WISR & DSI_IT) != (uint32_t)RESET) && enablestatus)
  1436. {
  1437. /* DSI_IT is set */
  1438. bitstatus = SET;
  1439. }
  1440. else
  1441. {
  1442. /* DSI_IT is reset */
  1443. bitstatus = RESET;
  1444. }
  1445. /* Return the DSI_IT status */
  1446. return bitstatus;
  1447. }
  1448. /**
  1449. * @brief Clears the DSIx interrupt pending bit.
  1450. * @param DSIx: To select the DSIx peripheral, where x can be the different DSI instances
  1451. * @param DSI_IT: specifies the DSI interrupt sources to be cleared.
  1452. * This parameter can be one of the following values:
  1453. * @arg DSI_IT_TE : Tearing Effect Interrupt
  1454. * @arg DSI_IT_ER : End of Refresh Interrupt
  1455. * @arg DSI_IT_PLLL: PLL Lock Interrupt
  1456. * @arg DSI_IT_PLLU: PLL Unlock Interrupt
  1457. * @arg DSI_IT_RR : Regulator Ready Interrupt
  1458. * @retval None
  1459. */
  1460. void DSI_ClearITPendingBit(DSI_TypeDef* DSIx, uint32_t DSI_IT)
  1461. {
  1462. /* Check the parameters */
  1463. assert_param(IS_DSI_ALL_PERIPH(DSIx));
  1464. assert_param(IS_DSI_IT(DSI_IT));
  1465. /* Clear the selected DSI interrupt pending bit */
  1466. DSIx->WIFCR = (uint32_t)DSI_IT;
  1467. }
  1468. /**
  1469. * @brief Enable the error monitor flags
  1470. * @param DSIx: To select the DSIx peripheral, where x can be the different DSI instances
  1471. * @param ActiveErrors: indicates which error interrupts will be enabled.
  1472. * This parameter can be any combination of @ref DSI_Error_Data_Type.
  1473. * @retval None
  1474. */
  1475. void DSI_ConfigErrorMonitor(DSI_TypeDef *DSIx, uint32_t ActiveErrors)
  1476. {
  1477. DSIx->IER[0] = 0;
  1478. DSIx->IER[1] = 0;
  1479. if((ActiveErrors & DSI_ERROR_ACK) != RESET)
  1480. {
  1481. /* Enable the interrupt generation on selected errors */
  1482. DSIx->IER[0] |= DSI_ERROR_ACK_MASK;
  1483. }
  1484. if((ActiveErrors & DSI_ERROR_PHY) != RESET)
  1485. {
  1486. /* Enable the interrupt generation on selected errors */
  1487. DSIx->IER[0] |= DSI_ERROR_PHY_MASK;
  1488. }
  1489. if((ActiveErrors & DSI_ERROR_TX) != RESET)
  1490. {
  1491. /* Enable the interrupt generation on selected errors */
  1492. DSIx->IER[1] |= DSI_ERROR_TX_MASK;
  1493. }
  1494. if((ActiveErrors & DSI_ERROR_RX) != RESET)
  1495. {
  1496. /* Enable the interrupt generation on selected errors */
  1497. DSIx->IER[1] |= DSI_ERROR_RX_MASK;
  1498. }
  1499. if((ActiveErrors & DSI_ERROR_ECC) != RESET)
  1500. {
  1501. /* Enable the interrupt generation on selected errors */
  1502. DSIx->IER[1] |= DSI_ERROR_ECC_MASK;
  1503. }
  1504. if((ActiveErrors & DSI_ERROR_CRC) != RESET)
  1505. {
  1506. /* Enable the interrupt generation on selected errors */
  1507. DSIx->IER[1] |= DSI_ERROR_CRC_MASK;
  1508. }
  1509. if((ActiveErrors & DSI_ERROR_PSE) != RESET)
  1510. {
  1511. /* Enable the interrupt generation on selected errors */
  1512. DSIx->IER[1] |= DSI_ERROR_PSE_MASK;
  1513. }
  1514. if((ActiveErrors & DSI_ERROR_EOT) != RESET)
  1515. {
  1516. /* Enable the interrupt generation on selected errors */
  1517. DSIx->IER[1] |= DSI_ERROR_EOT_MASK;
  1518. }
  1519. if((ActiveErrors & DSI_ERROR_OVF) != RESET)
  1520. {
  1521. /* Enable the interrupt generation on selected errors */
  1522. DSIx->IER[1] |= DSI_ERROR_OVF_MASK;
  1523. }
  1524. if((ActiveErrors & DSI_ERROR_GEN) != RESET)
  1525. {
  1526. /* Enable the interrupt generation on selected errors */
  1527. DSIx->IER[1] |= DSI_ERROR_GEN_MASK;
  1528. }
  1529. }
  1530. /**
  1531. * @}
  1532. */
  1533. /**
  1534. * @}
  1535. */
  1536. #endif /* STM32F469_479xx */
  1537. /**
  1538. * @}
  1539. */
  1540. /**
  1541. * @}
  1542. */