
/**
 ******************************************************************************
 *
 * @file        MG32_ARGB.c
 * @brief       The code is to control ARGB.
 
 * @par         Project
 *              MG32
 * @version     V1.00
 * @date        2024/10/04
 * @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.
 *******************************************************************************
 *******************************************************************************
 */
 

/* Includes ------------------------------------------------------------------*/
#include "MG32__Common_DRV.h"
#include "MG32_GPIO_DRV.h"
#include "MG32_EXIC_DRV.h"
#include "MG32_TM_DRV.h"
#include "MG32_ARGB.h"
#include "MG32_ARGB_Drama.h"
#include "MG32_ARGB_ASB.h"

/* Wizard menu ---------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
//GPIO Related
//Button
#define BUTTON_PINX              PINA(0)
#define BUTTON_PIN               PA0

//EXIC Related
//Button
#define BUTTON_EXIC_PX           EXIC_PA
#define BUTTON_EXIC_TRGS_PINX    EXIC_TRGS_PIN0
#define BUTTON_EXIC_PX_PINX      EXIC_PX_PIN0
#define BUTTON_EXIC_PX_IT        EXIC_PA_IT
#define BUTTON_EXIC_PX_ITF       EXIC_PA_ITF
#define BUTTON_EXINTX_IRQn       EXINT0_IRQn
#define BUTTON_EXINTX_IRQHandler EXINT0_IRQHandler


/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static uint8_t volatile  ARGB_UpdateFlag;                  /*!< Calculate next data flag.*/
static uint8_t volatile  ARGB_State;                       /*!< ARGB state information.*/
       
       uint8_t           SMP_ARGBDefault_TABLE[SMP_ARGB_DEFAULT_COLOR][3] = {
                                                                              {   0 ,  50 ,   0},    // ARGB0 (Input first): [G : R : B ] = [  0, 50,  0]
                                                                              {  50 ,  50 ,   0},    // ARGB1              : [G : R : B ] = [ 50, 50,  0]
                                                                              {  50 ,   0 ,   0},    // ARGB2              : [G : R : B ] = [ 50,  0,  0] 
                                                                              {  50 ,   0 ,  50},    // ARGB3              : [G : R : B ] = [ 50,  0, 50] 
                                                                              {   0 ,   0 ,  50},    // ARGB4              : [G : R : B ] = [  0,  0, 50] 
                                                                              {   0 ,  50 ,  50}     // ARGB5              : [G : R : B ] = [  0, 50, 50]
                                                                            };
       
static uint8_t MG32_ARGB_UpdateBuf[SMP_ARGB_PIECE*SMP_ARGB_DATASIZE];  /*!< ARGB update buffer.*/   
                                                                            
                                                                            
/* Private function prototypes -----------------------------------------------*/                                                            

void EXINT0_IRQHandler(void);                                                                  
void TM0x_IRQHandler(void);

void MG32_ARGB_CloseAll(void); 
void MG32_ARGB_ChangeDramaMode(void);
void MG32_ARGB_Update(uint8_t *ARGB_UpdateBuf, uint32_t UpDate_ARGBCount);
void MG32_ARGB_UpdateTrigger( uint8_t  ARGB_Mode);

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


                                                           
/**
 *******************************************************************************
 * @brief	   Close the all ARGB.  
 * @details     
 * @note       Close ARGB piece according to SMP_ARGB_PIECE
 *******************************************************************************
 */
void MG32_ARGB_CloseAll(void)
{
    uint32_t ARGB_CloseAllTmp = 0;
    
    MG32_ARGBDrama_ClearBuf(&ARGB_Drama);
    
    ARGB_Drama.UpdateTRG |= ARGB_UPDATE_DATA;
    
    MG32_ARGB_Update(&ARGB_DramaBuf[0][0],SMP_ARGB_PIECE);
    
    while( ARGB_State!= ARGB_READY);
 
    /*Keep all ARGB go out for a while*/
    do{
        if(ARGB_UpdateFlag==1)
        {
            ARGB_UpdateFlag  = 0;
            ARGB_CloseAllTmp = ARGB_CloseAllTmp + 1;
        }
    }while(ARGB_CloseAllTmp<10);
}
/**
 *******************************************************************************
 * @brief	   Update ARGB status.
 * @details     
 * @param[in]  ARGB_UpdateBuf : Update ARGB data buffer pointer.
 * @param[in]  UpDate_ARGBCount : Update ARGB pieces.     
 * @note       
 *******************************************************************************
 */
void MG32_ARGB_Update(uint8_t *ARGB_UpdateBuf, uint32_t UpDate_ARGBCount)
{
    uint32_t MG32_ARGB_UpdateTmp;
    
    if((ARGB_Drama.UpdateTRG & ARGB_UPDATE_DATA) && ARGB_State == ARGB_READY)
    {
        ARGB_Drama.UpdateTRG &= (~ARGB_UPDATE_DATA);
        
        for( MG32_ARGB_UpdateTmp = 0; MG32_ARGB_UpdateTmp < (UpDate_ARGBCount * SMP_ARGB_DATASIZE); MG32_ARGB_UpdateTmp++)
        {
            MG32_ARGB_UpdateBuf[MG32_ARGB_UpdateTmp]= ARGB_UpdateBuf[MG32_ARGB_UpdateTmp];
        }
        
        ARGB_State = ARGB_BUSY;
        MG32_ARGB_SendData_IT( &MG32_ARGB_UpdateBuf[0] , UpDate_ARGBCount);
    }
}

/**
 *******************************************************************************
 * @brief	   To sample ARGB control.
 * @details    By Wizard of MG32_ARGB.h to select ,using which module to update ARGB.
 * @return      
 * @note       No
 *******************************************************************************
 */
void MG32_ARGB_Main(void)
{
    PIN_InitTypeDef  PINX_InitStruct;
    EXIC_TRGSTypeDef EXIC_TRGS;
    
    //*. GPIO Initial (Button GPIO inital):
    PINX_InitStruct.PINX_Mode				= PINX_Mode_OpenDrain_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(BUTTON_PINX,&PINX_InitStruct);                                        // External input interrupt pin = PA0 (open drain with pull-up mode)
    
    
    //*. EXIC Initial (Button EXIC inital)
    EXIC_TRGS.EXIC_Pin       = BUTTON_EXIC_TRGS_PINX ;
    EXIC_TRGS.EXIC_TRGS_Mode = Edge;
    EXIC_PxTriggerMode_Select(BUTTON_EXIC_PX,&EXIC_TRGS);
    
    EXIC_PxTriggerOrMask_Select(BUTTON_EXIC_PX, BUTTON_EXIC_PX_PINX);
    
    EXIC_PxTriggerITEA_Cmd(BUTTON_EXIC_PX_IT , ENABLE);
    NVIC_EnableIRQ( BUTTON_EXINTX_IRQn);
    
    
    //*. Set Timer to count interval of ARGB update drama 
    //   (1). Here use TM00.
    //   (2). TM00 clock source from LS and divider 1.
    //   (3). TM00 is full counter mode.
    //   (4). TM00 overflow time is about 10 ms. ( 320 / 32KHz)
    //   (5). Enable TM00 interrupt.
    TM_InternalClockSource_Select( TM00 , TM_CK_LS);
    TM_SetInternalClockDivider(TM00, TM_IntDIV1);
    TM_CounterClock_Select(  TM00, TM_CK_INT);
    TM_PrescalerClock_Select(TM00, TM_CK_INT);
    
    TM_TimerMode_Select(TM00, Full_Counter);                            
    
    TM_Prescaler_Config( TM00 , 0x3F , 0x3F);                           
    TM_Counter_Config( TM00 , 0x01, 0x01);              
    
    TM_IT_Config( TM00 , TMx_TIE_IE , ENABLE);
    TM_ITEA_Cmd( TM00 , ENABLE);
    NVIC_EnableIRQ(TM0x_IRQn);
    
    TM_Timer_Cmd( TM00 , ENABLE);


    //*. ARGB Related Initial.
    ARGB_State = ARGB_BUSY;
    
    MG32_ARGB_Init();
    MG32_ARGBDrama_Init();
    
    ARGB_State = ARGB_READY;
  
    if( ARGB_State != ARGB_FAIL)
    {
        //------------------------------------------------------------------   
        //*. ARGB default mode is static color mode.
        MG32_ARGBDrama_ChangeMode(ARGB_DRAMA_STATIC);
        
        //------------------------------------------------------------------
        //Clear All ARGB according to SMP_ARGB_PIECE.
        MG32_ARGB_CloseAll();

        //------------------------------------------------------------------
        ARGB_UpdateFlag  = 0;                                                                     // Clear ARGB update software flag.
        
        //================================================================================================
        // It is main function of ARGB sample code. 
        while(1) 
        {
            //-----------------------------------------------------------------
            //Update ARGB Disaplay Mode.
            if( ARGB_Drama.UpdateTRG & ARGB_UPDATE_MODE)                                              // To detect whether ARG mode be changed or not.
            {
                MG32_ARGBDrama_UpdateMode(&ARGB_Drama);
                
                MG32_ARGB_CloseAll();
                ARGB_UpdateFlag = 0;
            }
            else
            {
                //------------------------------------------------------------------
                //Update Data To ARGB 
                MG32_ARGB_Update( &ARGB_DramaBuf[0][0] , SMP_ARGB_PIECE);
            }
            //-----------------------------------------------------------------
            //Calculate ARGB next data.
            if( ARGB_UpdateFlag == 1)                                          
            {
                ARGB_UpdateFlag = 0;
                MG32_ARGBDrama_UpdateData(&ARGB_Drama);
            }
        }
    }
}

/**
 *******************************************************************************
 * @brief	   Change ARGB display mode.
 * @details    
 * @return      
 * @note       
 *******************************************************************************
 */
void MG32_ARGB_ChangeDramaMode(void)
{
    if( ARGB_Drama.DramaMode == ARGB_DRAMA_2MOVING)
    {
        MG32_ARGBDrama_ChangeMode(ARGB_DRAMA_DISABLE);
    }
    else
    {
        MG32_ARGBDrama_ChangeMode(ARGB_Drama.DramaMode + 1);
    }
}

/**
 *******************************************************************************
 * @brief	   Exteranl input interrupt pin of PortA handle function.
 * @details     
 * @return      
 * @note       No
 *******************************************************************************
 */
void BUTTON_EXINTX_IRQHandler(void)
{
    uint32_t EXINT0IRQ_Debounce = 0;
    
    
    MG32_ARGB_ChangeDramaMode();
    ARGB_Drama.UpdateTRG  = ARGB_UPDATE_MODE;
    
    do
    {
        if(BUTTON_PIN ==0)
        {
            EXINT0IRQ_Debounce = 0;
        }
        else
        {
            EXINT0IRQ_Debounce = EXINT0IRQ_Debounce + 1;
        }
    }while( EXINT0IRQ_Debounce < 5000);
    
    
    EXIC_ClearPxTriggerEventFlag(BUTTON_EXIC_PX , BUTTON_EXIC_PX_PINX);
    EXIC_ClearPxTriggerITFlag( BUTTON_EXIC_PX_ITF , EXIC_PX_OF);
    
}



/**
 *******************************************************************************
 * @brief	   TM0x IRQHandle function.
 * @details     
 * @return      
 * @note       No
 *******************************************************************************
 */
void TM0x_IRQHandler(void)
{
    ARGB_UpdateFlag = 1;                       // Set ARGB update software flag.
    
    TM_ClearFlag( TM00 , TMx_TOF);
    
}


/**
 *******************************************************************************
 * @brief	   ARGB_Drama complete updating control parameter callback function.
 * @details     
 * @return      
 * @note       No
 *******************************************************************************
 */
void MG32_ARGBDrama_UpdateModeCallback(void)
{
    ARGB_UpdateFlag = 0;
}


/**
 *******************************************************************************
 * @brief	   ARGB data update  completion callback function.
 * @details     
 * @return      
 * @note       No
 *******************************************************************************
 */
void ARGB_UpdateCpltCallback(void)
{
    ARGB_State = ARGB_READY;
}


