

/**
 ******************************************************************************
 *
 * @file        BSP_11_RCServoMotor.c
 * @brief       This is RC Servo Motor C file.
 
 * @par         Project
 *              MG32
 * @version     V1.02
 * @date        2023/02/06
 * @author      Megawin Software Center
 * @copyright   Copyright (c) 2017 MegaWin Technology Co., Ltd.
 *              All rights reserved.
 * 
 ******************************************************************************* 
 * @par Disclaimer
 * The Demo software is provided "AS IS" without any warranty, either
 * expressed or implied, including, but not limited to, the implied warranties
 * of merchantability and fitness for a particular purpose. The author will
 * not be liable for any special, incidental, consequential or indirect
 * damages due to loss of data or any other reason.
 * These statements agree with the world wide and local dictated laws about
 * authorship and violence against these laws.
 *******************************************************************************
 *******************************************************************************
 */

/*==============================================================================
                                 User Notes
How To use this function:
-----------------------
   1. Use BSP_RCServoMotor_Init() function to initial.
   2. Use "BSP_RCServoMotor_ChangePulseWidth" function change PWM pulse width.
      (1). The function can change PWM pulse width range be limited by 
           "RCServoMotor_MaxPulseWidth" and "RCServoMotor_MinPulseWidth" parameters.
   3. Use "BSP_RCServoMotor_ChangePulseRnagle" function change 
          "RCServoMotor_MaxPulseWidth" and "RCServoMotor_MinPulseWidth" parameters.
   
Driver architecture:
--------------------
   + MG32_GPIO_DRV
   + MG32_TM_DRV
   
Known Limitations:
------------------

Require parameter
------------------
    Require module : CSC / GPIO / TM20
    
    GPIO pin configuration : 
        Pin / IO mode / AFS
        ---  --------  -----
        PA4 / PPO     / TM20_OC00 
        
    TM26 Module :        
        Timer Mode   : Cascade Mode.
        Control Mode : 16-bit PWM mode.

Example codes:
------------------

==============================================================================*/ 


/* Includes ------------------------------------------------------------------*/
#include "BSP_11_RCServoMotor.h"

/* Wizard menu ---------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
// GPIO (PA4, PPO, TM20_OC00)
#define RCSERVOMOTOR_SER_PIN          PX_Pin_4
#define RCSERVOMOTOR_SER_PIN_MODE     PINX_Mode_PushPull_O
#define RCSERVOMOTOR_SER_PIN_AFS      10
#define RCSERVOMOTOR_SER_IOM          IOMA

// Timer
#define RCSERVOMOTOR_TM               TM20

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static uint8_t RCServoMotor_MaxPulseWidth    =  200;       /*!< Default max pulse width is 2ms.*/
static uint8_t RCServoMotor_MinPulseWidth    =  100;       /*!< Default min pulse width is 1ms.*/


/* Private function prototypes -----------------------------------------------*/
/* Exported variables --------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/* External variables --------------------------------------------------------*/


/**
 *******************************************************************************
 * @brief	    RC servo motor initial.  
 * @details     GPIO and TM20 initial
 * @return      None
 * @exception   No 
 * @note       
 *******************************************************************************
 */
void BSP_RCServoMotor_Init(void)
{
    PIN_InitTypeDef        RCServoMoter_Pin;
    TM_TimeBaseInitTypeDef RCServoMoter_TimeBase;
    
    // ------------------------------------------------------------------------
    // GPIO Initial
    // ------------------------------------------------------------------------
    RCServoMoter_Pin.PINX_Pin                = RCSERVOMOTOR_SER_PIN;
    RCServoMoter_Pin.PINX_Mode               = RCSERVOMOTOR_SER_PIN_MODE;
    RCServoMoter_Pin.PINX_PUResistant        = PINX_PUResistant_Disable;
    RCServoMoter_Pin.PINX_Speed              = PINX_Speed_High;
    RCServoMoter_Pin.PINX_Inverse            = PINX_Inverse_Disable;
    RCServoMoter_Pin.PINX_OUTDrive           = PINX_OUTDrive_Level0;
    RCServoMoter_Pin.PINX_FilterDivider      = PINX_FilterDivider_Bypass;
    RCServoMoter_Pin.PINX_Alternate_Function = RCSERVOMOTOR_SER_PIN_AFS;
    
    GPIO_PortMode_Config(RCSERVOMOTOR_SER_IOM ,&RCServoMoter_Pin);
    
    // ------------------------------------------------------------------------
    // Timer Initial 
    // ------------------------------------------------------------------------
    // Timer default initial 
    TM_DeInit(RCSERVOMOTOR_TM);
    
    // TimeBase structure initial 
    TM_TimeBaseStruct_Init(&RCServoMoter_TimeBase);
    
    // Config TM channel3 function 
    TM_CH0Function_Config(RCSERVOMOTOR_TM, TM_16bitPWM);
    
    // ------------------------------------------------------------------------
    // modify parameter
    // PWM freq = TM clock source frq. / (TM_Prescaler + 1)*(TM_Period + 1)
    // ------------------------------------------------------------------------
    RCServoMoter_TimeBase.TM_MainClockDirection = TM_UpCount;
    RCServoMoter_TimeBase.TM_Prescaler   = 480 - 1;
    RCServoMoter_TimeBase.TM_Period      = 2000 - 1;        // In clock source is 48MHz PWM period is 20ms.
    RCServoMoter_TimeBase.TM_CounterMode = Cascade;
    
    TM_TimeBase_Init(RCSERVOMOTOR_TM, &RCServoMoter_TimeBase);
    
    // PWM output control
    TM_InverseOC0z_Cmd(RCSERVOMOTOR_TM, DISABLE);
    TM_OC00Output_Cmd(RCSERVOMOTOR_TM, ENABLE);
    
    // ------------------------------------------------------------------------
    BSP_RCServoMotor_ChangePulseWidth(0);                   // PWM duty is 0%
    
    // Select Edge Align
    TM_AlignmentMode_Select(RCSERVOMOTOR_TM, TM_EdgeAlign);
    
    // Timer Enable
    TM_Timer_Cmd(RCSERVOMOTOR_TM, ENABLE);
    
}
/**
 *******************************************************************************
 * @brief	    Change PWM H pulse width.
 * @param[in]   rModter_PulseWidth: (RCServoMotor_MaxPulseWidth ~ RCServoMotor_MinPulseWidth)
 *      \b      1. The parmaeter unit is 10us.
 *      \b      2. The parameter can't over pulse width max or pulse width min.
 *      \b      If parmaeter over range no effect.
 * @return      None
 * @exception   No 
 * @note      
 *******************************************************************************
 */
void BSP_RCServoMotor_ChangePulseWidth(uint8_t rModter_PulseWidth)
{
    
    // ------------------------------------------------------------------------
    // condition : RCServoMotor_MaxPulseWidth ~ RCServoMotor_MinPulseWidth
    // Exit when outside this range.
    // ------------------------------------------------------------------------
    if(rModter_PulseWidth > RCServoMotor_MaxPulseWidth || rModter_PulseWidth < RCServoMotor_MinPulseWidth)
    {
        return;
    }
    
    // ------------------------------------------------------------------------
    TM_ReloadFromCCxB_Cmd(RCSERVOMOTOR_TM, TM_StopReload);              // Stop update function (form CC0B->CC0A)
    RCSERVOMOTOR_TM->CC0B.H[0] = (uint16_t) rModter_PulseWidth;         // Update duty cycle
    TM_ReloadFromCCxB_Cmd(RCSERVOMOTOR_TM, TM_SimultaneouslyReload);    // Enable update function (CC0B to CC0A)

}
/**
 *******************************************************************************
 * @brief	    Change PWM can control pulse range parameter.
 * @param[in]   sMotor_Pulse_Max : PWM pulse could set max width(1 ~ 1999). 
 * @param[in]   sMotor_Pulse_Min : PWM pulse could set min width(1 ~ 1999).
 * @return      None
 * @exception   No 
 * @note       
 *******************************************************************************
 */
void BSP_RCServoMotor_ChangePulseRnagle(uint8_t sMotor_Pulse_Max , uint8_t sMotor_Pulse_Min)
{
    RCServoMotor_MaxPulseWidth = sMotor_Pulse_Max;
    RCServoMotor_MinPulseWidth = sMotor_Pulse_Min;
}




