aboutsummaryrefslogblamecommitdiff
path: root/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_STM32F4/stm32f4xx_hal_dcmi.c
blob: de0c7096a558a829e3202de56ad38c4fd0f68d4d (plain) (tree)
1
2
3
4
5
6
7
8
599
600
601
602
603
generated by cgit v1.2.3 (git 2.25.1) at 2024-09-18 11:02:28 +0000
class="n">CMCR &= ~DSI_CMCR_TEARE; hdsi->Instance->CMCR |= CmdCfg->TEAcknowledgeRequest; /* Enable the Tearing Effect interrupt */ __HAL_DSI_ENABLE_IT(hdsi, DSI_IT_TE); /* Enable the End of Refresh interrupt */ __HAL_DSI_ENABLE_IT(hdsi, DSI_IT_ER); /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_OK; } /** * @brief Configure command transmission mode: High-speed or Low-power * and enable/disable acknowledge request after packet transmission * @param hdsi: pointer to a DSI_HandleTypeDef structure that contains * the configuration information for the DSI. * @param LPCmd: pointer to a DSI_LPCmdTypeDef structure that contains * the DSI command transmission mode configuration parameters * @retval HAL status */ HAL_StatusTypeDef HAL_DSI_ConfigCommand(DSI_HandleTypeDef *hdsi, DSI_LPCmdTypeDef *LPCmd) { /* Process locked */ __HAL_LOCK(hdsi); assert_param(IS_DSI_LP_GSW0P(LPCmd->LPGenShortWriteNoP)); assert_param(IS_DSI_LP_GSW1P(LPCmd->LPGenShortWriteOneP)); assert_param(IS_DSI_LP_GSW2P(LPCmd->LPGenShortWriteTwoP)); assert_param(IS_DSI_LP_GSR0P(LPCmd->LPGenShortReadNoP)); assert_param(IS_DSI_LP_GSR1P(LPCmd->LPGenShortReadOneP)); assert_param(IS_DSI_LP_GSR2P(LPCmd->LPGenShortReadTwoP)); assert_param(IS_DSI_LP_GLW(LPCmd->LPGenLongWrite)); assert_param(IS_DSI_LP_DSW0P(LPCmd->LPDcsShortWriteNoP)); assert_param(IS_DSI_LP_DSW1P(LPCmd->LPDcsShortWriteOneP)); assert_param(IS_DSI_LP_DSR0P(LPCmd->LPDcsShortReadNoP)); assert_param(IS_DSI_LP_DLW(LPCmd->LPDcsLongWrite)); assert_param(IS_DSI_LP_MRDP(LPCmd->LPMaxReadPacket)); assert_param(IS_DSI_ACK_REQUEST(LPCmd->AcknowledgeRequest)); /* Select High-speed or Low-power for command transmission */ hdsi->Instance->CMCR &= ~(DSI_CMCR_GSW0TX |\ DSI_CMCR_GSW1TX |\ DSI_CMCR_GSW2TX |\ DSI_CMCR_GSR0TX |\ DSI_CMCR_GSR1TX |\ DSI_CMCR_GSR2TX |\ DSI_CMCR_GLWTX |\ DSI_CMCR_DSW0TX |\ DSI_CMCR_DSW1TX |\ DSI_CMCR_DSR0TX |\ DSI_CMCR_DLWTX |\ DSI_CMCR_MRDPS); hdsi->Instance->CMCR |= (LPCmd->LPGenShortWriteNoP |\ LPCmd->LPGenShortWriteOneP |\ LPCmd->LPGenShortWriteTwoP |\ LPCmd->LPGenShortReadNoP |\ LPCmd->LPGenShortReadOneP |\ LPCmd->LPGenShortReadTwoP |\ LPCmd->LPGenLongWrite |\ LPCmd->LPDcsShortWriteNoP |\ LPCmd->LPDcsShortWriteOneP |\ LPCmd->LPDcsShortReadNoP |\ LPCmd->LPDcsLongWrite |\ LPCmd->LPMaxReadPacket); /* Configure the acknowledge request after each packet transmission */ hdsi->Instance->CMCR &= ~DSI_CMCR_ARE; hdsi->Instance->CMCR |= LPCmd->AcknowledgeRequest; /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_OK; } /** * @brief Configure the flow control parameters * @param hdsi: pointer to a DSI_HandleTypeDef structure that contains * the configuration information for the DSI. * @param FlowControl: flow control feature(s) to be enabled. * This parameter can be any combination of @ref DSI_FlowControl. * @retval HAL status */ HAL_StatusTypeDef HAL_DSI_ConfigFlowControl(DSI_HandleTypeDef *hdsi, uint32_t FlowControl) { /* Process locked */ __HAL_LOCK(hdsi); /* Check the parameters */ assert_param(IS_DSI_FLOW_CONTROL(FlowControl)); /* Set the DSI Host Protocol Configuration Register */ hdsi->Instance->PCR &= ~DSI_FLOW_CONTROL_ALL; hdsi->Instance->PCR |= FlowControl; /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_OK; } /** * @brief Configure the DSI PHY timer parameters * @param hdsi: pointer to a DSI_HandleTypeDef structure that contains * the configuration information for the DSI. * @param PhyTimers: DSI_PHY_TimerTypeDef structure that contains * the DSI PHY timing parameters * @retval HAL status */ HAL_StatusTypeDef HAL_DSI_ConfigPhyTimer(DSI_HandleTypeDef *hdsi, DSI_PHY_TimerTypeDef *PhyTimers) { uint32_t maxTime; /* Process locked */ __HAL_LOCK(hdsi); maxTime = (PhyTimers->ClockLaneLP2HSTime > PhyTimers->ClockLaneHS2LPTime)? PhyTimers->ClockLaneLP2HSTime: PhyTimers->ClockLaneHS2LPTime; /* Clock lane timer configuration */ /* In Automatic Clock Lane control mode, the DSI Host can turn off the clock lane between two High-Speed transmission. To do so, the DSI Host calculates the time required for the clock lane to change from HighSpeed to Low-Power and from Low-Power to High-Speed. This timings are configured by the HS2LP_TIME and LP2HS_TIME in the DSI Host Clock Lane Timer Configuration Register (DSI_CLTCR). But the DSI Host is not calculating LP2HS_TIME + HS2LP_TIME but 2 x HS2LP_TIME. Workaround : Configure HS2LP_TIME and LP2HS_TIME with the same value being the max of HS2LP_TIME or LP2HS_TIME. */ hdsi->Instance->CLTCR &= ~(DSI_CLTCR_LP2HS_TIME | DSI_CLTCR_HS2LP_TIME); hdsi->Instance->CLTCR |= (maxTime | ((maxTime)<<16)); /* Data lane timer configuration */ hdsi->Instance->DLTCR &= ~(DSI_DLTCR_MRD_TIME | DSI_DLTCR_LP2HS_TIME | DSI_DLTCR_HS2LP_TIME); hdsi->Instance->DLTCR |= (PhyTimers->DataLaneMaxReadTime | ((PhyTimers->DataLaneLP2HSTime)<<16) | ((PhyTimers->DataLaneHS2LPTime)<<24)); /* Configure the wait period to request HS transmission after a stop state */ hdsi->Instance->PCONFR &= ~DSI_PCONFR_SW_TIME; hdsi->Instance->PCONFR |= ((PhyTimers->StopWaitTime)<<8); /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_OK; } /** * @brief Configure the DSI HOST timeout parameters * @param hdsi: pointer to a DSI_HandleTypeDef structure that contains * the configuration information for the DSI. * @param HostTimeouts: DSI_HOST_TimeoutTypeDef structure that contains * the DSI host timeout parameters * @retval HAL status */ HAL_StatusTypeDef HAL_DSI_ConfigHostTimeouts(DSI_HandleTypeDef *hdsi, DSI_HOST_TimeoutTypeDef *HostTimeouts) { /* Process locked */ __HAL_LOCK(hdsi); /* Set the timeout clock division factor */ hdsi->Instance->CCR &= ~DSI_CCR_TOCKDIV; hdsi->Instance->CCR = ((HostTimeouts->TimeoutCkdiv)<<8); /* High-speed transmission timeout */ hdsi->Instance->TCCR[0] &= ~DSI_TCCR0_HSTX_TOCNT; hdsi->Instance->TCCR[0] |= ((HostTimeouts->HighSpeedTransmissionTimeout)<<16); /* Low-power reception timeout */ hdsi->Instance->TCCR[0] &= ~DSI_TCCR0_LPRX_TOCNT; hdsi->Instance->TCCR[0] |= HostTimeouts->LowPowerReceptionTimeout; /* High-speed read timeout */ hdsi->Instance->TCCR[1] &= ~DSI_TCCR1_HSRD_TOCNT; hdsi->Instance->TCCR[1] |= HostTimeouts->HighSpeedReadTimeout; /* Low-power read timeout */ hdsi->Instance->TCCR[2] &= ~DSI_TCCR2_LPRD_TOCNT; hdsi->Instance->TCCR[2] |= HostTimeouts->LowPowerReadTimeout; /* High-speed write timeout */ hdsi->Instance->TCCR[3] &= ~DSI_TCCR3_HSWR_TOCNT; hdsi->Instance->TCCR[3] |= HostTimeouts->HighSpeedWriteTimeout; /* High-speed write presp mode */ hdsi->Instance->TCCR[3] &= ~DSI_TCCR3_PM; hdsi->Instance->TCCR[3] |= HostTimeouts->HighSpeedWritePrespMode; /* Low-speed write timeout */ hdsi->Instance->TCCR[4] &= ~DSI_TCCR4_LPWR_TOCNT; hdsi->Instance->TCCR[4] |= HostTimeouts->LowPowerWriteTimeout; /* BTA timeout */ hdsi->Instance->TCCR[5] &= ~DSI_TCCR5_BTA_TOCNT; hdsi->Instance->TCCR[5] |= HostTimeouts->BTATimeout; /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_OK; } /** * @brief Start the DSI module * @param hdsi: pointer to a DSI_HandleTypeDef structure that contains * the configuration information for the DSI. * @retval HAL status */ HAL_StatusTypeDef HAL_DSI_Start(DSI_HandleTypeDef *hdsi) { /* Process locked */ __HAL_LOCK(hdsi); /* Enable the DSI host */ __HAL_DSI_ENABLE(hdsi); /* Enable the DSI wrapper */ __HAL_DSI_WRAPPER_ENABLE(hdsi); /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_OK; } /** * @brief Stop the DSI module * @param hdsi: pointer to a DSI_HandleTypeDef structure that contains * the configuration information for the DSI. * @retval HAL status */ HAL_StatusTypeDef HAL_DSI_Stop(DSI_HandleTypeDef *hdsi) { /* Process locked */ __HAL_LOCK(hdsi); /* Disable the DSI host */ __HAL_DSI_DISABLE(hdsi); /* Disable the DSI wrapper */ __HAL_DSI_WRAPPER_DISABLE(hdsi); /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_OK; } /** * @brief Refresh the display in command mode * @param hdsi: pointer to a DSI_HandleTypeDef structure that contains * the configuration information for the DSI. * @retval HAL status */ HAL_StatusTypeDef HAL_DSI_Refresh(DSI_HandleTypeDef *hdsi) { /* Process locked */ __HAL_LOCK(hdsi); /* Update the display */ hdsi->Instance->WCR |= DSI_WCR_LTDCEN; /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_OK; } /** * @brief Controls the display color mode in Video mode * @param hdsi: pointer to a DSI_HandleTypeDef structure that contains * the configuration information for the DSI. * @param ColorMode: Color mode (full or 8-colors). * This parameter can be any value of @ref DSI_Color_Mode * @retval HAL status */ HAL_StatusTypeDef HAL_DSI_ColorMode(DSI_HandleTypeDef *hdsi, uint32_t ColorMode) { /* Process locked */ __HAL_LOCK(hdsi); /* Check the parameters */ assert_param(IS_DSI_COLOR_MODE(ColorMode)); /* Update the display color mode */ hdsi->Instance->WCR &= ~DSI_WCR_COLM; hdsi->Instance->WCR |= ColorMode; /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_OK; } /** * @brief Control the display shutdown in Video mode * @param hdsi: pointer to a DSI_HandleTypeDef structure that contains * the configuration information for the DSI. * @param Shutdown: Shut-down (Display-ON or Display-OFF). * This parameter can be any value of @ref DSI_ShutDown * @retval HAL status */ HAL_StatusTypeDef HAL_DSI_Shutdown(DSI_HandleTypeDef *hdsi, uint32_t Shutdown) { /* Process locked */ __HAL_LOCK(hdsi); /* Check the parameters */ assert_param(IS_DSI_SHUT_DOWN(Shutdown)); /* Update the display Shutdown */ hdsi->Instance->WCR &= ~DSI_WCR_SHTDN; hdsi->Instance->WCR |= Shutdown; /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_OK; } /** * @brief DCS or Generic short write command * @param hdsi: pointer to a DSI_HandleTypeDef structure that contains * the configuration information for the DSI. * @param ChannelID: Virtual channel ID. * @param Mode: DSI short packet data type. * This parameter can be any value of @ref DSI_SHORT_WRITE_PKT_Data_Type. * @param Param1: DSC command or first generic parameter. * This parameter can be any value of @ref DSI_DCS_Command or a * generic command code. * @param Param2: DSC parameter or second generic parameter. * @retval HAL status */ HAL_StatusTypeDef HAL_DSI_ShortWrite(DSI_HandleTypeDef *hdsi, uint32_t ChannelID, uint32_t Mode, uint32_t Param1, uint32_t Param2) { uint32_t tickstart = 0; /* Process locked */ __HAL_LOCK(hdsi); /* Check the parameters */ assert_param(IS_DSI_SHORT_WRITE_PACKET_TYPE(Mode)); /* Get tick */ tickstart = HAL_GetTick(); /* Wait for Command FIFO Empty */ while((hdsi->Instance->GPSR & DSI_GPSR_CMDFE) == 0) { /* Check for the Timeout */ if((HAL_GetTick() - tickstart ) > DSI_TIMEOUT_VALUE) { /* Process Unlocked */ __HAL_UNLOCK(hdsi); return HAL_TIMEOUT; } } /* Configure the packet to send a short DCS command with 0 or 1 parameter */ DSI_ConfigPacketHeader(hdsi->Instance, ChannelID, Mode, Param1, Param2); /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_OK; } /** * @brief DCS or Generic long write command * @param hdsi: pointer to a DSI_HandleTypeDef structure that contains * the configuration information for the DSI. * @param ChannelID: Virtual channel ID. * @param Mode: DSI long packet data type. * This parameter can be any value of @ref DSI_LONG_WRITE_PKT_Data_Type. * @param NbParams: Number of parameters. * @param Param1: DSC command or first generic parameter. * This parameter can be any value of @ref DSI_DCS_Command or a * generic command code * @param ParametersTable: Pointer to parameter values table. * @retval HAL status */ HAL_StatusTypeDef HAL_DSI_LongWrite(DSI_HandleTypeDef *hdsi, uint32_t ChannelID, uint32_t Mode, uint32_t NbParams, uint32_t Param1, uint8_t* ParametersTable) { uint32_t uicounter = 0; uint32_t tickstart = 0; /* Process locked */ __HAL_LOCK(hdsi); /* Check the parameters */ assert_param(IS_DSI_LONG_WRITE_PACKET_TYPE(Mode)); /* Get tick */ tickstart = HAL_GetTick(); /* Wait for Command FIFO Empty */ while((hdsi->Instance->GPSR & DSI_GPSR_CMDFE) == RESET) { /* Check for the Timeout */ if((HAL_GetTick() - tickstart ) > DSI_TIMEOUT_VALUE) { /* Process Unlocked */ __HAL_UNLOCK(hdsi); return HAL_TIMEOUT; } } /* Set the DCS code hexadecimal on payload byte 1, and the other parameters on the write FIFO command*/ while(uicounter < NbParams) { if(uicounter == 0x00) { hdsi->Instance->GPDR=(Param1 | \ ((*(ParametersTable+uicounter))<<8) | \ ((*(ParametersTable+uicounter+1))<<16) | \ ((*(ParametersTable+uicounter+2))<<24)); uicounter += 3; } else { hdsi->Instance->GPDR=((*(ParametersTable+uicounter)) | \ ((*(ParametersTable+uicounter+1))<<8) | \ ((*(ParametersTable+uicounter+2))<<16) | \ ((*(ParametersTable+uicounter+3))<<24)); uicounter+=4; } } /* Configure the packet to send a long DCS command */ DSI_ConfigPacketHeader(hdsi->Instance, ChannelID, Mode, ((NbParams+1)&0x00FF), (((NbParams+1)&0xFF00)>>8)); /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_OK; } /** * @brief Read command (DCS or generic) * @param hdsi: pointer to a DSI_HandleTypeDef structure that contains * the configuration information for the DSI. * @param ChannelNbr: Virtual channel ID * @param Array: pointer to a buffer to store the payload of a read back operation. * @param Size: Data size to be read (in byte). * @param Mode: DSI read packet data type. * This parameter can be any value of @ref DSI_SHORT_READ_PKT_Data_Type. * @param DCSCmd: DCS get/read command. * @param ParametersTable: Pointer to parameter values table. * @retval HAL status */ HAL_StatusTypeDef HAL_DSI_Read(DSI_HandleTypeDef *hdsi, uint32_t ChannelNbr, uint8_t* Array, uint32_t Size, uint32_t Mode, uint32_t DCSCmd, uint8_t* ParametersTable) { uint32_t tickstart = 0; /* Process locked */ __HAL_LOCK(hdsi); /* Check the parameters */ assert_param(IS_DSI_READ_PACKET_TYPE(Mode)); if(Size > 2) { /* set max return packet size */ HAL_DSI_ShortWrite(hdsi, ChannelNbr, DSI_MAX_RETURN_PKT_SIZE, ((Size)&0xFF), (((Size)>>8)&0xFF)); } /* Configure the packet to read command */ if (Mode == DSI_DCS_SHORT_PKT_READ) { DSI_ConfigPacketHeader(hdsi->Instance, ChannelNbr, Mode, DCSCmd, 0); } else if (Mode == DSI_GEN_SHORT_PKT_READ_P0) { DSI_ConfigPacketHeader(hdsi->Instance, ChannelNbr, Mode, 0, 0); } else if (Mode == DSI_GEN_SHORT_PKT_READ_P1) { DSI_ConfigPacketHeader(hdsi->Instance, ChannelNbr, Mode, ParametersTable[0], 0); } else if (Mode == DSI_GEN_SHORT_PKT_READ_P2) { DSI_ConfigPacketHeader(hdsi->Instance, ChannelNbr, Mode, ParametersTable[0], ParametersTable[1]); } /* Get tick */ tickstart = HAL_GetTick(); /* Check that the payload read FIFO is not empty */ while((hdsi->Instance->GPSR & DSI_GPSR_PRDFE) == DSI_GPSR_PRDFE) { /* Check for the Timeout */ if((HAL_GetTick() - tickstart ) > DSI_TIMEOUT_VALUE) { /* Process Unlocked */ __HAL_UNLOCK(hdsi); return HAL_TIMEOUT; } } /* Get the first byte */ *((uint32_t *)Array) = (hdsi->Instance->GPDR); if (Size > 4) { Size -= 4; Array += 4; } else { /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_OK; } /* Get tick */ tickstart = HAL_GetTick(); /* Get the remaining bytes if any */ while(((int)(Size)) > 0) { if((hdsi->Instance->GPSR & DSI_GPSR_PRDFE) == 0) { *((uint32_t *)Array) = (hdsi->Instance->GPDR); Size -= 4; Array += 4; } /* Check for the Timeout */ if((HAL_GetTick() - tickstart ) > DSI_TIMEOUT_VALUE) { /* Process Unlocked */ __HAL_UNLOCK(hdsi); return HAL_TIMEOUT; } } /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_OK; } /** * @brief Enter the ULPM (Ultra Low Power Mode) with the D-PHY PLL running * (only data lanes are in ULPM) * @param hdsi: pointer to a DSI_HandleTypeDef structure that contains * the configuration information for the DSI. * @retval HAL status */ HAL_StatusTypeDef HAL_DSI_EnterULPMData(DSI_HandleTypeDef *hdsi) { uint32_t tickstart = 0; /* Process locked */ __HAL_LOCK(hdsi); /* ULPS Request on Data Lanes */ hdsi->Instance->PUCR |= DSI_PUCR_URDL; /* Get tick */ tickstart = HAL_GetTick(); /* Wait until the D-PHY active lanes enter into ULPM */ if((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE) { while((hdsi->Instance->PSR & DSI_PSR_UAN0) != RESET) { /* Check for the Timeout */ if((HAL_GetTick() - tickstart ) > DSI_TIMEOUT_VALUE) { /* Process Unlocked */ __HAL_UNLOCK(hdsi); return HAL_TIMEOUT; } } } else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES) { while((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1)) != RESET) { /* Check for the Timeout */ if((HAL_GetTick() - tickstart ) > DSI_TIMEOUT_VALUE) { /* Process Unlocked */ __HAL_UNLOCK(hdsi); return HAL_TIMEOUT; } } } /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_OK; } /** * @brief Exit the ULPM (Ultra Low Power Mode) with the D-PHY PLL running * (only data lanes are in ULPM) * @param hdsi: pointer to a DSI_HandleTypeDef structure that contains * the configuration information for the DSI. * @retval HAL status */ HAL_StatusTypeDef HAL_DSI_ExitULPMData(DSI_HandleTypeDef *hdsi) { uint32_t tickstart = 0; /* Process locked */ __HAL_LOCK(hdsi); /* Exit ULPS on Data Lanes */ hdsi->Instance->PUCR |= DSI_PUCR_UEDL; /* Get tick */ tickstart = HAL_GetTick(); /* Wait until all active lanes exit ULPM */ if((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE) { while((hdsi->Instance->PSR & DSI_PSR_UAN0) != DSI_PSR_UAN0) { /* Check for the Timeout */ if((HAL_GetTick() - tickstart ) > DSI_TIMEOUT_VALUE) { /* Process Unlocked */ __HAL_UNLOCK(hdsi); return HAL_TIMEOUT; } } } else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES) { while((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1)) != (DSI_PSR_UAN0 | DSI_PSR_UAN1)) { /* Check for the Timeout */ if((HAL_GetTick() - tickstart ) > DSI_TIMEOUT_VALUE) { /* Process Unlocked */ __HAL_UNLOCK(hdsi); return HAL_TIMEOUT; } } } /* De-assert the ULPM requests and the ULPM exit bits */ hdsi->Instance->PUCR = 0; /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_OK; } /** * @brief Enter the ULPM (Ultra Low Power Mode) with the D-PHY PLL turned off * (both data and clock lanes are in ULPM) * @param hdsi: pointer to a DSI_HandleTypeDef structure that contains * the configuration information for the DSI. * @retval HAL status */ HAL_StatusTypeDef HAL_DSI_EnterULPM(DSI_HandleTypeDef *hdsi) { uint32_t tickstart = 0; /* Process locked */ __HAL_LOCK(hdsi); /* Clock lane configuration: no more HS request */ hdsi->Instance->CLCR &= ~DSI_CLCR_DPCC; /* Use system PLL as byte lane clock source before stopping DSIPHY clock source */ __HAL_RCC_DSI_CONFIG(RCC_DSICLKSOURCE_PLLR); /* ULPS Request on Clock and Data Lanes */ hdsi->Instance->PUCR |= (DSI_PUCR_URCL | DSI_PUCR_URDL); /* Get tick */ tickstart = HAL_GetTick(); /* Wait until all active lanes exit ULPM */ if((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE) { while((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UANC)) != RESET) { /* Check for the Timeout */ if((HAL_GetTick() - tickstart ) > DSI_TIMEOUT_VALUE) { /* Process Unlocked */ __HAL_UNLOCK(hdsi); return HAL_TIMEOUT; } } } else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES) { while((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1 | DSI_PSR_UANC)) != RESET) { /* Check for the Timeout */ if((HAL_GetTick() - tickstart ) > DSI_TIMEOUT_VALUE) { /* Process Unlocked */ __HAL_UNLOCK(hdsi); return HAL_TIMEOUT; } } } /* Turn off the DSI PLL */ __HAL_DSI_PLL_DISABLE(hdsi); /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_OK; } /** * @brief Exit the ULPM (Ultra Low Power Mode) with the D-PHY PLL turned off * (both data and clock lanes are in ULPM) * @param hdsi: pointer to a DSI_HandleTypeDef structure that contains * the configuration information for the DSI. * @retval HAL status */ HAL_StatusTypeDef HAL_DSI_ExitULPM(DSI_HandleTypeDef *hdsi) { uint32_t tickstart = 0; /* Process locked */ __HAL_LOCK(hdsi); /* Turn on the DSI PLL */ __HAL_DSI_PLL_ENABLE(hdsi); /* Get tick */ tickstart = HAL_GetTick(); /* Wait for the lock of the PLL */ while(__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_PLLLS) == RESET) { /* Check for the Timeout */ if((HAL_GetTick() - tickstart ) > DSI_TIMEOUT_VALUE) { /* Process Unlocked */ __HAL_UNLOCK(hdsi); return HAL_TIMEOUT; } } /* Exit ULPS on Clock and Data Lanes */ hdsi->Instance->PUCR |= (DSI_PUCR_UECL | DSI_PUCR_UEDL); /* Get tick */ tickstart = HAL_GetTick(); /* Wait until all active lanes exit ULPM */ if((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE) { while((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UANC)) != (DSI_PSR_UAN0 | DSI_PSR_UANC)) { /* Check for the Timeout */ if((HAL_GetTick() - tickstart ) > DSI_TIMEOUT_VALUE) { /* Process Unlocked */ __HAL_UNLOCK(hdsi); return HAL_TIMEOUT; } } } else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES) { while((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1 | DSI_PSR_UANC)) != (DSI_PSR_UAN0 | DSI_PSR_UAN1 | DSI_PSR_UANC)) { /* Check for the Timeout */ if((HAL_GetTick() - tickstart ) > DSI_TIMEOUT_VALUE) { /* Process Unlocked */ __HAL_UNLOCK(hdsi); return HAL_TIMEOUT; } } } /* De-assert the ULPM requests and the ULPM exit bits */ hdsi->Instance->PUCR = 0; /* Switch the lanbyteclock source in the RCC from system PLL to D-PHY */ __HAL_RCC_DSI_CONFIG(RCC_DSICLKSOURCE_DSIPHY); /* Restore clock lane configuration to HS */ hdsi->Instance->CLCR |= DSI_CLCR_DPCC; /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_OK; } /** * @brief Start test pattern generation * @param hdsi: pointer to a DSI_HandleTypeDef structure that contains * the configuration information for the DSI. * @param Mode: Pattern generator mode * This parameter can be one of the following values: * 0 : Color bars (horizontal or vertical) * 1 : BER pattern (vertical only) * @param Orientation: Pattern generator orientation * This parameter can be one of the following values: * 0 : Vertical color bars * 1 : Horizontal color bars * @retval HAL status */ HAL_StatusTypeDef HAL_DSI_PatternGeneratorStart(DSI_HandleTypeDef *hdsi, uint32_t Mode, uint32_t Orientation) { /* Process locked */ __HAL_LOCK(hdsi); /* Configure pattern generator mode and orientation */ hdsi->Instance->VMCR &= ~(DSI_VMCR_PGM | DSI_VMCR_PGO); hdsi->Instance->VMCR |= ((Mode<<20) | (Orientation<<24)); /* Enable pattern generator by setting PGE bit */ hdsi->Instance->VMCR |= DSI_VMCR_PGE; /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_OK; } /** * @brief Stop test pattern generation * @param hdsi: pointer to a DSI_HandleTypeDef structure that contains * the configuration information for the DSI. * @retval HAL status */ HAL_StatusTypeDef HAL_DSI_PatternGeneratorStop(DSI_HandleTypeDef *hdsi) { /* Process locked */ __HAL_LOCK(hdsi); /* Disable pattern generator by clearing PGE bit */ hdsi->Instance->VMCR &= ~DSI_VMCR_PGE; /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_OK; } /** * @brief Set Slew-Rate And Delay Tuning * @param hdsi: pointer to a DSI_HandleTypeDef structure that contains * the configuration information for the DSI. * @param CommDelay: Communication delay to be adjusted. * This parameter can be any value of @ref DSI_Communication_Delay * @param Lane: select between clock or data lanes. * This parameter can be any value of @ref DSI_Lane_Group * @param Value: Custom value of the slew-rate or delay * @retval HAL status */ HAL_StatusTypeDef HAL_DSI_SetSlewRateAndDelayTuning(DSI_HandleTypeDef *hdsi, uint32_t CommDelay, uint32_t Lane, uint32_t Value) { /* Process locked */ __HAL_LOCK(hdsi); /* Check function parameters */ assert_param(IS_DSI_COMMUNICATION_DELAY(CommDelay)); assert_param(IS_DSI_LANE_GROUP(Lane)); switch(CommDelay) { case DSI_SLEW_RATE_HSTX: if(Lane == DSI_CLOCK_LANE) { /* High-Speed Transmission Slew Rate Control on Clock Lane */ hdsi->Instance->WPCR[1] &= ~DSI_WPCR1_HSTXSRCCL; hdsi->Instance->WPCR[1] |= Value<<16; } else if(Lane == DSI_DATA_LANES) { /* High-Speed Transmission Slew Rate Control on Data Lanes */ hdsi->Instance->WPCR[1] &= ~DSI_WPCR1_HSTXSRCDL; hdsi->Instance->WPCR[1] |= Value<<18; } break; case DSI_SLEW_RATE_LPTX: if(Lane == DSI_CLOCK_LANE) { /* Low-Power transmission Slew Rate Compensation on Clock Lane */ hdsi->Instance->WPCR[1] &= ~DSI_WPCR1_LPSRCCL; hdsi->Instance->WPCR[1] |= Value<<6; } else if(Lane == DSI_DATA_LANES) { /* Low-Power transmission Slew Rate Compensation on Data Lanes */ hdsi->Instance->WPCR[1] &= ~DSI_WPCR1_LPSRCDL; hdsi->Instance->WPCR[1] |= Value<<8; } break; case DSI_HS_DELAY: if(Lane == DSI_CLOCK_LANE) { /* High-Speed Transmission Delay on Clock Lane */ hdsi->Instance->WPCR[1] &= ~DSI_WPCR1_HSTXDCL; hdsi->Instance->WPCR[1] |= Value; } else if(Lane == DSI_DATA_LANES) { /* High-Speed Transmission Delay on Data Lanes */ hdsi->Instance->WPCR[1] &= ~DSI_WPCR1_HSTXDDL; hdsi->Instance->WPCR[1] |= Value<<2; } break; default: break; } /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_OK; } /** * @brief Low-Power Reception Filter Tuning * @param hdsi: pointer to a DSI_HandleTypeDef structure that contains * the configuration information for the DSI. * @param Frequency: cutoff frequency of low-pass filter at the input of LPRX * @retval HAL status */ HAL_StatusTypeDef HAL_DSI_SetLowPowerRXFilter(DSI_HandleTypeDef *hdsi, uint32_t Frequency) { /* Process locked */ __HAL_LOCK(hdsi); /* Low-Power RX low-pass Filtering Tuning */ hdsi->Instance->WPCR[1] &= ~DSI_WPCR1_LPRXFT; hdsi->Instance->WPCR[1] |= Frequency<<25; /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_OK; } /** * @brief Activate an additional current path on all lanes to meet the SDDTx parameter * defined in the MIPI D-PHY specification * @param hdsi: pointer to a DSI_HandleTypeDef structure that contains * the configuration information for the DSI. * @param State: ENABLE or DISABLE * @retval HAL status */ HAL_StatusTypeDef HAL_DSI_SetSDD(DSI_HandleTypeDef *hdsi, FunctionalState State) { /* Process locked */ __HAL_LOCK(hdsi); /* Check function parameters */ assert_param(IS_FUNCTIONAL_STATE(State)); /* Activate/Disactivate additional current path on all lanes */ hdsi->Instance->WPCR[1] &= ~DSI_WPCR1_SDDC; hdsi->Instance->WPCR[1] |= State<<12; /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_OK; } /** * @brief Custom lane pins configuration * @param hdsi: pointer to a DSI_HandleTypeDef structure that contains * the configuration information for the DSI. * @param CustomLane: Function to be applyed on selected lane. * This parameter can be any value of @ref DSI_CustomLane * @param Lane: select between clock or data lane 0 or data lane 1. * This parameter can be any value of @ref DSI_Lane_Select * @param State: ENABLE or DISABLE * @retval HAL status */ HAL_StatusTypeDef HAL_DSI_SetLanePinsConfiguration(DSI_HandleTypeDef *hdsi, uint32_t CustomLane, uint32_t Lane, FunctionalState State) { /* Process locked */ __HAL_LOCK(hdsi); /* Check function parameters */ assert_param(IS_DSI_CUSTOM_LANE(CustomLane)); assert_param(IS_DSI_LANE(Lane)); assert_param(IS_FUNCTIONAL_STATE(State)); switch(CustomLane) { case DSI_SWAP_LANE_PINS: if(Lane == DSI_CLOCK_LANE) { /* Swap pins on clock lane */ hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_SWCL; hdsi->Instance->WPCR[0] |= (State<<6); } else if(Lane == DSI_DATA_LANE0) { /* Swap pins on data lane 0 */ hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_SWDL0; hdsi->Instance->WPCR[0] |= (State<<7); } else if(Lane == DSI_DATA_LANE1) { /* Swap pins on data lane 1 */ hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_SWDL1; hdsi->Instance->WPCR[0] |= (State<<8); } break; case DSI_INVERT_HS_SIGNAL: if(Lane == DSI_CLOCK_LANE) { /* Invert HS signal on clock lane */ hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_HSICL; hdsi->Instance->WPCR[0] |= (State<<9); } else if(Lane == DSI_DATA_LANE0) { /* Invert HS signal on data lane 0 */ hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_HSIDL0; hdsi->Instance->WPCR[0] |= (State<<10); } else if(Lane == DSI_DATA_LANE1) { /* Invert HS signal on data lane 1 */ hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_HSIDL1; hdsi->Instance->WPCR[0] |= (State<<11); } break; default: break; } /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_OK; } /** * @brief Set custom timing for the PHY * @param hdsi: pointer to a DSI_HandleTypeDef structure that contains * the configuration information for the DSI. * @param Timing: PHY timing to be adjusted. * This parameter can be any value of @ref DSI_PHY_Timing * @param State: ENABLE or DISABLE * @param Value: Custom value of the timing * @retval HAL status */ HAL_StatusTypeDef HAL_DSI_SetPHYTimings(DSI_HandleTypeDef *hdsi, uint32_t Timing, FunctionalState State, uint32_t Value) { /* Process locked */ __HAL_LOCK(hdsi); /* Check function parameters */ assert_param(IS_DSI_PHY_TIMING(Timing)); assert_param(IS_FUNCTIONAL_STATE(State)); switch(Timing) { case DSI_TCLK_POST: /* Enable/Disable custom timing setting */ hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_TCLKPOSTEN; hdsi->Instance->WPCR[0] |= (State<<27); if(State) { /* Set custom value */ hdsi->Instance->WPCR[4] &= ~DSI_WPCR4_TCLKPOST; hdsi->Instance->WPCR[4] |= Value; } break; case DSI_TLPX_CLK: /* Enable/Disable custom timing setting */ hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_TLPXCEN; hdsi->Instance->WPCR[0] |= (State<<26); if(State) { /* Set custom value */ hdsi->Instance->WPCR[3] &= ~DSI_WPCR3_TLPXC; hdsi->Instance->WPCR[3] |= Value; } break; case DSI_THS_EXIT: /* Enable/Disable custom timing setting */ hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_THSEXITEN; hdsi->Instance->WPCR[0] |= (State<<25); if(State) { /* Set custom value */ hdsi->Instance->WPCR[3] &= ~DSI_WPCR3_THSEXIT; hdsi->Instance->WPCR[3] |= Value; } break; case DSI_TLPX_DATA: /* Enable/Disable custom timing setting */ hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_TLPXDEN; hdsi->Instance->WPCR[0] |= (State<<24); if(State) { /* Set custom value */ hdsi->Instance->WPCR[3] &= ~DSI_WPCR3_TLPXD; hdsi->Instance->WPCR[3] |= Value; } break; case DSI_THS_ZERO: /* Enable/Disable custom timing setting */ hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_THSZEROEN; hdsi->Instance->WPCR[0] |= (State<<23); if(State) { /* Set custom value */ hdsi->Instance->WPCR[3] &= ~DSI_WPCR3_THSZERO; hdsi->Instance->WPCR[3] |= Value; } break; case DSI_THS_TRAIL: /* Enable/Disable custom timing setting */ hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_THSTRAILEN; hdsi->Instance->WPCR[0] |= (State<<22); if(State) { /* Set custom value */ hdsi->Instance->WPCR[2] &= ~DSI_WPCR2_THSTRAIL; hdsi->Instance->WPCR[2] |= Value; } break; case DSI_THS_PREPARE: /* Enable/Disable custom timing setting */ hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_THSPREPEN; hdsi->Instance->WPCR[0] |= (State<<21); if(State) { /* Set custom value */ hdsi->Instance->WPCR[2] &= ~DSI_WPCR2_THSPREP; hdsi->Instance->WPCR[2] |= Value; } break; case DSI_TCLK_ZERO: /* Enable/Disable custom timing setting */ hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_TCLKZEROEN; hdsi->Instance->WPCR[0] |= (State<<20); if(State) { /* Set custom value */ hdsi->Instance->WPCR[2] &= ~DSI_WPCR2_TCLKZERO; hdsi->Instance->WPCR[2] |= Value; } break; case DSI_TCLK_PREPARE: /* Enable/Disable custom timing setting */ hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_TCLKPREPEN; hdsi->Instance->WPCR[0] |= (State<<19); if(State) { /* Set custom value */ hdsi->Instance->WPCR[2] &= ~DSI_WPCR2_TCLKPREP; hdsi->Instance->WPCR[2] |= Value; } break; default: break; } /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_OK; } /** * @brief Force the Clock/Data Lane in TX Stop Mode * @param hdsi: pointer to a DSI_HandleTypeDef structure that contains * the configuration information for the DSI. * @param Lane: select between clock or data lanes. * This parameter can be any value of @ref DSI_Lane_Group * @param State: ENABLE or DISABLE * @retval HAL status */ HAL_StatusTypeDef HAL_DSI_ForceTXStopMode(DSI_HandleTypeDef *hdsi, uint32_t Lane, FunctionalState State) { /* Process locked */ __HAL_LOCK(hdsi); /* Check function parameters */ assert_param(IS_DSI_LANE_GROUP(Lane)); assert_param(IS_FUNCTIONAL_STATE(State)); if(Lane == DSI_CLOCK_LANE) { /* Force/Unforce the Clock Lane in TX Stop Mode */ hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_FTXSMCL; hdsi->Instance->WPCR[0] |= (State<<12); } else if(Lane == DSI_DATA_LANES) { /* Force/Unforce the Data Lanes in TX Stop Mode */ hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_FTXSMDL; hdsi->Instance->WPCR[0] |= (State<<13); } /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_OK; } /** * @brief Forces LP Receiver in Low-Power Mode * @param hdsi: pointer to a DSI_HandleTypeDef structure that contains * the configuration information for the DSI. * @param State: ENABLE or DISABLE * @retval HAL status */ HAL_StatusTypeDef HAL_DSI_ForceRXLowPower(DSI_HandleTypeDef *hdsi, FunctionalState State) { /* Process locked */ __HAL_LOCK(hdsi); /* Check function parameters */ assert_param(IS_FUNCTIONAL_STATE(State)); /* Force/Unforce LP Receiver in Low-Power Mode */ hdsi->Instance->WPCR[1] &= ~DSI_WPCR1_FLPRXLPM; hdsi->Instance->WPCR[1] |= State<<22; /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_OK; } /** * @brief Force Data Lanes in RX Mode after a BTA * @param hdsi: pointer to a DSI_HandleTypeDef structure that contains * the configuration information for the DSI. * @param State: ENABLE or DISABLE * @retval HAL status */ HAL_StatusTypeDef HAL_DSI_ForceDataLanesInRX(DSI_HandleTypeDef *hdsi, FunctionalState State) { /* Process locked */ __HAL_LOCK(hdsi); /* Check function parameters */ assert_param(IS_FUNCTIONAL_STATE(State)); /* Force Data Lanes in RX Mode */ hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_TDDL; hdsi->Instance->WPCR[0] |= State<<16; /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_OK; } /** * @brief Enable a pull-down on the lanes to prevent from floating states when unused * @param hdsi: pointer to a DSI_HandleTypeDef structure that contains * the configuration information for the DSI. * @param State: ENABLE or DISABLE * @retval HAL status */ HAL_StatusTypeDef HAL_DSI_SetPullDown(DSI_HandleTypeDef *hdsi, FunctionalState State) { /* Process locked */ __HAL_LOCK(hdsi); /* Check function parameters */ assert_param(IS_FUNCTIONAL_STATE(State)); /* Enable/Disable pull-down on lanes */ hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_PDEN; hdsi->Instance->WPCR[0] |= State<<18; /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_OK; } /** * @brief Switch off the contention detection on data lanes * @param hdsi: pointer to a DSI_HandleTypeDef structure that contains * the configuration information for the DSI. * @param State: ENABLE or DISABLE * @retval HAL status */ HAL_StatusTypeDef HAL_DSI_SetContentionDetectionOff(DSI_HandleTypeDef *hdsi, FunctionalState State) { /* Process locked */ __HAL_LOCK(hdsi); /* Check function parameters */ assert_param(IS_FUNCTIONAL_STATE(State)); /* Contention Detection on Data Lanes OFF */ hdsi->Instance->WPCR[0] &= ~DSI_WPCR0_CDOFFDL; hdsi->Instance->WPCR[0] |= State<<14; /* Process unlocked */ __HAL_UNLOCK(hdsi); return HAL_OK; } /** * @} */ /** @defgroup DSI_Group4 Peripheral State and Errors functions * @brief Peripheral State and Errors functions * @verbatim =============================================================================== ##### Peripheral State and Errors functions ##### =============================================================================== [..] This subsection provides functions allowing to (+) Check the DSI state. (+) Get error code. @endverbatim * @{ */ /** * @brief Return the DSI state * @param hdsi: pointer to a DSI_HandleTypeDef structure that contains * the configuration information for the DSI. * @retval HAL state */ HAL_DSI_StateTypeDef HAL_DSI_GetState(DSI_HandleTypeDef *hdsi) { return hdsi->State; } /** * @} */ /** * @} */ #endif /* STM32F469xx || STM32F479xx */ #endif /* HAL_DSI_MODULE_ENABLED */ /** * @} */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/