📄 iccpdir.c
字号:
/****************************
* iccpdir.c *
* Designe by 刘俐训 *
* T = 0 for ic card *
* Sync card *
* last update: 04-13-2007 *
****************************/
#include <reg52.h>
#include "stimer.h"
#include "string.h"
#include "uart.h"
#include "icc.h"
#include <v51rx2.h>
#include "intrsc.h"
//#include <wdt.h>
#define DEBUG_ICC 0
#define ICCIO P3_3
#define ICCRST P3_4
#define USERRST P2_0
#define ICCUSERCLKC P1_1
#define ICCUSERCLS P2_5
#define ICCUSEROVLD P2_6
#define ICCUSEREJECT P1_4
#define ICCUSERSCLK P1_2 // sync clk of user card
#define ICCUSERVCCC P2_1
#define ICCA0 P1_6
#define ICCA1 P1_5
#define ICCINH P1_7
#define INFOLEN 176
#ifndef enable
#define disable() EA = 0
#define enable() EA = 1
#endif
#define IccEnable(); IE1 = 0; EX1 = 1;
#define IccDisable(); EX1 = 0;
#define StartSend(); TxNotRx = 1;\
ICCIO = 0;
typedef struct _ICCATTR
{
unsigned char etu : 2; // baudrate, 00:9600, 01:38400, 10: onchip9600, 11: Onchip38400
unsigned char autob : 1; // auto baudrate or not
unsigned char dir : 1; // pdir or ndir
}ICCATTR;
static code unsigned char IccEtu[4] = {248, 62, 192, 48};
static ICCATTR attr[4] = {{0,1,1}, {0,1,1}, {0,1,1}, {0,1,1}};
static unsigned int data TIME_OUT_MS = 50; /* 默认超时时间是50毫秒 */
// these parameters are calculated from ETU
static unsigned int data ETU = 62; //248; // 372 * 4 / 12 = 124 (cycles)
static unsigned char data RLD = 256 - 62; // bit period
static unsigned char data TxRLDStart = 256 - 62 + 30; // the 1st bit period
static unsigned char data RxRLDStart = 256 - 62 - 31 + 60; // the 1st bit period
static unsigned char data RxBits = 8;
// data direction
static bit dir = 1; // pdir
// flag of reseting card
static bit fReset = 0;
// current card id
static unsigned char CardId;
/*********************************************************************/
void iccgetputonebit(void); // call in the user timer interrupt for every bit
/*********************************************************************/
#ifndef SSBUF_SIZE
#define SSBUF_SIZE 64
#endif
static unsigned char idata IBUF[SSBUF_SIZE];
static unsigned char data ibufputidx=0;
static unsigned char data ibufgetidx=0;
static bit TxNotRx = 0;
static bit GetInputData( unsigned char *addr);
// calculate ETU, RLD and so on.
static void IccInitETU(unsigned int etu);
/*********************************************************************/
// these parameters are prepared for the bit interrupt functions
static unsigned char data mycharp;
static unsigned char data parityerror;
static unsigned char data parityerrorcnt;
static unsigned char data bitcounter;
static unsigned char data endflag;
static volatile bit RxWorking = 0;
static volatile bit TxParity = 0;
void iccgetputonebit(void)
{
bit bioport;
if(TxNotRx)
{
if(endflag)
{
if(endflag == 1)
{
ICCIO = 1; // stop parity bit
endflag ++;
}
else
{
parityerror = ~ICCIO;
TxNotRx = 0;
DiUserTimer();
IccEnable();
}
}
else if(!bitcounter)
{
ICCIO = TxParity;
endflag = 1;
}
else
{
if(dir)
mycharp >>= 1;
else
mycharp <<= 1;
ICCIO = CY;
bitcounter --;
}
return;
}
else
{
bioport = dir ? ICCIO : ~ICCIO; // 首先取得端口数据,保证时间准确
if(parityerror)
{
if(parityerror == 1) // parity error bit start
{
ICCIO = 0; // show error
parityerror ++;
}
else // parity error bit end
{
ICCIO = 1;
parityerror = 0;
DiUserTimer(); // disable user timer interrupt
IccEnable();
RxWorking = 0;
}
return;
}
// if(!endflag)
if(bitcounter)
{
if(dir)
{
/*
mycharp >>= 1;
if(bioport)
mycharp |= 0x80;
*/
ACC = mycharp;
CY = bioport;
#pragma asm
RRC A;
#pragma endasm
mycharp = ACC;
}
else
{
/*
mycharp <<= 1;
if(bioport)
mycharp |= 0x01;
*/
ACC = mycharp;
CY = bioport;
#pragma asm
RLC A;
#pragma endasm
mycharp = ACC;
}
bitcounter --; /////////////////////////
return;
}
ACC = mycharp;
if(P == bioport) /* 校验正确 */
{
FillBuf:
if(ibufputidx != ibufgetidx-1) // ;
{ // |
if( (ibufputidx != SSBUF_SIZE-1) || (ibufgetidx != 0) ) // |
{ // |
IBUF[ibufputidx++] = mycharp; // > fill buf
if(ibufputidx == SSBUF_SIZE) // |
ibufputidx = 0; // |
} // |
} // /
DiUserTimer(); // disable user timer interrupt
IccEnable();
RxWorking = 0;
// clear reseting flag
fReset = 0;
return;
}
// 校验不正确,首先看是否是复位应答的开始字节TS
if(fReset && (mycharp == 0x03))
{
dir = 0; // 反向协议
mycharp = 0x3f;
goto FillBuf;
}
// 设校验错误标志并计数
// P2_0 = 1;/////////////////////////////////////////////////////////////////////////////////////////////////////////
parityerror = 1;
parityerrorcnt ++;
// clear reseting flag
fReset = 0;
return;
}
}
void TxRxdata(void) interrupt IE1_VECTOR using 3 //2
{
if(TxNotRx)
{
// do nothing
}
else
{
InitUserTimer(RLD, RxRLDStart);
// mycharp = 0x80;
bitcounter = RxBits;
RxWorking = 1;
IccDisable(); // EX1 = 0; // 禁止中断
parityerror = 0; // clear parity error flag
endflag = 0;
}
}
static bit GetInputData( unsigned char *addr )
{
if( ibufgetidx == ibufputidx )
{
return 0; //buf empty
}
else
{
*addr = IBUF[ibufgetidx++];
if(ibufgetidx == SSBUF_SIZE)
ibufgetidx = 0;
return 1;
}
}
static void IccInitETU(unsigned int etu)
{
ETU = etu;
RLD = 256 - ETU;
TxRLDStart = RLD + 30;
if(etu >= 170)
{
RxRLDStart = RLD + (ETU >> 1) + 60;
RxBits = 9;
}
else
{
RxRLDStart = RLD - (ETU >> 1) + 60;
RxBits = 8;
}
}
void IccSelect(unsigned char cardid)
{
// inhabit
ICCINH = 1;
// backup card id
CardId = cardid & 0x03;
// switch to specified card
if(cardid & 0x01)
ICCA0 = 1;
else
ICCA0 = 0;
if(cardid & 0x02)
ICCA1 = 1;
else
ICCA1 = 0;
// habit
ICCINH = 0;
// init card etu and direciton
IccInitETU(IccEtu[attr[cardid].etu]);
dir = attr[cardid].dir;
}
int IccRead( char *buf, int len )
{
int data i;
unsigned int data starttime;
for(i=0; i<len; i++)
{
starttime = GetTickCount();
while(!GetInputData(buf+i))
{
if(GetTickCount() - starttime >= TIME_OUT_MS)
return i;
}
}
return i;
}
int IccWrite(char * buf, int len)
{
int data i;
unsigned int data starttime;
unsigned char data trytimes = 3;
for(i=0; i<len; i++)
{
starttime = GetTickCount();
SoftDelayCyl(ETU); // delay 2 etu
while(RxWorking)
{
while(RxWorking) // 重复两次是为了防止接收校验出错的重传
{
if(GetTickCount() - starttime >= TIME_OUT_MS)
{
#if DEBUG_ICC
ComWrite("\xff", 1);
delay(3);
#endif
return i;
}
}
SoftDelayCyl(ETU); // delay 4 etu
}
SoftDelayCyl(ETU); // delay 2 etu
starttime = GetTickCount();
mycharp = buf[i];
///////////////////////////////////
// initialize for current byte
// get parity bit
ACC = mycharp;
TxParity = P;
if(!dir)
{
mycharp = ~mycharp;
TxParity = ~TxParity;
}
// clear parity error
parityerror = 0;
// clear endflag
endflag = 0;
// set bit counter
bitcounter = 8;
// disable receive interrupt
IccDisable(); // EX1 = 0;
disable(); // enter critical section
InitUserTimer(RLD, TxRLDStart);
StartSend();
enable(); // leave critical section
while(TxNotRx)
{
if(GetTickCount() - starttime >= TIME_OUT_MS)
{
TxNotRx = 0;
#if DEBUG_ICC
ComWrite("\xee", 1);
delay(3);
#endif
return i;
}
}
if(parityerror)
{
trytimes --;
if(!trytimes)
{
#if DEBUG_ICC
ComWrite("\xdd", 1);
delay(3);
#endif
return i;
}
else
i --;
}
//SoftDelayCyl(ETU); // delay 2 etu
}
return i;
}
void IccClear(void)
{
ibufputidx = ibufgetidx;
RxWorking = 0;
TxNotRx = 0;
ICCIO = 1; // 输入状态
// if smart card
IccEnable();
// else do nothing
}
/*** set time out time in receiving a char from sam ***/
void IccSetTimeout(unsigned int ms)
{
TIME_OUT_MS = ms;
}
int IccOpen(char *buf) // ICC_INFO *info)
{
unsigned char data i, j;
unsigned char data format;
unsigned char data mylrc;
unsigned char data CWI, BWI;
unsigned char data inchar;
unsigned int data oldtmo;
unsigned char data nhistory;
if(0x03 == CardId)
{
ICCUSERSCLK = 0;
ICCUSERCLKC = 1;
}
ICCIO = 1;
mylrc = 0;
// info->protocolid = 0;
// info->infolen = INFOLEN;
oldtmo = TIME_OUT_MS;
TIME_OUT_MS = 1200;
IccEnable();
for(j=0; j<4; j++)
{
parityerrorcnt = 0;
attr[CardId].dir = 1;
dir = 1;
if(0x03 == CardId)
{
delay(10);
USERRST = 0;
delay(10);
IccClear();
fReset = 1;
USERRST = 1;
}
else
{
delay(10);
ICCRST = 0;
delay(10);
IccClear();
fReset = 1;
ICCRST = 1;
}
i=IccRead(buf, 1); // TS
if (i < 1)
{
if(parityerrorcnt && attr[CardId].autob)
{
attr[CardId].etu ++;
IccInitETU(IccEtu[attr[CardId].etu]);
continue;
}
else
{
TIME_OUT_MS = oldtmo;
return 0;
}
}
else if(buf[0] == 0x3b)
{
break;
}
else if(buf[0] == 0x3f)
{
attr[CardId].dir = dir;
break;
}
else if(attr[CardId].autob && (j < 3))
{
attr[CardId].etu ++;
IccInitETU(IccEtu[attr[CardId].etu]);
continue;
}
else
{
TIME_OUT_MS = oldtmo;
return 0;
}
}
mylrc ^= buf[0];
j = 1;
i=IccRead(&format, 1); // TO /* T=0: format=0x69, T=1: 0xe9 */
if (i < 1)
{
TIME_OUT_MS = oldtmo;
return j;
}
mylrc ^= format;
buf[j++] = format;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -