/*------------------------------------------------------------ (C) Copyright [2006-2008] Marvell International Ltd. All Rights Reserved ------------------------------------------------------------*/ /***************************************************************************** * MODULE IMPLEMENTATION FILE ****************************************************************************** * COPYRIGHT (C) 2005 Intel Corporation, All rights reserved.. * * This file and the software in it is furnished under * license and may only be used or copied in accordance with the terms of the * license. The information in this file is furnished for informational use * only, is subject to change without notice, and should not be construed as * a commitment by Intel Corporation. Intel Corporation assumes no * responsibility or liability for any errors or inaccuracies that may appear * in this document or any software that may be provided in association with * this document. * Except as permitted by such license, no part of this document may be * reproduced, stored in a retrieval system, or transmitted in any form or by * any means without the express written consent of Intel Corporation. * * Title: USIM implementation file * * Filename: usim.c * * Author: Eilam Ben-Dror * Leonid Krasnopolsky * * Description: This file implements the main UICC Driver API functions. * * Last Updated: 19-Jan-2006 * * Copyright (c) 2005, Intel Corporation, All rights reserved. *****************************************************************************/ /*----------- External include files ----------------------------------------*/ #include "osa.h" #include "usim_config.h" #include "bsp_hisr.h" #include "bsp.h" #include "csw_memory.h" #include #include "utils.h" #include "intc.h" #ifdef USIM_TAVOR_DMA_ENABLE #include "dma.h" #endif #if defined(PERIPHERAL_CLOCKS_VIA_PRM_API) #include "prm.h" #else //#include "pmu.h" #endif #if 1 //_TAVOR_HARBELL_ #include "commpm.h" #endif /*----------- Local include files -------------------------------------------*/ #include "usim.h" #define _USIM_DB_NO_EXTERN_ #include "usim_db.h" #undef _USIM_DB_NO_EXTERN_ #include "usim_detect.h" #include "usim_hw.h" #include "usim_dl.h" #include "usim_transport.h" #if defined USIM_USE_TRACE #include "diag.h" #include "timer.h" #include "platform_nvm.h" #endif /* USIM_USE_TRACE */ #include "SysDynSilicon.h" #include "cgpio.h" #include "UART.h" #include "quec_cust_feature.h" //Chaim 2019.1.17 add, value is from asr register #define QUEC_xlli_MFPR_PHYSICAL_BASE_C 0xD401E000 // MFPR physical register base #define QUEC_PULL_UP_C 0xC000 //Enable pull up resistor #define QUEC_PULL_DN_C 0xA000 //Enable pull down resistor #define QUEC_DRV_SLOW_C 0x0800 //Use slow drive strength #define QUEC_DRV_MED_C 0x1000 //Use medium drive strength #define QUEC_DRV_FAST_C 0x1800 //Use fast drive strength #define QUEC_AF0_C 0X0000 //Alternate function 0 #define QUEC_AF1_C 0X0001 //Alternate function 1 #define QUEC_AF2_C 0X0002 //Alternate function 2 #define QUEC_AF3_C 0X0003 //Alternate function 3 #define QUEC_AF4_C 0X0004 //Alternate function 4 #define QUEC_AF5_C 0X0005 //Alternate function 5 #define QUEC_AF6_C 0X0006 //Alternate function 6 #define QUEC_AF7_C 0X0007 //Alternate function 7 #define QUEC_RESERVED_C 0x00C0 //RESERVED_C bits that must be set #define QUEC_PULL_INTERNAL 0x8000 //PullDn/Up is decied by internal resiter. #define QUEC_SLEEP_OUTPUT 0x0000 /* Output when in sleep. */ #define QUEC_SLEEP_HIGH 0x0100 /* High when in sleep. */ #define QUEC_SLEEP_INPUT 0x0080 /* jensen.fang 20181030: Input when in sleep. */ #define QUEC_EDGE_RISE_EN 0x0010 /* jensen.fang 20181030: detect a rising edge on a pin. */ #define QUEC_EDGE_FALL_EN 0x0020 /* jensen.fang 20181030: detect a falling edge on a pin. */ #define QUEC_EDGE_CLEAR 0x0040 /* jensen.fang 20181030: The edge-detection logic is disabled and no edge is detected. */ #define QUEC_SLEEP_CTL_ENABLE (1<<3 |1<<9) /* Chaim.qian 20181218: enable sleep_mode control */ /*----------- Local defines -------------------------------------------------*/ // ATR Definitions: // masks: #define USIM_RECEIVED_BYTE_MASK 0xFFL #define USIM_PARITY_ERROR_MASK 0x100L #define USIM_HISTORIC_LEN_MASK 0x0F #define USIM_TA_MASK 0x10 #define USIM_TB_MASK 0x20 #define USIM_TC_MASK 0x40 #define USIM_TD_MASK 0x80 #define USIM_CHANGEABILITY_MASK 0x80 #define USIM_SPECIFIC_MODE_PARAM_INDICATOR_MASK 0x10 #define USIM_ATR_MAX_LEN 33 #define USIM_ATR_MIN_LEN 2 #define USIM_GLOBAL_INTERFACE_BYTES 15 #define USIM_EQUAL_TX_EXTRA_GUARD_TIME 255 // Number of bytes to write to the TX FIFO at once #define USIM_TX_BLOCK_SIZE 8 /* Clock resume delay in usec: */ #define USIM_CLOCK_RESUME_DELAY_CYCLES 744 // clock cycles #define USIM_CLOCK_STOP_DELAY_CYCLES 1860 // clock cycles /* Delay after deactivation, before reactivation: */ #define USIM_REACTIVATE_DELAY_CYCLES ((10/OSA_TICK_FREQ_IN_MILLISEC)+1) #define USIM_INS_REMOVE_GUARD_TIME_TICK (6000/5) // PPS definitions: typedef enum { USIM_PPSS = 0, USIM_PPS0, USIM_PPS1, USIM_PCK, USIM_PPS_LENGTH }USIM_PPSfield; /*----------- Local macro definitions ---------------------------------------*/ #define USIM_CHECK_CARD_VALID(card) if (((int)card)<0 || ((int)card)>=((int)USIM_CARDS_AMOUNT)) \ return USIM_RC_INVALID_CARD #define USIM_GET_HIGH_END_FROM_BYTE(returned,byte) \ ((returned) = (((byte) & 0xF0) >> 4)) #define USIM_GET_LOW_END_FROM_BYTE(returned,byte) ((returned) = ((byte) & 0x0F)) // is this the end of the ATR? #define USIM_CHECK_END_ATR if(currByteNum>=atrLen) \ return USIMendATR(globalInterface, N, card);\ currByte = atrBuffer[++currByteNum]; // convert USIM_Class to its corresponding USIM_ControlStatus: #define USIM_CLASS_TO_CTRL_IND(v) (((v) == USIM_CLASS_C)? \ USIM_CARD_ACTIVE_CLASS_C : \ USIM_CARD_ACTIVE_CLASS_B) // Convert clock frequency to ratio: #define USIM_CLOCK_TO_RATIO(f) ((USIM_IN_CLK * 5) / (f)) /*----------- Local type definitions ----------------------------------------*/ /*----------- Global constant definitions -----------------------------------*/ /*----------- Local constant definitions ------------------------------------*/ extern BOOL GLFeatureFlag; UINT32 usim_swap_flag=0; // card interrupt sources: INTC_InterruptSources _USIMinterruptSources[2] = {INTC_SRC_USIM1,INTC_SRC_USIM2 }; /*----------- Local variable definitions ------------------------------------*/ //--- SW only related ------- OSATimerRef _USIMtimerRefs [USIM_CARDS_AMOUNT]; OS_HISR _USIMhisrRefs [USIM_CARDS_AMOUNT]; UINT32 _USIMinterruptStatus[USIM_CARDS_AMOUNT]; BOOL _USIMOsActive [USIM_CARDS_AMOUNT]; //--- SW/HW related BOOL _USIMclockStopped [USIM_CARDS_AMOUNT]; BOOL _USIMisClockStopUsed [USIM_CARDS_AMOUNT]; USIM_Class _USIMuseVoltageLevel [USIM_CARDS_AMOUNT]; BOOL _USIM_hwRemoveProgress[USIM_CARDS_AMOUNT]; BOOL _USIM_FastRemoveOnDetectContext = FALSE; //FALSE sends only notification to PS extern USIM_Class _USIMcurrentVoltageClass[USIM_CARDS_AMOUNT]; #if defined USIM_USE_TRACE #define USIM_TRACE_BWT_TIMERS_MAX 16 static UINT32 _USIMBWTTimers[USIM_CARDS_AMOUNT][USIM_TRACE_BWT_TIMERS_MAX]; #ifdef USIM_DSDS_DKB static UINT32 _USIMBWTTimersIndex[USIM_CARDS_AMOUNT] = {0,0}; #else static UINT32 _USIMBWTTimersIndex[USIM_CARDS_AMOUNT] = {0}; #endif #endif /* USIM_USE_TRACE */ /*----------- Local function definition -------------------------------------*/ void USIMControlIndication (USIM_Card card, USIM_ControlStatus status); static void USIMATRInfoInit(USIM_Card card); void USIMSetResponseReadFlag(UINT8 card, UINT32 responsereadFlag); //static void USIMmalfunction_Remove(USIM_Card card); /*----------begin--------------------TAVOR Stuff-----------------------------------*/ #ifdef USIM_TAVOR_DMA_ENABLE void USIMDmaSetup ( USIM_Card card ); void USIMD2rmD2Register(void); #endif /*-----------end---------------------TAVOR Stuff-----------------------------------*/ extern int getMasterSimID(void); #ifndef UPGRADE_LTE_ONLY extern void SimSendGLSwapFlag(unsigned int val); #endif USIM_ReturnCode USIManswerToReset(USIM_Card card, UINT8 atrLen); extern void usim_state_init(USIM_Card card); // // Enable original USIM clock management (Hermon) // The other option uses USIMRMManage in different placed, which is wrong. Specifically, it shuts down the USIM clock // without proper shutdown sequence, e.g. in USIMConfigure(), which results in Harbell hang. // #if QUEC_SIM_HOT_PLUG_PIN extern BOOL IsMiniSystem(void); extern void ATRecv(int AtpIndex, void* data, UINT32 length); #endif typedef struct { UINT32 len; USIM_Class voltage; UINT32 flag; }usim_boot_atr_info_t; usim_boot_atr_info_t usim_boot_atr_info[2]; int get_sim_swap_flag(void) { return GLFeatureFlag; } UINT32 usim_1_op_flag=0; void usim_1_op_enter(void) { } void usim_1_op_exit(void) { } UINT32 usim_1_get_op_flag(void) { return usim_1_op_flag; } UINT32 usim_2_op_flag=0; void usim_2_op_enter(void) { } void usim_2_op_exit(void) { } UINT32 usim_2_get_op_flag(void) { return usim_2_op_flag; } #ifdef PHS_SW_DEMO_TTC void usimClockSwitch_ttc(USIM_Card card,BOOL onOff) { #ifdef USIM_DSDS_DKB if (onOff) { if(usim_swap_flag==0) { if(card == USIM_BANKING_CARD) *(UINT32*)0xd403b024 = 0x3; else *(UINT32*)0xd403b020 = 0x3; } else { if(card == USIM_BANKING_CARD) *(UINT32*)0xd403b020 = 0x3; else *(UINT32*)0xd403b024 = 0x3; } } else { if(usim_swap_flag==0) { if(card == USIM_BANKING_CARD) *(UINT32*)0xd403b024 = 0x0; else *(UINT32*)0xd403b020 = 0x0; } else { if(card == USIM_BANKING_CARD) *(UINT32*)0xd403b020 = 0x0; else *(UINT32*)0xd403b024 = 0x0; } } #else if (onOff) { if(usim_swap_flag==0) { *(UINT32*)0xd403b020 = 0x3; } else { *(UINT32*)0xd403b024 = 0x3; } } else { if(usim_swap_flag==0) { *(UINT32*)0xd403b020 = 0x0; } else { *(UINT32*)0xd403b024 = 0x0; } } #endif } #endif #define PMU_ENABLE #if defined (PMU_ENABLE) void USIM_PmuClockSwitch(USIM_Card card,BOOL onOff) { #ifdef USIM_DSDS_DKB if(usim_swap_flag == 1) { if(card == USIM_BANKING_CARD) PRMManage(PRM_SRVC_USIM,(onOff)?PRM_RSRC_ALLOC:PRM_RSRC_FREE); else PRMManage(PRM_SRVC_USIM2,(onOff)?PRM_RSRC_ALLOC:PRM_RSRC_FREE); } else { if(card == USIM_BANKING_CARD) PRMManage(PRM_SRVC_USIM2,(onOff)?PRM_RSRC_ALLOC:PRM_RSRC_FREE); else PRMManage(PRM_SRVC_USIM,(onOff)?PRM_RSRC_ALLOC:PRM_RSRC_FREE); } #else if(usim_swap_flag == 1) { PRMManage(PRM_SRVC_USIM2,(onOff)?PRM_RSRC_ALLOC:PRM_RSRC_FREE); } else { PRMManage(PRM_SRVC_USIM,(onOff)?PRM_RSRC_ALLOC:PRM_RSRC_FREE); } #endif } //#define USIM_PmuClockSwitch(onOff) PRMManage(PRM_SRVC_USIM,(onOff)?PRM_RSRC_ALLOC:PRM_RSRC_FREE) #else #define USIM_PmuClockSwitch(onOff) #endif #if defined (USIM_USE_SW_WDT_TIMER) void USIM_wdtExpired(UINT32 tmrId) { if (_USIMtimerWDTactive[tmrId]) { usim_record_event(tmrId, USIM_EVT_USIM_wdtExpired); OSAFlagSet(_USIMflagsRefs[tmrId], USIM_WDT_TIMER_FLAG, OSA_FLAG_OR); _USIMtimerWDTactive[tmrId] = FALSE; } } #endif void usim_send_quit_event(UINT32 card) { extern UINT32 get_usim_busy_flag(UINT32 card); if(get_usim_busy_flag(card)==1) OSAFlagSet(_USIMflagsRefs[card], USIM_WDT_TIMER_FLAG, OSA_FLAG_OR); } void TestUsimGetStatus(USIM_Card card) { } UINT32 sim_removed_status = 0; /****************************************************************************** * Function : USIM_DetectFoundByHW ******************************************************************************* * * Description : This procedure should be called * when the SIM Remove or Insert event & new-stable-state discovered. * All issues of recognising and deboucing are out of it's scope - * when it is called the the state is definitelly correct and stable. * Should NOT be called on a LISR context but may be called on HISR. * * Parameters : inserted=TRUE - New state SIM is inside * inserted=FALSE - New state SIM is outside * * Return value : None ******************************************************************************/ void USIM_DetectFoundByHW(BOOL inserted) { USIM_Card card = USIM_COM_CARD; UINT32 cpsr; DIAG_FILTER(USIMLOG,USIM_DetectFoundByHW,LOG001,DIAG_INFORMATION) diagPrintf("USIM_DetectFoundByHW %x", inserted); if(inserted) {/*--------------------- I N S E R T -------------------------------------*/ DIAG_FILTER(USIMLOG,USIM_DetectFoundByHW,LOG002,DIAG_INFORMATION) diagPrintf("inserted _USIMstates=%lx, _USIM_hwRemoveProgress=%lx", _USIMstates[card], _USIM_hwRemoveProgress[card]); if( (_USIMstates[card] == USIM_REMOVED) || (_USIMstates[card] == USIM_INACTIVE)) { if(_USIM_hwRemoveProgress[card]) { //"Remove" is in progress, giv the time to finish it OSATaskSleep(USIM_INS_REMOVE_GUARD_TIME_TICK); } cpsr = disableInterrupts(); _USIMstates[card] = USIM_INACTIVE; restoreInterrupts(cpsr); //-- Notify the PS SIM driver manager (hadHandleUSIMControlIndication) USIMControlIndication(USIM_COM_CARD, USIM_CARD_INSERTED); } } else { /*--------------------- R E M O V E -------------------------------------*/ DIAG_FILTER(USIMLOG,USIM_DetectFoundByHW,LOG003,DIAG_INFORMATION) diagPrintf("remove _USIMstates=%lx, _USIM_hwRemoveProgress=%lx", _USIMstates[card], _USIM_hwRemoveProgress[card]); if((_USIMstates[card] != USIM_REMOVED) && (_USIMstates[card] != USIM_INACTIVE) && !_USIM_hwRemoveProgress[card]) { USIMControlIndication(USIM_COM_CARD, USIM_CARD_REMOVED); cpsr = disableInterrupts(); _USIMstates[card] = USIM_REMOVED; restoreInterrupts(cpsr); } } }/*USIM_DetectFoundByHW*/ /********************************************************************************* * **********************************************************************************/ void USIMRxFIFO_Clear(USIM_Card card) { /* UINT32 len, parityLen; UINT8 totalLen; // Get the number of erronuous bytes in the RX FIFO: USIM_PERR_NUM_GET(card, parityLen); // get the number of bytes still in the RX FIFO: USIM_RX_LENGTH_GET(card, len); totalLen = (UINT8)(parityLen+len); USIM_HW_RXRead_Dummy(card,totalLen); */ UINT32 len; // get the number of bytes still in the RX FIFO: USIM_RX_LENGTH_GET(card, len); if (len) USIM_HW_RXRead_Dummy(card,len); } BOOL USIMhandleBWTInterrupt (USIM_Card card) { UINT8 txFifoLen; UINT32 wt; USIM_Protocol protocol = _USIMatrInfos[card].protocol; BOOL bwtExpired = FALSE; if(_USIMstates[card] == USIM_ATR) { // ATR was not received yet, BWT expired bwtExpired = TRUE; } else { //-------------------------------------------------------------- if( protocol == USIM_T1) { //checking of rase condition when CWT occurs before any charachters has been send //ve.rify that the TX-FIFO is not empty: USIM_TX_LENGTH_GET(card, txFifoLen); if (txFifoLen > 0) { USIM_DL_BWTSet(card); // Do we have more data to send if (_USIMtxBufferSize[card] > 0 ) { //impossible condition // enable interrupts for "send" state: USIM_ENABLE_MASK(card, USIM_SEND_ENABLE_MASK); } else { // enable interrupts for "wait for response" state: USIM_ENABLE_MASK(card, USIM_W4RESPONSE_ENABLE_MASK); } return bwtExpired; } } //-------------------------------------------------------------- USIM_BLOCK_WAIT_TIME_GET(card,protocol,wt); if(_USIMWTCnt[card] -= wt) { // WWT has not expired, reset the counter: if(_USIMWTCnt[card] > USIM_MAX_WWT_REG_VALUE) USIM_BLOCK_WAIT_TIME_SET(card, protocol, USIM_MAX_WWT_REG_VALUE); else USIM_BLOCK_WAIT_TIME_SET(card, protocol, _USIMWTCnt[card]); // enable interrupts: USIM_ENABLE_MASK(card, USIM_W4RESPONSE_ENABLE_MASK); //Trigger the counters: USIM_DIVISOR_SET(card, USIM_DIVISOR_GET(card)); USIM_INTERRUPT_CLEAR_ALL(card); } else { // WWT expired: bwtExpired = TRUE; } } // clear BWT interrupt: USIM_INTERRUPT_CLEAR(card, USIM_BWT); #if 0 #if defined USIM_USE_TRACE USIM_TRACING_ON_DEMAND { _USIMBWTTimers[card][_USIMBWTTimersIndex[card]++] = timerCountRead((TCR_NUMBER)0); if (_USIMBWTTimersIndex[card] > USIM_TRACE_BWT_TIMERS_MAX) _USIMBWTTimersIndex[card] = 0; } #endif /* USIM_USE_TRACE */ #endif return bwtExpired; } BOOL USIMhandleCWTInterrupt (USIM_Card card) { UINT32 wt; UINT8 txFifoLen; BOOL cwtExpired = FALSE; if(_USIMatrInfos[card].protocol == USIM_T1) { //checking of rase condition when CWT occurs before any charachters has been send //ve.rify that the TX-FIFO is not empty: USIM_TX_LENGTH_GET(card, txFifoLen); if (txFifoLen > 0) { USIM_CHAR_WAIT_TIME_SET(card, USIM_T1, (_USIMatrInfos[card].charWaitingTime+USIM_ADJUST_CWT_GCF)); //Trigger the counters: USIM_DIVISOR_SET(card, USIM_DIVISOR_GET(card)); // Do we have more data to send if (_USIMtxBufferSize[card] > 0 ) { //impossible condition // enable interrupts for "send" state: USIM_ENABLE_MASK(card, USIM_SEND_ENABLE_MASK); } else { // enable interrupts for "wait for response" state: USIM_ENABLE_MASK(card, USIM_W4RESPONSE_ENABLE_MASK); } } else { // In T=1 CWT < FFFF cwtExpired = TRUE; } } else { // T=0 protocol USIM_CHAR_WAIT_TIME_GET(card,USIM_T0,wt); if(_USIMWTCnt[card] -= wt) { // WWT has not expired, reset the counter: if(_USIMWTCnt[card] > USIM_MAX_WWT_REG_VALUE) USIM_CHAR_WAIT_TIME_SET(card, USIM_T0, USIM_MAX_WWT_REG_VALUE); else USIM_CHAR_WAIT_TIME_SET(card, USIM_T0, _USIMWTCnt[card]); //Trigger the counters: USIM_DIVISOR_SET(card, USIM_DIVISOR_GET(card)); // clear all pending interrupts: //USIM_CLEAR_ALL(card); USIM_INTERRUPT_CLEAR_ALL(card); // enable interrupts for "receive" state: USIM_ENABLE_MASK(card, USIM_RECEIVE_ENABLE_MASK); } else { // WWT expired: cwtExpired = TRUE; } } return cwtExpired; } /******************************************************************************* * Functions: USIMbuffersAllocate / USIMbuffersFree * The USIM_COM_CARD is always used => the buffers are always should be present, * so use static alloc instead dynamic for the USIM_COM_CARD. * Right now, there is no other cards, but keep code generic... ******************************************************************************** * Parameters: card ******************************************************************************** */ static UINT8 _USIMrxBuf[2][USIM_BUFFER_SIZE]; static UINT8 _USIMtxBuf[2][USIM_BUFFER_SIZE]; static UINT8 _USIMdataBuf[2][USIM_BUFFER_SIZE]; /******************************************************************************* * Function: USIMbuffersFree *******************************************************************************/ static void USIMbuffersFree(USIM_Card card) { #if 0 if(card != USIM_COM_CARD) { //Should be done only if not NULL, but never called... Free(_USIMrxBuffers[card]); _USIMrxBuffers[card] = NULL; Free(_USIMtxBuffers[card]); _USIMtxBuffers[card] = NULL; Free(_USIMdataBuffers[card]); _USIMdataBuffers[card]= NULL; } #endif } /******************************************************************************* * Function: USIMbuffersAllocate *******************************************************************************/ static USIM_ReturnCode USIMbuffersAllocate(USIM_Card card) { #if 0 if(card == USIM_COM_CARD) { _USIMrxBuffers[card] = _USIMrxBuf; _USIMtxBuffers[card] = _USIMtxBuf; _USIMdataBuffers[card]= _USIMdataBuf; } else { _USIMrxBuffers[card] = alignMalloc(USIM_BUFFER_SIZE); ASSERT(_USIMrxBuffers[card]!=NULL); //return USIM_RC_OSA_ERROR; _USIMtxBuffers[card] = alignMalloc(USIM_BUFFER_SIZE); ASSERT(_USIMtxBuffers[card]!=NULL); //return USIM_RC_OSA_ERROR; _USIMdataBuffers[card]= alignMalloc(USIM_BUFFER_SIZE); ASSERT(_USIMdataBuffers[card]!=NULL); //return USIM_RC_OSA_ERROR; } #endif return USIM_RC_OK; } /******************************************************************************* * Function: USIMdelayHandler ******************************************************************************** * Description: This is called when the dealy is over. * * Parameters: card * * Return value: None * * Notes: *******************************************************************************/ static void USIMdelayHandler(USIM_Card card) { // clear all pending interrupts: USIM_CLEAR_ALL(card); USIM_DISABLE_ALL(card); // set the USIM_CLOCK_STOP_FLAG: OSAFlagSet(_USIMflagsRefs[card], USIM_CLOCK_STOP_FLAG, OSA_FLAG_OR); } /******************************************************************************* * Function: USIMwriteHandler ******************************************************************************** * Description: Handles the USIM interrupts for USIM_SEND state. * * Parameters: card - the USIM card * * Return value: None. * * Notes: called by interruptHandler *******************************************************************************/ static void USIMwriteHandler(USIM_Card card) { UINT32 dataLen; // the number of bytes to send UINT32 status = _USIMinterruptStatus[card]; UINT8 txFifoLen; usim_record_event(card, USIM_EVT_USIMwriteHandler_001); if (status & USIM_T0_ERR_MASK) { // clear T0 error indication: USIM_T0_ERR_CLEAR(card); // clear all other pending interrupts: USIM_CLEAR_ALL(card); _USIMErrorStat[card] = USIM_T0_ERR; #ifdef USIM_TAVOR_DMA_ENABLE if ( USIMRxTxModeGet(card) == USIM_DMA_MODE ) { USIM_DISABLE_TX_DMA_MODE(card); #ifdef PHS_SW_DEMO_TTC DMAChannelStop ( USIM1_TRANSMIT_DMA_CHANNEL , TRUE ); #else DMAChannelStop ( USIM_DMA_WRITE_CHAN , TRUE ); #endif } #endif USIM_WDT_TIMER_STOP(card); usim_record_event(card, USIM_EVT_USIMwriteHandler_002); OSAFlagSet(_USIMflagsRefs[card], USIM_DEACTIVATE_FLAG, OSA_FLAG_OR); } else {// Transmitter data refill //verify that the TX-FIFO has enough space for the next block: USIM_TX_LENGTH_GET(card, txFifoLen); usim_record_event_one_data(card, USIM_EVT_USIMwriteHandler_003, txFifoLen); if(txFifoLen > USIM_TX_BLOCK_SIZE) { // TX FIFO is still too full, trace in ICAT and wait for the next interrupt // enable interrupts for "send" state: USIM_ENABLE_MASK(card, USIM_SEND_ENABLE_MASK); return; } // how many bytes are left to be written: dataLen = _USIMtxBufferSize[card]; usim_record_event_one_data(card, USIM_EVT_USIMwriteHandler_004, dataLen); if (dataLen > USIM_TX_BLOCK_SIZE) { // write a block: USIM_HW_TXWrite(card, USIM_TX_BLOCK_SIZE, _USIMtxBufferPtrs[card]); // update pointer: _USIMtxBufferPtrs[card] += USIM_TX_BLOCK_SIZE; // update size: _USIMtxBufferSize[card] -= USIM_TX_BLOCK_SIZE; USIM_WDT_TIMER_START(card, 2000); // enable interrupts for "send" state: USIM_ENABLE_MASK(card, USIM_SEND_ENABLE_MASK); } else { // less than block to be written: USIM_HW_TXWrite(card, dataLen, _USIMtxBufferPtrs[card]); #if defined USIM_USE_TRACE #if 0 _USIMBWTTimersIndex = 0; USIM_TRACING_ON_DEMAND { _USIMBWTTimers[card][_USIMBWTTimersIndex[card]++] = timerCountRead((TCR_NUMBER)0); } #endif #endif /* USIM_USE_TRACE */ // FINISHED SENDING: // change DL state: _USIMDLstates[card] = USIM_WAIT_FOR_RESPONSE; USIM_WDT_TIMER_START(card, 2000); // enable interrupts for "wait for response" state: USIM_ENABLE_MASK(card, USIM_W4RESPONSE_ENABLE_MASK); } } } /* End of USIMwriteHandler */ /******************************************************************************* * Function: USIMT1ExpectedLenGet ******************************************************************************** * Description: Retrieves the LEN field of a T=1 response, and updates the * expected length accordingly. * * Parameters: card - the USIM card * * Return value: TRUE iff the expected len is updated * * Notes: called by readHandler *******************************************************************************/ static BOOL USIMT1ExpectedLenGet(USIM_Card card) { UINT8 prologue[USIM_T1_PROLOGUE_SIZE]; // read the prologue: USIM_HW_RXRead(card, USIM_T1_PROLOGUE_SIZE, prologue); // update the expected bytes number. LEN=field coudn't be equal to 0xFF (Reserved), _USIMexpectedLen[card] = ((prologue[USIM_T1_PROLOGUE_SIZE-1] ==0xFF)?0xFF:(prologue[USIM_T1_PROLOGUE_SIZE-1]+1)); // set the rx trigger level according to expected len USIMrxLevelSet(card, _USIMexpectedLen[card]); // write the prologue in the rx buffer: memcpy(_USIMrxBufferPtrs[card], prologue, USIM_T1_PROLOGUE_SIZE); // update pointer: _USIMrxBufferPtrs[card] += USIM_T1_PROLOGUE_SIZE; return TRUE; } /* End of USIMT1ExpectedLenGet */ /******************************************************************************* * Function: USIMdecodeProcedureByte ******************************************************************************** * Description: Decodes the first byte of the response * * Parameters: card - the USIM card * * Return value: FALSE iff the procedure byte was !ins or NULL byte * * Notes: called by readHandler *******************************************************************************/ static BOOL USIMdecodeProcedureByte(USIM_Card card) { UINT32 dataLen = 0; UINT8 procByte; UINT8 ins = (_USIMcommandHeaders[card]).instructionCode; BOOL readRest = FALSE; // read the procedure byte: USIM_HW_RXRead(card, 1, &procByte); usim_record_event_one_data(card, USIM_EVT_USIMdecodeProcedureByte_001, procByte); if(procByte == USIM_NULL_BYTE) { return readRest; } // if case 3: if(_USIMexpectedLen[card] == 1) { // write the byte in the rx buffer: *(_USIMrxBufferPtrs[card]) = procByte; // update pointer: _USIMrxBufferPtrs[card] += 1; if( (procByte== ins) || (procByte == USIM_BYTEWISE_NOT(ins))) //(CHECK_FOR_ACK(ins, procByte)) { // update the expected bytes number: _USIMexpectedLen[card] = 0; } usim_record_event_one_data(card, USIM_EVT_USIMdecodeProcedureByte_002, ins); readRest = TRUE; } else {// case 2: if((procByte == USIM_BYTEWISE_NOT(ins)) && (procByte != 0x6F) && (procByte != 0x90)) { usim_record_event_one_data(card, USIM_EVT_USIMdecodeProcedureByte_003, USIM_BYTEWISE_NOT(ins)); while (dataLen == 0) { // get the number of bytes received: USIM_RX_LENGTH_GET(card, dataLen); } // read 1 data byte: USIM_HW_RXRead(card, 1, _USIMrxBufferPtrs[card]); usim_record_event_one_data(card, USIM_EVT_USIMdecodeProcedureByte_004, *(_USIMrxBufferPtrs[card])); // update pointer: _USIMrxBufferPtrs[card] += 1; // update the expected bytes number: _USIMexpectedLen[card] -= 1; } else { readRest = TRUE; if((procByte != ins)||(procByte == 0x90))// == 6C / 61 / 6X / 9X i.e. we got SW1 { // write the byte in the rx buffer: *(_USIMrxBufferPtrs[card]) = procByte; // update pointer: _USIMrxBufferPtrs[card] += 1; // update the expected bytes number: _USIMexpectedLen[card] = 1; } } } return readRest; }/* End of USIMdecodeProcedureByte */ #ifdef USIM_DSDS_DKB BOOL calcATRlengthflag[USIM_CARDS_AMOUNT] = {FALSE,FALSE}; #else BOOL calcATRlengthflag[USIM_CARDS_AMOUNT] = {FALSE}; #endif /******************************************************************************* * Function: USIMreadHandler ******************************************************************************** * Description: Handles the USIM interrupts for USIM_WAIT_FOR_RESPONSE and * USIM_RECEIVE states. * * Parameters: card - the USIM card * dlState - the Data Link state * * Return value: None. * * Notes: called by interruptHandler *******************************************************************************/ static void USIMreadHandler(USIM_Card card, USIM_State dlState) { UINT32 dataLen = 0; // the number of bytes received from the card #ifdef USIM_DSDS_DKB static BOOL readRest[USIM_CARDS_AMOUNT] = {FALSE,FALSE}; // true iff ins byte was sent #else static BOOL readRest[USIM_CARDS_AMOUNT] = {FALSE}; #endif UINT32 status = _USIMinterruptStatus[card]; BOOL wwtExpired = FALSE; USIM_Protocol protocol = _USIMatrInfos[card].protocol; UINT32 parityLen = 0; UINT8 parityTri = 0; USIM_WDT_TIMER_STOP(card); usim_record_event(card, USIM_EVT_READ_USIMreadHandler_001); if (status & USIM_PARITY_ERR_MASK) { #ifdef SS_FEATURE USIM_PERR_NUM_GET(card, parityLen); //check Parity Error FIFO parityLen = 0; parityTri = 0xff & ((USIMHWRegisters[card]->ECR) > 0x3); #endif _USIMParityErrorCnt[card]++; usim_record_event_four_data(card, USIM_EVT_READ_USIMreadHandler_002, _USIMParityErrorCnt[card]); } if((dlState == USIM_WAIT_FOR_RESPONSE)&&(status & USIM_BWT_MASK)) { wwtExpired = USIMhandleBWTInterrupt(card); usim_record_event_one_data(card, USIM_EVT_READ_USIMreadHandler_003, wwtExpired); if(wwtExpired == FALSE) { // since WWT > 0xFFFF, more iterations are required, so ignore this interrupt return; } } if( (wwtExpired==TRUE)|| ( (status & ( USIM_PARITY_ERR_MASK | USIM_FRAMING_ERR_MASK)) && (protocol == USIM_T0)) || ( (status & USIM_RX_OVERRUN_MASK) && (protocol != USIM_T0)) || ( (dlState == USIM_WAIT_FOR_RESPONSE) && (status & USIM_T0_ERR_MASK))) { _USIMErrorStat[card] = status; // clear all pending interrupts: USIM_CLEAR_ALL(card); USIM_WDT_TIMER_STOP(card); // set the deactivate flag: usim_record_event(card, USIM_EVT_READ_USIMreadHandler_004); OSAFlagSet(_USIMflagsRefs[card], USIM_DEACTIVATE_FLAG, OSA_FLAG_OR); return; } if(status & USIM_CWT_MASK) { wwtExpired = USIMhandleCWTInterrupt(card); usim_record_event_one_data(card, USIM_EVT_READ_USIMreadHandler_005, wwtExpired); if(wwtExpired == FALSE) { // since WWT > 0xFFFF, more iterations are required, so ignore this interrupt return; } } else { // USIM_RX_DATA_READY_MASK || USIM_RX_TIMEOUT_MASK if (dlState == USIM_WAIT_FOR_RESPONSE) { // change DL state to receive: _USIMDLstates[card] = dlState = USIM_RECEIVE; usim_record_event(card, USIM_EVT_READ_USIMreadHandler_006); // enable Character Waiting Time: USIM_ENABLE(card, USIM_CWT); USIM_INTERRUPT_CLEAR(card,USIM_CWT); } } if (wwtExpired == FALSE) { USIM_RX_LENGTH_GET(card, dataLen); USIM_PERR_NUM_GET(card, parityLen); //check Parity Error FIFO usim_record_event_one_data(card, USIM_EVT_READ_USIMreadHandler_007, dataLen); usim_record_event_one_data(card, USIM_EVT_READ_USIMreadHandler_008, parityLen); if (parityLen) { _USIMParityErrorCnt[card]++; usim_record_event_four_data(card, USIM_EVT_READ_USIMreadHandler_009, _USIMParityErrorCnt[card]); } if(_USIMstates[card] == USIM_SPECIFIC) { while((readRest[card]==FALSE) && dataLen && (_USIMParityErrorCnt[card] == 0) ) { if(protocol == USIM_T0) // if ins was not sent yet - decode procedure byte: { //character was received, so WWT counting should be reset: USIM_DL_WWTSet(card); usim_record_event_one_data(card, USIM_EVT_READ_USIMreadHandler_010, dataLen); readRest[card] = USIMdecodeProcedureByte(card); } else {//T=1 used: if (( dataLen >= USIM_T1_PROLOGUE_SIZE) && ( _USIMParityErrorCnt[card] ==0)) readRest[card] = USIMT1ExpectedLenGet(card); else if (_USIMParityErrorCnt[card]) { _USIMDLstates[card] = USIM_RECEIVE; USIM_RX_CLEAR(card); } } // get the number of bytes received: USIM_RX_LENGTH_GET(card, dataLen); USIM_PERR_NUM_GET(card, parityLen); //check Parity Error FIFO usim_record_event_one_data(card, USIM_EVT_READ_USIMreadHandler_011, dataLen); usim_record_event_one_data(card, USIM_EVT_READ_USIMreadHandler_012, parityLen); if (parityLen) { _USIMParityErrorCnt[card]++; usim_record_event_four_data(card, USIM_EVT_READ_USIMreadHandler_013, _USIMParityErrorCnt[card]); } }// end of while(readRest==FALSE && dataLen) && (_USIMParityErrorCnt[card] == 0) } while (dataLen) { if (_USIMParityErrorCnt[card]==0) { if ( _USIMexpectedLen[card] < dataLen) // changened for VIBO USIM issue dataLen = _USIMexpectedLen[card]; // -lk- USIM_HW_RXRead(card, dataLen, _USIMrxBufferPtrs[card]); _USIMrxBufferPtrs[card] += dataLen; _USIMexpectedLen[card] -= dataLen; if((protocol == USIM_T0) && (_USIMstates[card] == USIM_ATR) && (dlState == USIM_RECEIVE)&& (calcATRlengthflag[card] == FALSE)) { UINT8 bytesRead = 0; UINT8 ATRlen = 0; UINT8 USIMcalcATRlen(USIM_Card card, UINT8 dataLen); bytesRead = _USIMrxBufferPtrs[card] - _USIMrxBuffers[card]; if(bytesRead > 12) { memcpy(_USIMatrBuffers[card], _USIMrxBuffers[card], bytesRead); ATRlen = USIMcalcATRlen(card, bytesRead); if(ATRlen >= bytesRead) { _USIMexpectedLen[card] = ATRlen - bytesRead; } calcATRlengthflag[card] = TRUE; } DIAG_FILTER(USIMLOG,USIMreadHandler,LOG03,DIAG_INFORMATION) diagPrintf("set %u, %d, %d", card, ATRlen, bytesRead); } /* VIBO USIM Issue. Check if instead of SW1 there is 'NULL' procedure bytes */ if ( (protocol == USIM_T0) && (_USIMstates[card] == USIM_SPECIFIC) && (dlState == USIM_RECEIVE)&& (_USIMexpectedLen[card] <= 1) ) { UINT8* pSW1SW2 = _USIMrxBufferPtrs[card] - 2 + _USIMexpectedLen[card] ; usim_record_event_one_data(card, USIM_EVT_READ_USIMreadHandler_014, pSW1SW2[0]); //check SW1 - second byte starting from the end of the buffer [data|data|data....data][SW1][SW2] if ( pSW1SW2[0] == USIM_NULL_BYTE) { if ( _USIMexpectedLen[card] == 0) { // All data has been read, so remove 'USIM_NULL_BYTE' and move SW2 into the SW1 pSW1SW2[0] = pSW1SW2[1]; //Correct expected len according the new value SW1(old SW2) ('NULL'?) _USIMexpectedLen[card] = ( pSW1SW2[0] == USIM_NULL_BYTE)?2:1; usim_record_event_one_data(card, USIM_EVT_READ_USIMreadHandler_015, _USIMexpectedLen[card]); } else { _USIMexpectedLen[card] = 2; usim_record_event(card, USIM_EVT_READ_USIMreadHandler_016); } // Update pointer according to found number (1 - 2) of 'USIM_NULL_BYTE' bytes _USIMrxBufferPtrs[card] = pSW1SW2 + 2 - _USIMexpectedLen[card]; } } // if ((protocol == USIM_T0) && (_USIMstates[card] == USIM_SPECIFIC) &&... }//_USIMParityErrorCnt[card] ==0 if (_USIMParityErrorCnt[card]) { usim_record_event_four_data(card, USIM_EVT_READ_USIMreadHandler_017, _USIMParityErrorCnt[card]); if ( protocol == USIM_T0) { // In Case of Parity Error AND T=0 - not necessary to read rest of data _USIMexpectedLen[card] = 0; break; } else USIM_RX_CLEAR(card); } if (_USIMexpectedLen[card] == 0 ) { usim_record_event(card, USIM_EVT_READ_USIMreadHandler_018); break; } // get the number of bytes received: USIM_RX_LENGTH_GET(card, dataLen); USIM_PERR_NUM_GET(card, parityLen); //check Parity Error FIFO usim_record_event_one_data(card, USIM_EVT_READ_USIMreadHandler_018, dataLen); usim_record_event_one_data(card, USIM_EVT_READ_USIMreadHandler_019, parityLen); if (parityLen) { _USIMParityErrorCnt[card]++; usim_record_event_four_data(card, USIM_EVT_READ_USIMreadHandler_020, _USIMParityErrorCnt[card]); } } // while (dataLen) } //if (wwtExpired == FALSE) if ((dlState == USIM_RECEIVE) && ((_USIMexpectedLen[card] == 0) || (wwtExpired == TRUE))) { // change DL state to "process" _USIMDLstates[card] = USIM_PROCESS; readRest[card] = FALSE; // clear all pending interrupts: USIM_CLEAR_ALL(card); /* Disable all interrupts */ USIM_DISABLE_ALL(card); USIM_WDT_TIMER_STOP(card); usim_record_event(card, USIM_EVT_READ_USIMreadHandler_021); // set the data read flag: OSAFlagSet(_USIMflagsRefs[card], USIM_DATA_READ_FLAG, OSA_FLAG_OR); } else /* Continue receiving data */ { if((status & USIM_RX_OVERRUN_MASK) && (protocol == USIM_T0)) { // Overrun error in T=0, character was retransmitted, clear interrupt USIM_INTERRUPT_CLEAR(card, USIM_RX_OVERRUN); usim_record_event(card, USIM_EVT_READ_USIMreadHandler_022); } if(protocol == USIM_T0) // -lk-- _USIMWTCnt[card] = _USIMatrInfos[card].workWaitingTime; // Instead of this: USIM_DL_WWTSet(card); if(readRest[card] == TRUE) { // set the Data Ready level according to the expected length: USIMrxLevelSet(card, _USIMexpectedLen[card]); } USIM_WDT_TIMER_START(card,2000); usim_record_event_four_data(card, USIM_EVT_READ_USIMreadHandler_023, USIM_WDT_CLK_VAL_READONLY(card, USIMCompRxFifoLevel(_USIMexpectedLen[card]))); // enable interrupts for "receive" state: USIM_ENABLE_MASK(card, USIM_RECEIVE_ENABLE_MASK); } } /* End of USIMreadHandler */ /******************************************************************************* * Function: USIMsisrBankingCard ******************************************************************************** * Description: second level ISR for the USIM_BANKING_CARD * * Parameters: None * * Return value: None. * * Notes: *******************************************************************************/ static void usim_lisr(USIM_Card card) { if(_USIMisDelaySet[card] && (_USIMinterruptStatus[card] & USIM_CWT_MASK)) { _USIMisDelaySet[card] = FALSE; usim_record_event(card, USIM_EVT_USIMsisrComCard_002); USIMdelayHandler(card); } else { usim_record_event_two_data(card, USIM_EVT_USIMsisrComCard_003, _USIMDLstates[card]); switch(_USIMDLstates[card]) { case USIM_WAIT_FOR_RESPONSE: USIMreadHandler(card, USIM_WAIT_FOR_RESPONSE); break; case USIM_RECEIVE: USIMreadHandler(card, USIM_RECEIVE); break; case USIM_SEND: USIMwriteHandler(card); break; default: return; }// end switch } } #ifdef USIM_DSDS_DKB static void USIMsisrBankingCard(void) { usim_lisr(USIM_BANKING_CARD); } #endif /******************************************************************************* * Function: USIMsisrComCard ******************************************************************************** * Description: second level ISR for the USIM_COM_CARD * * Parameters: None * * Return value: None. * * Notes: *******************************************************************************/ static void USIMsisrComCard(void) { usim_lisr(USIM_COM_CARD); }/* End of USIMsisrComCard */ /******************************************************************************* * Function: USIMhandler ******************************************************************************** * Description: handles the USIM interrupts * * Parameters: value - returned by INTC * * Return value: None. * * Notes: *******************************************************************************/ #ifndef PHS_SW_DEMO_TTC static void USIMhandler(UINT32 value) #else void USIMhandler(UINT32 value) #endif { UINT32 dummy,enabled_ints,status_ints,rxdata,txdata; //UINT32 pinStateMask = 0x80000000; // indicates the pin's state within value USIM_Card card = (USIM_Card)value; //if((value & ~pinStateMask) != _USIMinterruptSources[USIM_COM_CARD]) //{ // card++; //} // read the interrupt identification register: USIM_INTERRUPT_STATUS_GET(card,status_ints ); /* Clear all interrupts indications */ USIM_INTERRUPT_CLEAR_ALL(card); /* Dummy read, to verify that the interrupt clear has completed */ USIM_INTERRUPT_STATUS_GET(card,dummy); enabled_ints = USIM_GET_IER(card); /* Disable all interrupts */ USIM_DISABLE_ALL(card); usim_record_event_two_data(card, USIM_EVT_USIMhandler_001, (UINT16)status_ints); if ((status_ints & USIM_IIR_ALL_BITS_MASK )==0) { //abnormal case USIM_RX_LENGTH_GET(card, rxdata); USIM_TX_LENGTH_GET(card, txdata); usim_record_event_one_data(card, USIM_EVT_USIMhandler_002, txdata); usim_record_event_one_data(card, USIM_EVT_USIMhandler_003, rxdata); if ((enabled_ints & USIM_TX_DATA_REFILL_MASK) && txdata) { status_ints |= USIM_TX_DATA_REFILL_MASK; } if ((enabled_ints & USIM_RX_DATA_READY_MASK) && rxdata) { status_ints |= USIM_RX_DATA_READY_MASK; } if ((enabled_ints & USIM_IIR_ALL_BITS_MASK)==0) { USIM_ENABLE_MASK(card, enabled_ints); USIM_DIVISOR_SET(card, USIM_DIVISOR_GET(card)); return; } if(dummy) dummy =0; //Only to avoid the compile Warning } { if(status_ints&USIM_RX_OVERRUN_MASK) ASSERT(0); } _USIMinterruptStatus[card]= status_ints; ASSERT(OS_Activate_HISR(&_USIMhisrRefs[card]) == OS_SUCCESS); } /* End of USIMhandler */ static void USIMhandler_1(UINT32 v) { USIMhandler(USIM_COM_CARD); } #ifdef USIM_DSDS_DKB static void USIMhandler_2(UINT32 v) { USIMhandler(USIM_BANKING_CARD); } #endif /*----------- ATR Related Local Functions -----------------------------------*/ /******************************************************************************* * Function: USIMextraGuardTimeSet ******************************************************************************** * Description: Sets the extra guard time parameter, N * * Parameters: N - the extra guard time parameter, received at ATR * card - the USIM card * * Return value: None * * Notes: *******************************************************************************/ static void USIMextraGuardTimeSet(UINT8 N, USIM_Card card) { UINT32 exGuardTime = 0; USIM_ATRInfo * atrInfo = _USIMatrInfos + card; // check if 0 < N < 255 if (N != USIM_EQUAL_TX_EXTRA_GUARD_TIME) { exGuardTime = N; // check which protocol is in use: if(atrInfo->protocol == USIM_T1) { exGuardTime++; // beacause in T=1 HW adds 11 etu to the // exGuardTime, instead of the required 12 etu. } } // if using high baud rate - add 4 etu to extra guard time, due to errors seen on some cards if( (atrInfo->conversionFactor != USIM_DEFAULT_CONVERSION_FACTOR) || (atrInfo->adjustmentFactor != USIM_DEFAULT_ADJUSTMENT_FACTOR)) { exGuardTime += USIM_HIGH_BAUD_RATE_EXTRA_GUARD_TIME_ADJUST; } // verify that exGuardTime <= 255 if(exGuardTime > 0xFF) exGuardTime = 0xFF; if(atrInfo->extraGuardTime != (UINT8)exGuardTime) { // set the value in the HW register: USIM_EXTRA_GUARD_TIME_SET(card, exGuardTime); // set the value in _ATRInfo struct: atrInfo->extraGuardTime = (UINT8)exGuardTime; } return; } /* End of USIMextraGuardTimeSet */ //#ifndef USIM_NO_ATR_PPS_DECODING #if 1 /******************************************************************************* * Function: USIMconventionSet ******************************************************************************** * Description: Decodes the initial character and sets the used coding convention * * Parameters: convention - the received initial byte * card - the required card * * Return value: USIM_RC_OK * USIM_RC_ATR_ERROR * * Notes: *******************************************************************************/ static USIM_ReturnCode USIMconventionSet(UINT8 convention, USIM_Card card) { switch(convention) { case USIM_DIRECT: _USIMatrInfos[card].convention = USIM_DIRECT; break; case USIM_INVERSE: _USIMatrInfos[card].convention = USIM_INVERSE; break; default: return USIM_RC_ATR_ERROR; } return USIM_RC_OK; } /* End of USIMconventionSet */ /******************************************************************************* * Function: USIMdecodeTA1 ******************************************************************************** * Description: Decodes the TA1 character of the ATR, setting the indicated * factor and divisor values. * * Parameters: ta1 - the received byte * card - the USIM card * * Return value:None * * Notes: *******************************************************************************/ static void USIMdecodeTA1(UINT8 ta1, USIM_Card card) { UINT8 FI, DI; // get the indicated clock rate conversion factor, FI: USIM_GET_HIGH_END_FROM_BYTE(FI, ta1); // set its value according to lookup table: _USIMatrInfos[card].indConversionFactor = USIM_CONVERSION_FACTOR_TABLE[FI]; // set the max card clock frequency, f: _USIMatrInfos[card].indCardClock = USIM_MAX_FREQ_TABLE[FI]; // get the indicated baud rate adjustment factor, DI: USIM_GET_LOW_END_FROM_BYTE(DI, ta1); // set its value according to lookup table: _USIMatrInfos[card].indAdjustmentFactor= USIM_ADJUSTMENT_FACTOR_TABLE[DI]; return; } /* End of USIMdecodeTA1 */ /******************************************************************************* * Function: USIMdecodeTA2 ******************************************************************************** * Description: Decodes the TA2 character of the ATR: the specific mode byte * * Parameters: ta2 - the received byte * card - the USIM card * * Return value: None * * Notes: *******************************************************************************/ static void USIMdecodeTA2(UINT8 ta2, USIM_Card card) { USIM_ATRInfo * atrInfo = _USIMatrInfos + card; // check card's ability to change mode if (USIM_CHANGEABILITY_MASK & ta2) { atrInfo->modeChangeable = FALSE; } else { atrInfo->modeChangeable = TRUE; } // check which parameters would be used: indicated or default if (USIM_SPECIFIC_MODE_PARAM_INDICATOR_MASK & ta2) { // use default values atrInfo->conversionFactor = USIM_DEFAULT_CONVERSION_FACTOR; atrInfo->adjustmentFactor = USIM_DEFAULT_ADJUSTMENT_FACTOR; } else { // use indicated values: atrInfo->conversionFactor = atrInfo->indConversionFactor; atrInfo->adjustmentFactor = atrInfo->indAdjustmentFactor; } return; } /* End of USIMdecodeTA2 */ /******************************************************************************* * Function: USIMdecodeClockStopAndClass ******************************************************************************** * Description: Decodes the ATR character, which contains the clock stop and the * class indicators. * * Parameters: receivedByte - the received byte * card - the USIM card * * Return value: None * * Notes: *******************************************************************************/ static void USIMdecodeClockStopAndClass(UINT8 receivedByte, USIM_Card card) { UINT8 mask = 0x3F; USIM_HW_checkClock(card); // set the clock stop state: _USIMatrInfos[card].stopState = (~mask & receivedByte)>>6; if(_USIMatrInfos[card].stopState == USIM_CLK_STOP_LOW) { USIM_CARD_CLOCK_STOP_LEVEL_LOW(card); } else { USIM_CARD_CLOCK_STOP_LEVEL_HIGH(card); } // set the card classes supported: _USIMatrInfos[card].cardClasses = mask & receivedByte; return; } /* End of USIMdecodeClockStopAndClass */ /******************************************************************************* * Function: USIMgetHistoricalBytes ******************************************************************************** * Description: Copies the historical bytes from the ATR buffer to the ATRInfo * * Parameters: card - the USIM card * * Return value: None * * Notes: *******************************************************************************/ static void USIMgetHistoricalBytes(USIM_Card card) { USIM_ATRInfo * atrInfo = _USIMatrInfos + card; memcpy( atrInfo->historicBytes, _USIMatrBuffers[card] + (atrInfo->length - atrInfo->historicBytesNumber - 1), atrInfo->historicBytesNumber); } /* End of USIMgetHistoricalBytes */ /******************************************************************************* * Function: USIMcheckATR ******************************************************************************** * Description: checks the ATR: the result of XORing all bytes should be 0 * * Parameters: card - the USIM card * * Return value: USIM_RC_OK * USIM_RC_ATR_CHECK_FAILED * * Notes: *******************************************************************************/ static USIM_ReturnCode USIMcheckATR(USIM_Card card) { UINT8 count; UINT8 result=0; UINT8 * atrBuffer = _USIMatrBuffers[card]; for (count = 1; count < _USIMatrInfos[card].length; count++) { result ^= atrBuffer[count]; } if (result) { return USIM_RC_ATR_CHECK_FAILED; } return USIM_RC_OK; } /* End of USIMcheckATR */ /****************************************************************************** * Function : USIMendATR ******************************************************************************* * * Description : performs the end of the ATR decoding * * Parameters : globalInterface - indicator for global interface bytes. * N - extra guard time parameter * card - the USIM card * * Return value : USIM_RC_OK * USIM_RC_ATR_ERROR * USIM_RC_ATR_CHECK_FAILED * * Notes: ******************************************************************************/ USIM_ReturnCode USIMendATR(BOOL globalInterface, UINT8 N, USIM_Card card) { USIM_ATRInfo * atrInfo = _USIMatrInfos+card; USIM_Protocol protocol = atrInfo->protocol; USIM_ReturnCode rc; // copy historical bytes from buffer to _ATRInfo struct: if (atrInfo->historicBytesNumber) { USIMgetHistoricalBytes(card); } // Check Byte: if ((protocol != USIM_T0) || (globalInterface)) { // Check byte TCK is present: rc = USIMcheckATR(card); if ( rc != USIM_RC_OK) { return rc; } } // set the extra guard time HW register: USIMextraGuardTimeSet(N, card); if(_USIMstates[card] == USIM_ATR) { // set protocol: USIM_PROTOCOL_SET(card, protocol); // set the Character Waiting Time register: USIM_CHAR_WAIT_TIME_SET(card, protocol, (atrInfo->charWaitingTime+USIM_ADJUST_CWT_GCF)); // set the Block Waiting Time register: USIM_BLOCK_WAIT_TIME_SET(card, protocol, (atrInfo->blockWaitingTime+USIM_ADJUST_BWT_GCF)); // set the Block Guard Time Register: USIM_BLOCK_GUARD_TIME_SET(card, protocol); } else { if( (protocol == USIM_T0) && ((atrInfo->indAdjustmentFactor == 0) || (atrInfo->indAdjustmentFactor == 1)) && ((atrInfo->indConversionFactor == 0) || (atrInfo->indConversionFactor == 1))) { _USIMstates[card] = USIM_SPECIFIC; } } // set divisor last for resetting all waiting times: USIM_DIVISOR_SET(card, (USIM_DIVISOR_GET(card))); return USIM_RC_OK; } /* end of endATR */ /****************************************************************************** * Function : USIMprotocolParametersSelect ******************************************************************************* * * Description : Changes the protocol and the baud rate according to ATR. * * Parameters : card - the required card * * Output Param : None * * Return value : USIM_RC_OK * USIM_RC_PPS_ERROR * * Notes: ******************************************************************************/ static USIM_ReturnCode USIMprotocolParametersSelect(USIM_Card card) { UINT8 ppsMessage[USIM_PPS_LENGTH]; // The PPS message buffer //USe global RX instead UINT8 ppsResponse[USIM_PPS_LENGTH]; // The PPS response buffer UINT8 *ppsResponse = _USIMrxBuffers[card]; // The PPS response buffer USIM_ATRInfo * info = _USIMatrInfos + card; USIM_BaudRate baudRate; UINT8 FI = 0; UINT8 DI = 1; UINT8 pck = 0; UINT32 ppsResponseLen, ppsLen = 3; // PPSS, PPS0 and PCK UINT32 i, atrWwt, adjustmentFactor, conversionFactor; // save the Work Waiting Time indicated in the ATR: atrWwt = info->workWaitingTime; info->workWaitingTime = USIM_DEFAULT_WORK_WAIT_TIME+ USIM_ADJUST_WWT_GCF; //set the PPSS byte to 0xFF ppsMessage[USIM_PPSS] = 0xFF; //set the PPS0 byte according to protocol: ppsMessage[USIM_PPS0] = info->protocol; // set T=0 protocol for the PPS negociation: info->protocol = USIM_T0; //check whether baud rate should be negotiated: if((info->indAdjustmentFactor)&&(info->indConversionFactor)) { //set the PPS1 byte to be TA1 of the ATR ppsMessage[USIM_PPS1] = _USIMatrBuffers[card][USIM_PPS1]; //indicate the presence of PPS1 in PPS0: ppsMessage[USIM_PPS0] |= 0x10; //increment the PPS length ppsLen++; } // set PCK: for (i=0; iindAdjustmentFactor)&&(info->indConversionFactor)) { USIM_GET_HIGH_END_FROM_BYTE(FI, ppsMessage[USIM_PPS1]); USIM_GET_LOW_END_FROM_BYTE(DI, ppsMessage[USIM_PPS1]); } // get the desired baud rate from the baud rate table: baudRate = _USIMbaudRateTable[DI][FI]; if (USIM_HW_checkClock(card)) { /* abnormal */ return USIM_RC_GPIO_ERROR; } USIM_CARD_CLOCK_SET_RATIO(card, baudRate.ratio); USIM_FACTOR_SET(card, baudRate.factor); USIM_DIVISOR_SET(card, baudRate.divisor); } else if((ppsResponseLen != ppsLen - 1) || (ppsResponse[USIM_PPSS]!=ppsMessage[USIM_PPSS]) || ((ppsResponse[USIM_PPS0]&0x0F) != (ppsMessage[USIM_PPS0]&0x0F)) || (ppsResponse[USIM_PPS0] & 0x10) || (ppsResponse[ppsResponseLen-1]!= ppsResponse[USIM_PPSS]^ppsResponse[USIM_PPS0])) { return USIM_RC_PPS_ERROR; } // set protocol: info->protocol = (ppsResponse[USIM_PPS0] & 0x0F); USIM_PROTOCOL_SET(card, info->protocol); conversionFactor = USIM_CONVERSION_FACTOR_TABLE[FI]; adjustmentFactor = USIM_ADJUSTMENT_FACTOR_TABLE[DI]; if(info->protocol == USIM_T0) { // set the Work Waiting Time: info->workWaitingTime = atrWwt * adjustmentFactor+USIM_ADJUST_WWT_GCF; } else { // set the Block Waiting Time: info->blockWaitingTime = (info->blockWaitingTime * adjustmentFactor * USIM_DEFAULT_CONVERSION_FACTOR) / conversionFactor; } USIM_BLOCK_GUARD_TIME_SET(card, info->protocol); USIMextraGuardTimeSet(info->extraGuardTime, card); // set divisor last for resetting all waiting times: USIM_DIVISOR_SET(card, (USIM_DIVISOR_GET(card))); return USIM_RC_OK; } /* end of USIMprotocolParametersSelect */ UINT8 USIMcalcATRlen(USIM_Card card, UINT8 atrLen) { UINT8 TD; // the value of TD(i), according to protocol UINT8 currByte; // the ATR byte currently looked at UINT8 currByteNum = 0; // and its number UINT8 * atrBuffer = _USIMatrBuffers[card]; UINT8 ATRLen = 0; UINT8 N = 0; BOOL globalInterface=FALSE; // indicator for global interface bytes. // check initial character currByte = atrBuffer[currByteNum]; USIMconventionSet(currByte, card); USIM_CHECK_END_ATR; ATRLen++; /* TS */ /*#35520, delete second 0x3B byte when head two byte report 0x3B */ if(USIM_DIRECT == currByte || USIM_INVERSE == currByte) { USIM_CHECK_END_ATR; ATRLen++; } // get the Format Byte: TD = atrBuffer[currByteNum]; USIM_CHECK_END_ATR; ATRLen++; ATRLen += TD & USIM_HISTORIC_LEN_MASK; // Interface Bytes: // TA1: if (USIM_TA_MASK & TD) //TA1 is present { USIMdecodeTA1(currByte, card); USIM_CHECK_END_ATR; ATRLen++; } // TB1: if (USIM_TB_MASK & TD) // TB1 is present: Vpp, Ipp - irrelevant { USIM_CHECK_END_ATR; ATRLen++; } // TC1: if (USIM_TC_MASK & TD) // TC1 is present - extra guard time { // Set the extra guard time parameter N: USIM_CHECK_END_ATR; ATRLen++; } // TD1: if (USIM_TD_MASK & TD) // TD1 is present { TD = currByte; USIM_CHECK_END_ATR ATRLen++; } else { return ATRLen+1; } // TA2 if (USIM_TA_MASK & TD) // TA2 is present - specific mode byte { USIM_CHECK_END_ATR ATRLen++; } // TB2 if (USIM_TB_MASK & TD) // TB2 is present - alternative voltage, irrelevant { USIM_CHECK_END_ATR ATRLen++; } // TC2 if (USIM_TC_MASK & TD) // TC2 is present - Work Waiting Time { USIM_CHECK_END_ATR ATRLen++; } // TD2: if (USIM_TD_MASK & TD) // TD2 is present { TD = currByte; USIM_CHECK_END_ATR ATRLen++; } else { return ATRLen+1; } // TA3: if (USIM_TA_MASK & TD) // TA3 is present { USIM_CHECK_END_ATR ATRLen++; } //TB3: if (USIM_TB_MASK & TD) // TB3 is present - CWT and BWT { USIM_CHECK_END_ATR ATRLen++; } //TC3: if (USIM_TC_MASK & TD) // TC3 is present { USIM_CHECK_END_ATR ATRLen++; } // TD3: if (USIM_TD_MASK & TD) // TD3 is present { TD = currByte; USIM_CHECK_END_ATR ATRLen++; } else { return (ATRLen+1); } // TA4: if (USIM_TA_MASK & TD) // TA4 is present { USIM_CHECK_END_ATR ATRLen++; } // perform end of ATR decoding: return (ATRLen+1); } /****************************************************************************** * Function : USIManswerToReset ******************************************************************************* * * Description : decodes the ATR information sent by the card upon reset * * Parameters : card - the required card * atrLen - length of received ATR (2 - 33) * * Output Param : None * * Return value : USIM_RC_OK * USIM_RC_ATR_ERROR * USIM_RC_ATR_CHECK_FAILED * * Notes: ******************************************************************************/ static USIM_ReturnCode USIManswerToReset(USIM_Card card, UINT8 atrLen) { UINT8 TD; // the value of TD(i), according to protocol UINT8 N = 0; // extra guard time parameter N UINT8 WI = USIM_DEFAULT_WI; // work waiting time parameter WI, for T=0. UINT8 CWI = USIM_DEFAULT_CWI;// Character waiting time parameter CWI, for T=1. UINT8 BWI = USIM_DEFAULT_BWI;// Block waiting time parameter BWI, for T=1. UINT8 currByte; // the ATR byte currently looked at UINT8 currByteNum = 0; // and its number BOOL globalInterface=FALSE; // indicator for global interface bytes. USIM_ATRInfo * atrInfo = _USIMatrInfos+card; UINT8 * atrBuffer = _USIMatrBuffers[card]; // change state: _USIMstates[card] = USIM_NEGOTIABLE; // update the length field in the _ATRInfo structure: atrInfo->length = atrLen; // check initial character currByte = atrBuffer[currByteNum]; USIMconventionSet(currByte, card); USIM_CHECK_END_ATR; /*#35520, delete second 0x3B byte when head two byte report 0x3B */ if(USIM_DIRECT == currByte || USIM_INVERSE == currByte) { USIM_CHECK_END_ATR; } // get the Format Byte: TD = atrBuffer[currByteNum]; atrInfo->historicBytesNumber = TD & USIM_HISTORIC_LEN_MASK; USIM_CHECK_END_ATR; // Interface Bytes: // TA1: if (USIM_TA_MASK & TD) //TA1 is present { USIMdecodeTA1(currByte, card); USIM_CHECK_END_ATR; } // TB1: if (USIM_TB_MASK & TD) // TB1 is present: Vpp, Ipp - irrelevant { USIM_CHECK_END_ATR; } // TC1: if (USIM_TC_MASK & TD) // TC1 is present - extra guard time { // Set the extra guard time parameter N: N = currByte; USIM_CHECK_END_ATR } // TD1: if (USIM_TD_MASK & TD) // TD1 is present { TD = currByte; // get the transmission protocol: USIM_GET_LOW_END_FROM_BYTE(currByte, TD); if (currByte == USIM_GLOBAL_INTERFACE_BYTES) { return USIM_RC_ATR_ERROR; //globalInterface = TRUE; } else { atrInfo->protocol = currByte; } USIM_CHECK_END_ATR } else { return USIMendATR(globalInterface,N, card); } // TA2 if (USIM_TA_MASK & TD) // TA2 is present - specific mode byte { USIMdecodeTA2(currByte, card); // change state: _USIMstates[card] = USIM_SPECIFIC; USIM_CHECK_END_ATR } // TB2 if (USIM_TB_MASK & TD) // TB2 is present - alternative voltage, irrelevant { USIM_CHECK_END_ATR } // TC2 if (USIM_TC_MASK & TD) // TC2 is present - Work Waiting Time { WI = currByte; USIM_CHECK_END_ATR } // TD2: if (USIM_TD_MASK & TD) // TD2 is present { TD = currByte; // get the transmission protocol: USIM_GET_LOW_END_FROM_BYTE(currByte, TD); if (currByte == USIM_GLOBAL_INTERFACE_BYTES) { globalInterface = TRUE; } else { atrInfo->protocol = currByte; } USIM_CHECK_END_ATR } else { return USIMendATR(globalInterface,N, card); } // TA3: if (USIM_TA_MASK & TD) // TA3 is present { if (globalInterface) { // the byte contains the clock stop and the card class info: USIMdecodeClockStopAndClass(currByte, card); } else { // the byte refers to the card's information field size: atrInfo->infoFieldSize = currByte; } USIM_CHECK_END_ATR } //TB3: if (USIM_TB_MASK & TD) // TB3 is present - CWT and BWT { if (! globalInterface) { // the byte contains the CWT and the BWT: USIM_GET_LOW_END_FROM_BYTE(CWI, currByte); USIM_GET_HIGH_END_FROM_BYTE(BWI, currByte); } USIM_CHECK_END_ATR } // set the character and block waiting times: if (atrInfo->protocol == USIM_T0) { /* set work waiting time: */ atrInfo->workWaitingTime = (960*WI*USIM_DEFAULT_ADJUSTMENT_FACTOR) + USIM_ADJUST_WWT_GCF; // after PPS the adjustment factor may change. } else {// T1 is used: atrInfo->charWaitingTime = T1_ADJUST + (0x01 << CWI); atrInfo->blockWaitingTime = T1_ADJUST + (0x01 << BWI) * 960 * USIM_DEFAULT_ADJUSTMENT_FACTOR; // after PPS the adjustment factor may change.; } //TC3: if (USIM_TC_MASK & TD) // TC3 is present { if (! globalInterface) { // the byte contains the error detection code: atrInfo->errorCode = currByte; } USIM_CHECK_END_ATR } // TD3: if (USIM_TD_MASK & TD) // TD3 is present { TD = currByte; // get the global interface bytes indication: USIM_GET_LOW_END_FROM_BYTE(currByte, TD); if (currByte == USIM_GLOBAL_INTERFACE_BYTES) { globalInterface = TRUE; } USIM_CHECK_END_ATR } else { return USIMendATR(globalInterface,N, card); } // TA4: if (USIM_TA_MASK & TD) // TA4 is present { if (globalInterface) { // the byte contains the clock stop and the card class info: USIMdecodeClockStopAndClass(currByte, card); } USIM_CHECK_END_ATR } // perform end of ATR decoding: return USIMendATR(globalInterface,N, card); }/* End of USIManswerToReset */ #endif /* USIM_NO_ATR_PPS_DECODING */ /****************************************************************************** * Function: USIMcardClockStart ******************************************************************************* * Description: Starts the card's clock * * Parameters: card - the card whose clock is started * * Return value: TRUE - I/O HW error * * Notes: ******************************************************************************/ static BOOL USIMcardClockStart(UINT32 card) { if(_USIMclockStopped[card] == TRUE) { _USIMclockStopped[card] = FALSE; USIM_PmuClockSwitch((USIM_Card)card,TRUE); /* Turn clock on */ usim_hw_clk_onoff((USIM_Card)card, USIM_HW_CLOCK_START_REQ); if (USIM_HW_cardClockRequest((USIM_Card)card, USIM_HW_CLOCK_START_REQ)) { _USIMclockStopped[card] = TRUE; return TRUE; } // wait for 744 clock cycles before sending the command: return (USIM_HW_Delay((USIM_Card)card, USIM_CLOCK_RESUME_DELAY_CYCLES, 1)); //INTmode doesn't work properly in D2 } return FALSE ; } /****************************************************************************** * Function: USIMcardClockStop ******************************************************************************* * Description: Stops the card's clock * * Parameters: card - the card whose clock is stopped * * Return value: TRUE - I/O HW error * * Notes: ******************************************************************************/ static BOOL USIMcardClockStop(UINT32 card) { // wait for 1860 clock cycles before stopping the clock: BOOL rc = USIM_HW_Delay((USIM_Card)card, USIM_CLOCK_STOP_DELAY_CYCLES, 0); // change the clock stopped indicator: _USIMclockStopped[card] = TRUE; // stop the clock: if (USIM_HW_cardClockRequest((USIM_Card)card, USIM_HW_CLOCK_STOP_REQ)) { rc = TRUE; } usim_hw_clk_onoff((USIM_Card)card, USIM_HW_CLOCK_STOP_REQ); if (rc) { /* in false case, force diag printing */ TestUsimGetStatus((USIM_Card)card); } return (rc); } /* End of USIMcardClockStop */ UINT8 GetUSIMDDRLock(void) { if((_USIMclockStopped[0] == FALSE) || (_USIMclockStopped[1] == FALSE)) return 1; else return 0; } /****************************************************************************** * Function: USIMcardReset ******************************************************************************* * Description: Resets the card * * Parameters: card - the required card * * Return value: USIM_RC_OK * USIM_RC_ATR_ERROR * USIM_RC_PPS_ERROR * * Notes: ******************************************************************************/ static USIM_ReturnCode USIMcardReset(USIM_Card card) { UINT8 trial; // the number of consecutive reset trials UINT8 atrLen=0; // the length of the ATR USIM_ReturnCode rc = USIM_RC_ATR_ERROR; USIM_Class voltage = _USIMuseVoltageLevel[card]; USIM_BaudRate defaultBaudRate = _USIMbaudRateTable[1][0]; _USIMclockStopped[card] = FALSE; usimClockSwitch_ttc(card,TRUE); USIM_PmuClockSwitch(card,TRUE); usim_hw_clk_onoff((USIM_Card)card, USIM_HW_CLOCK_START_REQ); // set protocol to be T=0: USIM_PROTOCOL_SET(card, USIM_DEFAULT_PROTOCOL); _USIMatrInfos[card].protocol = USIM_DEFAULT_PROTOCOL; // initialize T=1 sequence numbers: _USIMcardSequence[card] = 0x01; _USIMdeviceSequence[card] = 0x01; // set extra guard time: USIM_EXTRA_GUARD_TIME_SET(card, USIM_DEFAULT_EXTRA_GUARD_TIME); _USIMatrInfos[card].extraGuardTime = USIM_DEFAULT_EXTRA_GUARD_TIME; // set block guard time: USIM_BLOCK_GUARD_TIME_SET(card, USIM_T0); // wait for the clock register to be changed: USIM_HW_checkClock(card); // set the card clock frequency: USIM_CARD_CLOCK_SET_RATIO(card, defaultBaudRate.ratio); // set factor: USIM_FACTOR_SET(card, defaultBaudRate.factor); // wait for the clock register to be changed: USIM_HW_checkClock(card); while((voltage != USIM_CLASS_A) && (rc != USIM_RC_OK)) { for (trial=0; (trial < USIM_RESET_REPEATS) && (rc != USIM_RC_OK); trial++) { // init the ATR database: USIMATRInfoInit(card); // clear all interrupts: USIM_CLEAR_ALL(card); // disable all interrupts: USIM_DISABLE_ALL(card); // Reset parity error count to detect the card's coding convention _USIMParityErrorCnt[card] = 0; calcATRlengthflag[card] = FALSE; _USIMWTCnt[card] = USIM_DEFAULT_WORK_WAIT_TIME; // set ATR CWT: USIM_CHAR_WAIT_TIME_SET(card, USIM_T0, USIM_DEFAULT_WORK_WAIT_TIME); //set ATR BWT: USIM_BLOCK_WAIT_TIME_SET(card, USIM_T0, USIM_ATR_BWT); // set divisor last for resetting all waiting times: USIM_DIVISOR_SET(card, defaultBaudRate.divisor); #ifdef SS_FEATURE USIMHWRegisters[card]->FCR |= 0x08; // set the parity error trigger level: USIM_PARITY_ERR_LEVEL_SET(card, USIM_PARITY_ERROR_INTERRUPT_TRIGGER); #endif // reset the card: DIAG_FILTER(USIMLOG, USIMcardReset, LOG002, DIAG_INFORMATION) diagPrintf("USIMcardReset %lu, trial=%lx, rc=%d, voltage=%lx", card, trial, rc, voltage); USIM_HW_cardReset(card, voltage); // change state: _USIMstates[card] = USIM_ATR; USIM_WDT_TIMER_START(card,300); // Read the received ATR from the Receive FIFO into the ATR Buffer: atrLen = (UINT8)USIM_DL_read(card, USIM_ATR_MAX_LEN, _USIMatrBuffers[card]); if (_USIMstates[card] == USIM_REMOVED) { return USIM_RC_CARD_REMOVED; } if (atrLen >= USIM_ATR_MIN_LEN) { DIAG_FILTER(USIMLOG, USIMcardReset, LOG003, DIAG_INFORMATION) diagPrintf("USIMcardReset %lu, atrLen=%lx", card, atrLen); DIAG_FILTER(USIMLOG, USIMcardReset, LOG004, DIAG_INFORMATION) diagStructPrintf("ATR Data:", _USIMatrBuffers[card], atrLen); #ifdef USIM_NO_ATR_PPS_DECODING // rc = USIM_RC_OK; rc = USIManswerToReset(card, atrLen); DIAG_FILTER(USIMLOG, USIMcardReset, LOG010, DIAG_INFORMATION) diagPrintf("USIManswerToReset %d=0x%lx", card, rc); #else // decode ATR: rc = USIManswerToReset(card, atrLen); if(rc == USIM_RC_OK) { // compare card class if (voltage != (_USIMatrInfos[card].cardClasses & voltage)) { rc = USIM_RC_ATR_ERROR; /* Try the next voltage level */ trial = USIM_RESET_REPEATS; /* we can try the next voltage only if the current is * 1.8V and 3V is supported by the card */ if(!((voltage == USIM_CLASS_C) &&((_USIMatrInfos[card].cardClasses & USIM_CLASS_B ) != 0 ))) break; //exit the while loop, deactivate the card } } #endif /* USIM_NO_ATR_PPS_DECODING */ } else { #ifdef SS_FEATURE if ((_USIMParityErrorCnt[card] > 0 ) || (_USIMstates[card] == USIM_WDT_TIMER_EXPIRED)) { /* Parity error may be a result of the wrong coding convention convetion */ UINT8 parityLen = 0; UINT8 eprLen = 0; USIM_PERR_NUM_GET(card, parityLen); //check Parity Error FIFO eprLen = (USIMHWRegisters[card]->LCR)&0x04L; // try changing the convention: USIM_CONVENTION_TOGGLE(card); } else { if(_USIMstates[card] != USIM_WDT_TIMER_EXPIRED) trial = USIM_RESET_REPEATS; rc = USIM_RC_ATR_ERROR; } #else if (_USIMParityErrorCnt[card] > 0 || (_USIMErrorStat[card] & USIM_FRAMING_ERR_MASK)) { DIAG_FILTER(USIMLOG, USIMcardReset, LOG005, DIAG_INFORMATION) diagPrintf("USIMcardReset %lu, _USIMParityErrorCnt=%lx, _USIMErrorStat[card]=%lx", card, _USIMParityErrorCnt[card], _USIMErrorStat[card]); USIM_CONVENTION_TOGGLE(card); } else { DIAG_FILTER(USIMLOG, USIMcardReset, LOG006, DIAG_INFORMATION) diagPrintf("USIMcardReset %lu, try next voltage", card); trial = USIM_RESET_REPEATS; rc = USIM_RC_ATR_ERROR; } #endif } if(rc != USIM_RC_OK) { DIAG_FILTER(USIMLOG, USIMcardReset, LOG007, DIAG_INFORMATION) diagPrintf("USIMcardReset %lu, fail, USIM_HW_deactivate", card); USIM_HW_deactivate(card, FALSE); /* wait for 10ms delay before reactivating: */ OSATaskSleep(USIM_REACTIVATE_DELAY_CYCLES); } }// end for trial if(rc != USIM_RC_OK) { voltage >>= 1; } }//end while voltage if(rc != USIM_RC_OK) { DIAG_FILTER(USIMLOG, USIMcardReset, LOG008, DIAG_INFORMATION) diagPrintf("USIMcardReset %lu, fail, rc=%d", card, rc); return rc; } #ifdef USIM_NO_ATR_PPS_DECODING DIAG_FILTER(USIMLOG, USIMcardReset, LOG009, DIAG_INFORMATION) diagPrintf("USIMcardReset %lu, USIMControlIndication=%lx, USIMResponseNotify", card, (USIM_CLASS_TO_CTRL_IND(voltage))); _USIMstates[card] = USIM_SPECIFIC; USIMControlIndication(card, (USIM_CLASS_TO_CTRL_IND(voltage))); USIMResponseNotify(card, NULL, atrLen, _USIMatrBuffers[card]); #else if(_USIMstates[card] == USIM_NEGOTIABLE) { rc = USIMprotocolParametersSelect(card); if(rc != USIM_RC_OK) { // USIMClockStop(card); return rc; } } _USIMstates[card] = USIM_SPECIFIC; if(_USIMatrInfos[card].protocol == USIM_T1) { rc = USIM_DL_T1Initiate(card); } #endif return rc; } /* End of USIMcardReset */ static USIM_ReturnCode USIMcardReset_boot(USIM_Card card) { UINT8 trial; // the number of consecutive reset trials UINT8 atrLen=0; // the length of the ATR USIM_ReturnCode rc = USIM_RC_ATR_ERROR; USIM_Class voltage = _USIMuseVoltageLevel[card]; USIM_BaudRate defaultBaudRate = _USIMbaudRateTable[1][0]; _USIMclockStopped[card] = FALSE; usimClockSwitch_ttc(card,TRUE); USIM_PmuClockSwitch(card,TRUE); usim_hw_clk_onoff((USIM_Card)card, USIM_HW_CLOCK_START_REQ); // set protocol to be T=0: USIM_PROTOCOL_SET(card, USIM_DEFAULT_PROTOCOL); _USIMatrInfos[card].protocol = USIM_DEFAULT_PROTOCOL; // initialize T=1 sequence numbers: _USIMcardSequence[card] = 0x01; _USIMdeviceSequence[card] = 0x01; // set extra guard time: USIM_EXTRA_GUARD_TIME_SET(card, USIM_DEFAULT_EXTRA_GUARD_TIME); _USIMatrInfos[card].extraGuardTime = USIM_DEFAULT_EXTRA_GUARD_TIME; // set block guard time: USIM_BLOCK_GUARD_TIME_SET(card, USIM_T0); // wait for the clock register to be changed: USIM_HW_checkClock(card); // set the card clock frequency: USIM_CARD_CLOCK_SET_RATIO(card, defaultBaudRate.ratio); // set factor: USIM_FACTOR_SET(card, defaultBaudRate.factor); // wait for the clock register to be changed: USIM_HW_checkClock(card); while((voltage != USIM_CLASS_A) && (rc != USIM_RC_OK)) { for (trial=0; (trial < USIM_RESET_REPEATS) && (rc != USIM_RC_OK); trial++) { // init the ATR database: USIMATRInfoInit(card); // clear all interrupts: USIM_CLEAR_ALL(card); // disable all interrupts: USIM_DISABLE_ALL(card); // Reset parity error count to detect the card's coding convention _USIMParityErrorCnt[card] = 0; _USIMWTCnt[card] = USIM_DEFAULT_WORK_WAIT_TIME; // set ATR CWT: USIM_CHAR_WAIT_TIME_SET(card, USIM_T0, USIM_DEFAULT_WORK_WAIT_TIME); //set ATR BWT: USIM_BLOCK_WAIT_TIME_SET(card, USIM_T0, USIM_ATR_BWT); // set divisor last for resetting all waiting times: USIM_DIVISOR_SET(card, defaultBaudRate.divisor); USIM_HW_cardReset(card, voltage); // change state: _USIMstates[card] = USIM_ATR; USIM_WDT_TIMER_START(card,300); // Read the received ATR from the Receive FIFO into the ATR Buffer: atrLen = (UINT8)USIM_DL_read(card, USIM_ATR_MAX_LEN, _USIMatrBuffers[card]); if (_USIMstates[card] == USIM_REMOVED) { return USIM_RC_CARD_REMOVED; } if (atrLen >= USIM_ATR_MIN_LEN) { // rc = USIM_RC_OK; rc = USIManswerToReset(card, atrLen); } else { if (_USIMParityErrorCnt[card] > 0 || (_USIMErrorStat[card] & USIM_FRAMING_ERR_MASK)) { USIM_CONVENTION_TOGGLE(card); } else { trial = USIM_RESET_REPEATS; rc = USIM_RC_ATR_ERROR; } } if(rc != USIM_RC_OK) { USIM_HW_deactivate(card, FALSE); /* wait for 10ms delay before reactivating: */ OSATaskSleep(USIM_REACTIVATE_DELAY_CYCLES); } }// end for trial if(rc != USIM_RC_OK) { voltage >>= 1; } }//end while voltage usim_boot_atr_info[card].voltage=voltage; usim_boot_atr_info[card].len=atrLen; usim_boot_atr_info[card].flag=1; if(rc != USIM_RC_OK) { DIAG_FILTER(USIMLOG, USIMcardReset, LOG008, DIAG_INFORMATION) diagPrintf("USIMcardReset %lu, fail, rc=%d", card, rc); return rc; } _USIMstates[card] = USIM_SPECIFIC; return rc; } /* End of USIMcardReset */ /****************************************************************************** * Function: USIMregistersInit ******************************************************************************* * Description: Initializes the USIM I/F registers * * Parameters: card - the required card * * Return value: None * * Notes: called by USIMPhase1Init ******************************************************************************/ static void USIMregistersInit(USIM_Card card) { USIM_BaudRate defaultBaudRate = _USIMbaudRateTable[1][0]; USIM_PmuClockSwitch(card,TRUE); /* Turn clock on */ _USIMclockStopped[card] = FALSE; usim_hw_clk_onoff((USIM_Card)card, USIM_HW_CLOCK_START_REQ); // clear FIFOs: USIM_RX_CLEAR(card); USIM_TX_CLEAR(card); // disable all interrupts: USIM_DISABLE_ALL(card); #ifdef SS_FEATURE USIMHWRegisters[card]->FCR |= 0x08; #endif // set the parity error trigger level: USIM_PARITY_ERR_LEVEL_SET(card, USIM_PARITY_ERROR_INTERRUPT_TRIGGER); // set the T=0 error trigger level: USIM_T0_ERR_LEVEL_SET(card, USIM_ERROR_REPEAT); // set protocol to be T=0: USIM_PROTOCOL_SET(card, USIM_DEFAULT_PROTOCOL); // set the coding convention: USIM_CONVENTION_SET(card, USIM_DEFAULT_CONVENTION); // set extra guard time: USIM_EXTRA_GUARD_TIME_SET(card, USIM_DEFAULT_EXTRA_GUARD_TIME); // set block guard time: USIM_BLOCK_GUARD_TIME_SET(card, USIM_T0); // set character waiting time: USIM_CHAR_WAIT_TIME_SET(card, USIM_T0, USIM_DEFAULT_WORK_WAIT_TIME); // set block waiting time: USIM_BLOCK_WAIT_TIME_SET(card, USIM_T0, USIM_DEFAULT_WORK_WAIT_TIME); USIM_HW_checkClock(card); // set the card clock frequency: USIM_CARD_CLOCK_SET_RATIO(card, defaultBaudRate.ratio); // set factor: USIM_FACTOR_SET(card, (defaultBaudRate.factor)); // set divisor: USIM_DIVISOR_SET(card, (defaultBaudRate.divisor)); // set the TX block size: USIM_TX_BLOCK_SET(card); USIM_PmuClockSwitch(card,FALSE); /* Turn clock off */ _USIMclockStopped[card] = TRUE; } /* End of USIMregistersInit */ /****************************************************************************** * Function: USIMATRInfoInit ******************************************************************************* * Description: Initializes the ATR Info structure * * Parameters: card - the required card * * Return value: None * * Notes: called by USIMPhase1Init ******************************************************************************/ static void USIMATRInfoInit(USIM_Card card) { USIM_ATRInfo * info = _USIMatrInfos + card; info->cardClock = (USIM_Frequency)(240 / ((_USIMbaudRateTable[1][0]).ratio)); info->indCardClock = (USIM_Frequency)0; info->conversionFactor = USIM_DEFAULT_CONVERSION_FACTOR; info->indConversionFactor = 0; info->adjustmentFactor = USIM_DEFAULT_ADJUSTMENT_FACTOR; info->indAdjustmentFactor = 0; info->extraGuardTime = USIM_DEFAULT_EXTRA_GUARD_TIME; info->modeChangeable = FALSE; info->protocol = USIM_DEFAULT_PROTOCOL; info->stopState = USIM_CLK_STOP_NOT_SUPPORTED; info->cardClasses = (USIM_Class)USIM_DEFAULT_AVAILABLE_CLASSES; info->convention = USIM_DEFAULT_CONVENTION; info->historicBytesNumber = 0; info->length = 0; info->infoFieldSize = USIM_DEFAULT_INFO_FIELD_SIZE; info->workWaitingTime = USIM_DEFAULT_WORK_WAIT_TIME + USIM_ADJUST_WWT_GCF; info->charWaitingTime = USIM_DEFAULT_CHAR_WAIT_TIME; info->blockWaitingTime = USIM_DEFAULT_BLOCK_WAIT_TIME; info->errorCode = USIM_LRC; // info->wdtTime = (info->workWaitingTime * 260 + 2610) * USIM_DEFAULT_CONVERSION_FACTOR * 10 / (info->cardClock * USIM_DEFAULT_ADJUSTMENT_FACTOR) } /* End of USIMATRInfoInit */ /****************************************************************************** * Function : USIMControlIndication ******************************************************************************* * * Description : Sends the control indication to the USIM Manager * * Parameters : card - the card indicated. * status - the card's status * * Return value : None * * Notes: ******************************************************************************/ void USIMControlIndication (USIM_Card card, USIM_ControlStatus status) { if (_USIMcontrolIndications[card] == NULL) { DIAG_FILTER(USIMLOG, USIMControlIndication, LOG001, DIAG_INFORMATION) diagPrintf("USIMControlIndication %u %lx, null",card, status); USIMClose(card); //No PS, do it here } else { DIAG_FILTER(USIMLOG, USIMControlIndication, LOG002, DIAG_INFORMATION) diagPrintf("USIMControlIndication %u %lx",card, status); (_USIMcontrolIndications[card])(status); } } /****************************************************************************** * Function : USIMResponseNotify ******************************************************************************* * * Description : Sends the card's response to the USIM Manager * * Parameters : card - the card which sent the data. * header - a pointer to the response header * dataLength - length in bytes of the returned data * data - a pointer to the buffer which contains the data * * Return value : None * * Notes: ******************************************************************************/ void USIMResponseNotify(USIM_Card card, USIM_ResponseHeader * header, UINT16 dataLength, UINT8 * data) { if (_USIMresponseNotifies[card] != NULL) { (_USIMresponseNotifies[card])(header, dataLength, data); } }/* End of USIMResponseNotify */ /*----------- Global function definition ------------------------------------*/ /****************************************************************************** * Function: USIMClockStop ******************************************************************************* * Description: Stops the card's clock * * Parameters: card - the card whose clock is stopped * * Return value: USIM_RC_OK * USIM_RC_INVALID_CARD * * Notes: ******************************************************************************/ USIM_ReturnCode USIMClockStop(USIM_Card card) { USIM_CHECK_CARD_VALID(card); USIM_ReturnCode rc = USIM_RC_OK; if((_USIMclockStopped[card] == FALSE) && (_USIMatrInfos[card].stopState != USIM_CLK_STOP_NOT_SUPPORTED)) { /* stop the clock: */ BOOL rs; USIM_WDT_TIMER_START(card, USIM_WDT_CLK_STOP_VAL); /* stop the clock: */ rs = USIMcardClockStop(card); USIM_WDT_TIMER_STOP(card); USIM_PmuClockSwitch(card,FALSE); /* Turn clock off */ if (rs) rc = USIM_RC_GPIO_ERROR; } return (rc); } /* End of USIMClockStop */ #ifdef USIM_NO_ATR_PPS_DECODING /*CQ00076401, lkrasnop, 23/11/2014, Warm Reset, begin*/ /****************************************************************************** * Function: USIMWarmReset ******************************************************************************* * Description: Make warm Resets of the card * * Parameters: card - the required card * voltageClass - the voltage to be applied to the card * * Return value: USIM_RC_OK * USIM_RC_INVALID_CARD * USIM_RC_ATR_ERROR * USIM_RC_CARD_REMOVED * USIM_RC_CARD_CLOSED * * Notes: ******************************************************************************/ USIM_ReturnCode USIMWarmReset(USIM_Card card) { if (USIMcardClockStart(card)) { TestUsimGetStatus(card /*, USIM_RC_GPIO_ERROR*/); return USIM_RC_GPIO_ERROR; } USIM_HW_cardReset(card, _USIMcurrentVoltageClass[card]); return USIM_RC_OK; } /*CQ00076401, lkrasnop, 23/11/2014, Warm Reset, end*/ /****************************************************************************** * Function: USIMReset ******************************************************************************* * Description: Resets the card * * Parameters: card - the required card * voltageClass - the voltage to be applied to the card * * Return value: USIM_RC_OK * USIM_RC_INVALID_CARD * USIM_RC_ATR_ERROR * USIM_RC_CARD_REMOVED * USIM_RC_CARD_CLOSED * * Notes: ******************************************************************************/ USIM_ReturnCode USIMReset(USIM_Card card, USIM_Class voltageClass) { USIM_ReturnCode rc = USIM_RC_OK; USIM_CHECK_CARD_VALID(card); extern USIM_Class _USIMcurrentVoltageClass[USIM_CARDS_AMOUNT]; /*CQ00076401, lkrasnop, 23/11/2014, Warm Reset*/ DIAG_FILTER(USIMLOG, USIMReset, LOG001, DIAG_INFORMATION) diagPrintf("USIMReset %u, voltageClass=%lu",card, voltageClass); if( _USIM_hwRemoveProgress[card]) { DIAG_FILTER(USIMLOG, USIMReset, LOG002, DIAG_INFORMATION) diagPrintf("USIMReset %u, USIMClose", card); USIMClose(card); return USIM_RC_CARD_REMOVED; } // verify that registration of return functions took place: if (_USIMresponseNotifies[card] == NULL) { DIAG_FILTER(USIMLOG, USIMReset, LOG003, DIAG_INFORMATION) diagPrintf("USIMReset %u, _USIMresponseNotifies null", card); return USIM_RC_NOT_REGISTERED; } // init the ATR database: USIMATRInfoInit(card); /*CQ00076401, lkrasnop, 23/11/2014, Warm Reset, begin*/ if (voltageClass != USIM_CLASS_NULL) { /* normal reset case */ DIAG_FILTER(USIMLOG, USIMReset, LOG004, DIAG_INFORMATION) diagPrintf("USIMReset %u, Warm Reset", card); _USIMuseVoltageLevel[card] = voltageClass; } else /* WARM RESET request: voltageClass == USIM_CLASS_NULL */ { /* warm reset case ! */ /* send USIM_CARD_DEACTIVATED to cause SIG_L1SI_CARD_REMOVED_IND send to Sim Mgr*/ DIAG_FILTER(USIMLOG, USIMReset, LOG005, DIAG_INFORMATION) diagPrintf("USIMReset %u, USIMControlIndication", card); USIMControlIndication(card, USIM_CARD_DEACTIVATED); /*107252*/ _USIMuseVoltageLevel[card] = _USIMcurrentVoltageClass[card]; if (_USIMuseVoltageLevel[card] == USIM_CLASS_NULL) { DIAG_FILTER(USIMLOG, USIMReset, LOG006, DIAG_INFORMATION) diagPrintf("USIMReset %u, _USIMuseVoltageLevel=%lu", card, _USIMuseVoltageLevel[card]); /* trying to use WARM reset, when we can't use it, so move to cold reset with Default Class */ _USIMuseVoltageLevel[card] = USIM_DEFAULT_CLASS; voltageClass = USIM_DEFAULT_CLASS; } } /*CQ00076401, lkrasnop, 23/11/2014, Warm Reset, end*/ if((_USIMstates[card] != USIM_SPECIFIC) && (_USIMstates[card] != USIM_WDT_TIMER_EXPIRED)) { /* card is closed: */ DIAG_FILTER(USIMLOG, USIMReset, LOG007, DIAG_INFORMATION) diagPrintf("USIMReset %u, _USIMstates=%lx, _USIMstates=%lx", card, _USIMstates[card], _USIMstates[card]); rc = USIMOpen(card); } else { /*CQ00076401, lkrasnop, 23/11/2014, Warm Reset, begin*/ if (voltageClass != USIM_CLASS_NULL) { /* normal reset case */ DIAG_FILTER(USIMLOG, USIMReset, LOG008, DIAG_INFORMATION) diagPrintf("USIMReset %u,voltageClass=%lx, USIM_HW_deactivate", card, voltageClass); /*CQ00076401, lkrasnop, 23/11/2014, Warm Reset, single line below was prior of change*/ USIM_HW_deactivate(card, FALSE); // Deactivate SIM card before any reset, in case voltage changes afterwards } /*CQ00076401, lkrasnop, 23/11/2014, Warm Reset, end*/ OSATaskSleep(USIM_REACTIVATE_DELAY_CYCLES); rc = USIMcardReset(card); DIAG_FILTER(USIMLOG, USIMReset, LOG009, DIAG_INFORMATION) diagPrintf("USIMReset %u, USIMcardReset rc=%d", card, rc); if ( rc != USIM_RC_OK ) { DIAG_FILTER(USIMLOG, USIMReset, LOG010, DIAG_INFORMATION) diagPrintf("USIMReset %u, USIMClose", card); USIMClose(card); //return rc; } } _USIMuseVoltageLevel[card] = USIM_DEFAULT_CLASS; return rc; } /* End of USIMReset */ /****************************************************************************** * Function: USIMPPSSend ******************************************************************************* * Description: Sends a PPS request to the card * * Parameters: card - the required card * length - the number of bytes in the PPS request * data - the PPS request buffer * * Return value: USIM_RC_OK * USIM_RC_INVALID_CARD * USIM_RC_CARD_REMOVED * USIM_RC_CARD_CLOSED * USIM_RC_NULL_POINTER * USIM_RC_PPS_ERROR * * Notes: ******************************************************************************/ USIM_ReturnCode USIMPPSSend(USIM_Card card, UINT8 length, UINT8 * data) { UINT32 returnedLength = 0; USIM_ReturnCode rc = USIM_RC_OK; if( (_USIM_hwRemoveProgress[card]) || (_USIMstates[card] == USIM_REMOVED)) { USIMClose(card); return USIM_RC_CARD_REMOVED; } if (_USIMstates[card] != USIM_SPECIFIC) { return USIM_RC_CARD_CLOSED; } if (data == NULL) { return USIM_RC_NULL_POINTER; } // change state to negotiable: _USIMstates[card] = USIM_NEGOTIABLE; /* Turn clock on */ if (! USIMcardClockStart(card)) { /* Send the PPS request and receive the response: */ returnedLength = USIM_DL_writeRead (card, (UINT32)length, data, (UINT32)length, _USIMdataBuffers[card]); } else { rc = USIM_RC_GPIO_ERROR; } /* Check for HW remove detected */ if ((rc == USIM_RC_OK) && (_USIMstates[card] == USIM_REMOVED)) rc = USIM_RC_CARD_REMOVED; if (rc == USIM_RC_OK) { // change state to specific: _USIMstates[card] = USIM_SPECIFIC; if(returnedLength) { // send the PPS response to the USIM Manager: USIMResponseNotify(card, NULL, returnedLength, _USIMdataBuffers[card]); } else { rc = USIM_RC_PPS_ERROR; } // give small delay for slow cards OSATaskSleep(3); //We using the task sleep instead of timerDelay to avoid stucking of the GPB bus by the timerDelay DIAG_FILTER(HAL, USIM,api_USIMPPSSend1, DIAG_INFORMATION) diagStructPrintf("USIM API USIMPPSSend exit : ", _USIMdataBuffers[card], returnedLength); } return rc; } /* End of USIMPPSSend */ /****************************************************************************** * Function: USIMConfigure ******************************************************************************* * Description: Configures the physical transmission parameters * * Parameters: card - the required card * config - pointer to the configuration structure * * Return value: USIM_RC_OK * USIM_RC_INVALID_CARD * USIM_RC_NULL_POINTER * * Notes: ******************************************************************************/ #ifdef EDEN_1928 unsigned long USIM_pin_clock_status[2] = {1,1}; #endif USIM_ReturnCode USIMConfigure(USIM_Card card, USIM_Configuration * config) { USIM_ATRInfo * atrInfo = &_USIMatrInfos[card]; USIM_BaudRate baudRate; UINT8 FI, DI; BOOL T1Init = FALSE; USIM_ReturnCode rc = USIM_RC_OK ; DIAG_FILTER(USIMLOG,USIMConfigure,LOG001,DIAG_INFORMATION) diagPrintf("USIMConfigure %u", card); if(config == NULL) { DIAG_FILTER(USIMLOG,USIMConfigure,LOG002,DIAG_INFORMATION) diagPrintf("USIMConfigure %u, config null", card); return USIM_RC_NULL_POINTER; } if(_USIM_hwRemoveProgress[card]) { DIAG_FILTER(USIMLOG,USIMConfigure,LOG003,DIAG_INFORMATION) diagPrintf("USIMConfigure %u, _USIM_hwRemoveProgress, USIMClose", card); USIMClose(card); return USIM_RC_CARD_REMOVED; } if (USIMcardClockStart(card)) { DIAG_FILTER(USIMLOG,USIMConfigure,LOG004,DIAG_INFORMATION) diagPrintf("USIMConfigure %u, USIMcardClockStart error", card); return USIM_RC_GPIO_ERROR; } /* Baud Rate parameters: */ FI = config->clockRateFactorRef; DI = config->baudRateFactorRef; /* get the desired baud rate from the baud rate table: */ baudRate = _USIMbaudRateTable[DI][FI]; if ( USIM_CARD_CLOCK_GET_DIVISOR(card) != baudRate.ratio) { if (USIM_HW_checkClock(card)) { /* abnormal */ DIAG_FILTER(USIMLOG,USIMConfigure,LOG005,DIAG_INFORMATION) diagPrintf("USIMConfigure %u, USIM_HW_checkClock error", card); return USIM_RC_GPIO_ERROR; } USIM_CARD_CLOCK_SET_RATIO(card, baudRate.ratio); } if(USIM_FACTOR_GET(card) != baudRate.factor) { USIM_FACTOR_SET(card, baudRate.factor); } atrInfo->cardClock = (USIM_Frequency)(240 / ((int)baudRate.ratio)); atrInfo->conversionFactor = USIM_CONVERSION_FACTOR_TABLE[FI]; atrInfo->adjustmentFactor = USIM_ADJUSTMENT_FACTOR_TABLE[DI]; /* set transmission protocol: */ if(config->protocol == USIM_T0) { if(atrInfo->protocol != USIM_T0) { USIM_PROTOCOL_SET(card, USIM_T0); atrInfo->protocol = USIM_T0; } /* set work waiting time: */ _USIMWTCnt[card] = config->workWaitingTime+ USIM_ADJUST_WWT_GCF; atrInfo->workWaitingTime = config->workWaitingTime+ USIM_ADJUST_WWT_GCF; /* *MS->SIM max: 255 max data + 5 bytes APDU = 261 bytes * SIM->MS max: 255 bytes + 2 SW1/SW2 = 258 bytes * * + BWT + 258 *CWT == 259*WWT (for T=0) * 261*10etu */ //atrInfo->wdtTime = ((atrInfo->workWaitingTime * 260 + 2610) * FI * 10 ) / (atrInfo->cardClock * DI); } else { /* T1 used: */ if(atrInfo->protocol != USIM_T1) { USIM_PROTOCOL_SET(card, USIM_T1); atrInfo->protocol = USIM_T1; T1Init = TRUE; } if((atrInfo->charWaitingTime+ USIM_ADJUST_CWT_GCF) != config->charWaitingTime) { /* set the Character Waiting Time register: */ USIM_CHAR_WAIT_TIME_SET(card, USIM_T1, (config->charWaitingTime + USIM_ADJUST_CWT_GCF)); atrInfo->charWaitingTime = config->charWaitingTime+ USIM_ADJUST_CWT_GCF; } // Save the BWT: _USIMWTCnt[card] = config->blockWaitingTime+ USIM_ADJUST_BWT_GCF; atrInfo->blockWaitingTime = config->blockWaitingTime+ USIM_ADJUST_BWT_GCF; /* Set the card's Information Field Size: */ atrInfo->infoFieldSize = config->infoFieldSize; //atrInfo->wdtTime = ((atrInfo->blockWaitingTime + atrInfo->charWaitingTime * 260 + 2610) * FI * 10 ) / (atrInfo->cardClock * DI); } // set the Block Guard Time Register: USIM_BLOCK_GUARD_TIME_SET(card, atrInfo->protocol); /* set the Extra Guard Time Register: */ USIMextraGuardTimeSet(config->extraGuardTime, card); if(atrInfo->stopState != config->stopState) { if (USIM_HW_checkClock(card)) { /* abnormal */ DIAG_FILTER(USIMLOG,USIMConfigure,LOG006,DIAG_INFORMATION) diagPrintf("USIMConfigure %u, USIM_HW_checkClock error", card); rc = USIM_RC_GPIO_ERROR; } /* Set the clock stop level: */ if(config->stopState == USIM_CLK_STOP_HIGH) { #ifdef EDEN_1928 USIM_pin_clock_status[card] = 1; #endif USIM_CARD_CLOCK_STOP_LEVEL_HIGH(card); } else { #ifdef EDEN_1928 USIM_pin_clock_status[card] = 0; #endif USIM_CARD_CLOCK_STOP_LEVEL_LOW(card); } atrInfo->stopState = config->stopState; } USIM_DIVISOR_SET(card, baudRate.divisor); if ((rc == USIM_RC_OK) && ( T1Init)) { rc = USIM_DL_T1Initiate(card); if (rc != USIM_RC_OK) { USIMClose(card); return rc; } // give small delay for slow cards OSATaskSleep(3); //We using the task sleep instead of timerDelay to avoid stucking of the GPB bus by the timerDelay } return rc; } /* End of USIMConfigure */ #endif /* USIM_NO_ATR_PPS_DECODING */ /***************************************************************************** * Function : USIMATRGet Moved to the end of file * to resolve an optimisation *.axf problem in JTAG debugger ******************************************************************************/ /***************************************************************************** * Function : USIMStatusGet ****************************************************************************** * * Description : Retrieves the card's status * * Parameters : card - the required USIM card * * Output Param : status - a pointer to the retrieved status structure * * * Return value : USIM_RC_OK * USIM_RC_INVALID_CARD * USIM_RC_NULL_POINTER * * Notes: *****************************************************************************/ USIM_ReturnCode USIMStatusGet (USIM_Card card, USIM_Status *status ) { USIM_CHECK_CARD_VALID(card); if(status==NULL) { return USIM_RC_NULL_POINTER; } switch ( _USIMstates[card]) { case USIM_REMOVED : status->controlStatus = USIM_CARD_REMOVED; break; case USIM_INACTIVE : status->controlStatus = USIM_CARD_DEACTIVATED; break; default : status->controlStatus = USIM_CARD_ACTIVATED; } USIMcardClockStart(card); if(USIM_IS_RX_ACTIVE(card)) { status->activeReceiver = TRUE; } else { status->activeReceiver = FALSE; } if(USIM_IS_TX_ACTIVE(card)) { status->activeTransmitter = TRUE; } else { status->activeTransmitter = FALSE; } return USIM_RC_OK; }/* End of USIMStatusGet */ /***************************************************************************** * Function : USIMCommandSend ****************************************************************************** * * Description : Sends commands (C-APDU) from the USIM Manager to the card * * Parameters : card - the required USIM card * header - a command header structure, as defined above * data - a pointer to the data sent, or NULL if no data * * Output Param : None * * Return value : USIM_RC_OK * USIM_RC_INVALID_CARD * USIM_RC_CARD_REMOVED * USIM_RC_CARD_CLOSED * USIM_RC_CARD_BUSY * USIM_RC_NULL_POINTER * USIM_RC_INVALID_DATA_LENGTH * * Notes: This service is blocking! It returns after the card's * response has been received. *****************************************************************************/ USIM_ReturnCode USIMCommandSend (USIM_Card card, USIM_CommandHeader * header, UINT8 * data) { USIM_ReturnCode rc=USIM_RC_OK; DIAG_FILTER(USIMLOG, USIMCommandSend, LOG001, DIAG_INFORMATION) diagStructPrintf("USIMCommandSend: %S{USIM_CommandHeader} ", header, sizeof(USIM_CommandHeader)); if(( _USIM_hwRemoveProgress[card]) || (_USIMstates[card] == USIM_REMOVED)) { DIAG_FILTER(USIMLOG,USIMCommandSend,LOG003,DIAG_INFORMATION) diagPrintf("USIMCommandSend %u, _USIM_hwRemoveProgress=%lx, _USIMstates=%lx", card, _USIM_hwRemoveProgress[card], _USIMstates[card]); rc = USIM_RC_CARD_REMOVED; } else if (_USIMstates[card] != USIM_SPECIFIC) { /* if we are here race conditions happened */ /* send USIM_CARD_DEACTIVATED to cause SIG_L1SI_CARD_REMOVED_IND send to Sim Mgr*/ //CQ00006140 //USIMControlIndication(card, USIM_CARD_DEACTIVATED); if (USIM_DL_CheckFlagSetState( card, 0) ) { /*coverity[returned_value]*/ rc = USIM_DL_Check_States(card); } DIAG_FILTER(USIMLOG,USIMCommandSend,LOG004,DIAG_INFORMATION) diagPrintf("USIMCommandSend %u, rc=%d", card, rc); rc = USIM_RC_CARD_CLOSED; } else if (_USIMDLstates[card] != USIM_IDLE) { DIAG_FILTER(USIMLOG,USIMCommandSend,LOG005,DIAG_INFORMATION) diagPrintf("USIMCommandSend %u, _USIMDLstates=%lx", card, _USIMDLstates[card]); rc = USIM_RC_CARD_BUSY; } else if(header == NULL) { DIAG_FILTER(USIMLOG,USIMCommandSend,LOG006,DIAG_INFORMATION) diagPrintf("USIMCommandSend %u, header null", card); rc =USIM_RC_NULL_POINTER; } else if ((header->dataLength > 255) || (header->expectDataLength > 256)) { DIAG_FILTER(USIMLOG,USIMCommandSend,LOG007,DIAG_INFORMATION) diagPrintf("USIMCommandSend %u, dataLength=%lu, expectDataLength=%lu", card, header->dataLength, header->expectDataLength); rc = USIM_RC_INVALID_DATA_LENGTH; } if (rc != USIM_RC_OK) { DIAG_FILTER(USIMLOG,USIMCommandSend,LOG008,DIAG_INFORMATION) diagPrintf("USIMCommandSend %u, rc=%d", card, rc); TestUsimGetStatus(card); return (rc); } // set the data buffer size to 0: _USIMdataBufferSize[card] = 0; _USIMresponseHeaders[card].status1 = 0; _USIMresponseHeaders[card].status2 = 0; // copy header to header buffer: _USIMcommandHeaders[card] = *header; if (header->dataLength) { // copy data to data buffer: memcpy(_USIMdataBuffers[card], data, header->dataLength); } #ifdef USIM_USE_CLOCK_STOP_TIMER if(_USIMisClockStopUsed[card] == TRUE) { OSATimerStop(_USIMtimerRefs[card]); } #endif /* USIM_USE_CLOCK_STOP_TIMER */ /* we don't need WDT below, since USIM HW interface is not used for TimerDelay HERE USIM_WDT_TIMER_START(card, USIM_WDT_CLK_START_VAL); */ if (USIMcardClockStart(card)) { TestUsimGetStatus(card); //USIM_WDT_TIMER_STOP(card); DIAG_FILTER(USIMLOG,USIMCommandSend,LOG009,DIAG_INFORMATION) diagPrintf("USIMCommandSend %u, USIMcardClockStart fail", card); return USIM_RC_GPIO_ERROR; } //USIM_WDT_TIMER_STOP(card); // check which protocol is used, and send command: if(_USIMatrInfos[card].protocol == USIM_T0) { rc = USIMTransportT0CommandSend(card); } else { rc = USIMTransportT1CommandSend(card); } if(rc == USIM_RC_OK) { if(_USIMdataBufferSize[card]) { DIAG_FILTER(USIMLOG,USIMCommandSend,LOG010,DIAG_INFORMATION) diagPrintf("USIMCommandSend %u, _USIMdataBufferSize=%lu", card, _USIMdataBufferSize[card]); USIMResponseNotify(card, &(_USIMresponseHeaders[card]), _USIMdataBufferSize[card], _USIMdataBuffers[card]); } else { DIAG_FILTER(USIMLOG,USIMCommandSend,LOG011,DIAG_INFORMATION) diagPrintf("USIMCommandSend %u, _USIMdataBufferSize=%lu", card, _USIMdataBufferSize[card]); USIMResponseNotify(card, &(_USIMresponseHeaders[card]), 0, NULL); } } else { DIAG_FILTER(USIMLOG,USIMCommandSend,LOG012,DIAG_INFORMATION) diagPrintf("USIMCommandSend %u, rc=%d", card, rc); TestUsimGetStatus(card); /* CQ00065401 tc TC 7.2.1 c-3 */ // USIM is removed or not answer - this is abnormal //CQ00006140 //USIMClose (card); USIM_HW_deactivate(card, TRUE); return rc; } _USIMdataBufferSize[card] = 0; #ifdef USIM_USE_CLOCK_STOP_TIMER if(_USIMisClockStopUsed[card] == TRUE) { OSATimerStart(_USIMtimerRefs[card], USIM_CLK_STOP_INTERVAL, 0, USIMClockStop, (UINT32)card); } #endif /* USIM_USE_CLOCK_STOP_TIMER */ #if defined USIM_STOP_CLOCK_AFTER_EVERY_COMMAND USIM_WDT_TIMER_START(card, USIM_WDT_CLK_STOP_VAL); /* stop the clock: */ if (USIMcardClockStop(card)) rc = USIM_RC_GPIO_ERROR; USIM_WDT_TIMER_STOP(card); USIM_PmuClockSwitch(card,FALSE); /* Turn clock off */ if (rc != USIM_RC_OK) { TestUsimGetStatus(card); } #endif /* USIM_STOP_CLOCK_AFTER_EVERY_COMMAND */ return (rc); }/* End of USIMCommandSend */ /****************************************************************************** * Function: USIMClose ******************************************************************************* * Description: Deactivates a card (see the opposite USIMOpen) * * Parameters: card - the card to be closed. * * Return value: USIM_RC_OK * USIM_RC_INVALID_CARD * * Notes: Refer also USIMClose, USIMOsDeactivate ******************************************************************************/ UINT32 usim_close_ind_flag[2]={1,1}; void enable_usim_close_ind(USIM_Card card) { usim_close_ind_flag[card]=1; } void disable_usim_close_ind(USIM_Card card) { usim_close_ind_flag[card]=0; } USIM_ReturnCode USIMClose(USIM_Card card) { UINT32 cpsr; DIAG_FILTER(USIMLOG,USIMClose,LOG001,DIAG_INFORMATION) diagPrintf("USIMClose %u, _USIM_hwRemoveProgress=%lx, _USIMstates=%lx, _USIMDLstates=%lx", card, _USIM_hwRemoveProgress[card], _USIMstates[card], _USIMDLstates[card]); USIM_CHECK_CARD_VALID(card); INTCDisable(_USIMinterruptSources[card]); cpsr = disableInterrupts(); if((!_USIM_hwRemoveProgress[card]) &&(_USIMstates[card] != USIM_INACTIVE) && (_USIMDLstates[card] != USIM_REMOVED)) { _USIM_hwRemoveProgress[card] = TRUE; _USIMDLstates[card] = USIM_REMOVED; /* this will protect aginst several USIMClose */ if (_USIMstates[card] != USIM_REMOVED) _USIMstates[card] = USIM_INACTIVE; restoreInterrupts(cpsr); if(_USIMclockStopped[card] == TRUE) { USIM_PmuClockSwitch(card,TRUE); usim_hw_clk_onoff((USIM_Card)card, USIM_HW_CLOCK_START_REQ); } USIM_HW_deactivate(card, TRUE); USIM_PmuClockSwitch(card,FALSE); /* Turn clock off */ _USIMclockStopped[card] = TRUE; if(usim_close_ind_flag[card]==1) { DIAG_FILTER(USIMLOG, USIMClose, LOG002, DIAG_INFORMATION) diagPrintf("USIMClose %lu send USIM_CARD_DEACTIVATED ind",card); USIMControlIndication(card, USIM_CARD_DEACTIVATED); } else { DIAG_FILTER(USIMLOG, USIMClose, LOG003, DIAG_INFORMATION) diagPrintf("USIMClose %lu not send USIM_CARD_DEACTIVATED ind",card); } _USIM_hwRemoveProgress[card] = FALSE; } else { restoreInterrupts(cpsr); USIM_DL_CheckFlagSetState( card, 0); /* USIM_INACTIVE --> USIM_REMOVED */ } USIM_WDT_TIMER_STOP(card); usim_close_mfpr_set(card); return USIM_RC_OK; } /* End of USIMClose */ USIM_ReturnCode USIMClose_boot(USIM_Card card) { UINT32 cpsr; INTCDisable(_USIMinterruptSources[card]); cpsr = disableInterrupts(); if((!_USIM_hwRemoveProgress[card]) &&(_USIMstates[card] != USIM_INACTIVE) && (_USIMDLstates[card] != USIM_REMOVED)) { _USIM_hwRemoveProgress[card] = TRUE; _USIMDLstates[card] = USIM_REMOVED; /* this will protect aginst several USIMClose */ if (_USIMstates[card] != USIM_REMOVED) _USIMstates[card] = USIM_INACTIVE; restoreInterrupts(cpsr); if(_USIMclockStopped[card] == TRUE) { USIM_PmuClockSwitch(card,TRUE); usim_hw_clk_onoff((USIM_Card)card, USIM_HW_CLOCK_START_REQ); } USIM_HW_deactivate(card, TRUE); USIM_PmuClockSwitch(card,FALSE); /* Turn clock off */ _USIMclockStopped[card] = TRUE; _USIM_hwRemoveProgress[card] = FALSE; } else { restoreInterrupts(cpsr); USIM_DL_CheckFlagSetState( card, 0); /* USIM_INACTIVE --> USIM_REMOVED */ } USIM_WDT_TIMER_STOP(card); usim_close_mfpr_set(card); return USIM_RC_OK; } /* End of USIMClose */ /****************************************************************************** * Function: USIMOpen ******************************************************************************* * Description: Opens a card for usage. * * Parameters: card - the card to be opened * * Return value: USIM_RC_OK * USIM_RC_INVALID_CARD * USIM_RC_NOT_REGISTERED * USIM_RC_CARD_REMOVED * USIM_RC_CARD_ALREADY_OPEN * USIM_RC_ATR_ERROR * USIM_RC_PPS_ERROR * USIM_RC_OSA_ERROR * * Notes: ******************************************************************************/ USIM_ReturnCode USIMOpen(USIM_Card card) { UINT32 flags; USIM_ReturnCode rc=USIM_RC_OK; DIAG_FILTER(USIMLOG, USIMOpen, LOG001, DIAG_INFORMATION) diagPrintf("USIMOpen %lu", card); #ifdef USIM_OP_FOR_SGIT if(getMasterSimID()!=card) { USIMControlIndication(card, USIM_CARD_DEACTIVATED); rc=USIM_RC_ATR_ERROR; return rc; } #endif if((_USIMstates[card] != USIM_INACTIVE) && (_USIMstates[card] != USIM_REMOVED)) { DIAG_FILTER(USIMLOG, USIMOpen, LOG004, DIAG_INFORMATION) diagPrintf("USIMOpen %lu, _USIMstates=%lx", card, _USIMstates[card]); ASSERT(0); } _USIMstates[card] = USIM_INACTIVE; USIMSetResponseReadFlag(card, 1);/* default value: 1 SIM DRIVER supports get response */ INTCEnable(_USIMinterruptSources[card]); rc = USIMcardReset(card); DIAG_FILTER(USIMLOG, USIMOpen, LOG006, DIAG_INFORMATION) diagPrintf("USIMOpen %lu, USIMcardReset=%d", card, rc); if (rc == USIM_RC_OK) { #ifdef USIM_USE_CLOCK_STOP_TIMER if ( ((_USIMatrInfos[card]).stopState == USIM_CLK_STOP_NOT_SUPPORTED) || (OSATimerStart(_USIMtimerRefs[card], USIM_CLK_STOP_INTERVAL, 0, USIMClockStop, (UINT32)card) != OS_SUCCESS)) { _USIMisClockStopUsed[card] = FALSE; } else { _USIMisClockStopUsed[card] = TRUE; } #endif } else { DIAG_FILTER(USIMLOG, USIMOpen, LOG007, DIAG_INFORMATION) diagPrintf("USIMOpen %lu, fail, rc=%d", card, rc); USIMClose(card); } return rc; } /* End of USIMOpen */ USIM_ReturnCode USIMOpen_boot(USIM_Card card) { UINT32 flags; USIM_ReturnCode rc=USIM_RC_OK; USIMSetResponseReadFlag(card, 1);/* default value: 1 SIM DRIVER supports get response */ _USIMstates[card] = USIM_INACTIVE; INTCEnable(_USIMinterruptSources[card]); rc = USIMcardReset_boot(card); if (rc == USIM_RC_OK) { #ifdef USIM_USE_CLOCK_STOP_TIMER if ( ((_USIMatrInfos[card]).stopState == USIM_CLK_STOP_NOT_SUPPORTED) || (OSATimerStart(_USIMtimerRefs[card], USIM_CLK_STOP_INTERVAL, 0, USIMClockStop, (UINT32)card) != OS_SUCCESS)) { _USIMisClockStopUsed[card] = FALSE; } else { _USIMisClockStopUsed[card] = TRUE; } #endif } else { USIMClose_boot(card); } return rc; } /* End of USIMOpen */ USIM_ReturnCode USIMOpen_first(USIM_Card card) { UINT32 flags; USIM_ReturnCode rc=USIM_RC_OK; #ifdef USIM_OP_FOR_SGIT if(getMasterSimID()!=card) { USIMControlIndication(card, USIM_CARD_DEACTIVATED); rc=USIM_RC_ATR_ERROR; return rc; } #endif while(usim_boot_atr_info[card].flag==0) OSATaskSleep(1); if(usim_boot_atr_info[card].len==0) { rc=USIM_RC_ATR_ERROR; USIMControlIndication(card, USIM_CARD_DEACTIVATED); } else { rc=USIM_RC_OK; USIMControlIndication(card, (USIM_CLASS_TO_CTRL_IND(usim_boot_atr_info[card].voltage))); USIMResponseNotify(card, NULL, usim_boot_atr_info[card].len, _USIMatrBuffers[card]); } return rc; } /* End of USIMOpen */ /****************************************************************************** * Function: USIMUnRegister ******************************************************************************* * Description: Unbinds the return functions associated with the card. * * Parameters: card - the card from which the functions would be unbound. * * Return value: USIM_RC_OK * USIM_RC_INVALID_CARD * * Notes: ******************************************************************************/ USIM_ReturnCode USIMUnRegister (USIM_Card card) { _USIMstates[card] = USIM_INACTIVE; return USIM_RC_OK; } /* End of USIMUnRegister */ /****************************************************************************** * Function: USIMRegister ******************************************************************************* * Description: Binds the given functions: responseFunc would be called when * the card returns a response for a command; ctrlFunc is called * for indicaing that the card's state has changed. * * Parameters: card - the card to which the functions would be registered. * responseFunc - a pointer to a return function, which notifies * the USIM Manager of the card's response to a * command. * ctrlFunc - a pointer to a return function, which indicates card * state changes. * * Return value: USIM_RC_OK * USIM_RC_INVALID_CARD * USIM_RC_NULL_POINTER * USIM_RC_ALREADY_BOUND * * Notes: ******************************************************************************/ USIM_ReturnCode USIMRegister(USIM_Card card, USIM_CardResponseNotify responseFunc, USIM_ControlIndication ctrlFunc) { _USIMresponseNotifies[card] = responseFunc; _USIMcontrolIndications[card] = ctrlFunc; return USIM_RC_OK; } /* End of USIMRegister */ extern void usim_bind_callback (void); UINT32 usim_1_detect_gpio=0; UINT32 usim_1_detect_gpio_insert_level=1; UINT32 usim_1_debounce_time=100; UINT32 usim_2_detect_gpio=0; UINT32 usim_2_detect_gpio_insert_level=1; UINT32 usim_2_debounce_time=100; #if defined(QUEC_DUAL_SINGLE_PS_SUPPORT) static void quec_mini_simslotswitch_init(void) { *(volatile unsigned long *)(0xD401E0C8) = 0x3;//GPIO_55 *(volatile unsigned long *)(0xD401E1C4) = 0x2;//GPIO_73 *(volatile unsigned long *)(0xD401E1C8) = 0x2;//GPIO_74 } #endif void USIMResourceInit(void) { USIM_Card card; #ifndef MIN_SYS if(!IsMiniSystem()) { #if defined(QUEC_DUAL_SINGLE_PS_SUPPORT)//单卡协议栈SLOT切卡 extern void quec_simslotswitch_init(void); quec_simslotswitch_init(); #endif } else { #if defined(QUEC_DUAL_SINGLE_PS_SUPPORT) quec_mini_simslotswitch_init(); #endif } #endif OS_Create_HISR(&_USIMhisrRefs[0], "USIMsisrComCard", USIMsisrComCard, HISR_PRIORITY_0); ASSERT(OSAFlagCreate(&_USIMflagsRefs[USIM_COM_CARD]) == OS_SUCCESS); #ifdef USIM_USE_CLOCK_STOP_TIMER ASSERT(OSATimerCreate(&_USIMtimerRefs[USIM_COM_CARD]) != OS_SUCCESS); #endif #ifdef USIM_USE_SW_WDT_TIMER ASSERT(OSATimerCreate(&_USIMtimerRefsWdt[USIM_COM_CARD]) == OS_SUCCESS); #endif #ifdef USIM_DSDS_DKB OS_Create_HISR(&_USIMhisrRefs[1], "USIMsisrBankingCard", USIMsisrBankingCard, HISR_PRIORITY_0); ASSERT(OSAFlagCreate(&_USIMflagsRefs[USIM_BANKING_CARD]) == OS_SUCCESS); #ifdef USIM_USE_CLOCK_STOP_TIMER ASSERT(OSATimerCreate(&_USIMtimerRefs[USIM_BANKING_CARD]) != OS_SUCCESS); #endif #ifdef USIM_USE_SW_WDT_TIMER ASSERT(OSATimerCreate(&_USIMtimerRefsWdt[USIM_BANKING_CARD]) == OS_SUCCESS); #endif #endif usim_bind_callback(); } /****************************************************************************** * Function: USIMPhase2Init ******************************************************************************* * Description: Initializes database * * Parameters: * * Return value: USIM_RC_OK * USIM_RC_INTC_ERROR * * Notes: ******************************************************************************/ extern void USIMD2rmD2Register(void); extern void Set_R13_EEH(UINT32 ptr); void eeh_set_stack(void) { UINT8* ptr; extern UINT8 IpNetNodePool[]; ptr=(UINT8*)IpNetNodePool; memset(ptr,0xAA,4096); Set_R13_EEH(((UINT32)ptr)+4096); } void usim_disable_io_drive_up(void) { UINT32 addr; UINT32 reg; if (CHIP_IS_CRANEG || CHIP_IS_CRANEM || CHIP_IS_CRANEL || CHIP_IS_CRANELS || CHIP_IS_CRANELR || CHIP_IS_CRANELG || CHIP_IS_CRANELRH) { addr=USIM_0_HW_ADDRESS+0x48; reg=*(volatile UINT32*)addr; reg|=0x1; *(volatile UINT32*)addr=reg; addr=USIM_1_HW_ADDRESS+0x48; reg=*(volatile UINT32*)addr; reg|=0x1; *(volatile UINT32*)addr=reg; } } void usim_boot_init (USIM_Card card) { USIM_ReturnCode result; usim_state_init(card); result = USIMOpen_boot (card); } UINT8* usim_0_fast_boot_task_stack; UINT8* usim_1_fast_boot_task_stack; OSATaskRef usim_0_fast_boot_task_ref=NULL; OSATaskRef usim_1_fast_boot_task_ref=NULL; VOID usim_0_fast_boot_task(VOID *argv) { usim_boot_init(USIM_COM_CARD); } #ifdef USIM_DSDS_DKB VOID usim_1_fast_boot_task(VOID *argv) { usim_boot_init(USIM_BANKING_CARD); } #endif void usim_fast_boot_task_init(void) { OS_STATUS status; memset(usim_boot_atr_info, 0, sizeof(usim_boot_atr_info)); usim_0_fast_boot_task_stack=(UINT8*)malloc(2048); status = OSATaskCreate(&usim_0_fast_boot_task_ref, usim_0_fast_boot_task_stack, 2048, 39, "Usim0FaT", usim_0_fast_boot_task, NULL); ASSERT(status == OS_SUCCESS); #ifdef USIM_DSDS_DKB usim_1_fast_boot_task_stack=(UINT8*)malloc(2048); status = OSATaskCreate(&usim_1_fast_boot_task_ref, usim_1_fast_boot_task_stack, 2048, 39, "Usim1FaT", usim_1_fast_boot_task, NULL); ASSERT(status == OS_SUCCESS); #endif } void usim_fast_boot_task_del(void) { OS_STATUS status; #ifdef USIM_DSDS_DKB while((usim_boot_atr_info[0].flag==0)||(usim_boot_atr_info[1].flag==0)) #else while(usim_boot_atr_info[0].flag==0) #endif OSATaskSleep(1); status = OSATaskDelete(usim_0_fast_boot_task_ref); ASSERT(status == OS_SUCCESS); free(usim_0_fast_boot_task_stack); #ifdef USIM_DSDS_DKB status = OSATaskDelete(usim_1_fast_boot_task_ref); ASSERT(status == OS_SUCCESS); free(usim_1_fast_boot_task_stack); #endif } USIM_ReturnCode USIMPhase2Init(void) { USIM_Card card; static UINT8 usim_fast_boot_init_flag=0; static UINT8 usim_int_init_flag=0; extern UINT32 read_usim_swap_flag(void); extern UINT32 usim_pin_drive; extern UINT32 usim_internal_pull_up; if(CHIP_IS_CRANELG || CHIP_IS_CRANELRH) { /*DKB doesn't has external usim io pull up resistor, should set usim_internal_pull_up=1, usim_pin_drive=8, customer need check hardware SCH*/ #if 0 usim_internal_pull_up=0; usim_pin_drive=3; #else //20250506 don't konw the customer's SCH,and can't fit all the customers,keep same with the before usim_internal_pull_up=1; usim_pin_drive=8; #endif } else { usim_internal_pull_up=0; usim_pin_drive=3; } usim_swap_flag=read_usim_swap_flag(); RTI_LOG("USIMPhase2Init %d\r\n", usim_swap_flag); for (card = (USIM_Card)0; card < USIM_CARDS_AMOUNT; card++) { USIMATRInfoInit(card); _USIMrxBuffers[card] = _USIMrxBuf[card]; _USIMtxBuffers[card] = _USIMtxBuf[card]; _USIMdataBuffers[card]= _USIMdataBuf[card]; // set the rx buffer pointers to the beginning of the buffer: _USIMrxBufferPtrs[card] = _USIMrxBuffers[card]; // Reset the number of bytes expected from card: _USIMexpectedLen[card] = 0; // set the tx buffer pointers to the beginning of the buffer: _USIMtxBufferPtrs[card] = _USIMtxBuffers[card]; // reset the size of tx buffers: _USIMtxBufferSize[card] = 0; // reset the data buffer valid bytes number: _USIMdataBufferSize[card] = 0; // initialize clock stop indicators: _USIMclockStopped[card] = TRUE; // initialize DL states: _USIMDLstates[card] = USIM_IDLE; _USIMstates[card] = USIM_REMOVED; // initialize T=1 sequence numbers: _USIMcardSequence[card] = 0x01; _USIMdeviceSequence[card] = 0x01; _USIMisClockStopUsed[card] = FALSE; _USIMuseVoltageLevel[card] = USIM_DEFAULT_CLASS; _USIMisDelaySet[card] = FALSE; _USIMParityErrorCnt[card] = 0; _USIMWTCnt[card] = USIM_DEFAULT_WORK_WAIT_TIME; #if defined(USIM_PMC_LDO_ENABLED_ON_BOOT) _SIMFirstTimePowered[card] = TRUE; #endif _USIM_hwRemoveProgress[card] = FALSE; // _USIMtimerRefs[card] = NULL; #if defined (USIM_USE_SW_WDT_TIMER) // _USIMtimerRefsWdt[card] = NULL; _USIMtimerWDTactive[card] = FALSE; _USIMtimerWDTval[card] = 0xFFFFFFF; #endif //_USIMhisrRefs[currCard] = NULL; _USIMinterruptStatus[card] = 0; _USIMcurrentVoltageClass[card] = USIM_CLASS_NULL; } if(usim_int_init_flag==1) { INTCDisable(_USIMinterruptSources[USIM_COM_CARD]); ASSERT(INTCUnbind (_USIMinterruptSources[USIM_COM_CARD]) == INTC_RC_OK); #ifdef USIM_DSDS_DKB INTCDisable(_USIMinterruptSources[USIM_BANKING_CARD]); ASSERT(INTCUnbind (_USIMinterruptSources[USIM_BANKING_CARD]) == INTC_RC_OK); #endif } usim_int_init_flag=1; if(usim_swap_flag == 0) { USIMHWRegisters[0] = (volatile struct USIMController *)USIM_0_HW_ADDRESS; _USIMinterruptSources[0] = INTC_SRC_USIM1; USIMHWRegisters[1] = (volatile struct USIMController *)USIM_1_HW_ADDRESS; _USIMinterruptSources[1] = INTC_SRC_USIM2; } else { USIMHWRegisters[0] = (volatile struct USIMController *)USIM_1_HW_ADDRESS; _USIMinterruptSources[0] = INTC_SRC_USIM2; USIMHWRegisters[1] = (volatile struct USIMController *)USIM_0_HW_ADDRESS; _USIMinterruptSources[1] = INTC_SRC_USIM1; } USIMregistersInit((USIM_Card)0); ASSERT(INTCConfigure(_USIMinterruptSources[0], INTC_IRQ, INTC_HIGH_LEVEL) == INTC_RC_OK); ASSERT(INTCBind(_USIMinterruptSources[0], USIMhandler_1) == INTC_RC_OK); USIMregistersInit((USIM_Card)1); #ifdef USIM_DSDS_DKB ASSERT(INTCConfigure(_USIMinterruptSources[1], INTC_IRQ, INTC_HIGH_LEVEL) == INTC_RC_OK); ASSERT(INTCBind(_USIMinterruptSources[1], USIMhandler_2) == INTC_RC_OK) ; #endif USIMD2rmD2Register() ; if(usim_internal_pull_up==0) usim_disable_io_drive_up(); if(usim_fast_boot_init_flag==0) { usim_fast_boot_task_init(); usim_fast_boot_init_flag=1; } return USIM_RC_OK; } /* End of USIMPhase2Init */ void set_usim_swap_flag(UINT32 val) { extern void save_usim_swap_flag(UINT32 val); save_usim_swap_flag(val); USIMPhase2Init(); } UINT32 get_usim_swap_flag(void) { uart_printf("get_usim_swap_flag %d\r\n", usim_swap_flag); return usim_swap_flag; } void disable_usim_swap(void) { RTI_LOG("disable_usim_swap\r\n"); set_usim_swap_flag(0); } void enable_usim_swap(void) { RTI_LOG("enable_usim_swap\r\n"); set_usim_swap_flag(1); } extern BOOL GLFeatureFlag; char _USIMDLstates_string[][32]= { "USIM_REMOVED", "USIM_INACTIVE", "USIM_ATR" "USIM_NEGOTIABLE", "USIM_SPECIFIC", "USIM_IDLE", "USIM_SEND", "USIM_WAIT_FOR_RESPONSE", "USIM_RECEIVE", "USIM_PROCESS", "USIM_WDT_TIMER_EXPIRED" }; char *get__USIMDLstates_string(unsigned int val) { if(val==USIM_REMOVED) return _USIMDLstates_string[0]; else if(val==USIM_INACTIVE) return _USIMDLstates_string[1]; else if(val==USIM_ATR) return _USIMDLstates_string[2]; else if(val==USIM_NEGOTIABLE) return _USIMDLstates_string[3]; else if(val==USIM_SPECIFIC) return _USIMDLstates_string[4]; else if(val==USIM_IDLE) return _USIMDLstates_string[5]; else if(val==USIM_SEND) return _USIMDLstates_string[6]; else if(val==USIM_WAIT_FOR_RESPONSE) return _USIMDLstates_string[7]; else if(val==USIM_RECEIVE) return _USIMDLstates_string[8]; else if(val==USIM_PROCESS) return _USIMDLstates_string[9]; else if(val==USIM_WDT_TIMER_EXPIRED) return _USIMDLstates_string[10]; return NULL; } #ifndef UPGRADE_LTE_ONLY void set_glfeatureflag(BOOL val) { unsigned int flag; if((_USIMDLstates[0] != USIM_REMOVED)||(_USIMDLstates[1] != USIM_REMOVED)||(_USIMstates[0] != USIM_INACTIVE)||(_USIMstates[1] != USIM_INACTIVE)) { ASSERT(0); } INTCDisable(_USIMinterruptSources[0]); INTCDisable(_USIMinterruptSources[1]); ASSERT(INTCUnbind (_USIMinterruptSources[0]) == INTC_RC_OK); ASSERT(INTCUnbind (_USIMinterruptSources[1]) == INTC_RC_OK); #ifdef USIM_USE_CLOCK_STOP_TIMER OSATimerStop(_USIMtimerRefs[0]); OSATimerStop(_USIMtimerRefs[1]); #endif #ifdef USIM_USE_SW_WDT_TIMER OSATimerStop(_USIMtimerRefsWdt[0]); OSATimerStop(_USIMtimerRefsWdt[1]); #endif flag=(unsigned int)val; SimSendGLSwapFlag(flag); } void change_glfeatureflag(unsigned int val) { GLFeatureFlag=val; USIMPhase2Init(); } BOOL get_glfeatureflag(void) { return GLFeatureFlag; } #else #if defined(LTEONLY_8M8M) || defined(DM_LTEONLY_16MPSRAM) || defined(LTEONLY_THIN) void change_glfeatureflag(unsigned int val) { GLFeatureFlag=val; USIMPhase2Init(); } #endif #endif /****************************************************************************** * Function: USIMPhase1Init ******************************************************************************* * Description: Initializes database * * Parameters: * * Return value: USIM_RC_OK * * Notes: ******************************************************************************/ USIM_ReturnCode USIMPhase1Init(void) { /* Init trace pointer: */ return USIM_RC_OK; } /* End of USIMPhase1Init */ /****************************************************************************** * Function: USIMVersionGet() ******************************************************************************* * Description: Get the current version of the Package * * Parameters: * * Return value: * * Notes: ******************************************************************************/ SwVersion USIMVersionGet(void) { SwVersion usimVersion = "USIM Driver, version 2.50"; #if defined (USIM_USE_TRACE) USIM_TRACING_ON_DEMAND { DIAG_FILTER(HAL, USIM, USIMVersionGet, DIAG_INFORMATION) diagPrintf("%s", usimVersion); } #endif /* USIM_USE_TRACE */ return usimVersion; }/* End of USIMVersionGet */ /***************************************************************************** * Function : USIMATRGet ****************************************************************************** * * Description : Retrieves the latest Answer To Reset information. * * Parameters : card - the required USIM card * * Output Param : info - pointer to the retrieved ATR information structure * * * Return value : USIM_RC_OK * USIM_RC_INVALID_CARD * USIM_RC_NULL_POINTER * USIM_RC_CARD_CLOSED * USIM_RC_CARD_REMOVED * * Notes: Compile-optimization makes problem with this proceddure in JTAG-debug-view * So polace this procedure last... *****************************************************************************/ USIM_ReturnCode USIMATRGet (USIM_Card card, USIM_ATRInfo * info) { USIM_CHECK_CARD_VALID(card); if(info==NULL) { return USIM_RC_NULL_POINTER; } if((_USIM_hwRemoveProgress[card]) || (_USIMstates[card] == USIM_REMOVED)) { USIMClose(card); return USIM_RC_CARD_REMOVED; } if (_USIMstates[card] == USIM_INACTIVE) { return USIM_RC_CARD_CLOSED; } // copy the atr information struct: info->cardClock = _USIMatrInfos[card].cardClock; info->indCardClock = _USIMatrInfos[card].indCardClock; info->conversionFactor = _USIMatrInfos[card].conversionFactor; info->indConversionFactor = _USIMatrInfos[card].indConversionFactor; info->adjustmentFactor = _USIMatrInfos[card].adjustmentFactor; info->indAdjustmentFactor = _USIMatrInfos[card].indAdjustmentFactor; info->extraGuardTime = _USIMatrInfos[card].extraGuardTime; info->modeChangeable = _USIMatrInfos[card].modeChangeable; info->protocol = _USIMatrInfos[card].protocol; info->stopState = _USIMatrInfos[card].stopState; info->cardClasses = _USIMatrInfos[card].cardClasses; info->convention = _USIMatrInfos[card].convention; info->length = _USIMatrInfos[card].length; info->workWaitingTime = _USIMatrInfos[card].workWaitingTime; info->charWaitingTime = _USIMatrInfos[card].charWaitingTime; info->blockWaitingTime = _USIMatrInfos[card].blockWaitingTime; info->infoFieldSize = _USIMatrInfos[card].infoFieldSize; info->errorCode = _USIMatrInfos[card].errorCode; info->historicBytesNumber = _USIMatrInfos[card].historicBytesNumber; memcpy(info->historicBytes, _USIMatrInfos[card].historicBytes, (UINT32)(info->historicBytesNumber)); return USIM_RC_OK; } /*-------------------------------------USIM Hotplug-------------------------------------*/ #ifndef SINGLE_SIM UINT32 USIMHotPlugFlag[USIM_CARDS_AMOUNT]; OS_HISR usim_1_detect_hisr_ref; OSATimerRef usim_1_detect_timer_ref = NULL; OSFlagRef usim_1_detect_flag_ref=NULL; OSATaskRef usim_1_detect_task_ref=NULL; char usim_1_detect_task_stack[1024]={0}; OS_HISR usim_2_detect_hisr_ref; OSATimerRef usim_2_detect_timer_ref = NULL; OSFlagRef usim_2_detect_flag_ref=NULL; OSATaskRef usim_2_detect_task_ref=NULL; char usim_2_detect_task_stack[1024]={0}; UINT32 get_usim_1_insert_status(void) { UINT32 value; value=GpioGetLevel(usim_1_detect_gpio); if(value==usim_1_detect_gpio_insert_level) return 1; else return 0; } UINT32 get_usim_2_insert_status(void) { UINT32 value; value=GpioGetLevel(usim_2_detect_gpio); if(value==usim_2_detect_gpio_insert_level) return 1; else return 0; } void usim_1_det_lisr (void) { STATUS status; GpioDisableEdgeDetectionBit(usim_1_detect_gpio, GPIO_TWO_EDGE); status = OS_Activate_HISR(&usim_1_detect_hisr_ref); ASSERT(status == OS_SUCCESS); } void usim_2_det_lisr (void) { STATUS status; GpioDisableEdgeDetectionBit(usim_2_detect_gpio, GPIO_TWO_EDGE); status = OS_Activate_HISR(&usim_2_detect_hisr_ref); ASSERT(status == OS_SUCCESS); } #define USIM_HOT_PLUG_BIT 0x100 void usim_1_hotplug_trigger(void) { OSAFlagSet(usim_1_detect_flag_ref, USIM_HOT_PLUG_BIT, OSA_FLAG_OR); } void usim_2_hotplug_trigger(void) { OSAFlagSet(usim_2_detect_flag_ref, USIM_HOT_PLUG_BIT, OSA_FLAG_OR); } extern void ATRecv(int AtpIndex, void* data, UINT32 length); void usim_1_det_task_entry(void *ptr) { GPIO_ReturnCode ret; UINT32 value; OSA_STATUS status = OS_SUCCESS; UINT32 flag_value = 0; UINT32 flag_mask=USIM_HOT_PLUG_BIT; UINT32 insert_status; UINT32 wait_cnt=0; char *cfun0 = "AT+CFUN=0\r\n"; char *cfun5 = "AT+CFUN=5\r\n"; char *cfun1 = "AT+CFUN=1\r\n"; extern UINT32 flush_cfun4_at_ch; extern UINT32 flush_cfun4_at_ch_sim2; extern UINT32 flush_cfun4_rsp_flag; extern UINT32 flush_cfun4_rsp_flag_sim2; while(1) { status = OSAFlagWait( usim_1_detect_flag_ref, flag_mask, OSA_FLAG_OR_CLEAR, &flag_value, OSA_SUSPEND); if(flag_value & USIM_HOT_PLUG_BIT) { insert_status=get_usim_1_insert_status(); DIAG_FILTER(USIMLOG, usim_1_det_task_entry, LOG001, DIAG_INFORMATION) diagPrintf("SIM_1_DET_TASK insert_status = %d", insert_status); //ִ��QuecOpenע��Ļص� #ifndef MIN_SYS if(!IsMiniSystem()){ extern void ql_sim1_detect_ind_cust_callback(unsigned int insert_status); extern unsigned char ql_sim1_detect_is_enable(void); if(ql_sim1_detect_is_enable()){ ql_sim1_detect_ind_cust_callback(insert_status); }else{ CPUartLogPrintf("%s,%d, sim hot plug config disabled!", __func__, __LINE__); continue; } } #endif if(insert_status==0) { usim_send_quit_event(0); flush_cfun4_rsp_flag=0; wait_cnt=0; ATRecv(flush_cfun4_at_ch, cfun5, strlen(cfun5)); USIMHotPlugFlag[0] = TRUE; #if 0 while(flush_cfun4_rsp_flag==0) { OSATaskSleep(50); wait_cnt++; DIAG_FILTER(USIMLOG, usim_1_det_task_entry, LOG002, DIAG_INFORMATION) diagPrintf("SIM_1_DET_TASK wait cfun5 %lu", wait_cnt); } #endif OSATaskSleep(200*1); DIAG_FILTER(USIMLOG, usim_1_det_task_entry, LOG003, DIAG_INFORMATION) diagPrintf("SIM_1_DET_TASK end cfun5"); } else { usim_send_quit_event(0); flush_cfun4_rsp_flag=0; wait_cnt=0; ATRecv(flush_cfun4_at_ch, cfun0, strlen(cfun0)); #if 0 while(flush_cfun4_rsp_flag==0) { OSATaskSleep(50); wait_cnt++; DIAG_FILTER(USIMLOG, usim_1_det_task_entry, LOG004, DIAG_INFORMATION) diagPrintf("SIM_1_DET_TASK wait cfun0 %lu", wait_cnt); } #endif OSATaskSleep(200*1); DIAG_FILTER(USIMLOG, usim_1_det_task_entry, LOG005, DIAG_INFORMATION) diagPrintf("SIM_1_DET_TASK end cfun0"); flag_value=0; status = OSAFlagWait( usim_1_detect_flag_ref, flag_mask, OSA_FLAG_OR_CLEAR, &flag_value, OSA_NO_SUSPEND); if(flag_value & USIM_HOT_PLUG_BIT) { insert_status=get_usim_1_insert_status(); DIAG_FILTER(USIMLOG, usim_1_det_task_entry, LOG006, DIAG_INFORMATION) diagPrintf("SIM_1_DET_TASK again insert_status = %d", insert_status); if(insert_status==0) { usim_send_quit_event(0); flush_cfun4_rsp_flag=0; wait_cnt=0; ATRecv(flush_cfun4_at_ch, cfun5, strlen(cfun5)); USIMHotPlugFlag[0] = TRUE; #if 0 while(flush_cfun4_rsp_flag==0) { OSATaskSleep(50); wait_cnt++; DIAG_FILTER(USIMLOG, usim_1_det_task_entry, LOG007, DIAG_INFORMATION) diagPrintf("SIM_1_DET_TASK wait cfun5 %lu", wait_cnt); } #endif OSATaskSleep(200*1); DIAG_FILTER(USIMLOG, usim_1_det_task_entry, LOG008, DIAG_INFORMATION) diagPrintf("SIM_1_DET_TASK end cfun5"); } else { flush_cfun4_rsp_flag=0; wait_cnt=0; ATRecv(flush_cfun4_at_ch, cfun1, strlen(cfun1)); USIMHotPlugFlag[0] = FALSE; #if 0 while(flush_cfun4_rsp_flag==0) { OSATaskSleep(50); wait_cnt++; DIAG_FILTER(USIMLOG, usim_1_det_task_entry, LOG009, DIAG_INFORMATION) diagPrintf("SIM_1_DET_TASK wait cfun1 %lu", wait_cnt); } #endif OSATaskSleep(200*2); DIAG_FILTER(USIMLOG, usim_1_det_task_entry, LOG010, DIAG_INFORMATION) diagPrintf("SIM_1_DET_TASK end cfun1"); } } else { flush_cfun4_rsp_flag=0; wait_cnt=0; ATRecv(flush_cfun4_at_ch, cfun1, strlen(cfun1)); USIMHotPlugFlag[0] = FALSE; #if 0 while(flush_cfun4_rsp_flag==0) { OSATaskSleep(50); wait_cnt++; DIAG_FILTER(USIMLOG, usim_1_det_task_entry, LOG011, DIAG_INFORMATION) diagPrintf("SIM_1_DET_TASK wait cfun1 %lu", wait_cnt); } #endif OSATaskSleep(200*2); DIAG_FILTER(USIMLOG, usim_1_det_task_entry, LOG012, DIAG_INFORMATION) diagPrintf("SIM_1_DET_TASK end cfun1"); } } } } } void usim_2_det_task_entry(void *ptr) { GPIO_ReturnCode ret; UINT32 value; OSA_STATUS status = OS_SUCCESS; UINT32 flag_value = 0; UINT32 flag_mask=USIM_HOT_PLUG_BIT; UINT32 insert_status; UINT32 wait_cnt=0; char *cfun0 = "AT+CFUN=0\r\n"; char *cfun5 = "AT+CFUN=5\r\n"; char *cfun1 = "AT+CFUN=1\r\n"; extern UINT32 flush_cfun4_at_ch; extern UINT32 flush_cfun4_at_ch_sim2; extern UINT32 flush_cfun4_rsp_flag; extern UINT32 flush_cfun4_rsp_flag_sim2; while(1) { status = OSAFlagWait( usim_2_detect_flag_ref, flag_mask, OSA_FLAG_OR_CLEAR, &flag_value, OSA_SUSPEND); if(flag_value & USIM_HOT_PLUG_BIT) { insert_status=get_usim_2_insert_status(); DIAG_FILTER(USIMLOG, usim_2_det_task_entry, LOG001, DIAG_INFORMATION) diagPrintf("SIM_2_DET_TASK insert_status = %d", insert_status); if(insert_status==0) { usim_send_quit_event(1); flush_cfun4_rsp_flag_sim2=0; wait_cnt=0; ATRecv(flush_cfun4_at_ch_sim2, cfun5, strlen(cfun5)); USIMHotPlugFlag[1] = TRUE; #if 0 while(flush_cfun4_rsp_flag_sim2==0) { OSATaskSleep(50); wait_cnt++; DIAG_FILTER(USIMLOG, usim_2_det_task_entry, LOG002, DIAG_INFORMATION) diagPrintf("SIM_2_DET_TASK wait cfun5 %lu", wait_cnt); } #endif OSATaskSleep(200*1); DIAG_FILTER(USIMLOG, usim_2_det_task_entry, LOG003, DIAG_INFORMATION) diagPrintf("SIM_2_DET_TASK end cfun5"); } else { usim_send_quit_event(0); flush_cfun4_rsp_flag_sim2=0; wait_cnt=0; ATRecv(flush_cfun4_at_ch_sim2, cfun0, strlen(cfun0)); #if 0 while(flush_cfun4_rsp_flag_sim2==0) { OSATaskSleep(50); wait_cnt++; DIAG_FILTER(USIMLOG, usim_2_det_task_entry, LOG004, DIAG_INFORMATION) diagPrintf("SIM_2_DET_TASK wait cfun0 %lu", wait_cnt); } #endif OSATaskSleep(200*1); DIAG_FILTER(USIMLOG, usim_2_det_task_entry, LOG005, DIAG_INFORMATION) diagPrintf("SIM_2_DET_TASK end cfun0"); flag_value=0; status = OSAFlagWait( usim_2_detect_flag_ref, flag_mask, OSA_FLAG_OR_CLEAR, &flag_value, OSA_NO_SUSPEND); if(flag_value & USIM_HOT_PLUG_BIT) { insert_status=get_usim_2_insert_status(); DIAG_FILTER(USIMLOG, usim_2_det_task_entry, LOG006, DIAG_INFORMATION) diagPrintf("SIM_2_DET_TASK again insert_status = %d", insert_status); if(insert_status==0) { usim_send_quit_event(1); flush_cfun4_rsp_flag_sim2=0; wait_cnt=0; ATRecv(flush_cfun4_at_ch_sim2, cfun5, strlen(cfun5)); USIMHotPlugFlag[1] = TRUE; #if 0 while(flush_cfun4_rsp_flag_sim2==0) { OSATaskSleep(50); wait_cnt++; DIAG_FILTER(USIMLOG, usim_2_det_task_entry, LOG007, DIAG_INFORMATION) diagPrintf("SIM_2_DET_TASK wait cfun5 %lu", wait_cnt); } #endif OSATaskSleep(200*1); DIAG_FILTER(USIMLOG, usim_2_det_task_entry, LOG008, DIAG_INFORMATION) diagPrintf("SIM_2_DET_TASK end cfun5"); } else { flush_cfun4_rsp_flag_sim2=0; wait_cnt=0; ATRecv(flush_cfun4_at_ch_sim2, cfun1, strlen(cfun1)); USIMHotPlugFlag[1] = FALSE; #if 0 while(flush_cfun4_rsp_flag_sim2==0) { OSATaskSleep(50); wait_cnt++; DIAG_FILTER(USIMLOG, usim_2_det_task_entry, LOG009, DIAG_INFORMATION) diagPrintf("SIM_2_DET_TASK wait cfun1 %lu", wait_cnt); } #endif OSATaskSleep(200*2); DIAG_FILTER(USIMLOG, usim_2_det_task_entry, LOG010, DIAG_INFORMATION) diagPrintf("SIM_2_DET_TASK end cfun1"); } } else { flush_cfun4_rsp_flag_sim2=0; wait_cnt=0; ATRecv(flush_cfun4_at_ch_sim2, cfun1, strlen(cfun1)); USIMHotPlugFlag[1] = FALSE; #if 0 while(flush_cfun4_rsp_flag_sim2==0) { OSATaskSleep(50); wait_cnt++; DIAG_FILTER(USIMLOG, usim_2_det_task_entry, LOG011, DIAG_INFORMATION) diagPrintf("SIM_2_DET_TASK wait cfun1 %lu", wait_cnt); } #endif OSATaskSleep(200*2); DIAG_FILTER(USIMLOG, usim_2_det_task_entry, LOG012, DIAG_INFORMATION) diagPrintf("SIM_2_DET_TASK end cfun1"); } } } } } void usim_1_det_timer_handler(UINT32 arg) { OS_STATUS os_status; UINT32 insert_status; insert_status=get_usim_1_insert_status(); DIAG_FILTER(USIMLOG,usim_1_det_timer_handler,LOG001,DIAG_INFORMATION) diagPrintf("SIM_1_DET_TIMER = %u", insert_status); GpioEnableEdgeDetectionBit(usim_1_detect_gpio, GPIO_TWO_EDGE); usim_1_hotplug_trigger(); } void usim_2_det_timer_handler(UINT32 arg) { OS_STATUS os_status; UINT32 insert_status; insert_status=get_usim_2_insert_status(); DIAG_FILTER(USIMLOG,usim_2_det_timer_handler,LOG001,DIAG_INFORMATION) diagPrintf("SIM_2_DET_TIMER = %u", insert_status); GpioEnableEdgeDetectionBit(usim_2_detect_gpio, GPIO_TWO_EDGE); usim_2_hotplug_trigger(); } static void usim_1_det_hisr(void) { UINT32 timeout; OS_STATUS status; OSATimerStop(usim_1_detect_timer_ref); timeout=usim_1_debounce_time/5; if(timeout==0) timeout=1; DIAG_FILTER(USIMLOG,usim_1_det_hisr,LOG001,DIAG_INFORMATION) diagPrintf("SIM_1_DET_HISR %lu 0x%lx, insert_status=%u", timeout, get_current_TStimer_tick(), get_usim_1_insert_status()); status = OSATimerStart(usim_1_detect_timer_ref, timeout, 0, usim_1_det_timer_handler, 0); } static void usim_2_det_hisr(void) { UINT32 timeout; OS_STATUS status; OSATimerStop(usim_2_detect_timer_ref); timeout=usim_2_debounce_time/5; if(timeout==0) timeout=1; DIAG_FILTER(USIMLOG,usim_2_det_hisr,LOG001,DIAG_INFORMATION) diagPrintf("SIM_2_DET_HISR %lu 0x%lx, insert_status=%u", timeout, get_current_TStimer_tick(), get_usim_2_insert_status()); status = OSATimerStart(usim_2_detect_timer_ref, timeout, 0, usim_2_det_timer_handler, 0); } void usim_1_detect_init(void) { static UINT32 usim_1_detect_init_flag=0; GPIOConfiguration config; memset(&config, 0, sizeof(GPIOConfiguration)); if(usim_1_detect_init_flag==1) return; else usim_1_detect_init_flag=1; OSATimerCreate(&usim_1_detect_timer_ref); OSAFlagCreate( &usim_1_detect_flag_ref); Os_Create_HISR(&usim_1_detect_hisr_ref, "SIM1DETH", usim_1_det_hisr, 2); OSATaskCreate(&usim_1_detect_task_ref, usim_1_detect_task_stack, 1024, 60, "SIM1DETT", usim_1_det_task_entry, NULL); if(usim_1_detect_gpio != 0) { if(usim_1_detect_gpio_insert_level) { #if defined (__QUECTEL_PROJECT_EC600KCN_CC__) || defined (__QUECTEL_PROJECT_EC600KCN_LC__) \ ||defined (__QUECTEL_PROJECT_EC600KCN_CK__) || defined (__QUECTEL_PROJECT_EC600KCN_LK__) *(volatile unsigned long *)(GPIO_MFPR_ADDR(usim_1_detect_gpio))=(QUEC_AF1_C|QUEC_PULL_UP_C|QUEC_DRV_SLOW_C|QUEC_RESERVED_C); #else *(volatile unsigned long *)(GPIO_MFPR_ADDR(usim_1_detect_gpio))=(QUEC_AF0_C|QUEC_PULL_UP_C|QUEC_DRV_SLOW_C|QUEC_RESERVED_C); #endif config.pinPull = GPIO_PULLDN_ENABLE; config.initLv = GPIO_INITIAL_VALUE_LOW; } else { #if defined (__QUECTEL_PROJECT_EC600KCN_CC__) || defined (__QUECTEL_PROJECT_EC600KCN_LC__)\ ||defined (__QUECTEL_PROJECT_EC600KCN_CK__) || defined (__QUECTEL_PROJECT_EC600KCN_LK__) *(volatile unsigned long *)(GPIO_MFPR_ADDR(usim_1_detect_gpio))=(QUEC_AF1_C|QUEC_DRV_SLOW_C|QUEC_RESERVED_C); #else *(volatile unsigned long *)(GPIO_MFPR_ADDR(usim_1_detect_gpio))=(QUEC_AF0_C|QUEC_DRV_SLOW_C|QUEC_RESERVED_C); #endif config.pinPull = GPIO_PULLUP_ENABLE; config.initLv = GPIO_INITIAL_VALUE_HIGH; } config.pinDir = GPIO_IN_PIN; config.pinEd = GPIO_TWO_EDGE; config.isr = usim_1_det_lisr; GpioInitConfiguration(usim_1_detect_gpio,config); } } void usim_2_detect_init(void) { static UINT32 usim_2_detect_init_flag=0; GPIOConfiguration config; memset(&config, 0, sizeof(GPIOConfiguration)); if(usim_2_detect_init_flag==1) return; else usim_2_detect_init_flag=1; OSATimerCreate(&usim_2_detect_timer_ref); OSAFlagCreate( &usim_2_detect_flag_ref); Os_Create_HISR(&usim_2_detect_hisr_ref, "SIM2DETH", usim_2_det_hisr, 2); OSATaskCreate(&usim_2_detect_task_ref, usim_2_detect_task_stack, 1024, 60,"SIM2DETT", usim_2_det_task_entry, NULL); if(usim_2_detect_gpio != 0) { *(volatile unsigned long *)(GPIO_MFPR_ADDR(usim_2_detect_gpio))=0x1080; config.pinDir = GPIO_IN_PIN; config.pinEd = GPIO_TWO_EDGE; config.pinPull = GPIO_PULLUP_ENABLE; config.isr = usim_2_det_lisr; GpioInitConfiguration(usim_2_detect_gpio,config); } } void usim_init_hook(USIM_Card card) { if(card==USIM_COM_CARD) usim_1_detect_init(); #ifdef USIM_DSDS_DKB if(card==USIM_BANKING_CARD) usim_2_detect_init(); #endif } //ICAT EXPORTED FUNCTION - USIM,HotplugTest,HotplugTestGPIOInit void HotplugTestGPIOInit(void) { #if 1 *(volatile unsigned int*)0xD401E160=0xD0C0; GpioSetDirection(33,GPIO_OUT_PIN); GpioSetLevel(33, 0); #endif #if 0 *(volatile unsigned int*)0xD401E168=0xD0C0; GpioSetDirection(35,GPIO_OUT_PIN); GpioSetLevel(35, 0); #endif } //ICAT EXPORTED FUNCTION - USIM,HotplugTest,GPIO33High void GPIO33High(void) { GpioSetLevel(33, 1); } //ICAT EXPORTED FUNCTION - USIM,HotplugTest,GPIO33Low void GPIO33Low(void) { GpioSetLevel(33, 0); } //ICAT EXPORTED FUNCTION - USIM,HotplugTest,GPIO35High void GPIO35High(void) { GpioSetLevel(35, 1); } //ICAT EXPORTED FUNCTION - USIM,HotplugTest,GPIO35Low void GPIO35Low(void) { GpioSetLevel(35, 0); } UINT32 usim_get_hotplug_flag(UINT32 card) { DIAG_FILTER(USIMLOG, usim_get_hotplug_flag, LOG001, DIAG_INFORMATION) diagPrintf("hotplugflag %lu, SIM card status:%lu", card, USIMHotPlugFlag[card]); return USIMHotPlugFlag[card]; } /*-------------------------------------USIM Hotplug End-------------------------------------*/ #else //!SUPPORT_USIM_HW_HOT_PLUG #if QUEC_SIM_HOT_PLUG_PIN UINT32 USIMHotPlugFlag[USIM_CARDS_AMOUNT]; #define USIM_HOT_PLUG_BIT 0x100 OS_HISR usim_1_detect_hisr_ref; OSATimerRef usim_1_detect_timer_ref = NULL; OSFlagRef usim_1_detect_flag_ref=NULL; OSATaskRef usim_1_detect_task_ref=NULL; char usim_1_detect_task_stack[2048]={0}; UINT32 get_usim_1_insert_status(void) { UINT32 value; value=GpioGetLevel(usim_1_detect_gpio); if(value==usim_1_detect_gpio_insert_level){ return 1; } else { return 0; } } void usim_1_det_lisr (void) { STATUS status; GpioDisableEdgeDetectionBit(usim_1_detect_gpio, GPIO_TWO_EDGE); status = OS_Activate_HISR(&usim_1_detect_hisr_ref); ASSERT(status == OS_SUCCESS); } void usim_1_hotplug_trigger(void) { OSAFlagSet(usim_1_detect_flag_ref, USIM_HOT_PLUG_BIT, OSA_FLAG_OR); } void usim_1_det_task_entry(void *ptr) { GPIO_ReturnCode ret; UINT32 value; OSA_STATUS status = OS_SUCCESS; UINT32 flag_value = 0; UINT32 flag_mask=USIM_HOT_PLUG_BIT; UINT32 insert_status; UINT32 wait_cnt=0; char *cfun0 = "AT+CFUN=0\r\n"; char *cfun5 = "AT+CFUN=5\r\n"; char *cfun1 = "AT+CFUN=1\r\n"; extern UINT32 flush_cfun4_at_ch; extern UINT32 flush_cfun4_rsp_flag; while(1) { status = OSAFlagWait( usim_1_detect_flag_ref, flag_mask, OSA_FLAG_OR_CLEAR, &flag_value, OSA_SUSPEND); if(flag_value & USIM_HOT_PLUG_BIT) { insert_status=get_usim_1_insert_status(); uart_printf("SIM_1_DET_TASK %d\r\n", insert_status); DIAG_FILTER(USIMLOG, usim_1_det_task_entry, LOG001, DIAG_INFORMATION) diagPrintf("SIM_1_DET_TASK = %d", insert_status); //ִ��QuecOpenע��Ļص� #ifndef MIN_SYS if(!IsMiniSystem()){ extern void ql_sim1_detect_ind_cust_callback(unsigned int insert_status); extern unsigned char ql_sim1_detect_is_enable(void); if(ql_sim1_detect_is_enable()){ ql_sim1_detect_ind_cust_callback(insert_status); }else{ CPUartLogPrintf("%s,%d, sim hot plug config disabled!", __func__, __LINE__); continue; } } #endif if(insert_status==0) { uart_printf("SIM_1_DET_TASK CFUN0 S\r\n"); DIAG_FILTER(USIMLOG, usim_1_det_task_entry, LOG002, DIAG_INFORMATION) diagPrintf("SIM_1_DET_TASK CFUN5 B"); usim_send_quit_event(0); USIMHotPlugFlag[0] = TRUE; flush_cfun4_rsp_flag=0; wait_cnt=0; ATRecv(flush_cfun4_at_ch, cfun5, strlen(cfun5)); DIAG_FILTER(USIMLOG, usim_1_det_task_entry, LOG004, DIAG_INFORMATION) diagPrintf("SIM_1_DET_TASK CFUN5 E"); OSATaskSleep(200*2); DIAG_FILTER(USIMLOG, usim_1_det_task_entry, LOG005, DIAG_INFORMATION) diagPrintf("SIM_1_DET_TASK CFUN5 SLEEP E"); } else { DIAG_FILTER(USIMLOG, usim_1_det_task_entry, LOG006, DIAG_INFORMATION) diagPrintf("SIM_1_DET_TASK CFUN0 B"); usim_send_quit_event(0); flush_cfun4_rsp_flag=0; wait_cnt=0; ATRecv(flush_cfun4_at_ch, cfun0, strlen(cfun0)); OSATaskSleep(200*2); DIAG_FILTER(USIMLOG, usim_1_det_task_entry, LOG008, DIAG_INFORMATION) diagPrintf("SIM_1_DET_TASK CFUN0 SLEEP E"); DIAG_FILTER(USIMLOG, usim_1_det_task_entry, LOG009, DIAG_INFORMATION) diagPrintf("SIM_1_DET_TASK CFUN1 B"); USIMHotPlugFlag[0] = FALSE; flush_cfun4_rsp_flag=0; wait_cnt=0; ATRecv(flush_cfun4_at_ch, cfun1, strlen(cfun1)); DIAG_FILTER(USIMLOG, usim_1_det_task_entry, LOG011, DIAG_INFORMATION) diagPrintf("SIM_1_DET_TASK CFUN1 E"); OSATaskSleep(200*5); DIAG_FILTER(USIMLOG, usim_1_det_task_entry, LOG012, DIAG_INFORMATION) diagPrintf("SIM_1_DET_TASK CFUN1 SLEEP E"); } } } } void usim_1_det_timer_handler(UINT32 arg) { OS_STATUS os_status; UINT32 insert_status; insert_status=get_usim_1_insert_status(); DIAG_FILTER(USIMLOG,usim_1_det_timer_handler,LOG001,DIAG_INFORMATION) diagPrintf("SIM_1_DET_TIMER = %u", insert_status); GpioEnableEdgeDetectionBit(usim_1_detect_gpio, GPIO_TWO_EDGE); usim_1_hotplug_trigger(); } static void usim_1_det_hisr(void) { UINT32 timeout; OS_STATUS status; OSATimerStop(usim_1_detect_timer_ref); timeout=usim_1_debounce_time/5; if(timeout==0) timeout=1; DIAG_FILTER(USIMLOG,usim_1_det_hisr,LOG001,DIAG_INFORMATION) diagPrintf("SIM_1_DET_HISR %lu 0x%lx", timeout, get_current_TStimer_tick()); status = OSATimerStart(usim_1_detect_timer_ref, timeout, 0, usim_1_det_timer_handler, 0); } UINT32 usim_get_hotplug_flag(UINT32 card) { DIAG_FILTER(USIMLOG, usim_get_hotplug_flag, LOG001, DIAG_INFORMATION) diagPrintf("hotplugflag %lu, SIM card status:%lu", card, USIMHotPlugFlag[card]); return USIMHotPlugFlag[card]; } void usim_1_detect_init(void) { static UINT32 usim_1_detect_init_flag=0; GPIOConfiguration config; if(usim_1_detect_init_flag==1) { return; } else { usim_1_detect_init_flag=1; } OSATimerCreate(&usim_1_detect_timer_ref); OSAFlagCreate( &usim_1_detect_flag_ref); Os_Create_HISR(&usim_1_detect_hisr_ref, "SIM1DETH", usim_1_det_hisr, 2); OSATaskCreate(&usim_1_detect_task_ref, usim_1_detect_task_stack, 2048, 60, "SIM1DETT", usim_1_det_task_entry, NULL); if(usim_1_detect_gpio != 0) { if(usim_1_detect_gpio_insert_level) { #if defined (__QUECTEL_PROJECT_EC600KCN_CC__) || defined (__QUECTEL_PROJECT_EC600KCN_LC__) \ ||defined (__QUECTEL_PROJECT_EC600KCN_CK__) || defined (__QUECTEL_PROJECT_EC600KCN_LK__) *(volatile unsigned long *)(GPIO_MFPR_ADDR(usim_1_detect_gpio))=(QUEC_AF1_C|QUEC_PULL_UP_C|QUEC_DRV_SLOW_C|QUEC_RESERVED_C); #else *(volatile unsigned long *)(GPIO_MFPR_ADDR(usim_1_detect_gpio))=(QUEC_AF0_C|QUEC_PULL_UP_C|QUEC_DRV_SLOW_C|QUEC_RESERVED_C); #endif config.pinPull = GPIO_PULLDN_ENABLE; config.initLv = GPIO_INITIAL_VALUE_LOW; } else { #if defined (__QUECTEL_PROJECT_EC600KCN_CC__) || defined (__QUECTEL_PROJECT_EC600KCN_LC__) \ ||defined (__QUECTEL_PROJECT_EC600KCN_CK__) || defined (__QUECTEL_PROJECT_EC600KCN_LK__) *(volatile unsigned long *)(GPIO_MFPR_ADDR(usim_1_detect_gpio))=(QUEC_AF1_C|QUEC_DRV_SLOW_C|QUEC_RESERVED_C); #else *(volatile unsigned long *)(GPIO_MFPR_ADDR(usim_1_detect_gpio))=(QUEC_AF0_C|QUEC_DRV_SLOW_C|QUEC_RESERVED_C); #endif config.pinPull = GPIO_PULLUP_ENABLE; config.initLv = GPIO_INITIAL_VALUE_HIGH; } config.pinDir = GPIO_IN_PIN; config.pinEd = GPIO_TWO_EDGE; config.isr = usim_1_det_lisr; GpioInitConfiguration(usim_1_detect_gpio,config); } } void usim_init_hook(USIM_Card card) { //usim1 init if( (card==USIM_COM_CARD) && (usim_1_detect_gpio != 0)){ usim_1_detect_init(); } } #else void usim_init_hook(USIM_Card card) { return; } UINT32 usim_get_hotplug_flag(UINT32 card) { return FALSE; } #endif #endif