📄 sim_driver.c
字号:
#include "sfr_def.h"
#include "id.h"
#include "sim_driver.h"
#include "v_sim_contact.h"
#include "..\mmi\wt_cnt.h"
#include "ap_ui.h"
#include "yd_debug.h"
///////////////////////////////////////////////////////////////////////////////
//
// SIM interface param
//
///////////////////////////////////////////////////////////////////////////////
#define SIM_DEFAULT_F 372 // initial bit rate
#define SIM_DEFAULT_D 1 // initial bit rate
#define SIM_DEFAULT_N 0 // extra guard time
#define SIM_DEFAULT_WI 10 // initial wait time
#define SIM_DEFAULT_BAUD_FACTOR (SIM_DEFAULT_F / SIM_DEFAULT_D)
#define SIM_DEFAULT_CLK_COUNTER 2
#define SIM_DEFAULT_BRG_COUNTER (SIM_DEFAULT_BAUD_FACTOR * SIM_DEFAULT_CLK_COUNTER * 2 / 16)
#define SIM_MAX_F 512
#define SIM_MAX_D 8
#define SIM_MAX_BAUD_FACTOR (SIM_MAX_F / SIM_MAX_D)
#define SIM_MAX_CLK_COUNTER 1
#define SIM_MAX_BRG_COUNTER (SIM_MAX_BAUD_FACTOR * SIM_MAX_CLK_COUNTER * 2 / 16)
#ifdef KEVIN_VERIFY_MSG_DEBUG // Kevin 2005-6-29 for KEVIN_VERIFY_MSG_DEBUG
extern unsigned char ucDebugCode[];
#endif
static unsigned char sim_atr_TS;
static unsigned short sim_guard_time, sim_wait_time;
static unsigned char sim_wait_time_WI;
static const unsigned short sim_factor_F[] = {
372, 372, 558, 744, 1116, 1488, 1860, 0, 0, 512, 768, 1024, 1536, 2048, 0, 0
};
static const unsigned char sim_factor_D[] = {
0, 1, 2, 4, 8, 16, 0, 0, 0, 0, -2, -4, -8, -16, -32, -64
};
static const unsigned char sim_interface_char_len[] = {
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4
};
///////////////////////////////////////////////////////////////////////////////
//
// SIM buffer
//
///////////////////////////////////////////////////////////////////////////////
#define MAX_ATR_BUFSIZE 33
#define SIM_RX_BUFSIZE 256 // kevin 2005-5-24 for sim_rx_buf size
#define SIM_RX_BUFMASK 0xFF
static unsigned char sim_rx_buf[ SIM_RX_BUFSIZE ]; // rx ring buffer
static unsigned char sim_rx_head, sim_rx_tail;
static unsigned char sim_rx_data;
///////////////////////////////////////////////////////////////////////////////
//
// SIM driver status
//
///////////////////////////////////////////////////////////////////////////////
unsigned char sim_card_ready;
static unsigned char sim_in_transaction;
#ifdef KEVIN_VERIFY_MSG_DEBUG // Kevin 2005-6-29 for KEVIN_VERIFY_MSG_DEBUG
unsigned char sim_rx_status;
#else
static unsigned char sim_rx_status;
#endif
#define SIM_STATUS_OK 0x00
#define SIM_STATUS_RX_ERROR 0x01
#define SIM_STATUS_RX_TIMEOUT 0x02
#define SIM_STATUS_RX_OVERFLOW 0x03
#define SIM_STATUS_VERIFY_FAIL 0x04
#define SIM_STATUS_INVALID_TS 0x05
#define SIM_STATUS_INVALID_TCK 0x06
#define SIM_STATUS_INVALID_ACK 0x07
#define SIM_STATUS_INVALID_TA1 0x08
#define SIM_STATUS_INVALID_PI1 0x09
#define SIM_STATUS_INVALID_PCK 0x0A
#define SIM_STATUS_PPS_FAIL 0x0B
///////////////////////////////////////////////////////////////////////////////
//
// UART2 routine
//
///////////////////////////////////////////////////////////////////////////////
#define UART2_C1_TX_ENABLE 0x01
#define UART2_C1_RX_ENABLE 0x04
#define UART2_start() (u2c1 |= UART2_C1_RX_ENABLE | UART2_C1_TX_ENABLE)
#define UART2_stop() (u2c1 &= ~(UART2_C1_RX_ENABLE | UART2_C1_TX_ENABLE))
void UART2_open(void)
{
u2mr = 0x65; // even parity, one stop bit, internal clock, 8 bits
u2c0 = 0x10; // LSB first (direct format), disable CTS/RTS, clock source f1
u2c1 = 0x90; // no reverse (direct format), interrupt on transmission complete
u2brg = SIM_DEFAULT_BRG_COUNTER - 1;
s2tic = 0x00; /* disable tx interrupt */
s2ric = 0x06; /* enable rx interrupt, level 6 */
}
void UART2_close(void)
{
u2mr = 0x00;
u2c0 = 0x00;
u2c1 = 0x00;
s2tic = 0x00; /* disable tx interrupt */
s2ric = 0x00; /* disable rx interrupt */
}
void UART2_tx_int(void)
{
/* do not use interrupt mode, because guardtime required */
}
void UART2_rx_int(void)
{
unsigned char rx_status, rx_data;
unsigned char ptr;
rx_data = u2rbl;
rx_status = u2rbh;
asm(" fset i");
if (rx_status & 0xF0)
{
sim_rx_status = SIM_STATUS_RX_ERROR;
}
else
{
ptr = (sim_rx_tail + 1) & SIM_RX_BUFMASK;
if (ptr == sim_rx_head)
{
sim_rx_status = SIM_STATUS_RX_OVERFLOW;
}
else
{
sim_rx_buf[ sim_rx_tail ] = rx_data;
sim_rx_tail = ptr;
}
}
}
///////////////////////////////////////////////////////////////////////////////
//
// Ring Buffer
//
///////////////////////////////////////////////////////////////////////////////
static void SIM_ResetRingBuffer(void)
{
sim_rx_status = SIM_STATUS_OK;
sim_rx_head = sim_rx_tail = 0;
}
///////////////////////////////////////////////////////////////////////////////
//
// Timer function
//
///////////////////////////////////////////////////////////////////////////////
static void SIM_PrepareTimer(unsigned char clk_src, unsigned short interval)
{
SIM_CNT_taXs = 0;
SIM_CNT_taXmr = clk_src | 0x02; /* one-shot timer mode */
SIM_CNT_taXic = 0x00; /* disable interrupt */
SIM_CNT_taX = interval;
SIM_CNT_taXs = 1;
}
static void SIM_Delay(void)
{
SIM_CNT_taXos = 1;
while (SIM_CNT_ir_taXic != 1) /* wait time expired */
;
SIM_CNT_ir_taXic = 0;
}
///////////////////////////////////////////////////////////////////////////////
//
// CLK function
//
///////////////////////////////////////////////////////////////////////////////
static void SIM_CLK_Init(void)
{
SIM_CLK_taXs = 0;
SIM_CLK_taXic = 0x00; /* disable interrupt */
SIM_CLK_taXmr = 0x04; /* timer mode, clock souce f1, pulse output */
SIM_CLK_taX = SIM_DEFAULT_CLK_COUNTER - 1;
}
static void SIM_CLK_SwitchOn(void)
{
sim_in_transaction = 1;
STimerMgr_StopTimer(ID_STIMER_SIM_DRIVER);
if (MFLG_WAIT_SIM_DRIVER == 0) // CLK maybe stopped before
{
#if 0
if (SIM_CLK_taXs == 0)
SIM_CLK_taXs = 1;
#endif
SIM_PrepareTimer(0x40, 744 - 1); // clock source f8
SIM_Delay();
}
}
static void SIM_CLK_SwitchOff(void)
{
if (sim_in_transaction)
return;
#if 0
if (SIM_CLK_taXs == 1)
SIM_CLK_taXs = 0;
#endif
MFLG_WAIT_SIM_DRIVER = 0; // enable WAIT mode
}
static void SIM_CLK_PrepareOff(void)
{
MFLG_WAIT_SIM_DRIVER = 1; // disable WAIT mode
sim_in_transaction = 0;
STimerMgr_StartTimer(ID_STIMER_SIM_DRIVER, 2, SIM_CLK_SwitchOff); // wait 1860 CLK at least
}
///////////////////////////////////////////////////////////////////////////////
//
// SIM IO routine
//
///////////////////////////////////////////////////////////////////////////////
static unsigned char SIM_SendByte(unsigned char tx_data)
{
extern const far unsigned char t_invert[256];
unsigned char rx_data;
if (sim_atr_TS != 0x3B)
{
tx_data = t_invert[ ~tx_data ]; /* inverse and reverse the data */
}
u2tb = tx_data;
while (txept_u2c0 != 1) /* wait transmission complete */
;
while (sim_rx_status == SIM_STATUS_OK)
{
if (sim_rx_head != sim_rx_tail)
{
rx_data = sim_rx_buf[ sim_rx_head ];
sim_rx_head = (sim_rx_head + 1) & SIM_RX_BUFMASK;
/* verify send byte */
if (rx_data != tx_data)
{
sim_rx_status = SIM_STATUS_VERIFY_FAIL;
}
break;
}
}
return sim_rx_status;
}
static unsigned char SIM_ReceiveByte(void)
{
extern const far unsigned char t_invert[256];
unsigned char WI;
WI = sim_wait_time_WI;
SIM_CNT_ir_taXic = 0;
SIM_CNT_taXos = 1; /* start wait time */
while (sim_rx_status == SIM_STATUS_OK)
{
if (sim_rx_head != sim_rx_tail)
{
sim_rx_data = sim_rx_buf[ sim_rx_head ];
sim_rx_head = (sim_rx_head + 1) % SIM_RX_BUFSIZE;
if (sim_atr_TS != 0x3B)
{
sim_rx_data = t_invert[ ~sim_rx_data ]; /* inverse and reverse the data */
}
break;
}
if (SIM_CNT_ir_taXic == 1)
{
SIM_CNT_ir_taXic = 0;
WI--;
if (WI == 0) /* wait time expired */
{
sim_rx_status = SIM_STATUS_RX_TIMEOUT;
break;
}
SIM_CNT_taXos = 1; /* restart wait time */
}
}
return sim_rx_status;
}
static void SIM_SendBuffer(unsigned char *tx_buf, unsigned char tx_len)
{
/* prepare guard time */
SIM_PrepareTimer(0x40, sim_guard_time); // clock source f8
do
{
SIM_Delay();
if (SIM_SendByte( *tx_buf++ ) != SIM_STATUS_OK)
return;
} while (--tx_len);
}
static void SIM_ReceiveBuffer(unsigned char *rx_buf, unsigned char rx_len)
{
do
{
if (SIM_ReceiveByte() != SIM_STATUS_OK)
return;
*rx_buf++ = sim_rx_data;
} while (--rx_len);
}
///////////////////////////////////////////////////////////////////////////////
//
// PPS Transaction
//
///////////////////////////////////////////////////////////////////////////////
static unsigned char SIM_CalcCheckChar(unsigned char *buf, unsigned char len)
{
unsigned char i, ck = 0;
for (i = 0; i < len; i++)
ck ^= buf[i];
return ck;
}
static void SIM_Transaction_PPS(unsigned char *req, unsigned char *rsp)
{
unsigned char len;
/* send PPS */
len = sim_interface_char_len[ req[1] >> 4 ] + 3;
SIM_SendBuffer(&req[0], len);
if (sim_rx_status != SIM_STATUS_OK)
return;
/* prepare wait time */
SIM_PrepareTimer(0x80, sim_wait_time); // clock source f32
/* receive PPSS, PPS0 */
SIM_ReceiveBuffer(&rsp[0], 2);
if (sim_rx_status != SIM_STATUS_OK)
return;
/* receive PPS1, PPS2, PPS3, PCK */
len = sim_interface_char_len[ rsp[1] >> 4 ] + 1;
SIM_ReceiveBuffer(&rsp[2], len);
if (sim_rx_status != SIM_STATUS_OK)
return;
len += 2;
if (SIM_CalcCheckChar(rsp, len) != 0)
{
sim_rx_status = SIM_STATUS_INVALID_PCK;
}
else if (rsp[0] != 0xFF) // PPSS
{
sim_rx_status = SIM_STATUS_PPS_FAIL;
}
}
///////////////////////////////////////////////////////////////////////////////
//
// SIM driver routine
//
///////////////////////////////////////////////////////////////////////////////
static void SIM_SetInterfaceParams(unsigned short baud_factor, unsigned char clk_counter, unsigned char N, unsigned char WI)
{
unsigned short tmp = baud_factor * clk_counter;
sim_guard_time = ((unsigned short)(N + (12 - 10)) * (tmp * 2 / 8)) - 1; // clock source f8
sim_wait_time = (tmp * 2 * (960 / 32)) - 1; // clock source 32
sim_wait_time_WI = WI;
}
void SIM_OpenDriver(void)
{
union {
unsigned char atr[MAX_ATR_BUFSIZE]; // answer to reset
struct {
unsigned char req[6];
unsigned char rsp[6];
} pps; // protocol and parameter selection
} buf;
unsigned char rx_ptr, rx_len;
unsigned char protocol_type_T;
unsigned char interface_char_lvl, interface_char_map;
unsigned char interface_char_TA1, interface_char_TB1, interface_char_TC1, interface_char_TC2;
unsigned short factor_F, baud_factor, brg_counter;
unsigned char factor_D, clk_counter, pps_selection;
SIM_ResetRingBuffer();
SIM_SetInterfaceParams(SIM_DEFAULT_BAUD_FACTOR, SIM_DEFAULT_CLK_COUNTER, SIM_DEFAULT_N, SIM_DEFAULT_WI);
/* activate SIM contact */
SIM_RST = 0; /* RST is in state L */
#ifdef SIM_CNTL
SIM_CNTL = 1; /* VCC shall be powered */
#endif
SIM_IO_OUT = 1; /* I/O in the interface device shall be put in reception mode */
SIM_CLK_Init(); /* CLK shall be provided with a suitable and stable clock */
SIM_CLK_taXs = 1;
/* set minimum reset time */
SIM_PrepareTimer(0x80, (SIM_DEFAULT_CLK_COUNTER * 2 * (40000 / 32)) - 1); // clock source f32
SIM_Delay();
/* open UART2 port */
UART2_open();
/* prepare receiving ATR */
sim_atr_TS = 0x3B;
protocol_type_T = 0;
/* prepare wait time */
SIM_PrepareTimer(0x80, sim_wait_time); // clock source f32
SIM_RST = 1;
/* start ATR */
UART2_start();
/* receive TS */
if (SIM_ReceiveByte() != SIM_STATUS_OK)
goto label_atr_stop;
if (sim_rx_data != 0x3B && sim_rx_data != 0x03)
{
sim_rx_status = SIM_STATUS_INVALID_TS;
goto label_atr_stop;
}
sim_atr_TS = sim_rx_data;
/* receive T0 */
if (SIM_ReceiveByte() != SIM_STATUS_OK)
goto label_atr_stop;
buf.atr[0] = sim_rx_data;
/* receive interface char */
rx_ptr = 1;
interface_char_lvl = 0;
interface_char_map = buf.atr[0] >> 4; /* Y1 */
while (interface_char_map)
{
rx_len = sim_interface_char_len[ interface_char_map ];
SIM_ReceiveBuffer(&buf.atr[rx_ptr], rx_len);
if (sim_rx_status != SIM_STATUS_OK)
goto label_atr_stop;
interface_char_lvl++;
if (interface_char_lvl == 1)
{
if (interface_char_map & 0x08) /* TD1 */
protocol_type_T = sim_rx_data & 0x0F;
}
rx_ptr += rx_len;
if (interface_char_map & 0x08) /* check TDi */
interface_char_map = sim_rx_data >> 4; /* Yi+1 */
else
interface_char_map = 0;
}
/* receive historical char */
rx_len = buf.atr[0] & 0x0F;
if (rx_len != 0)
{
SIM_ReceiveBuffer(&buf.atr[rx_ptr], rx_len);
if (sim_rx_status != SIM_STATUS_OK)
goto label_atr_stop;
rx_ptr += rx_len;
}
/* receive TCK */
if (protocol_type_T != 0)
{
if (SIM_ReceiveByte() != SIM_STATUS_OK)
goto label_atr_stop;
buf.atr[ rx_ptr++ ] = sim_rx_data;
}
/* stop ATR */
label_atr_stop:
UART2_stop();
if (sim_rx_status != SIM_STATUS_OK)
{
label_open_driver_error:
SIM_CloseDriver();
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -