📄 usim_drv.c
字号:
/*****************************************************************************
* Copyright Statement:
* --------------------
* This software is protected by Copyright and the information contained
* herein is confidential. The software may not be copied and the information
* contained herein may not be used or disclosed except with the written
* permission of MediaTek Inc. (C) 2005
*
* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
*
* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
*
* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
*
*****************************************************************************/
/*****************************************************************************
*
* Filename:
* ---------
* usim_drv.c
*
* Project:
* --------
* Maui_Software
*
* Description:
* ------------
* USIM driver functions.
*
*
* Author:
* -------
* -------
*
*============================================================================
* HISTORY
* Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
*------------------------------------------------------------------------------
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*------------------------------------------------------------------------------
* Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
*============================================================================
****************************************************************************/
#include "drv_comm.h"
#include "reg_base.h"
#include "intrCtrl.h"
#include "sim_al.h"
#include "sim_hw.h"
#include "sim_sw.h"
#include "dma_hw.h"
#include "dma_sw.h"
#include "gpt_sw.h"
#ifdef MT6318
#include "pmic6318_sw.h"
#endif /*MT6318*/
#if defined(__USIM_DRV__)
#include "usim_drv.h"
extern void SIM_SetRXTIDE(kal_uint16 RXTIDE);
extern void SIM_SetTXTIDE(kal_uint16 _TXTIDE);
extern Sim_Card SimCard;
//extern kal_bool TS_HSK_ENABLE;
usim_dcb_struct usim_dcb;
kal_uint8 BWT_Factor[3] = {1, 6, 12}; // 372/64 = 6, 372/32 = 12
#if defined(USIM_DEBUG)
#define BUF_COUNT 1024
kal_uint16 int_buffer[BUF_COUNT];
kal_uint32 buf_index;
#define PUSH_INT(a) int_buffer[(buf_index&(BUF_COUNT-1))] = a;\
buf_index++;
#else
#define PUSH_INT(a)
#endif
#if defined(USIM_DEBUG)
extern void dbg_print(char * fmt,...);
static kal_uint32 start, end;
kal_uint32 get_current_time(void)
{
return (DRV_Reg32(0x80200230));
}
kal_uint32 get_duration_tick(kal_uint32 previous_time)
{
kal_uint32 result, current_time;
current_time = DRV_Reg32(0x80200230);
if (previous_time > current_time)
{
result = 0x80000 - previous_time + current_time;
}
else
{
result = current_time - previous_time;
}
return result;
}
#endif
// proto type
static kal_bool usim_check_input_volt(usim_power_enum volt);
static usim_status_enum usim_process_ATR(void);
static void usim_process_TA1(kal_uint8 TA1);
static void usim_process_PTS(void);
static void usim_set_speed(usim_speed_enum speed);
static void usim_set_protocol(usim_protocol_enum T);
static void usim_set_timeout(kal_uint32 timeout);
static kal_bool usim_select_power(usim_power_enum ExpectVolt);
static void usim_activation(void);
static void usim_lisr(void);
static void usim_deactivation(void) ;
static void usim_t1end_handler(void);
static void usim_hisr(void);
static void usim_rx_handler(kal_uint32 int_status);
static void usim_send_block(kal_uint8 *adrs );
static kal_bool usim_rx_block_handler(kal_uint32 *adrs);
static sim_status usim_send_i_block(kal_uint8 *txData,kal_uint32 *txSize,kal_uint8 *rxData, kal_uint32 *rxSize);
/*************************************************************************
* FUNCTION
* usim_check_input_volt
*
* DESCRIPTION
* check if the input volt is supported by the interface device
*
* PARAMETERS
* volt: voltage used by SIM card
*
* RETURNS
* KAL_TRUE: it is supported
* KAL_FALSE: not supported
*
* GLOBALS AFFECTED
*
*
*************************************************************************/
static kal_bool usim_check_input_volt(usim_power_enum volt)
{
if(usim_dcb.sim_env == ME_18V_30V)
return KAL_TRUE;
if(usim_dcb.sim_env == ME_30V_ONLY && volt == CLASS_B_30V)
return KAL_TRUE;
if(usim_dcb.sim_env == ME_18V_ONLY && volt == CLASS_C_18V)
return KAL_TRUE;
return KAL_FALSE;
}
/*************************************************************************
* FUNCTION
* usim_process_ATR
*
* DESCRIPTION
* 1. wait all ATR characters received at HISR and put into usim_dcb.ATR_data
* 2. Get parameters from ATR, Fi, Di, T0_support, T1_support, reset mode, WWT(T0)
* IFSC(T1), CWI, BWI, X, U
*
* PARAMETERS
* None
* RETURNS
* KAL_TRUE: Valid TS is received
* KAL_FALSE: Valid TS is not received, card is not present or not supported
*
* GLOBALS AFFECTED
* usim_dcb
*
*************************************************************************/
static usim_status_enum usim_process_ATR(void)
{
kal_uint8 data,TD;
kal_uint8 *ptr = usim_dcb.ATR_data;
kal_uint32 index = 1; // skip the first TS byte
// get the application protocol of the sim card
if((ptr[index] & 0x0f) == 0)
usim_dcb.app_proto = SIM_PROTOCOL; // no historical char imply SIM_PROTOCOL
do
{
data = ptr[index++];
USIM_CAL_TD_COUNT(data, index);
}while(data & TDMask);
usim_dcb.hist_index = index;
if(ptr[index] == HIST_FIRST_USIM && ptr[index+1] == HIST_SEC_USIM
&& ptr[index+3] == HIST_FOUR_USIM)
usim_dcb.app_proto = USIM_PROTOCOL;
else
usim_dcb.app_proto = SIM_PROTOCOL;
// check TCK if exists.
if(DRV_Reg(SIM_COUNT))
{
kal_uint32 i;
kal_uint8 ck = 0;
ptr[usim_dcb.ATR_index++] = DRV_Reg(SIM_DATA);
for(i=1;i<usim_dcb.ATR_index;i++)
ck ^= ptr[i];
if(ck != 0)
return USIM_INVALID_ATR;
}
// parse the content of ATR
index = 1;
TD = ptr[index++]; //T0
if(TD & TAMask)
{
// TA1 (FI, DI)
data = ptr[index++];
usim_process_TA1(data);
usim_dcb.WWT = INIT_WWT_T0*usim_dcb.Di;
}
if(TD & TBMask)
{
// TB1 (PI, II) (neglect it)
data = ptr[index++];
}
if(TD & TCMask)
{
// TC1 (N: extra guard time) (neglect it)
data = ptr[index++];
if(data != 0 && data != 255)
return USIM_INVALID_ATR;
}
if( !(TD & TDMask))
{
usim_dcb.T0_support = KAL_TRUE;
return USIM_NO_ERROR;
}
TD = ptr[index++]; // TD1
if((TD & 0x0f) == 0)
usim_dcb.T0_support = KAL_TRUE;
else if((TD & 0x0f) == 1)
usim_dcb.T1_support = KAL_TRUE;
else if(TD & 0x0f == 0x0f)
{
// T = 15 is forbidden in TD1
return USIM_INVALID_ATR;
}
if(TD & TAMask)
{
//TA2 (specific mode)
dbg_print("TA2(specific mode) \r\n");
data = ptr[index++];
usim_dcb.reset_mode = USIM_RESET_SPECIFIC;
// chage the clock to the one before reset.
}
if(TD & TBMask)
{
// TB2 (PI2)(neglect it)
data = ptr[index++];
}
if(TD & TCMask)
{
// TC2 (work waiting time = 960xWIxDi etu)(T0)
data = ptr[index++];
usim_dcb.WWT = 960*data*usim_dcb.Di;
}
dbg_print("WWT: %d \r\n",usim_dcb.WWT);
if( !(TD & TDMask))
return USIM_NO_ERROR;
TD = ptr[index++]; // TD2
if((TD & 0x0f) == 1)
usim_dcb.T1_support = KAL_TRUE;
else if(TD & 0x0f == 0x0f)
goto global_interface;
if(TD & TAMask)
{
//TA3 (ISFC)
data = ptr[index++];
usim_dcb.ifsc = data;
dbg_print("IFSC: %d \r\n",data);
}
if(TD & TBMask)
{
kal_uint8 cwi,bwi;
// TB3 (PI2)
data = ptr[index++];
cwi = data&0xf; // range from 0~5
bwi = (data&0xf0)>>4;
if(cwi > MAX_CWI)
return USIM_INVALID_ATR;
if(bwi > MAX_BWI)
return USIM_INVALID_ATR;
usim_dcb.CWT = (1<<cwi)+11;
usim_dcb.BWT = (1<<bwi)*960;
}
else
{
usim_dcb.CWT = USIM_CWT_DEFAULT;
usim_dcb.BWT = USIM_BWT_DEFAULT;
}
dbg_print("BWT: %d \r\n",usim_dcb.BWT);
if(TD & TCMask)
{
// TC3 (neglect)
data = ptr[index++];
}
if( !(TD & TDMask))
return USIM_NO_ERROR;
TD = ptr[index++]; // TD3
if(TD & 0x0f != 0x0f)
return USIM_NO_ERROR;
global_interface:
if(TD & TAMask)
{
//TAi (clock stop(X) and power class(U))
data = ptr[index++];
usim_dcb.clock_stop_type = (data&CLOCK_STOP_MSK);
if(usim_dcb.app_proto == SIM_PROTOCOL)
usim_dcb.power_class = 0xff;
else
usim_dcb.power_class = (data & USIM_POW_CLASS_MSK);
dbg_print("clock stop[7:8]|power class[1:6]: %x \r\n",data);
}
// check if used power is supported by the UICC
if((usim_dcb.power & usim_dcb.power_class) == 0)
{
if(usim_dcb.sim_env == ME_18V_30V)
{
if(usim_dcb.power == CLASS_C_18V)
usim_dcb.power = CLASS_B_30V;
return USIM_VOLT_NOT_SUPPORT;
}
}
else if(usim_dcb.app_proto == SIM_PROTOCOL)
return USIM_NO_ERROR;
return USIM_NO_ERROR;
}
/*************************************************************************
* FUNCTION
* usim_process_TA1
*
* DESCRIPTION
1.
Get Di and Fi from TA1
*
* PARAMETERS
TA1: first interface character used to indicate the Fi and Di
* RETURNS
* None
*
* GLOBALS AFFECTED
* usim_dcb.Fi, usim_dcb.Di
*
*************************************************************************/
static void usim_process_TA1(kal_uint8 TA1)
{
if(TA1 == ATR_TA1_64)
{
dbg_print("SPEED64 \r\n");
usim_dcb.Fi = 512;
usim_dcb.Di = 8;
usim_dcb.card_speed = SPEED_64;
}
else if(TA1 == ATR_TA1_32)
{
dbg_print("SPEED32 \r\n");
usim_dcb.Fi = 512;
usim_dcb.Di = 16;
usim_dcb.card_speed = SPEED_32;
}
else if(TA1 == ATR_TA1_16)
{ // only support speed32 even encounter a speed16 card
dbg_print("SPEED16 \r\n");
usim_dcb.Fi = 512;
usim_dcb.Di = 16;
usim_dcb.card_speed = SPEED_16;
}
else
{
dbg_print("SPEED372 \r\n");
usim_dcb.Fi = 372;
usim_dcb.Di = 1;
usim_dcb.card_speed = SPEED_372;
}
}
/*************************************************************************
* FUNCTION
* usim_process_PTS
*
* DESCRIPTION
* 1. Perform the PTS to select the protocol and enhanced speed parameter(Fn,Dn).
T1 has higher priority than T0
* 2. Change the clock rate according to the PTS response
* 3. Enable the T0 or T1 controller according to the PTS response
*
* PARAMETERS
None
* RETURNS
* None
*
* GLOBALS AFFECTED
* usim_dcb.speed
*
*************************************************************************/
static void usim_process_PTS(void)
{
kal_uint32 i;
kal_uint8 pts[PPS_LEN],pts_r[PPS_LEN],pck;
usim_speed_enum speed;
kal_bool echoed = KAL_TRUE;
dbg_print("usim_process_PTS \r\n");
if(usim_dcb.app_proto == SIM_PROTOCOL)
{
dbg_print("PTS not performed (SIM_PROTOCOL) ");
echoed = KAL_FALSE;
goto exit;
}
if(usim_dcb.reset_mode == USIM_RESET_SPECIFIC)
{
dbg_print("not performed (specific mode)");
echoed = KAL_TRUE;
goto exit;
}
if(usim_dcb.high_speed_en)
{
if(usim_dcb.Di == 1)
speed = SPEED_372;
else if(usim_dcb.Di == 8)
speed = SPEED_64;
else if(usim_dcb.Di == 16)
speed = SPEED_32;
else
speed = SPEED_372;
}
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -