/*!
 * @file        bmp561_sysctrl.c
 *
 * @brief       This file provides all the SYSCTRL firmware functions
 *
 * @version     V1.0.0
 *
 * @date        2025-01-01
 *
 * @attention
 *
 *  Copyright (C) 2025 Geehy Semiconductor
 *
 *  You may not use this file except in compliance with the
 *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
 *
 *  The program is only for reference, which is distributed in the hope
 *  that it will be useful and instructional for customers to develop
 *  their software. Unless required by applicable law or agreed to in
 *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
 *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
 *  and limitations under the License.
 */

#include "bmp561_sysctrl.h"

/** @addtogroup Peripherals_Library Standard Peripheral Library
  @{
*/

/** @addtogroup SYSCTRL_Driver SYSCTRL Driver
  @{
*/

/** @addtogroup SYSCTRL_Functions Functions
  @{
*/

/*!
 * @brief     System Control Register unlock.
 *
 * @param     None
 *
 * @retval    None
 *
 * @note      Must write the fixed value to the SYSCTRL_KEY register before operating
 *            System Control module.
 *
 */
void SYSCTRL_Unlock(void)
{
    SYSCTRL->KEY = 0x000087E4;
}

/*!
 * @brief     System Control Register lock.
 *
 * @param     None
 *
 * @retval    None
 *
 * @note      Must be write 1 to the SYSCTRL_KEY's Bit16 after operating System Control module.
 *
 */
void SYSCTRL_Lock(void)
{
    SYSCTRL->KEY_B.KEYST = BIT_SET;
}

/*!
 * @brief     Enable LSI.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void SYSCTRL_EnableLSI(void)
{
    SYSCTRL->LSICLKCR_B.LSICLKEN = BIT_SET;
    /** wait LSI stable */
    while(SYSCTRL->LSICLKCR_B.LSICLKRDY != 1);
}

/*!
 * @brief     Disable LSI.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void SYSCTRL_DisableLSI(void)
{
    SYSCTRL->LSICLKCR_B.LSICLKEN = BIT_RESET;
}

/*!
 * @brief     configures HSI clock divisor.
 *
 * @param     div: specifies the HSI clock divisor.
 *                 This parameter can be one of the following values:
 *                 @arg SYSCTRL_HSI_DIV_1: divisor = 1
 *                 @arg SYSCTRL_HSI_DIV_2: divisor = 2
 *                 @arg SYSCTRL_HSI_DIV_4: divisor = 4
 *                 @arg SYSCTRL_HSI_DIV_8: divisor = 8
 *
 * @retval    None
 *
 */
void SYSCTRL_ConfigHSIDiv(SYSCTRL_HSI_DIV_T div)
{
    /** set HSI frequency divisor */
    SYSCTRL->HSICLKCR_B.HSICLKDIV = div;
    /** wait HSI stable */
    while(SYSCTRL->HSICLKCR_B.HSICLKRDY != 1);
}

/*!
 * @brief     configures system clock.
 *
 * @param     sysClkDiv: specifies the system clock divisor.
 *                       This parameter can be one of the following values:
 *                       @arg SYSCTRL_SYSCLK_DIV_1  : divisor = 1
 *                       @arg SYSCTRL_SYSCLK_DIV_2  : divisor = 2
 *                       @arg SYSCTRL_SYSCLK_DIV_4  : divisor = 4
 *                       @arg SYSCTRL_SYSCLK_DIV_8  : divisor = 8
 *                       @arg SYSCTRL_SYSCLK_DIV_16 : divisor = 16
 *                       @arg SYSCTRL_SYSCLK_DIV_32 : divisor = 32
 *                       @arg SYSCTRL_SYSCLK_DIV_64 : divisor = 64
 *                       @arg SYSCTRL_SYSCLK_DIV_128: divisor = 128
 *
 * @param     APBClkDiv: specifies the APB clock divisor.
 *                       This parameter can be one of the following values:
 *                       @arg SYSCTRL_APBCLK_DIV_1  : divisor = 1
 *                       @arg SYSCTRL_APBCLK_DIV_2  : divisor = 2
 *                       @arg SYSCTRL_APBCLK_DIV_4  : divisor = 4
 *                       @arg SYSCTRL_APBCLK_DIV_8  : divisor = 8
 *
 * @retval    None
 *
 */
void SYSCTRL_ConfigSystemClock(SYSCTRL_SYSCLK_DIV_T sysClkDiv, SYSCTRL_APBCLK_DIV_T APBClkDiv)
{
    SYSCTRL->SCCR_B.SYSCLKDIV = sysClkDiv;
    SYSCTRL->SCCR_B.APBCLKDIV = APBClkDiv;
}

/*!
 * @brief     Enables AHB Bus' peripheral module clock.
 *
 * @param     AHBPeriph: specifies the AHB peripheral.
 *                       This parameter can be one of the following values:
 *                       @arg SYSCTRL_AHB_FLASH  : FLASH clock
 *                       @arg SYSCTRL_AHB_GPIO   : GPIO clock
 *                       @arg SYSCTRL_AHB_AHB2APB: AHB2APB clock
 *                       @arg SYSCTRL_AHB_ROM    : ROM clock
 *
 * @retval    None
 *
 */
void SYSCTRL_EnableAHBPeriphClock(SYSCTRL_AHB_T AHBPeriph)
{
    SYSCTRL->AHBBCG |= AHBPeriph;
}

/*!
 * @brief     Disables AHB Bus' peripheral module clock.
 *
 * @param     AHBPeriph: specifies the AHB peripheral.
 *                       This parameter can be one of the following values:
 *                       @arg SYSCTRL_AHB_FLASH  : FLASH clock
 *                       @arg SYSCTRL_AHB_GPIO   : GPIO clock
 *                       @arg SYSCTRL_AHB_AHB2APB: AHB2APB clock
 *                       @arg SYSCTRL_AHB_ROM    : ROM clock
 *
 * @retval    None
 *
 */
void SYSCTRL_DisableAHBPeriphClock(SYSCTRL_AHB_T AHBPeriph)
{
    SYSCTRL->AHBBCG &= ~AHBPeriph;
}

/*!
 * @brief     Enables APB Bus' peripheral module BCG clock.
 *
 * @param     APBPeriph: specifies the APB peripheral.
 *                       This parameter can be one of the following values:
 *                       @arg SYSCTRL_APB_WWDT: WWDT clock
 *                       @arg SYSCTRL_APB_I2C : I2C clock
 *                       @arg SYSCTRL_APB_HSC : HSC clock
 *                       @arg SYSCTRL_APB_TMR0: TIMER0 clock
 *                       @arg SYSCTRL_APB_TMR1: TIMER1 clock
 *                       @arg SYSCTRL_APB_CADC: CADC clock
 *                       @arg SYSCTRL_APB_VADC: VADC clock
 *                       @arg SYSCTRL_APB_UART: UART clock
 *                       @arg SYSCTRL_APB_HMAC: HMAC/SHA256 clock
 *                       @arg SYSCTRL_APB_IWDT: IWDT clock
 *                       @arg SYSCTRL_APB_WUPT: WUPT clock
 *                       @arg SYSCTRL_APB_EXTI: EXTI clock
 *
 * @retval    None
 *
 */
void SYSCTRL_EnableAPBPeriphBCGClock(SYSCTRL_APB_T APBPeriph)
{
    SYSCTRL->APBBCG |= APBPeriph;
}

/*!
 * @brief     Disables APB Bus' peripheral module BCG clock.
 *
 * @param     APBPeriph: specifies the APB peripheral.
 *                       This parameter can be one of the following values:
 *                       @arg SYSCTRL_APB_WWDT: WWDT clock
 *                       @arg SYSCTRL_APB_I2C : I2C clock
 *                       @arg SYSCTRL_APB_HSC : HSC clock
 *                       @arg SYSCTRL_APB_TMR0: TIMER0 clock
 *                       @arg SYSCTRL_APB_TMR1: TIMER1 clock
 *                       @arg SYSCTRL_APB_CADC: CADC clock
 *                       @arg SYSCTRL_APB_VADC: VADC clock
 *                       @arg SYSCTRL_APB_UART: UART clock
 *                       @arg SYSCTRL_APB_HMAC: HMAC/SHA256 clock
 *                       @arg SYSCTRL_APB_IWDT: IWDT clock
 *                       @arg SYSCTRL_APB_WUPT: WUPT clock
 *                       @arg SYSCTRL_APB_EXTI: EXTI clock
 *
 * @retval    None
 *
 */
void SYSCTRL_DisableAPBPeriphBCGClock(SYSCTRL_APB_T APBPeriph)
{
    SYSCTRL->APBBCG &= ~APBPeriph;
}

/*!
 * @brief     Enables APB Bus' peripheral module WCG clock.
 *
 * @param     APBPeriph: specifies the APB peripheral.
 *                       This parameter can be one of the following values:
 *                       @arg SYSCTRL_APB_WWDT: WWDT clock
 *                       @arg SYSCTRL_APB_I2C : I2C clock
 *                       @arg SYSCTRL_APB_HSC : HSC clock
 *                       @arg SYSCTRL_APB_TMR0: TIMER0 clock
 *                       @arg SYSCTRL_APB_TMR1: TIMER1 clock
 *                       @arg SYSCTRL_APB_CADC: CADC clock
 *                       @arg SYSCTRL_APB_VADC: VADC clock
 *                       @arg SYSCTRL_APB_UART: UART clock
 *                       @arg SYSCTRL_APB_HMAC: HMAC/SHA256 clock
 *                       @arg SYSCTRL_APB_IWDT: IWDT clock
 *                       @arg SYSCTRL_APB_WUPT: WUPT clock
 *                       @arg SYSCTRL_APB_EXTI: EXTI clock
 *
 * @retval    None
 *
 */
void SYSCTRL_EnableAPBPeriphWCGClock(SYSCTRL_APB_T APBPeriph)
{
    SYSCTRL->APBWCG |= APBPeriph;
}

/*!
 * @brief     Disables APB Bus' peripheral module WCG clock.
 *
 * @param     APBPeriph: specifies the APB peripheral.
 *                       This parameter can be one of the following values:
 *                       @arg SYSCTRL_APB_WWDT: WWDT clock
 *                       @arg SYSCTRL_APB_I2C : I2C clock
 *                       @arg SYSCTRL_APB_HSC : HSC clock
 *                       @arg SYSCTRL_APB_TMR0: TIMER0 clock
 *                       @arg SYSCTRL_APB_TMR1: TIMER1 clock
 *                       @arg SYSCTRL_APB_CADC: CADC clock
 *                       @arg SYSCTRL_APB_VADC: VADC clock
 *                       @arg SYSCTRL_APB_UART: UART clock
 *                       @arg SYSCTRL_APB_HMAC: HMAC/SHA256 clock
 *                       @arg SYSCTRL_APB_IWDT: IWDT clock
 *                       @arg SYSCTRL_APB_WUPT: WUPT clock
 *                       @arg SYSCTRL_APB_EXTI: EXTI clock
 *
 * @retval    None
 *
 */
void SYSCTRL_DisableAPBPeriphWCGClock(SYSCTRL_APB_T APBPeriph)
{
    SYSCTRL->APBWCG &= ~APBPeriph;
}

/*!
 * @brief     Enables AHB Bus' peripheral module clock.
 *
 * @param     AHBPeriph: specifies the AHB peripheral.
 *                       This parameter can be one of the following values:
 *                       @arg SYSCTRL_AHB_FLASH  : FLASH clock
 *                       @arg SYSCTRL_AHB_GPIO   : GPIO clock
 *
 * @retval    None
 *
 * @note      Default status is 1, write 0 to corresponding bit will reset this module.
 *
 */
void SYSCTRL_EnableAHBPeriphReset(SYSCTRL_AHB_T AHBPeriph)
{
    SYSCTRL->AHBRSTCR &= ~AHBPeriph;
}

/*!
 * @brief     Disables AHB Bus' peripheral module clock.
 *
 * @param     AHBPeriph: specifies the AHB peripheral.
 *                       This parameter can be one of the following values:
 *                       @arg SYSCTRL_AHB_FLASH  : FLASH clock
 *                       @arg SYSCTRL_AHB_GPIO   : GPIO clock
 *
 * @retval    None
 *
 * @note      Default status is 1, write 0 to corresponding bit will reset this module.
 *
 */
void SYSCTRL_DisableAHBPeriphReset(SYSCTRL_AHB_T AHBPeriph)
{
    SYSCTRL->AHBRSTCR |= AHBPeriph;
}

/*!
 * @brief     Enables APB Bus' peripheral module clock.
 *
 * @param     APBPeriph: specifies the APB peripheral.
 *                       This parameter can be one of the following values:
 *                       @arg SYSCTRL_APB_WWDT: WWDT clock
 *                       @arg SYSCTRL_APB_I2C : I2C clock
 *                       @arg SYSCTRL_APB_HSC : HSC clock
 *                       @arg SYSCTRL_APB_TMR0: TIMER0 clock
 *                       @arg SYSCTRL_APB_TMR1: TIMER1 clock
 *                       @arg SYSCTRL_APB_CADC: CADC clock
 *                       @arg SYSCTRL_APB_VADC: VADC clock
 *                       @arg SYSCTRL_APB_UART: UART clock
 *                       @arg SYSCTRL_APB_HMAC: HMAC/SHA256 clock
 *                       @arg SYSCTRL_APB_IWDT: IWDT clock
 *                       @arg SYSCTRL_APB_WUPT: WUPT clock
 *                       @arg SYSCTRL_APB_EXTI: EXTI clock
 *
 * @retval    None
 *
 * @note      Default status is 1, write 0 to corresponding bit will reset this module.
 *
 */
void SYSCTRL_EnableAPBPeriphReset(SYSCTRL_APB_T APBPeriph)
{
    SYSCTRL->APBRSTCR &= ~APBPeriph;
}

/*!
 * @brief     Disables APB Bus' peripheral module clock.
 *
 * @param     APBPeriph: specifies the APB peripheral.
 *                       This parameter can be one of the following values:
 *                       @arg SYSCTRL_APB_WWDT: WWDT clock
 *                       @arg SYSCTRL_APB_I2C : I2C clock
 *                       @arg SYSCTRL_APB_HSC : HSC clock
 *                       @arg SYSCTRL_APB_TMR0: TIMER0 clock
 *                       @arg SYSCTRL_APB_TMR1: TIMER1 clock
 *                       @arg SYSCTRL_APB_CADC: CADC clock
 *                       @arg SYSCTRL_APB_VADC: VADC clock
 *                       @arg SYSCTRL_APB_UART: UART clock
 *                       @arg SYSCTRL_APB_HMAC: HMAC/SHA256 clock
 *                       @arg SYSCTRL_APB_IWDT: IWDT clock
 *                       @arg SYSCTRL_APB_WUPT: WUPT clock
 *                       @arg SYSCTRL_APB_EXTI: EXTI clock
 *
 * @retval    None
 *
 * @note      Default status is 1, write 0 to corresponding bit will reset this module.
 *
 */
void SYSCTRL_DisableAPBPeriphReset(SYSCTRL_APB_T APBPeriph)
{
    SYSCTRL->APBRSTCR |= APBPeriph;
}

/*!
 * @brief     Reads the specified SYSCTRL reset flag.
 *
 * @param     flag: specifies the SYSCTRL reset flag.
 *                  This parameter can be one of the following values:
 *                  @arg SYSCTRL_RST_WWDT: WWDT reset flag
 *                  @arg SYSCTRL_RST_IWDT: IWDT reset flag
 *                  @arg SYSCTRL_RST_SYS : SYSRSTREQ reset flag
 *                  @arg SYSCTRL_RST_OPL : Option byte load reset flag
 *                  @arg SYSCTRL_RST_LP  : Hibernate low power reset flag
 *                  @arg SYSCTRL_RST_POR : Power on/off reset flag
 *
 * @retval    The new state of flag(SET or RESET).
 *
 */
uint8_t SYSCTRL_ReadResetFlag(SYSCTRL_RST_FLAG_T flag)
{
    uint8_t status = RESET;

    if((SYSCTRL->RSTSR & flag) != (uint32_t)RESET)
    {
        status = SET;
    }
    else
    {
        status = RESET;
    }
    return status;
}

/*!
 * @brief     Clears the specified SYSCTRL reset flag.
 *
 * @param     flag: specifies the SYSCTRL reset flag.
 *                  This parameter can be one of the following values:
 *                  @arg SYSCTRL_RST_WWDT: WWDT reset flag
 *                  @arg SYSCTRL_RST_IWDT: IWDT reset flag
 *                  @arg SYSCTRL_RST_SYS : SYSRSTREQ reset flag
 *                  @arg SYSCTRL_RST_OPL : Optional byte load reset flag
 *                  @arg SYSCTRL_RST_LP  : Hibernate low power reset flag
 *                  @arg SYSCTRL_RST_POR : Power on/off reset flag
 *
 * @retval    None
 *
 */
void SYSCTRL_ClearResetFlag(SYSCTRL_RST_FLAG_T flag)
{
    SYSCTRL->RSTSRCLR |= flag;
}

/*!
 * @brief     Configures low power according to the specified parameters in the lowPowerConfig.
 *
 * @param     lowPowerConfig: pointer to SYSCTRL low power mode structure.
 *
 * @retval    None
 *
 */
void SYSCTRL_ConfigLowPower(SYSCTRL_LowPowerConfig_T* lowPowerConfig)
{
    SYSCTRL->LPMCR_B.LPM = lowPowerConfig->mode;
    SYSCTRL->LPCR_B.LDO_LP = lowPowerConfig->ldoEn;
    SYSCTRL->LPCR_B.HSI_LPSEL = lowPowerConfig->hsiMode;
    SYSCTRL->LPCR_B.WAITLDO = lowPowerConfig->waitCycle;
}

/*!
 * @brief     Fills each SYSCTRL_LowPowerConfig_T member with its default value.
 *
 * @param     lowPowerConfig: pointer to SYSCTRL low power mode structure which will be initialized.
 *
 * @retval    None
 *
 */
void SYSCTRL_ConfigLowPowerStructInit(SYSCTRL_LowPowerConfig_T* lowPowerConfig)
{
    lowPowerConfig->mode = SYSCTRL_LP_WAIT;
    lowPowerConfig->ldoEn = DISABLE;
    lowPowerConfig->hsiMode = SYSCTRL_LP_HSI_1P4MHZ;
    lowPowerConfig->waitCycle = 0;
}

/*!
 * @brief     configures low power mode.
 *
 * @param     mode: specifies the system clock divisor.
 *                       This parameter can be one of the following values:
 *                       @arg SYSCTRL_LP_WAIT     : Wait mode
 *                       @arg SYSCTRL_LP_SLEEP    : Sleep mode
 *                       @arg SYSCTRL_LP_DPSLEEP  : Deep sleep mode
 *                       @arg SYSCTRL_LP_HIBERNATE: Hibernate mode
 *
 * @retval    None
 *
 */
void SYSCTRL_ConfigLowPowerMode(SYSCTRL_LP_T mode)
{
    SYSCTRL->LPMCR_B.LPM = mode;
}

/*!
 * @brief     Enables LDO low power in wait, sleep or deep sleep mode.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void SYSCTRL_EnableLDOLowPower(void)
{
    SYSCTRL->LPCR_B.LDO_LP = BIT_SET;
}

/*!
 * @brief     Disables LDO low power in wait, sleep or deep sleep mode.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void SYSCTRL_DisableLDOLowPower(void)
{
    SYSCTRL->LPCR_B.LDO_LP = BIT_RESET;
}

/*!
 * @brief     Configures HSI low power in deep sleep mode.
 *
 * @param     mode: specifies HSI low power in deep sleep mode.
 *                  This parameter can be one of the following values:
 *                  @arg SYSCTRL_LP_HSI_1P4MHZ: Secondary low power, almost 1.4MHz
 *                  @arg SYSCTRL_LP_HSI_700KHZ: Super low power, almost 700KHz
 *
 * @retval    None
 *
 */
void SYSCTRL_ConfigHSILowPower(SYSCTRL_LP_HSI_T mode)
{
    SYSCTRL->LPCR_B.HSI_LPSEL = mode;
}

/*!
 * @brief     Configures LDO wait cycle for waiting LDO stable after exiting from sleep or deep sleep mode.
 *
 * @param     waitCycle: specifies LDO wait cycle.
 *                       This parameter can be configured from 0 to 0x3F.
 *
 * @retval    None
 *
 * @note      Cycle = waitCycle + 1
 *
 */
void SYSCTRL_ConfigLDOWaitCycle(uint8_t waitCycle)
{
    SYSCTRL->LPCR_B.WAITLDO = waitCycle;
}

/*!
 * @brief     Enter low power mode.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void SYSCTRL_EnterLowPowerMode(void)
{
		SYSCTRL->LPCR |=(0xA5A50000 | 0x100);
}

/*!
 * @brief     Configures STA according to the specified parameters in the startConfig.
 *
 * @param     startConfig: pointer to SYSCTRL STA structure.
 *
 * @retval    None
 *
 */
void SYSCTRL_ConfigStart(SYSCTRL_StartConfig_T* startConfig)
{
    SYSCTRL->STA_B.WUPEN = startConfig->wakeUpEn;
    SYSCTRL->STA_B.AUTO = startConfig->autoMode;
    SYSCTRL->STA_B.WUPIE = startConfig->wakeUpInt;
    SYSCTRL->STA_B.COMM_MODE = startConfig->commMode;
}

/*!
 * @brief     Fills each SYSCTRL_StartConfig_T member with its default value.
 *
 * @param     startConfig: pointer to SYSCTRL STA structure which will be initialized.
 *
 * @retval    None
 *
 */
void SYSCTRL_ConfigStartStructInit(SYSCTRL_StartConfig_T* startConfig)
{
    startConfig->wakeUpEn = DISABLE;
    startConfig->autoMode = SYSCTRL_STA_AUTO_MODE_AUTO;
    startConfig->wakeUpInt = DISABLE;
    startConfig->commMode = SYSCTRL_STA_COMM_MODE_I2C;
}

/*!
 * @brief     Enables I2C start signal or HSC-BREAK detected.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void SYSCTRL_EnableStartWakeUp(void)
{
    SYSCTRL->STA_B.WUPEN = BIT_SET;
}

/*!
 * @brief     Disables I2C start signal or HSC-BREAK detected.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void SYSCTRL_DisableStartWakeUp(void)
{
    SYSCTRL->STA_B.WUPEN = BIT_RESET;
}

/*!
 * @brief     Configures STA auto mode.
 *
 * @param     mode: specifies STA auto mode.
 *                  This parameter can be one of the following values:
 *                  @arg SYSCTRL_STA_AUTO_MODE_AUTO  : Auto mode
 *                  @arg SYSCTRL_STA_AUTO_MODE_MANUAL: Manual mode
 *
 * @retval    None
 *
 */
void SYSCTRL_ConfigStartAutoMode(SYSCTRL_STA_AUTO_MODE_T mode)
{
    SYSCTRL->STA_B.AUTO = mode;
}

/*!
 * @brief     Enables STA I2C start signal or HSC-BREAK detected interrupt.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void SYSCTRL_EnableStartWakeUpInterrupt(void)
{
    SYSCTRL->STA_B.WUPIE = BIT_SET;
}

/*!
 * @brief     Disables STA I2C start signal or HSC-BREAK detected interrupt.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void SYSCTRL_DisableStartWakeUpInterrupt(void)
{
    SYSCTRL->STA_B.WUPIE = BIT_RESET;
}

/*!
 * @brief     Configures STA communication mode.
 *
 * @param     mode: specifies STA communication mode.
 *                  This parameter can be one of the following values:
 *                  @arg SYSCTRL_STA_COMM_MODE_HSC: HSC mode
 *                  @arg SYSCTRL_STA_COMM_MODE_I2C: I2C mode
 *
 * @retval    None
 *
 */
void SYSCTRL_ConfigStartcommunicationMode(SYSCTRL_STA_COMM_MODE_T mode)
{
    SYSCTRL->STA_B.COMM_MODE = mode;
}

/*!
 * @brief     Reads the SYSCTRL STA flag.
 *
 * @param     None
 *
 * @retval    The STA flag.
 *
 */
uint8_t SYSCTRL_ReadStartFlag(void)
{
    return SYSCTRL->STA_B.FLAG;
}


/*!
 * @brief     Clears the SYSCTRL STA flag.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void SYSCTRL_ClearStartFlag(void)
{
    SYSCTRL->STACLR_B.STA_FLAGCLR = BIT_SET;
}

/*!
 * @brief     Reads the peripheral module's whether or not occurs interrupt wake up flag.
 *
 * @param     flag: specifies the wake up flag.
 *                  This parameter can be one of the following values:
 *                  @arg SYSCTRL_WU_I2C  : I2C wake up flag
 *                  @arg SYSCTRL_WU_HSC  : HSC wake up flag
 *                  @arg SYSCTRL_WU_UART : UART wake up flag
 *                  @arg SYSCTRL_WU_IWDT : IWDT wake up flag
 *                  @arg SYSCTRL_WU_TMR0 : TMR0 wake up flag
 *                  @arg SYSCTRL_WU_TMR1 : TMR1 wake up flag
 *                  @arg SYSCTRL_WU_ADC0 : ADC0 wake up flag
 *                  @arg SYSCTRL_WU_ADC1 : ADC1 wake up flag
 *                  @arg SYSCTRL_WU_FLASH: FLASH wake up flag
 *                  @arg SYSCTRL_WU_WUPT : WUPT wake up flag
 *                  @arg SYSCTRL_WU_STA  : STA wake up flag
 *                  @arg SYSCTRL_WU_EXTI0: EXTI0 wake up flag
 *                  @arg SYSCTRL_WU_EXTI1: EXTI1 wake up flag
 *                  @arg SYSCTRL_WU_EXTI2: EXTI2 wake up flag
 *                  @arg SYSCTRL_WU_HMAC : HMAC/SHA256 wake up flag
 *
 * @retval    The wake up flag.
 *
 */
uint8_t SYSCTRL_ReadWakeUpFlag(SYSCTRL_WU_T flag)
{
    uint8_t status = RESET;

    if((SYSCTRL->WUSR & flag) != (uint32_t)RESET)
    {
        status = SET;
    }
    else
    {
        status = RESET;
    }
    return status;
}

/*!
 * @brief     Clears the SYSCTRL wake up flag.
 *
 * @param     flag: specifies the wake up flag.
 *                  This parameter can be one of the following values:
 *                  @arg SYSCTRL_WU_I2C  : I2C wake up flag
 *                  @arg SYSCTRL_WU_HSC  : HSC wake up flag
 *                  @arg SYSCTRL_WU_UART : UART wake up flag
 *                  @arg SYSCTRL_WU_IWDT : IWDT wake up flag
 *                  @arg SYSCTRL_WU_TMR0 : TMR0 wake up flag
 *                  @arg SYSCTRL_WU_TMR1 : TMR1 wake up flag
 *                  @arg SYSCTRL_WU_ADC0 : ADC0 wake up flag
 *                  @arg SYSCTRL_WU_ADC1 : ADC1 wake up flag
 *                  @arg SYSCTRL_WU_FLASH: FLASH wake up flag
 *                  @arg SYSCTRL_WU_WUPT : WUPT wake up flag
 *                  @arg SYSCTRL_WU_STA  : STA wake up flag
 *
 * @retval    None
 *
 */
void SYSCTRL_ClearWakeUpFlag(SYSCTRL_WU_T flag)
{
    SYSCTRL->WUSRCLR |= flag;
}

/*!
 * @brief     Configures ANA according to the specified parameters in the analogConfig.
 *
 * @param     analogConfig: pointer to SYSCTRL ANA structure.
 *
 * @retval    None
 *
 */
void SYSCTRL_ConfigAnalog(SYSCTRL_AnalogConfig_T* analogConfig)
{
    SYSCTRL->ANACR_B.NTCRPUEN = analogConfig->ntcPullUp;
    SYSCTRL->ANACR_B.TSEN = analogConfig->tsEn;
    SYSCTRL->ANACR_B.LVDISEL = analogConfig->lvdiSel;
    SYSCTRL->ANACR_B.SYSLVDVSEL = analogConfig->lvdvSel;
    SYSCTRL->ANACR_B.SYSLVDEN = analogConfig->lvdEn;
    SYSCTRL->ANACR_B.VADCMUXSEL = analogConfig->vadcMuxSel;
    SYSCTRL->ANACR_B.AFECLKEN = analogConfig->afeClkEn;
    SYSCTRL->ANACR_B.AFEEN = analogConfig->afeEn;
}

/*!
 * @brief     Fills each SYSCTRL_AnalogConfig_T member with its default value.
 *
 * @param     analogConfig: pointer to SYSCTRL ANA structure which will be initialized.
 *
 * @retval    None
 *
 */
void SYSCTRL_ConfigAnalogStructInit(SYSCTRL_AnalogConfig_T* analogConfig)
{
    analogConfig->ntcPullUp = DISABLE;
    analogConfig->tsEn = DISABLE;
    analogConfig->lvdiSel = SYSCTRL_ANA_LVDI_0P08UA;
    analogConfig->lvdvSel = SYSCTRL_ANA_LVDV_1P8V;
    analogConfig->lvdEn = DISABLE;
    analogConfig->vadcMuxSel = SYSCTRL_ANA_VADCMUX_BAT_5P0;
    analogConfig->afeClkEn = DISABLE;
    analogConfig->afeEn = DISABLE;
}

/*!
 * @brief     Enables NTC pull up resistor.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void SYSCTRL_EnableNTCPullUpResistor(void)
{
    SYSCTRL->ANACR_B.NTCRPUEN = BIT_SET;
}

/*!
 * @brief     Disables NTC pull up resistor.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void SYSCTRL_DisableNTCPullUpResistor(void)
{
    SYSCTRL->ANACR_B.NTCRPUEN = BIT_RESET;
}

/*!
 * @brief     Enables TS internal.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void SYSCTRL_EnableTS(void)
{
    SYSCTRL->ANACR_B.TSEN = BIT_SET;
}

/*!
 * @brief     Disables TS internal.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void SYSCTRL_DisableTS(void)
{
    SYSCTRL->ANACR_B.TSEN = BIT_RESET;
}

/*!
 * @brief     Configures LVDI.
 *
 * @param     mode: specifies the LVDI.
 *                  This parameter can be one of the following values:
 *                  @arg SYSCTRL_ANA_LVDI_0P08UA: 0.08uA
 *                  @arg SYSCTRL_ANA_LVDI_0P72UA: 0.72uA
 *                  @arg SYSCTRL_ANA_LVDI_5UA   : 5uA
 *                  @arg SYSCTRL_ANA_LVDI_45UA  : 45uA
 *
 * @retval    None
 *
 */
void SYSCTRL_ConfigLVDI(SYSCTRL_ANA_LVDI_T mode)
{
    SYSCTRL->ANACR_B.LVDISEL = mode;
}

/*!
 * @brief     Configures LVDV.
 *
 * @param     mode: specifies the LVDV.
 *                  This parameter can be one of the following values:
 *                  @arg SYSCTRL_ANA_LVDV_1P8V: 1.8V
 *                  @arg SYSCTRL_ANA_LVDV_1P9V: 1.9V
 *                  @arg SYSCTRL_ANA_LVDV_2P0V: 2.0V
 *                  @arg SYSCTRL_ANA_LVDV_2P1V: 2.1V
 *                  @arg SYSCTRL_ANA_LVDV_2P2V: 2.2V
 *                  @arg SYSCTRL_ANA_LVDV_2P3V: 2.3V
 *                  @arg SYSCTRL_ANA_LVDV_2P4V: 2.4V
 *                  @arg SYSCTRL_ANA_LVDV_2P5V: 2.5V
 *                  @arg SYSCTRL_ANA_LVDV_2P6V: 2.6V
 *                  @arg SYSCTRL_ANA_LVDV_2P7V: 2.7V
 *                  @arg SYSCTRL_ANA_LVDV_2P8V: 2.8V
 *                  @arg SYSCTRL_ANA_LVDV_2P9V: 2.9V
 *                  @arg SYSCTRL_ANA_LVDV_3P0V: 3.0V
 *                  @arg SYSCTRL_ANA_LVDV_3P1V: 3.1V
 *                  @arg SYSCTRL_ANA_LVDV_3P2V: 3.2V
 *                  @arg SYSCTRL_ANA_LVDV_3P3V: 3.3V
 *
 * @retval    None
 *
 */
void SYSCTRL_ConfigLVDV(SYSCTRL_ANA_LVDV_T mode)
{
    SYSCTRL->ANACR_B.SYSLVDVSEL = mode;
}

/*!
 * @brief     Enables LVD in SYSCTRL peripheral.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void SYSCTRL_EnableLVD(void)
{
    SYSCTRL->ANACR_B.SYSLVDEN = BIT_SET;
}

/*!
 * @brief     Disables LVD in SYSCTRL peripheral.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void SYSCTRL_DisableLVD(void)
{
    SYSCTRL->ANACR_B.SYSLVDEN = BIT_RESET;
}

/*!
 * @brief     Configures VADC MUX.
 *
 * @param     channel: specifies the VADC MUX.
 *                     This parameter can be one of the following values:
 *                     @arg SYSCTRL_ANA_VADCMUX_BAT_5P0    : mux_bat_5p0
 *                     @arg SYSCTRL_ANA_VADCMUX_BAT_SNS_5P0: mux_bat_sns_5p0
 *                     @arg SYSCTRL_ANA_VADCMUX_NTC_5P0    : mux_ntc_5p0
 *                     @arg SYSCTRL_ANA_VADCMUX_IPAT_5P0   : mux_ipat_5p0
 *                     @arg SYSCTRL_ANA_VADCMUX_VSS_5P0    : mux_vss_5p0
 *                     @arg SYSCTRL_ANA_VADCMUX_DVDD1P5    : dvdd1p5
 *
 * @retval    None
 *
 */
void SYSCTRL_ConfigVADCMUX(SYSCTRL_ANA_VADCMUX_T channel)
{
    SYSCTRL->ANACR_B.VADCMUXSEL = channel;
}

/*!
 * @brief     Enables AFE clock for CADC and VADC.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void SYSCTRL_EnableAFEClock(void)
{
    SYSCTRL->ANACR_B.AFECLKEN = BIT_SET;
}

/*!
 * @brief     Disables AFE clock for CADC and VADC.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void SYSCTRL_DisableAFEClock(void)
{
    SYSCTRL->ANACR_B.AFECLKEN = BIT_RESET;
}

/*!
 * @brief     Enables AFE for CADC, VADC and NTC.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void SYSCTRL_EnableAFE(void)
{
    SYSCTRL->ANACR_B.AFEEN = BIT_SET;
}

/*!
 * @brief     Disables AFE for CADC, VADC and NTC.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void SYSCTRL_DisableAFE(void)
{
    SYSCTRL->ANACR_B.AFEEN = BIT_RESET;
}

/*!
 * @brief     Enables debug signal.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void SYSCTRL_EnableDebug(void)
{
    SYSCTRL->DEBUGCR_B.SYSDEBUGEN = BIT_SET;
}

/*!
 * @brief     Disables debug signal.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void SYSCTRL_DisableDebug(void)
{
    SYSCTRL->DEBUGCR_B.SYSDEBUGEN = BIT_RESET;
}

/*!
 * @brief     Configures debug signal output.
 *
 * @param     output: specifies debug signal output.
 *                    This parameter can be one of the following values:
 *                    @arg SYSCTRL_DEBUG_OUT_HSI: HSI clock
 *                    @arg SYSCTRL_DEBUG_OUT_LSI: LSI clock
 *
 * @retval    None
 *
 */
void SYSCTRL_ConfigDebugOutput(SYSCTRL_DEBUG_OUT_T output)
{
    SYSCTRL->DEBUGCR_B.SYSDEBUGSEL = output;
}

/*!
 * @brief     Enables PAD2 and PAD3 filter.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void SYSCTRL_EnablePadFilter(void)
{
    SYSCTRL->DEBUGCR_B.PAD23FILSEL = BIT_SET;
}

/*!
 * @brief     Disables PAD2 and PAD3 filter.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void SYSCTRL_DisablePadFilter(void)
{
    SYSCTRL->DEBUGCR_B.PAD23FILSEL = BIT_RESET;
}

/*!
 * @brief     Configures boot mode.
 *
 * @param     mode: specifies boot mode.
 *                  This parameter can be one of the following values:
 *                  @arg SYSCTRL_BOOT_OPBYTE  : Option byte mode
 *                  @arg SYSCTRL_BOOT_SYSREMAP: SYSREMAP mode
 *
 * @retval    None
 *
 */
void SYSCTRL_ConfigBootMode(SYSCTRL_BOOT_T mode)
{
    SYSCTRL->BOOTCR_B.REMAPSEL = mode;
}

/*!
 * @brief     Configures boot remap when boot mode is SYSREMAP mode.
 *
 * @param     mode: specifies boot mode.
 *                  This parameter can be one of the following values:
 *                  @arg SYSCTRL_BOOT_REMAP_FLASH: Remap to FLASH
 *                  @arg SYSCTRL_BOOT_REMAP_ROM  : Remap to ROM
 *                  @arg SYSCTRL_BOOT_REMAP_RAM  : Remap to RAM
 *                  @arg SYSCTRL_BOOT_REMAP_ROM1 : Remap to ROM1
 *
 * @retval    None
 *
 */
void SYSCTRL_ConfigBootRemap(SYSCTRL_BOOT_REMAP_T remap)
{
    SYSCTRL->BOOTCR_B.SYSREMAP = remap;
}

/*!
 * @brief     Enables ADFT.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void SYSCTRL_EnableADFT(void)
{
    SYSCTRL->ADFT_B.ADFTEN = BIT_SET;
}

/*!
 * @brief     Disables ADFT.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void SYSCTRL_DisableADFT(void)
{
    SYSCTRL->ADFT_B.ADFTEN = BIT_RESET;
}

/*!
 * @brief     Configures ADFT decoder input signal.
 *
 * @param     decoder: specifies ADFT decoder input signal.
 *                     This parameter can be one of the following values:
 *                     @arg SYSCTRL_ADFT_DECODE_SEL0 : signal 0
 *                     @arg SYSCTRL_ADFT_DECODE_SEL1 : signal 1
 *                     @arg SYSCTRL_ADFT_DECODE_SEL2 : signal 2
 *                     @arg SYSCTRL_ADFT_DECODE_SEL3 : signal 3
 *                     @arg SYSCTRL_ADFT_DECODE_SEL4 : signal 4
 *                     @arg SYSCTRL_ADFT_DECODE_SEL5 : signal 5
 *                     @arg SYSCTRL_ADFT_DECODE_SEL6 : signal 6
 *                     @arg SYSCTRL_ADFT_DECODE_SEL7 : signal 7
 *                     @arg SYSCTRL_ADFT_DECODE_SEL8 : signal 8
 *                     @arg SYSCTRL_ADFT_DECODE_SEL9 : signal 9
 *                     @arg SYSCTRL_ADFT_DECODE_SEL10: signal 10
 *
 * @retval    None
 *
 */
void SYSCTRL_ConfigADFTDecoder(SYSCTRL_ADFT_DECODE_T decoder)
{
    SYSCTRL->ADFT_B.ADFTDECCODE = decoder;
}

/*!
 * @brief     Configures LTBG trim value.
 *
 * @param     tTrim: specifies PMU LTBG Ttrim.
 *                   This parameter can be configured from 0 to 0x1F:
 *
 * @param     vTrim: specifies PMU LTBG Vtrim.
 *                   This parameter can be configured from 0 to 0x1F:
 *
 * @param     resbgTrim: specifies RESBG trim.
 *                   This parameter can be configured from 0 to 0x3F:
 *
 * @param     cadcTrim: specifies CADC-BG trim.
 *                   This parameter can be configured from 0 to 0x7F:
 *
 * @retval    None
 *
 */
void SYSCTRL_ConfigLTBGTrim(uint8_t tTrim, uint8_t vTrim, uint8_t resbgTrim, uint8_t cadcTrim)
{
    SYSCTRL->LTLPBGTR_B.TTRIM = tTrim;
    SYSCTRL->LTLPBGTR_B.VTRIM = vTrim;
    SYSCTRL->LTLPBGTR_B.RESBGTRIM= resbgTrim;
    SYSCTRL->LTLPBGTR_B.SWCAPCADCTRIM = cadcTrim;
}

/*!
 * @brief     Configures OSC trim value.
 *
 * @param     HSITrim: specifies HSI trim.
 *                     This parameter can be configured from 0 to 0xFF:
 *
 * @param     LSITrim: specifies LSI trim.
 *                     This parameter can be configured from 0 to 0x1FF:
 *
 * @retval    None
 *
 */
void SYSCTRL_ConfigOSCTrim(uint8_t HSITrim, uint16_t LSITrim)
{
    SYSCTRL->OSCTR_B.HSIFREQTRIM = HSITrim;
    SYSCTRL->OSCTR_B.LSIFREQTRIM = LSITrim;
}

/*!
 * @brief     Configures NTC TS trim value.
 *
 * @param     ntcTrim: specifies NTC trim.
 *                     This parameter can be configured from 0 to 0x1F:
 *
 * @param     tsTrim: specifies TS trim.
 *                    This parameter can be configured from 0 to 0x3F:
 *
 * @param     ldovTrim: specifies LDO Vtrim.
 *                      This parameter can be configured from 0 to 0x0F:
 *
 * @param     vadcTrim: specifies VADC-BG trim.
 *                      This parameter can be configured from 0 to 0x7F:
 *
 * @retval    None
 *
 */
void SYSCTRL_ConfigNTCTTrim(uint8_t ntcTrim, uint8_t tsTrim, uint8_t ldovTrim, uint8_t vadcTrim)
{
    SYSCTRL->NTCTSTR_B.NTCTRIM = ntcTrim;
    SYSCTRL->NTCTSTR_B.TSTRIM = tsTrim;
    SYSCTRL->NTCTSTR_B.LDOVTRIM = ldovTrim;
    SYSCTRL->NTCTSTR_B.SWCAPVADCTRIM = vadcTrim;
}

/**@} end of group SYSCTRL_Functions*/
/**@} end of group SYSCTRL_Driver*/
/**@} end of group Peripherals_Library*/
