

/**
 ******************************************************************************
 *
 * @file        MG32_ARGB_ASB.c
 * @brief       Use ASB of APX to control ARGB .c file.
 
 * @par         Project
 *              MG32
 * @version     V1.01
 * @date        2025/06/10
 * @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_GPIO_DRV.h"
#include "MG32_EXIC_DRV.h"
#include "MG32_APX_DRV.h"
#include "MG32_ARGB.h"



#if defined(APX_ASB00_ASB0_EN_mask_w)

#include "MG32_ARGB_ASB.h"

/* Wizard menu ---------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
//GPIO related define
#define ARGB_PINX             PINA(8)                /*!< ARGB output pin*/
#define ARGB_AFS              2                      /*!< ARGB output pin alternate function.*/

//ARGB control module related define
#define ARGB_Module           APX
#define AGRG_Module_Channel   0
#define ARGB_IRQn             APX_IRQn   
#define ARGBModule_IRQHandler APX_IRQHandler 

#define ARGB_REG_INT          ARGB_Module->INT.W
#define ARGB_REG_STA          ARGB_Module->STA.W
#define ARGB_REG_CRX          ARGB_Module->ASB00.W
#define ARGB_REG_TXData       APX->ASBDAT.B[AGRG_Module_Channel] 

#define ARGB_STA_TX           APX_STA_ASB0_TXF_mask_w
#define ARGB_STA_TC           APX_STA_ASB0_TCF_mask_w

#define ARGB_CLEAR_BUF        APX_ASB00_ASB0_FCLR_mask_w

//Button interrupt related define
#define EXIC_GET_ID_SOURCE()  __DRV_EXIC_GET_ID31_SOURCE()
#define EXIC_SRC_ID           EXIC_SRC7_ID31_apx_b3

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static uint32_t ARGB_TotalCount;
static uint32_t ARGB_DataCount;
static uint8_t  *ARGB_Buf;

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

void ARGBModule_IRQHandler(void);

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


/**
 *******************************************************************************
 * @brief	    ASB of APX initial.
 * @details     
 * @return      
 * @exception   No
 * @note 
 *******************************************************************************
 */
void MG32_ARGB_Init(void)
{
    PIN_InitTypeDef      ARGB_PIN_Init;
    ASB_TypeDef          ASB_Common;
    ASBChannel_TypeDef   ASBChannel;
    
    
    //GPIO Inital
    ARGB_PIN_Init.PINX_Mode               = PINX_Mode_PushPull_O;
    ARGB_PIN_Init.PINX_PUResistant        = PINX_PUResistant_Disable;
    ARGB_PIN_Init.PINX_Speed              = PINX_Speed_Low;
    ARGB_PIN_Init.PINX_OUTDrive           = PINX_OUTDrive_Level0;
    ARGB_PIN_Init.PINX_FilterDivider      = PINX_FilterDivider_Bypass;
    ARGB_PIN_Init.PINX_Inverse            = PINX_Inverse_Disable;
    
    ARGB_PIN_Init.PINX_Alternate_Function = ARGB_AFS;
    GPIO_PinMode_Config(ARGB_PINX,&ARGB_PIN_Init);   
    
    /*
        Configure ASB Common part.
    */
    ASB_Common.SyncCode            = ASB_SYNCCODE_CODE0;            // ASB SYNC code = CODE0.
    ASB_Common.IdleStatus          = ASB_IDLESTATUS_LOW;            // ASB idle status is low.
    ASB_Common.ResetStatus         = ASB_RSTSTATUS_LOW;             // ASB Reset status is low.
    ASB_Common.ResetSync           = ASB_RST_SYNC_DISABLE;          // ASB RESET code synchronous mode disable.
    ASB_Common.ClockInverse        = ASB_CLOKC_INVERSE_DISABLE;     // ASB clock signal invers disable ( it is for ASB channel mode is SHFIT mode ( ex DotStar LEDs) 
    ASB_Common.BitTimePrescaler    = 2  - 1;                        // ASB Bit time clock source CK_ASB = CK_APX_PR / 2
    ASB_Common.BitTimeCounter      = 30 - 1;                        // Bit time = CK_ASB / 30                // CK_ASB     = 1.25us if CK_ASB is 24MHz                        
    ASB_Common.ResetTime           = 40 - 1;                        // Reset time  = Bit time * 40           // Reset time = 1.25 * 40 = 50us 
    ASB_Common.Code0_HighWidthTime = 8 - 1;                         // Code0's T0H = CK_ASB * 8              // T0H is about 0.3us and T0L is about 0.95 ( 1.25 - 0.3) in CK_ASB is 24MHz
    ASB_Common.Code1_HighWidthTime = 22 - 1;                        // Code1's T1H = CK_ASB * 22             // T1H is about 0.9us and T1L is about 0.35 ( 1.25 - 0.9) in CK_ASB is 24MHz
    APX_ASB_Config(&ASB_Common);
    
    /*
        Configure ASB Channel0 
    */
    ASBChannel.OutputMode       = ASB_MODE_ARGB;                    // Set ARGB Mode.        // ARGB ( NeoPixel LEDs) , ASB_MODE_SHIFT ( DotStar LEDs)
    ASBChannel.DataOrder        = ASB_DATA_MSB;                     // Data order is MSB.
    ASBChannel.DataInverse      = ASB_DATA_INVERSE_DISABLE;         // Data inverse disable
    ASBChannel.SignalInverse    = ASB_SIGNAL_INVERSE_DISABLE;       // Output inverse disable
    ASBChannel.PixelLength      = ASB_FRAME_PIXEL_3BYTE;            // ASB pixel byte is 3 bytes.
    ASBChannel.TX_FIFOThreshold = ASB_TX_FIFOTHRESHOLD_2BYTE;       // ASB Channel0 FIFO threshold is 2 bytes.
    APX_ASBChannel_Config( AGRG_Module_Channel , &ASBChannel);      // ASB Channel0 Inital 
    
    APX_ASBChannel_Cmd( AGRG_Module_Channel , ENABLE);              // ASB Channel0 output function enable.
    
    //========================================================
    //Enable URT Interrupt
    CLEAR_BIT( ARGB_REG_INT, ( ARGB_STA_TX | ARGB_STA_TC));

    APX_ITEA_Cmd(ARGB_Module,ENABLE);
    NVIC_EnableIRQ(ARGB_IRQn);
    
    
}
/**
 *******************************************************************************
 * @brief	   Trigger ARGB data update and using interrupt to continuous transmit.
 * @details 
 * @param[in]  uARGB_UpdateBuf: ARGB data transmit data buffer pointer.
 * @param[in]  uARGB_Count : ARGB data transmit total byte.
 * @return      
 * @exception  No
 * @note 
 *******************************************************************************
 */

void MG32_ARGB_SendData_IT(uint8_t *uARGB_UpdateBuf , uint32_t uARGB_Count)
{
    ARGB_TotalCount  = (uARGB_Count * SMP_ARGB_DATASIZE)-3;
    ARGB_Buf         = uARGB_UpdateBuf;
    ARGB_DataCount   = 3;
    
    SET_BIT( ARGB_REG_CRX , ARGB_CLEAR_BUF);
    while( APX_ASBChannel_GetResetStatus(AGRG_Module_Channel)!=0);                    // Check previous RESET signal already complete
    
    ARGB_REG_TXData = ARGB_Buf[0];
    ARGB_REG_TXData = ARGB_Buf[1];
    ARGB_REG_TXData = ARGB_Buf[2];
    
    
    SET_BIT( ARGB_REG_INT , ARGB_STA_TX);
}

/**
 *******************************************************************************
 * @brief	    ARGB interrupt handler function.
 * @details     
 * @return      
 * @exception   No
 * @note 
 *******************************************************************************
 */
void ARGBModule_IRQHandler(void)
{
    if( EXIC_GET_ID_SOURCE() & EXIC_SRC_ID)
    {
        ARGB_IRQHandler();
    }
}

/**
 *******************************************************************************
 * @brief	   Handle ARGB (URT) interrupt request. 
 * @details    
 * @return      
 * @note       No
 *******************************************************************************
 */
void ARGB_IRQHandler(void)
{
    uint32_t IRQHandler_Flag;
    uint8_t  DataCnt;


    IRQHandler_Flag = READ_REG(ARGB_REG_STA);                          // Get Interrupt flag.
    IRQHandler_Flag = (IRQHandler_Flag & READ_REG(ARGB_REG_INT));   // Get already enabled interrupt flag
     
    //===============================================================================================
    // In transmit.
    if( IRQHandler_Flag & ARGB_STA_TX)
    {
        DataCnt = 0;

        do{
            if(ARGB_TotalCount==0)
            {
                ARGB_REG_INT |= ARGB_STA_TC;
                ARGB_REG_INT &= (~ARGB_STA_TX);
                break;
            }
            ARGB_REG_TXData = ARGB_Buf[ARGB_DataCount];
            
            ARGB_DataCount  = ARGB_DataCount  + 1;
            ARGB_TotalCount = ARGB_TotalCount - 1;
            DataCnt         = DataCnt + 1;
        }while(DataCnt<2);
    }
    //===============================================================================================
    // Wrap up transmission 
    else if( READ_REG(ARGB_REG_STA) & ARGB_STA_TC)
    {
        ARGB_REG_INT &= (~ARGB_STA_TC);
        APX_ASBChannel_TriggerResetSignal(AGRG_Module_Channel);                   // Send RESET Signal
        ARGB_UpdateCpltCallback();
        return;
    }
}

/**
 *******************************************************************************
 * @brief	   ARGB data update  completion callback function.
 * @details     
 * @return      
 * @note       No
 *******************************************************************************
 */
__WEAK void ARGB_UpdateCpltCallback(void)
{
    //=========================================================
    //Note : This function should not be modified, when th callback
    //       is needed, the MID_URT_AbortReceiveCpltCallback can
    //       be implemented in the user file.
  
}

#endif





