usb_32l0A.S 21 KB

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