usbdrvasm.S 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. /* Name: usbdrvasm.S
  2. * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
  3. * Author: Christian Starkjohann
  4. * Creation Date: 2007-06-13
  5. * Tabsize: 4
  6. * Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
  7. * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
  8. * Revision: $Id: usbdrvasm.S 740 2009-04-13 18:23:31Z cs $
  9. */
  10. /*
  11. General Description:
  12. This module is the assembler part of the USB driver. This file contains
  13. general code (preprocessor acrobatics and CRC computation) and then includes
  14. the file appropriate for the given clock rate.
  15. */
  16. #define __SFR_OFFSET 0 /* used by avr-libc's register definitions */
  17. #include "usbportability.h"
  18. #include "usbdrv.h" /* for common defs */
  19. /* register names */
  20. #define x1 r16
  21. #define x2 r17
  22. #define shift r18
  23. #define cnt r19
  24. #define x3 r20
  25. #define x4 r21
  26. #define x5 r22
  27. #define bitcnt x5
  28. #define phase x4
  29. #define leap x4
  30. /* Some assembler dependent definitions and declarations: */
  31. #ifdef __IAR_SYSTEMS_ASM__
  32. extern usbRxBuf, usbDeviceAddr, usbNewDeviceAddr, usbInputBufOffset
  33. extern usbCurrentTok, usbRxLen, usbRxToken, usbTxLen
  34. extern usbTxBuf, usbTxStatus1, usbTxStatus3
  35. # if USB_COUNT_SOF
  36. extern usbSofCount
  37. # endif
  38. public usbCrc16
  39. public usbCrc16Append
  40. COMMON INTVEC
  41. # ifndef USB_INTR_VECTOR
  42. ORG INT0_vect
  43. # else /* USB_INTR_VECTOR */
  44. ORG USB_INTR_VECTOR
  45. # undef USB_INTR_VECTOR
  46. # endif /* USB_INTR_VECTOR */
  47. # define USB_INTR_VECTOR usbInterruptHandler
  48. rjmp USB_INTR_VECTOR
  49. RSEG CODE
  50. #else /* __IAR_SYSTEMS_ASM__ */
  51. # ifndef USB_INTR_VECTOR /* default to hardware interrupt INT0 */
  52. # define USB_INTR_VECTOR SIG_INTERRUPT0
  53. # endif
  54. .text
  55. .global USB_INTR_VECTOR
  56. .type USB_INTR_VECTOR, @function
  57. .global usbCrc16
  58. .global usbCrc16Append
  59. #endif /* __IAR_SYSTEMS_ASM__ */
  60. #if USB_INTR_PENDING < 0x40 /* This is an I/O address, use in and out */
  61. # define USB_LOAD_PENDING(reg) in reg, USB_INTR_PENDING
  62. # define USB_STORE_PENDING(reg) out USB_INTR_PENDING, reg
  63. #else /* It's a memory address, use lds and sts */
  64. # define USB_LOAD_PENDING(reg) lds reg, USB_INTR_PENDING
  65. # define USB_STORE_PENDING(reg) sts USB_INTR_PENDING, reg
  66. #endif
  67. #define usbTxLen1 usbTxStatus1
  68. #define usbTxBuf1 (usbTxStatus1 + 1)
  69. #define usbTxLen3 usbTxStatus3
  70. #define usbTxBuf3 (usbTxStatus3 + 1)
  71. ;----------------------------------------------------------------------------
  72. ; Utility functions
  73. ;----------------------------------------------------------------------------
  74. #ifdef __IAR_SYSTEMS_ASM__
  75. /* Register assignments for usbCrc16 on IAR cc */
  76. /* Calling conventions on IAR:
  77. * First parameter passed in r16/r17, second in r18/r19 and so on.
  78. * Callee must preserve r4-r15, r24-r29 (r28/r29 is frame pointer)
  79. * Result is passed in r16/r17
  80. * In case of the "tiny" memory model, pointers are only 8 bit with no
  81. * padding. We therefore pass argument 1 as "16 bit unsigned".
  82. */
  83. RTMODEL "__rt_version", "3"
  84. /* The line above will generate an error if cc calling conventions change.
  85. * The value "3" above is valid for IAR 4.10B/W32
  86. */
  87. # define argLen r18 /* argument 2 */
  88. # define argPtrL r16 /* argument 1 */
  89. # define argPtrH r17 /* argument 1 */
  90. # define resCrcL r16 /* result */
  91. # define resCrcH r17 /* result */
  92. # define ptrL ZL
  93. # define ptrH ZH
  94. # define ptr Z
  95. # define byte r22
  96. # define bitCnt r19
  97. # define polyL r20
  98. # define polyH r21
  99. # define scratch r23
  100. #else /* __IAR_SYSTEMS_ASM__ */
  101. /* Register assignments for usbCrc16 on gcc */
  102. /* Calling conventions on gcc:
  103. * First parameter passed in r24/r25, second in r22/23 and so on.
  104. * Callee must preserve r1-r17, r28/r29
  105. * Result is passed in r24/r25
  106. */
  107. # define argLen r22 /* argument 2 */
  108. # define argPtrL r24 /* argument 1 */
  109. # define argPtrH r25 /* argument 1 */
  110. # define resCrcL r24 /* result */
  111. # define resCrcH r25 /* result */
  112. # define ptrL XL
  113. # define ptrH XH
  114. # define ptr x
  115. # define byte r18
  116. # define bitCnt r19
  117. # define polyL r20
  118. # define polyH r21
  119. # define scratch r23
  120. #endif
  121. ; extern unsigned usbCrc16(unsigned char *data, unsigned char len);
  122. ; data: r24/25
  123. ; len: r22
  124. ; temp variables:
  125. ; r18: data byte
  126. ; r19: bit counter
  127. ; r20/21: polynomial
  128. ; r23: scratch
  129. ; r24/25: crc-sum
  130. ; r26/27=X: ptr
  131. usbCrc16:
  132. mov ptrL, argPtrL
  133. mov ptrH, argPtrH
  134. ldi resCrcL, 0
  135. ldi resCrcH, 0
  136. ldi polyL, lo8(0xa001)
  137. ldi polyH, hi8(0xa001)
  138. com argLen ; argLen = -argLen - 1
  139. crcByteLoop:
  140. subi argLen, -1
  141. brcc crcReady ; modified loop to ensure that carry is set below
  142. ld byte, ptr+
  143. ldi bitCnt, -8 ; strange loop counter to ensure that carry is set where we need it
  144. eor resCrcL, byte
  145. crcBitLoop:
  146. ror resCrcH ; carry is always set here
  147. ror resCrcL
  148. brcs crcNoXor
  149. eor resCrcL, polyL
  150. eor resCrcH, polyH
  151. crcNoXor:
  152. subi bitCnt, -1
  153. brcs crcBitLoop
  154. rjmp crcByteLoop
  155. crcReady:
  156. ret
  157. ; Thanks to Reimar Doeffinger for optimizing this CRC routine!
  158. ; extern unsigned usbCrc16Append(unsigned char *data, unsigned char len);
  159. usbCrc16Append:
  160. rcall usbCrc16
  161. st ptr+, resCrcL
  162. st ptr+, resCrcH
  163. ret
  164. #undef argLen
  165. #undef argPtrL
  166. #undef argPtrH
  167. #undef resCrcL
  168. #undef resCrcH
  169. #undef ptrL
  170. #undef ptrH
  171. #undef ptr
  172. #undef byte
  173. #undef bitCnt
  174. #undef polyL
  175. #undef polyH
  176. #undef scratch
  177. #if USB_CFG_HAVE_MEASURE_FRAME_LENGTH
  178. #ifdef __IAR_SYSTEMS_ASM__
  179. /* Register assignments for usbMeasureFrameLength on IAR cc */
  180. /* Calling conventions on IAR:
  181. * First parameter passed in r16/r17, second in r18/r19 and so on.
  182. * Callee must preserve r4-r15, r24-r29 (r28/r29 is frame pointer)
  183. * Result is passed in r16/r17
  184. * In case of the "tiny" memory model, pointers are only 8 bit with no
  185. * padding. We therefore pass argument 1 as "16 bit unsigned".
  186. */
  187. # define resL r16
  188. # define resH r17
  189. # define cnt16L r30
  190. # define cnt16H r31
  191. # define cntH r18
  192. #else /* __IAR_SYSTEMS_ASM__ */
  193. /* Register assignments for usbMeasureFrameLength on gcc */
  194. /* Calling conventions on gcc:
  195. * First parameter passed in r24/r25, second in r22/23 and so on.
  196. * Callee must preserve r1-r17, r28/r29
  197. * Result is passed in r24/r25
  198. */
  199. # define resL r24
  200. # define resH r25
  201. # define cnt16L r24
  202. # define cnt16H r25
  203. # define cntH r26
  204. #endif
  205. # define cnt16 cnt16L
  206. ; extern unsigned usbMeasurePacketLength(void);
  207. ; returns time between two idle strobes in multiples of 7 CPU clocks
  208. .global usbMeasureFrameLength
  209. usbMeasureFrameLength:
  210. ldi cntH, 6 ; wait ~ 10 ms for D- == 0
  211. clr cnt16L
  212. clr cnt16H
  213. usbMFTime16:
  214. dec cntH
  215. breq usbMFTimeout
  216. usbMFWaitStrobe: ; first wait for D- == 0 (idle strobe)
  217. sbiw cnt16, 1 ;[0] [6]
  218. breq usbMFTime16 ;[2]
  219. sbic USBIN, USBMINUS ;[3]
  220. rjmp usbMFWaitStrobe ;[4]
  221. usbMFWaitIdle: ; then wait until idle again
  222. sbis USBIN, USBMINUS ;1 wait for D- == 1
  223. rjmp usbMFWaitIdle ;2
  224. ldi cnt16L, 1 ;1 represents cycles so far
  225. clr cnt16H ;1
  226. usbMFWaitLoop:
  227. in cntH, USBIN ;[0] [7]
  228. adiw cnt16, 1 ;[1]
  229. breq usbMFTimeout ;[3]
  230. andi cntH, USBMASK ;[4]
  231. brne usbMFWaitLoop ;[5]
  232. usbMFTimeout:
  233. #if resL != cnt16L
  234. mov resL, cnt16L
  235. mov resH, cnt16H
  236. #endif
  237. ret
  238. #undef resL
  239. #undef resH
  240. #undef cnt16
  241. #undef cnt16L
  242. #undef cnt16H
  243. #undef cntH
  244. #endif /* USB_CFG_HAVE_MEASURE_FRAME_LENGTH */
  245. ;----------------------------------------------------------------------------
  246. ; Now include the clock rate specific code
  247. ;----------------------------------------------------------------------------
  248. #ifndef USB_CFG_CLOCK_KHZ
  249. # define USB_CFG_CLOCK_KHZ 12000
  250. #endif
  251. #if USB_CFG_CHECK_CRC /* separate dispatcher for CRC type modules */
  252. # if USB_CFG_CLOCK_KHZ == 18000
  253. # include "usbdrvasm18-crc.inc"
  254. # else
  255. # error "USB_CFG_CLOCK_KHZ is not one of the supported crc-rates!"
  256. # endif
  257. #else /* USB_CFG_CHECK_CRC */
  258. # if USB_CFG_CLOCK_KHZ == 12000
  259. # include "usbdrvasm12.inc"
  260. # elif USB_CFG_CLOCK_KHZ == 12800
  261. # include "usbdrvasm128.inc"
  262. # elif USB_CFG_CLOCK_KHZ == 15000
  263. # include "usbdrvasm15.inc"
  264. # elif USB_CFG_CLOCK_KHZ == 16000
  265. # include "usbdrvasm16.inc"
  266. # elif USB_CFG_CLOCK_KHZ == 16500
  267. # include "usbdrvasm165.inc"
  268. # elif USB_CFG_CLOCK_KHZ == 20000
  269. # include "usbdrvasm20.inc"
  270. # else
  271. # error "USB_CFG_CLOCK_KHZ is not one of the supported non-crc-rates!"
  272. # endif
  273. #endif /* USB_CFG_CHECK_CRC */