usbd_stm32f103_devfs_asm.S 23 KB

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