
/**
 ******************************************************************************
 *
 * @file        BSP_RGB.c
 * @brief       BSP_2_RGB Code's C file(use middleware).
 *
 * @par         Project
 *              MG32
 * @version     V1.02
 * @date        2023/01/30
 * @author      Megawin Software Center
 * @copyright   Copyright (c) 2022 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. By changing "RGB_PWM_CYCLE" value to set PWM freq.
      (1) PWM freq. = TM clock source freq. / (RGB_PWM_TM_PRESCALER * RGB_PWM_CYCLE).
      (2) RGB_PWM_TM_PRESCALER can set range 1 to 65536.
      (3) RGB_PWM_CYCLE can set range from 1 to 65536.
   2. Use BSP_RGB_Init() function to initial.
      (1) PWM duty default is 0%.
   3. By calling "BSP_RGB_RefreshData" function to change PWM duty.
      (1) The parameter can't set over "RGB_PWM_CYCLE" value. 
      (2) PWM duty = The input parameter (RGB_R, RGB_G, RGB_B) / RGB_PWM_CYCLE.
      
Driver architecture:
--------------------
   + MG32_GPIO_DRV
   + MG32_TM_DRV
   
Known Limitations:
------------------
   1. When RGB_PWM_CYCLE = 65536 duty can't set 100%.

Require parameter
------------------
    Require module : CSC / GPIO / TM36
    
    GPIO pin configuration : 
        Pin / IO mode / AFS
        ---  --------  -----
        PA0 / PPO     / TM36_OC00
        PA1 / PPO     / TM36_OC10
        PA2 / PPO     / TM36_OC2

    TM36 Module : 
        Timer mode        : Cascade + up count mode.
        Channel function  : 16 bit PWM mode.
        PWM mode          : Edge Align mode.
        
Example codes:
------------------

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


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

/* Wizard menu ---------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
// GPIO (PA0/PA1/PA2, PPO, AFS=TM36_OC00/TM36_OC10/TM36_OC2)
#define RGB_IOM               IOMA                    /*!< RGB output port.*/
#define RGB_IOM_R_PIN         PX_Pin_0                /*!< RGB Red output pin.*/
#define RGB_IOM_G_PIN         PX_Pin_1                /*!< RGB Green output pin.*/
#define RGB_IOM_B_PIN         PX_Pin_2                /*!< RGB Blue output pin.*/
                              
#define RGB_PIN_MODE          PINX_Mode_PushPull_O    /*!< RGB pin's GPIO mode.*/
                              
#define RGB_R_PIN_AFS         10                      /*!< RGB pin's alternate function.*/
#define RGB_G_PIN_AFS         10                      /*!< RGB pin's alternate function.*/
#define RGB_B_PIN_AFS         10                      /*!< RGB pin's alternate function.*/
                              
// Timer module                
#define RGB_PWM_TM            TM36                    /*!< Define PWM use Timer(Only use TM2x & TM36).*/
#define RGB_PWM_TM_PRESCALER  10
#define RGB_PWM_CYCLE         255                     /*!< PWM counter total count.*/


/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Exported variables --------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/* External variables --------------------------------------------------------*/
                                                          
/**
 *******************************************************************************
 * @brief	    Update RGB duty.
 * @details     Duty is { RGB_R or RGB_G or RGB_B } / RGB_PWM_CYCLE
 * @param[in]   RGB_R: Red duty   : 0 ~ RGB_PWM_CYCLE value.
 * @param[in]   RGB_G: Green duty : 0 ~ RGB_PWM_CYCLE value.
 * @param[in]   RGB_B: Blue duty  : 0 ~ RGB_PWM_CYCLE value.                                                          
 * @return      None
 *******************************************************************************
 */                                                         
void BSP_RGB_RefreshData(uint32_t RGB_R, uint32_t RGB_G, uint32_t RGB_B)
{
    // Stop reload simultaneously 
    TM_ReloadFromCCxB_Cmd(RGB_PWM_TM, TM_StopReload);
   
    // Update the next duty cycle for TM36 Channel0/1/2
    RGB_PWM_TM->CC0B.H[0] = (uint16_t)RGB_R;
    RGB_PWM_TM->CC1B.H[0] = (uint16_t)RGB_G;
    RGB_PWM_TM->CC2B.H[0] = (uint16_t)RGB_B;
    
    // Reload simultaneously to prevent glitch
    TM_ReloadFromCCxB_Cmd(RGB_PWM_TM, TM_SimultaneouslyReload);
}

/**
 *******************************************************************************
 * @brief	    RGB initial. 
 * @details     User Timer(TM2x or TM36) to control PWM.
 * @return      None
 *******************************************************************************
 */
void BSP_RGB_Init(void)
{
    PIN_InitTypeDef        RGB_Pin;
    TM_TimeBaseInitTypeDef TM_TimeBase_InitStruct;

    // ------------------------------------------------------------------------
    // RGB PWM Pin Initial
    //    - TM_OC00  : PA0
    //    - TM_OC10  : PA1
    //    - TM_OC2   : PA2
    // ------------------------------------------------------------------------
    RGB_Pin.PINX_Pin                = (RGB_IOM_R_PIN | RGB_IOM_G_PIN | RGB_IOM_B_PIN );
    RGB_Pin.PINX_Mode               = RGB_PIN_MODE;
    RGB_Pin.PINX_PUResistant        = PINX_PUResistant_Disable;
    RGB_Pin.PINX_Speed              = PINX_Speed_Low;
    RGB_Pin.PINX_Inverse            = PINX_Inverse_Disable;
    RGB_Pin.PINX_OUTDrive           = PINX_OUTDrive_Level0;
    RGB_Pin.PINX_FilterDivider      = PINX_FilterDivider_Bypass;
    RGB_Pin.PINX_Alternate_Function = RGB_R_PIN_AFS;                          
    GPIO_PortMode_Config(RGB_IOM ,&RGB_Pin);
    
    
    // ------------------------------------------------------------------------
    // RGB Timer Initial (Use Timer36)    
    // ------------------------------------------------------------------------
    /* Timer PWM initial (TM36) */
    TM_DeInit(RGB_PWM_TM);

    /* TimeBase structure initial */
    TM_TimeBaseStruct_Init(&TM_TimeBase_InitStruct);

    /* Config TM36 channel3 function */ 
    TM_CH0Function_Config(RGB_PWM_TM, TM_16bitPWM);
    TM_CH1Function_Config(RGB_PWM_TM, TM_16bitPWM);
    TM_CH2Function_Config(RGB_PWM_TM, TM_16bitPWM);

    /* 
     * modify parameter
     *  PWM freq = TM36 clock source frq. / (TM_Prescaler + 1)*(TM_Period + 1)
     */
    TM_TimeBase_InitStruct.TM_MainClockDirection =TM_UpCount;
    TM_TimeBase_InitStruct.TM_Prescaler   = RGB_PWM_TM_PRESCALER - 1;
    TM_TimeBase_InitStruct.TM_Period      = RGB_PWM_CYCLE - 1;          // The RGB_PWM_CYCLE max can set 65535 because the mode is TM_16bitPWM mode
    TM_TimeBase_InitStruct.TM_CounterMode = Cascade;
    
    TM_TimeBase_Init(RGB_PWM_TM, &TM_TimeBase_InitStruct);
    
    /* PWM output control */
    TM_InverseOC0z_Cmd(RGB_PWM_TM, ENABLE);     // Inverse CH0z~CH2 output
    TM_InverseOC1z_Cmd(RGB_PWM_TM, ENABLE);
    TM_InverseOC2_Cmd(RGB_PWM_TM, ENABLE);

    TM_OC00Output_Cmd(RGB_PWM_TM, ENABLE);      // Enable CH0z~CH2 output
    TM_OC10Output_Cmd(RGB_PWM_TM, ENABLE);
    TM_OC2Output_Cmd(RGB_PWM_TM, ENABLE);
    
    BSP_RGB_RefreshData(0, 0, 0);               // Update R/G/B LED PWM output

    /* Select Edge Align */
    TM_AlignmentMode_Select(RGB_PWM_TM, TM_EdgeAlign);
    
    
    /*  Timer Enable */
    TM_Timer_Cmd(RGB_PWM_TM, ENABLE);
}








