usb_32l0A.S 21 KB

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