- push x4 ;[-14]
-; [---] ;[-13]
- lds YL, usbInputBufOffset;[-12] used to toggle the two usb receive buffers
-; [---] ;[-11]
- clr YH ;[-10]
- subi YL, lo8(-(usbRxBuf));[-9] [rx loop init]
- sbci YH, hi8(-(usbRxBuf));[-8] [rx loop init]
- push shift ;[-7]
-; [---] ;[-6]
- ldi shift, 0x80 ;[-5] the last bit is the end of byte marker for the pid receiver loop
- clc ;[-4] the carry has to be clear for receipt of pid bit 0
- sbis USBIN, USBMINUS ;[-3] we want two bits K (sample 3 cycles too early)
- rjmp haveTwoBitsK ;[-2]
- pop shift ;[-1] undo the push from before
- pop x4 ;[1]
- rjmp waitForK ;[3] this was not the end of sync, retry
+ push x4 ;[-14]
+; [---] ;[-13]
+ lds YL, usbInputBufOffset ;[-12] used to toggle the two usb receive buffers
+; [---] ;[-11]
+ clr YH ;[-10]
+ subi YL, lo8(-(usbRxBuf)) ;[-9] [rx loop init]
+ sbci YH, hi8(-(usbRxBuf)) ;[-8] [rx loop init]
+ push shift ;[-7]
+; [---] ;[-6]
+ ldi shift, 0x80 ;[-5] the last bit is the end of byte marker for the pid receiver loop
+ clc ;[-4] the carry has to be clear for receipt of pid bit 0
+ sbis USBIN, USBMINUS ;[-3] we want two bits K (sample 3 cycles too early)
+ rjmp haveTwoBitsK ;[-2]
+ pop shift ;[-1] undo the push from before
+ pop x4 ;[1]
+ rjmp waitForK ;[3] this was not the end of sync, retry
- in x1, USBIN ;[0] sample line state (note: a se0 check is not useful due to bit dribbling)
- ser x5 ;[1] prepare the unstuff marker register
- eor x2, x1 ;[2] generates the inverted of the actual bit
- bst x2, USBMINUS ;[3] copy the bit from x2
- bld shift, 0 ;[4] and store it in shift
- mov x2, shift ;[5] make a copy of shift for unstuffing check
- andi x2, 0xF9 ;[6] mask the last six bits, if we got six zeros (which are six ones in fact)
- breq unstuff0 ;[7] then Z is set now and we branch to the unstuffing handler
+ in x1, USBIN ;[0] sample line state (note: a se0 check is not useful due to bit dribbling)
+ ser x5 ;[1] prepare the unstuff marker register
+ eor x2, x1 ;[2] generates the inverted of the actual bit
+ bst x2, USBMINUS ;[3] copy the bit from x2
+ bld shift, 0 ;[4] and store it in shift
+ mov x2, shift ;[5] make a copy of shift for unstuffing check
+ andi x2, 0xF9 ;[6] mask the last six bits, if we got six zeros (which are six ones in fact)
+ breq unstuff0 ;[7] then Z is set now and we branch to the unstuffing handler
-unstuff0: ;[8] this is the branch delay of breq unstuffX
- andi x1, USBMASK ;[9] do an se0 check here (if the last crc byte ends with 5 one's we might end up here
- breq didunstuff0 ;[10] event tough the message is complete -> jump back and store the byte
- ori shift, 0x01 ;[11] invert the last received bit to prevent furhter unstuffing
- in x2, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
- andi x5, 0xFE ;[1] mark this bit as inverted (will be corrected before storing shift)
- eor x1, x2 ;[2] x1 and x2 have to be different because the stuff bit is always a zero
- andi x1, USBMASK ;[3] mask the interesting bits
- breq stuffErr ;[4] if the stuff bit is a 1-bit something went wrong
- mov x1, x2 ;[5] the next bit expects the last state to be in x1
- rjmp didunstuff0 ;[6]
- ;[7] jump delay of rjmp didunstuffX
-
-unstuff1: ;[11] this is the jump delay of breq unstuffX
- in x1, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
- ori shift, 0x02 ;[1] invert the last received bit to prevent furhter unstuffing
- andi x5, 0xFD ;[2] mark this bit as inverted (will be corrected before storing shift)
- eor x2, x1 ;[3] x1 and x2 have to be different because the stuff bit is always a zero
- andi x2, USBMASK ;[4] mask the interesting bits
- breq stuffErr ;[5] if the stuff bit is a 1-bit something went wrong
- mov x2, x1 ;[6] the next bit expects the last state to be in x2
- nop2 ;[7]
- ;[8]
- rjmp didunstuff1 ;[9]
- ;[10] jump delay of rjmp didunstuffX
-
-unstuff2: ;[9] this is the jump delay of breq unstuffX
- ori shift, 0x04 ;[10] invert the last received bit to prevent furhter unstuffing
- andi x5, 0xFB ;[11] mark this bit as inverted (will be corrected before storing shift)
- in x2, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
- eor x1, x2 ;[1] x1 and x2 have to be different because the stuff bit is always a zero
- andi x1, USBMASK ;[2] mask the interesting bits
- breq stuffErr ;[3] if the stuff bit is a 1-bit something went wrong
- mov x1, x2 ;[4] the next bit expects the last state to be in x1
- nop2 ;[5]
- ;[6]
- rjmp didunstuff2 ;[7]
- ;[8] jump delay of rjmp didunstuffX
-
-unstuff3: ;[9] this is the jump delay of breq unstuffX
- ori shift, 0x08 ;[10] invert the last received bit to prevent furhter unstuffing
- andi x5, 0xF7 ;[11] mark this bit as inverted (will be corrected before storing shift)
- in x1, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
- eor x2, x1 ;[1] x1 and x2 have to be different because the stuff bit is always a zero
- andi x2, USBMASK ;[2] mask the interesting bits
- breq stuffErr ;[3] if the stuff bit is a 1-bit something went wrong
- mov x2, x1 ;[4] the next bit expects the last state to be in x2
- nop2 ;[5]
- ;[6]
- rjmp didunstuff3 ;[7]
- ;[8] jump delay of rjmp didunstuffX
+unstuff0: ;[8] this is the branch delay of breq unstuffX
+ andi x1, USBMASK ;[9] do an se0 check here (if the last crc byte ends with 5 one's we might end up here
+ breq didunstuff0 ;[10] event tough the message is complete -> jump back and store the byte
+ ori shift, 0x01 ;[11] invert the last received bit to prevent furhter unstuffing
+ in x2, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
+ andi x5, 0xFE ;[1] mark this bit as inverted (will be corrected before storing shift)
+ eor x1, x2 ;[2] x1 and x2 have to be different because the stuff bit is always a zero
+ andi x1, USBMASK ;[3] mask the interesting bits
+ breq stuffErr ;[4] if the stuff bit is a 1-bit something went wrong
+ mov x1, x2 ;[5] the next bit expects the last state to be in x1
+ rjmp didunstuff0 ;[6]
+ ;[7] jump delay of rjmp didunstuffX
+
+unstuff1: ;[11] this is the jump delay of breq unstuffX
+ in x1, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
+ ori shift, 0x02 ;[1] invert the last received bit to prevent furhter unstuffing
+ andi x5, 0xFD ;[2] mark this bit as inverted (will be corrected before storing shift)
+ eor x2, x1 ;[3] x1 and x2 have to be different because the stuff bit is always a zero
+ andi x2, USBMASK ;[4] mask the interesting bits
+ breq stuffErr ;[5] if the stuff bit is a 1-bit something went wrong
+ mov x2, x1 ;[6] the next bit expects the last state to be in x2
+ nop2 ;[7]
+ ;[8]
+ rjmp didunstuff1 ;[9]
+ ;[10] jump delay of rjmp didunstuffX
+
+unstuff2: ;[9] this is the jump delay of breq unstuffX
+ ori shift, 0x04 ;[10] invert the last received bit to prevent furhter unstuffing
+ andi x5, 0xFB ;[11] mark this bit as inverted (will be corrected before storing shift)
+ in x2, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
+ eor x1, x2 ;[1] x1 and x2 have to be different because the stuff bit is always a zero
+ andi x1, USBMASK ;[2] mask the interesting bits
+ breq stuffErr ;[3] if the stuff bit is a 1-bit something went wrong
+ mov x1, x2 ;[4] the next bit expects the last state to be in x1
+ nop2 ;[5]
+ ;[6]
+ rjmp didunstuff2 ;[7]
+ ;[8] jump delay of rjmp didunstuffX
+
+unstuff3: ;[9] this is the jump delay of breq unstuffX
+ ori shift, 0x08 ;[10] invert the last received bit to prevent furhter unstuffing
+ andi x5, 0xF7 ;[11] mark this bit as inverted (will be corrected before storing shift)
+ in x1, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
+ eor x2, x1 ;[1] x1 and x2 have to be different because the stuff bit is always a zero
+ andi x2, USBMASK ;[2] mask the interesting bits
+ breq stuffErr ;[3] if the stuff bit is a 1-bit something went wrong
+ mov x2, x1 ;[4] the next bit expects the last state to be in x2
+ nop2 ;[5]
+ ;[6]
+ rjmp didunstuff3 ;[7]
+ ;[8] jump delay of rjmp didunstuffX
-usbSendAndReti: ; 12 cycles until SOP
- in x2, USBDDR ;[-12]
- ori x2, USBMASK ;[-11]
- sbi USBOUT, USBMINUS;[-10] prepare idle state; D+ and D- must have been 0 (no pullups)
- in x1, USBOUT ;[-8] port mirror for tx loop
- out USBDDR, x2 ;[-6] <- acquire bus
- ldi x2, 0 ;[-6] init x2 (bitstuff history) because sync starts with 0
- ldi x4, USBMASK ;[-5] exor mask
- ldi shift, 0x80 ;[-4] sync byte is first byte sent
+usbSendAndReti: ; 12 cycles until SOP
+ in x2, USBDDR ;[-12]
+ ori x2, USBMASK ;[-11]
+ sbi USBOUT, USBMINUS ;[-10] prepare idle state; D+ and D- must have been 0 (no pullups)
+ in x1, USBOUT ;[-8] port mirror for tx loop
+ out USBDDR, x2 ;[-6] <- acquire bus
+ ldi x2, 0 ;[-6] init x2 (bitstuff history) because sync starts with 0
+ ldi x4, USBMASK ;[-5] exor mask
+ ldi shift, 0x80 ;[-4] sync byte is first byte sent
- eor x5, shift ;[7] x5 marks all bits which have not been inverted by the unstuffing subs
- mov x4, x5 ;[8] keep a copy of the data byte it will be stored during next bit0
- eor ZL, x4 ;[9] feed the actual byte into the crc algorithm
- rjmp rxDataStart ;[10] next byte
- ;[11] during the reception of the next byte this one will be fed int the crc algorithm
-
-unstuff4: ;[9] this is the jump delay of rjmp unstuffX
- ori shift, 0x10 ;[10] invert the last received bit to prevent furhter unstuffing
- andi x5, 0xEF ;[11] mark this bit as inverted (will be corrected before storing shift)
- in x2, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
- eor x1, x2 ;[1] x1 and x2 have to be different because the stuff bit is always a zero
- andi x1, USBMASK ;[2] mask the interesting bits
- breq stuffErr2 ;[3] if the stuff bit is a 1-bit something went wrong
- mov x1, x2 ;[4] the next bit expects the last state to be in x1
- nop2 ;[5]
- ;[6]
- rjmp didunstuff4 ;[7]
- ;[8] jump delay of rjmp didunstuffX
-
-unstuff5: ;[8] this is the jump delay of rjmp unstuffX
- nop ;[9]
- ori shift, 0x20 ;[10] invert the last received bit to prevent furhter unstuffing
- andi x5, 0xDF ;[11] mark this bit as inverted (will be corrected before storing shift)
- in x1, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
- eor x2, x1 ;[1] x1 and x2 have to be different because the stuff bit is always a zero
- andi x2, USBMASK ;[2] mask the interesting bits
- breq stuffErr2 ;[3] if the stuff bit is a 1-bit something went wrong
- mov x2, x1 ;[4] the next bit expects the last state to be in x2
- nop ;[5]
- rjmp didunstuff5 ;[6]
- ;[7] jump delay of rjmp didunstuffX
-
-unstuff6: ;[7] this is the jump delay of rjmp unstuffX
- nop2 ;[8]
- ;[9]
- ori shift, 0x40 ;[10] invert the last received bit to prevent furhter unstuffing
- andi x5, 0xBF ;[11] mark this bit as inverted (will be corrected before storing shift)
- in x2, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
- eor x1, x2 ;[1] x1 and x2 have to be different because the stuff bit is always a zero
- andi x1, USBMASK ;[2] mask the interesting bits
- breq stuffErr2 ;[3] if the stuff bit is a 1-bit something went wrong
- mov x1, x2 ;[4] the next bit expects the last state to be in x1
- rjmp didunstuff6 ;[5]
- ;[6] jump delay of rjmp didunstuffX
-
-unstuff7: ;[7] this is the jump delay of rjmp unstuffX
- nop ;[8]
- nop ;[9]
- ori shift, 0x80 ;[10] invert the last received bit to prevent furhter unstuffing
- andi x5, 0x7F ;[11] mark this bit as inverted (will be corrected before storing shift)
- in x1, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
- eor x2, x1 ;[1] x1 and x2 have to be different because the stuff bit is always a zero
- andi x2, USBMASK ;[2] mask the interesting bits
- breq stuffErr2 ;[3] if the stuff bit is a 1-bit something went wrong
- mov x2, x1 ;[4] the next bit expects the last state to be in x2
- rjmp didunstuff7 ;[5]
- ;[6] jump delay of rjmp didunstuff7
+ eor x5, shift ;[7] x5 marks all bits which have not been inverted by the unstuffing subs
+ mov x4, x5 ;[8] keep a copy of the data byte it will be stored during next bit0
+ eor ZL, x4 ;[9] feed the actual byte into the crc algorithm
+ rjmp rxDataStart ;[10] next byte
+ ;[11] during the reception of the next byte this one will be fed int the crc algorithm
+
+unstuff4: ;[9] this is the jump delay of rjmp unstuffX
+ ori shift, 0x10 ;[10] invert the last received bit to prevent furhter unstuffing
+ andi x5, 0xEF ;[11] mark this bit as inverted (will be corrected before storing shift)
+ in x2, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
+ eor x1, x2 ;[1] x1 and x2 have to be different because the stuff bit is always a zero
+ andi x1, USBMASK ;[2] mask the interesting bits
+ breq stuffErr2 ;[3] if the stuff bit is a 1-bit something went wrong
+ mov x1, x2 ;[4] the next bit expects the last state to be in x1
+ nop2 ;[5]
+ ;[6]
+ rjmp didunstuff4 ;[7]
+ ;[8] jump delay of rjmp didunstuffX
+
+unstuff5: ;[8] this is the jump delay of rjmp unstuffX
+ nop ;[9]
+ ori shift, 0x20 ;[10] invert the last received bit to prevent furhter unstuffing
+ andi x5, 0xDF ;[11] mark this bit as inverted (will be corrected before storing shift)
+ in x1, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
+ eor x2, x1 ;[1] x1 and x2 have to be different because the stuff bit is always a zero
+ andi x2, USBMASK ;[2] mask the interesting bits
+ breq stuffErr2 ;[3] if the stuff bit is a 1-bit something went wrong
+ mov x2, x1 ;[4] the next bit expects the last state to be in x2
+ nop ;[5]
+ rjmp didunstuff5 ;[6]
+ ;[7] jump delay of rjmp didunstuffX
+
+unstuff6: ;[7] this is the jump delay of rjmp unstuffX
+ nop2 ;[8]
+ ;[9]
+ ori shift, 0x40 ;[10] invert the last received bit to prevent furhter unstuffing
+ andi x5, 0xBF ;[11] mark this bit as inverted (will be corrected before storing shift)
+ in x2, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
+ eor x1, x2 ;[1] x1 and x2 have to be different because the stuff bit is always a zero
+ andi x1, USBMASK ;[2] mask the interesting bits
+ breq stuffErr2 ;[3] if the stuff bit is a 1-bit something went wrong
+ mov x1, x2 ;[4] the next bit expects the last state to be in x1
+ rjmp didunstuff6 ;[5]
+ ;[6] jump delay of rjmp didunstuffX
+
+unstuff7: ;[7] this is the jump delay of rjmp unstuffX
+ nop ;[8]
+ nop ;[9]
+ ori shift, 0x80 ;[10] invert the last received bit to prevent furhter unstuffing
+ andi x5, 0x7F ;[11] mark this bit as inverted (will be corrected before storing shift)
+ in x1, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
+ eor x2, x1 ;[1] x1 and x2 have to be different because the stuff bit is always a zero
+ andi x2, USBMASK ;[2] mask the interesting bits
+ breq stuffErr2 ;[3] if the stuff bit is a 1-bit something went wrong
+ mov x2, x1 ;[4] the next bit expects the last state to be in x2
+ rjmp didunstuff7 ;[5]
+ ;[6] jump delay of rjmp didunstuff7