usbd_stm32f103_devfs_asm.S 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865
  1. /* This file is the part of the Lightweight USB device Stack for STM32 microcontrollers
  2. *
  3. * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. #if !defined (__ASSEMBLER__)
  16. #define __ASSEMBLER__
  17. #endif
  18. #include "usb.h"
  19. #if defined(USBD_STM32F103)
  20. #include "memmap.inc"
  21. #define EP_SETUP 0x0800
  22. #define EP_TYPE 0x0600
  23. #define EP_KIND 0x0100
  24. #define EP_ADDR 0x000F
  25. #define EP_RX_CTR 0x8000
  26. #define EP_RX_DTOG 0x4000
  27. #define EP_RX_STAT 0x3000
  28. #define EP_RX_SWBUF 0x0040
  29. #define EP_RX_DIS 0x0000
  30. #define EP_RX_STAL 0x1000
  31. #define EP_RX_NAK 0x2000
  32. #define EP_RX_VAL 0x3000
  33. #define EP_TX_CTR 0x0080
  34. #define EP_TX_DTOG 0x0040
  35. #define EP_TX_STAT 0x0030
  36. #define EP_TX_SWBUF 0x4000
  37. #define EP_TX_DIS 0x0000
  38. #define EP_TX_STAL 0x0010
  39. #define EP_TX_NAK 0x0020
  40. #define EP_TX_VAL 0x0030
  41. #if defined(STM32F302x8) || defined(STM32F302xE) || defined(STM32F303xE)
  42. #define RXADDR0 0x00
  43. #define RXCOUNT0 0x02
  44. #define RXADDR1 0x04
  45. #define RXCOUNT1 0x06
  46. #define USB_PMASZ 0x300
  47. #define USB_PMASTP 0x02
  48. #define EPT_SHIFT 3
  49. #else
  50. #define RXADDR0 0x00
  51. #define RXCOUNT0 0x04
  52. #define RXADDR1 0x08
  53. #define RXCOUNT1 0x0C
  54. #define USB_PMASZ 0x200
  55. #define USB_PMASTP 0x04
  56. #define EPT_SHIFT 4
  57. #endif
  58. #define TXADDR0 RXADDR0
  59. #define TXCOUNT0 RXCOUNT0
  60. #define TXADDR1 RXADDR1
  61. #define TXCOUNT1 RXCOUNT1
  62. #define TXADDR RXADDR0
  63. #define TXCOUNT RXCOUNT0
  64. #define RXADDR RXADDR1
  65. #define RXCOUNT RXCOUNT1
  66. #define EP_NOTOG (EP_RX_CTR | EP_TX_CTR | EP_SETUP | EP_TYPE | EP_KIND | EP_ADDR)
  67. #define TGL_SET(mask, bits) ((EP_NOTOG | (mask))<<16 | (bits))
  68. #define TX_STALL TGL_SET(EP_TX_STAT, EP_TX_STAL)
  69. #define RX_STALL TGL_SET(EP_RX_STAT, EP_RX_STAL)
  70. #define TX_USTALL TGL_SET(EP_TX_STAT | EP_TX_DTOG, EP_TX_NAK)
  71. #define RX_USTALL TGL_SET(EP_RX_STAT | EP_RX_DTOG, EP_RX_VAL)
  72. #define DTX_USTALL TGL_SET(EP_TX_STAT | EP_TX_DTOG | EP_TX_SWBUF, EP_TX_VAL)
  73. #define DRX_USTALL TGL_SET(EP_RX_STAT | EP_RX_DTOG | EP_RX_SWBUF, EP_RX_VAL | EP_RX_SWBUF)
  74. #if (USBD_DP_PORT == GPIOA)
  75. #define RCC_GPIOxEN RCC_GPIOAEN
  76. #elif (USBD_DP_PORT == GPIOB)
  77. #define RCC_GPIOxEN RCC_GPIOBEN
  78. #elif (USBD_DP_PORT == GPIOC)
  79. #define RCC_GPIOxEN RCC_GPIOCEN
  80. #elif (USBD_DP_PORT == GPIOD)
  81. #define RCC_GPIOxEN RCC_GPIODEN
  82. #elif (USBD_DP_PORT == GPIOE)
  83. #define RCC_GPIOxEN RCC_GPIOEEN
  84. #elif (USBD_DP_PORT == GPIOF)
  85. #define RCC_GPIOxEN RCC_GPIOFEN
  86. #elif (USBD_DP_PORT == GPIOG)
  87. #define RCC_GPIOxEN RCC_GPIOGEN
  88. #elif (USBD_DP_PORT == GPIOH)
  89. #define RCC_GPIOxEN RCC_GPIOHEN
  90. #else
  91. #warning "No USB DP control used for F303"
  92. #undef USBD_DP_PORT
  93. #undef USBD_DP_PIN
  94. #endif
  95. .syntax unified
  96. .cpu cortex-m3
  97. .thumb
  98. .section .rodata.usbd_devfs_asm
  99. .align 4
  100. .globl usbd_devfs_asm
  101. usbd_devfs_asm:
  102. .long _getinfo
  103. .long _enable
  104. .long _connect
  105. .long _setaddr
  106. .long _ep_config
  107. .long _ep_deconfig
  108. .long _ep_read
  109. .long _ep_write
  110. .long _ep_setstall
  111. .long _ep_isstalled
  112. .long _evt_poll
  113. .long _get_frame
  114. .long _get_serial_desc
  115. .size usbd_devfs_asm, . - usbd_devfs_asm
  116. .text
  117. .align 2
  118. .thumb_func
  119. .type _get_serial_desc, %function
  120. /* uint16_t get_serial_desc (void *buffer)
  121. * R0 <- buffer for the string descriptor
  122. * descrpitor size -> R0
  123. */
  124. _get_serial_desc:
  125. push {r4, r5, lr}
  126. movs r1, #18 //descriptor size 18 bytes
  127. strb r1, [r0]
  128. movs r1, #0x03 //DTYPE_STRING
  129. strb r1, [r0, #0x01]
  130. ldr r5, .L_uid_base //UID3 this is the serial number
  131. ldr r4, .L_fnv1a_offset //FNV1A offset
  132. ldr r2, [r5, 0x00] //UID0
  133. bl .L_fnv1a
  134. ldr r2, [r5, 0x04] //UID1
  135. bl .L_fnv1a
  136. ldr r2, [r5, 0x08] //UID2
  137. bl .L_fnv1a
  138. movs r3, #28
  139. .L_gsn_loop:
  140. lsrs r1, r4, r3
  141. and r1, #0x0F
  142. cmp r1, #0x09
  143. ite gt
  144. addgt r1, #55
  145. addle r1, #48
  146. .L_gsn_store:
  147. adds r0, #0x02
  148. strb r1, [r0]
  149. lsrs r1, #0x08
  150. strb r1, [r0, #0x01]
  151. subs r3, #0x04
  152. bpl .L_gsn_loop
  153. movs r0, #18
  154. pop {r4, r5, pc}
  155. .L_fnv1a:
  156. movs r3, #0x04
  157. .L_fnv1a_loop:
  158. uxtb r1, r2
  159. eors r4, r1
  160. ldr r1, .L_fnv1a_prime //FNV1A prime
  161. muls r4, r1
  162. lsrs r2, #0x08
  163. subs r3, #0x01
  164. bne .L_fnv1a_loop
  165. bx lr
  166. .align 2
  167. .L_uid_base: .long UID_BASE
  168. .L_fnv1a_offset: .long 2166136261
  169. .L_fnv1a_prime: .long 16777619
  170. .size _get_serial_desc, . - _get_serial_desc
  171. .thumb_func
  172. .type _connect, %function
  173. _connect:
  174. #if defined(USBD_DP_PORT) && defined(USBD_DP_PIN) && defined(STM32F1)
  175. #if (USBD_DP_PIN < 8)
  176. #define GPIO_CRx GPIO_CRL
  177. #define DP_PIN (4 * USBD_DP_PIN)
  178. #else
  179. #define GPIO_CRx GPIO_CRH
  180. #define DP_PIN (4 * (USBD_DP_PIN - 8))
  181. #endif
  182. ldr r3, =USBD_DP_PORT
  183. ldr r2, [r3, #GPIO_CRx]
  184. movs r1, #0x0F
  185. bics r2, r2, r1, LSL #DP_PIN
  186. movs r1, #0x04
  187. cbz r0, .L_store
  188. movs r1, #0x01
  189. lsls r1, #USBD_DP_PIN
  190. str r1, [r3, #GPIO_BSRR]
  191. movs r1, #0x02
  192. .L_store:
  193. orrs r2, r2, r1, LSL #DP_PIN
  194. str r2, [r3, #GPIO_CRx]
  195. #elif defined(USBD_DP_PORT) && defined(USBD_DP_PIN) && defined(STM32F3)
  196. ldr r3, =USBD_DP_PORT
  197. ldr r2, [r3, #GPIO_MODER]
  198. movs r1, #0x03
  199. bics r2, r2, r1, LSL #(2 * USBD_DP_PIN)
  200. movs r1, #0x01
  201. cbz r0, .L_store
  202. orrs r2, r2, r1, LSL #(2 * USBD_DP_PIN)
  203. lsls r1, #USBD_DP_PIN
  204. str r1, [r3, #GPIO_BSRR]
  205. .L_store:
  206. str r2, [r3, #GPIO_MODER]
  207. #endif
  208. movs r0, #usbd_lane_unk
  209. bx lr
  210. .size _connect, . - _connect
  211. .thumb_func
  212. .type _setaddr, %function
  213. _setaddr:
  214. ldr r1, =USB_REGBASE
  215. adds r0, #0x80
  216. strh r0, [r1, #USB_DADDR] //USB->DADDR
  217. bx lr
  218. .size _setaddr, . - _setaddr
  219. .thumb_func
  220. .type _get_frame, %function
  221. _get_frame:
  222. ldr r0, =USB_REGBASE
  223. ldrh r0, [r0, #USB_FNR] //FNR
  224. lsls r0, #21
  225. lsrs r0, #21
  226. bx lr
  227. .size _get_frame, . - _get_frame
  228. .thumb_func
  229. .type _enable, %function
  230. _enable:
  231. ldr r2, =RCC_BASE //RCC
  232. movs r1, #0x01
  233. lsls r3, r1, #23 //USBEN or USBRST
  234. cbz r0, .L_disable
  235. .L_enable:
  236. /* enabling and resetting USB peripheral */
  237. /* enabling DP control GPIO port */
  238. #if defined(USBD_DP_PORT) && defined(USBD_DP_PIN) && defined(STM32F3)
  239. lsls r1, #RCC_GPIOxEN
  240. ldr r0, [r2, #RCC_AHBENR]
  241. orrs r0, r1
  242. str r0, [r2, #RCC_AHBENR]
  243. #elif defined(USBD_DP_PORT) && defined(USBD_DP_PIN)
  244. lsls r1, #RCC_GPIOxEN
  245. ldr r0, [r2, #RCC_APB2ENR]
  246. orrs r0, r1
  247. str r0, [r2, #RCC_APB2ENR]
  248. #endif
  249. ldr r1, =USB_REGBASE
  250. ldr r0, [r2, #RCC_APB1ENR]
  251. orrs r0, r3
  252. str r0, [r2, #RCC_APB1ENR] //RCC->APB1ENR |= USBEN
  253. ldr r0, [r2, #RCC_APB1RSTR]
  254. orrs r0, r3
  255. str r0, [r2, #RCC_APB1RSTR] //RCC->APB1RSTR |= USBRST
  256. bics r0, r3
  257. str r0, [r2, #RCC_APB1RSTR] //RCC->APB1RSTR &= ~USBRST
  258. /* setting up USB CNTR */
  259. #if !defined(USBD_SOF_DISABLED)
  260. movs r0, #0xBE // CTRM | ERRM | WKUPM | SUSPM | RESETM | SOFM
  261. #else
  262. movs r0, #0xBC // CTRM | ERRM | WKUPM | SUSPM | RESETM
  263. #endif
  264. lsls r0, #0x08
  265. strh r0, [r1, #USB_CNTR] //set USB->CNTR
  266. bx lr
  267. .L_disable:
  268. ldr r0, [r2, #RCC_APB1ENR]
  269. tst r0, r3
  270. beq .L_enable_end // usb is already disabled
  271. /* disabling USB peripheral */
  272. bics r0, r3
  273. str r0, [r2, #RCC_APB1ENR]
  274. movs r0, #0
  275. b _connect // jump to disconnect subroutine
  276. .L_enable_end:
  277. bx lr
  278. .size _enable, . - _enable
  279. .thumb_func
  280. .type _getinfo, %function
  281. _getinfo:
  282. movs r0, #0
  283. ldr r2, =RCC_BASE
  284. ldr r1, [r2, #RCC_APB1ENR]
  285. lsrs r1, #24 //USBEN -> CF
  286. bcc .L_getinfo_end
  287. adds r0, #USBD_HW_ENABLED
  288. #if defined(USBD_DP_PORT) && defined(USBD_DP_PIN)
  289. ldr r2, =USBD_DP_PORT
  290. ldr r1, [r2, #GPIO_IDR]
  291. lsrs r1, #USBD_DP_PIN //USBD_DP_PIN -> CF
  292. bcc .L_getinfo_end
  293. #endif
  294. adds r0, #USBD_HW_SPEED_FS
  295. .L_getinfo_end:
  296. bx lr
  297. .size _getinfo, . - _getinfo
  298. .thumb_func
  299. .type _ep_setstall, %function
  300. /*void ep_settall(uint8_t ep, bool stall)
  301. * in R0 <- endpoint number
  302. * in R1 <- 0 if unstall, !0 if stall
  303. */
  304. _ep_setstall:
  305. push {r4, lr}
  306. lsls r2, r0, #28
  307. lsrs r2, #26
  308. ldr r3, =USB_EPBASE
  309. adds r3, r2 // epr -> r3
  310. movs r2, 0x30 // TX_STAT_MASK -> r2
  311. ldrh r4, [r3]
  312. lsls r4, #21
  313. lsrs r4, #29 // EP_TYPE | EP_KIND -> R4 LSB
  314. cmp r4, #0x04 // ISO ?
  315. beq .L_eps_exit
  316. cmp r0, #0x80
  317. blo .L_eps_rx
  318. .L_eps_tx:
  319. ldr r0, =TX_STALL //stall TX
  320. cmp r1, #0x00
  321. bne .L_eps_reg_set
  322. .L_eps_tx_unstall:
  323. ldr r0, =DTX_USTALL //unstall dblbulk or iso TX (VALID and clr DTOG_TX & SWBUF_TX)
  324. cmp r4, #0x01 // if doublebuffered bulk endpoint
  325. beq .L_eps_reg_set
  326. ldr r0, =TX_USTALL // unstall other TX (NAKED + clr DTOG_TX)
  327. b .L_eps_reg_set
  328. .L_eps_rx:
  329. lsls r2, #8 // RX_STAT_MASK -> R2
  330. ldr r0,=RX_STALL //stall RX
  331. cmp r1, #0x00
  332. bne .L_eps_reg_set
  333. .L_eps_rx_unstall:
  334. ldr r0, =DRX_USTALL //unstall dblbulk or iso (VALID. clr DTOG_RX set SWBUF_RX)
  335. cmp r4, #0x01 // if dblbulk
  336. beq .L_eps_reg_set
  337. ldr r0, =RX_USTALL // unstall other RX (VALID + clr
  338. /* R0 - mask and toggle bits
  339. * R2 - mask for STAT bits
  340. * R3 - endpoint register pointer
  341. */
  342. .L_eps_reg_set:
  343. ldrh r1, [r3] // *epr -> r1
  344. ands r2, r1 // check if endpoint disabled
  345. beq .L_eps_exit // do nothing
  346. eors r1, r0
  347. lsrs r0, #16
  348. ands r1, r0
  349. strh r1, [r3]
  350. .L_eps_exit:
  351. pop {r4, pc}
  352. .size _ep_setstall, . - _ep_setstall
  353. .thumb_func
  354. .type _ep_isstalled, %function
  355. /* bool ep_isstalled(uint8t ep) */
  356. _ep_isstalled:
  357. ldr r1, =USB_EPBASE
  358. lsls r2, r0, #28
  359. lsrs r2, #26
  360. ldr r1, [r1, r2]
  361. lsls r1, #18
  362. cmp r0, #0x80
  363. blo .L_eis_check
  364. lsls r1, #8
  365. .L_eis_check:
  366. lsrs r0, r1, #30
  367. subs r0, #0x01
  368. subs r1, r0, #0x01
  369. sbcs r0, r0
  370. bx lr
  371. .size _ep_isstalled, . - _ep_isstalled
  372. .thumb_func
  373. .type _ep_read, %function
  374. /* int32_t _ep_read(uint8_t ep, void *buf, uint16_t blen)
  375. * in R0 <- endpoint
  376. * in R1 <- *buffer
  377. * in R2 <- length of the buffer
  378. * out length of the recieved data -> R0 or 0 on error
  379. */
  380. _ep_read:
  381. push {r4, r5, r6, lr}
  382. ldr r3, =USB_EPBASE
  383. ldr r6, =USB_PMABASE
  384. lsls r0, #28
  385. add r3, r3, r0, LSR #26 //*EPR -> R3
  386. add r4, r6, r0, LSR (28 - EPT_SHIFT) //*EPT -> R4
  387. ldrh r5, [r3] // reading epr
  388. /* validating endpoint */
  389. movs r0, #0x37
  390. ands r0, r0, r5, LSR #8
  391. cmp r0, #0x34 // (OK) RX_VALID + ISO
  392. beq .L_epr_iso
  393. cmp r0, #0x31 // (OK) RX_VALID + DBLBULK
  394. beq .L_epr_dbl
  395. cmp r0, #0x20 // (OK) RX_NAKED + BULK
  396. beq .L_epr_sngl
  397. cmp r0, #0x22 // (OK) RX_NAKED + CTRL
  398. beq .L_epr_sngl
  399. cmp r0, #0x26 // (OK) RX_NAKED + INTR
  400. beq .L_epr_sngl
  401. movs r0, #0xFF // endpoint contains no valid data
  402. sxtb r0, r0
  403. b .L_epr_exit
  404. /* processing */
  405. .L_epr_dbl:
  406. eors r0, r5, r5, LSR #8
  407. lsrs r0, #7 // SW_RX ^ DTOG_RX -> CF
  408. bcs .L_epr_notog // jmp if SW_RX != DTOG_RX (VALID)
  409. ldr r0, =EP_NOTOG
  410. ands r5, r0
  411. adds r5, #EP_RX_SWBUF
  412. strh r5, [r3] // toggling SW_RX
  413. .L_epr_notog:
  414. ldrh r5, [r3]
  415. lsls r5, #8 // shift SW_RX to DTOG_RX
  416. .L_epr_iso:
  417. lsrs r5, #15 // DTOG_RX -> CF
  418. bcs .L_epr_sngl
  419. subs r4, #RXADDR1 // set RXADDR0
  420. .L_epr_sngl:
  421. ldrh r0, [r4, #RXCOUNT]
  422. lsrs r5, r0, #0x0A
  423. lsls r5, #0x0A // r5 = r5 & ~0x03FF
  424. strh r5, [r4, #RXCOUNT]
  425. eors r0, r5 // r0 &= 0x3FF (RX count)
  426. ldrh r5, [r4, #RXADDR]
  427. adds r5, r6, r5, LSL (EPT_SHIFT - 3)
  428. cmp r2, r0
  429. blo .L_epr_read
  430. mov r2, r0 // if buffer is larger
  431. .L_epr_read:
  432. cmp r2, #1
  433. blo .L_epr_read_end
  434. ldrh r4, [r5]
  435. strb r4, [r1]
  436. beq .L_epr_read_end
  437. lsrs r4, #8
  438. strb r4, [r1, #1]
  439. adds r1, #2
  440. adds r5, #USB_PMASTP
  441. subs r2, #2
  442. bhi .L_epr_read
  443. .L_epr_read_end:
  444. ldrh r5, [r3] // reload EPR
  445. lsls r1, r5, #21
  446. lsrs r1, #29
  447. cmp r1, #0x04
  448. beq .L_epr_exit // ep is iso. no needs to set it to valid
  449. cmp r1, #0x01
  450. beq .L_epr_exit // ep is dblbulk. no needs to set it to valid
  451. ldr r2, =TGL_SET(EP_RX_STAT , EP_RX_VAL)
  452. eors r5, r2
  453. and r5, r5, r2, LSR #16
  454. strh r5, [r3] // set ep to VALID state
  455. .L_epr_exit:
  456. pop {r4, r5, r6, pc}
  457. .size _ep_read, . - _ep_read
  458. .thumb_func
  459. .type _ep_write, %function
  460. /* int32_t ep_write(uint8_t ep, const void *buf, uint16_t blen)
  461. * R0 -> endpoint
  462. * R1 -> *buffer
  463. * R2 -> data length
  464. * result -> R0
  465. */
  466. _ep_write:
  467. push {r4, r5, r6, lr}
  468. ldr r3, =USB_EPBASE
  469. ldr r6, =USB_PMABASE
  470. lsls r0, #28
  471. add r3, r3, r0, LSR #26 //*EPR -> R3
  472. add r4, r6, r0, LSR (28 - EPT_SHIFT) //*EPT -> R4
  473. ldrh r5, [r3] // reading epr
  474. movs r0, #0x73
  475. and r0, r0, r5, LSR #4
  476. cmp r0, #0x43 // (OK) TX_VALID + ISO
  477. beq .L_epw_iso
  478. cmp r0, #0x12 // (OK) TX_NAK + DBLBULK
  479. beq .L_epw_dbl
  480. cmp r0, #0x02 // (OK) TX_NAK + BULK
  481. beq .L_epw_sngl
  482. cmp r0, #0x22 // (OK) TX_NAK + CONTROL
  483. beq .L_epw_sngl
  484. cmp r0, #0x62 // (OK) TX_NAK + INTERRUPT
  485. beq .L_epw_sngl
  486. movs r0, #0xFF // -1 error
  487. sxtb r0, r0
  488. b .L_epw_exit
  489. .L_epw_dbl:
  490. mvns r5, r5
  491. lsrs r5, #8 // ~SWBUF_TX -> DTOG_TX
  492. .L_epw_iso:
  493. lsrs r5, #7 // DTOG_TX -> CF
  494. bcs .L_epw_sngl
  495. adds r4, #RXADDR1 // TXADDR1 -> R4
  496. .L_epw_sngl:
  497. strh r2, [r4, #TXCOUNT]
  498. mov r0, r2 // save count for return
  499. ldrh r5, [r4, #TXADDR]
  500. adds r5, r6, r5, LSL (EPT_SHIFT - 3)
  501. .L_epw_write:
  502. cmp r2, #1
  503. blo .L_epw_write_end
  504. ldrb r4, [r1]
  505. beq .L_epw_store
  506. ldrb r6, [r1, #1]
  507. orr r4, r4, r6, LSL #8
  508. .L_epw_store:
  509. strh r4, [r5]
  510. adds r5, #USB_PMASTP
  511. adds r1, #2
  512. subs r2, #2
  513. bhi .L_epw_write
  514. .L_epw_write_end:
  515. ldrh r5, [r3] // reload EPR
  516. lsls r1, r5, #21
  517. lsrs r1, #29
  518. cmp r1, #0x04
  519. beq .L_epw_exit // isochronous ep. do nothing
  520. ldr r2, =TGL_SET(EP_TX_STAT, EP_TX_VAL)
  521. cmp r1, #0x01
  522. bne .L_epw_setstate // NOT a doublebuffered bulk
  523. ldr r2, =TGL_SET(EP_TX_SWBUF, EP_TX_SWBUF)
  524. bics r5, r2 // clear TX_SWBUF
  525. .L_epw_setstate:
  526. eors r5, r2
  527. and r5, r5, r2, LSR #16
  528. strh r5, [r3]
  529. .L_epw_exit:
  530. pop {r4, r5, r6, pc}
  531. .size _ep_write, .- _ep_write
  532. /* internal function */
  533. /* requester size passed in R2 */
  534. /* result returns in R0 CF=1 if OK*/
  535. _get_next_pma:
  536. push {r1, r3, r4, lr}
  537. movs r1, #16
  538. ldr r3, =USB_PMASZ
  539. ldr r0, =USB_PMABASE
  540. .L_gnp_chkaddr:
  541. ldrh r4, [r0, #0] //txaddr
  542. tst r4, r4
  543. beq .L_gnp_nxtaddr
  544. cmp r3, r4
  545. blo .L_gnp_nxtaddr
  546. mov r3, r4
  547. .L_gnp_nxtaddr:
  548. adds r0, #RXADDR1
  549. subs r1, #1
  550. bne .L_gnp_chkaddr
  551. subs r0, r3, r2
  552. blo .L_gnp_exit
  553. cmp r0, #0x20 //check for the pma table overlap
  554. .L_gnp_exit:
  555. pop {r1, r3, r4, pc}
  556. .size _get_next_pma, . - _get_next_pma
  557. .thumb_func
  558. .type _ep_config, %function
  559. /* bool ep_config(uint8_t ep, uint8_t eptype, uint16_t epsize)
  560. * R0 <- ep
  561. * R1 <- eptype
  562. * R2 <- epsize
  563. * result -> R0
  564. */
  565. _ep_config:
  566. push {r4, r5, lr}
  567. movs r3, #0x01
  568. adds r2, r3
  569. bics r2, r3 //R2 -> halfword aligned epsize
  570. cmp r1, #0x06 //DBLBULK (0x01)
  571. beq .L_epc_settype
  572. movs r3, #0x00
  573. cmp r1, #0x02 //BULK
  574. beq .L_epc_settype
  575. movs r3, #0x02
  576. cmp r1, #0x00 //CONTROL
  577. beq .L_epc_settype
  578. movs r3, #0x04
  579. cmp r1, #0x01 //ISO
  580. beq .L_epc_settype
  581. movs r3, #0x06 //INTERRUPT
  582. .L_epc_settype:
  583. lsls r3, #8
  584. movs r4, #0x07
  585. ands r4, r0
  586. orrs r3, r4
  587. lsls r4, #2
  588. ldr r5, =USB_EPBASE
  589. strh r3, [r5, r4] //setup EPTYPE EPKIND EPADDR
  590. cmp r1, #0x00 // is a control ep ?
  591. beq .L_epc_setuptx
  592. cmp r0, #0x80
  593. blo .L_epc_setuprx
  594. .L_epc_setuptx:
  595. ldr r5, =USB_PMABASE
  596. adds r5, r5, r4, LSL (EPT_SHIFT - 2)
  597. bl _get_next_pma
  598. bcc .L_epc_fail
  599. strh r0, [r5, #TXADDR] //store txaddr or txaddr0
  600. movs r0, #0x00
  601. strh r0, [r5, #TXCOUNT] //store txcnt
  602. cmp r1, #0x06 // is DBLBULK
  603. beq .L_epc_txdbl
  604. ldr r3, =TX_USTALL //set state NAKED , clr DTOG_TX
  605. cmp r1, #0x01 // is ISO
  606. bne .L_epc_txsetstate //
  607. .L_epc_txdbl:
  608. ldr r3, =DTX_USTALL //set state VALID clr DTOG_TX & SWBUF_TX
  609. bl _get_next_pma
  610. bcc .L_epc_fail
  611. strh r0, [r5, #TXADDR1] //store txaddr1
  612. movs r0, #0x00
  613. strh r0, [r5, #TXCOUNT1] //store txcnt
  614. .L_epc_txsetstate:
  615. ldr r5, =USB_EPBASE
  616. ldrh r0, [r5, r4]
  617. eors r0, r3
  618. lsrs r3, #16
  619. ands r0, r3
  620. strh r0, [r5, r4]
  621. cmp r1, #0x00 //is a control ep ?
  622. bne .L_epc_exit
  623. .L_epc_setuprx:
  624. movs r3, r2
  625. cmp r2, #62
  626. bls .L_epc_rxbb
  627. movs r3, #0x1F
  628. adds r2, r3
  629. bics r2, r3
  630. lsrs r3, r2, #4
  631. adds r3, #0x3E
  632. .L_epc_rxbb:
  633. lsls r3, #9
  634. ldr r5, =USB_PMABASE
  635. adds r5, r5, r4, LSL (EPT_SHIFT - 2)
  636. /* RX or RX1 */
  637. bl _get_next_pma
  638. bcc .L_epc_fail
  639. strh r0, [r5, #RXADDR]
  640. strh r3, [r5, #RXCOUNT]
  641. ldr r0, =RX_USTALL
  642. /* check if doublebuffered */
  643. cmp r1, 0x06 //if dblbulk
  644. beq .L_epc_rxdbl
  645. cmp r1, 0x01 // iso
  646. bne .L_epc_rxsetstate
  647. .L_epc_rxdbl:
  648. bl _get_next_pma
  649. bcc .L_epc_fail
  650. strh r0, [r5, #RXADDR0] //store rxaddr0
  651. strh r3, [r5, #RXCOUNT0] //store rxcnt0
  652. ldr r0, =DRX_USTALL
  653. .L_epc_rxsetstate:
  654. ldr r5, =USB_EPBASE
  655. ldrh r3, [r5, r4]
  656. eors r3, r0
  657. lsrs r0, #16
  658. ands r3, r0
  659. strh r3, [r5, r4]
  660. .L_epc_exit:
  661. movs r0, #0x01
  662. pop {r4, r5, pc}
  663. .L_epc_fail:
  664. movs r0, #0x00
  665. pop {r4, r5, pc}
  666. .size _ep_config, . - _ep_config
  667. .thumb_func
  668. .type _ep_deconfig, %function
  669. /* void ep_deconfig( uint8_t ep)
  670. * R0 <- ep
  671. */
  672. _ep_deconfig:
  673. lsls r1, r0, #28
  674. lsrs r1, #26
  675. ldr r2, =USB_EPBASE
  676. ldr r3, =USB_PMABASE
  677. adds r2, r1
  678. adds r3, r3, r1, LSL (EPT_SHIFT - 2)
  679. /* clearing endpoint register */
  680. ldr r1, =EP_NOTOG
  681. ldrh r0, [r2]
  682. bics r0, r1
  683. strh r0, [r2]
  684. /* clearing PMA data */
  685. movs r0, #0x00
  686. strh r0, [r3, #TXADDR]
  687. strh r0, [r3, #TXCOUNT]
  688. strh r0, [r3, #RXADDR]
  689. strh r0, [r3, #RXCOUNT]
  690. bx lr
  691. .size _ep_deconfig, . - _ep_config
  692. #define ISTRSHIFT 8
  693. #define ISTRBIT(bit) ((1 << bit) >> ISTRSHIFT)
  694. .thumb_func
  695. .type _evt_poll, %function
  696. /*void evt_poll(usbd_device *dev, usbd_evt_callback callback)*/
  697. _evt_poll:
  698. push {r0, r1, r4, r5}
  699. ldr r3, =USB_REGBASE
  700. ldrh r0, [r3, #4] //USB->ISTR -> R2
  701. /* ep_index -> R2 */
  702. movs r2, 0x07
  703. ands r2, r0
  704. /* checking USB->ISTR for events */
  705. #if !defined(USBD_SOF_DISABLED)
  706. lsrs r1, r0, #10 //SOFM -> CF
  707. bcs .L_ep_sofm
  708. #endif
  709. lsrs r1, r0, #11 //RESETM -> CF
  710. bcs .L_ep_resetm
  711. lsrs r1, r0, #16 //CTRM -> CF
  712. bcs .L_ep_ctrm
  713. lsrs r1, r0, #14 //ERRM -> CF
  714. bcs .L_ep_errm
  715. lsrs r1, r0, #13 //WKUPM -> CF
  716. bcs .L_ep_wkupm
  717. lsrs r1, r0, #12 //SUSPM -> CF
  718. bcs .L_ep_suspm
  719. /* exit with no callback */
  720. pop {r0, r1, r4 , r5}
  721. bx lr
  722. .L_ep_ctrm:
  723. movs r5, #0x80 // CTR_TX mask to R5
  724. ldr r0,=USB_EPBASE
  725. add r0, r0, r2, LSL #2 // R0 ep register address
  726. ldrh r4, [r0] // R4 EPR valur
  727. lsrs r3, r4, #8 // CTR_TX -> CF
  728. bcc .L_ep_ctr_rx
  729. /* CTR_TX event */
  730. movs r1, #usbd_evt_eptx
  731. orrs r2, r5 // set endpoint tx
  732. b .L_ep_clr_ctr
  733. .L_ep_ctr_rx:
  734. /* CTR_RX RX or SETUP */
  735. lsls r5, #0x08 // set mask to CRT_RX
  736. movs r1, #usbd_evt_eprx
  737. lsls r3, r4, #21 //SETUP -> CF
  738. bcc .L_ep_clr_ctr
  739. movs r1, #usbd_evt_epsetup
  740. .L_ep_clr_ctr:
  741. bics r4, r5 //clear CTR flag
  742. ldr r5, =EP_NOTOG
  743. ands r4, r5
  744. strh r4, [r0] // store
  745. b .L_ep_callback
  746. .L_ep_errm:
  747. movs r1, #usbd_evt_error
  748. movs r4, #ISTRBIT(13)
  749. b .L_ep_clristr
  750. #if !defined(USBD_SOF_DISABLED)
  751. .L_ep_sofm:
  752. movs r1, #usbd_evt_sof
  753. movs r4, #ISTRBIT(9)
  754. b .L_ep_clristr
  755. #endif
  756. .L_ep_wkupm:
  757. ldrh r1, [r3, #0] //R1 USB->CNTR
  758. movs r5, #0x08
  759. bics r1, r5 //clr FSUSP
  760. strh r1, [r3, #0] //USB->CNTR R2
  761. movs r1, #usbd_evt_wkup
  762. movs r4, #ISTRBIT(12)
  763. b .L_ep_clristr
  764. .L_ep_suspm:
  765. ldrh r1, [r3, #0] //R1 USB->CNTR
  766. movs r5, #0x08
  767. orrs r1, r5 //set FSUSP
  768. strh r1, [r3, #0] //USB->CNTR R2
  769. movs r1, #usbd_evt_susp
  770. movs r4, #ISTRBIT(11)
  771. b .L_ep_clristr
  772. /* do reset routine */
  773. .L_ep_resetm:
  774. movs r1, #7
  775. ldr r2, =USB_EPBASE
  776. ldr r0, =USB_PMABASE
  777. ldr r5, =EP_NOTOG
  778. .L_ep_reset_loop:
  779. ldrh r4, [r2]
  780. bics r4, r5
  781. strh r4, [r2]
  782. movs r4, #0
  783. strh r4, [r0, #TXADDR]
  784. strh r4, [r0, #TXCOUNT]
  785. strh r4, [r0, #RXADDR]
  786. strh r4, [r0, #RXCOUNT]
  787. adds r2, #0x04
  788. adds r0, #(0x04 * USB_PMASTP)
  789. subs r1, #1
  790. bpl .L_ep_reset_loop
  791. movs r2, #0x00
  792. strh r2, [r3, #0x10] // 0 -> USB->BTABLE
  793. movs r1, #usbd_evt_reset
  794. movs r4, #ISTRBIT(10)
  795. .L_ep_clristr:
  796. lsls r4, #ISTRSHIFT
  797. ldrh r0, [r3, #4]
  798. bics r0, r4
  799. strh r0, [r3, #4]
  800. .L_ep_callback:
  801. pop {r0, r3, r4, r5 }
  802. bx r3
  803. .size _evt_poll, . - _evt_poll
  804. .pool
  805. .end
  806. #endif //USBD_STM32F103