?? usbtiny2313.asm
字號:
ldi temp0,SOPbyte
sts OutputBufferBegin+0,temp0 ;SOP byte
rcall ToggleDATAPID ;change DATAPID
ldi temp0,0x00
sts OutputBufferBegin+2,temp0 ;CRC byte
sts OutputBufferBegin+3,temp0 ;CRC byte
ldi ByteCount,2+2 ;length of output buffer (SOP and 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 to begin of ACK buffer
ldi ByteCount,2 ;number of transmit bytes (only SOP and 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 to begin of ACK buffer
ldi ByteCount,2 ;number of transmited bytes (only SOP and 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 ;length of output buffer (SOP and PID)
ret
;------------------------------------------------------------------------------------------
DecodeNRZI: ;encoding of buffer from NRZI code to binary
push USBBufptrY ;back up pointer to buffer
push ByteCount ;back up length of buffer
add ByteCount,USBBufptrY ;end of buffer to ByteCount
ser temp0 ;to ensure unit carry (in the next rotation)
NRZIloop:
ror temp0 ;filling carry from previous byte
ld temp0,Y ;load received byte from buffer
mov temp2,temp0 ;shifted register to one bit to the right and XOR for function of NRZI decoding
ror temp2 ;carry to most significant digit bit and shift
eor temp2,temp0 ;NRZI decoding
com temp2 ;negate
st Y+,temp2 ;save back as decoded byte and increment pointer to buffer
cp USBBufptrY,ByteCount ;if not all bytes
brne NRZIloop ;then repeat
pop ByteCount ;restore buffer length
pop USBBufptrY ;restore pointer to buffer
ret ;otherwise finish
;------------------------------------------------------------------------------------------
BitStuff: ;removal of bitstuffing in buffer
clr temp3 ;counter of omitted bits
clr lastBitstufNumber ;0xFF to lastBitstufNumber
dec lastBitstufNumber
BitStuffRepeat:
push USBBufptrY ;back up pointer to buffer
push ByteCount ;back up buffer length
mov temp1,temp3 ;counter of all bits
ldi temp0,8 ;sum all bits in buffer
SumAllBits:
add temp1,temp0
dec ByteCount
brne SumAllBits
ldi temp2,6 ;initialize counter of ones
pop ByteCount ;restore buffer length
push ByteCount ;back up buffer length
add ByteCount,USBBufptrY ;end of buffer to ByteCount
inc ByteCount ;and for safety increment it with 2 (because of shifting)
inc ByteCount
BitStuffLoop:
ld temp0,Y ;load received byte from buffer
ldi bitcount,8 ;bits counter in byte
BitStuffByteLoop:
ror temp0 ;filling carry from LSB
brcs IncrementBitstuff ;if that LSB=0
ldi temp2,7 ;initialize counter of ones +1 (if was zero)
IncrementBitstuff:
dec temp2 ;decrement counter of ones (assumption of one bit)
brne DontShiftBuffer ;if there was not 6 ones together - don't shift buffer
cp temp1,lastBitstufNumber ;
ldi temp2,6 ;initialize counter of ones (if no bitstuffing will be made then must be started again)
brcc DontShiftBuffer ;if already was made bitstuffing - don't shift buffer
dec temp1 ;
mov lastBitstufNumber,temp1 ;remember last position of bitstuffing
cpi bitcount,1 ;for pointing to 7-th bit (which must be deleted or where to insert zero)
brne NoBitcountCorrect
ldi bitcount,9 ;
inc USBBufptrY ;increment pointer to buffer
NoBitcountCorrect:
dec bitcount
bst BitStuffInOut,0
brts CorrectOutBuffer ;if this is Out buffer - increment buffer length
rcall ShiftDeleteBuffer ;shift In buffer
dec temp3 ;decrement counter of omission
rjmp CorrectBufferEnd
CorrectOutBuffer:
rcall ShiftInsertBuffer ;shift Out buffer
inc temp3 ;increment counter of omission
CorrectBufferEnd:
pop ByteCount ;restore buffer length
pop USBBufptrY ;restore pointer to buffer
rjmp BitStuffRepeat ;and restart from begin
DontShiftBuffer:
dec temp1 ;if already were all bits
breq EndBitStuff ;finish cycle
dec bitcount ;decrement bits counter in byte
brne BitStuffByteLoop ;if not yet been all bits in byte - go to next bit
;otherwise load next byte
inc USBBufptrY ;increment pointer to buffer
rjmp BitStuffLoop ;and repeat
EndBitStuff:
pop ByteCount ;restore buffer length
pop USBBufptrY ;restore pointer to buffer
bst BitStuffInOut,0
brts IncrementLength ;if this is Out buffer - increment length of Out buffer
DecrementLength: ;if this is In buffer - decrement length of In buffer
cpi temp3,0 ;was at least one decrement
breq NoChangeByteCount ;if no - don't change buffer length
dec ByteCount ;if this is In buffer - decrement buffer length
subi temp3,256-8 ;if there wasn't above 8 bits over
brcc NoChangeByteCount ;then finish
dec ByteCount ;otherwise next decrement buffer length
ret ;and finish
IncrementLength:
mov OutBitStuffNumber,temp3 ;remember number of bits over
subi temp3,8 ;if there wasn't above 8 bits over
brcs NoChangeByteCount ;then finish
inc ByteCount ;otherwise increment buffer length
mov OutBitStuffNumber,temp3 ;and remember number of bits over (decremented by 8)
NoChangeByteCount:
ret ;finish
;------------------------------------------------------------------------------------------
ShiftInsertBuffer: ;shift buffer by one bit to right from end till to position: byte-USBBufptrY and bit-bitcount
mov temp0,bitcount ;calculation: bitcount= 9-bitcount
ldi bitcount,9
sub bitcount,temp0 ;to bitcount bit position, which is necessary to clear
ld temp1,Y ;load byte which still must be shifted from position bitcount
rol temp1 ;and shift to the left through Carry (transmission from higher byte and LSB to Carry)
ser temp2 ;FF to mask - temp2
HalfInsertPosuvMask:
lsl temp2 ;zero to the next low bit of mask
dec bitcount ;till not reached boundary of shifting in byte
brne HalfInsertPosuvMask
and temp1,temp2 ;unmask that remains only high shifted bits in temp1
com temp2 ;invert mask
lsr temp2 ;shift mask to the right - for insertion of zero bit
ld temp0,Y ;load byte which must be shifted from position bitcount to temp0
and temp0,temp2 ;unmask to remains only low non-shifted bits in temp0
or temp1,temp0 ;and put together shifted and nonshifted part
ld temp0,Y ;load byte which must be shifted from position bitcount
rol temp0 ;and shift it to the left through Carry (to set right Carry for further carry)
st Y+,temp1 ;and load back modified byte
ShiftInsertBufferLoop:
cpse USBBufptrY,ByteCount ;if are not all entire bytes
rjmp NoEndShiftInsertBuffer ;then continue
ret ;otherwise finish
NoEndShiftInsertBuffer:
ld temp1,Y ;load byte
rol temp1 ;and shift to the left through Carry (carry from low byte and LSB to Carry)
st Y+,temp1 ;and store back
rjmp ShiftInsertBufferLoop ;and continue
;------------------------------------------------------------------------------------------
ShiftDeleteBuffer: ;shift buffer one bit to the left from end to position: byte-USBBufptrY and bit-bitcount
mov temp0,bitcount ;calculation: bitcount= 9-bitcount
ldi bitcount,9
sub bitcount,temp0 ;to bitcount bit position, which must be shifted
mov temp0,USBBufptrY ;backup pointera to buffer
inc temp0 ;position of completed bytes to temp0
mov USBBufptrY,ByteCount ;maximum position to pointer
ShiftDeleteBufferLoop:
ld temp1,-Y ;decrement buffer and load byte
ror temp1 ;and right shift through Carry (carry from higher byte and LSB to Carry)
st Y,temp1 ;and store back
cpse USBBufptrY,temp0 ;if there are not all entire bytes
rjmp ShiftDeleteBufferLoop ;then continue
ld temp1,-Y ;decrement buffer and load byte which must be shifted from position bitcount
ror temp1 ;and right shift through Carry (carry from higher byte and LSB to Carry)
ser temp2 ;FF to mask - temp2
HalfDeletePosuvMask:
dec bitcount ;till not reached boundary of shifting in byte
breq DoneMask
lsl temp2 ;zero to the next low bit of mask
rjmp HalfDeletePosuvMask
DoneMask:
and temp1,temp2 ;unmask to remain only high shifted bits in temp1
com temp2 ;invert mask
ld temp0,Y ;load byte which must be shifted from position bitcount to temp0
and temp0,temp2 ;unmask to remain only low nonshifted bits in temp0
or temp1,temp0 ;and put together shifted and nonshifted part
st Y,temp1 ;and store back
ret ;and finish
;------------------------------------------------------------------------------------------
MirrorInBufferBytes:
push USBBufptrY
push ByteCount
ldi USBBufptrY,InputBufferBegin
rcall MirrorBufferBytes
pop ByteCount
pop USBBufptrY
ret
;------------------------------------------------------------------------------------------
MirrorBufferBytes:
add ByteCount,USBBufptrY ;ByteCount shows to the end of message
MirrorBufferloop:
ld temp0,Y ;load received byte from buffer
ldi temp1,8 ;bits counter
MirrorBufferByteLoop:
ror temp0 ;to carry next least bit
rol temp2 ;from carry next bit to reverse order
dec temp1 ;was already entire byte
brne MirrorBufferByteLoop ;if no then repeat next least bit
st Y+,temp2 ;save back as reversed byte and increment pointer to buffer
cp USBBufptrY,ByteCount ;if not yet been all
brne MirrorBufferloop ;then repeat
ret ;otherwise finish
;------------------------------------------------------------------------------------------
;CheckCRCIn:
; kiss USBBUFPTRY
; kiss ByteCount
; ldi USBBUFPTRY,InputBuffercompare
; rcall CheckCRC
; pope ByteCount
; pope USBBUFPTRY
; lip
;------------------------------------------------------------------------------------------
AddCRCOut:
push USBBufptrY
push ByteCount
ldi USBBufptrY,OutputBufferBegin
rcall CheckCRC
com temp0 ;negation of CRC
com temp1
st Y+,temp1 ;save CRC to the end of buffer (at first MSB)
st Y,temp0 ;save CRC to the end of buffer (then LSB)
dec USBBufptrY ;pointer to CRC position
ldi ByteCount,2 ;reverse bits order in 2 bytes CRC
rcall MirrorBufferBytes ;reverse bits order in CRC (transmiting CRC - MSB first)
pop ByteCount
pop USBBufptrY
ret
;------------------------------------------------------------------------------------------
CheckCRC: ;input: USBBufptrY = begin of message ,ByteCount = length of message
add ByteCount,USBBufptrY ;ByteCount points to the end of message
inc USBBufptrY ;set the pointer to message start - omit SOP
ld temp0,Y+ ;load PID to temp0
;and set the pointer to start of message - omit also PID
cpi temp0,DATA0PID ;if is DATA0 field
breq ComputeDATACRC ;compute CRC16
cpi temp0,DATA1PID ;if is DATA1 field
brne CRC16End ;if no then finish
ComputeDATACRC:
ser temp0 ;initialization of remaider LSB to 0xff
ser temp1 ;initialization of remaider MSB to 0xff
CRC16Loop:
ld temp2,Y+ ;load message to temp2 and increment pointer to buffer
ldi temp3,8 ;bits counter in byte - temp3
CRC16LoopByte:
bst temp1,7 ;to T save MSB of remainder (remainder is only 16 bits - 8 bit of higher byte)
bld bitcount,0 ;to bitcount LSB save T - of MSB remainder
eor bitcount,temp2 ;XOR of bit message and bit remainder - in LSB bitcount
rol temp0 ;shift remainder to the left - low byte (two bytes - through carry)
rol temp1 ;shift remainder to the left - high byte (two bytes - through carry)
cbr temp0,1 ;znuluj LSB remains
lsr temp2 ;shift message to right
ror bitcount ;result of XOR bits from LSB to carry
brcc CRC16NoXOR ;if is XOR bitmessage and MSB of remainder = 0 , then no XOR
ldi bitcount,CRC16poly>>8 ;to bitcount CRC polynomial - high byte
eor temp1,bitcount ;and make XOR from remains and CRC polynomial - high byte
ldi bitcount,LOW(CRC16poly) ;to bitcount CRC polynomial - low byte
eor temp0,bitcount ;and make XOR of remainder and CRC polynomial - low byte
CRC16NoXOR:
dec temp3 ;were already all bits in byte
brne CRC16LoopByte ;unless, then go to next bit
cp USBBufptrY,ByteCount ;was already end-of-message
brne CRC16Loop ;unless then repeat
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -