usbd_stm32l100_devfs_asm.S 22 KB

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