📄 usbtors232.asm
字号:
out outputport,temp0 ;send out to USB
dec bitcount ;decrement bits counter - according to carry flag
brne SendUSBAnswerByteLoop ;if bits counter isn't zero - repeat transmiting with next bit
sbrs inputbuf,0 ;if is transmiting bit one - don't change USB state
eor temp0,temp2 ;otherwise state will be changed
NoXORSendLSB:
dec temp3 ;decrement bytes counter
ld inputbuf,Y+ ;load next byte and increment pointer to buffer
out outputport,temp0 ;transmit to USB
brne SendUSBAnswerLoop ;repeat for all buffer (till temp3=0)
mov bitcount,OutBitStuffNumber ;bits counter for bitstuff
cpi bitcount,0 ;if not be needed bitstuff
breq ZeroBitStuf
SendUSBAnswerBitstuffLoop:
ror inputbuf ;to carry transmiting bit (in direction first LSB then MSB)
brcs NoXORBitstuffSend ;if is one - don't change state on USB
eor temp0,temp2 ;otherwise state will be changed
NoXORBitstuffSend:
out outputport,temp0 ;transmit to USB
nop ;delay because of timing
dec bitcount ;decrement bits counter - according to carry flag
brne SendUSBAnswerBitstuffLoop ;if bits counter isn't zero - repeat transmiting with next bit
ld inputbuf,Y ;delay 2 cycle
ZeroBitStuf:
nop ;delay 1 cycle
cbr temp0,3
out outputport,temp0 ;transmit EOP on USB
ldi bitcount,5 ;delay counter: EOP shouls exists 2 bits (16 cycle at 12MHz)
SendUSBWaitEOP:
dec bitcount
brne SendUSBWaitEOP
sbi outputport,DATAminus ;set DATAMINUS : idle state on USB port
sbi outputport,DATAminus ;delay 2 cycle: Idle should exists 1 bit (8 cycle at 12MHz)
cbi USBdirection,DATAplus ;DATAPLUS as input
cbi USBdirection,DATAminus ;DATAMINUS as input
cbi outputport,DATAminus ;reset DATAMINUS : the third state on USB port
ret
;------------------------------------------------------------------------------------------
ToggleDATAPID:
lds temp0,OutputBufferBegin+1 ;load last PID
cpi temp0,DATA1PID ;if last was DATA1PID byte
ldi temp0,DATA0PID
breq SendData0PID ;then send zero answer with DATA0PID
ldi temp0,DATA1PID ;otherwise send zero answer with DATA1PID
SendData0PID:
sts OutputBufferBegin+1,temp0 ;DATA0PID byte
ret
;------------------------------------------------------------------------------------------
ComposeZeroDATA1PIDAnswer:
ldi temp0,DATA0PID ;DATA0 PID - in the next will be toggled to DATA1PID in load descriptor
sts OutputBufferBegin+1,temp0 ;load to output buffer
ComposeZeroAnswer:
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 ;zvys pointer do buffera ENG;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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -