Ingen beskrivning
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

usbdrvasm.S 8.7KB

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