usbd_stm32l052_devfs_asm.S 23 KB

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