Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

usbdrvasm18-crc.inc 31KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707
  1. /* Name: usbdrvasm18.inc
  2. * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
  3. * Author: Lukas Schrittwieser (based on 20 MHz usbdrvasm20.inc by Jeroen Benschop)
  4. * Creation Date: 2009-01-20
  5. * Tabsize: 4
  6. * Copyright: (c) 2008 by Lukas Schrittwieser and OBJECTIVE DEVELOPMENT Software GmbH
  7. * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
  8. * Revision: $Id: usbdrvasm18-crc.inc 740 2009-04-13 18:23:31Z cs $
  9. */
  10. /* Do not link this file! Link usbdrvasm.S instead, which includes the
  11. * appropriate implementation!
  12. */
  13. /*
  14. General Description:
  15. This file is the 18 MHz version of the asssembler part of the USB driver. It
  16. requires a 18 MHz crystal (not a ceramic resonator and not a calibrated RC
  17. oscillator).
  18. See usbdrv.h for a description of the entire driver.
  19. Since almost all of this code is timing critical, don't change unless you
  20. really know what you are doing! Many parts require not only a maximum number
  21. of CPU cycles, but even an exact number of cycles!
  22. */
  23. ;max stack usage: [ret(2), YL, SREG, YH, [sofError], bitcnt(x5), shift, x1, x2, x3, x4, cnt, ZL, ZH] = 14 bytes
  24. ;nominal frequency: 18 MHz -> 12 cycles per bit
  25. ; Numbers in brackets are clocks counted from center of last sync bit
  26. ; when instruction starts
  27. ;register use in receive loop to receive the data bytes:
  28. ; shift assembles the byte currently being received
  29. ; x1 holds the D+ and D- line state
  30. ; x2 holds the previous line state
  31. ; cnt holds the number of bytes left in the receive buffer
  32. ; x3 holds the higher crc byte (see algorithm below)
  33. ; x4 is used as temporary register for the crc algorithm
  34. ; x5 is used for unstuffing: when unstuffing the last received bit is inverted in shift (to prevent further
  35. ; unstuffing calls. In the same time the corresponding bit in x5 is cleared to mark the bit as beening iverted
  36. ; zl lower crc value and crc table index
  37. ; zh used for crc table accesses
  38. ;--------------------------------------------------------------------------------------------------------------
  39. ; CRC mods:
  40. ; table driven crc checker, Z points to table in prog space
  41. ; ZL is the lower crc byte, x3 is the higher crc byte
  42. ; x4 is used as temp register to store different results
  43. ; the initialization of the crc register is not 0xFFFF but 0xFE54. This is because during the receipt of the
  44. ; first data byte an virtual zero data byte is added to the crc register, this results in the correct initial
  45. ; value of 0xFFFF at beginning of the second data byte before the first data byte is added to the crc.
  46. ; The magic number 0xFE54 results form the crc table: At tabH[0x54] = 0xFF = crcH (required) and
  47. ; tabL[0x54] = 0x01 -> crcL = 0x01 xor 0xFE = 0xFF
  48. ; bitcnt is renamed to x5 and is used for unstuffing purposes, the unstuffing works like in the 12MHz version
  49. ;--------------------------------------------------------------------------------------------------------------
  50. ; CRC algorithm:
  51. ; The crc register is formed by x3 (higher byte) and ZL (lower byte). The algorithm uses a 'reversed' form
  52. ; i.e. that it takes the least significant bit first and shifts to the right. So in fact the highest order
  53. ; bit seen from the polynomial devision point of view is the lsb of ZL. (If this sounds strange to you i
  54. ; propose a research on CRC :-) )
  55. ; Each data byte received is xored to ZL, the lower crc byte. This byte now builds the crc
  56. ; table index. Next the new high byte is loaded from the table and stored in x4 until we have space in x3
  57. ; (its destination).
  58. ; Afterwards the lower table is loaded from the table and stored in ZL (the old index is overwritten as
  59. ; we don't need it anymore. In fact this is a right shift by 8 bits.) Now the old crc high value is xored
  60. ; to ZL, this is the second shift of the old crc value. Now x4 (the temp reg) is moved to x3 and the crc
  61. ; calculation is done.
  62. ; Prior to the first byte the two CRC register have to be initialized to 0xFFFF (as defined in usb spec)
  63. ; however the crc engine also runs during the receipt of the first byte, therefore x3 and zl are initialized
  64. ; to a magic number which results in a crc value of 0xFFFF after the first complete byte.
  65. ;
  66. ; This algorithm is split into the extra cycles of the different bits:
  67. ; bit7: XOR the received byte to ZL
  68. ; bit5: load the new high byte to x4
  69. ; bit6: load the lower xor byte from the table, xor zl and x3, store result in zl (=the new crc low value)
  70. ; move x4 (the new high byte) to x3, the crc value is ready
  71. ;
  72. macro POP_STANDARD ; 18 cycles
  73. pop ZH
  74. pop ZL
  75. pop cnt
  76. pop x5
  77. pop x3
  78. pop x2
  79. pop x1
  80. pop shift
  81. pop x4
  82. endm
  83. macro POP_RETI ; 7 cycles
  84. pop YH
  85. pop YL
  86. out SREG, YL
  87. pop YL
  88. endm
  89. macro CRC_CLEANUP_AND_CHECK
  90. ; the last byte has already been xored with the lower crc byte, we have to do the table lookup and xor
  91. ; x3 is the higher crc byte, zl the lower one
  92. ldi ZH, hi8(usbCrcTableHigh);[+1] get the new high byte from the table
  93. lpm x2, Z ;[+2][+3][+4]
  94. ldi ZH, hi8(usbCrcTableLow);[+5] get the new low xor byte from the table
  95. lpm ZL, Z ;[+6][+7][+8]
  96. eor ZL, x3 ;[+7] xor the old high byte with the value from the table, x2:ZL now holds the crc value
  97. cpi ZL, 0x01 ;[+8] if the crc is ok we have a fixed remainder value of 0xb001 in x2:ZL (see usb spec)
  98. brne ignorePacket ;[+9] detected a crc fault -> paket is ignored and retransmitted by the host
  99. cpi x2, 0xb0 ;[+10]
  100. brne ignorePacket ;[+11] detected a crc fault -> paket is ignored and retransmitted by the host
  101. endm
  102. USB_INTR_VECTOR:
  103. ;order of registers pushed: YL, SREG, YH, [sofError], x4, shift, x1, x2, x3, x5, cnt, ZL, ZH
  104. push YL ;[-28] push only what is necessary to sync with edge ASAP
  105. in YL, SREG ;[-26]
  106. push YL ;[-25]
  107. push YH ;[-23]
  108. ;----------------------------------------------------------------------------
  109. ; Synchronize with sync pattern:
  110. ;----------------------------------------------------------------------------
  111. ;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K]
  112. ;sync up with J to K edge during sync pattern -- use fastest possible loops
  113. ;The first part waits at most 1 bit long since we must be in sync pattern.
  114. ;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to
  115. ;waitForJ, ensure that this prerequisite is met.
  116. waitForJ:
  117. inc YL
  118. sbis USBIN, USBMINUS
  119. brne waitForJ ; just make sure we have ANY timeout
  120. waitForK:
  121. ;The following code results in a sampling window of < 1/4 bit which meets the spec.
  122. sbis USBIN, USBMINUS ;[-17]
  123. rjmp foundK ;[-16]
  124. sbis USBIN, USBMINUS
  125. rjmp foundK
  126. sbis USBIN, USBMINUS
  127. rjmp foundK
  128. sbis USBIN, USBMINUS
  129. rjmp foundK
  130. sbis USBIN, USBMINUS
  131. rjmp foundK
  132. sbis USBIN, USBMINUS
  133. rjmp foundK
  134. sbis USBIN, USBMINUS
  135. rjmp foundK
  136. sbis USBIN, USBMINUS
  137. rjmp foundK
  138. sbis USBIN, USBMINUS
  139. rjmp foundK
  140. #if USB_COUNT_SOF
  141. lds YL, usbSofCount
  142. inc YL
  143. sts usbSofCount, YL
  144. #endif /* USB_COUNT_SOF */
  145. #ifdef USB_SOF_HOOK
  146. USB_SOF_HOOK
  147. #endif
  148. rjmp sofError
  149. foundK: ;[-15]
  150. ;{3, 5} after falling D- edge, average delay: 4 cycles
  151. ;bit0 should be at 30 (2.5 bits) for center sampling. Currently at 4 so 26 cylces till bit 0 sample
  152. ;use 1 bit time for setup purposes, then sample again. Numbers in brackets
  153. ;are cycles from center of first sync (double K) bit after the instruction
  154. push x4 ;[-14]
  155. ; [---] ;[-13]
  156. lds YL, usbInputBufOffset;[-12] used to toggle the two usb receive buffers
  157. ; [---] ;[-11]
  158. clr YH ;[-10]
  159. subi YL, lo8(-(usbRxBuf));[-9] [rx loop init]
  160. sbci YH, hi8(-(usbRxBuf));[-8] [rx loop init]
  161. push shift ;[-7]
  162. ; [---] ;[-6]
  163. ldi shift, 0x80 ;[-5] the last bit is the end of byte marker for the pid receiver loop
  164. clc ;[-4] the carry has to be clear for receipt of pid bit 0
  165. sbis USBIN, USBMINUS ;[-3] we want two bits K (sample 3 cycles too early)
  166. rjmp haveTwoBitsK ;[-2]
  167. pop shift ;[-1] undo the push from before
  168. pop x4 ;[1]
  169. rjmp waitForK ;[3] this was not the end of sync, retry
  170. ; The entire loop from waitForK until rjmp waitForK above must not exceed two
  171. ; bit times (= 24 cycles).
  172. ;----------------------------------------------------------------------------
  173. ; push more registers and initialize values while we sample the first bits:
  174. ;----------------------------------------------------------------------------
  175. haveTwoBitsK:
  176. push x1 ;[0]
  177. push x2 ;[2]
  178. push x3 ;[4] crc high byte
  179. ldi x2, 1<<USBPLUS ;[6] [rx loop init] current line state is K state. D+=="1", D-=="0"
  180. push x5 ;[7]
  181. push cnt ;[9]
  182. ldi cnt, USB_BUFSIZE ;[11]
  183. ;--------------------------------------------------------------------------------------------------------------
  184. ; receives the pid byte
  185. ; there is no real unstuffing algorithm implemented here as a stuffing bit is impossible in the pid byte.
  186. ; That's because the last four bits of the byte are the inverted of the first four bits. If we detect a
  187. ; unstuffing condition something went wrong and abort
  188. ; shift has to be initialized to 0x80
  189. ;--------------------------------------------------------------------------------------------------------------
  190. ; pid bit 0 - used for even more register saving (we need the z pointer)
  191. in x1, USBIN ;[0] sample line state
  192. andi x1, USBMASK ;[1] filter only D+ and D- bits
  193. eor x2, x1 ;[2] generate inverted of actual bit
  194. sbrc x2, USBMINUS ;[3] if the bit is set we received a zero
  195. sec ;[4]
  196. ror shift ;[5] we perform no unstuffing check here as this is the first bit
  197. mov x2, x1 ;[6]
  198. push ZL ;[7]
  199. ;[8]
  200. push ZH ;[9]
  201. ;[10]
  202. ldi x3, 0xFE ;[11] x3 is the high order crc value
  203. bitloopPid:
  204. in x1, USBIN ;[0] sample line state
  205. andi x1, USBMASK ;[1] filter only D+ and D- bits
  206. breq nse0 ;[2] both lines are low so handle se0
  207. eor x2, x1 ;[3] generate inverted of actual bit
  208. sbrc x2, USBMINUS ;[4] set the carry if we received a zero
  209. sec ;[5]
  210. ror shift ;[6]
  211. ldi ZL, 0x54 ;[7] ZL is the low order crc value
  212. ser x4 ;[8] the is no bit stuffing check here as the pid bit can't be stuffed. if so
  213. ; some error occured. In this case the paket is discarded later on anyway.
  214. mov x2, x1 ;[9] prepare for the next cycle
  215. brcc bitloopPid ;[10] while 0s drop out of shift we get the next bit
  216. eor x4, shift ;[11] invert all bits in shift and store result in x4
  217. ;--------------------------------------------------------------------------------------------------------------
  218. ; receives data bytes and calculates the crc
  219. ; the last USBIN state has to be in x2
  220. ; this is only the first half, due to branch distanc limitations the second half of the loop is near the end
  221. ; of this asm file
  222. ;--------------------------------------------------------------------------------------------------------------
  223. rxDataStart:
  224. in x1, USBIN ;[0] sample line state (note: a se0 check is not useful due to bit dribbling)
  225. ser x5 ;[1] prepare the unstuff marker register
  226. eor x2, x1 ;[2] generates the inverted of the actual bit
  227. bst x2, USBMINUS ;[3] copy the bit from x2
  228. bld shift, 0 ;[4] and store it in shift
  229. mov x2, shift ;[5] make a copy of shift for unstuffing check
  230. andi x2, 0xF9 ;[6] mask the last six bits, if we got six zeros (which are six ones in fact)
  231. breq unstuff0 ;[7] then Z is set now and we branch to the unstuffing handler
  232. didunstuff0:
  233. subi cnt, 1 ;[8] cannot use dec because it doesn't affect the carry flag
  234. brcs nOverflow ;[9] Too many bytes received. Ignore packet
  235. st Y+, x4 ;[10] store the last received byte
  236. ;[11] st needs two cycles
  237. ; bit1
  238. in x2, USBIN ;[0] sample line state
  239. andi x1, USBMASK ;[1] check for se0 during bit 0
  240. breq nse0 ;[2]
  241. andi x2, USBMASK ;[3] check se0 during bit 1
  242. breq nse0 ;[4]
  243. eor x1, x2 ;[5]
  244. bst x1, USBMINUS ;[6]
  245. bld shift, 1 ;[7]
  246. mov x1, shift ;[8]
  247. andi x1, 0xF3 ;[9]
  248. breq unstuff1 ;[10]
  249. didunstuff1:
  250. nop ;[11]
  251. ; bit2
  252. in x1, USBIN ;[0] sample line state
  253. andi x1, USBMASK ;[1] check for se0 (as there is nothing else to do here
  254. breq nOverflow ;[2]
  255. eor x2, x1 ;[3] generates the inverted of the actual bit
  256. bst x2, USBMINUS ;[4]
  257. bld shift, 2 ;[5] store the bit
  258. mov x2, shift ;[6]
  259. andi x2, 0xE7 ;[7] if we have six zeros here (which means six 1 in the stream)
  260. breq unstuff2 ;[8] the next bit is a stuffing bit
  261. didunstuff2:
  262. nop2 ;[9]
  263. ;[10]
  264. nop ;[11]
  265. ; bit3
  266. in x2, USBIN ;[0] sample line state
  267. andi x2, USBMASK ;[1] check for se0
  268. breq nOverflow ;[2]
  269. eor x1, x2 ;[3]
  270. bst x1, USBMINUS ;[4]
  271. bld shift, 3 ;[5]
  272. mov x1, shift ;[6]
  273. andi x1, 0xCF ;[7]
  274. breq unstuff3 ;[8]
  275. didunstuff3:
  276. nop ;[9]
  277. rjmp rxDataBit4 ;[10]
  278. ;[11]
  279. ; the avr branch instructions allow an offset of +63 insturction only, so we need this
  280. ; 'local copy' of se0
  281. nse0:
  282. rjmp se0 ;[4]
  283. ;[5]
  284. ; the same same as for se0 is needed for overflow and StuffErr
  285. nOverflow:
  286. stuffErr:
  287. rjmp overflow
  288. unstuff0: ;[8] this is the branch delay of breq unstuffX
  289. andi x1, USBMASK ;[9] do an se0 check here (if the last crc byte ends with 5 one's we might end up here
  290. breq didunstuff0 ;[10] event tough the message is complete -> jump back and store the byte
  291. ori shift, 0x01 ;[11] invert the last received bit to prevent furhter unstuffing
  292. in x2, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
  293. andi x5, 0xFE ;[1] mark this bit as inverted (will be corrected before storing shift)
  294. eor x1, x2 ;[2] x1 and x2 have to be different because the stuff bit is always a zero
  295. andi x1, USBMASK ;[3] mask the interesting bits
  296. breq stuffErr ;[4] if the stuff bit is a 1-bit something went wrong
  297. mov x1, x2 ;[5] the next bit expects the last state to be in x1
  298. rjmp didunstuff0 ;[6]
  299. ;[7] jump delay of rjmp didunstuffX
  300. unstuff1: ;[11] this is the jump delay of breq unstuffX
  301. in x1, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
  302. ori shift, 0x02 ;[1] invert the last received bit to prevent furhter unstuffing
  303. andi x5, 0xFD ;[2] mark this bit as inverted (will be corrected before storing shift)
  304. eor x2, x1 ;[3] x1 and x2 have to be different because the stuff bit is always a zero
  305. andi x2, USBMASK ;[4] mask the interesting bits
  306. breq stuffErr ;[5] if the stuff bit is a 1-bit something went wrong
  307. mov x2, x1 ;[6] the next bit expects the last state to be in x2
  308. nop2 ;[7]
  309. ;[8]
  310. rjmp didunstuff1 ;[9]
  311. ;[10] jump delay of rjmp didunstuffX
  312. unstuff2: ;[9] this is the jump delay of breq unstuffX
  313. ori shift, 0x04 ;[10] invert the last received bit to prevent furhter unstuffing
  314. andi x5, 0xFB ;[11] mark this bit as inverted (will be corrected before storing shift)
  315. in x2, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
  316. eor x1, x2 ;[1] x1 and x2 have to be different because the stuff bit is always a zero
  317. andi x1, USBMASK ;[2] mask the interesting bits
  318. breq stuffErr ;[3] if the stuff bit is a 1-bit something went wrong
  319. mov x1, x2 ;[4] the next bit expects the last state to be in x1
  320. nop2 ;[5]
  321. ;[6]
  322. rjmp didunstuff2 ;[7]
  323. ;[8] jump delay of rjmp didunstuffX
  324. unstuff3: ;[9] this is the jump delay of breq unstuffX
  325. ori shift, 0x08 ;[10] invert the last received bit to prevent furhter unstuffing
  326. andi x5, 0xF7 ;[11] mark this bit as inverted (will be corrected before storing shift)
  327. in x1, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
  328. eor x2, x1 ;[1] x1 and x2 have to be different because the stuff bit is always a zero
  329. andi x2, USBMASK ;[2] mask the interesting bits
  330. breq stuffErr ;[3] if the stuff bit is a 1-bit something went wrong
  331. mov x2, x1 ;[4] the next bit expects the last state to be in x2
  332. nop2 ;[5]
  333. ;[6]
  334. rjmp didunstuff3 ;[7]
  335. ;[8] jump delay of rjmp didunstuffX
  336. ; the include has to be here due to branch distance restirctions
  337. #define __USE_CRC__
  338. #include "asmcommon.inc"
  339. ; USB spec says:
  340. ; idle = J
  341. ; J = (D+ = 0), (D- = 1)
  342. ; K = (D+ = 1), (D- = 0)
  343. ; Spec allows 7.5 bit times from EOP to SOP for replies
  344. ; 7.5 bit times is 90 cycles. ...there is plenty of time
  345. sendNakAndReti:
  346. ldi x3, USBPID_NAK ;[-18]
  347. rjmp sendX3AndReti ;[-17]
  348. sendAckAndReti:
  349. ldi cnt, USBPID_ACK ;[-17]
  350. sendCntAndReti:
  351. mov x3, cnt ;[-16]
  352. sendX3AndReti:
  353. ldi YL, 20 ;[-15] x3==r20 address is 20
  354. ldi YH, 0 ;[-14]
  355. ldi cnt, 2 ;[-13]
  356. ; rjmp usbSendAndReti fallthrough
  357. ;usbSend:
  358. ;pointer to data in 'Y'
  359. ;number of bytes in 'cnt' -- including sync byte [range 2 ... 12]
  360. ;uses: x1...x4, btcnt, shift, cnt, Y
  361. ;Numbers in brackets are time since first bit of sync pattern is sent
  362. usbSendAndReti: ; 12 cycles until SOP
  363. in x2, USBDDR ;[-12]
  364. ori x2, USBMASK ;[-11]
  365. sbi USBOUT, USBMINUS;[-10] prepare idle state; D+ and D- must have been 0 (no pullups)
  366. in x1, USBOUT ;[-8] port mirror for tx loop
  367. out USBDDR, x2 ;[-6] <- acquire bus
  368. ldi x2, 0 ;[-6] init x2 (bitstuff history) because sync starts with 0
  369. ldi x4, USBMASK ;[-5] exor mask
  370. ldi shift, 0x80 ;[-4] sync byte is first byte sent
  371. txByteLoop:
  372. ldi bitcnt, 0x40 ;[-3]=[9] binary 01000000
  373. txBitLoop: ; the loop sends the first 7 bits of the byte
  374. sbrs shift, 0 ;[-2]=[10] if we have to send a 1 don't change the line state
  375. eor x1, x4 ;[-1]=[11]
  376. out USBOUT, x1 ;[0]
  377. ror shift ;[1]
  378. ror x2 ;[2] transfers the last sent bit to the stuffing history
  379. didStuffN:
  380. nop ;[3]
  381. nop ;[4]
  382. cpi x2, 0xfc ;[5] if we sent six consecutive ones
  383. brcc bitstuffN ;[6]
  384. lsr bitcnt ;[7]
  385. brne txBitLoop ;[8] restart the loop while the 1 is still in the bitcount
  386. ; transmit bit 7
  387. sbrs shift, 0 ;[9]
  388. eor x1, x4 ;[10]
  389. didStuff7:
  390. ror shift ;[11]
  391. out USBOUT, x1 ;[0] transfer bit 7 to the pins
  392. ror x2 ;[1] move the bit into the stuffing history
  393. cpi x2, 0xfc ;[2]
  394. brcc bitstuff7 ;[3]
  395. ld shift, y+ ;[4] get next byte to transmit
  396. dec cnt ;[5] decrement byte counter
  397. brne txByteLoop ;[7] if we have more bytes start next one
  398. ;[8] branch delay
  399. ;make SE0:
  400. cbr x1, USBMASK ;[8] prepare SE0 [spec says EOP may be 25 to 30 cycles]
  401. lds x2, usbNewDeviceAddr;[9]
  402. lsl x2 ;[11] we compare with left shifted address
  403. out USBOUT, x1 ;[0] <-- out SE0 -- from now 2 bits = 24 cycles until bus idle
  404. subi YL, 20 + 2 ;[1] Only assign address on data packets, not ACK/NAK in x3
  405. sbci YH, 0 ;[2]
  406. ;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm:
  407. ;set address only after data packet was sent, not after handshake
  408. breq skipAddrAssign ;[3]
  409. sts usbDeviceAddr, x2 ; if not skipped: SE0 is one cycle longer
  410. skipAddrAssign:
  411. ;end of usbDeviceAddress transfer
  412. ldi x2, 1<<USB_INTR_PENDING_BIT;[5] int0 occurred during TX -- clear pending flag
  413. USB_STORE_PENDING(x2) ;[6]
  414. ori x1, USBIDLE ;[7]
  415. in x2, USBDDR ;[8]
  416. cbr x2, USBMASK ;[9] set both pins to input
  417. mov x3, x1 ;[10]
  418. cbr x3, USBMASK ;[11] configure no pullup on both pins
  419. ldi x4, 4 ;[12]
  420. se0Delay:
  421. dec x4 ;[13] [16] [19] [22]
  422. brne se0Delay ;[14] [17] [20] [23]
  423. out USBOUT, x1 ;[24] <-- out J (idle) -- end of SE0 (EOP signal)
  424. out USBDDR, x2 ;[25] <-- release bus now
  425. out USBOUT, x3 ;[26] <-- ensure no pull-up resistors are active
  426. rjmp doReturn
  427. bitstuffN:
  428. eor x1, x4 ;[8] generate a zero
  429. ldi x2, 0 ;[9] reset the bit stuffing history
  430. nop2 ;[10]
  431. out USBOUT, x1 ;[0] <-- send the stuffing bit
  432. rjmp didStuffN ;[1]
  433. bitstuff7:
  434. eor x1, x4 ;[5]
  435. ldi x2, 0 ;[6] reset bit stuffing history
  436. clc ;[7] fill a zero into the shift register
  437. rol shift ;[8] compensate for ror shift at branch destination
  438. rjmp didStuff7 ;[9]
  439. ;[10] jump delay
  440. ;--------------------------------------------------------------------------------------------------------------
  441. ; receives data bytes and calculates the crc
  442. ; second half of the data byte receiver loop
  443. ; most parts of the crc algorithm are here
  444. ;--------------------------------------------------------------------------------------------------------------
  445. nOverflow2:
  446. rjmp overflow
  447. rxDataBit4:
  448. in x1, USBIN ;[0] sample line state
  449. andi x1, USBMASK ;[1] check for se0
  450. breq nOverflow2 ;[2]
  451. eor x2, x1 ;[3]
  452. bst x2, USBMINUS ;[4]
  453. bld shift, 4 ;[5]
  454. mov x2, shift ;[6]
  455. andi x2, 0x9F ;[7]
  456. breq unstuff4 ;[8]
  457. didunstuff4:
  458. nop2 ;[9][10]
  459. nop ;[11]
  460. ; bit5
  461. in x2, USBIN ;[0] sample line state
  462. ldi ZH, hi8(usbCrcTableHigh);[1] use the table for the higher byte
  463. eor x1, x2 ;[2]
  464. bst x1, USBMINUS ;[3]
  465. bld shift, 5 ;[4]
  466. mov x1, shift ;[5]
  467. andi x1, 0x3F ;[6]
  468. breq unstuff5 ;[7]
  469. didunstuff5:
  470. lpm x4, Z ;[8] load the higher crc xor-byte and store it for later use
  471. ;[9] lpm needs 3 cycles
  472. ;[10]
  473. ldi ZH, hi8(usbCrcTableLow);[11] load the lower crc xor byte adress
  474. ; bit6
  475. in x1, USBIN ;[0] sample line state
  476. eor x2, x1 ;[1]
  477. bst x2, USBMINUS ;[2]
  478. bld shift, 6 ;[3]
  479. mov x2, shift ;[4]
  480. andi x2, 0x7E ;[5]
  481. breq unstuff6 ;[6]
  482. didunstuff6:
  483. lpm ZL, Z ;[7] load the lower xor crc byte
  484. ;[8] lpm needs 3 cycles
  485. ;[9]
  486. eor ZL, x3 ;[10] xor the old high crc byte with the low xor-byte
  487. mov x3, x4 ;[11] move the new high order crc value from temp to its destination
  488. ; bit7
  489. in x2, USBIN ;[0] sample line state
  490. eor x1, x2 ;[1]
  491. bst x1, USBMINUS ;[2]
  492. bld shift, 7 ;[3] now shift holds the complete but inverted data byte
  493. mov x1, shift ;[4]
  494. andi x1, 0xFC ;[5]
  495. breq unstuff7 ;[6]
  496. didunstuff7:
  497. eor x5, shift ;[7] x5 marks all bits which have not been inverted by the unstuffing subs
  498. mov x4, x5 ;[8] keep a copy of the data byte it will be stored during next bit0
  499. eor ZL, x4 ;[9] feed the actual byte into the crc algorithm
  500. rjmp rxDataStart ;[10] next byte
  501. ;[11] during the reception of the next byte this one will be fed int the crc algorithm
  502. unstuff4: ;[9] this is the jump delay of rjmp unstuffX
  503. ori shift, 0x10 ;[10] invert the last received bit to prevent furhter unstuffing
  504. andi x5, 0xEF ;[11] mark this bit as inverted (will be corrected before storing shift)
  505. in x2, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
  506. eor x1, x2 ;[1] x1 and x2 have to be different because the stuff bit is always a zero
  507. andi x1, USBMASK ;[2] mask the interesting bits
  508. breq stuffErr2 ;[3] if the stuff bit is a 1-bit something went wrong
  509. mov x1, x2 ;[4] the next bit expects the last state to be in x1
  510. nop2 ;[5]
  511. ;[6]
  512. rjmp didunstuff4 ;[7]
  513. ;[8] jump delay of rjmp didunstuffX
  514. unstuff5: ;[8] this is the jump delay of rjmp unstuffX
  515. nop ;[9]
  516. ori shift, 0x20 ;[10] invert the last received bit to prevent furhter unstuffing
  517. andi x5, 0xDF ;[11] mark this bit as inverted (will be corrected before storing shift)
  518. in x1, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
  519. eor x2, x1 ;[1] x1 and x2 have to be different because the stuff bit is always a zero
  520. andi x2, USBMASK ;[2] mask the interesting bits
  521. breq stuffErr2 ;[3] if the stuff bit is a 1-bit something went wrong
  522. mov x2, x1 ;[4] the next bit expects the last state to be in x2
  523. nop ;[5]
  524. rjmp didunstuff5 ;[6]
  525. ;[7] jump delay of rjmp didunstuffX
  526. unstuff6: ;[7] this is the jump delay of rjmp unstuffX
  527. nop2 ;[8]
  528. ;[9]
  529. ori shift, 0x40 ;[10] invert the last received bit to prevent furhter unstuffing
  530. andi x5, 0xBF ;[11] mark this bit as inverted (will be corrected before storing shift)
  531. in x2, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
  532. eor x1, x2 ;[1] x1 and x2 have to be different because the stuff bit is always a zero
  533. andi x1, USBMASK ;[2] mask the interesting bits
  534. breq stuffErr2 ;[3] if the stuff bit is a 1-bit something went wrong
  535. mov x1, x2 ;[4] the next bit expects the last state to be in x1
  536. rjmp didunstuff6 ;[5]
  537. ;[6] jump delay of rjmp didunstuffX
  538. unstuff7: ;[7] this is the jump delay of rjmp unstuffX
  539. nop ;[8]
  540. nop ;[9]
  541. ori shift, 0x80 ;[10] invert the last received bit to prevent furhter unstuffing
  542. andi x5, 0x7F ;[11] mark this bit as inverted (will be corrected before storing shift)
  543. in x1, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
  544. eor x2, x1 ;[1] x1 and x2 have to be different because the stuff bit is always a zero
  545. andi x2, USBMASK ;[2] mask the interesting bits
  546. breq stuffErr2 ;[3] if the stuff bit is a 1-bit something went wrong
  547. mov x2, x1 ;[4] the next bit expects the last state to be in x2
  548. rjmp didunstuff7 ;[5]
  549. ;[6] jump delay of rjmp didunstuff7
  550. ; local copy of the stuffErr desitnation for the second half of the receiver loop
  551. stuffErr2:
  552. rjmp stuffErr
  553. ;--------------------------------------------------------------------------------------------------------------
  554. ; The crc table follows. It has to be aligned to enable a fast loading of the needed bytes.
  555. ; There are two tables of 256 entries each, the low and the high byte table.
  556. ; Table values were generated with the following C code:
  557. /*
  558. #include <stdio.h>
  559. int main (int argc, char **argv)
  560. {
  561. int i, j;
  562. for (i=0; i<512; i++){
  563. unsigned short crc = i & 0xff;
  564. for(j=0; j<8; j++) crc = (crc >> 1) ^ ((crc & 1) ? 0xa001 : 0);
  565. if((i & 7) == 0) printf("\n.byte ");
  566. printf("0x%02x, ", (i > 0xff ? (crc >> 8) : crc) & 0xff);
  567. if(i == 255) printf("\n");
  568. }
  569. return 0;
  570. }
  571. // Use the following algorithm to compute CRC values:
  572. ushort computeCrc(uchar *msg, uchar msgLen)
  573. {
  574. uchar i;
  575. ushort crc = 0xffff;
  576. for(i = 0; i < msgLen; i++)
  577. crc = usbCrcTable16[lo8(crc) ^ msg[i]] ^ hi8(crc);
  578. return crc;
  579. }
  580. */
  581. .balign 256
  582. usbCrcTableLow:
  583. .byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
  584. .byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
  585. .byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
  586. .byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
  587. .byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
  588. .byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
  589. .byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
  590. .byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
  591. .byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
  592. .byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
  593. .byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
  594. .byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
  595. .byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
  596. .byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
  597. .byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
  598. .byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
  599. .byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
  600. .byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
  601. .byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
  602. .byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
  603. .byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
  604. .byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
  605. .byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
  606. .byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
  607. .byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
  608. .byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
  609. .byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
  610. .byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
  611. .byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
  612. .byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
  613. .byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
  614. .byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
  615. ; .balign 256
  616. usbCrcTableHigh:
  617. .byte 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2
  618. .byte 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04
  619. .byte 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E
  620. .byte 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8
  621. .byte 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A
  622. .byte 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC
  623. .byte 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6
  624. .byte 0xD2, 0x12, 0x13, 0xD3, 0x11, 0xD1, 0xD0, 0x10
  625. .byte 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32
  626. .byte 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4
  627. .byte 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE
  628. .byte 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38
  629. .byte 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA
  630. .byte 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C
  631. .byte 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26
  632. .byte 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0
  633. .byte 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62
  634. .byte 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4
  635. .byte 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE
  636. .byte 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68
  637. .byte 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA
  638. .byte 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C
  639. .byte 0xB4, 0x74, 0x75, 0xB5, 0x77, 0xB7, 0xB6, 0x76
  640. .byte 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0
  641. .byte 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92
  642. .byte 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54
  643. .byte 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E
  644. .byte 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98
  645. .byte 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A
  646. .byte 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C
  647. .byte 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86
  648. .byte 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, 0x40