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

📄 cid.asm

📁 cid file. the prgram is used to get caller id
💻 ASM
📖 第 1 页 / 共 2 页
字号:

//.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 + -