/*!
 * @file        main.c
 *
 * @brief       Main program body
 *
 * @version     V1.0.0
 *
 * @date        2026-02-25
 *
 * @attention
 *
 *  Copyright (C) 2026 Geehy Semiconductor
 *
 *  You may not use this file except in compliance with the
 *  GEEHY COPYRIGHT NOTICE (Geehy Semiconductor Software License Agreement).
 *
 *  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 Semiconductor Software License Agreement for the governing permissions
 *  and limitations under the License.
 */

/* Includes */
#include "user_tmr_config.h"
#include "Board.h"

/** @addtogroup Examples
  @{
*/

/** @addtogroup TMR_Examples
@{
*/

/** @addtogroup TMR_OCToggle
  @{
  */

/** @defgroup TMR_OCToggle_Functions Functions
  @{
  */
void TMR3_IRQHandler(void);

/*!
 * @brief       Main program
 *
 * @param       None
 *
 * @retval      None
 */
int main(void)
{
    Rcm_EnableApb1PeriphClock(RCM_APB1_PERIPH_TMR3);
    Rcm_EnableAhbPeriphClock(RCM_AHB_PERIPH_GPIOA);
    Rcm_EnableAhbPeriphClock(RCM_AHB_PERIPH_GPIOB);

    /* GPIO AF Configuration */
    Gpio_ConfigPinAF(TMR3_CH1_GPIO_PORT, TMR3_CH1_PIN_SOURCE, TMR3_CH1_GPIO_AF);
    Gpio_ConfigPinAF(TMR3_CH2_GPIO_PORT, TMR3_CH2_PIN_SOURCE, TMR3_CH2_GPIO_AF);
    Gpio_ConfigPinAF(TMR3_CH3_GPIO_PORT, TMR3_CH3_PIN_SOURCE, TMR3_CH3_GPIO_AF);
    Gpio_ConfigPinAF(TMR3_CH4_GPIO_PORT, TMR3_CH4_PIN_SOURCE, TMR3_CH4_GPIO_AF);

    /* Config TMR3 GPIO */
    Gpio_Config(TMR3_CH1_GPIO_PORT, &g_tmr3_Ch1GpioConfig);
    Gpio_Config(TMR3_CH2_GPIO_PORT, &g_tmr3_Ch2GpioConfig);
    Gpio_Config(TMR3_CH3_GPIO_PORT, &g_tmr3_Ch3GpioConfig);
    Gpio_Config(TMR3_CH4_GPIO_PORT, &g_tmr3_Ch4GpioConfig);

    /* Config TMR3 */
    Tmr_ConfigTimeBase(TMR3, &g_tmr3_BaseConfig);

    /* Configure channel1 */
    g_tmr3_OC1Config.Pulse = (uint16_t)((uint16_t)SystemCoreClock / (uint16_t)5000);
    Tmr_OC1Config(TMR3, &g_tmr3_OC1Config);
    Tmr_OC1PreloadConfig(TMR3, TMR_OC_PRELOAD_DISABLE);

    /* Configure channel2 */
    g_tmr3_OC2Config.Pulse = (uint16_t)((uint16_t)SystemCoreClock / (uint16_t)10000);
    Tmr_OC2Config(TMR3, &g_tmr3_OC2Config);
    Tmr_OC2PreloadConfig(TMR3, TMR_OC_PRELOAD_DISABLE);

    /* Configure channel3 */
    g_tmr3_OC3Config.Pulse = (uint16_t)((uint16_t)SystemCoreClock / (uint16_t)50000);
    Tmr_OC3Config(TMR3, &g_tmr3_OC3Config);
    Tmr_OC3PreloadConfig(TMR3, TMR_OC_PRELOAD_DISABLE);

    /* Configure channel4 */
    g_tmr3_OC4Config.Pulse = (uint16_t)((uint16_t)SystemCoreClock / (uint16_t)100000);
    Tmr_OC4Config(TMR3, &g_tmr3_OC4Config);
    Tmr_OC4PreloadConfig(TMR3, TMR_OC_PRELOAD_DISABLE);

    /* Timer3 Commutation Interrupt */
    Tmr_EnableInterrupt(TMR3, (uint16_t)((uint16_t)TMR_INT_CH1 | (uint16_t)TMR_INT_CH2 | (uint16_t)TMR_INT_CH3 | (uint16_t)TMR_INT_CH4));
    NVIC_EnableIRQ(TMR3_IRQn);

    Tmr_Enable(TMR3);

    while (1)
    {
    }
}

/*!
 * @brief       TMR3 Handler
 *
 * @param       None
 *
 * @retval      None
 */
void TMR3_IRQHandler(void)
{
    uint16_t capValue = 0;

    /* TMR3_CH1 toggling with frequency = 5KHz */
    if ((uint16_t)0u != Tmr_ReadIntFlag(TMR3, TMR_INT_FLAG_CH1))
    {
        Tmr_ClearIntFlag(TMR3, (uint16_t)TMR_INT_CH1);
        capValue = Tmr_ReadCaputer1(TMR3);
        Tmr_SetCompare1(TMR3, capValue + (SystemCoreClock / (uint32_t)5000));
    }
    else
    {
        /* nothing */
    }

    /* TMR3_CH2 toggling with frequency = 50KHz */
    if ((uint16_t)0u != Tmr_ReadIntFlag(TMR3, TMR_INT_FLAG_CH2))
    {
        Tmr_ClearIntFlag(TMR3, (uint16_t)TMR_INT_CH2);
        capValue = Tmr_ReadCaputer2(TMR3);
        Tmr_SetCompare2(TMR3, capValue + (SystemCoreClock / (uint32_t)10000));
    }
    else
    {
        /* nothing */
    }

    /* TMR3_CH3 toggling with frequency  */
    if ((uint16_t)0u != Tmr_ReadIntFlag(TMR3, TMR_INT_FLAG_CH3))
    {
        Tmr_ClearIntFlag(TMR3, (uint16_t)TMR_INT_CH3);
        capValue = Tmr_ReadCaputer3(TMR3);
        Tmr_SetCompare3(TMR3, capValue + (SystemCoreClock / (uint32_t)50000));
    }
    else
    {
        /* nothing */
    }

    /* TMR3_CH4 toggling with frequency  */
    if ((uint16_t)0u != Tmr_ReadIntFlag(TMR3, TMR_INT_FLAG_CH4))
    {
        Tmr_ClearIntFlag(TMR3, (uint16_t)TMR_INT_CH4);
        capValue = Tmr_ReadCaputer4(TMR3);
        Tmr_SetCompare4(TMR3, capValue + (SystemCoreClock / (uint32_t)100000));
    }
    else
    {
        /* nothing */
    }
}

/**@} end of group TMR_OCToggle_Functions */
/**@} end of group TMR_OCToggle */
/**@} end of group TMR_Examples */
/**@} end of group Examples */
