


/**
 ******************************************************************************
 *
 * @file        Common.c
 *
 * @brief       
 *
 * @par         Project
 *              Smart Card
 * @version     V1.00
 * @date        2022/11/23
 * @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_DRV.h"
#include "MG32_CSC_Init.h"
#include "MG32_Common.h"
#include "MG32_SmartCard_API.h"
#include "stdio.h"


/* Wizard menu ---------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
//UART Connector - 0 related
#define UART_URT         URT4

#define UART_TX_PINX     PINE(0)
#define UART_TX_AFS      11
#define UART_RX_PINX     PINE(1)
#define UART_RX_AFS      11

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static __IO uint32_t SysTickCnt; 


/* Private function prototypes -----------------------------------------------*/
/* Exported variables --------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/* External variables --------------------------------------------------------*/


/**
 *******************************************************************************
 * @brief	    BSP GPIO initial
 * @details     Pin mode initial
 * @param[in]   PinName: PINA(n) ~ PIND(n) (n = 0 ~ 15)
 * @param[in]   PinMode: 
 *   @arg\b     Analog_Mode: IO mode control.
 *   @arg\b     Data_DIR_OUT_QB      : Quasi-Birdirectional output.
 *   @arg\b     Data_DIR_OUT_OD_NoRU : Open drain output and disable internal pull-up resister.
 *   @arg\b     Data_DIR_OUT_OD_RU   : Open drain output with internal pull-up resister.
 *   @arg\b     Data_DIR_OUT_PP      : Push pull output.
 *   @arg\b     Data_DIR_IN_NoRU     : Digital input and disable internal pull-up resister.
 *   @arg\b     Data_DIR_IN_RU       : Digital input with internal pull-up resister.
 * @param[in]   PinAFS: Pin alternate function select.
 * @return      
 * @exception   No
 * @note        
 *******************************************************************************
 */
void API_GPIO_PinConfig(Pin_Struct* PinName , GPIO_Mode_TypeDef PinMode , uint8_t PinAFS)
{
    PIN_InitTypeDef                 PINX_InitStruct;
    
    PINX_InitStruct.PINX_PUResistant        = PINX_PUResistant_Enable;
    PINX_InitStruct.PINX_Speed              = PINX_Speed_High;
    
    if( PinMode == Data_DIR_OUT_QB)
    {
        PINX_InitStruct.PINX_Mode               = PINX_Mode_Quasi_IO;
    }
    else if( PinMode == Data_DIR_OUT_OD_NoRU)
    {
        PINX_InitStruct.PINX_PUResistant        = PINX_PUResistant_Disable;
        PINX_InitStruct.PINX_Mode				= PINX_Mode_OpenDrain_O;
    }
    else if( PinMode == Data_DIR_OUT_OD_RU)
    {
        PINX_InitStruct.PINX_Mode				= PINX_Mode_OpenDrain_O;
    }
    else if( PinMode == Data_DIR_OUT_PP)
    {
         PINX_InitStruct.PINX_Mode				 = PINX_Mode_PushPull_O;
    }
    else if( PinMode == Data_DIR_IN_NoRU)
    {
        PINX_InitStruct.PINX_PUResistant        = PINX_PUResistant_Disable;
        PINX_InitStruct.PINX_Mode				= PINX_Mode_Digital_I;
        PINX_InitStruct.PINX_Speed              = PINX_Speed_Low;
    }
    else if( PinMode == Data_DIR_IN_RU)
    {
        PINX_InitStruct.PINX_Mode				= PINX_Mode_Digital_I;
        PINX_InitStruct.PINX_Speed              = PINX_Speed_Low;
    }
    else 
    {
        PINX_InitStruct.PINX_PUResistant        = PINX_PUResistant_Disable;
        PINX_InitStruct.PINX_Mode				= PINX_Mode_Analog_IO;
        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 = PinAFS;
    GPIO_PinMode_Config(PinName,&PINX_InitStruct);  
}
/**
 *******************************************************************************
 * @brief	    UART of UARTConnector0 initial.
 * @details     
 * @return      
 * @exception   No
 * @note        
 *******************************************************************************
 */
void API_UARTConnector0_Init(void)
{
    URT_BRG_TypeDef    UARTx_BRG;
    URT_Data_TypeDef   UARTx_DataDef;
    
    /*Set pin */
    API_GPIO_PinConfig(UART_TX_PINX,Data_DIR_OUT_PP,UART_TX_AFS);
    API_GPIO_PinConfig(UART_RX_PINX,Data_DIR_IN_RU,UART_RX_AFS);
    
    /*Set Clock*/
    //Set BaudRate
    UARTx_BRG.URT_InternalClockSource = URT_BDClock_PROC;
    UARTx_BRG.URT_BaudRateMode = URT_BDMode_Separated;
    UARTx_BRG.URT_PrescalerCounterReload = 0;	                //Set PSR
    UARTx_BRG.URT_BaudRateCounterReload = 25;	                //Set RLR
    URT_BaudRateGenerator_Config(UART_URT, &UARTx_BRG);         //BR115200 = f(CK_URTx)/(PSR+1)/(RLR+1)/(OS_NUM+1)
    URT_BaudRateGenerator_Cmd(UART_URT, ENABLE);	            //Enable BaudRateGenerator
    //TX/RX Clock
    URT_TXClockSource_Select(UART_URT, URT_TXClock_Internal);	//URT_TX use BaudRateGenerator
    URT_RXClockSource_Select(UART_URT, URT_RXClock_Internal);	//URT_RX use BaudRateGenerator
    URT_TXOverSamplingSampleNumber_Select(UART_URT,15);	        //Set TX OS_NUM
    URT_RXOverSamplingSampleNumber_Select(UART_URT,15);	        //Set RX OS_NUM
    URT_RXOverSamplingMode_Select(UART_URT, URT_RXSMP_3TIME);
    URT_TX_Cmd(UART_URT, ENABLE);	                            //Enable TX
    URT_RX_Cmd(UART_URT, ENABLE);	                            //Enable RX
    
    /*Set Mode*/
    //Set Data character config
    UARTx_DataDef.URT_TX_DataLength  = URT_DataLength_8;
    UARTx_DataDef.URT_RX_DataLength  = URT_DataLength_8;
    UARTx_DataDef.URT_TX_DataOrder   = URT_DataTyped_LSB;
    UARTx_DataDef.URT_RX_DataOrder   = URT_DataTyped_LSB;
    UARTx_DataDef.URT_TX_Parity      = URT_Parity_No;
    UARTx_DataDef.URT_RX_Parity      = URT_Parity_No;
    UARTx_DataDef.URT_TX_StopBits    = URT_StopBits_1_0;
    UARTx_DataDef.URT_RX_StopBits    = URT_StopBits_1_0;
    UARTx_DataDef.URT_TX_DataInverse = DISABLE;
    UARTx_DataDef.URT_RX_DataInverse = DISABLE;
    URT_DataCharacter_Config(UART_URT, &UARTx_DataDef);
    //Set Mode Select
    URT_Mode_Select(UART_URT, URT_URT_mode);
    //Set DataLine Select
    URT_DataLine_Select(UART_URT, URT_DataLine_2);
    
    /*Set Data Control*/
    URT_RXShadowBufferThreshold_Select(UART_URT, URT_RXTH_1BYTE);
    URT_TXGuardTime_Select(UART_URT, 0);
    URT_ClearTXData(UART_URT);
    URT_ClearRXData(UART_URT);
    
    /*Enable URT*/
    URT_Cmd(UART_URT, ENABLE);
    
}
/**
 *******************************************************************************
 * @brief	    Replace fputc function of printf Lib.
 * @details     
 * @return      
 * @exception   No
 * @note        
 *******************************************************************************
 */
int fputc(int ch, FILE *f __attribute__((unused)))
{
    while((UART_URT->STA.W & URT_STA_TXF_mask_w) == 0);
    UART_URT->TDAT.B[0] = (uint8_t)ch;
    return ch;
}

/**
 *******************************************************************************
 * @brief	    DMA intail.
 * @details     
 * @return      
 * @exception   No
 * @note        
 *******************************************************************************
 */
void DMA_Init(void)
{
    DMA_BaseInitTypeDef          DMAPattern;


    /*Set DMA*/
    DMA_Cmd(DISABLE);
    DMA_Cmd(ENABLE);
    
    /*SMC TX DM*/
    DMA_Channel_Cmd(DMAChannel2, ENABLE);                     // DMA channel2 for URTX TX
    DMA_BaseInitStructure_Init(&DMAPattern);                  
    DMAPattern.DMAChx         = SmartCard_TX_DMA_Channel;                  
    DMAPattern.DMALoopCmd     = DISABLE;                            
    DMAPattern.SrcSINCSel     = ENABLE;                       // MEM address Increase enable
    DMAPattern.SrcSymSel      = DMA_MEM_Read;                 // DMA source from MEM
    DMAPattern.DestSymSel     = SmartCard_TX_DMA_DEST;              // DMA destination is to URTn_TX
    DMAPattern.BurstDataSize  = DMA_BurstSize_1Byte;          // DMA data size is 1byte
    DMAPattern.DMATransferNUM = 0;                            // Transmit total size 
    DMAPattern.DMASourceAddr  = SmartCard_CTR.TxBuf;                // Transmit data address.
    DMA_Base_Init(&DMAPattern);                               
                                                              
                                                  
    /*RX DMA*/                                 
    DMA_Channel_Cmd(DMAChannel1, ENABLE);                     // DMA channel1 for URTX TX
    DMA_BaseInitStructure_Init(&DMAPattern);                  
    DMAPattern.DMAChx         = SmartCard_RX_DMA_Channel;                  
    DMAPattern.DMALoopCmd     = DISABLE;                      
    DMAPattern.DestDINCSel    = ENABLE;                       // MEM address Increase enable
    DMAPattern.SrcSymSel      = SmartCard_RX_DMA_SRC;               // DMA source from URTn RX
    DMAPattern.DestSymSel     = DMA_MEM_Write;                // DMA destination is to MEM 
    DMAPattern.BurstDataSize  = DMA_BurstSize_1Byte;          // DMA data size is 1byte
    DMAPattern.DMATransferNUM = 0;                            // Transmit total size  
    DMAPattern.DMADestinationAddr = SmartCard_CTR.RxBuf;            // Receive MEM address.
    DMA_Base_Init(&DMAPattern);
      
}


/**
 *******************************************************************************
 * @brief	    Provides a tick value
 * @details     
 * @return      
 * @exception   No
 * @note        
 *******************************************************************************
 */ 
uint32_t API_GetTick(void)
{
    return(SysTickCnt);
}
/**
 *******************************************************************************
 * @brief	    Provides a tick value
 * @details     
 * @return      
 * @exception   No
 * @note        
 *******************************************************************************
 */ 
void API_IncTick(void)
{
    SysTickCnt++;
}

/**
 *******************************************************************************
 * @brief       This function configures the source of the time base. 
 *              The time source is configured  to have 1ms time base with a dedicated 
 *              Tick interrupt priority.
 * @param       TickPriority Tick interrupt priority.
 * @details     
 * @return      
 * @exception   No
 * @note        
 *******************************************************************************
 */
void API_InitTick( uint32_t BSP_TickPriority)
{
    /*
      Cofig the SysTick to have interrupt in 1ms time basis.
      (CONF_CK_AHB_FREQ data from MG32_CSC_Init.h
    */
    SysTick_Config((CONF_CK_AHB_FREQ/1000));
    
    /*Configure the SysTick IRQ priority.*/
    NVIC_SetPriority(SysTick_IRQn,BSP_TickPriority);
}



/**
 *******************************************************************************
 * @brief       This function provides accurate delay based 
 *              on variable incremented.
 * @param[in]   DelayTime: specifies the delay time length in SysTick basis time.
 * @details     
 * @return      
 * @exception   No
 * @note        
 *******************************************************************************
 */ 
void Delay( uint32_t DelayTime)
{
    uint32_t Delay_tickstart = API_GetTick();
    uint32_t Delay_wait = DelayTime;
    
    if (Delay_wait < 0xFFFFFFFF)
    {
       Delay_wait++;
    }
  
    while((API_GetTick() - Delay_tickstart) < Delay_wait)
    {
        __NOP();
    }  
}
























