home *** CD-ROM | disk | FTP | other *** search
- page 132,63,1,1
- opt rc
- title 'CPFSK Modulation/Demodulation'
-
- ;***************************************************************
- ;* CPFSK.ASM -- CPFSK Modulation/Demodulation *
- ;* *
- ;* Provides interrupt based SSI handling, sample buffering and *
- ;* CPFSK modulation and demodulation. *
- ;* *
- ;* CPFSK demodulation is based on article *
- ;* Osborne, W., P., Lunz, M., B.: *
- ;* "Coherent and Noncoherent Detection of CPFSK", *
- ;* IEEE Trans. on Comm., Vol. 22, No. 8, August 1974 *
- ;* *
- ;* Symbol syncronization is based on article *
- ;* Glisic, S., G.: *
- ;* "Symbol Syncronization in Digital Communications *
- ;* Using Partial Response CPM signaling", *
- ;* IEEE Trans. on Comm., Vol. 37, No. 3, March 1989 *
- ;* *
- ;* This module uses registers as follows: *
- ;* r0 - general purpose (temporary use) *
- ;* r2 - input sample write pointer *
- ;* r3 - output sample read pointer *
- ;* r6 - input sample read pointer *
- ;* r7 - output sample write pointer *
- ;* *
- ;* Copyright (C) 1990, 1991 by Alef Null. All rights reserved. *
- ;* Author(s): Jarkko Vuori, OH2LNS *
- ;* Modification(s): *
- ;***************************************************************
-
- nolist
- include 'ioequlc'
- list
-
- section CPFSK
- xdef ssi_ini,modem_i
- xdef m_loop
- xref putbit,getbit
- xref m_cra,m_crb,m_tde,m_sr,m_tx
-
- org p:
-
- nolist
- include 'macros'
- list
-
- ; CPFSK sync parameters
- cM0 equ 4 ; random walk filter constant
- adjlen equ 32 ; ADC timing control lenght (in samples)
- analen equ 18 ; sample quality analyzing lenght
- trshold equ 16 ; sample quality decision treshold
-
- ; complex correlation (result in a1)
- ccorr macro
- ; s0 real -> b (real mode)
- conv 0,N,r6,r0,a
- move a1,x0 ; square result
- mpy x0,x0,a (r6)+n6
-
- ; s0 imaginary -> a (real mode)
- conv 0,N,r6,r0,b
- move b1,x0 ; square result
- macr x0,x0,a (r6)+n6
- endm
-
-
- ;****************************
- ;* SSI initialization *
- ;****************************
- ssi_ini
- ; initialize SSI,
- IF !DEBUG
- movep #$4000,x:m_cra ; 16 bit word
- movep #$f200,x:m_crb ; syncronous,word frame,ext clk
- ELSE
- movep #$4011,x:m_cra ; 16 bit word, abt. 19.2 ksamples/s
- movep #$f620,x:m_crb ; syncronous,word frame,ext clk
- ENDIF
-
- rts
-
-
- ;****************************
- ;* ADC & MODEM *
- ;* initialization *
- ;****************************
- modem_i
- ; program the A/D & D/A converter chip (TLC32044, master clock is 5.184MHz)
- ; enable A/D high-pass filter, disable loopback, disable AUX IN,
- ; select syncronous mode, select input span 3Vpp, insert sinx/x correction
- ; lowpass cutoff frequency at 3420Hz -> TA = 10 (SCF = 259kHz)
- ; sampling frequency is 7200Hz -> TB = 36
- ; unit sampling correction time 1.2uS -> TA' = 6
- pgmtlc %10101001,10,6,36
-
- ; sample handling,
- move #<insamp,r6
- move #<inN-N,n6
- move #<inN-1,m6
- move r6,r2
- move m6,m2
- movi <costab,x:<frqptr
- movi <f1,x:<frq
- movi <m,x:<rsamc
- movi 0,x:<samque
-
- move #<outsamp,r3
- move #<outN-1,m3
- move #<outsamp+1,r7
- move m3,m7
- movi <1,x:<xsamc
-
- ; symbol syncro logic,
- movi cM0,x:<rwalk
- movi analen,x:<anacnt
- movi 0,x:<goodcnt
-
- ; ADC command word
- movi 0,x:<adcnt
-
- rts
-
-
- ;****************************
- ;* Main Loop *
- ;****************************
- loop wait
- m_loop
-
-
- ;****************************
- ;* Receiver *
- ;****************************
- ; check if there are new samples received
- rec move r2,a
- move r6,x0
- cmp x0,a #<refs,r0
- jeq <xmit
-
- ; yes, there indeed are new samples, check if receiver enabled
- jset #ptt,x:<status,xmit
-
- ; yes, correlate with s0 signal
- ccorr
- move a1,x1
-
- ; correlate with s1 signal
- ccorr
-
- ; calculate result, limit to binary and queue received bits
- sub x1,a x:<samque,b1
- rol b (r6)-
- move b1,x:<samque
-
- ; check if one symbol (m samples) received
- move #>1,x0
- move #>-1,x1
- move x:<rsamc,b
- sub x0,b #>m,y0
- move b1,x:<rsamc
- jne <ssi_end
- move y0,x:<rsamc
-
- ; yes, analyze eye pattern (= symbol quality)
- ; (by checking that samples nearby decision sample are equal)
- ; (...|X****X|X****X|X**...)
- ; where X ignored samples
- ; * analyzed sample
- ; | symbol boundaries
- clr b #>%011110000,y0
- move x:<samque,b1
- and y0,b
- cmp y0,b #>%000000000,y0
- jeq <ssi_r0a
- cmp y0,b
- jne <ssi_r0b
-
- ssi_r0a move x:<goodcnt,b ; good quality symbol
- add x0,b
- move b1,x:<goodcnt
-
- ssi_r0b move x:<anacnt,b ; update analyses counter
- sub x0,b #>analen,y0
- move b1,x:<anacnt
- jne <ssi_rs
- move y0,x:<anacnt
-
- move x:<goodcnt,b ; make dcd decision
- move #>trshold,y0
- cmp y0,b
- jhs <ssi_r0c
- bclr #dcd,x:<status ; dcd off
- jcc <ssi_r0d
- dcdoff
- jsset #req,x:<status,kickx ; call persistence routine if needed
- jmp <ssi_r0d
- ssi_r0c bset #dcd,x:<status ; dcd on
- jcs <ssi_r0d
- dcdon
-
- ssi_r0d clr b
- move b,x:<goodcnt
-
- ; check if there are transitions (by analyzing the sample between decision samples)
- ; (...|00X00*|00X00*|00X...)
- ; where X decision sample
- ; * analyzed sample
- ; | symbol boundaries
- ssi_rs clr a #>1,x0
- move #>-1,x1
- jclr #0,x:<samque,ssi_l1
- jset #6,x:<samque,ssi_le
- ; 1x0
- move x0,a
- btst #3,x:<samque
- tcc x1,a
- jmp <ssi_le
- ssi_l1 jclr #6,x:<samque,ssi_le
- ; 0x1
- move x1,a
- btst #3,x:<samque
- tcc x0,a
-
- ; symbol syncro
- ssi_le tst a x:<rwalk,x0
- jeq <ssi_r4
- add x0,a #>2*cM0,x0
- jpl <ssi_r2
- ; retard sampling
- move #cM0,a1
- movib retard,x:<adccmd
- movib adjlen,x:<adcnt
- jmp <ssi_r3
- ;
- ssi_r2 cmp x0,a
- jle <ssi_r3
- ; advance sampling
- move #cM0,a1
- movib advance,x:<adccmd
- movib adjlen,x:<adcnt
- ;
- ssi_r3 move a1,x:<rwalk
-
- ; make symbol decision (with NRZ-S decoding)
- ssi_r4 move x:<prvrsym,x0
- move x:<samque,a1
- eor x0,a a1,x:<prvrsym
- not a
- move a1,x:<tmp
- btst #6,x:<tmp
- ; forward to the HDLC handler
- jsr <putbit
-
- ssi_end jmp <rec
-
-
- ;****************************
- ;* Transmitter *
- ;****************************
- ; check if we can calculate new samples
- xmit move r3,a
- move r7,x0
- cmp x0,a
- jeq <loop
-
- ; yes, check if the transmitter is on at all
- clr a #>1,x0
- jclr #ptt,x:<status,xmt2
-
- ; xmit mode, check if we have sent a whole symbol
- move x:<xsamc,a
- sub x0,a #>m,x0
- move a,x:<xsamc
- jne <xmt1
- move x0,x:<xsamc
-
- ; yes, check on what phase we are
- jset #xmt,x:status,xmt0
-
- ; training phase, send continuous preamble (zero pattern)
- andi #$fe,ccr
- jmp <morebit
-
- ; data phase, get a new bit to xmit
- xmt0 jsr <getbit
- jne <morebit
- ; there is no more bits to send, switch to receiving mode
- jsr <shutx
- andi #$fc,mr
-
- ; NRZ-S coding
- morebit rol a x:<prvxsym,x0
- not a
- eor x0,a #>f1,x0
- ror a a1,x:<prvxsym
-
- ; determine frequency
- move #<f0,b1
- tcs x0,b
- move b1,x:<frq
-
- ; send a new bit
- xmt1 move x:<frqptr,r0
- move x:<frq,n0
- move #<ent-1,m0
- move x:<gain,x1
- move x:(r0)+n0,x0 ; adjust output level
- move r0,x:<frqptr
- move #-1,m0
- mpyr x0,x1,a #>$fffc<<8,x0
- xmt2 and x0,a x:<adcnt,b
- tst b #>1,y0 ; check if we must adjust timing
- jeq <xmt3
- sub y0,b x:<adccmd,x0 ; yes, add converter chip control cmds
- or x0,a b1,x:<adcnt
- xmt3 move a,x:(r7)+
-
- scx_end jmp <xmit
-
-
-
- ;****************************
- ;* DATA - AREA *
- ;****************************
-
- org x:
-
- adccmd ds 1 ; ADC timing command
- adcnt ds 1 ; ADC timing command counter
- rsamc ds 1 ; receiver sample counter
- xsamc ds 1 ; xmitter sample counter
- samque ds 1 ; received sample queue
- prvrsym ds 1 ; previous received symbol
- prvxsym ds 1 ; previous xmitted symbol
- rwalk ds 1 ; random walk filter counter
- anacnt ds 1 ; signal quality analyzing lenght counter
- goodcnt ds 1 ; good symbol counter
- frqptr ds 1
- frq ds 1
-
- tmp ds 1
-
- org y:
-
- ; Complex reference signals
- ; m=6, bits=3
- refs
-
- ; s0
- ; real
- dc -0.02856969,-0.00150768,-0.01250000,-0.01099232
- dc 0.04106969,0.02500000,-0.04924039,0.00868241
- dc 0.04330127,-0.03830222,-0.01710101,0.05000000
- dc 0.00394950,-0.03165111,-0.00334936,-0.00815880
- dc -0.01212019,0.03750000
- ; imaginary
- dc -0.00249952,0.00855050,-0.00334936,0.03020114
- dc 0.01915111,-0.04330127,-0.00868241,0.04924039
- dc -0.02500000,-0.03213938,0.04698463,0.00000000
- dc -0.04514295,-0.00558094,0.01250000,-0.00296956
- dc 0.02599184,0.02165064
-
- ; s1
- ; real
- dc -0.01212019,-0.00815880,-0.00334936,-0.03165111
- dc 0.00394950,0.05000000,0.02500000,-0.02500000
- dc -0.05000000,-0.02500000,0.02500000,0.05000000
- dc 0.00394950,-0.03165111,-0.00334936,-0.00815880
- dc -0.01212019,0.03750000
- ; imaginary
- dc -0.02599184,0.00296956,-0.01250000,0.00558094
- dc 0.04514295,-0.00000000,-0.04330127,-0.04330127
- dc 0.00000000,0.04330127,0.04330127,0.00000000
- dc -0.04514295,-0.00558094,0.01250000,-0.00296956
- dc 0.02599184,0.02165064
-
- endsec
-
-
- ;****************************
- ;* M*BITS MODULO DATA *
- ;****************************
- section CPFSKData
- xdef N,m,inN,outN
- xdef insamp,outsamp
- xdef ent,f0,f1,costab
-
- org x:
-
- ; CPFSK demod parameters
- m equ 6 ; samples per symbol
- bits equ 3 ; number of observed bits
- N equ m*bits
- inN equ 32
- outN equ 8
-
- insamp ds inN
- outsamp ds outN
- ds 32-outN ; for modulo justification
-
- pi equ 3.141592654
- ent equ 36
- f0 equ 11
- f1 equ 6
- freq equ 2.0*pi/@cvf(ent)
-
- ; cosine lookuptable
- costab
- count set 0
- dup ent
- dc 0.999999*@cos(@cvf(count)*freq)
- count set count+1
- endm
-
- endsec
-
- end
-