📄 fm1702.asm
字号:
push acc
lcall ReadRC
orl a,b
mov b,a
pop acc
lcall WriteRC
ret
ClearBitMask:
push acc
lcall ReadRC
xch a,b
cpl a
anl a,b
mov b,a
pop acc
lcall WriteRC
ret
FlushFIFO:
mov a,#RegControl
mov b,#01h
lcall SetBitMask
ret
StartT2Timeout:
clr ET2 ; Disable Timer2 interrupt
clr TR2 ;
mov RCAP2H,#0ffh
mov RCAP2L,#0a4h
; RCAP2LH = 0xFFA4;
mov TH2,#0ffh
mov TL2,#0a4h
; T2LH = 0xFFA4;
mov T2CNTH,dph
mov T2CNTL,dpl
; CountDown = _50us;
clr FLAG_T2OUT
; T2IR = 0; // Reset timeout state
mov T2CON,#04
; T2CON = 0x04; // 16-bit auto-reload, clear TF2, start timer
setb ET2
setb TR2
ret
;}
StopT2Timeout:
clr ET2 ; Disable Timer2 interrupt
clr TR2 ;
; ET2 = 0; // disable Timer2 interrupt
mov T2CNTH,#0
mov T2CNTL,#0
; CountDown = 0;
mov T2CON,#0
; T2CON = 0x00; // 16-bit auto-reload, clear TF2, stop timer
clr FLAG_T2OUT
ret
;}
;/////////////////////////////////////////////////////////////////////////////
; Interrupt Handler TIMER2
;/////////////////////////////////////////////////////////////////////////////
;void TIMEOUTISR (void) interrupt 5 using 2 //Timer2 interrupt
Timer2Out:
push psw
push acc
push b
mov a,T2CNTH
orl a,T2CNTL
jz tmr2_1
mov a,T2CNTL
jz tmr20_1
dec T2CNTL
sjmp tmr2_ex
tmr20_1:
mov a,T2CNTH
jz tmr2_1
dec T2CNTH
mov T2CNTL,#0ffh
sjmp tmr2_ex
; if(CountDown)
; CountDown--; // Decrease timeout counter
tmr2_1:
setb FLAG_T2OUT
clr TR2
; if(!CountDown)
; {
; T2IR = 1; // Set timeout state
; TR2 = 0;
; }
tmr2_ex:
clr TF2
; TF2 = 0;
pop b
pop acc
pop psw
reti
;/****************************************************************************
;* *
;* Function: delay_50us *
;* *
;* Input: _50us *
;* Output: - *
;* *
;* Description: *
;* *
;* Time delay with a resolution of 50 us. *
;* *
;****************************************************************************/
;void delay_50us (uchar _50us)
Delay50us:
; \param A = delay times
; \return none
;
;{
mov TL2,#TL2_50us;
mov TH2,#TH2_50us;
mov RCAP2L,#TL2_50us;
mov RCAP2H,#TH2_50us;
; RCAP2LH = RCAP2_50us;
; T2LH = RCAP2_50us;
clr ET2
setb TR2
; ET2 = 0; // Disable timer2 interrupt
mov T2CON,#04h
; T2CON = 0x04; // 16-bit auto-reload, clear TF2, start timer
clr TF2
d50_0: jnb TF2,$
clr TF2
djnz acc,d50_0
; while (_50us--)
; {
; while (!TF2);
; TF2 = FALSE;
; }
clr TR2
; TR2 = FALSE;
ret
;}
;/****************************************************************************
;* *
;* Function: delay_1ms *
;* *
;* Input: _1ms *
;* Output: - *
;* *
;* Description: *
;* *
;* Time delay with a resolution of 1 ms. *
;* *
;****************************************************************************/
;void delay_1ms (uchar _1ms)
Delay1ms:
; \param A = delay times
; \return none
;
;{
mov TL2,#TL2_1ms;
mov TH2,#TH2_1ms;
mov RCAP2L,#TL2_50us;
mov RCAP2H,#TH2_50us;
; RCAP2LH = RCAP2_1ms;
; T2LH = RCAP2_1ms;
clr ET2
; ET2 = 0; // Disable timer2 interrupt
mov T2CON,#04h
; T2CON = 0x04; // 16-bit auto-reload, clear TF2, start timer
setb TR2
clr TF2
d1ms_0: jnb TF2,$
clr TF2
lcall ResetWDT
djnz acc,d1ms_0
; while (_1ms--)
; {
; while (!TF2);
; TF2 = FALSE;
; }
clr TR2
; TR2 = FALSE;
ret
;}
;/////////////////////////////////////////////////////////////////////
; M I F A R E M O D U L E R E S E T
;/////////////////////////////////////////////////////////////////////
; If the MF RC500 reset pin is connected to a dedicated 礐ontroller port pin,
; a reset can be performed. After each reset, the automatic interface
; recognition of the reader IC is activated. Both, resetting the reader IC
; and determining the interface is done by this function.
;FCT_PREF PcdReset(void);
; \param none
; \return A = status
;
PcdReset:
; char status = MI_OK;
clr RC500RST
mov a,#25
lcall Delay1ms
; delay_1ms(25); // wait for 25ms
; SleepMs(500); // wait
setb RC500RST
; READER_RESET; // reset RC500
mov a,#50
lcall Delay50us
; delay_50us(50); // wait for 2.5ms
; SleepMs(100); // wait
clr RC500RST
; READER_CLEAR_RESET; // clear reset pin
mov dptr,#42000
lcall StartT2Timeout
; start_timeout(42000); // count down with a period of 50 us
; // 42000 * 50 us = 2.1 s
; GT_vInitTmr(TIMER_3,0x87); // stop timer, count down with a period of 52 us
; T3IC = 0x00; // reset interrupt request
; GT_vLoadTmr(TIMER_3,0xAFFF); // 0x9FFF * 52 us = 2.1 s
; GT_vStartTmr(TIMER_3); // start timer
pr_00: mov a,#RegCommand
lcall ReadRawRC
anl a,#3fh
cjne a,#3fh,pr_001
sjmp pr_01
pr_001:
jb FLAG_T2OUT,pr_err
lcall ResetWDT
sjmp pr_00
; // wait until reset command recognized
; while (((ReadRawRC(RegCommand) & 0x3F) != 0x3F) && !T3IR);
pr_01: mov a,#RegCommand
lcall ReadRawRC
anl a,#3fh
jz pr_02
jb FLAG_T2OUT,pr_err
lcall ResetWDT
sjmp pr_01
; // while reset sequence in progress
; while ((ReadRawRC(RegCommand) & 0x3F) && !T3IR);
pr_02: lcall StopT2Timeout
; GT_vStopTmr(TIMER_3); // stop timeout counter
mov a,#RegPage
; mov b,#80
mov b,#00
lcall WriteRawRC
; mov a,#0
; lcall Delay1ms
mov a,#RegCommand
lcall ReadRawRC
jnz pr_03
mov a,#MI_OK
ret
pr_03:
mov a,#MI_INTERFACEERR
ret
pr_err: lcall StopT2Timeout
mov a,#MI_RESETERR
ret
; if (T3IR)
; {
; status = MI_RESETERR; // respose of reader IC is not correct
; T3IR = 0;
; }
; if (status == MI_OK)
; {
; WriteRawRC(RegPage,0x80); // Dummy access in order to determine the bus
; // configuration
; // necessary read access
; // after first write access, the returned value
; // should be zero ==> interface recognized
; if (ReadRawRC(RegCommand) != 0x00)
; {
; status = MI_INTERFACEERR;
; }
; else
; {
; // sequence is ok
; }
; }
;
; return status;
;}
;//////////////////////////////////////////////////////////////////////
;// W R I T E A P C D C O M M A N D
;///////////////////////////////////////////////////////////////////////
; This function provides the central interface to the reader module.
; Depending on the "cmd"-value, all necessary interrupts are enabled
; and the communication is started. While the processing is done by
; the reader module, this function waits for its completion.
;
; It's notable, that the data in the <em>send byte stream</em> is written
; to the FIFO of the reader module by the ISR itself. Immediate after
; enabling the interrupts, the LoAlert interrupt is activated.
;
; The ISR writes the data to the FIFO. This function is not directly involved
; in writing or fetching data from FIFO, all work is done by the
; corresponding ISR.After command completion, the error status is evaluated and
; returned to the calling function.
;char PcdSingleResponseCmd(unsigned char cmd,
; volatile unsigned char * send,
; volatile unsigned char * rcv,
; volatile MfCmdInfo * info);
; \param A = cmd
; \return A = status
PcdSingleResponseCmd:
;char PcdSingleResponseCmd(unsigned char cmd,
; volatile unsigned char* send,
; volatile unsigned char* rcv,
; volatile MfCmdInfo *info)
;{
; char status = MI_OK;
; char tmpStatus ;
; unsigned char lastBits;
; unsigned char irqEn = 0x00;
; unsigned char waitFor = 0x00;
; unsigned char timerCtl = 0x00;
mov b,r0
push b
mov b,r1
push b
mov b,r2
push b
mov r2,a
mov a,#RegIRqPinConfig
mov b,#03h
lcall WriteRC
; WriteIO(RegIRqPinConfig,0x03);
mov a,#RegInterruptEn
mov b,#7Fh
lcall WriteRC
; WriteRC(RegInterruptEn,0x7F); // disable all interrupts
mov a,#RegInterruptRq
mov b,#7Fh
lcall WriteRC
; WriteRC(RegInterruptRq,0x7F); // reset interrupt requests
mov a,#RegCommand
mov b,#PCD_IDLE
lcall WriteRC
; WriteRC(RegCommand,PCD_IDLE); // terminate probably running command
lcall FlushFIFO
; FlushFIFO(); // flush FIFO buffer
; // save info structures to module pointers
; MpIsrInfo = info;
; MpIsrOut = send;
; MpIsrIn = rcv;
; // initialising the ISR-Function pointer for mifare
; // protocol - do this after initialising the MpXXXX variables
; PcdIsrFct = SingleResponseIsr;
mov MfIrqSource,#0
; info->irqSource = 0x0; // reset interrupt flags
setb RC500INT_EN
; READER_INT_ENABLE;
; // depending on the command code, appropriate interrupts are enabled (irqEn)
; // and the commit interrupt is choosen (waitFor).
mov a,r2
; switch(cmd)
; {
cjne a,#PCD_IDLE,PSRC0_1
mov r0,#00h
mov r1,#00h
sjmp PSRC_1
; case PCD_IDLE: // nothing else required
; irqEn = 0x00;
; waitFor = 0x00;
; break;
PSRC0_1:
cjne a,#PCD_WRITEE2,PSRC0_2
mov r0,#11h
mov r1,#10h
sjmp PSRC_1
; case PCD_WRITEE2: // LoAlert and TxIRq
; irqEn = 0x11;
; waitFor = 0x10;
; break;
PSRC0_2:
cjne a,#PCD_READE2,PSRC0_3
mov r0,#07h
mov r1,#04h
sjmp PSRC_1
; case PCD_READE2: // HiAlert, LoAlert and IdleIRq
; irqEn = 0x07;
; waitFor = 0x04;
; break;
PSRC0_3:
cjne a,#PCD_LOADCONFIG,PSRC0_4
sjmp PSRC05_1
; case PCD_LOADCONFIG: // IdleIRq and LoAlert
PSRC0_4:
cjne a,#PCD_LOADKEYE2,PSRC0_5
sjmp PSRC05_1
; case PCD_LOADKEYE2: // IdleIRq and LoAlert
mov r0,#07h
mov r1,#04h
sjmp PSRC_1
PSRC0_5:
cjne a,#PCD_AUTHENT1,PSRC0_6
PSRC05_1:
mov r0,#05h
mov r1,#04h
sjmp PSRC_1
; case PCD_AUTHENT1: // IdleIRq and LoAlert
; irqEn = 0x05;
; waitFor = 0x04;
; break;
PSRC0_6:
cjne a,#PCD_CALCCRC,PSRC0_7
mov r0,#11h
mov r1,#10h
sjmp PSRC_1
; case PCD_CALCCRC: // LoAlert and TxIRq
; irqEn = 0x11;
; waitFor = 0x10;
; break;
PSRC0_7:
cjne a,#PCD_AUTHENT2,PSRC0_8
mov r0,#04h
mov r1,#04h
sjmp PSRC_1
; case PCD_AUTHENT2: // IdleIRq
; irqEn = 0x04;
; waitFor = 0x04;
; break;
PSRC0_8:
cjne a,#PCD_RECEIVE,PSRC0_9
mov a,#RegBitFraming
lcall ReadRC
swap a
anl a,#0fh
cpl a
inc a
mov r0,#06h
mov r1,#04h
sjmp PSRC_1
; case PCD_RECEIVE:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -