/**
  ******************************************************************************
  * @file     TIMER_CFG.c
  * @author   SINOMCU-AE
  * @brief    Timer basic config
  *    
  *          This file provides functions to Timer1 CH1 CH1N PWM out config:
  *              PA8      --> TIM1_CH1
  *              PB13     --> TIM1_CH1N 
  *             PWM period 1KHz,UIF interrupt enable;Duty adjustment in main.c. 
  *         
  ******************************************************************************
  * @attention 
  *                           DISCLAIMER
  * The present firmware which is for guidance only aims at providing customers
  * with coding information regarding their products in order for them to save
  * time. As a result, SinoMCU shall not be held liable for any direct,indirect
  * or consequential damages with respect to any claims arising from the content 
  * of such firmware and/or the use made by customers of the coding information 
  * contained herein in connection with their products.
  *
  * <h2><center>&copy; Copyright (c) 2021 sinomcu All rights reserved.</center></h2>
  *
  ******************************************************************************
  */
    
#include "TIMER_CFG.h"

/**
  * @brief  Timer1 CH1 CH1N PWM Out Pin Initialization
  * @param  None
  * @retval None
  */
void Timer1_PWMwN_Pin_Init(void)
{
  MS32_GPIO_InitTypeDef GPIO_InitStruct = {0};

  MS32_AHB1_GRP1_EnableClock(MS32_AHB1_GRP1_PERIPH_GPIOB);
  MS32_AHB1_GRP1_EnableClock(MS32_AHB1_GRP1_PERIPH_GPIOA);

  // PA8      --> TIM1_CH1
  // PB13     --> TIM1_CH1N
  MS32_GPIO_StructInit(&GPIO_InitStruct); 
  GPIO_InitStruct.Pin = MS32_GPIO_PIN_8;
  GPIO_InitStruct.Mode = MS32_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = MS32_GPIO_SPEED_FREQ_HIGH;
  GPIO_InitStruct.OutputType = MS32_GPIO_OUTPUT_PUSHPULL;
  GPIO_InitStruct.Pull = MS32_GPIO_PULL_UP;
  GPIO_InitStruct.Alternate = MS32_GPIO_AF_2;
  MS32_GPIO_Init(GPIOA, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = MS32_GPIO_PIN_13;
  GPIO_InitStruct.Mode = MS32_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = MS32_GPIO_SPEED_FREQ_HIGH;
  GPIO_InitStruct.OutputType = MS32_GPIO_OUTPUT_PUSHPULL;
  GPIO_InitStruct.Pull = MS32_GPIO_PULL_DOWN;
  GPIO_InitStruct.Alternate = MS32_GPIO_AF_2;
  MS32_GPIO_Init(GPIOB, &GPIO_InitStruct);
}

/**
  * @brief  Timer1 CH1 CH1N PWM Initialization
  * @param  None
  * @retval None
  */
void Timer1_PWMwN_Init(void)
{
  MS32_TIM_InitTypeDef TIM_InitStruct = {0};
  MS32_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0};
  MS32_TIM_BDTR_InitTypeDef TIM_BDTRInitStruct = {0};

  MS32_APB1_GRP2_EnableClock(MS32_APB1_GRP2_PERIPH_TIM1);

  // count up,PWM period 1KHz
  MS32_TIM_StructInit(&TIM_InitStruct);
  TIM_InitStruct.Prescaler = __MS32_TIM_CALC_PSC(SystemCoreClock,1000000);                         // unit Hz,div sysclk to  CNT clk:1Mhz
  TIM_InitStruct.CounterMode = MS32_TIM_COUNTERMODE_UP;
  TIM_InitStruct.Autoreload = __MS32_TIM_CALC_ARR(SystemCoreClock,TIM_InitStruct.Prescaler,1000);  // unit Hz,1KHz
  TIM_InitStruct.ClockDivision = MS32_TIM_CLOCKDIVISION_DIV1;
  TIM_InitStruct.RepetitionCounter = 0;
  MS32_TIM_Init(TIM1, &TIM_InitStruct);

  MS32_TIM_EnableARRPreload(TIM1);
  MS32_TIM_SetClockSource(TIM1, MS32_TIM_CLOCKSOURCE_INTERNAL);                                    // CNT clk form RCC

  MS32_TIM_OC_EnablePreload(TIM1, MS32_TIM_CHANNEL_CH1);
  MS32_TIM_OC_StructInit(&TIM_OC_InitStruct);
  TIM_OC_InitStruct.OCMode = MS32_TIM_OCMODE_PWM1;                                                 // PWM mode
  TIM_OC_InitStruct.OCState = MS32_TIM_OCSTATE_DISABLE;
  TIM_OC_InitStruct.OCNState = MS32_TIM_OCSTATE_DISABLE;
  TIM_OC_InitStruct.CompareValue =  ((( MS32_TIM_GetAutoReload(TIM1) + 1 ) * TIMER1_PWM_DUTY_PER_MIN ) / 100);    // set duty cycle
  TIM_OC_InitStruct.OCPolarity = MS32_TIM_OCPOLARITY_HIGH;
  TIM_OC_InitStruct.OCNPolarity = MS32_TIM_OCPOLARITY_HIGH;
  TIM_OC_InitStruct.OCIdleState = MS32_TIM_OCIDLESTATE_LOW;
  TIM_OC_InitStruct.OCNIdleState = MS32_TIM_OCIDLESTATE_LOW;
  MS32_TIM_OC_Init(TIM1, MS32_TIM_CHANNEL_CH1, &TIM_OC_InitStruct);
  MS32_TIM_OC_DisableFast(TIM1, MS32_TIM_CHANNEL_CH1);

  MS32_TIM_SetTriggerOutput(TIM1, MS32_TIM_TRGO_RESET);
  MS32_TIM_DisableMasterSlaveMode(TIM1);

  MS32_TIM_BDTR_StructInit(&TIM_BDTRInitStruct);
  TIM_BDTRInitStruct.OSSRState = MS32_TIM_OSSR_DISABLE;
  TIM_BDTRInitStruct.OSSIState = MS32_TIM_OSSI_DISABLE;
  TIM_BDTRInitStruct.LockLevel = MS32_TIM_LOCKLEVEL_OFF;
  TIM_BDTRInitStruct.DeadTime = __MS32_TIM_CALC_DEADTIME(SystemCoreClock,MS32_TIM_GetClockDivision(TIM1), 1000);  // unit ns, deadtime 1us
  TIM_BDTRInitStruct.BreakState = MS32_TIM_BREAK_DISABLE;
  TIM_BDTRInitStruct.BreakPolarity = MS32_TIM_BREAK_POLARITY_HIGH;
  TIM_BDTRInitStruct.AutomaticOutput = MS32_TIM_AUTOMATICOUTPUT_DISABLE;
  MS32_TIM_BDTR_Init(TIM1, &TIM_BDTRInitStruct);

  Timer1_PWMwN_Pin_Init();                                                                         // PWM pin set

  MS32_TIM_CC_EnableChannel(TIM1, MS32_TIM_CHANNEL_CH1);                                           // enable channel 
  MS32_TIM_CC_EnableChannel(TIM1, MS32_TIM_CHANNEL_CH1N);
  MS32_TIM_EnableAllOutputs(TIM1);                                                                 // enable ouput 

  // TIM1 interrupt Init
  NVIC_SetPriority(TIM1_BRK_UP_TRG_COM_IRQn, 0);
  NVIC_EnableIRQ(TIM1_BRK_UP_TRG_COM_IRQn);
  
  MS32_TIM_EnableIT_UPDATE(TIM1);                                                                  // UIF interrupt enable
  MS32_TIM_EnableCounter(TIM1);                                                                    // start timer
  //MS32_TIM_GenerateEvent_UPDATE(TIM1);                                                             // Force update
} 

/******************************** END OF FILE *********************************/
