
/**
 ******************************************************************************
 *
 * @file        LCDDEMO_RGBLED_API.c
 *
 * @brief       Demo RGB LED routine.
 *
 * @par         Project
 *              MG32x02z
 * @version     V1.02
 * @date        2022/09/26
 * @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 
 *      and violence against these laws. 
 ******************************************************************************
 ******************************************************************************
 */

/* Includes ------------------------------------------------------------------*/ 
#include "MG32x02z__Common_DRV.h"
#include "MG32x02z_GPIO_DRV.h"
#include "MG32x02z_URT_DRV.h"
#include "MG32x02z_RGBLED_API.h"

/* Wizard menu ---------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define  RGB1_URT   URT1

#define RGB1_R_PIN  PA1
#define RGB1_G_PIN  PA2
#define RGB1_B_PIN  PA0

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static uint32_t SW_RGB_CNT;

static uint8_t  *RGBX_CTR;

RGB_TYPE RGB1;

/* Private function prototypes -----------------------------------------------*/
void API_LED_Plusing_Drama(void);
void API_RGB_Percentage_Table(uint8_t BR_STEP , uint8_t BR_BASE,uint8_t type);
void API_RGB_STEP(void);
void API_RGB_Breathing_Drama(void);
void API_RGB_Spectrum_Inital(void);
void API_RGB_Spectrum_Drama(void);
void API_RGBPWM_Config(RGB_TYPE* RGBX);
void URT123_IRQHandler(void);

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

/**
 *******************************************************************************
 * @brief       
 * @details     
 * @return      
 * @exception   No
 * @note
 * @par         Example
 * @code
 * @endcode
 *******************************************************************************
 */
void API_RGBLED_Init(void)
{

    URT_BRG_TypeDef     URT_BRGStruct;

    //---------------------------------------------------------------------------
    // RGB LED pin inital
    RGB1_RGB_OFF();

    GPIO_PinFunction_Select(PINA(0), 0);
    GPIO_PinFunction_Select(PINA(1), 0);
    GPIO_PinFunction_Select(PINA(2), 0);

    // ------------------------------------------------------------------------
    //RGB Control Timer Inital (use URT3 Timeout timer overflow

    URT_BRGStruct.URT_InternalClockSource    = URT_BDClock_PROC;
    URT_BRGStruct.URT_BaudRateMode           = URT_BDMode_Combined;
    URT_BRGStruct.URT_PrescalerCounterReload = 0x07;
    URT_BRGStruct.URT_BaudRateCounterReload  = 0x53;
    URT_BaudRateGenerator_Config(RGB1_URT,&URT_BRGStruct); 

    URT_ITEA_Cmd(RGB1_URT,ENABLE);
    NVIC_EnableIRQ(URT123_IRQn);

    //=========================================================================
    // RGB Mode :
    //    1. Static    Mode : The mode can change color.
    //    2. Pulsing   Mode : The mode can change color.
    //    3. Breath    Mode : The mode can change color.
    //    4. Spectrum  Mode : The mode can't change color.
    //    5. OFF       Mode : Disable RGB , Counter and Relationship Interrupt. 
    //-------------------------------------------------------------------------
    //Default Mode and Color.
    API_RGBColor_Select( &RGB1, 128 , 128 , 128);
    API_RGBMode_Select( &RGB1 , RGB_Mode_SPECTRUM);
//    API_RGBMode_Select( &RGB1 , RGB_Mode_STATIC);
//    API_RGBMode_Select( &RGB1 , RGB_Mode_PULSING);
//    API_RGBMode_Select( &RGB1 , RGB_Mode_BREATH);
//    API_RGBMode_Select( &RGB1 , RGB_Mode_SPECTRUM);
//    API_RGBMode_Select( &RGB1 , RGB_Mode_OFF);
}

/**
 *******************************************************************************
 * @brief       
 * @details     
 * @return      
 * @exception   No
 * @note
 * @par         Example
 * @code
 * @endcode
 *******************************************************************************
 */
void API_RGB_Percentage_Table(uint8_t BR_STEP , uint8_t BR_BASE,uint8_t type)
{
    uint8_t i;
    uint16_t Tmp;
    for(i=0;i<3;i++)
    {
        Tmp = BR_STEP * RGBX_CTR[RGB_COLOR_R_TABLE + i];
        RGBX_CTR[RGB_COLOR_R + i] = (uint8_t)(255 - (Tmp/BR_BASE));
        if(type!=0)
        {
            Tmp = BR_STEP * RGBX_CTR[RGB_COLOR_R_TABLE + i];
            RGBX_CTR[RGB_COLOR_R + i] = (uint8_t)(255 - (Tmp / BR_BASE));
        }
    }
}

/**
 *******************************************************************************
 * @brief       
 * @details     
 * @return      
 * @exception   No
 * @note
 * @par         Example
 * @code
 * @endcode
 *******************************************************************************
 */
void API_RGB_STEP(void)
{
    if(RGBX_CTR[RGB_SUB_STEP] < RGBX_CTR[RGB_SUB_STEP_CMP])
    {
        RGBX_CTR[RGB_SUB_STEP] = RGBX_CTR[RGB_SUB_STEP] + 1;
    }
    else
    {
        if(RGBX_CTR[RGB_MAIN_STEP]== RGBX_CTR[RGB_MAIN_STEP_CMP])
        {
            RGBX_CTR[RGB_MAIN_STEP] = 0;
        }
        else
        {
            RGBX_CTR[RGB_MAIN_STEP] = RGBX_CTR[RGB_MAIN_STEP] + 1;
        }
        RGBX_CTR[RGB_SUB_STEP] = 0;
    }
}

/**
 *******************************************************************************
 * @brief       
 * @details     
 * @return      
 * @exception   No
 * @note
 * @par         Example
 * @code
 * @endcode
 *******************************************************************************
 */
void API_LED_Plusing_Drama(void)
{
    uint8_t Tmp;

    Tmp = RGBX_CTR[RGB_SUB_STEP] % 2;
    if(Tmp ==0)
    {
        for(Tmp = 0; Tmp<RGB_LEN ; Tmp++)
        {
            RGBX_CTR[RGB_COLOR_R+Tmp] = 255 - 0;
        }
    }
    else
    {
        RGBX_CTR[RGB_COLOR_R] = 255 - RGBX_CTR[RGB_COLOR_R_TABLE];
        RGBX_CTR[RGB_COLOR_G] = 255 - RGBX_CTR[RGB_COLOR_G_TABLE];
        RGBX_CTR[RGB_COLOR_B] = 255 - RGBX_CTR[RGB_COLOR_B_TABLE];
    }
    API_RGB_STEP();
}
/**
 *******************************************************************************
 * @brief       
 * @details     
 * @return      
 * @exception   No
 * @note
 * @par         Example
 * @code
 * @endcode
 *******************************************************************************
 */
void API_RGB_Breathing_Drama(void)
{
    if(RGBX_CTR[RGB_MAIN_STEP] == 0)
    {
        API_RGB_Percentage_Table(RGBX_CTR[RGB_SUB_STEP],RGBX_CTR[RGB_SUB_STEP_CMP],1);
    }
    else
    {
        API_RGB_Percentage_Table(RGBX_CTR[RGB_SUB_STEP_CMP]-RGBX_CTR[RGB_SUB_STEP],RGBX_CTR[RGB_SUB_STEP_CMP],1);
    }
    API_RGB_STEP();
}

/**
 *******************************************************************************
 * @brief       
 * @details     
 * @return      
 * @exception   No
 * @note
 * @par         Example
 * @code
 * @endcode
 *******************************************************************************
 */
#define RGB_BRIGHT     5

void API_RGB_Spectrum_Inital(void)
{
    RGBX_CTR[RGB_COLOR_R] = 255 - 255;
    RGBX_CTR[RGB_COLOR_G] = 255 - RGB_BRIGHT;
    RGBX_CTR[RGB_COLOR_B] = 255 - 0;
}

/**
 *******************************************************************************
 * @brief       
 * @details     
 * @return      
 * @exception   No
 * @note
 * @par         Example
 * @code
 * @endcode
 *******************************************************************************
 */
void API_RGB_Spectrum_Drama(void)
{
    API_RGB_STEP();

    if(RGBX_CTR[RGB_MAIN_STEP]==0)
    {
        if(RGBX_CTR[RGB_SUB_STEP]==1)
        {
            API_RGB_Spectrum_Inital();
        }
        RGBX_CTR[RGB_COLOR_G] = RGBX_CTR[RGB_COLOR_G] - RGB_BRIGHT;
    }
    else if(RGBX_CTR[RGB_MAIN_STEP]==1)
    {
        RGBX_CTR[RGB_COLOR_R] = RGBX_CTR[RGB_COLOR_R] + RGB_BRIGHT;
    }
    else if(RGBX_CTR[RGB_MAIN_STEP]==2)
    {
        RGBX_CTR[RGB_COLOR_B] = RGBX_CTR[RGB_COLOR_B] - RGB_BRIGHT;
    }
    else if(RGBX_CTR[RGB_MAIN_STEP]==3)
    {
        RGBX_CTR[RGB_COLOR_G] = RGBX_CTR[RGB_COLOR_G] + RGB_BRIGHT;   
    }
    else if(RGBX_CTR[RGB_MAIN_STEP]==4)
    {
        RGBX_CTR[RGB_COLOR_R] = RGBX_CTR[RGB_COLOR_R] - RGB_BRIGHT;
    }
    else if(RGBX_CTR[RGB_MAIN_STEP]==5)
    { 
        RGBX_CTR[RGB_COLOR_B] = RGBX_CTR[RGB_COLOR_B] + RGB_BRIGHT;
    }
}

/**
 *******************************************************************************
 * @brief       
 * @details     
 * @return      
 * @exception   No
 * @note
 * @par         Example
 * @code
 * @endcode
 *******************************************************************************
 */
void API_RGBPWM_Config(RGB_TYPE* RGBX)
{
    RGBX_CTR = &(RGBX->RGB_CTR[RGB_COLOR_R_TABLE]);

    switch(RGBX->RGB_MODE)
    {
        case RGB_Mode_STATIC:
                                RGBX->RGB_CTR[RGB_COLOR_R] = 255 - RGBX->RGB_CTR[RGB_COLOR_R_TABLE];
                                RGBX->RGB_CTR[RGB_COLOR_G] = 255 - RGBX->RGB_CTR[RGB_COLOR_G_TABLE];
                                RGBX->RGB_CTR[RGB_COLOR_B] = 255 - RGBX->RGB_CTR[RGB_COLOR_B_TABLE];
                                break;
        case RGB_Mode_PULSING:
                                API_LED_Plusing_Drama();
                                break;
        case RGB_Mode_BREATH:
                                API_RGB_Breathing_Drama();
                                break;
        case RGB_Mode_SPECTRUM:
                                API_RGB_Spectrum_Drama();
                                break;
        case RGB_Mode_OFF:
                                RGBX->RGB_CTR[RGB_COLOR_R] = 255 - 0;
                                RGBX->RGB_CTR[RGB_COLOR_G] = 255 - 0;
                                RGBX->RGB_CTR[RGB_COLOR_B] = 255 - 0;
                                return;
    }
}
/**
 *******************************************************************************
 * @brief       
 * @details     
 * @return      
 * @exception   No
 * @note
 * @par         Example
 * @code
 * @endcode
 *******************************************************************************
 */
void API_RGBMode_Select(RGB_TYPE* RGBX, RGB_MODE_TYPE RGB_Mode)
{
    RGBX->RGB_SWITCH = RGB_OFF;
    RGBX->RGB_MODE   = RGB_Mode;

    URT_BaudRateGenerator_Cmd(RGB1_URT,DISABLE);
    URT_IT_Config(RGB1_URT,(URT_IT_BRT | URT_IT_UG),DISABLE);
    URT_ClearITFlag( RGB1_URT , (URT_IT_BRT | URT_IT_UG));

    RGB1_RGB_OFF();
    
    RGBX->RGB_CTR[RGB_MAIN_STEP] = 0;
    RGBX->RGB_CTR[RGB_SUB_STEP]  = 0;
    RGBX->RGB_CTR[RGB_TEMPO_CNT] = 0;
    
    SW_RGB_CNT = 0;
    
    switch(RGB_Mode)
    {
        case RGB_Mode_STATIC:
                                 RGBX->RGB_CTR[RGB_TEMPO_CNT_CMP] = 1;
                                 break;
        case RGB_Mode_PULSING:
                                 RGBX->RGB_CTR[RGB_MAIN_STEP_CMP] = 1 - 1;
                                 RGBX->RGB_CTR[RGB_SUB_STEP_CMP]  = 2 - 1;
                                 RGBX->RGB_CTR[RGB_TEMPO_CNT_CMP] = 75;
                                 break;
        case RGB_Mode_BREATH:
                                 RGBX->RGB_CTR[RGB_MAIN_STEP_CMP] = 2 - 1;
                                 RGBX->RGB_CTR[RGB_SUB_STEP_CMP]  = 80 - 1;
                                 RGBX->RGB_CTR[RGB_TEMPO_CNT_CMP] = 2;
                                 break;
        case RGB_Mode_SPECTRUM:
                      
                                 RGBX->RGB_CTR[RGB_MAIN_STEP_CMP] = 6 - 1;
                                 RGBX->RGB_CTR[RGB_SUB_STEP_CMP]  = 51 - 1;        //RGBX->RGB_CTR[RGB_SUB_STEP_CMP]  * RGB_BRIGHT = 255
                                 RGBX->RGB_CTR[RGB_TEMPO_CNT_CMP] = 2;
                                 break;
        case RGB_Mode_OFF:
                                 RGBX->RGB_MODE = RGB_Mode_OFF;
                                 return;
    }

    API_RGBPWM_Config(RGBX);

    RGBX->RGB_SWITCH = RGB_ON;
    URT_ClearITFlag( RGB1_URT , (URT_IT_BRT | URT_IT_UG));
    URT_IT_Config(RGB1_URT,(URT_IT_BRT | URT_IT_UG), ENABLE);
    URT_BaudRateGenerator_Cmd(RGB1_URT, ENABLE);
}

/**
 *******************************************************************************
 * @brief       
 * @details     
 * @return      
 * @exception   No
 * @note
 * @par         Example
 * @code
 * @endcode
 *******************************************************************************
 */
void API_RGBColor_Select(RGB_TYPE* RGBX, uint8_t RGB_R_Param , uint8_t RGB_G_Param , uint8_t RGB_B_Param)
{
    RGBX->RGB_SWITCH                 = RGB_OFF;
    RGBX->RGB_CTR[RGB_COLOR_R_TABLE] = RGB_R_Param;
    RGBX->RGB_CTR[RGB_COLOR_G_TABLE] = RGB_G_Param;
    RGBX->RGB_CTR[RGB_COLOR_B_TABLE] = RGB_B_Param;
    RGBX->RGB_SWITCH                 = RGB_ON;
}



/**
 *******************************************************************************
 * @brief       
 * @details     
 * @return      
 * @exception   No
 * @note
 * @par         Example
 * @code
 * @endcode
 *******************************************************************************
 */
void URT123_IRQHandler(void)
{
    URT_ClearITFlag( RGB1_URT , (URT_IT_BRT | URT_IT_UG));

    if( RGB1.RGB_SWITCH == RGB_OFF)
    {
        RGB1_RGB_OFF();
        return;
    }

    if( SW_RGB_CNT == RGB1.RGB_CTR[RGB_COLOR_R])
    {
        RGB1_R_PIN  = 0;
    }
    if( SW_RGB_CNT == RGB1.RGB_CTR[RGB_COLOR_G])
    {
        RGB1_G_PIN  = 0;
    }
    if( SW_RGB_CNT == RGB1.RGB_CTR[RGB_COLOR_B])
    {
        RGB1_B_PIN  = 0;
    }

    SW_RGB_CNT = SW_RGB_CNT + 1;
    
    if( SW_RGB_CNT == 255)
    {
        RGB1_RGB_OFF();

        if( RGB1.RGB_CTR[RGB_TEMPO_CNT] == RGB1.RGB_CTR[RGB_TEMPO_CNT_CMP])
        {
            API_RGBPWM_Config(&RGB1);
            RGB1.RGB_CTR[RGB_TEMPO_CNT] = 0;
        }
        else
        {
            RGB1.RGB_CTR[RGB_TEMPO_CNT] = RGB1.RGB_CTR[RGB_TEMPO_CNT] + 1;
        }

        SW_RGB_CNT = 0;
    }
}


