Mercurial > public > ostc4
view Common/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dsi.c @ 850:bc2fcd002fc4 Evo_2_23
Check line enable/disable state when a new page is selected:
Some lines may change the enable/disable state based on events which are triggered from outside the page scope (for example sensor setup). Updating the line states while another page is active caused problems in the framebuffer handling. To solve this usecase the conditions for the line dis/enabling is checked when a "nextPage" is selected. If condition changed then the page will be refreshed.
author | Ideenmodellierer |
---|---|
date | Fri, 01 Mar 2024 19:30:29 +0100 |
parents | c78bcbd5deda |
children |
line wrap: on
line source
/** ****************************************************************************** * @file stm32f4xx_hal_dsi.c * @author MCD Application Team * @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>© COPYRIGHT(c) 2017 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 * @{ */ #ifdef HAL_DSI_MODULE_ENABLED #if defined(DSI) /** @addtogroup DSI * @{ */ /* Private types -------------------------------------------------------------*/ /* Private defines -----------------------------------------------------------*/ /** @addtogroup DSI_Private_Constants * @{ */ #define DSI_TIMEOUT_VALUE ((uint32_t)1000U) /* 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<<6U) | (Data0<<8U) | (Data1<<16U)); } /* 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; uint32_t unitIntervalx4; uint32_t tempIDF; /* 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)<<2U) | ((PLLInit->PLLIDF)<<11U) | ((PLLInit->PLLODF)<<16U)); /* 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 > 0U) ? PLLInit->PLLIDF : 1U; unitIntervalx4 = (4000000U * tempIDF * (1U << PLLInit->PLLODF)) / ((HSE_VALUE/1000U) * PLLInit->PLLNDIV); /* Set the bit period in high-speed mode */ hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_UIX4; hdsi->Instance->WPCR[0U] |= unitIntervalx4; /****************************** Error management *****************************/ /* Disable all error interrupts and reset the Error Mask */ hdsi->Instance->IER[0U] = 0U; hdsi->Instance->IER[1U] = 0U; hdsi->ErrorMsk = 0U; /* 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 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[0U] = 0U; hdsi->Instance->IER[1U] = 0U; /* Store active errors to the handle */ hdsi->ErrorMsk = ActiveErrors; if((ActiveErrors & HAL_DSI_ERROR_ACK) != RESET) { /* Enable the interrupt generation on selected errors */ hdsi->Instance->IER[0U] |= DSI_ERROR_ACK_MASK; } if((ActiveErrors & HAL_DSI_ERROR_PHY) != RESET) { /* Enable the interrupt generation on selected errors */ hdsi->Instance->IER[0U] |= DSI_ERROR_PHY_MASK; } if((ActiveErrors & HAL_DSI_ERROR_TX) != RESET) { /* Enable the interrupt generation on selected errors */ hdsi->Instance->IER[1U] |= DSI_ERROR_TX_MASK; } if((ActiveErrors & HAL_DSI_ERROR_RX) != RESET) { /* Enable the interrupt generation on selected errors */ hdsi->Instance->IER[1U] |= DSI_ERROR_RX_MASK; } if((ActiveErrors & HAL_DSI_ERROR_ECC) != RESET) { /* Enable the interrupt generation on selected errors */ hdsi->Instance->IER[1U] |= DSI_ERROR_ECC_MASK; } if((ActiveErrors & HAL_DSI_ERROR_CRC) != RESET) { /* Enable the interrupt generation on selected errors */ hdsi->Instance->IER[1U] |= DSI_ERROR_CRC_MASK; } if((ActiveErrors & HAL_DSI_ERROR_PSE) != RESET) { /* Enable the interrupt generation on selected errors */ hdsi->Instance->IER[1U] |= DSI_ERROR_PSE_MASK; } if((ActiveErrors & HAL_DSI_ERROR_EOT) != RESET) { /* Enable the interrupt generation on selected errors */ hdsi->Instance->IER[1U] |= DSI_ERROR_EOT_MASK; } if((ActiveErrors & HAL_DSI_ERROR_OVF) != RESET) { /* Enable the interrupt generation on selected errors */ hdsi->Instance->IER[1U] |= DSI_ERROR_OVF_MASK; } if((ActiveErrors & HAL_DSI_ERROR_GEN) != RESET) { /* Enable the interrupt generation on selected errors */ hdsi->Instance->IER[1U] |= 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) { /* Prevent unused argument(s) compilation warning */ UNUSED(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) { /* Prevent unused argument(s) compilation warning */ UNUSED(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 != 0U) { ErrorStatus0 = hdsi->Instance->ISR[0U]; ErrorStatus0 &= hdsi->Instance->IER[0U]; ErrorStatus1 = hdsi->Instance->ISR[1U]; ErrorStatus1 &= hdsi->Instance->IER[1U]; if((ErrorStatus0 & DSI_ERROR_ACK_MASK) != RESET) { hdsi->ErrorCode |= HAL_DSI_ERROR_ACK; } if((ErrorStatus0 & DSI_ERROR_PHY_MASK) != RESET) { hdsi->ErrorCode |= HAL_DSI_ERROR_PHY; } if((ErrorStatus1 & DSI_ERROR_TX_MASK) != RESET) { hdsi->ErrorCode |= HAL_DSI_ERROR_TX; } if((ErrorStatus1 & DSI_ERROR_RX_MASK) != RESET) { hdsi->ErrorCode |= HAL_DSI_ERROR_RX; } if((ErrorStatus1 & DSI_ERROR_ECC_MASK) != RESET) { hdsi->ErrorCode |= HAL_DSI_ERROR_ECC; } if((ErrorStatus1 & DSI_ERROR_CRC_MASK) != RESET) { hdsi->ErrorCode |= HAL_DSI_ERROR_CRC; } if((ErrorStatus1 & DSI_ERROR_PSE_MASK) != RESET) { hdsi->ErrorCode |= HAL_DSI_ERROR_PSE; } if((ErrorStatus1 & DSI_ERROR_EOT_MASK) != RESET) { hdsi->ErrorCode |= HAL_DSI_ERROR_EOT; } if((ErrorStatus1 & DSI_ERROR_OVF_MASK) != RESET) { hdsi->ErrorCode |= HAL_DSI_ERROR_OVF; } if((ErrorStatus1 & DSI_ERROR_GEN_MASK) != RESET) { 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) { /* Prevent unused argument(s) compilation warning */ UNUSED(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) { /* Prevent unused argument(s) compilation warning */ UNUSED(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) { /* Prevent unused argument(s) compilation warning */ UNUSED(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: (+) Configure the Generic interface read-back Virtual Channel ID (+) Select video mode and configure the corresponding parameters (+) Configure command transmission mode: High-speed or Low-power (+) Configure the flow control (+) Configure the DSI PHY timer (+) Configure the DSI HOST timeout (+) Configure the DSI HOST timeout (+) Start/Stop the DSI module (+) Refresh the display in command mode (+) Controls the display color mode in Video mode (+) Control the display shutdown in Video mode (+) write short DCS or short Generic command (+) write long DCS or long Generic command (+) Read command (DCS or generic) (+) Enter/Exit the Ultra Low Power Mode on data only (D-PHY PLL running) (+) Enter/Exit the Ultra Low Power Mode on data only and clock (D-PHY PLL turned off) (+) Start/Stop test pattern generation (+) Slew-Rate And Delay Tuning (+) Low-Power Reception Filter Tuning (+) Activate an additional current path on all lanes to meet the SDDTx parameter (+) Custom lane pins configuration (+) Set custom timing for the PHY (+) Force the Clock/Data Lane in TX Stop Mode (+) Force LP Receiver in Low-Power Mode (+) Force Data Lanes in RX Mode after a BTA (+) Enable a pull-down on the lanes to prevent from floating states when unused (+) Switch off the contention detection on data lanes @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)<<1U); /* 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)<<16U); /* 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)<<1U); /* 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)<<16U)); /* 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)<<16U) | ((PhyTimers->DataLaneHS2LPTime)<<24U)); /* Configure the wait period to request HS transmission after a stop state */ hdsi->Instance->PCONFR &= ~DSI_PCONFR_SW_TIME; hdsi->Instance->PCONFR |= ((PhyTimers->StopWaitTime)<<8U); /* 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)<<8U); /* High-speed transmission timeout */ hdsi->Instance->TCCR[0U] &= ~DSI_TCCR0_HSTX_TOCNT; hdsi->Instance->TCCR[0U] |= ((HostTimeouts->HighSpeedTransmissionTimeout)<<16U); /* Low-power reception timeout */ hdsi->Instance->TCCR[0U] &= ~DSI_TCCR0_LPRX_TOCNT; hdsi->Instance->TCCR[0U] |= HostTimeouts->LowPowerReceptionTimeout; /* High-speed read timeout */ hdsi->Instance->TCCR[1U] &= ~DSI_TCCR1_HSRD_TOCNT; hdsi->Instance->TCCR[1U] |= HostTimeouts->HighSpeedReadTimeout; /* Low-power read timeout */ hdsi->Instance->TCCR[2U] &= ~DSI_TCCR2_LPRD_TOCNT; hdsi->Instance->TCCR[2U] |= HostTimeouts->LowPowerReadTimeout; /* High-speed write timeout */ hdsi->Instance->TCCR[3U] &= ~DSI_TCCR3_HSWR_TOCNT; hdsi->Instance->TCCR[3U] |= HostTimeouts->HighSpeedWriteTimeout; /* High-speed write presp mode */ hdsi->Instance->TCCR[3U] &= ~DSI_TCCR3_PM; hdsi->Instance->TCCR[3U] |= HostTimeouts->HighSpeedWritePrespMode; /* Low-speed write timeout */ hdsi->Instance->TCCR[4U] &= ~DSI_TCCR4_LPWR_TOCNT; hdsi->Instance->TCCR[4U] |= HostTimeouts->LowPowerWriteTimeout; /* BTA timeout */ hdsi->Instance->TCCR[5U] &= ~DSI_TCCR5_BTA_TOCNT; hdsi->Instance->TCCR[5U] |= 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 write short DCS or short Generic 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; /* 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) == 0U) { /* 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 write long DCS or long Generic 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, nbBytes, count; uint32_t tickstart; uint32_t fifoword; uint8_t* pparams = ParametersTable; /* 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 on payload byte 1, and the other parameters on the write FIFO command*/ fifoword = Param1; nbBytes = (NbParams < 3U) ? NbParams : 3U; for(count = 0U; count < nbBytes; count++) { fifoword |= (((uint32_t)(*(pparams + count))) << (8U + (8U*count))); } hdsi->Instance->GPDR = fifoword; uicounter = NbParams - nbBytes; pparams += nbBytes; /* Set the Next parameters on the write FIFO command*/ while(uicounter != 0U) { nbBytes = (uicounter < 4U) ? uicounter : 4U; fifoword = 0U; for(count = 0U; count < nbBytes; count++) { fifoword |= (((uint32_t)(*(pparams + count))) << (8U*count)); } hdsi->Instance->GPDR = fifoword; uicounter -= nbBytes; pparams += nbBytes; } /* Configure the packet to send a long DCS command */ DSI_ConfigPacketHeader(hdsi->Instance, ChannelID, Mode, ((NbParams+1U)&0x00FFU), (((NbParams+1U)&0xFF00U)>>8U)); /* 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; uint8_t* pdata = Array; uint32_t datasize = Size; /* Process locked */ __HAL_LOCK(hdsi); /* Check the parameters */ assert_param(IS_DSI_READ_PACKET_TYPE(Mode)); if(datasize > 2U) { /* set max return packet size */ if (HAL_DSI_ShortWrite(hdsi, ChannelNbr, DSI_MAX_RETURN_PKT_SIZE, ((datasize)&0xFFU), (((datasize)>>8U)&0xFFU)) != HAL_OK) { /* Process Unlocked */ __HAL_UNLOCK(hdsi); return HAL_ERROR; } } /* Configure the packet to read command */ if (Mode == DSI_DCS_SHORT_PKT_READ) { DSI_ConfigPacketHeader(hdsi->Instance, ChannelNbr, Mode, DCSCmd, 0U); } else if (Mode == DSI_GEN_SHORT_PKT_READ_P0) { DSI_ConfigPacketHeader(hdsi->Instance, ChannelNbr, Mode, 0U, 0U); } else if (Mode == DSI_GEN_SHORT_PKT_READ_P1) { DSI_ConfigPacketHeader(hdsi->Instance, ChannelNbr, Mode, ParametersTable[0U], 0U); } else if (Mode == DSI_GEN_SHORT_PKT_READ_P2) { DSI_ConfigPacketHeader(hdsi->Instance, ChannelNbr, Mode, ParametersTable[0U], ParametersTable[1U]); } else { /* Process Unlocked */ __HAL_UNLOCK(hdsi); return HAL_ERROR; } /* 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 *)pdata) = (hdsi->Instance->GPDR); if (datasize > 4U) { datasize -= 4U; pdata += 4U; } else { /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_OK; } /* Get tick */ tickstart = HAL_GetTick(); /* Get the remaining bytes if any */ while(((int)(datasize)) > 0) { if((hdsi->Instance->GPSR & DSI_GPSR_PRDFE) == 0U) { *((uint32_t *)pdata) = (hdsi->Instance->GPDR); datasize -= 4U; pdata += 4U; } /* 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; /* 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; } } } else { /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_ERROR; } /* 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; /* 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; } } } else { /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_ERROR; } /* wait for 1 ms*/ HAL_Delay(1U); /* De-assert the ULPM requests and the ULPM exit bits */ hdsi->Instance->PUCR = 0U; /* 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; /* 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; } } } else { /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_ERROR; } /* 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; /* 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; } } } else { /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_ERROR; } /* wait for 1 ms */ HAL_Delay(1U); /* De-assert the ULPM requests and the ULPM exit bits */ hdsi->Instance->PUCR = 0U; /* 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<<20U) | (Orientation<<24U)); /* 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[1U] &= ~DSI_WPCR1_HSTXSRCCL; hdsi->Instance->WPCR[1U] |= Value<<16U; } else if(Lane == DSI_DATA_LANES) { /* High-Speed Transmission Slew Rate Control on Data Lanes */ hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_HSTXSRCDL; hdsi->Instance->WPCR[1U] |= Value<<18U; } else { /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_ERROR; } break; case DSI_SLEW_RATE_LPTX: if(Lane == DSI_CLOCK_LANE) { /* Low-Power transmission Slew Rate Compensation on Clock Lane */ hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_LPSRCCL; hdsi->Instance->WPCR[1U] |= Value<<6U; } else if(Lane == DSI_DATA_LANES) { /* Low-Power transmission Slew Rate Compensation on Data Lanes */ hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_LPSRCDL; hdsi->Instance->WPCR[1U] |= Value<<8U; } else { /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_ERROR; } break; case DSI_HS_DELAY: if(Lane == DSI_CLOCK_LANE) { /* High-Speed Transmission Delay on Clock Lane */ hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_HSTXDCL; hdsi->Instance->WPCR[1U] |= Value; } else if(Lane == DSI_DATA_LANES) { /* High-Speed Transmission Delay on Data Lanes */ hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_HSTXDDL; hdsi->Instance->WPCR[1U] |= Value<<2U; } else { /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_ERROR; } 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[1U] &= ~DSI_WPCR1_LPRXFT; hdsi->Instance->WPCR[1U] |= Frequency<<25U; /* 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[1U] &= ~DSI_WPCR1_SDDC; hdsi->Instance->WPCR[1U] |= ((uint32_t)State << 12U); /* 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_CLK_LANE) { /* Swap pins on clock lane */ hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_SWCL; hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 6U); } else if(Lane == DSI_DATA_LANE0) { /* Swap pins on data lane 0 */ hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_SWDL0; hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 7U); } else if(Lane == DSI_DATA_LANE1) { /* Swap pins on data lane 1 */ hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_SWDL1; hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 8U); } else { /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_ERROR; } break; case DSI_INVERT_HS_SIGNAL: if(Lane == DSI_CLK_LANE) { /* Invert HS signal on clock lane */ hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_HSICL; hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 9U); } else if(Lane == DSI_DATA_LANE0) { /* Invert HS signal on data lane 0 */ hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_HSIDL0; hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 10U); } else if(Lane == DSI_DATA_LANE1) { /* Invert HS signal on data lane 1 */ hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_HSIDL1; hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 11U); } else { /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_ERROR; } 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[0U] &= ~DSI_WPCR0_TCLKPOSTEN; hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 27U); if(State != DISABLE) { /* Set custom value */ hdsi->Instance->WPCR[4U] &= ~DSI_WPCR4_TCLKPOST; hdsi->Instance->WPCR[4U] |= Value & DSI_WPCR4_TCLKPOST; } break; case DSI_TLPX_CLK: /* Enable/Disable custom timing setting */ hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_TLPXCEN; hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 26U); if(State != DISABLE) { /* Set custom value */ hdsi->Instance->WPCR[3U] &= ~DSI_WPCR3_TLPXC; hdsi->Instance->WPCR[3U] |= (Value << 24U) & DSI_WPCR3_TLPXC; } break; case DSI_THS_EXIT: /* Enable/Disable custom timing setting */ hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_THSEXITEN; hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 25U); if(State != DISABLE) { /* Set custom value */ hdsi->Instance->WPCR[3U] &= ~DSI_WPCR3_THSEXIT; hdsi->Instance->WPCR[3U] |= (Value << 16U) & DSI_WPCR3_THSEXIT; } break; case DSI_TLPX_DATA: /* Enable/Disable custom timing setting */ hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_TLPXDEN; hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 24U); if(State != DISABLE) { /* Set custom value */ hdsi->Instance->WPCR[3U] &= ~DSI_WPCR3_TLPXD; hdsi->Instance->WPCR[3U] |= (Value << 8U) & DSI_WPCR3_TLPXD; } break; case DSI_THS_ZERO: /* Enable/Disable custom timing setting */ hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_THSZEROEN; hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 23U); if(State != DISABLE) { /* Set custom value */ hdsi->Instance->WPCR[3U] &= ~DSI_WPCR3_THSZERO; hdsi->Instance->WPCR[3U] |= Value & DSI_WPCR3_THSZERO; } break; case DSI_THS_TRAIL: /* Enable/Disable custom timing setting */ hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_THSTRAILEN; hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 22U); if(State != DISABLE) { /* Set custom value */ hdsi->Instance->WPCR[2U] &= ~DSI_WPCR2_THSTRAIL; hdsi->Instance->WPCR[2U] |= (Value << 24U) & DSI_WPCR2_THSTRAIL; } break; case DSI_THS_PREPARE: /* Enable/Disable custom timing setting */ hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_THSPREPEN; hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 21U); if(State != DISABLE) { /* Set custom value */ hdsi->Instance->WPCR[2U] &= ~DSI_WPCR2_THSPREP; hdsi->Instance->WPCR[2U] |= (Value << 16U) & DSI_WPCR2_THSPREP; } break; case DSI_TCLK_ZERO: /* Enable/Disable custom timing setting */ hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_TCLKZEROEN; hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 20U); if(State != DISABLE) { /* Set custom value */ hdsi->Instance->WPCR[2U] &= ~DSI_WPCR2_TCLKZERO; hdsi->Instance->WPCR[2U] |= (Value << 8U) & DSI_WPCR2_TCLKZERO; } break; case DSI_TCLK_PREPARE: /* Enable/Disable custom timing setting */ hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_TCLKPREPEN; hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 19U); if(State != DISABLE) { /* Set custom value */ hdsi->Instance->WPCR[2U] &= ~DSI_WPCR2_TCLKPREP; hdsi->Instance->WPCR[2U] |= Value & DSI_WPCR2_TCLKPREP; } 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[0U] &= ~DSI_WPCR0_FTXSMCL; hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 12U); } else if(Lane == DSI_DATA_LANES) { /* Force/Unforce the Data Lanes in TX Stop Mode */ hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_FTXSMDL; hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 13U); } else { /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_ERROR; } /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_OK; } /** * @brief Force 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[1U] &= ~DSI_WPCR1_FLPRXLPM; hdsi->Instance->WPCR[1U] |= ((uint32_t)State << 22U); /* 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[0U] &= ~DSI_WPCR0_TDDL; hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 16U); /* 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[0U] &= ~DSI_WPCR0_PDEN; hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 18U); /* 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[0U] &= ~DSI_WPCR0_CDOFFDL; hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 14U); /* 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; } /** * @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; } /** * @} */ /** * @} */ /** * @} */ #endif /* DSI */ #endif /* HAL_DSI_MODULE_ENABLED */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/