/** | |
****************************************************************************** | |
* @file stm32f4xx_hal_dsi.c | |
* @author MCD Application Team | |
* @version V1.7.0 | |
* @date 17-February-2017 | |
* @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 | |
* @{ | |
*/ | |
/** @addtogroup DSI | |
* @{ | |
*/ | |
#ifdef HAL_DSI_MODULE_ENABLED | |
#if defined(STM32F469xx) || defined(STM32F479xx) | |
/* Private types -------------------------------------------------------------*/ | |
/* Private defines -----------------------------------------------------------*/ | |
/** @addtogroup DSI_Private_Constants | |
* @{ | |
*/ | |
#define DSI_TIMEOUT_VALUE ((uint32_t)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 = 0U; | |
uint32_t unitIntervalx4 = 0U; | |
uint32_t tempIDF = 0U; | |
/* 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 Return the DSI error code | |
* @param hdsi: pointer to a DSI_HandleTypeDef structure that contains | |
* the configuration information for the DSI. | |
* @retval DSI Error Code | |
*/ | |
uint32_t HAL_DSI_GetError(DSI_HandleTypeDef *hdsi) | |
{ | |
/* Get the error code */ | |
return hdsi->ErrorCode; | |
} | |
/** | |
* @brief Enable the error monitor flags | |
* @param hdsi: pointer to a DSI_HandleTypeDef structure that contains | |
* the configuration information for the DSI. | |
* @param ActiveErrors: indicates which error interrupts will be enabled. | |
* This parameter can be any combination of @ref DSI_Error_Data_Type. | |
* @retval HAL status | |
*/ | |
HAL_StatusTypeDef HAL_DSI_ConfigErrorMonitor(DSI_HandleTypeDef *hdsi, uint32_t ActiveErrors) | |
{ | |
/* Process locked */ | |
__HAL_LOCK(hdsi); | |
hdsi->Instance->IER[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 ##### | |
=============================================================================== | |
@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 DCS or Generic short write command | |
* @param hdsi: pointer to a DSI_HandleTypeDef structure that contains | |
* the configuration information for the DSI. | |
* @param ChannelID: Virtual channel ID. | |
* @param Mode: DSI short packet data type. | |
* This parameter can be any value of @ref DSI_SHORT_WRITE_PKT_Data_Type. | |
* @param Param1: DSC command or first generic parameter. | |
* This parameter can be any value of @ref DSI_DCS_Command or a | |
* generic command code. | |
* @param Param2: DSC parameter or second generic parameter. | |
* @retval HAL status | |
*/ | |
HAL_StatusTypeDef HAL_DSI_ShortWrite(DSI_HandleTypeDef *hdsi, | |
uint32_t ChannelID, | |
uint32_t Mode, | |
uint32_t Param1, | |
uint32_t Param2) | |
{ | |
uint32_t tickstart = 0U; | |
/* 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 DCS or Generic long write command | |
* @param hdsi: pointer to a DSI_HandleTypeDef structure that contains | |
* the configuration information for the DSI. | |
* @param ChannelID: Virtual channel ID. | |
* @param Mode: DSI long packet data type. | |
* This parameter can be any value of @ref DSI_LONG_WRITE_PKT_Data_Type. | |
* @param NbParams: Number of parameters. | |
* @param Param1: DSC command or first generic parameter. | |
* This parameter can be any value of @ref DSI_DCS_Command or a | |
* generic command code | |
* @param ParametersTable: Pointer to parameter values table. | |
* @retval HAL status | |
*/ | |
HAL_StatusTypeDef HAL_DSI_LongWrite(DSI_HandleTypeDef *hdsi, | |
uint32_t ChannelID, | |
uint32_t Mode, | |
uint32_t NbParams, | |
uint32_t Param1, | |
uint8_t* ParametersTable) | |
{ | |
uint32_t uicounter = 0U, nbBytes = 0U, count = 0U; | |
uint32_t tickstart = 0U; | |
uint32_t fifoword = 0U; | |
/* 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)(*(ParametersTable + count))) << (8U + (8U*count))); | |
} | |
hdsi->Instance->GPDR = fifoword; | |
uicounter = NbParams - nbBytes; | |
ParametersTable += 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)(*(ParametersTable + count))) << (8U*count)); | |
} | |
hdsi->Instance->GPDR = fifoword; | |
uicounter -= nbBytes; | |
ParametersTable += 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 = 0U; | |
/* Process locked */ | |
__HAL_LOCK(hdsi); | |
/* Check the parameters */ | |
assert_param(IS_DSI_READ_PACKET_TYPE(Mode)); | |
if(Size > 2U) | |
{ | |
/* set max return packet size */ | |
HAL_DSI_ShortWrite(hdsi, ChannelNbr, DSI_MAX_RETURN_PKT_SIZE, ((Size)&0xFFU), (((Size)>>8U)&0xFFU)); | |
} | |
/* 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 *)Array) = (hdsi->Instance->GPDR); | |
if (Size > 4U) | |
{ | |
Size -= 4U; | |
Array += 4U; | |
} | |
else | |
{ | |
/* Process unlocked */ | |
__HAL_UNLOCK(hdsi); | |
return HAL_OK; | |
} | |
/* Get tick */ | |
tickstart = HAL_GetTick(); | |
/* Get the remaining bytes if any */ | |
while(((int)(Size)) > 0U) | |
{ | |
if((hdsi->Instance->GPSR & DSI_GPSR_PRDFE) == 0U) | |
{ | |
*((uint32_t *)Array) = (hdsi->Instance->GPDR); | |
Size -= 4U; | |
Array += 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 = 0U; | |
/* Process locked */ | |
__HAL_LOCK(hdsi); | |
/* ULPS Request on Data Lanes */ | |
hdsi->Instance->PUCR |= DSI_PUCR_URDL; | |
/* Get tick */ | |
tickstart = HAL_GetTick(); | |
/* Wait until the D-PHY active lanes enter into ULPM */ | |
if((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE) | |
{ | |
while((hdsi->Instance->PSR & DSI_PSR_UAN0) != RESET) | |
{ | |
/* Check for the Timeout */ | |
if((HAL_GetTick() - tickstart ) > DSI_TIMEOUT_VALUE) | |
{ | |
/* Process Unlocked */ | |
__HAL_UNLOCK(hdsi); | |
return HAL_TIMEOUT; | |
} | |
} | |
} | |
else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES) | |
{ | |
while((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1)) != RESET) | |
{ | |
/* Check for the Timeout */ | |
if((HAL_GetTick() - tickstart ) > DSI_TIMEOUT_VALUE) | |
{ | |
/* Process Unlocked */ | |
__HAL_UNLOCK(hdsi); | |
return HAL_TIMEOUT; | |
} | |
} | |
} | |
/* Process unlocked */ | |
__HAL_UNLOCK(hdsi); | |
return HAL_OK; | |
} | |
/** | |
* @brief Exit the ULPM (Ultra Low Power Mode) with the D-PHY PLL running | |
* (only data lanes are in ULPM) | |
* @param hdsi: pointer to a DSI_HandleTypeDef structure that contains | |
* the configuration information for the DSI. | |
* @retval HAL status | |
*/ | |
HAL_StatusTypeDef HAL_DSI_ExitULPMData(DSI_HandleTypeDef *hdsi) | |
{ | |
uint32_t tickstart = 0U; | |
/* 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; | |
} | |
} | |
} | |
/* 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 = 0U; | |
/* Process locked */ | |
__HAL_LOCK(hdsi); | |
/* Clock lane configuration: no more HS request */ | |
hdsi->Instance->CLCR &= ~DSI_CLCR_DPCC; | |
/* Use system PLL as byte lane clock source before stopping DSIPHY clock source */ | |
__HAL_RCC_DSI_CONFIG(RCC_DSICLKSOURCE_PLLR); | |
/* ULPS Request on Clock and Data Lanes */ | |
hdsi->Instance->PUCR |= (DSI_PUCR_URCL | DSI_PUCR_URDL); | |
/* Get tick */ | |
tickstart = HAL_GetTick(); | |
/* Wait until all active lanes exit ULPM */ | |
if((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE) | |
{ | |
while((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UANC)) != RESET) | |
{ | |
/* Check for the Timeout */ | |
if((HAL_GetTick() - tickstart ) > DSI_TIMEOUT_VALUE) | |
{ | |
/* Process Unlocked */ | |
__HAL_UNLOCK(hdsi); | |
return HAL_TIMEOUT; | |
} | |
} | |
} | |
else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES) | |
{ | |
while((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1 | DSI_PSR_UANC)) != RESET) | |
{ | |
/* Check for the Timeout */ | |
if((HAL_GetTick() - tickstart ) > DSI_TIMEOUT_VALUE) | |
{ | |
/* Process Unlocked */ | |
__HAL_UNLOCK(hdsi); | |
return HAL_TIMEOUT; | |
} | |
} | |
} | |
/* Turn off the DSI PLL */ | |
__HAL_DSI_PLL_DISABLE(hdsi); | |
/* Process unlocked */ | |
__HAL_UNLOCK(hdsi); | |
return HAL_OK; | |
} | |
/** | |
* @brief Exit the ULPM (Ultra Low Power Mode) with the D-PHY PLL turned off | |
* (both data and clock lanes are in ULPM) | |
* @param hdsi: pointer to a DSI_HandleTypeDef structure that contains | |
* the configuration information for the DSI. | |
* @retval HAL status | |
*/ | |
HAL_StatusTypeDef HAL_DSI_ExitULPM(DSI_HandleTypeDef *hdsi) | |
{ | |
uint32_t tickstart = 0U; | |
/* 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; | |
} | |
} | |
} | |
/* 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; | |
} | |
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; | |
} | |
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; | |
} | |
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_CLOCK_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); | |
} | |
break; | |
case DSI_INVERT_HS_SIGNAL: | |
if(Lane == DSI_CLOCK_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); | |
} | |
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) | |
{ | |
/* 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) | |
{ | |
/* 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) | |
{ | |
/* 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) | |
{ | |
/* 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) | |
{ | |
/* 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) | |
{ | |
/* 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) | |
{ | |
/* 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) | |
{ | |
/* 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) | |
{ | |
/* 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); | |
} | |
/* Process unlocked */ | |
__HAL_UNLOCK(hdsi); | |
return HAL_OK; | |
} | |
/** | |
* @brief Forces LP Receiver in Low-Power Mode | |
* @param hdsi: pointer to a DSI_HandleTypeDef structure that contains | |
* the configuration information for the DSI. | |
* @param State: ENABLE or DISABLE | |
* @retval HAL status | |
*/ | |
HAL_StatusTypeDef HAL_DSI_ForceRXLowPower(DSI_HandleTypeDef *hdsi, FunctionalState State) | |
{ | |
/* Process locked */ | |
__HAL_LOCK(hdsi); | |
/* Check function parameters */ | |
assert_param(IS_FUNCTIONAL_STATE(State)); | |
/* Force/Unforce LP Receiver in Low-Power Mode */ | |
hdsi->Instance->WPCR[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; | |
} | |
/** | |
* @} | |
*/ | |
/** | |
* @} | |
*/ | |
#endif /* STM32F469xx || STM32F479xx */ | |
#endif /* HAL_DSI_MODULE_ENABLED */ | |
/** | |
* @} | |
*/ | |
/** | |
* @} | |
*/ | |
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |