Нема описа
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

usbdrvasm165.inc 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. /* Name: usbdrvasm165.inc
  2. * Project: AVR USB driver
  3. * Author: Christian Starkjohann
  4. * Creation Date: 2007-04-22
  5. * Tabsize: 4
  6. * Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
  7. * License: GNU GPL v2 (see License.txt) or proprietary (CommercialLicense.txt)
  8. * Revision: $Id$
  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 16.5 MHz version of the USB driver. It is intended for the
  16. ATTiny45 and similar controllers running on 16.5 MHz internal RC oscillator.
  17. This version contains a phase locked loop in the receiver routine to cope with
  18. slight clock rate deviations of up to +/- 1%.
  19. See usbdrv.h for a description of the entire driver.
  20. Since almost all of this code is timing critical, don't change unless you
  21. really know what you are doing! Many parts require not only a maximum number
  22. of CPU cycles, but even an exact number of cycles!
  23. */
  24. ;Software-receiver engine. Strict timing! Don't change unless you can preserve timing!
  25. ;interrupt response time: 4 cycles + insn running = 7 max if interrupts always enabled
  26. ;max allowable interrupt latency: 59 cycles -> max 52 cycles interrupt disable
  27. ;max stack usage: [ret(2), r0, SREG, YL, YH, shift, x1, x2, x3, x4, cnt] = 12 bytes
  28. ;nominal frequency: 16.5 MHz -> 11 cycles per bit
  29. ; 16.3125 MHz < F_CPU < 16.6875 MHz (+/- 1.1%)
  30. ; Numbers in brackets are clocks counted from center of last sync bit
  31. ; when instruction starts
  32. USB_INTR_VECTOR:
  33. ;order of registers pushed: YL, SREG [sofError], r0, YH, shift, x1, x2, x3, x4, cnt
  34. push YL ;[-23] push only what is necessary to sync with edge ASAP
  35. in YL, SREG ;[-21]
  36. push YL ;[-20]
  37. ;----------------------------------------------------------------------------
  38. ; Synchronize with sync pattern:
  39. ;----------------------------------------------------------------------------
  40. ;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K]
  41. ;sync up with J to K edge during sync pattern -- use fastest possible loops
  42. ;first part has no timeout because it waits for IDLE or SE1 (== disconnected)
  43. waitForJ:
  44. sbis USBIN, USBMINUS ;[-18] wait for D- == 1
  45. rjmp waitForJ
  46. waitForK:
  47. ;The following code results in a sampling window of < 1/4 bit which meets the spec.
  48. sbis USBIN, USBMINUS ;[-15]
  49. rjmp foundK ;[-14]
  50. sbis USBIN, USBMINUS
  51. rjmp foundK
  52. sbis USBIN, USBMINUS
  53. rjmp foundK
  54. sbis USBIN, USBMINUS
  55. rjmp foundK
  56. sbis USBIN, USBMINUS
  57. rjmp foundK
  58. sbis USBIN, USBMINUS
  59. rjmp foundK
  60. #if USB_COUNT_SOF
  61. lds YL, usbSofCount
  62. inc YL
  63. sts usbSofCount, YL
  64. #endif /* USB_COUNT_SOF */
  65. rjmp sofError
  66. foundK: ;[-12]
  67. ;{3, 5} after falling D- edge, average delay: 4 cycles [we want 5 for center sampling]
  68. ;we have 1 bit time for setup purposes, then sample again. Numbers in brackets
  69. ;are cycles from center of first sync (double K) bit after the instruction
  70. push r0 ;[-12]
  71. ; [---] ;[-11]
  72. push YH ;[-10]
  73. ; [---] ;[-9]
  74. lds YL, usbInputBufOffset;[-8]
  75. ; [---] ;[-7]
  76. clr YH ;[-6]
  77. subi YL, lo8(-(usbRxBuf));[-5] [rx loop init]
  78. sbci YH, hi8(-(usbRxBuf));[-4] [rx loop init]
  79. mov r0, x2 ;[-3] [rx loop init]
  80. sbis USBIN, USBMINUS ;[-2] we want two bits K (sample 2 cycles too early)
  81. rjmp haveTwoBitsK ;[-1]
  82. pop YH ;[0] undo the pushes from before
  83. pop r0 ;[2]
  84. rjmp waitForK ;[4] this was not the end of sync, retry
  85. ; The entire loop from waitForK until rjmp waitForK above must not exceed two
  86. ; bit times (= 22 cycles).
  87. ;----------------------------------------------------------------------------
  88. ; push more registers and initialize values while we sample the first bits:
  89. ;----------------------------------------------------------------------------
  90. haveTwoBitsK: ;[1]
  91. push shift ;[1]
  92. push x1 ;[3]
  93. push x2 ;[5]
  94. push x3 ;[7]
  95. ldi shift, 0xff ;[9] [rx loop init]
  96. ori x3, 0xff ;[10] [rx loop init] == ser x3, clear zero flag
  97. in x1, USBIN ;[11] <-- sample bit 0
  98. bst x1, USBMINUS ;[12]
  99. bld shift, 0 ;[13]
  100. push x4 ;[14] == phase
  101. ; [---] ;[15]
  102. push cnt ;[16]
  103. ; [---] ;[17]
  104. ldi phase, 0 ;[18] [rx loop init]
  105. ldi cnt, USB_BUFSIZE;[19] [rx loop init]
  106. rjmp rxbit1 ;[20]
  107. ; [---] ;[21]
  108. ;----------------------------------------------------------------------------
  109. ; Receiver loop (numbers in brackets are cycles within byte after instr)
  110. ;----------------------------------------------------------------------------
  111. /*
  112. byte oriented operations done during loop:
  113. bit 0: store data
  114. bit 1: SE0 check
  115. bit 2: overflow check
  116. bit 3: catch up
  117. bit 4: rjmp to achieve conditional jump range
  118. bit 5: PLL
  119. bit 6: catch up
  120. bit 7: jump, fixup bitstuff
  121. ; 87 [+ 2] cycles
  122. ------------------------------------------------------------------
  123. */
  124. continueWithBit5:
  125. in x2, USBIN ;[055] <-- bit 5
  126. eor r0, x2 ;[056]
  127. or phase, r0 ;[057]
  128. sbrc phase, USBMINUS ;[058]
  129. lpm ;[059] optional nop3; modifies r0
  130. in phase, USBIN ;[060] <-- phase
  131. eor x1, x2 ;[061]
  132. bst x1, USBMINUS ;[062]
  133. bld shift, 5 ;[063]
  134. andi shift, 0x3f ;[064]
  135. in x1, USBIN ;[065] <-- bit 6
  136. breq unstuff5 ;[066] *** unstuff escape
  137. eor phase, x1 ;[067]
  138. eor x2, x1 ;[068]
  139. bst x2, USBMINUS ;[069]
  140. bld shift, 6 ;[070]
  141. didUnstuff6: ;[ ]
  142. in r0, USBIN ;[071] <-- phase
  143. cpi shift, 0x02 ;[072]
  144. brlo unstuff6 ;[073] *** unstuff escape
  145. didUnstuff5: ;[ ]
  146. nop2 ;[074]
  147. ; [---] ;[075]
  148. in x2, USBIN ;[076] <-- bit 7
  149. eor x1, x2 ;[077]
  150. bst x1, USBMINUS ;[078]
  151. bld shift, 7 ;[079]
  152. didUnstuff7: ;[ ]
  153. eor r0, x2 ;[080]
  154. or phase, r0 ;[081]
  155. in r0, USBIN ;[082] <-- phase
  156. cpi shift, 0x04 ;[083]
  157. brsh rxLoop ;[084]
  158. ; [---] ;[085]
  159. unstuff7: ;[ ]
  160. andi x3, ~0x80 ;[085]
  161. ori shift, 0x80 ;[086]
  162. in x2, USBIN ;[087] <-- sample stuffed bit 7
  163. nop ;[088]
  164. rjmp didUnstuff7 ;[089]
  165. ; [---] ;[090]
  166. ;[080]
  167. unstuff5: ;[067]
  168. eor phase, x1 ;[068]
  169. andi x3, ~0x20 ;[069]
  170. ori shift, 0x20 ;[070]
  171. in r0, USBIN ;[071] <-- phase
  172. mov x2, x1 ;[072]
  173. nop ;[073]
  174. nop2 ;[074]
  175. ; [---] ;[075]
  176. in x1, USBIN ;[076] <-- bit 6
  177. eor r0, x1 ;[077]
  178. or phase, r0 ;[078]
  179. eor x2, x1 ;[079]
  180. bst x2, USBMINUS ;[080]
  181. bld shift, 6 ;[081] no need to check bitstuffing, we just had one
  182. in r0, USBIN ;[082] <-- phase
  183. rjmp didUnstuff5 ;[083]
  184. ; [---] ;[084]
  185. ;[074]
  186. unstuff6: ;[074]
  187. andi x3, ~0x40 ;[075]
  188. in x1, USBIN ;[076] <-- bit 6 again
  189. ori shift, 0x40 ;[077]
  190. nop2 ;[078]
  191. ; [---] ;[079]
  192. rjmp didUnstuff6 ;[080]
  193. ; [---] ;[081]
  194. ;[071]
  195. unstuff0: ;[013]
  196. eor r0, x2 ;[014]
  197. or phase, r0 ;[015]
  198. andi x2, USBMASK ;[016] check for SE0
  199. in r0, USBIN ;[017] <-- phase
  200. breq didUnstuff0 ;[018] direct jump to se0 would be too long
  201. andi x3, ~0x01 ;[019]
  202. ori shift, 0x01 ;[020]
  203. mov x1, x2 ;[021] mov existing sample
  204. in x2, USBIN ;[022] <-- bit 1 again
  205. rjmp didUnstuff0 ;[023]
  206. ; [---] ;[024]
  207. ;[014]
  208. unstuff1: ;[024]
  209. eor r0, x1 ;[025]
  210. or phase, r0 ;[026]
  211. andi x3, ~0x02 ;[027]
  212. in r0, USBIN ;[028] <-- phase
  213. ori shift, 0x02 ;[029]
  214. mov x2, x1 ;[030]
  215. rjmp didUnstuff1 ;[031]
  216. ; [---] ;[032]
  217. ;[022]
  218. unstuff2: ;[035]
  219. eor r0, x2 ;[036]
  220. or phase, r0 ;[037]
  221. andi x3, ~0x04 ;[038]
  222. in r0, USBIN ;[039] <-- phase
  223. ori shift, 0x04 ;[040]
  224. mov x1, x2 ;[041]
  225. rjmp didUnstuff2 ;[042]
  226. ; [---] ;[043]
  227. ;[033]
  228. unstuff3: ;[043]
  229. in x2, USBIN ;[044] <-- bit 3 again
  230. eor r0, x2 ;[045]
  231. or phase, r0 ;[046]
  232. andi x3, ~0x08 ;[047]
  233. ori shift, 0x08 ;[048]
  234. nop ;[049]
  235. in r0, USBIN ;[050] <-- phase
  236. rjmp didUnstuff3 ;[051]
  237. ; [---] ;[052]
  238. ;[042]
  239. unstuff4: ;[053]
  240. andi x3, ~0x10 ;[054]
  241. in x1, USBIN ;[055] <-- bit 4 again
  242. ori shift, 0x10 ;[056]
  243. rjmp didUnstuff4 ;[057]
  244. ; [---] ;[058]
  245. ;[048]
  246. rxLoop: ;[085]
  247. eor x3, shift ;[086] reconstruct: x3 is 0 at bit locations we changed, 1 at others
  248. in x1, USBIN ;[000] <-- bit 0
  249. st y+, x3 ;[001]
  250. ; [---] ;[002]
  251. eor r0, x1 ;[003]
  252. or phase, r0 ;[004]
  253. eor x2, x1 ;[005]
  254. in r0, USBIN ;[006] <-- phase
  255. ser x3 ;[007]
  256. bst x2, USBMINUS ;[008]
  257. bld shift, 0 ;[009]
  258. andi shift, 0xf9 ;[010]
  259. rxbit1: ;[ ]
  260. in x2, USBIN ;[011] <-- bit 1
  261. breq unstuff0 ;[012] *** unstuff escape
  262. andi x2, USBMASK ;[013] SE0 check for bit 1
  263. didUnstuff0: ;[ ] Z only set if we detected SE0 in bitstuff
  264. breq se0 ;[014]
  265. eor r0, x2 ;[015]
  266. or phase, r0 ;[016]
  267. in r0, USBIN ;[017] <-- phase
  268. eor x1, x2 ;[018]
  269. bst x1, USBMINUS ;[019]
  270. bld shift, 1 ;[020]
  271. andi shift, 0xf3 ;[021]
  272. didUnstuff1: ;[ ]
  273. in x1, USBIN ;[022] <-- bit 2
  274. breq unstuff1 ;[023] *** unstuff escape
  275. eor r0, x1 ;[024]
  276. or phase, r0 ;[025]
  277. subi cnt, 1 ;[026] overflow check
  278. brcs overflow ;[027]
  279. in r0, USBIN ;[028] <-- phase
  280. eor x2, x1 ;[029]
  281. bst x2, USBMINUS ;[030]
  282. bld shift, 2 ;[031]
  283. andi shift, 0xe7 ;[032]
  284. didUnstuff2: ;[ ]
  285. in x2, USBIN ;[033] <-- bit 3
  286. breq unstuff2 ;[034] *** unstuff escape
  287. eor r0, x2 ;[035]
  288. or phase, r0 ;[036]
  289. eor x1, x2 ;[037]
  290. bst x1, USBMINUS ;[038]
  291. in r0, USBIN ;[039] <-- phase
  292. bld shift, 3 ;[040]
  293. andi shift, 0xcf ;[041]
  294. didUnstuff3: ;[ ]
  295. breq unstuff3 ;[042] *** unstuff escape
  296. nop ;[043]
  297. in x1, USBIN ;[044] <-- bit 4
  298. eor x2, x1 ;[045]
  299. bst x2, USBMINUS ;[046]
  300. bld shift, 4 ;[047]
  301. didUnstuff4: ;[ ]
  302. eor r0, x1 ;[048]
  303. or phase, r0 ;[049]
  304. in r0, USBIN ;[050] <-- phase
  305. andi shift, 0x9f ;[051]
  306. breq unstuff4 ;[052] *** unstuff escape
  307. rjmp continueWithBit5;[053]
  308. ; [---] ;[054]
  309. macro POP_STANDARD ; 16 cycles
  310. pop cnt
  311. pop x4
  312. pop x3
  313. pop x2
  314. pop x1
  315. pop shift
  316. pop YH
  317. pop r0
  318. endm
  319. macro POP_RETI ; 5 cycles
  320. pop YL
  321. out SREG, YL
  322. pop YL
  323. endm
  324. #include "asmcommon.inc"
  325. ; USB spec says:
  326. ; idle = J
  327. ; J = (D+ = 0), (D- = 1)
  328. ; K = (D+ = 1), (D- = 0)
  329. ; Spec allows 7.5 bit times from EOP to SOP for replies
  330. bitstuff7:
  331. eor x1, x4 ;[4]
  332. ldi x2, 0 ;[5]
  333. nop2 ;[6] C is zero (brcc)
  334. rjmp didStuff7 ;[8]
  335. bitstuffN:
  336. eor x1, x4 ;[5]
  337. ldi x2, 0 ;[6]
  338. lpm ;[7] 3 cycle NOP, modifies r0
  339. out USBOUT, x1 ;[10] <-- out
  340. rjmp didStuffN ;[0]
  341. #define bitStatus x3
  342. sendNakAndReti:
  343. ldi cnt, USBPID_NAK ;[-19]
  344. rjmp sendCntAndReti ;[-18]
  345. sendAckAndReti:
  346. ldi cnt, USBPID_ACK ;[-17]
  347. sendCntAndReti:
  348. mov r0, cnt ;[-16]
  349. ldi YL, 0 ;[-15] R0 address is 0
  350. ldi YH, 0 ;[-14]
  351. ldi cnt, 2 ;[-13]
  352. ; rjmp usbSendAndReti fallthrough
  353. ;usbSend:
  354. ;pointer to data in 'Y'
  355. ;number of bytes in 'cnt' -- including sync byte [range 2 ... 12]
  356. ;uses: x1...x4, shift, cnt, Y
  357. ;Numbers in brackets are time since first bit of sync pattern is sent
  358. usbSendAndReti: ; 12 cycles until SOP
  359. in x2, USBDDR ;[-12]
  360. ori x2, USBMASK ;[-11]
  361. sbi USBOUT, USBMINUS;[-10] prepare idle state; D+ and D- must have been 0 (no pullups)
  362. in x1, USBOUT ;[-8] port mirror for tx loop
  363. out USBDDR, x2 ;[-7] <- acquire bus
  364. ; need not init x2 (bitstuff history) because sync starts with 0
  365. ldi x4, USBMASK ;[-6] exor mask
  366. ldi shift, 0x80 ;[-5] sync byte is first byte sent
  367. ldi bitStatus, 0xff ;[-4] init bit loop counter, works for up to 12 bytes
  368. byteloop:
  369. bitloop:
  370. sbrs shift, 0 ;[8] [-3]
  371. eor x1, x4 ;[9] [-2]
  372. out USBOUT, x1 ;[10] [-1] <-- out
  373. ror shift ;[0]
  374. ror x2 ;[1]
  375. didStuffN:
  376. cpi x2, 0xfc ;[2]
  377. brcc bitstuffN ;[3]
  378. nop ;[4]
  379. subi bitStatus, 37 ;[5] 256 / 7 ~=~ 37
  380. brcc bitloop ;[6] when we leave the loop, bitStatus has almost the initial value
  381. sbrs shift, 0 ;[7]
  382. eor x1, x4 ;[8]
  383. ror shift ;[9]
  384. didStuff7:
  385. out USBOUT, x1 ;[10] <-- out
  386. ror x2 ;[0]
  387. cpi x2, 0xfc ;[1]
  388. brcc bitstuff7 ;[2]
  389. ld shift, y+ ;[3]
  390. dec cnt ;[5]
  391. brne byteloop ;[6]
  392. ;make SE0:
  393. cbr x1, USBMASK ;[7] prepare SE0 [spec says EOP may be 21 to 25 cycles]
  394. lds x2, usbNewDeviceAddr;[8]
  395. lsl x2 ;[10] we compare with left shifted address
  396. out USBOUT, x1 ;[11] <-- out SE0 -- from now 2 bits = 22 cycles until bus idle
  397. ;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm:
  398. ;set address only after data packet was sent, not after handshake
  399. subi YL, 2 ;[0] Only assign address on data packets, not ACK/NAK in r0
  400. sbci YH, 0 ;[1]
  401. breq skipAddrAssign ;[2]
  402. sts usbDeviceAddr, x2; if not skipped: SE0 is one cycle longer
  403. skipAddrAssign:
  404. ;end of usbDeviceAddress transfer
  405. ldi x2, 1<<USB_INTR_PENDING_BIT;[4] int0 occurred during TX -- clear pending flag
  406. USB_STORE_PENDING(x2) ;[5]
  407. ori x1, USBIDLE ;[6]
  408. in x2, USBDDR ;[7]
  409. cbr x2, USBMASK ;[8] set both pins to input
  410. mov x3, x1 ;[9]
  411. cbr x3, USBMASK ;[10] configure no pullup on both pins
  412. ldi x4, 4 ;[11]
  413. se0Delay:
  414. dec x4 ;[12] [15] [18] [21]
  415. brne se0Delay ;[13] [16] [19] [22]
  416. out USBOUT, x1 ;[23] <-- out J (idle) -- end of SE0 (EOP signal)
  417. out USBDDR, x2 ;[24] <-- release bus now
  418. out USBOUT, x3 ;[25] <-- ensure no pull-up resistors are active
  419. rjmp doReturn