📄 usb90s2313.asm
字号:
sts OutputBufferBegin+1,temp0 ;nahraj do vyst buffera
ComposeZeroAnswer:
ldi temp0,SOPbyte
sts OutputBufferBegin+0,temp0 ;SOP byte
rcall ToggleDATAPID ;zmen DATAPID
ldi temp0,0x00
sts OutputBufferBegin+2,temp0 ;CRC byte
sts OutputBufferBegin+3,temp0 ;CRC byte
ldi ByteCount,2+2 ;dlzka vystupneho buffera (SOP a PID + CRC16)
ret
;------------------------------------------------------------------------------------------
InitACKBufffer:
ldi temp0,SOPbyte
sts ACKBufferBegin+0,temp0 ;SOP byte
ldi temp0,ACKPID
sts ACKBufferBegin+1,temp0 ;ACKPID byte
ret
;------------------------------------------------------------------------------------------
SendACK:
push USBBufptrY
push bitcount
push OutBitStuffNumber
ldi USBBufptrY,ACKBufferBegin ;pointer na zaciatok ACK buffera
ldi ByteCount,2 ;pocet vyslanych bytov (iba SOP a ACKPID)
clr OutBitStuffNumber
rcall SendUSBBuffer
pop OutBitStuffNumber
pop bitcount
pop USBBufptrY
ret
;------------------------------------------------------------------------------------------
InitNAKBufffer:
ldi temp0,SOPbyte
sts NAKBufferBegin+0,temp0 ;SOP byte
ldi temp0,NAKPID
sts NAKBufferBegin+1,temp0 ;NAKPID byte
ret
;------------------------------------------------------------------------------------------
SendNAK:
push OutBitStuffNumber
ldi USBBufptrY,NAKBufferBegin ;pointer na zaciatok ACK buffera
ldi ByteCount,2 ;pocet vyslanych bytov (iba SOP a NAKPID)
clr OutBitStuffNumber
rcall SendUSBBuffer
pop OutBitStuffNumber
ret
;------------------------------------------------------------------------------------------
ComposeSTALL:
ldi temp0,SOPbyte
sts OutputBufferBegin+0,temp0 ;SOP byte
ldi temp0,STALLPID
sts OutputBufferBegin+1,temp0 ;STALLPID byte
ldi ByteCount,2 ;dlzka vystupneho buffera (SOP a PID)
ret
;------------------------------------------------------------------------------------------
DecodeNRZI: ;enkodovanie buffera z NRZI kodu do binarneho
push USBBufptrY ;zalohuj pointer do buffera
push ByteCount ;zalohuj dlzku buffera
add ByteCount,USBBufptrY ;koniec buffera do ByteCount
ser temp0 ;na zabezpecenie jednotkoveho carry (v nasledujucej rotacii)
NRZIloop:
ror temp0 ;naplnenie carry z predchadzajuceho byte
ld temp0,Y ;nahraj prijaty byte z buffera
mov temp2,temp0 ;posunuty register o jeden bit vpravo a XOR na funkciu NRZI dekodovania
ror temp2 ;carry do najvyssieho bitu a sucasne posuv
eor temp2,temp0 ;samotne dekodovanie NRZI
com temp2 ;negovanie
st Y+,temp2 ;ulozenie spat ako dekodovany byte a zvys pointer do buffera
cp USBBufptrY,ByteCount ;ak este neboli vsetky
brne NRZIloop ;tak opakuj
pop ByteCount ;obnov dlzku buffera
pop USBBufptrY ;obnov pointer do buffera
ret ;inak skonci
;------------------------------------------------------------------------------------------
BitStuff: ;odstranenie bit-stuffingu v buffri
clr temp3 ;pocitadlo vynechanych bitov
clr lastBitstufNumber ;0xFF do lastBitstufNumber
dec lastBitstufNumber
BitStuffRepeat:
push USBBufptrY ;zalohuj pointer do buffera
push ByteCount ;zalohuj dlzku buffera
mov temp1,temp3 ;pocitadlo vsetkych bitov
ldi temp0,8 ;spocitat vsetky bity v bufferi
SumAllBits:
add temp1,temp0
dec ByteCount
brne SumAllBits
ldi temp2,6 ;inicializuj pocitadlo jednotiek
pop ByteCount ;obnov dlzku buffera
push ByteCount ;zalohuj dlzku buffera
add ByteCount,USBBufptrY ;koniec buffera do ByteCount
inc ByteCount ;a pre istotu ho zvys o 2 (kvoli posuvaniu)
inc ByteCount
BitStuffLoop:
ld temp0,Y ;nahraj prijaty byte z buffera
ldi bitcount,8 ;pocitadlo bitov v byte
BitStuffByteLoop:
ror temp0 ;naplnenie carry z LSB
brcs IncrementBitstuff ;ak LSB=0
ldi temp2,7 ;inicializuj pocitadlo jednotiek +1 (ak bola nula)
IncrementBitstuff:
dec temp2 ;zniz pocitadlo jednotiek (predpoklad jednotkoveho bitu)
brne DontShiftBuffer ;ak este nebolo 6 jednotiek za sebou - neposun buffer
cp temp1,lastBitstufNumber ;
ldi temp2,6 ;inicializuj pocitadlo jednotiek (ak by sa nerobil bitstuffing tak sa musi zacat odznova)
brcc DontShiftBuffer ;ak sa tu uz robil bitstuffing - neposun buffer
dec temp1
mov lastBitstufNumber,temp1 ;zapamataj si poslednu poziciu bitstuffingu
cpi bitcount,1 ;aby sa ukazovalo na 7 bit (ktory sa ma vymazat alebo kde sa ma vlozit nula)
brne NoBitcountCorrect
ldi bitcount,9
inc USBBufptrY ;zvys pointer do buffera
NoBitcountCorrect:
dec bitcount
bst BitStuffInOut,0
brts CorrectOutBuffer ;ak je Out buffer - zvys dlzku buffera
rcall ShiftDeleteBuffer ;posun In buffer
dec temp3 ;zniz pocitadlo vynechani
rjmp CorrectBufferEnd
CorrectOutBuffer:
rcall ShiftInsertBuffer ;posun Out buffer
inc temp3 ;zvys pocitadlo vynechani
CorrectBufferEnd:
pop ByteCount ;obnov dlzku buffera
pop USBBufptrY ;obnov pointer do buffera
rjmp BitStuffRepeat ;a restartni od zaciatku
DontShiftBuffer:
dec temp1 ;ak uz boli vsetky bity
breq EndBitStuff ;ukonci cyklus
dec bitcount ;zniz pocitadlo bitov v byte
brne BitStuffByteLoop ;ak este neboli vsetky bity v byte - chod na dalsi bit
;inak nahraj dalsi byte
inc USBBufptrY ;zvys pointer do buffera
rjmp BitStuffLoop ;a opakuj
EndBitStuff:
pop ByteCount ;obnov dlzku buffera
pop USBBufptrY ;obnov pointer do buffera
bst BitStuffInOut,0
brts IncrementLength ;ak je Out buffer - zvys dlzku Out buffera
DecrementLength: ;ak je In buffer - zniz dlzku In buffera
cpi temp3,0 ;bolo aspon jedno znizenie
breq NoChangeByteCount ;ak nie - nemen dlzku buffera
dec ByteCount ;ak je In buffer - zniz dlzku buffera
subi temp3,256-8 ;ak nebolo viac ako 8 bitov naviac
brcc NoChangeByteCount ;tak skonci
dec ByteCount ;inak este zniz dlzku buffera
ret ;a skonci
IncrementLength:
mov OutBitStuffNumber,temp3 ;zapamataj si pocet bitov naviac
subi temp3,8 ;ak nebolo viac ako 8 bitov naviac
brcs NoChangeByteCount ;tak skonci
inc ByteCount ;inak zvys dlzku buffera
mov OutBitStuffNumber,temp3 ;a zapamataj si pocet bitov naviac (znizene o 8)
NoChangeByteCount:
ret ;skonci
;------------------------------------------------------------------------------------------
ShiftInsertBuffer: ;posuv buffera o jeden bit vpravo od konca az po poziciu: byte-USBBufptrY a bit-bitcount
mov temp0,bitcount ;vypocet: bitcount= 9-bitcount
ldi bitcount,9
sub bitcount,temp0 ;do bitcount poloha bitu, ktory treba nulovat
ld temp1,Y ;nahraj byte ktory este treba posunut od pozicie bitcount
rol temp1 ;a posun vlavo cez Carry (prenos z vyssieho byte a LSB do Carry)
ser temp2 ;FF do masky - temp2
HalfInsertPosuvMask:
lsl temp2 ;nula do dalsieho spodneho bitu masky
dec bitcount ;az pokial sa nedosiahne hranica posuvania v byte
brne HalfInsertPosuvMask
and temp1,temp2 ;odmaskuj aby zostali iba vrchne posunute bity v temp1
com temp2 ;invertuj masku
lsr temp2 ;posun masku vpravo - na vlozenie nuloveho bitu
ld temp0,Y ;nahraj byte ktory este treba posunut od pozicie bitcount do temp0
and temp0,temp2 ;odmaskuj aby zostali iba spodne neposunute bity v temp0
or temp1,temp0 ;a zluc posunutu a neposunutu cast
ld temp0,Y ;nahraj byte ktory este treba posunut od pozicie bitcount
rol temp0 ;a posun ho vlavo cez Carry (aby sa nastavilo spravne Carry pre dalsie prenosy)
st Y+,temp1 ;a nahraj spat upraveny byte
ShiftInsertBufferLoop:
cpse USBBufptrY,ByteCount ;ak nie su vsetky cele byty
rjmp NoEndShiftInsertBuffer ;tak pokracuj
ret ;inak skonci
NoEndShiftInsertBuffer:
ld temp1,Y ;nahraj byte
rol temp1 ;a posun vlavo cez Carry (prenos z nizsieho byte a LSB do Carry)
st Y+,temp1 ;a nahraj spat
rjmp ShiftInsertBufferLoop ;a pokracuj
;------------------------------------------------------------------------------------------
ShiftDeleteBuffer: ;posuv buffera o jeden bit vlavo od konca az po poziciu: byte-USBBufptrY a bit-bitcount
mov temp0,bitcount ;vypocet: bitcount= 9-bitcount
ldi bitcount,9
sub bitcount,temp0 ;do bitcount poloha bitu, ktory este treba posunut
mov temp0,USBBufptrY ;uschovanie pointera do buffera
inc temp0 ;pozicia celych bytov do temp0
mov USBBufptrY,ByteCount ;maximalna pozicia do pointra
ShiftDeleteBufferLoop:
ld temp1,-Y ;zniz buffer a nahraj byte
ror temp1 ;a posun vpravo cez Carry (prenos z vyssieho byte a LSB do Carry)
st Y,temp1 ;a nahraj spat
cpse USBBufptrY,temp0 ;ak nie su vsetky cele byty
rjmp ShiftDeleteBufferLoop ;tak pokracuj
ld temp1,-Y ;zniz buffer a nahraj byte ktory este treba posunut od pozicie bitcount
ror temp1 ;a posun vpravo cez Carry (prenos z vyssieho byte a LSB do Carry)
ser temp2 ;FF do masky - temp2
HalfDeletePosuvMask:
dec bitcount ;az pokial sa nedosiahne hranica posuvania v byte
breq DoneMask
lsl temp2 ;nula do dalsieho spodneho bitu masky
rjmp HalfDeletePosuvMask
DoneMask:
and temp1,temp2 ;odmaskuj aby zostali iba vrchne posunute bity v temp1
com temp2 ;invertuj masku
ld temp0,Y ;nahraj byte ktory este treba posunut od pozicie bitcount do temp0
and temp0,temp2 ;odmaskuj aby zostali iba spodne neposunute bity v temp0
or temp1,temp0 ;a zluc posunutu a neposunutu cast
st Y,temp1 ;a nahraj spat
ret ;a skonci
;------------------------------------------------------------------------------------------
MirrorInBufferBytes:
push USBBufptrY
push ByteCount
ldi USBBufptrY,InputBufferBegin
rcall MirrorBufferBytes
pop ByteCount
pop USBBufptrY
ret
;------------------------------------------------------------------------------------------
MirrorBufferBytes:
add ByteCount,USBBufptrY ;ByteCount ukazuje na koniec spravy
MirrorBufferloop:
ld temp0,Y ;nahraj prijaty byte z buffera
ldi temp1,8 ;pocitadlo bitov
MirrorBufferByteLoop:
ror temp0 ;do carry dalsi najnizsi bit
rol temp2 ;z carry dalsi bit na obratene poradie
dec temp1 ;bol uz cely byte
brne MirrorBufferByteLoop ;ak nie tak opakuj dalsi najnizsi bit
st Y+,temp2 ;ulozenie spat ako obrateny byte a zvys pointer do buffera
cp USBBufptrY,ByteCount ;ak este neboli vsetky
brne MirrorBufferloop ;tak opakuj
ret ;inak skonci
;------------------------------------------------------------------------------------------
;CheckCRCIn:
; push USBBufptrY
; push ByteCount
; ldi USBBufptrY,InputBufferBegin
; rcall CheckCRC
; pop ByteCount
; pop USBBufptrY
; ret
;------------------------------------------------------------------------------------------
AddCRCOut:
push USBBufptrY
push ByteCount
ldi USBBufptrY,OutputBufferBegin
rcall CheckCRC
com temp0 ;negacia CRC
com temp1
st Y+,temp1 ;ulozenie CRC na koniec buffera (najskor MSB)
st Y,temp0 ;ulozenie CRC na koniec buffera (potom LSB)
dec USBBufptrY ;pointer na poziciu CRC
ldi ByteCount,2 ;otocit 2 byty CRC
rcall MirrorBufferBytes ;opacne poradie bitov CRC (pri vysielani CRC sa posiela naskor MSB)
pop ByteCount
pop USBBufptrY
ret
;------------------------------------------------------------------------------------------
CheckCRC: ;vstup: USBBufptrY = zaciatok spravy ,ByteCount = dlzka spravy
add ByteCount,USBBufptrY ;ByteCount ukazuje na koniec spravy
inc USBBufptrY ;nastav pointer na zaciatok spravy - vynechat SOP
ld temp0,Y+ ;nahraj PID do temp0
;a nastav pointer na zaciatok spravy - vynechat aj PID
cpi temp0,DATA0PID ;ci je DATA0 pole
breq ComputeDATACRC ;pocitaj CRC16
cpi temp0,DATA1PID ;ci je DATA1 pole
brne CRC16End ;ak nie tak skonci
ComputeDATACRC:
ser temp0 ;inicializacia zvysku LSB na 0xff
ser temp1 ;inicializacia zvysku MSB na 0xff
CRC16Loop:
ld temp2,Y+ ;nahraj spravu do temp2 a zvys pointer do buffera
ldi temp3,8 ;pocitadlo bitov v byte - temp3
CRC16LoopByte:
bst temp1,7 ;do T uloz MSB zvysku (zvysok je iba 16 bitovy - 8 bit vyssieho byte)
bld bitcount,0 ;do bitcount LSB uloz T - MSB zvysku
eor bitcount,temp2 ;XOR bitu spravy a bitu zvysku - v LSB bitcount
rol temp0 ;posun zvysok dolava - nizsi byte (dva byty - cez carry)
rol temp1 ;posun zvysok dolava - vyssi byte (dva byty - cez carry)
cbr temp0,1 ;znuluj LSB zvysku
lsr temp2 ;posun spravu doprava
ror bitcount ;vysledok XOR-u bitov z LSB do carry
brcc CRC16NoXOR ;ak je XOR bitu spravy a MSB zvysku = 0 , tak nerob XOR
ldi bitcount,CRC16poly>>8 ;do bitcount CRC polynom - vrchny byte
eor temp1,bitcount ;a urob XOR zo zvyskom a CRC polynomom - vrchny byte
ldi bitcount,CRC16poly ;do bitcount CRC polynom - spodny byte
eor temp0,bitcount ;a urob XOR zo zvyskom a CRC polynomom - spodny byte
CRC16NoXOR:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -