
/**
 ******************************************************************************
 *
 * @file        LEDBreathing_SW.c
 *
 * @brief       Use software to control LED (for Megawin CM0 Evaluation Board ).
 *
 * @par         Project
 *              MG32
 * @version     V1.02
 * @date        2022/05/11
 * @author      Megawin Software Center
 * @copyright   Copyright (c) 2016 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. 
 ******************************************************************************
 ******************************************************************************
 */


/* Includes ------------------------------------------------------------------*/
#include "MG32__Common_DRV.h"
#include "MG32_GPIO_DRV.h"
#include "MG32_TM_DRV.h"
#include "LEDBreathing_SW.h"

/* Wizard menu ---------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define     TMx      TM16

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static uint8_t     LED_CTR[LED_CTR_LEN]; 

/* Private function prototypes -----------------------------------------------*/
static void LEDBreathing_Drama(void);

/* Exported variables --------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/* External variables --------------------------------------------------------*/


/**
 *******************************************************************************
 * @brief	    Initial hardware and software parameter.
 * @details     
 * @return      No
 * @exception   No
 * @note                
 *******************************************************************************
 */
void LEDBreathing_Init(void)                          
{
    PIN_InitTypeDef        PINX_InitStruct;
    
    //====================================
    //Setting control parameter
    LED1_SET_PWM(0);
    LED2_SET_PWM(0);
    LED3_SET_PWM(0);
    
    LED123_PWM_CNT       = 0;
    
    LED123_SUB_STEP      = 0;
    LED123_SUB_STEP_CMP  = 60;
    
    LED123_TEMP_CNT      = 0;
    LED123_TEMP_CNT_CMP  = 15;
    
    LED123_MAIN_STEP     = 0;
    LED123_MAIN_STEP_CMP = 1;

    LED123_MODE = LED123_MODE_POWERON;
    //===================================
    //Use timer16 to control timing
    TM_InternalClockSource_Select(TMx,TM_PROC);
    TM_Counter_Config(TMx, 0, 200);
    TM_TimerMode_Select(TMx, Separate);
    TM_CounterClock_Select(TMx, TM_CK_INT);
    TM_SetInternalClockDivider(TMx, TM_IntDIV1);
    TM_SetCounterDirection(TMx, TM_UpCount);
    TM_Counter_Cmd(TMx,ENABLE);
    
    //=======================================
    //Set GPIO status initial and GPIO mode.
    LED123_OFF;
    PINX_InitStruct.PINX_Mode				= PINX_Mode_PushPull_O;
    PINX_InitStruct.PINX_PUResistant        = PINX_PUResistant_Enable;
    PINX_InitStruct.PINX_Speed              = PINX_Speed_Low;
    PINX_InitStruct.PINX_OUTDrive           = PINX_OUTDrive_Level0;
    PINX_InitStruct.PINX_FilterDivider      = PINX_FilterDivider_Bypass;
    PINX_InitStruct.PINX_Inverse            = PINX_Inverse_Disable;
    PINX_InitStruct.PINX_Alternate_Function = 0;

    GPIO_PinMode_Config(LED1_PINSET,&PINX_InitStruct);
    GPIO_PinMode_Config(LED2_PINSET,&PINX_InitStruct);
    GPIO_PinMode_Config(LED3_PINSET,&PINX_InitStruct);
    
}

/**
 *******************************************************************************
 * @brief	    Software control PWM and control LED flow.
 * @details     
 * @return      No
 * @exception   No
 * @note                
 *******************************************************************************
 */
void LEDBreathing_main(void)
{
    if(TM_GetSingleFlagStatus(TMx,TMx_TOF)==DRV_Happened)
    {
        TM_ClearFlag(TMx,TMx_TOF);
        
        
        //====================================
        //One PWM cycle end.
        if(LED123_PWM_CNT==LED_PWM_MAX)
        {
            LED123_PWM_CNT = 0;
            LED123_TEMP_CNT = LED123_TEMP_CNT + 1;
            
            if(LED123_TEMP_CNT==LED123_TEMP_CNT_CMP)           
            {
                LED123_TEMP_CNT = 0;
                LEDBreathing_Drama();
            }
            
            //--------------------------------
            //Control PWM = 0
            if(LED_CTR[LED1_PWM_CMP]>LED_CTR[LED_PWM_CNT])
            {
                LED1_PIN = LED_ON;
            }
            if(LED_CTR[LED2_PWM_CMP]>LED_CTR[LED_PWM_CNT])
            {
                LED2_PIN = LED_ON;
            }
            if(LED_CTR[LED3_PWM_CMP]>LED_CTR[LED_PWM_CNT])
            {
                LED3_PIN = LED_ON;
            }
        }
        //====================================
        //Control PWM duty.
        else
        {
            if(LED_CTR[LED1_PWM_CMP]==LED_CTR[LED_PWM_CNT])
            {
                LED1_PIN = LED_OFF;
            }
            if(LED_CTR[LED2_PWM_CMP]==LED_CTR[LED_PWM_CNT])
            {
                LED2_PIN = LED_OFF;
            }
            if(LED_CTR[LED3_PWM_CMP]==LED_CTR[LED_PWM_CNT])
            {
                LED3_PIN = LED_OFF;
            }
            
            LED123_PWM_CNT = LED123_PWM_CNT + 1;
        }
    }
}
/**
 *******************************************************************************
 * @brief	    Control PWM value of LED and LED flow. 
 * @details     
 * @return      No
 * @exception   No
 * @note                
 *******************************************************************************
 */
static void LEDBreathing_Drama(void)
{
    uint8_t Tmp; 

    uint8_t LED_DramaShift;

    //================================================
    //Control LED1 ~ LED3 PWM value.
    LED1_SET_PWM(0);
    LED2_SET_PWM(0);
    LED3_SET_PWM(0);
    

    if(LED123_MODE==LED123_MODE_NORAML)
    {
        LED_DramaShift = (LED123_MAIN_STEP >> 1);
    }
    else
    {
        LED_DramaShift = ((LED123_SUB_STEP & 0x06) >> 1);
    }
    
    if(LED_DramaShift<3)
    {
        if((LED123_MAIN_STEP & 0x01)==0)
        {
            Tmp = LED_CTR[LED_SUB_STEP];
        }
        else
        {
            Tmp = (LED_CTR[LED_SUB_STEP_CMP] - LED_CTR[LED_SUB_STEP]);
        }
        LED_CTR[LED1_PWM_CMP + LED_DramaShift] = ((LED_PWM_MAX * (Tmp * Tmp))  ) / (LED123_SUB_STEP_CMP * LED123_SUB_STEP_CMP);
    }
    
    
    
    //==================================================
    //Control LED1 ~ LED3 flow.
    if(LED123_SUB_STEP<LED123_SUB_STEP_CMP)
    {
        LED123_SUB_STEP = LED123_SUB_STEP + 1;
    }
    else
    {
        if(LED123_MAIN_STEP == LED123_MAIN_STEP_CMP)
        {
            LED123_MAIN_STEP = 0;
            LED123_MODE = LED123_MODE_NORAML;
            LED123_MAIN_STEP_CMP = 0x05;
            LED123_SUB_STEP_CMP  = 150;                                           // control total images.
            LED123_TEMP_CNT_CMP = 4;                                              // control times in every image.
        }
        else
        {
            LED123_MAIN_STEP = LED123_MAIN_STEP + 1;
        }
        LED123_SUB_STEP = 0;
    }
}









