

/**
 ******************************************************************************
 *
 * @file        MG32x02z_LCD.c
 * @brief       The code is Using SPI of MG32x02z to control ILI9341 
 *
 * @par         Project
 *              MG32x02z
 * @version     V1.00
 * @date        2023/01/03
 * @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 "MG32x02z_Common.h"
#include "MG32x02z_SmartCard_API.h"
#include "MG32x02z_SPILCD_API.h"
#include "MG32x02z_LCD.h"


/* Wizard menu ---------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/

uint8_t  LCD_Refresh;
uint8_t  LCD_RefreshDataType;
uint32_t LCD_RefreshErrorStatus;

static  uint32_t SmartCard_ATR_Fi_Table[16] = {372,372,558,744,1116,1488,1860,372,372,512,768,1024,1536,2048,372,372};
static  uint8_t  SmartCard_ATR_Di_Table[16] = {1,1,2,4,8,16,32,64,12,20,1,1,1,1,1,1};


static  char LCD_StringBuf[132];


/* Private function prototypes -----------------------------------------------*/
static void MG32x02z_LCD_ShowBackground(void);
static void MG32x02z_LCD_ShowCardDetectedStatus( uint8_t CardInserted_Flag);
static void MG32x02z_LCD_ShowATRData(void);
static void MG32x02z_LCD_ShowGlobalInterfaceByte(void);
static void MG32x02z_LCD_ShowSpecificInterfaceByte(void);
static void MG32x02z_LCD_ShowHistoricalByte(void);
static void MG32x02z_LCD_ShowError(void);

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


/**
 *******************************************************************************
 * @brief	    LCD inital callback function.
 * @details     
 * @return      
 * @exception   No
 * @note        
 *******************************************************************************
 */
void BSP_LCD_InitCallback(void)
{
    MG32x02z_LCD_Init();
}

/**
 *******************************************************************************
 * @brief	    LCD inital function.
 * @details     
 * @return      
 * @exception   No
 * @note        
 *******************************************************************************
 */
void MG32x02z_LCD_Init(void)
{
    /*LCD show background.*/
    MG32x02z_LCD_ShowBackground();
    
    /*Initial parameter*/
    LCD_Refresh         = 1;
    LCD_RefreshDataType = LCD_REFRESH_DATATYPE_NO; 
}

/**
 *******************************************************************************
 * @brief	   LCD display drama control function. 
 * @details     
 * @return      
 * @exception  No. 
 * @note        
 *******************************************************************************
 */
void MG32x02z_LCD_main(void)
{
    if(LCD_Refresh==0)
    {
        return;   
    }    
    LCD_Refresh = 0;
    
        
    /*When detecting card remove clear ATR data in the LCD.*/
    if( SmartCard_CTR.Status.MBIT.Inserted == 0)
    {
        MG32x02z_LCD_ShowCardDetectedStatus(SmartCard_CTR.Status.MBIT.Inserted);
        BSP_LCD_FillMonochrome(0,(LCD_STRING_SIZE*3),LCD_CTR.Width,LCD_CTR.Height,BLACK);
        return;
    }  
    /*When detected card insert show ATR data in the LCD.*/
    
    MG32x02z_LCD_ShowCardDetectedStatus(SmartCard_CTR.Status.MBIT.Inserted);
    
    switch(LCD_RefreshDataType)
    {
        case LCD_REFRESH_DATATYPE_ATR:
                                      MG32x02z_LCD_ShowATRData();
                                      MG32x02z_LCD_ShowGlobalInterfaceByte();
                                      MG32x02z_LCD_ShowSpecificInterfaceByte();
                                      MG32x02z_LCD_ShowHistoricalByte();
                                      break;
        case LCD_REFRESH_DATATYPE_ERR:
                                      MG32x02z_LCD_ShowError();
                                      break;
        default:
                                      break;            
    }
    
    LCD_RefreshDataType = LCD_REFRESH_DATATYPE_NO;
}


/**
 *******************************************************************************
 * @brief	   Show background.
 * @details     
 * @return      
 * @exception  No 
 * @note        
 *******************************************************************************
 */
static void MG32x02z_LCD_ShowBackground(void)
{
    /*Show LCD Background */
    //Background color.
    BSP_LCD_Clear(BLACK);

    //Card Detected status
    BSP_LCD_ShowString(0,(LCD_STRING_SIZE*1),((LCD_STRING_SIZE / 2)*14),LCD_STRING_SIZE,GREEN,"Card Detected:");
}

/**
 *******************************************************************************
 * @brief	  Show card status.
 * @details     
 * @return      
 * @exception No  
 * @note        
 *******************************************************************************
 */   
static void MG32x02z_LCD_ShowCardDetectedStatus( uint8_t CardInserted_Flag)
{
    uint16_t LCD_CDStatuBGColor;
    uint16_t LCD_CDStatuStringColor;
    
    if( CardInserted_Flag == SmartCard_FALSE)
    {
        sprintf(LCD_StringBuf,"  No");
        
        LCD_CDStatuBGColor     = RED;
        LCD_CDStatuStringColor = YELLOW; 
    }
    else
    {
        sprintf(LCD_StringBuf," YES");
        
        LCD_CDStatuBGColor     = GREEN;
        LCD_CDStatuStringColor = BLACK;
    }

    BSP_LCD_FillMonochrome(((LCD_STRING_SIZE / 2)*14),(LCD_STRING_SIZE*1),((LCD_STRING_SIZE / 2)*19),(LCD_STRING_SIZE*2),LCD_CDStatuBGColor);
    BSP_LCD_ShowString(((LCD_STRING_SIZE / 2)*14),(LCD_STRING_SIZE*1),((LCD_STRING_SIZE / 2)*4),LCD_STRING_SIZE,LCD_CDStatuStringColor,LCD_StringBuf);
    
}

/**
 *******************************************************************************
 * @brief	    Show Answer-to-Reset.
 * @details     
 * @return      
 * @exception   No
 * @note        
 *******************************************************************************
 */
static void MG32x02z_LCD_ShowATRData(void)
{
    uint8_t LCD_ShowATRDataTmp;
    uint8_t LCD_pShowATRData;
    
    BSP_LCD_ShowString(0,(LCD_STRING_SIZE*3),((LCD_STRING_SIZE / 2)*9),LCD_STRING_SIZE,GREEN,"ATR Data:");
    
    LCD_pShowATRData = 0;
    
    LCD_pShowATRData += sprintf(LCD_StringBuf,"%02Xh,%02Xh,",SmartCard_CTR.ATR.TS,SmartCard_CTR.ATR.T0);

    for(LCD_ShowATRDataTmp=0;LCD_ShowATRDataTmp<SmartCard_CTR.ATR.InterfaceLength;LCD_ShowATRDataTmp++)
    {
        LCD_pShowATRData += sprintf((LCD_StringBuf + LCD_pShowATRData),"%02Xh,", SmartCard_CTR.ATR.Interface[LCD_ShowATRDataTmp]);
    }
    for(LCD_ShowATRDataTmp=0;LCD_ShowATRDataTmp<SmartCard_CTR.ATR.HistoricalLength;LCD_ShowATRDataTmp++)
    {
        LCD_pShowATRData += sprintf((LCD_StringBuf + LCD_pShowATRData),"%02Xh,", SmartCard_CTR.ATR.Historical[LCD_ShowATRDataTmp]);
    }
    if(SmartCard_CTR.ATR.TCK_present==1)
    {
        LCD_pShowATRData += sprintf((LCD_StringBuf + LCD_pShowATRData),"%02Xh,", SmartCard_CTR.ATR.TCK);
    }   
    
    BSP_LCD_ShowString(((LCD_STRING_SIZE / 2)*2),(LCD_STRING_SIZE*4),((LCD_STRING_SIZE / 2)*28),(LCD_STRING_SIZE*5),YELLOW,LCD_StringBuf);
}

/**
 *******************************************************************************
 * @brief	    Show global interface bytes.
 * @details     
 * @return      
 * @exception   No
 * @note        
 *******************************************************************************
 */
static void MG32x02z_LCD_ShowGlobalInterfaceByte(void)
{
    /*Show Clock rate conversion integer (Fi), the baud rate adjustmetn integer (Di)*/
    sprintf(LCD_StringBuf,"F = %d,D = %d",SmartCard_ATR_Fi_Table[SmartCard_CTR.GITByte.Fi],SmartCard_ATR_Di_Table[SmartCard_CTR.GITByte.Di]);
    BSP_LCD_ShowString(((LCD_STRING_SIZE / 2)*0),(LCD_STRING_SIZE*9),((LCD_STRING_SIZE / 2)*15),(LCD_STRING_SIZE*1),YELLOW,LCD_StringBuf);
    
    /*Show extra guard time integer (N)*/
    sprintf(LCD_StringBuf,"N = %d",SmartCard_CTR.GITByte.N);
    BSP_LCD_ShowString(((LCD_STRING_SIZE / 2)*0),(LCD_STRING_SIZE*10),((LCD_STRING_SIZE / 2)*7),(LCD_STRING_SIZE*1),YELLOW,LCD_StringBuf);
    
    if(SmartCard_CTR.GITByte.TA2_present==SmartCard_TRUE)
    {
        sprintf(LCD_StringBuf,"TA2 = %02Xh",SmartCard_CTR.GITByte.TA2);
        BSP_LCD_ShowString(((LCD_STRING_SIZE / 2)*0),(LCD_STRING_SIZE*11),((LCD_STRING_SIZE / 2)*9),(LCD_STRING_SIZE*1),YELLOW,LCD_StringBuf);
    }
    else
    {
        BSP_LCD_ShowString(((LCD_STRING_SIZE / 2)*0),(LCD_STRING_SIZE*11),((LCD_STRING_SIZE / 2)*10),(LCD_STRING_SIZE*1),YELLOW,"TA2 absent");
    }
}
/**
 *******************************************************************************
 * @brief	    Show specific interface bytes.
 * @details     
 * @return      
 * @exception   No
 * @note        
 *******************************************************************************
 */
static void MG32x02z_LCD_ShowSpecificInterfaceByte(void)
{
    uint8_t LCD_ShowSpIntByteTmp;
    uint8_t LCD_ShowSpIntByteCmp;
    uint8_t LCD_pShowSpIntByte;
    
    if((SmartCard_CTR.GITByte.T_15_present==SmartCard_TRUE)& (( SmartCard_CTR.GITByte.T15_Data[SmartCard_ATR_SPIT_TA] & SmartCard_ATR_Y_TA)!=0))
    {
        sprintf(LCD_StringBuf,"First TA = %02Xh in T = 15",SmartCard_CTR.GITByte.T15_Data[SmartCard_ATR_SPIT_TA]);
        BSP_LCD_ShowString(((LCD_STRING_SIZE / 2)*0),(LCD_STRING_SIZE*12),((LCD_STRING_SIZE / 2)*23),(LCD_STRING_SIZE*1),YELLOW,LCD_StringBuf);
    }        
    
    sprintf(LCD_StringBuf,"T = %d", SmartCard_CTR.GITByte.T);
    BSP_LCD_ShowString(((LCD_STRING_SIZE / 2)*0),(LCD_STRING_SIZE*13),((LCD_STRING_SIZE / 2)*6),(LCD_STRING_SIZE*1),YELLOW,LCD_StringBuf);
    
    
    for( LCD_ShowSpIntByteTmp = 0; LCD_ShowSpIntByteTmp < SmartCard_CTR.SPITByte.Total_SPinterface;LCD_ShowSpIntByteTmp++)
    {
        if( (SmartCard_CTR.SPITByte.SpData[LCD_ShowSpIntByteTmp][SmartCard_ATR_SPIT_TD] & SmartCard_ATR_T_MASK)==SmartCard_CTR.GITByte.T)
        {
            LCD_pShowSpIntByte = 0;
            
            LCD_ShowSpIntByteCmp = (SmartCard_CTR.SPITByte.SpData[LCD_ShowSpIntByteTmp][SmartCard_ATR_SPIT_TD] & SmartCard_ATR_Y_MASK);

            if(LCD_ShowSpIntByteCmp & SmartCard_ATR_Y_TA)
            {
                LCD_pShowSpIntByte += sprintf((LCD_StringBuf+LCD_pShowSpIntByte),"TA=%02Xh,", SmartCard_CTR.SPITByte.SpData[LCD_ShowSpIntByteTmp][SmartCard_ATR_SPIT_TA]);
            }
            if(LCD_ShowSpIntByteCmp & SmartCard_ATR_Y_TB)
            {
                LCD_pShowSpIntByte += sprintf((LCD_StringBuf+LCD_pShowSpIntByte),"TB=%02Xh,", SmartCard_CTR.SPITByte.SpData[LCD_ShowSpIntByteTmp][SmartCard_ATR_SPIT_TB]);
            }
            if(LCD_ShowSpIntByteCmp & SmartCard_ATR_Y_TC)
            {
                LCD_pShowSpIntByte += sprintf((LCD_StringBuf+LCD_pShowSpIntByte),"TC=%02Xh,", SmartCard_CTR.SPITByte.SpData[LCD_ShowSpIntByteTmp][SmartCard_ATR_SPIT_TC]);
            }

            BSP_LCD_ShowString(((LCD_STRING_SIZE / 2)*2),(LCD_STRING_SIZE*(14+LCD_ShowSpIntByteTmp)),((LCD_STRING_SIZE / 2)*28),(LCD_STRING_SIZE*1),YELLOW,LCD_StringBuf);            
        }
    }
}

/**
 *******************************************************************************
 * @brief	    Show historical bytes
 * @details     
 * @return      
 * @exception   No
 * @note        
 *******************************************************************************
 */
static void MG32x02z_LCD_ShowHistoricalByte(void)
{
    uint8_t LCD_ShowHistoricalByteTmp;
    uint8_t LCD_ShowHistoricalByteLen;
    
    
    BSP_LCD_ShowString(((LCD_STRING_SIZE / 2)*0),(LCD_STRING_SIZE*16),((LCD_STRING_SIZE / 2)*16), LCD_STRING_SIZE, GREEN, "Historical byte:");
    
    LCD_ShowHistoricalByteLen = 0;
    for(LCD_ShowHistoricalByteTmp = 0; LCD_ShowHistoricalByteTmp < SmartCard_CTR.ATR.HistoricalLength; LCD_ShowHistoricalByteTmp++)
    {
        LCD_ShowHistoricalByteLen += sprintf(LCD_StringBuf+LCD_ShowHistoricalByteLen,"%02Xh,", SmartCard_CTR.ATR.Historical[LCD_ShowHistoricalByteTmp]);
    }

    BSP_LCD_ShowString(((LCD_STRING_SIZE / 2)*2),(LCD_STRING_SIZE*17),((LCD_STRING_SIZE / 2)*28), LCD_STRING_SIZE*3, YELLOW, LCD_StringBuf);
}

/**
 *******************************************************************************
 * @brief	    Show error string.
 * @details     
 * @return      
 * @exception   No
 * @note        
 *******************************************************************************
 */
void MG32x02z_LCD_ShowError(void)
{

    BSP_LCD_ShowString(0,(LCD_STRING_SIZE*3),((LCD_STRING_SIZE / 2)*8), LCD_STRING_SIZE, RED, "Error!!!");
    
    /*Receive error signal.*/
    if( LCD_RefreshErrorStatus & SmartCard_ERROR_PARITYERROR)
    {
        BSP_LCD_ShowString(((LCD_STRING_SIZE / 2)*2),(LCD_STRING_SIZE*4),((LCD_STRING_SIZE / 2)*21), LCD_STRING_SIZE, YELLOW, "Receive error signal");
    }
    /*Answer to Reset data error.*/
    else if( LCD_RefreshErrorStatus & SmartCard_ERROR_ATRERROR)
    {
        BSP_LCD_ShowString(((LCD_STRING_SIZE / 2)*2),(LCD_STRING_SIZE*4),((LCD_STRING_SIZE / 2)*21), LCD_STRING_SIZE, YELLOW, "ATR data error");
    }
    /*PPS request error*/
    else if( LCD_RefreshErrorStatus & SmartCard_ERROR_PPSERROR)
    {
        BSP_LCD_ShowString(((LCD_STRING_SIZE / 2)*2),(LCD_STRING_SIZE*4),((LCD_STRING_SIZE / 2)*21), LCD_STRING_SIZE, YELLOW, "PPS request error");
    }
    /*User Receive timeout.*/
    else if( LCD_RefreshErrorStatus & SmartCard_ERROR_WTERROR)
    {
        BSP_LCD_ShowString(((LCD_STRING_SIZE / 2)*2),(LCD_STRING_SIZE*4),((LCD_STRING_SIZE / 2)*21), LCD_STRING_SIZE, YELLOW, "Receive timeout");
    }
    /*ATR timeout in cold reset.*/
    else if( LCD_RefreshErrorStatus & SmartCard_ERROR_ATRTIMEOUT)
    {
        BSP_LCD_ShowString(((LCD_STRING_SIZE / 2)*2),(LCD_STRING_SIZE*4),((LCD_STRING_SIZE / 2)*21), LCD_STRING_SIZE, YELLOW, "ATR timeout");
    }
}



