usb_32v0A.S 22 KB

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