usb_32v3A.S 22 KB

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