📄 usim_drv.c
字号:
kal_uint32 retry;
dbg_print("L1usim_Reset\r\n");
DRVPDN_Disable(DRVPDN_CON1,DRVPDN_CON1_SIM,PDN_SIM);
if(usim_dcb.clock_stop_en == KAL_TRUE && usim_dcb.warm_rst == KAL_TRUE &&
usim_dcb.phy_proto == T1_PROTOCOL)
{
if(usim_dcb.main_state == CLK_STOPPING_STATE)
{
usim_set_timeout(0);
usim_dcb.main_state = MAIN_CMD_READY_STATE;
}
else if(usim_dcb.main_state == CLK_STOPPED_STATE)
{
DRV_Reg(SIM_CTRL) &= ~SIM_CTRL_HALT;
usim_set_timeout(usim_dcb.etu_of_700);
DRV_WriteReg(SIM_IRQEN, SIM_IRQEN_TOUT);
USIM_WAIT_EVENT();
}
}
L1usim_Init();
if(usim_check_input_volt(ExpectVolt) == KAL_FALSE)
return USIM_VOLT_NOT_SUPPORT;
// 1. Activate the USIM interface
SIM_DisAllIntr();
DMA_Stop(usim_dcb.dma_port);
usim_set_speed(SPEED_372);
usim_set_timeout(INIT_WWT_T0);
/*
if(TS_HSK_ENABLE)
{
SIM_SetRXRetry(7);
SIM_SetTXRetry(7);
USIM_ENABLE_TXRX_HANSHAKE();
}
*/
// if corrupted ATRs are received, retry 3 times
for(retry = 0; retry < ATR_RETRY; retry++)
{
kal_set_eg_events(usim_dcb.event,0,KAL_AND);
if(usim_select_power(ExpectVolt) == KAL_FALSE)
{
if(usim_dcb.warm_rst == KAL_TRUE)
return USIM_ATR_ERR;
if( usim_dcb.ts_hsk_en == KAL_TRUE)
usim_dcb.ts_hsk_en = KAL_FALSE;
else
return USIM_NO_INSERT;
//continue;
}
else if (usim_process_ATR() == USIM_NO_ERROR)
break;
ExpectVolt = usim_dcb.power;
}
if(retry == 3)
return USIM_ATR_ERR;
*ResultVolt = usim_dcb.power;
// 3. Process PTS
//if(usim_dcb.reset_mode == USIM_RESET_NEGOTIABLE)
{
usim_process_PTS();
// 4. Configure the IFSD
if(usim_dcb.phy_proto == T1_PROTOCOL)
{
if( usim_send_s_block(IFS_REQ, USIM_IFSD_MAX) == USIM_NO_ERROR)
usim_dcb.ifsd = USIM_IFSD_MAX;
}
}
// NOTE: can't turn off the PDN bit of SIM interface over, it will cause
// the SIM behavior abnormal.
usim_dcb.main_state = MAIN_CMD_READY_STATE;
usim_dcb.cmd_state = USIM_CMD_READY;
kal_set_eg_events(usim_dcb.event,0,KAL_AND);
return USIM_NO_ERROR;
}
/*************************************************************************
* FUNCTION
* L1usim_PowerOff
*
* DESCRIPTION
* 1. perform the deactivation to UICC
*
* PARAMETERS
*
* RETURNS
*
* GLOBALS AFFECTED
*
*************************************************************************/
void L1usim_PowerOff(void)
{
DRVPDN_Disable(DRVPDN_CON1,DRVPDN_CON1_SIM,PDN_SIM);
usim_deactivation();
DRVPDN_Enable(DRVPDN_CON1,DRVPDN_CON1_SIM,PDN_SIM);
}
/*************************************************************************
* FUNCTION
* L1usim_Get_Card_Info
*
* DESCRIPTION
* get the card informations
*
* PARAMETERS
*
* RETURNS
*
* GLOBALS AFFECTED
*
*************************************************************************/
void L1usim_Get_Card_Info(sim_info_struct *info)
{
ASSERT(usim_dcb.main_state >= ATR_STATE);
info->power = usim_dcb.power;
info->speed = usim_dcb.speed;
info->clock_stop = usim_dcb.clock_stop_type;
info->app_proto = usim_dcb.app_proto;
info->phy_proto = usim_dcb.phy_proto;
info->hist_index = usim_dcb.hist_index;
info->ATR = usim_dcb.ATR_data;
}
/*************************************************************************
* FUNCTION
* L1usim_Enable_Enhanced_Speed
*
* DESCRIPTION
* 1. enable the enhance speed mode if UICC supports
* 2. shall be called before reset after init
*
* PARAMETERS
*
* RETURNS
*
* GLOBALS AFFECTED
*
*************************************************************************/
void L1usim_Enable_Enhanced_Speed(kal_bool enable)
{
ASSERT(usim_dcb.main_state == IDLE_STATE);
usim_dcb.high_speed_en = enable;
}
/*************************************************************************
* FUNCTION
* L1usim_Set_ClockStopMode
*
* DESCRIPTION
* setup the clock stop mode according to the ATR information.
*
* PARAMETERS
* mode: clock stop mode
*
* RETURNS
*
* GLOBALS AFFECTED
*
*************************************************************************/
void L1usim_Set_ClockStopMode(usim_clock_stop_enum mode)
{
if(mode & CLOCK_STOP_MSK)
{
// calculate the clock to etu for 1860 and 700
usim_dcb.etu_of_1860 = (1860/(usim_dcb.Fi/usim_dcb.Di))+10; // longer than spec.
usim_dcb.etu_of_700 = (700/(usim_dcb.Fi/usim_dcb.Di))+5;
usim_dcb.clock_stop_en = KAL_TRUE;
if(mode == CLOCK_STOP_ANY)
usim_dcb.clock_stop_type = CLOCK_STOP_LOW;
else
usim_dcb.clock_stop_type = mode;
}
else
{
usim_dcb.clock_stop_en = KAL_FALSE;
}
}
/*************************************************************************
* FUNCTION
* L1usim_Cmd
*
* DESCRIPTION
* usim T=1 command
*
* PARAMETERS
* 1. txData: tx buffer containing command header optional with tx data.
* 2. txSize: length of the tx data
* 3. rxData: rx buffer (must inluding two extra one for sw1 and sw2)
* 4. rxSize: length of the rx data except sw1|sw2
*
* RETURNS
* status bytes(SW1|SW2), 0 means a physical error.
* GLOBALS AFFECTED
*
*************************************************************************/
sim_status L1usim_Cmd(kal_uint8 *txData,kal_uint32 *txSize,kal_uint8 *rxData, kal_uint32 *rxSize)
{
if(usim_dcb.main_state != MAIN_CMD_READY_STATE && usim_dcb.main_state != CLK_STOPPED_STATE)
{
kal_prompt_trace(MOD_SIM,"[SIM_DRV]:L1usim_Cmd is called at err state");
return STATUS_FAIL;
}
if(rxData == NULL && *rxSize != 0)
ASSERT(0);
if(usim_dcb.cmd_case == usim_case_1)
{ // for case1, only 4 bytes need to be transfer
*txSize = 4;
*rxSize = 0;
}
return usim_send_i_block(txData, txSize, rxData, rxSize);
}
/*************************************************************************
* FUNCTION
* usim_TimeOutHandler
*
* DESCRIPTION
* Callback function of gpt timer, and launched while MSDC busy for a while
*
* PARAMETERS
*
*
* RETURNS
*
* GLOBALS AFFECTED
*
*
*************************************************************************/
void usim_gpt_timeout_handler(void *parameter)
{
kal_prompt_trace(MOD_SIM,"[SIM_DRV]: usim gpt timeout !");
usim_dcb.status = USIM_GPT_TIMEOUT;
USIM_SET_EVENT();
}
//------------------------------------------------------------------------//
// General interfaces of sim driver
//------------------------------------------------------------------------//
/*************************************************************************
* FUNCTION
* L1sim_Reset_All
*
* DESCRIPTION
* 1. general interface of sim reset for T=0 and T=1
* 2. it support warm reset for UICC
* 3. first enable error repeat handling process to cover parity error at ATR, if not
* success, disable it.
* 4. for SIM protocol with T=0, additional reset will be perfromed.
*
* PARAMETERS
* ExpectVolt: expected input voltage for the SIM card.
* ResultVolt: finally used power voltage.
* warm: specify warm reset for UICC
*
* RETURNS
*
* GLOBALS AFFECTED
*
*************************************************************************/
usim_status_enum L1sim_Reset_All(sim_power_enum ExpectVolt, sim_power_enum *ResultVolt, kal_bool warm)
{
usim_status_enum status;
if(warm == KAL_FALSE)
{
dbg_print("cold reset \r\n");
//TS_HSK_ENABLE = KAL_TRUE;
status = L1usim_Reset(ExpectVolt, ResultVolt);
if(status < 0)
{
kal_prompt_trace(MOD_SIM,"[SIM_DRV]: L1usim_Reset failed!(%d)",status);
L1sim_PowerOff_All();
if(status == USIM_NO_INSERT)
usim_dcb.present = KAL_FALSE;
return status;
/*
TS_HSK_ENABLE = KAL_FALSE;
status = L1usim_Reset(ExpectVolt, ResultVolt);
if(status <0)
{
L1sim_PowerOff_All();
return status;
}
*/
}
else
{
kal_uint32 i,j;
kal_char buf[100],*p;
p = buf;
sprintf(p,"[SIM_DRV]:ATR= ");
p += strlen(buf);
for(i = 0; i< usim_dcb.ATR_index; i++)
{
sprintf(p," %2x",usim_dcb.ATR_data[i]);
p+= 3;
}
kal_prompt_trace(MOD_SIM,buf);
kal_prompt_trace(MOD_SIM,"[SIM_DRV]: L1usim_Reset OK v: %d, T: %d, speed:%d",
usim_dcb.power, usim_dcb.phy_proto, usim_dcb.card_speed);
}
if(usim_dcb.phy_proto == T0_PROTOCOL)
{
extern kal_uint8 sim_dmaport;
kal_uint8 s;
kal_uint8 power;
#if !defined(MT6218B) && !defined(MT6218)
sim_dmaport = usim_dcb.dma_port;
#endif
L1sim_Init();
if(usim_dcb.power == CLASS_C_18V)
power = SIM_18V;
else
power = SIM_30V;
if(usim_dcb.app_proto == SIM_PROTOCOL)
{
s = L1sim_Reset(power, NULL, NULL );
ASSERT(s == SIM_NO_ERROR);
}
else
usim_update_sim_to_ready();
}
}
else
{
dbg_print("warm reset \r\n");
if(usim_dcb.app_proto == USIM_PROTOCOL)
{
usim_dcb.warm_rst = KAL_TRUE;
status = L1usim_Reset(usim_dcb.power, ResultVolt);
usim_dcb.warm_rst = KAL_FALSE;
if(status <0)
{
L1sim_PowerOff_All();
return status;
}
if(usim_dcb.phy_proto == T0_PROTOCOL)
{
extern kal_uint8 sim_dmaport;
kal_uint8 power = 0;
sim_dmaport = usim_dcb.dma_port;
L1sim_Init();
if(usim_dcb.power == CLASS_C_18V)
power = SIM_18V;
else
power = SIM_30V;
if(usim_dcb.app_proto == SIM_PROTOCOL)
L1sim_Reset(power, NULL, NULL);
else
usim_update_sim_to_ready();
}
}
else
{
status = USIM_INVALID_WRST;
}
}
return status;
}
/*************************************************************************
* FUNCTION
* L1sim_Enable_Enhanced_Speed_All
*
* DESCRIPTION
* enable the enhance speed
*
* PARAMETERS
*
* RETURNS
*
* GLOBALS AFFECTED
*
*************************************************************************/
void L1sim_Enable_Enhanced_Speed_All(kal_bool enable)
{
L1sim_Enable_Enhanced_Speed(enable);
L1usim_Enable_Enhanced_Speed(enable);
}
/*************************************************************************
* FUNCTION
* L1sim_Set_ClockStopMode_All
*
* DESCRIPTION
* configure the clock stop mode.
*
* PARAMETERS
*
* RETURNS
*
* GLOBALS AFFECTED
*
*************************************************************************/
kal_bool L1sim_Set_ClockStopMode_All(sim_clock_stop_enum mode)
{
if(usim_dcb.phy_proto == T0_PROTOCOL)
{
if(mode == CLOCK_STOP_HIGH)
L1sim_Configure(CLOCK_STOP_AT_HIGH);
else if(mode == CLOCK_STOP_LOW || mode == CLOCK_STOP_ANY)
L1sim_Configure(CLOCK_STOP_AT_LOW);
else
L1sim_Configure(CLOCK_STOP_NOT_ALLOW);
#if 0
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
#endif
}
else
{
L1usim_Set_ClockStopMode(mode);
}
return KAL_TRUE;
}
/*************************************************************************
* FUNCTION
* L1sim_PowerOff_All
*
* DESCRIPTION
* turn off the SIM card.
*
* PARAMETERS
*
* RETURNS
*
* GLOBALS AFFECTED
*
*************************************************************************/
void L1sim_PowerOff_All(void)
{
if(usim_dcb.phy_proto == T0_PROTOCOL)
L1sim_PowerOff();
else
L1usim_PowerOff();
}
/*************************************************************************
* FUNCTION
* L1sim_Get_Card_Info_All
*
* DESCRIPTION
* get the card information
*
* PARAMETERS
*
* RETURNS
*
* GLOBALS AFFECTED
*
*************************************************************************/
void L1sim_Get_Card_Info_All(sim_info_struct *info)
{
L1usim_Get_Card_Info(info);
}
/*************************************************************************
* FUNCTION
* L1sim_Cmd_All
*
* DESCRIPTION
* 1. check which case the command belongs to.
* 2. direct the command into T=0 or T=1 protocol layer.
*
* PARAMETERS
* 1. txData: tx buffer containing command header optional with tx data.
* 2. txSize: length of the tx data
* 3. rxData: rx buffer (for T=1, must inluding two extra one for sw1 and sw2)
* 4. rxSize: length of the rx data except sw1|sw2
*
* RETURNS
* status bytes(SW1|SW2), 0 means a physical error.
*
* GLOBALS AFFECTED
*
*************************************************************************/
sim_status L1sim_Cmd_All(kal_uint8 *txData,kal_uint32 *txSize,kal_uint8 *rxData, kal_uint32 *rxSize)
{
if(usim_dcb.present == KAL_FALSE)
return STATUS_FAIL;
// check cmd cases
if(*txSize == 5 && rxData == NULL)
{
usim_dcb.cmd_case = usim_case_1;
dbg_print("usim_case_1 \r\n");
}
else if(*txSize == 5 && rxData != NULL)
{
usim_dcb.cmd_case = usim_case_2;
dbg_print("usim_case_2 \r\n");
}
else if(*txSize != 5 && rxData == NULL)
{
usim_dcb.cmd_case = usim_case_3;
dbg_print("usim_case_3 \r\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -