Требуется программист в Зеленограде
- обработка данных с датчиков; ColdFire; 40 тыс. e-mail:jobsmp@pochta.ru |
;Decoder module
;----------------------------------------------------------------------------
;Constantes:
.equ FCLK = 16000000 ;Fclk, Hz
.equ FOUT = 125 ;output frequency, kHz
.equ BYTC = 11 ;data byte count
.equ BITC = 5 ;data bit count
.equ dMask = 0b00011111 ;data byte mask
.equ sSymb = 0b0000000111111111 ;syncro symbol
.equ sMask = 0b0000001111111111 ;syncro symbol mask
.equ MIN1T = 58 ;64 - 10%
.equ NOM1T5 = 96 ;64 + 1/2 * 64
.equ MAX2T = 141 ;128 + 10%
;Decoder phases (dPhase values):
.equ pOff = 0 ;off
.equ pSync = 1 ;find syncronization
.equ pData = 2 ;get data
;----------------------------------------------------------------------------
;Derivated constantes:
.equ T1DIV = (((FCLK/FOUT)/200)+5)/10 ;CK/1
.if T1DIV > MAXWORD
.error "out of range constant"
.endif
;----------------------------------------------------------------------------
.DSEG ;Data segment
dBuff: .byte BYTC ;data buffer
;----------------------------------------------------------------------------
.CSEG ;Code segment
.equ Decod = PC
;----------------------------------------------------------------------------
;Interrupt Vectors:
.org OC1Aaddr
rjmp FInt ;Timer1 OC vector
.org Decod
;----------------------------------------------------------------------------
;Decoder init:
iDec: ldi temp,(1<<COM1A1) | (1<<COM1A0) | (1<<COM1B1)
; ldi temp,0
out TCCR1A,temp ;
ldi temp,(1<<WGM12) | (1<<CS10)
out TCCR1B,temp ;CTC, CK/1
ldi temp,byte2(T1DIV-1)
out OCR1AH,temp ;compare register load
ldi temp,byte1(T1DIV-1)
out OCR1AL,temp
in temp,TIMSK
ori temp,(1<<OCIE1A)
out TIFR,temp ;clear pending interrupts
out TIMSK,temp ;output compare interrupt enable
ldi dPhase,pSync
clr dSyncL
clr dSyncH
ret
;----------------------------------------------------------------------------
;Decode routine:
;Input: NowIn
;Out: dBuff
mDec: stbr Flags,NowIn
Skip_if_Port_DecIn_0 ;sample DecIn (inverted!)
clbr Flags,NowIn
bbrs Flags,NowIn,In1 ;check for transition
In0: bbrc Flags,PreIn,SkipT ;no changes
rjmp YesTr
In1: bbrs Flags,PreIn,SkipT ;no changes
;Check for timer:
YesTr: cpi dTimer,MIN1T
brlo SkipT ;skip early transition
cpi dTimer,MAX2T
brlo GetSyn
ldi dPhase,pSync ;too late transition
rjmp NewTm
;Get synchronization:
GetSyn: cpi dPhase,pSync
brne GetDat
cpi dTimer,NOM1T5
brsh gets1 ;dTimer > NOM1T5
bbrc Flags,Half,gets1 ;dTimer < NOM1T5
clbr Flags,Half
rjmp NewTm
gets1: stbr Flags,Half
clc
sbrc Flags,NowIn
sec
rol dSyncL
rol dSyncH
andi dSyncL,byte1(sMask)
andi dSyncH,byte2(sMask)
cpi dSyncL,byte1(sSymb)
brne NewTm
cpi dSyncH,byte2(sSymb)
brne NewTm
Port_Sync_1
ldi dPhase,pData
clr dCnt
clr dSyncL
clr dSyncH
Port_Sync_0
rjmp NewTm
;Get data:
GetDat: cpi dTimer,NOM1T5
brsh getd1 ;dTimer > NOM1T5
bbrc Flags,Half,getd1 ;dTimer < NOM1T5
clbr Flags,Half
rjmp NewTm
getd1: stbr Flags,Half
cpi dPhase,pData+BYTC
brsh NewTm
ldy dBuff-pData
add YL,dPhase
adc YH,dPhase
sub YH,dPhase
ld temp,Y
clc
sbrc Flags,NowIn
sec
rol temp
andi temp,dMask
st Y,temp ;save data
inc dCnt
cpi dCnt,BITC ;bit count
brne NewTm
clr dCnt
inc dPhase ;new byte
NewTm: bst Flags,NowIn
bld Flags,PreIn
clr dTimer
SkipT: ret
;----------------------------------------------------------------------------
;Check parity:
;Out: C=1 if parity error
CheckP: ldi Cnt,BYTC-1
ldy dBuff
nrr: ldi XL,0 ;check parity for rows 1..10
ld temp,Y+
sbrc temp,4
inc XL
sbrc temp,3
inc XL
sbrc temp,2
inc XL
sbrc temp,1
inc XL
sbrc temp,0
inc XL
andi XL,0x01
brne PErr
dec Cnt
brne nrr
ldi Cnt,BYTC ;check parity for col 1
ldy dBuff
ldi XL,0
nra: ld temp,Y+
sbrc temp,4
inc XL
dec Cnt
brne nra
andi XL,0x01
brne PErr
ldi Cnt,BYTC ;check parity for col 2
ldy dBuff
ldi XL,0
nrb: ld temp,Y+
sbrc temp,3
inc XL
dec Cnt
brne nrb
andi XL,0x01
brne PErr
ldi Cnt,BYTC ;check parity for col 3
ldy dBuff
ldi XL,0
nrc: ld temp,Y+
sbrc temp,2
inc XL
dec Cnt
brne nrc
andi XL,0x01
brne PErr
ldi Cnt,BYTC ;check parity for col 4
ldy dBuff
ldi XL,0
nrd: ld temp,Y+
sbrc temp,1
inc XL
dec Cnt
brne nrd
andi XL,0x01
brne PErr
lds temp,dBuff+BYTC-1 ;check stop bit
andi temp,0x01
brne PErr
clc ;clear error flag
rjmp POk
PErr: sec ;set parity error flag
POk: ret
;----------------------------------------------------------------------------
;Timer interrupt:
FInt: in xSreg,SREG
push temp
;Update Out_P and Out_N:
Skip_if_Port_Out_P_0
rjmp Ph1
Ph0:
ldi temp,(1<<COM1A1) | (1<<COM1A0) | (1<<COM1B1)
out TCCR1A,temp
rjmp PhX
Ph1:
ldi temp,(1<<COM1A1) | (1<<COM1B0) | (1<<COM1B1)
out TCCR1A,temp
PhX:
;Advance decoder timer:
cpi dTimer,MAX2T
breq dT0
inc dTimer
dT0:
;Advance wiegand rate timer:
dec wTimer
brne wT0
ldi temp,WRT
mov wTimer,temp
stbr Flags,wRate
wT0:
pop temp
out SREG,xSreg
reti
;----------------------------------------------------------------------------