/**
 * *************************************************************************************************************
 * @file CTM.c
 * @author BH_CodeGenerator
 * @version 0.1
 * @date 2022-04-01
 * @warning <!--auto generated by Tools, do not modify or add anything, otherwise, your change will be lost!!! -->
 * @brief all the functions prototypes for CTM firmware library
 * MCU / CFG Ver. :BH66F2475/1.7
 * Version = 1.0.0

 * *************************************************************************************************************
 *  @attention
 *
 *  Firmware Disclaimer Information
 *
 *  1. The customer hereby acknowledges and agrees that the program technical documentation, including the
 *     code, which is supplied by BEST HEALTH ELECTRONIC Inc., (hereinafter referred to as BestHealth) is the
 *     proprietary and confidential intellectual property of BestHealth, and is protected by copyright law and
 *     other intellectual property laws.
 *
 *  2. The customer hereby acknowledges and agrees that the program technical documentation, including the
 *     code, is confidential information belonging to BestHealth, and must not be disclosed to any third parties
 *     other than BestHealth and the customer.
 *
 *  3. The program technical documentation, including the code, is provided and for customer reference
 *     only. After delivery by BestHealth, the customer shall use the program technical documentation, including
 *     the code, at their own risk. BestHealth disclaims any expressed, implied or statutory warranties, including
 *     the warranties of merchantability, satisfactory quality and fitness for a particular purpose.
 *
 *  <h2><center>Copyright (C) BEST HEALTH ELECTRONIC Inc. All rights reserved</center></h2>
 */
#include "CTM.h"
#include "..\board\BoardCfg.h"

/*! timer work mode selection enum */
typedef enum {
    TIMER_COMPARE_MATCH_OUTPUT    = (0x00 << 6),
    TIMER_CAPTURE_INPUT           = (0x01 << 6),
    TIMER_PWM_SINGLE_PULSE_OUTPUT = (0x02 << 6),
    TIMER_TIMER_COUNTER           = (0x03 << 6),
} TimerModeCfg_t;

// clang-format off
// Timer
#define SET_TMn_CLOCK(n, type)          { _ctm##n##c0 &= 0x8F; _ctm##n##c0 |= type;}
#define SET_TMn_MODE(n, type)           { _ctm##n##c1 &= 0x3F; _ctm##n##c1 |= type;}
#define SET_TMn_CCRA(n,x)               { _ctm##n##al = x%256; _ctm##n##ah = x/256;}
#define SET_TMn_CCRP(n,x)               { _ctm##n##c0 &= 0xF8; _ctm##n##c0 |= x;}
#define SET_TMn_OUTPUT_INVERT(n,type)   {_ct##n##pol = type;}
#define SET_TMn_COUNT_CLEAR(n,type)     {_ct##n##cclr = type;}
#define SET_TMn_OUTPUT_MODE(n,type)     {_ctm##n##c1 &= 0xC7; _ctm##n##c1 |= type;}

// Capture Input mode
#define SET_CAPTURE_INPUT_EDGE(n,type)  {_ctm##n##c1 &= 0xCF; _ctm##n##c1 |= type;}
#define SET_PWM_DUTY_PERIOD(n,type)     {_ct##n##dpx = type;}   // pwm mode

// clang-format on

/**
 * @brief CTM0 compare match configuration
 *
 * @param Cfg @see CTM_Cfg_CompareMatchOutputMode_t
 */
void CTM0_Cfg_CompareMatchOutput(CTM_Cfg_CompareMatchOutputMode_t *cfg)
{
#if defined(PIN_CTCK0_PA4)
    PIN_PA4_CTCK0();
#endif
#if defined(PIN_CTP0_PA4)
    PIN_PA4_CTP0();
#endif
    SET_TMn_MODE(0, TIMER_COMPARE_MATCH_OUTPUT);
    SET_TMn_CLOCK(0, cfg->clockSource);
    SET_TMn_OUTPUT_MODE(0, cfg->outputMode);
    SET_TMn_COUNT_CLEAR(0, cfg->countClear);
    SET_TMn_OUTPUT_INVERT(0, cfg->pinInvert);
    if (cfg->countClear == CTM_COUNT_CLEAR_A_MATCH)
    {
        SET_TMn_CCRA(0, cfg->count);
    }
    else
    {
        SET_TMn_CCRP(0, cfg->count);
    }
}

/*
 * @Brief CTM0 pwm configuration
 **
 * @Param Cfg @see CTM_Cfg_PWM_t
 */
void CTM0_Cfg_PWM(CTM_Cfg_PWM_t *cfg)
{
#if defined(PIN_CTCK0_PA4)
    PIN_PA4_CTCK0();
#endif
#if defined(PIN_CTP0_PA4)
    PIN_PA4_CTP0();
#endif
    SET_TMn_MODE(0, TIMER_PWM_SINGLE_PULSE_OUTPUT);
    SET_TMn_CLOCK(0, cfg->clockSource);
    SET_TMn_OUTPUT_MODE(0, cfg->outputMode);
    SET_TMn_OUTPUT_INVERT(0, cfg->pinInvert);
    SET_PWM_DUTY_PERIOD(0, cfg->dutyPeriod);
    SET_TMn_CCRA(0, cfg->ccraData);
    SET_TMn_CCRP(0, cfg->ccrpData);
}

/*
 * @Brief CTM0 moder
 **
 * @Param Cfg @see CTM_Cfg_TimerCounter_t
 */
void CTM0_Cfg_TimerCounter(CTM_Cfg_TimerCounter_t *cfg)
{
#if defined(PIN_CTCK0_PA4)
    PIN_PA4_CTCK0();
#endif
    SET_TMn_COUNT_CLEAR(0, cfg->countClear);
    SET_TMn_MODE(0, TIMER_TIMER_COUNTER);
    SET_TMn_CLOCK(0, cfg->clockSource);
    if (cfg->countClear == CTM_COUNT_CLEAR_A_MATCH)
    {
        SET_TMn_CCRA(0, cfg->count);
    }
    else
    {
        SET_TMn_CCRP(0, cfg->count);
    }
}

/**
 * @brief CTM1 compare match configuration
 *
 * @param Cfg @see CTM_Cfg_CompareMatchOutputMode_t
 */
void CTM1_Cfg_CompareMatchOutput(CTM_Cfg_CompareMatchOutputMode_t *cfg)
{
#if defined(PIN_CTCK1_PA6)
    PIN_PA6_CTCK1();
#endif
#if defined(PIN_CTP1_PA6)
    PIN_PA6_CTP1();
#endif
    SET_TMn_MODE(1, TIMER_COMPARE_MATCH_OUTPUT);
    SET_TMn_CLOCK(1, cfg->clockSource);
    SET_TMn_OUTPUT_MODE(1, cfg->outputMode);
    SET_TMn_COUNT_CLEAR(1, cfg->countClear);
    SET_TMn_OUTPUT_INVERT(1, cfg->pinInvert);
    if (cfg->countClear == CTM_COUNT_CLEAR_A_MATCH)
    {
        SET_TMn_CCRA(1, cfg->count);
    }
    else
    {
        SET_TMn_CCRP(1, cfg->count);
    }
}

/*
 * @Brief CTM1 pwm configuration
 **
 * @Param Cfg @see CTM_Cfg_PWM_t
 */
void CTM1_Cfg_PWM(CTM_Cfg_PWM_t *cfg)
{
#if defined(PIN_CTCK1_PA6)
    PIN_PA6_CTCK1();
#endif
#if defined(PIN_CTP1_PA6)
    PIN_PA6_CTP1();
#endif
    SET_TMn_MODE(1, TIMER_PWM_SINGLE_PULSE_OUTPUT);
    SET_TMn_CLOCK(1, cfg->clockSource);
    SET_TMn_OUTPUT_MODE(1, cfg->outputMode);
    SET_TMn_OUTPUT_INVERT(1, cfg->pinInvert);
    SET_PWM_DUTY_PERIOD(1, cfg->dutyPeriod);
    SET_TMn_CCRA(1, cfg->ccraData);
    SET_TMn_CCRP(1, cfg->ccrpData);
}

/*
 * @Brief CTM1 timer configuration
 **
 * @Param Cfg @see CTM_Cfg_TimerCounter_t
 */
void CTM1_Cfg_TimerCounter(CTM_Cfg_TimerCounter_t *cfg)
{
#if defined(PIN_CTCK1_PA6)
    PIN_PA6_CTCK1();
#endif
    SET_TMn_COUNT_CLEAR(1, cfg->countClear);
    SET_TMn_MODE(1, TIMER_TIMER_COUNTER);
    SET_TMn_CLOCK(1, cfg->clockSource);
    if (cfg->countClear == CTM_COUNT_CLEAR_A_MATCH)
    {
        SET_TMn_CCRA(1, cfg->count);
    }
    else
    {
        SET_TMn_CCRP(1, cfg->count);
    }
}
