⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iccpdir.c.bak

📁 mifarea卡程序mifarea卡程序mifarea卡程序
💻 BAK
📖 第 1 页 / 共 2 页
字号:
/****************************
 *    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 	(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 + -