usb_32v1A.S 22 KB

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