📄 card.asm
字号:
*
.mmregs
.include constant.inc
.include c54.inc
.def card
.def IC_COLD_RST,IC_WARM_RST,COM_IC,R0_IC,W0_IC
.def select_a,select_b
.ref card_map,card_num,card_in_map
.ref X,Y,sta
.ref STLC ;CPU卡的命令中含有LC标记
.ref TOIC ;CPU卡通讯时数据流向标记
.ref CERR ;出错标记
.ref RECEIPT ;正确收到上位机命令标记
.ref REAA ;收到上位机发送的AA标记
.ref TC1 ;CPU卡的额外保护时间
.ref RENUM ;接收到上位机发送的字节数
.ref ERR ;错误代码
.ref BUFFER ;和上位机通讯时的数据缓冲区128byte
.sect "progsys"
*********************** card ****************************
*常数定义:
FAULT0 .set 0x80
FAULT2 .set 0x82
FAULT15 .set 0x8f
*宏定义:
CLR_CARD_RST .macro
ANDM #0x07,*(card_map)
PORTW *(card_map),CARD_DATA
.endm
SET_CARD_RST .macro
ORM #0x08,*(card_map)
PORTW *(card_map),CARD_DATA
.endm
CLR_CARD_SCK1 .macro
ANDM #0x0b,*(card_map)
PORTW *(card_map),CARD_DATA
.endm
SET_CARD_SCK1 .macro
ORM #0x04,*(card_map)
PORTW *(card_map),CARD_DATA
.endm
CLR_CARD_DA .macro
ANDM #0x0e,*(card_map)
PORTW *(card_map),CARD_DATA
.endm
SET_CARD_DA .macro
ORM #0x01,*(card_map)
PORTW *(card_map),CARD_DATA
.endm
CLR_CARD_LED .macro
ANDM #0x0d,*(card_map)
PORTW *(card_map),CARD_DATA
.endm
SET_CARD_LED .macro
ORM #0x02,*(card_map)
PORTW *(card_map),CARD_DATA
.endm
*测试是否有卡 有卡:TC=0 无卡TC=1
TEST_CARD_SW .macro
PORTR CARD_DATA,*(card_in_map)
BITF *(card_in_map),#0x02
NOP
NOP
.endm
TEST_CARD_DA .macro
PORTR CARD_DATA,*(card_in_map)
BITF *(card_in_map),#0x01
NOP
NOP
.endm
CARD_NUM_0 .macro
ST #0,*(card_num)
PORTW *(card_num),CARD_NUM
.endm
CARD_NUM_1 .macro
ST #1,*(card_num)
PORTW *(card_num),CARD_NUM
.endm
*宏定义结束
*********************************************************
card:
* CARD_NUM_0
TEST_CARD_SW
BC card1,TC
CLR_CARD_LED
B card_exit
card1: SET_CARD_LED
card_exit:
RET
**************************选择A卡子程序****************
select_a:
CARD_NUM_0
RET
**************************选择B卡子程序*******************
select_b:
CARD_NUM_1
RET
******************** 复位CPU卡子程序 *********************
*入口:AR7指定存放复位应答信息的起始内存地址
*出口:IC_SBUF=复位应答信息,AR7应答信息的字节数
*TC1和卡通讯时的额外保护时间
*不充许中断
*冷复位
*========================================================
IC_COLD_RST:
SSBX INTM ;关中断
ST #0,*(X) ;X=0冷复位
*--------------------------------------------------------
*冷复位前CPU卡的各引脚应处于低电平
CLR_CARD_RST
CLR_CARD_SCK1
CLR_CARD_DA
STM #BUFFER,AR7
rpt #(128-1)
ST #0,*AR7+
STM #BUFFER,AR7
nop
*--------------------------------------------------------
SET_CARD_SCK1 ;使能时钟
rpt #(2000-1) ;20us
nop
SET_CARD_DA ;i/o=1
SET_CARD_LED
CALL D42KCLK ;延时42000clk
CLR_CARD_LED
SET_CARD_RST ;RST=1
B IC_RST
*--------------------------------------------------------
*热复位
IC_WARM_RST:
SSBX INTM ;关中断
ST #01,*(X) ;X=0热复位
SET_CARD_SCK1 ;使能时钟
SET_CARD_DA ;i/o=1
CLR_CARD_RST
CALL D42KCLK ;延时42000clk
SET_CARD_RST ;RST=1
*-------------------------------------------------------
*读复位应答信息
IC_RST: CALL D400CLK ;延时400clk
MVMM AR7,AR0
STM #(2-1),AR2
CALL R0_IC
CMPM *(CERR),#0
NOP
NOP
BC IC_RST1,TC ;CERR=0 无错误
CMPM *(X),#0
NOP
NOP
BC IC_WARM_RST,TC ;X=0是冷复位,如果失败,再启动一次热复位
RSBX INTM ;复位失败,开中断,返回
RET
*--------------------------------------------------------
IC_RST1:
ST #1,*(CERR)
MVMM AR7,AR0
CMPM *AR0+,#0x3b
BC IC_RST5,NTC
LD *AR0,A
MVDK *AR0,*(X)
AND #0x0f,A
ANDM #0xf0,*(X)
CMPM *(X),#0x60
ADD #1,A ;应该+2,但banz #(x-1)
XC 2,NTC
ADD #1,A
STL A,*(Y)
IC_RST2:
STLM A,AR2
NOP
LDM AR7,A
ADD #2,A
STLM A,AR0
CALL R0_IC
BITF *(CERR),0x01
BC IC_RST5,TC
LDM AR7,A
ADD #1,A
STLM A,AR0
NOP
nop
nop
BITF *AR0,#0x10
BC IC_RST3,NTC
LD *AR0+,A ;INC AR0
IC_RST3:
LD *AR0+,A ;INC AR0
LD *AR0+,A ;INC AR0
NOP
NOP
CMPM *AR0,#0xff
MVDK *AR0,*(TC1)
BC IC_RST4,NTC
ST #0,*(TC1)
IC_RST4:
ADDM #3,*(Y) ;本应该+2,但以前应该加2的时候为了BANZ却只加了1.
MVDM *(Y),AR7
ST #0,*(CERR)
IC_RST5:
RSBX INTM
RET
*********************************************************
D400CLK:RPT #(13000-1)
NOP
RET
*********************************************************
D42KCLK:STM #(28-1),AR5
D42CLK1:RPT #(50000-1)
NOP
BANZ D42CLK1,*AR5-
RET
*
*
***************读CPU卡一个字节,结果在A中****************
READ_1BYTE:
STM #1,AR1 ;读一个字节标志
STM #1,AR2 ;读的字节数=1
B R0_IC0
*
*
***********************读CPU卡数据***********************
*AR0:指定返回字节起始地址
*AR2:指定读的字节数
*TOIC =0表明刚完成的操作是数据从卡到CPU
*CERR =0/1读成功或失败
*========================================================
R0_IC: STM #0,AR1 ;清读一个字节标志
R0_IC0: ST #0,*(TOIC)
ST #0x01,*(CERR)
R0_IC1: STM #(3-1),AR3 ;错误时重读的次数3次
LD #0,A
STM #(600-1) ,BRC
RPTB #(R0_IC3-1)
TEST_CARD_DA
BC R0_IC4,NTC
RPT #(2480-1) ;2480 * 10ns=24.8us
NOP
R0_IC3: RET
*--------------------------------------------------------
*检测到起始位后延时0.5ETU,之后,
*每隔1个ETU读取一位数据,共读8位.
*48M\16=3M ETU = 0.33333us * 372 = 124us
R0_IC4: STM #(8-1),AR6 ;读的位数,共8位
ST #0,*(X) ;检测奇偶校验
LD #0,A
RPT #(6200-1)
NOP ;延时62us
R0_IC5: RPT #(12400-1)
NOP
LD A,-1,A ;A=A>>1
TEST_CARD_DA
BC R0_IC5_1,NTC
XORM #1,*(X)
ADD #0x80,A ;if card_da=1 then A=A+1
R0_IC5_1:
BANZ R0_IC5,*AR6-
stl A,*(sta) ;test
BANZ R0_IC6,*AR1
STL A,*AR0
*--------------------------------------------------------
*判断奇偶校验位
R0_IC6: RPT #(12400-1)
NOP
TEST_CARD_DA
BC R0_IC6_1,NTC
XORM #1,*(X)
R0_IC6_1:
NOP
NOP
BITF *(X),0x01
NOP
NOP
BC R0_IC_ERR,TC ;奇偶校验错误x=1
BANZ R0_IC9,*AR1
LD *AR0+,A ;INC AR0
R0_IC9: RPT #(12400-1)
NOP
BANZ R0_IC1,*AR2- ;奇偶校验正确,读下一字节
ST #0,*(CERR) ;清除错误标志
RET
*-------------------------------------------------------
*奇偶校验出错处理
*CPU把CARD_DA拉低2个ETU后再置高,并重读此字节,最多重复3次
R0_IC_ERR:
BANZ R0_IC_ERR1,*AR3-
RET
R0_IC_ERR1:
RPT #(6200-1)
NOP
CLR_CARD_DA
RPT #(24800)
NOP
SET_CARD_DA
B R0_IC1
*
*
******************* 写CPU卡子程序 ***********************
*写CPU卡子程序 T=0模式
*入口:AR0=要写入的数据的起始地址
* AR2=要写入的字节数
*出口:TOIC=1表明刚完成的操作是数据从终端到CPU卡
* CERR=0/1写成功或失败
*占用:AR0,AR2,AR3,AR4,AR5,AR6,A
W0_IC: ST #1,*(CERR)
LD *AR2-,A ;DEC AR2
BITF *(TOIC),0x01
BC W0_IC1,TC
*相反方向的保护时间。设置为16或20个ETU
RPT #(49600-1) ;124us*4=496us
NOP
RPT #(49600-1) ;124us*4=496us
NOP
RPT #(49600-1) ;124us*4=496us
NOP
RPT #(49600-1) ;124us*4=496us
NOP
W0_IC0: ST #1,*(TOIC) ;置为写标记
STM #(3-1),AR3
SET_CARD_DA
W0_IC1: STM X,AR4 ;得到该数的奇偶位
LD *AR0,A
ST #0,*AR4
STM #(8-1),BRC
RPTB W0_IC2-1
ROR A ;A循环右移
NOP
NOP
XC 2 ,C
XORM #1,*AR4
NOP
NOP
W0_IC2: LD *AR0,A
OR #0x0f00,A
BITF *(X),0x01
NOP
NOP
XC 2,NTC
AND #0x0eff,A ;奇偶位置0
LD A,1,A ;得到起始位0
STM #(10-1),BRC
RPTB W0_IC5-1
ROR A
BC W0_IC3,C
CLR_CARD_DA
B W0_IC4
W0_IC3: SET_CARD_DA
W0_IC4: RPT #(12400-1)
NOP
*-----------------------------------------------------
*在第11个ETU时读取卡的数据线状态。
W0_IC5: RPT #(600-1)
NOP
SET_CARD_DA
RPT #(12400-1)
NOP
TEST_CARD_DA
RPT #(37200-1)
NOP ;3 ETU保护时间
*------------------------------------------------------
*如果卡接收正确,则发送下一字节,如果错误再重发此字节,最多重发3次
BC W0_IC6,TC
BANZ W0_IC1,*AR3-
RET ;失败返回
W0_IC6: LD *AR0+,A ;INC AR0
BANZ W0_IC1,*AR2-
ST #0,*(CERR)
RET ;成功返回
*************************DSP 与CPU卡通信子程序**********
*入口:AR7:命令缓冲区入口地址
*出口:AR7:应答数据字节数
COM_IC: RSBX INTM
MVMM AR7,AR0
STM #5,AR2
CALL W0_IC
CMPM *(CERR),#0
BC COM_IC1,TC ;CERR=0写成功
*-------------------------------------------------------
*读过程字:
COM_IC1:STM #BUFFER,AR0
STM #(2-1),AR2 ;READ 1 BYTE
CALL R0_IC
*-------------------------------------------------------
RSBX INTM
RET
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -