Files
banban/ql-kernel/threadx/quec_minsys/usim.c
T

5811 lines
153 KiB
C

/*------------------------------------------------------------
(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 <string.h>
#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; i<ppsLen-1; i++)
{
pck ^= ppsMessage[i];
}
ppsMessage[ppsLen-1] = pck;
// send the PPS message to the card and read the card's response:
ppsResponseLen = USIM_DL_writeRead(card, ppsLen, ppsMessage, ppsLen, NULL);
/* Check for HW remove detected */
if (_USIMstates[card] == USIM_REMOVED)
return USIM_RC_CARD_REMOVED;
if(ppsResponseLen == ppsLen)
{
// compare response to message:
for(i=0; i<ppsLen; i++)
{
if (ppsResponse[i] != ppsMessage[i])
{
return USIM_RC_PPS_ERROR;
}
}
if((info->indAdjustmentFactor)&&(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