PeripheralDriver_Flagchip_F.../Src/fc7xxx_driver_tmu.c

313 lines
9.1 KiB
C

/**
* @file fc7xxx_driver_tmu.c
* @author Flagchip
* @brief FC7xxx TMU driver source code
* @version 0.1.0
* @date 2023-12-29
*
* @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd.
*
* @details
*/
/*********************************************************************************
* Revision History:
*
* Version Date Initials CR# Descriptions
* --------- ---------- ------------ ---------- ---------------
* 0.1.0 2023-12-29 qxw074 N/A First version for FC7240
******************************************************************************** */
#include "fc7xxx_driver_tmu.h"
#include "fc7xxx_driver_pcc.h"
#include "interrupt_manager.h"
/********* Local Variables ************/
/** @brief TMU peripheral base pointers */
static TMU_Type *const s_apTmuBase = TMU_BASE_PTRS;
/** @brief Temperature over 150 Celsius notify callback function point */
static TMU_TempOver150InterruptCallbackType s_apTmuOver150Notify = NULL;
/** @brief Temperature over 125 Celsius notify callback function point */
static TMU_TempOver125InterruptCallbackType s_apTmuOver125Notify = NULL;
/** @brief The Flag-based temperature sensor ready notify callback function point */
static TMU_TempFlagReadyInterruptCallbackType s_apTmuFlagReadyNotify = NULL;
/** @brief The Voltage-based temperature sensor ready notify callback function point */
static TMU_TempVoltageReadyInterruptCallbackType s_apTmuVoltgeReadyNotify = NULL;
/***************TMU IRQ Functions*****************/
/** @brief TMU interrupt entry */
void TMU_IRQHandler(void);
/**
* @brief TMU irq handler
*
*/
void TMU_IRQHandler(void)
{
TMU_Type *const pTmu = s_apTmuBase;
if (TMU_HWA_GetFlagTemperature150InterruptFlag(pTmu) == true)
{
if (TMU_HWA_Get150Flag(pTmu) == true)
{
if (s_apTmuOver150Notify != NULL)
{
s_apTmuOver150Notify();
}
TMU_HWA_Clear150Flag(pTmu);
}
}
if (TMU_HWA_GetFlagTemperature125InterruptFlag(pTmu) == true)
{
if (TMU_HWA_Get125Flag(pTmu) == true)
{
if (s_apTmuOver125Notify != NULL)
{
s_apTmuOver125Notify();
}
TMU_HWA_Clear125Flag(pTmu);
}
}
if (TMU_HWA_GetFlagTemperatureReadyInterruptFlag(pTmu) == true)
{
if (TMU_HWA_GetFlagTemperatureReady(pTmu) == true)
{
if (s_apTmuFlagReadyNotify != NULL)
{
s_apTmuFlagReadyNotify();
}
TMU_HWA_SetTemperatureLockStatus(pTmu, TMU_TF_TV_UNLOCK);
TMU_HWA_SetFlagTemperatureReadyInterruptFlag(pTmu, false);
TMU_HWA_SetTemperatureLockStatus(pTmu, TMU_TF_TV_LOCK);
}
}
if (TMU_HWA_GetVoltageTemperatureReadyInterruptFlag(pTmu) == true)
{
if (TMU_HWA_GetVoltageTemperatureReady(pTmu) == true)
{
if (s_apTmuVoltgeReadyNotify != NULL)
{
s_apTmuVoltgeReadyNotify();
}
TMU_HWA_SetTemperatureLockStatus(pTmu, TMU_TF_TV_UNLOCK);
TMU_HWA_SetVoltageTemperatureReadyInterruptFlag(pTmu, false);
TMU_HWA_SetTemperatureLockStatus(pTmu, TMU_TF_TV_LOCK);
}
}
}
/**
* @brief Initialize the TMU instance
*
* @param pInitCfg the configurations of the TMU instance
*/
void TMU_Init(const TMU_InitType *const pInitCfg)
{
DEV_ASSERT(pInitCfg != NULL);
TMU_Type *const pTmu = s_apTmuBase;
uint32_t u32FlagCtrl;
uint32_t u32VoltageCtrl;
uint8_t u8FlagStartupCnt;
uint8_t u8VoltageStartupCnt;
PCC_ClkSrcType eAdcClkName = PCC_CLK_TMU0;
uint32_t u32TmuClk;
u32TmuClk = PCC_GetPccFunctionClock(eAdcClkName);
u8FlagStartupCnt = (uint8_t)((u32TmuClk * 11U) / 127000000U + 1U);
u8VoltageStartupCnt = (uint8_t)((u32TmuClk * 5U) / 127000000U + 1U);
if (u8FlagStartupCnt > 15U)
{
u8FlagStartupCnt = 15U;
}
if (u8VoltageStartupCnt > 7U)
{
u8VoltageStartupCnt = 7U;
}
u32FlagCtrl = TMU_TF_CTRL_TF_150F_IE(pInitCfg->bTemperatureOver150IntEn) |
TMU_TF_CTRL_TF_125F_IE(pInitCfg->bTemperatureOver125IntEn) |
TMU_TF_CTRL_TF_RDYF_IE(pInitCfg->bFlagTempReadyIntEn) |
TMU_TF_CTRL_TF_HYSOFF(pInitCfg->eFlagTempHysteresisCon) |
TMU_TF_CTRL_TF_START_CNT(u8FlagStartupCnt) |
TMU_TF_CTRL_TF_FILT_BYP(pInitCfg->eFlagTempFilterBypassCon);
TMU_HWA_SetFlagTempCtrl(pTmu, u32FlagCtrl);
u32VoltageCtrl = TMU_TV_CTRL_TV_RDYF_IE(pInitCfg->bVoltageTempReadyIntEn) |
TMU_TV_CTRL_TV_START_CNT(u8VoltageStartupCnt);
TMU_HWA_SetVoltageTempCtrl(pTmu, u32VoltageCtrl);
TMU_HWA_SetStopAck(pInitCfg->bSmicsStopAckEn);
/* interrupt callback function */
s_apTmuOver150Notify = pInitCfg->pTemp150Notify;
s_apTmuOver125Notify = pInitCfg->pTemp125Notify;
s_apTmuFlagReadyNotify = pInitCfg->pFlagReadyNotify;
s_apTmuVoltgeReadyNotify = pInitCfg->pVoltagReadyNotify;
TMU_HWA_SetTemperatureLockStatus(pTmu, TMU_TF_TV_LOCK);
}
/**
* @brief Enable the Flag-based temperature sensor
*
* @return TMU_StatusType TMU_STATUS_SUCCESS when enable successfully, others fail
*/
TMU_StatusType TMU_FlagTempEnable(void)
{
TMU_StatusType eRet;
uint32_t u32TimeOut = 15000000U;
TMU_Type *const pTmu = s_apTmuBase;
TMU_HWA_SetTemperatureLockStatus(pTmu, TMU_TF_TV_UNLOCK);
TMU_HWA_SetFlagTemperatureEnableStatus(pTmu, true);
while ((TMU_HWA_GetFlagTemperatureReady(pTmu) != true) && (u32TimeOut != 0U))
{
u32TimeOut--;
}
if (u32TimeOut != 0U)
{
eRet = TMU_STATUS_SUCCESS;
TMU_HWA_ClearFlagTemperatureReady(pTmu);
}
else
{
eRet = TMU_STATUS_TIMEOUT;
}
TMU_HWA_SetTemperatureLockStatus(pTmu, TMU_TF_TV_LOCK);
return eRet;
}
/**
* @brief Disable the Flag-based temperature sensor
*
* @return TMU_StatusType TMU_STATUS_SUCCESS when disable successfully, others fail
*/
TMU_StatusType TMU_FlagTempDisable(void)
{
TMU_StatusType eRet;
uint32_t u32TimeOut = 15000000U;
TMU_Type *const pTmu = s_apTmuBase;
TMU_HWA_SetTemperatureLockStatus(pTmu, TMU_TF_TV_UNLOCK);
TMU_HWA_SetFlagTemperatureEnableStatus(pTmu, false);
TMU_HWA_ClearFlagTemperatureReady(pTmu);
while ((TMU_HWA_GetFlagTemperatureEnableStatus(pTmu) == true) && (u32TimeOut != 0U))
{
u32TimeOut--;
}
if (u32TimeOut != 0U)
{
eRet = TMU_STATUS_SUCCESS;
}
else
{
eRet = TMU_STATUS_TIMEOUT;
}
TMU_HWA_SetTemperatureLockStatus(pTmu, TMU_TF_TV_LOCK);
return eRet;
}
/**
* @brief Enable the Voltage-based temperature sensor
*
* @return TMU_StatusType TMU_STATUS_SUCCESS when enable successfully, others fail
*/
TMU_StatusType TMU_VoltageTempEnable(void)
{
TMU_StatusType eRet;
uint32_t u32TimeOut = 15000000U;
TMU_Type *const pTmu = s_apTmuBase;
TMU_HWA_SetTemperatureLockStatus(pTmu, TMU_TF_TV_UNLOCK);
TMU_HWA_SetVoltageTemperatureEnableStatus(pTmu, true);
while ((TMU_HWA_GetVoltageTemperatureReady(pTmu) != true) && (u32TimeOut != 0U))
{
u32TimeOut--;
}
if (u32TimeOut != 0U)
{
eRet = TMU_STATUS_SUCCESS;
TMU_HWA_ClearVoltageTemperatureReady(pTmu);
}
else
{
eRet = TMU_STATUS_TIMEOUT;
}
TMU_HWA_SetTemperatureLockStatus(pTmu, TMU_TF_TV_LOCK);
return eRet;
}
/**
* @brief Disable the Voltage-based temperature sensor
*
* @return TMU_StatusType TMU_STATUS_SUCCESS when disable successfully, others fail
*/
TMU_StatusType TMU_VoltageTempDisable(void)
{
TMU_StatusType eRet;
uint32_t u32TimeOut = 15000000U;
TMU_Type *const pTmu = s_apTmuBase;
TMU_HWA_SetTemperatureLockStatus(pTmu, TMU_TF_TV_UNLOCK);
TMU_HWA_SetVoltageTemperatureEnableStatus(pTmu, false);
TMU_HWA_ClearVoltageTemperatureReady(pTmu);
while ((TMU_HWA_GetVoltageTemperatureEnableStatus(pTmu) == true) && (u32TimeOut != 0U))
{
u32TimeOut--;
}
if (u32TimeOut != 0U)
{
eRet = TMU_STATUS_SUCCESS;
}
else
{
eRet = TMU_STATUS_TIMEOUT;
}
TMU_HWA_SetTemperatureLockStatus(pTmu, TMU_TF_TV_LOCK);
return eRet;
}
/**
* @brief Check if cleaning flag is required
*
*/
void TMU_TempOverClear(void)
{
TMU_Type *const pTmu = s_apTmuBase;
if (TMU_HWA_Get150Flag(pTmu))
{
if (!TMU_HWA_Get150Status(pTmu))
{
TMU_HWA_Clear150Flag(pTmu);
}
}
if (TMU_HWA_Get125Flag(pTmu))
{
if (!TMU_HWA_Get125Status(pTmu))
{
TMU_HWA_Clear125Flag(pTmu);
}
}
}
/**
* @brief Get the temperature code from ADC
*
* @return uint32_t the value records the ADC conversion results for voltage-based temperature sensor result in 135 Celsius
*/
uint32_t TMU_GetTcode(void)
{
TMU_Type *const pTmu = s_apTmuBase;
return TMU_HWA_GetTemperatureCode(pTmu);
}
/**
* @brief Get the slope factor
*
* @return uint32_t the value records the slope factor for voltage-based temperature sensor
*/
uint32_t TMU_GetTslope(void)
{
TMU_Type *const pTmu = s_apTmuBase;
return TMU_HWA_GetSlopeFactor(pTmu);
}