/*!
 * @file        bmp561_sysctrl.h
 *
 * @brief       This file contains all the functions prototypes for the SYSCTRL firmware library
 *
 * @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.
 */

/* Define to prevent recursive inclusion */
#ifndef __BMP561_SYSCTRL_H
#define __BMP561_SYSCTRL_H

#ifdef __cplusplus
  extern "C" {
#endif

#include "bmp561.h"

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

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

/** @addtogroup SYSCTRL_Enumerations Enumerations
  @{
*/

/**
 * @brief   SYSCTRL HSI divisor
 */
typedef enum
{
    SYSCTRL_HSI_DIV_1 = 0x00,    /*!< divisor = 1 */
    SYSCTRL_HSI_DIV_2 = 0x01,    /*!< divisor = 2 */
    SYSCTRL_HSI_DIV_4 = 0x02,    /*!< divisor = 4 */
    SYSCTRL_HSI_DIV_8 = 0x03     /*!< divisor = 8 */
} SYSCTRL_HSI_DIV_T;

/**
 * @brief   SYSCTRL system clock divisor
 */
typedef enum
{
    SYSCTRL_SYSCLK_DIV_1   = 0x00,    /*!< divisor = 1 */
    SYSCTRL_SYSCLK_DIV_2   = 0x01,    /*!< divisor = 2 */
    SYSCTRL_SYSCLK_DIV_4   = 0x02,    /*!< divisor = 4 */
    SYSCTRL_SYSCLK_DIV_8   = 0x03,    /*!< divisor = 8 */
    SYSCTRL_SYSCLK_DIV_16  = 0x04,    /*!< divisor = 16 */
    SYSCTRL_SYSCLK_DIV_32  = 0x05,    /*!< divisor = 32 */
    SYSCTRL_SYSCLK_DIV_64  = 0x06,    /*!< divisor = 64 */
    SYSCTRL_SYSCLK_DIV_128 = 0x07     /*!< divisor = 128 */
} SYSCTRL_SYSCLK_DIV_T;

/**
 * @brief   SYSCTRL APB clock divisor
 */
typedef enum
{
    SYSCTRL_APBCLK_DIV_1 = 0x00,    /*!< divisor = 1 */
    SYSCTRL_APBCLK_DIV_2 = 0x01,    /*!< divisor = 2 */
    SYSCTRL_APBCLK_DIV_4 = 0x02,    /*!< divisor = 4 */
    SYSCTRL_APBCLK_DIV_8 = 0x03     /*!< divisor = 8 */
} SYSCTRL_APBCLK_DIV_T;

/**
 * @brief   SYSCTRL AHB peripheral
 */
typedef enum
{
    SYSCTRL_AHB_FLASH   = 0x01,    /*!< FLASH clock */
    SYSCTRL_AHB_GPIO    = 0x02,    /*!< GPIO clock */
    SYSCTRL_AHB_AHB2APB = 0x04,    /*!< AHB2APB clock */
    SYSCTRL_AHB_ROM     = 0x08     /*!< ROM clock */
} SYSCTRL_AHB_T;

/**
 * @brief   SYSCTRL APB peripheral
 */
typedef enum
{
    SYSCTRL_APB_WWDT = 0x0001,    /*!< WWDT clock */
    SYSCTRL_APB_I2C  = 0x0002,    /*!< I2C clock */
    SYSCTRL_APB_HSC  = 0x0004,    /*!< HSC clock */
    SYSCTRL_APB_TMR0 = 0x0008,    /*!< TIMER0 clock */
    SYSCTRL_APB_TMR1 = 0x0010,    /*!< TIMER1 clock */
    SYSCTRL_APB_CADC = 0x0020,    /*!< ADC0 clock */
    SYSCTRL_APB_VADC = 0x0040,    /*!< ADC1 clock */
    SYSCTRL_APB_UART = 0x0100,    /*!< UART clock */
    SYSCTRL_APB_HMAC = 0x0200,    /*!< HMAC/SHA256 clock */
    SYSCTRL_APB_IWDT = 0x0400,    /*!< IWDT clock */
    SYSCTRL_APB_WUPT = 0x0800,    /*!< WUPT clock */
    SYSCTRL_APB_EINT = 0x1000     /*!< EXTI clock */
} SYSCTRL_APB_T;

/**
 * @brief   SYSCTRL reset flag
 */
typedef enum
{
    SYSCTRL_RST_WWDT = 0x01,    /*!< WWDT reset flag */
    SYSCTRL_RST_IWDT = 0x02,    /*!< IWDT reset flag */
    SYSCTRL_RST_SYS  = 0x04,    /*!< SYSRSTREQ reset flag */
    SYSCTRL_RST_OPL  = 0x08,    /*!< Option byte load reset flag */
    SYSCTRL_RST_LP   = 0x10,    /*!< Hibernate low power reset flag */
    SYSCTRL_RST_POR  = 0x20     /*!< Power on/off reset flag */
} SYSCTRL_RST_FLAG_T;

/**
 * @brief   SYSCTRL low power mode
 */
typedef enum
{
    SYSCTRL_LP_WAIT      = 0x00,    /*!< Wait mode */
    SYSCTRL_LP_SLEEP     = 0x01,    /*!< Sleep mode */
    SYSCTRL_LP_DPSLEEP   = 0x02,    /*!< Deep sleep mode */
    SYSCTRL_LP_HIBERNATE = 0x03     /*!< Hibernate mode */
} SYSCTRL_LP_T;

/**
 * @brief   SYSCTRL low power mode HSI frequency
 */
typedef enum
{
    SYSCTRL_LP_HSI_1P4MHZ = 0x00,    /*!< Secondary low power, almost 1.4MHz */
    SYSCTRL_LP_HSI_700KHZ = 0x01,    /*!< Super low power, almost 700KHz */
} SYSCTRL_LP_HSI_T;

/**
 * @brief   SYSCTRL STA communication mode
 */
typedef enum
{
    SYSCTRL_STA_COMM_MODE_HSC = 0x00,    /*!< HSC mode */
    SYSCTRL_STA_COMM_MODE_I2C = 0x01     /*!< I2C mode */
} SYSCTRL_STA_COMM_MODE_T;

/**
 * @brief   SYSCTRL STA auto mode
 */
typedef enum
{
    SYSCTRL_STA_AUTO_MODE_AUTO   = 0x00,    /*!< Auto mode */
    SYSCTRL_STA_AUTO_MODE_MANUAL = 0x01     /*!< Manual mode */
} SYSCTRL_STA_AUTO_MODE_T;

/**
 * @brief   SYSCTRL wake up peripheral
 */
typedef enum
{
    SYSCTRL_WU_I2C   = 0x0001,    /*!< I2C wake up flag */
    SYSCTRL_WU_HSC   = 0x0002,    /*!< HSC wake up flag */
    SYSCTRL_WU_UART  = 0x0004,    /*!< UART wake up flag */
    SYSCTRL_WU_IWDT  = 0x0008,    /*!< IWDT wake up flag */
    SYSCTRL_WU_TMR0  = 0x0020,    /*!< TMR0 wake up flag */
    SYSCTRL_WU_TMR1  = 0x0040,    /*!< TMR1 wake up flag */
    SYSCTRL_WU_ADC0  = 0x0080,    /*!< ADC0 wake up flag */
    SYSCTRL_WU_ADC1  = 0x0100,    /*!< ADC1 wake up flag */
    SYSCTRL_WU_FLASH = 0x0200,    /*!< FLASH wake up flag */
    SYSCTRL_WU_WUPT  = 0x0400,    /*!< WUPT wake up flag */
    SYSCTRL_WU_STA   = 0x0800,    /*!< STA wake up flag */
    SYSCTRL_WU_EINT0 = 0x1000,    /*!< EXTI0 wake up flag */
    SYSCTRL_WU_EINT1 = 0x2000,    /*!< EXTI1 wake up flag */
    SYSCTRL_WU_EINT2 = 0x4000,    /*!< EXTI2 wake up flag */
    SYSCTRL_WU_HMAC  = 0x8000     /*!< HMAC/SHA256 wake up flag */
} SYSCTRL_WU_T;

/**
 * @brief   SYSCTRL ANA LVD power consumption mode
 */
typedef enum
{
    SYSCTRL_ANA_LVDI_0P08UA = 0x00,    /*!< 0.08uA */
    SYSCTRL_ANA_LVDI_0P72UA = 0x01,    /*!< 0.72uA */
    SYSCTRL_ANA_LVDI_5UA    = 0x02,    /*!< 5uA */
    SYSCTRL_ANA_LVDI_45UA   = 0x03     /*!< 45uA */
} SYSCTRL_ANA_LVDI_T;

/**
 * @brief   SYSCTRL ANA LVD threshold voltage
 */
typedef enum
{
    SYSCTRL_ANA_LVDV_1P8V = 0x00,    /*!< 1.8V */
    SYSCTRL_ANA_LVDV_1P9V = 0x01,    /*!< 1.9V */
    SYSCTRL_ANA_LVDV_2P0V = 0x02,    /*!< 2.0V */
    SYSCTRL_ANA_LVDV_2P1V = 0x03,    /*!< 2.1V */
    SYSCTRL_ANA_LVDV_2P2V = 0x04,    /*!< 2.2V */
    SYSCTRL_ANA_LVDV_2P3V = 0x05,    /*!< 2.3V */
    SYSCTRL_ANA_LVDV_2P4V = 0x06,    /*!< 2.4V */
    SYSCTRL_ANA_LVDV_2P5V = 0x07,    /*!< 2.5V */
    SYSCTRL_ANA_LVDV_2P6V = 0x08,    /*!< 2.6V */
    SYSCTRL_ANA_LVDV_2P7V = 0x09,    /*!< 2.7V */
    SYSCTRL_ANA_LVDV_2P8V = 0x0A,    /*!< 2.8V */
    SYSCTRL_ANA_LVDV_2P9V = 0x0B,    /*!< 2.9V */
    SYSCTRL_ANA_LVDV_3P0V = 0x0C,    /*!< 3.0V */
    SYSCTRL_ANA_LVDV_3P1V = 0x0D,    /*!< 3.1V */
    SYSCTRL_ANA_LVDV_3P2V = 0x0E,    /*!< 3.2V */
    SYSCTRL_ANA_LVDV_3P3V = 0x0F     /*!< 3.3V */
} SYSCTRL_ANA_LVDV_T;

/**
 * @brief   SYSCTRL ANA VADC MUX channel
 */
typedef enum
{
    SYSCTRL_ANA_VADCMUX_BAT_5P0     = 0x00,    /*!< mux_bat_5p0 */
    SYSCTRL_ANA_VADCMUX_BAT_SNS_5P0 = 0x01,    /*!< mux_bat_sns_5p0 */
    SYSCTRL_ANA_VADCMUX_NTC_5P0     = 0x02,    /*!< mux_ntc_5p0 */
    SYSCTRL_ANA_VADCMUX_IPAT_5P0    = 0x03,    /*!< mux_ipat_5p0 */
    SYSCTRL_ANA_VADCMUX_VSS_5P0     = 0x04,    /*!< mux_vss_5p0 */
    SYSCTRL_ANA_VADCMUX_DVDD1P5     = 0x05,    /*!< dvdd1p5 */
} SYSCTRL_ANA_VADCMUX_T;

/**
 * @brief   SYSCTRL debug output
 */
typedef enum
{
    SYSCTRL_DEBUG_OUT_HSI = 0x00,    /*!< HSI clock */
    SYSCTRL_DEBUG_OUT_LSI = 0x01     /*!< LSI clock */
} SYSCTRL_DEBUG_OUT_T;

/**
 * @brief   SYSCTRL boot
 */
typedef enum
{
    SYSCTRL_BOOT_OPBYTE   = 0x00,    /*!< Option byte mode */
    SYSCTRL_BOOT_SYSREMAP = 0x01     /*!< SYSREMAP mode */
} SYSCTRL_BOOT_T;

/**
 * @brief   SYSCTRL boot remap
 */
typedef enum
{
    SYSCTRL_BOOT_REMAP_FLASH = 0x00,    /*!< Remap to FLASH */
    SYSCTRL_BOOT_REMAP_ROM   = 0x01,    /*!< Remap to ROM */
    SYSCTRL_BOOT_REMAP_RAM   = 0x02,    /*!< Remap to RAM */
    SYSCTRL_BOOT_REMAP_ROM1  = 0x03     /*!< Remap to ROM1 */
} SYSCTRL_BOOT_REMAP_T;

/**
 * @brief   SYSCTRL ADFT decoder
 */
typedef enum
{
    SYSCTRL_ADFT_DECODE_SEL0  = 0x00,    /*!< Signal 0 */
    SYSCTRL_ADFT_DECODE_SEL1  = 0x01,    /*!< Signal 1 */
    SYSCTRL_ADFT_DECODE_SEL2  = 0x02,    /*!< Signal 2 */
    SYSCTRL_ADFT_DECODE_SEL3  = 0x03,    /*!< Signal 3 */
    SYSCTRL_ADFT_DECODE_SEL4  = 0x04,    /*!< Signal 4 */
    SYSCTRL_ADFT_DECODE_SEL5  = 0x05,    /*!< Signal 5 */
    SYSCTRL_ADFT_DECODE_SEL6  = 0x06,    /*!< Signal 6 */
    SYSCTRL_ADFT_DECODE_SEL7  = 0x07,    /*!< Signal 7 */
    SYSCTRL_ADFT_DECODE_SEL8  = 0x08,    /*!< Signal 8 */
    SYSCTRL_ADFT_DECODE_SEL9  = 0x09,    /*!< Signal 9 */
    SYSCTRL_ADFT_DECODE_SEL10 = 0x0A     /*!< Signal 10 */
} SYSCTRL_ADFT_DECODE_T;

/**@} end of group SYSCTRL_Enumerations */

/** @addtogroup SYSCTRL_Structure Data Structure
  @{
*/

/**
 * @brief    SYSCTRL low power mode structure definition
 */
typedef struct
{
    SYSCTRL_LP_T     mode;       /*!< Select low power mode. */
    uint8_t          ldoEn;      /*!< LDO's low power enable in sleep or deep sleep mode, can be ENABLE or DISABLE. */
    uint8_t          waitCycle;  /*!< Wait LDO stable cycle after exiting low power, Cycle = SYSC_LowPowerConfig_T->waitCycle + 1. */
    SYSCTRL_LP_HSI_T hsiMode;    /*!< HSI mode in deep sleep mode. */
} SYSCTRL_LowPowerConfig_T;

/**
 * @brief    SYSCTRL STA configure structure definition
 */
typedef struct
{
    uint8_t                 wakeUpEn;   /*!< Enable check I2C start signal or HSC-BREAK, can be ENABLE or DISABLE. */
    SYSCTRL_STA_AUTO_MODE_T autoMode;   /*!< Wake up mode set. */
    uint8_t                 wakeUpInt;  /*!< Wake up interrupt enable, can be ENABLE or DISABLE. */
    SYSCTRL_STA_COMM_MODE_T commMode;   /*!< Communication mode select. */
}SYSCTRL_StartConfig_T;

/**
 * @brief    SYSCTRL ANA configure structure definition
 */
typedef struct
{
    uint8_t               ntcPullUp;   /*!< NTC pull up resistor, can be ENABLE or DISABLE. */
    uint8_t               tsEn;        /*!< TS internal enable, can be ENABLE or DISABLE. */
    SYSCTRL_ANA_LVDI_T    lvdiSel;     /*!< LVD power consumption mode. */
    SYSCTRL_ANA_LVDV_T    lvdvSel;     /*!< LVD threshold voltage. */
    uint8_t               lvdEn;       /*!< LVD enable, can be ENABLE or DISABLE. */
    SYSCTRL_ANA_VADCMUX_T vadcMuxSel;  /*!< VADC MUX channel. */
    uint8_t               afeClkEn;    /*!< AFE clock enable, can be ENABLE or DISABLE. */
    uint8_t               afeEn;       /*!< AFE enable, can be ENABLE or DISABLE. */
} SYSCTRL_AnalogConfig_T;

/**@} end of group SYSCTRL_Structure*/

/** @addtogroup SYSCTRL_Functions Functions
  @{
*/

/** SYSCTRL register configuration */
void SYSCTRL_Unlock(void);
void SYSCTRL_Lock(void);

/** SYSCTRL system clock configuration */
void SYSCTRL_EnableLSI(void);
void SYSCTRL_DisableLSI(void);
void SYSCTRL_ConfigHSIDiv(SYSCTRL_HSI_DIV_T div);
void SYSCTRL_ConfigSystemClock(SYSCTRL_SYSCLK_DIV_T sysClkDiv, SYSCTRL_APBCLK_DIV_T APBClkDiv);

/** SYSCTRL peripheral clock configuration */
void SYSCTRL_EnableAHBPeriphClock(SYSCTRL_AHB_T AHBPeriph);
void SYSCTRL_DisableAHBPeriphClock(SYSCTRL_AHB_T AHBPeriph);
void SYSCTRL_EnableAPBPeriphBCGClock(SYSCTRL_APB_T APBPeriph);
void SYSCTRL_DisableAPBPeriphBCGClock(SYSCTRL_APB_T APBPeriph);
void SYSCTRL_EnableAPBPeriphWCGClock(SYSCTRL_APB_T APBPeriph);
void SYSCTRL_DisableAPBPeriphWCGClock(SYSCTRL_APB_T APBPeriph);

/** SYSCTRL peripheral reset configuration */
void SYSCTRL_EnableAHBPeriphReset(SYSCTRL_AHB_T AHBPeriph);
void SYSCTRL_DisableAHBPeriphReset(SYSCTRL_AHB_T AHBPeriph);
void SYSCTRL_EnableAPBPeriphReset(SYSCTRL_APB_T APBPeriph);
void SYSCTRL_DisableAPBPeriphReset(SYSCTRL_APB_T APBPeriph);
uint8_t SYSCTRL_ReadResetFlag(SYSCTRL_RST_FLAG_T flag);
void SYSCTRL_ClearResetFlag(SYSCTRL_RST_FLAG_T flag);

/** SYSCTRL low power configuration */
void SYSCTRL_ConfigLowPower(SYSCTRL_LowPowerConfig_T* lowPowerConfig);
void SYSCTRL_ConfigLowPowerStructInit(SYSCTRL_LowPowerConfig_T* lowPowerConfig);
void SYSCTRL_ConfigLowPowerMode(SYSCTRL_LP_T mode);
void SYSCTRL_EnableLDOLowPower(void);
void SYSCTRL_DisableLDOLowPower(void);
void SYSCTRL_ConfigHSILowPower(SYSCTRL_LP_HSI_T mode);
void SYSCTRL_ConfigLDOWaitCycle(uint8_t waitCycle);
void SYSCTRL_UnlockLowPowerEnable(void);
void SYSCTRL_EnterLowPowerMode(void);

/** SYSCTRL start configuration */
void SYSCTRL_ConfigStart(SYSCTRL_StartConfig_T* startConfig);
void SYSCTRL_ConfigStartStructInit(SYSCTRL_StartConfig_T* startConfig);
void SYSCTRL_EnableStartWakeUp(void);
void SYSCTRL_DisableStartWakeUp(void);
void SYSCTRL_ConfigStartAutoMode(SYSCTRL_STA_AUTO_MODE_T mode);
void SYSCTRL_EnableStartWakeUpInterrupt(void);
void SYSCTRL_DisableStartWakeUpInterrupt(void);
void SYSCTRL_ConfigStartcommunicationMode(SYSCTRL_STA_COMM_MODE_T mode);
uint8_t SYSCTRL_ReadStartFlag(void);
void SYSCTRL_ClearStartFlag(void);

/** SYSCTRL wake up configuration */
uint8_t SYSCTRL_ReadWakeUpFlag(SYSCTRL_WU_T flag);
void SYSCTRL_ClearWakeUpFlag(SYSCTRL_WU_T flag);

/** SYSCTRL analog configuration */
void SYSCTRL_ConfigAnalog(SYSCTRL_AnalogConfig_T* analogConfig);
void SYSCTRL_ConfigAnalogStructInit(SYSCTRL_AnalogConfig_T* analogConfig);
void SYSCTRL_EnableNTCPullUpResistor(void);
void SYSCTRL_DisableNTCPullUpResistor(void);
void SYSCTRL_EnableTS(void);
void SYSCTRL_DisableTS(void);
void SYSCTRL_ConfigLVDI(SYSCTRL_ANA_LVDI_T mode);
void SYSCTRL_ConfigLVDV(SYSCTRL_ANA_LVDV_T mode);
void SYSCTRL_EnableLVD(void);
void SYSCTRL_DisableLVD(void);
void SYSCTRL_ConfigVADCMUX(SYSCTRL_ANA_VADCMUX_T channel);
void SYSCTRL_EnableAFEClock(void);
void SYSCTRL_DisableAFEClock(void);
void SYSCTRL_EnableAFE(void);
void SYSCTRL_DisableAFE(void);

/** SYSCTRL debug configuration */
void SYSCTRL_EnableDebug(void);
void SYSCTRL_DisableDebug(void);
void SYSCTRL_ConfigDebugOutput(SYSCTRL_DEBUG_OUT_T output);
void SYSCTRL_EnablePadFilter(void);
void SYSCTRL_DisablePadFilter(void);

/** SYSCTRL boot configuration */
void SYSCTRL_ConfigBootMode(SYSCTRL_BOOT_T mode);
void SYSCTRL_ConfigBootRemap(SYSCTRL_BOOT_REMAP_T remap);

/** SYSCTRL ADFT configuration */
void SYSCTRL_EnableADFT(void);
void SYSCTRL_DisableADFT(void);
void SYSCTRL_ConfigADFTDecoder(SYSCTRL_ADFT_DECODE_T decoder);

/** SYSCTRL trim configuration */
void SYSCTRL_ConfigLTBGTrim(uint8_t tTrim, uint8_t vTrim, uint8_t resbgTrim, uint8_t cadcTrim);
void SYSCTRL_ConfigOSCTrim(uint8_t HSITrim, uint16_t LSITrim);
void SYSCTRL_ConfigNTCTTrim(uint8_t ntcTrim, uint8_t tsTrim, uint8_t ldovTrim, uint8_t vadcTrim);

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

#ifdef __cplusplus
}
#endif

#endif /* __BMP561_SYSCTRL_H */
