📄 cid.asm
字号:
//.define BoxDetDtmf 1
.public ShareArea1
.public ShareArea2
//----------------------------------------------------------------------------------------
.OSRAM
StartOfSram:
StartOfCidSram:
CidFlag: .DW 0;
// fedc ba98 7654 3210
// |||| |||| |||| ||||
// CID is FSK --+||| |||| |||| |||+-- x
// CID is DTMF ---+|| |||| |||| ||+--- x
// Enable DTMF decoder ----+| |||| |||| |+---- x
// Enable DTMF encoder -----+ |||| |||| +----- set if it is receiving CAS
// 2 DTMF frames are rx'ed -------+||| |||+------- FSK modulation
// 1 DTMF frame is rx'ed --------+|| ||+-------- x
// It's time to check DTMF ---------+| |+--------- Bias of AGC is stable
// All FSK data are rx'ed ----------+ +---------- The rx'ed checksum is wrong
//.const B_CASDetect = 0x0008;// b3=1, set if it is receiving CAS
.const B_AgcIsStable = 0x0040 // b6=1, the bias voltage of AGC is stable
.const B_ChksumErr = 0x0080 // b7=1, checksum is erroreous, error correction is a must
.const B_FskIsOver = 0x0100 // b8=1, all FSK data are rx'ed
.const B_DtmfReady = 0x0200 // set if it is time to check DTMF
.const B_1stDtmfFrame = 0x0400 // set if a DTMF is found in the previous
// checking time
.const B_MoreDtmfFrame = 0x0800 // the current DTMF has been received, don't
// care its residue. Hunt for the next DTMF
.const B_EncodeDtmf = 0x1000 // set if it is necessary to send DTMF
.const B_DecodeDtmfFsk = 0x2000 // set if it is necessary to receive DTMF
// * b14,b15 should be reserved for CID Type
// because it's frequently checked by 8KHz
// interrupt. b15 is used to reduce cycles.
.const B_CidIsDtmf = 0x4000 // * b14=0 - CID is not identified yet
// * 1 - CID is DTMF type
.const B_CidIsFsk = 0x8000 // * b15=0 - CID is not identified yet
// * 1 - CID is FSK type
//----------------------------------------------------------------------------------------
DtmfSampleCount:
FskCidState: .DW 0;
DtmfGainPower: .DW 0;
ShareArea1: .DW 61 DUP(0)
//----------------------------------------------------------------------------------------
.ORAM
//ShareArea2: .DW 343 DUP(0); //for SPT6605_Decode_V05J_20040723.lib
//ShareArea2: .DW 403 DUP(0); //for SPT6605_Decode_050517.lib
//ShareArea2: .DW 93 DUP(0); //for GPTC6606 Europe
ShareArea2: .DW (93+32+1) DUP(0); //for GPTC6606 USA
.define GPTC6606
.ifndef GPTC6606
.const FskCidBuf = ShareArea2+34;
.else
.const FskCidBuf = ShareArea2+33;
.endif
.const FskData = ShareArea2+84;
.const B_FskDataReceived = 0x0100; // b8=1, set if it received FSK Byte
EndOfCidSram: .DW 0;
.if 0
.public TmpDtmfCidBufPtr;
.public TmpDtmfCidBuf;
.public TmpRxedDtmf;
.public TmpLastDtmf;
.public _TmpDtmfCidBufPtr;
.public _TmpDtmfCidBuf;
.public _TmpRxedDtmf;
.public _TmpLastDtmf;
TmpDtmfCidBufPtr: .DW 0;
TmpDtmfCidBuf: .DW 8 DUP(0);
TmpRxedDtmf: .DW 0;
TmpLastDtmf: .DW 0;
.const _TmpDtmfCidBufPtr = TmpDtmfCidBufPtr;
.const _TmpDtmfCidBuf = TmpDtmfCidBuf;
.const _TmpRxedDtmf = TmpRxedDtmf;
.const _TmpLastDtmf = TmpLastDtmf;
.endif
//============== DTMF Generator External Function ========================//
.external _F_EnableDtmfEncoder_SW;
.external _F_StopDtmf_SW;
//============== CID Decoder External Function ===========================//
.external _F_EnableCidDecoder;
.external _F_EnableBoxDetDTMF;
.external _F_DisableCidDecoder
.external _F_ClrTmpCidBuf;
.external _F_DtmfDecoder;
.if 1
.external _TmpDtmfCidBufPtr;
.external _TmpDtmfCidBuf;
.external DtmfFlag;
.endif
//----------------------------------------------------------------------------*/
.external _IRQ4;
.public _FIQ;
.public _IRQ0;
.public _IRQ1;
.public _IRQ2;
.public _IRQ3;
.public _IRQ5;
.public _IRQ6;
.public _IRQ7;
.public _BREAK;
.public _main;
//----------------------------------------------------------------------
.const RW_FskTotalByteCnt = ShareArea1;
.const RW_FskByteCnt = ShareArea1+1;
//----------------------------------------------------------------------
.const StackSize = 40
.const StackBottom = 0x03FF
.const StackTop = StackBottom - StackSize + 1
//----------------------------------------------------------------------
.RAM
RW_512HzTmr: .DW 0;
CidState: .DW 0;
RPtr_LcdDigit: .DW 0;
RW_Date: .DW 0;
RW_Time: .DW 0;
RPtr_FskByteIndex: .DW 0;
.const CW_LenOfCidBuf = 0x0008;
CidNumber: .DW 0;
RPtr_CidBuf: .DW 0;
SW_CidBuf: .DW CW_LenOfCidBuf DUP(0);
//----------------------------------------------------------------------
.include SPT6605.inc
.include Display.ASM
//----------------------------------------------------------------------
.Code
_main:
INT OFF; //Disable Interrupt
R1 = 0x55AA;
[P_WatchdogClr] = R1 // reset watchdog
R1 = 0;
[P_WakeUp] = R1;
[P_Int] = R1;
[P_IoaWakeUp] = R1;
R1 = B_NormalCpuClock;
[P_SystemClock] = R1;
r1 = 0x55aa; //clear Watchdog
[P_WatchdogClr] = r1;
sp = 0x03FF; //Initial stack
r1 = B_2Hz+B_128Hz+B_512Hz+B_8KHz+B_Enable32768+B_Strong32768;
[P_TimeBaseSet] = r1; //Initial TimeBaseSet
r1 = [P_WakeUpClr];
[P_WakeUpClr] = r1; //clear Wake Up Register
r1 = 0; //Set IOA0~IOA7 as input port
[P_IOA_Dir] = r1;
r1 = 0x00FF; //Set IOB0~7 as output port
[P_IOB_Dir] = r1;
r1 = 0xFF00; //Enable Internal Pull-High for IOA0~7
[P_IOA_PullR] = r1;
R1 = 0x00FF;
[P_IOC_Dir] = R1;
[P_IOD_Dir] = R1;
R1 = 0x0080; //B_HFO -> 0, B_Mute -> 0, B_DP -> 1
[P_IOB_Data] = R1;
R1 = 0;
[P_IOC_Data] = R1;
[P_IOD_Data] = R1;
[P_LineDetCtrl] = R1;
R1 = B_EnRiDet+0x0003;
[P_RiDet] = R1;
R1 = 0x0003;
[P_IOCD_Ctrl] = R1;
r2 = 0;
R1 = 0;
ClrRAMLoop:
[R1++] = R2;
CMP R1,0x03FF;
JBE ClrRAMLoop;
CALL F_ClrLcd;
r1 = 0x00cf; //Enable Lcd Display
[P_LcdCtrl] = r1;
R1 = [CidNumber];
CALL F_ShowCidNumber;
R1 = 2;
BP = Digit4;
CALL F_ShowDigit;
R1 = 0x000A;
BP = Digit5;
CALL F_ShowDigit;
R1 = 0x000A;
BP = Digit6;
CALL F_ShowDigit;
R1 = 5;
BP = Digit7;
CALL F_ShowDigit;
R1 = B_T2KHzInt;
[P_Int] = r1;
INT FIQ,IRQ; //Enable FIQ and IRQ
//----------------------------------------------------------------------
MainLoop:
R1 = 0x55AA;
[P_WatchdogClr] = R1 // reset watchdog
R2 = [P_IOD_Buf];
R2 &= 0xFFF3;
R1 = [CidFlag];
TEST R1,B_CidIsFsk;
JZ MainLoop_10;
R2 |= 0x0004;
MainLoop_10:
TEST R1,B_CidIsDtmf;
JZ MainLoop_15;
R2 |= 0x0008;
MainLoop_15:
[P_IOD_Data] = R2;
call F_DecodeCid
jmp MainLoop
//-----------------------------------------------------------------------
V_DecodeCid:
V_WaitCid: .DW F_WaitCid;
.const S_WaitCid = V_WaitCid - V_DecodeCid;
V_ReceiveCid: .DW F_ReceiveCid;
.const S_ReceiveCid = V_ReceiveCid - V_DecodeCid;
//-----------------------------------------------------------------------
F_DecodeCid:
R1 = [CidState];
R1 += V_DecodeCid;
PC = [R1];
PC = [R1];
//-----------------------------------------------------------------------
F_WaitCid:
.ifdef BoxDetDtmf
CALL _F_EnableBoxDetDTMF;
.else
R1 = 0x0800; //FSK reject power
R2 = 0x2000; //DTMF reject power
R3 = 0xFFFF; //0: Not detect DTMF
//Non Zero: detect DTMF
CALL _F_EnableCidDecoder
.endif
R1 = 6*512;
[RW_512HzTmr] = R1;
R1 = S_ReceiveCid;
[CidState] = R1;
RETF;
//-----------------------------------------------------------------------
F_ReceiveCid:
r1 = [CidFlag]
test r1,B_FskIsOver //Check if Have FSK signal and it is over
jz CheckDtmf;
goto ParseFskCid; //Yes, parse FSK data
CheckDtmf:
test r1,B_DtmfReady //Check if sample data of DTMF is ready
jz CheckIfTimeOut //No, check if CID time out
call _F_DtmfDecoder //Call decode function to get DTMF data
int off
r2 = [CidFlag]
r2 &= ~B_DtmfReady //clear flag of DTMF sample data ready
[CidFlag] = r2
int fiq,irq
test r1,0x0010; //Check if found DTMF Data
jz CheckIfFsk;
R1 = [CidFlag];
TEST R1,B_CidIsDtmf;
JZ DtmfFrameNotStart;
.ifdef BoxDetDtmf
R1 = 50*512/1000;
.else
R1 = 300*512/1000;
.endif
[RW_512HzTmr] = R1;
DtmfFrameNotStart:
RETF;
CheckIfFsk:
R1 = [CidFlag];
TEST R1,B_CidIsFsk;
JZ DtmfFrameNotStart;
R1 = 4*512;
[RW_512HzTmr] = R1;
RETF;
//----------------------------------------------------------------------
CheckIfTimeOut:
r1 = [RW_512HzTmr]
jnz DtmfFrameNotStart;
call _F_DisableCidDecoder;
R1 = [_TmpDtmfCidBufPtr];
JNZ ReceivedSomeNumber;
GoTo WaitNextCid;
ReceivedSomeNumber:
.ifdef BoxDetDtmf
R1 = [_TmpDtmfCidBuf];
R1 &= 0x000F;
BP = Digit13;
CALL F_ShowDigit;
CALL _F_ClrTmpCidBuf;
CALL _F_EnableBoxDetDTMF;
RETF;
.else
R1 = [_TmpDtmfCidBufPtr];
CMP R1,3;
JAE ReceivedOneCall;
GoTo WaitNextCid;
ReceivedOneCall:
call F_ClrLcd //clear LCD
R1 = [CidNumber];
R1 += 1;
[CidNumber] = R1;
CALL F_ShowCidNumber;
R1 = [_TmpDtmfCidBufPtr];
[RPtr_CidBuf] = R1;
BP = _TmpDtmfCidBuf;
R4 = SW_CidBuf;
R1 = [BP++];
[R4++] = R1;
R1 = [BP++];
[R4++] = R1;
R1 = [BP++];
[R4++] = R1;
R1 = [BP++];
[R4++] = R1;
R1 = [BP++];
[R4++] = R1;
R1 = [BP++];
[R4++] = R1;
R1 = [BP++];
[R4++] = R1;
R1 = [BP++];
[R4++] = R1;
CidBufOk:
r2 = 0; //display number index
bp = 0;
r1 = [RPtr_CidBuf]
cmp r1,0x000e
jae LcdDigitOk
bp = 0x000e
bp -= r1 //the position of 1st digit of Caller ID information
LcdDigitOk:
r1 = bp lsl 4
r1 -= bp // R1 = BP * 15
[RPtr_LcdDigit] = r1 // start of dots table
ShowDtmfLoop:
cmp r2,0x000e
jb CheckNextDigit;
GoTo WaitNextCid; // Max. 14 digits to show
CheckNextDigit:
cmp r2,[RPtr_CidBuf]
jae WaitNextCid; // all digits of the Caller ID are shown
r3 = r2 lsr 2
r3 += SW_CidBuf
r1 = [r3] // fetch data to display
test r2,0x0002
jz DisplayByteOk
r1 = r1 lsr 4
r1 = r1 lsr 4
DisplayByteOk:
test r2,0x0001
jz DisplayNibbleOk
r1 = r1 lsr 4
DisplayNibbleOk:
r1 &= 0x000f // got one nibble of a word
bp = [RPtr_LcdDigit] //Calculate display position
bp += r2 lsl 4 //of current number
bp -= r2
bp += Digit0
call F_ShowDigit
r2 += 0x0001 // index + 1;
jmp ShowDtmfLoop
.endif
//--------------------------------------------------------------
ParseFskCid:
CALL _F_DisableCidDecoder //Stop decoder
CALL F_ClrLcd //clear LCD
R1 = [CidNumber];
R1 += 1;
[CidNumber] = R1;
CALL F_ShowCidNumber;
CALL F_ParseFSK //Call FSK parse function
WaitNextCid:
R1 = 0;
[CidState] = R1;
retf;
//--------------------------------------------------------------
F_ParseFSK:
r1 = [CidFlag]
test r1,B_ChksumErr
jz StartParseFsk;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -