usbd_stm32f103_devfs.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554
  1. /* This file is the part of the Lightweight USB device Stack for STM32 microcontrollers
  2. *
  3. * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
  4. * Copyright ©2017 Max Chan <max[at]maxchan[dot]info>
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include <stdint.h>
  17. #include <stdbool.h>
  18. #include "stm32.h"
  19. #include "usb.h"
  20. #if defined(USBD_STM32F103)
  21. #define USB_EP_SWBUF_TX USB_EP_DTOG_RX
  22. #define USB_EP_SWBUF_RX USB_EP_DTOG_TX
  23. #define EP_TOGGLE_SET(epr, bits, mask) *(epr) = (*(epr) ^ (bits)) & (USB_EPREG_MASK | (mask))
  24. #define EP_TX_STALL(epr) EP_TOGGLE_SET((epr), USB_EP_TX_STALL, USB_EPTX_STAT)
  25. #define EP_RX_STALL(epr) EP_TOGGLE_SET((epr), USB_EP_RX_STALL, USB_EPRX_STAT)
  26. #define EP_TX_UNSTALL(epr) EP_TOGGLE_SET((epr), USB_EP_TX_NAK, USB_EPTX_STAT | USB_EP_DTOG_TX)
  27. #define EP_RX_UNSTALL(epr) EP_TOGGLE_SET((epr), USB_EP_RX_VALID, USB_EPRX_STAT | USB_EP_DTOG_RX)
  28. #define EP_DTX_UNSTALL(epr) EP_TOGGLE_SET((epr), USB_EP_TX_VALID, USB_EPTX_STAT | USB_EP_DTOG_TX | USB_EP_SWBUF_TX)
  29. #define EP_DRX_UNSTALL(epr) EP_TOGGLE_SET((epr), USB_EP_RX_VALID | USB_EP_SWBUF_RX, USB_EPRX_STAT | USB_EP_DTOG_RX | USB_EP_SWBUF_RX)
  30. #define EP_TX_VALID(epr) EP_TOGGLE_SET((epr), USB_EP_TX_VALID, USB_EPTX_STAT)
  31. #define EP_RX_VALID(epr) EP_TOGGLE_SET((epr), USB_EP_RX_VALID, USB_EPRX_STAT)
  32. #define STATUS_VAL(x) (x)
  33. typedef union _pma_table pma_table;
  34. #if defined(STM32F302x8) || defined(STM32F302xE) || defined(STM32F303xE)
  35. #if !defined(USB_PMASIZE)
  36. #warning PMA memory size is not defined. Use 768 bytes by default
  37. #define USB_PMASIZE 0x300
  38. #endif
  39. #define PMA_STEP 1
  40. typedef struct {
  41. uint16_t addr;
  42. uint16_t cnt;
  43. } pma_rec;
  44. inline static pma_table *EPT(uint8_t ep) {
  45. return (pma_table*)((ep & 0x07) * 8 + USB_PMAADDR);
  46. }
  47. inline static uint16_t *PMA(uint16_t addr) {
  48. return (uint16_t*)(USB_PMAADDR + addr);
  49. }
  50. #else
  51. #if !defined(USB_PMASIZE)
  52. #warning PMA memory size is not defined. Use 512 bytes by default
  53. #define USB_PMASIZE 0x200
  54. #endif
  55. #define PMA_STEP 2
  56. typedef struct {
  57. uint16_t addr;
  58. uint16_t :16;
  59. uint16_t cnt;
  60. uint16_t :16;
  61. } pma_rec;
  62. inline static pma_table *EPT(uint8_t ep) {
  63. return (pma_table*)((ep & 0x07) * 16 + USB_PMAADDR);
  64. }
  65. inline static uint16_t *PMA(uint16_t addr) {
  66. return (uint16_t*)(USB_PMAADDR + 2 * addr);
  67. }
  68. #endif
  69. union _pma_table {
  70. struct {
  71. pma_rec tx;
  72. pma_rec rx;
  73. };
  74. struct {
  75. pma_rec tx0;
  76. pma_rec tx1;
  77. };
  78. struct {
  79. pma_rec rx0;
  80. pma_rec rx1;
  81. };
  82. };
  83. /** \brief Helper function. Enables GPIOx for DP.
  84. * Looks ugly. But compiler should optimize this
  85. * to single line
  86. */
  87. inline static void set_gpiox() {
  88. #if defined(STM32F1) && defined(USBD_DP_PORT)
  89. if (USBD_DP_PORT == GPIOA) {RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; return;}
  90. if (USBD_DP_PORT == GPIOB) {RCC->APB2ENR |= RCC_APB2ENR_IOPBEN; return;}
  91. if (USBD_DP_PORT == GPIOC) {RCC->APB2ENR |= RCC_APB2ENR_IOPCEN; return;}
  92. if (USBD_DP_PORT == GPIOD) {RCC->APB2ENR |= RCC_APB2ENR_IOPDEN; return;}
  93. #if defined(GPIOE)
  94. if (USBD_DP_PORT == GPIOE) {RCC->APB2ENR |= RCC_APB2ENR_IOPEEN; return;}
  95. #endif
  96. #if defined(GPIOF)
  97. if (USBD_DP_PORT = GPIOF) {RCC->APB2ENR |= RCC_APB2ENR_IOPFEN; return;}
  98. #endif
  99. #elif defined(STM32F3) && defined(USBD_DP_PORT)
  100. if (USBD_DP_PORT == GPIOA) {RCC->AHBENR |= RCC_AHBENR_GPIOAEN; return;}
  101. if (USBD_DP_PORT == GPIOB) {RCC->AHBENR |= RCC_AHBENR_GPIOBEN; return;}
  102. if (USBD_DP_PORT == GPIOC) {RCC->AHBENR |= RCC_AHBENR_GPIOCEN; return;}
  103. if (USBD_DP_PORT == GPIOD) {RCC->AHBENR |= RCC_AHBENR_GPIODEN; return;}
  104. #if defined(GPIOE)
  105. if (USBD_DP_PORT == GPIOE) {RCC->AHBENR |= RCC_AHBENR_GPIOEEN; return;}
  106. #endif
  107. #if defined(GPIOF)
  108. if (USBD_DP_PORT == GPIOF) {RCC->AHBENR |= RCC_AHBENR_GPIOFEN; return;}
  109. #endif
  110. #if defined(GPIOG)
  111. if (USBD_DP_PORT == GPIOG) {RCC->AHBENR |= RCC_AHBENR_GPIOGEN; return;}
  112. #endif
  113. #if defined(GPIOH)
  114. if (USBD_DP_PORT == GPIOH) {RCC->AHBENR |= RCC_AHBENR_GPIOHEN; return;}
  115. #endif
  116. #endif
  117. return;
  118. }
  119. /** \brief Helper function. Returns pointer to the endpoint control register.
  120. */
  121. inline static volatile uint16_t *EPR(uint8_t ep) {
  122. return (uint16_t*)((ep & 0x07) * 4 + USB_BASE);
  123. }
  124. /** \brief Helper function. Returns next available PMA buffer.
  125. *
  126. * \param sz uint16_t Requested buffer size.
  127. * \return uint16_t Buffer address for PMA table.
  128. * \note PMA buffers grown from top to bottom like stack.
  129. */
  130. static uint16_t get_next_pma(uint16_t sz) {
  131. unsigned _result = USB_PMASIZE;
  132. for (int i = 0; i < 8; i++) {
  133. pma_table *tbl = EPT(i);
  134. if ((tbl->tx.addr) && (tbl->tx.addr < _result)) _result = tbl->tx.addr;
  135. if ((tbl->rx.addr) && (tbl->rx.addr < _result)) _result = tbl->rx.addr;
  136. }
  137. if ( _result < (4 * sizeof(pma_table) + sz)) {
  138. return 0;
  139. } else {
  140. return _result - sz;
  141. }
  142. }
  143. uint32_t getinfo(void) {
  144. if (!(RCC->APB1ENR & RCC_APB1ENR_USBEN)) return STATUS_VAL(0);
  145. #if defined(USBD_DP_PORT) && defined(USBD_DP_PIN)
  146. if (USBD_DP_PORT->IDR && _BV(USBD_DP_PIN)) return STATUS_VAL(USBD_HW_ENABLED | USBD_HW_SPEED_FS);
  147. return STATUS_VAL(USBD_HW_ENABLED);
  148. #else
  149. return STATUS_VAL(USBD_HW_ENABLED | USBD_HW_SPEED_FS);
  150. #endif
  151. }
  152. void ep_setstall(uint8_t ep, bool stall) {
  153. volatile uint16_t *reg = EPR(ep);
  154. /* ISOCHRONOUS endpoint can't be stalled or unstalled */
  155. if (USB_EP_ISOCHRONOUS == (*reg & USB_EP_T_FIELD)) return;
  156. /* If it's an IN endpoint */
  157. if (ep & 0x80) {
  158. /* DISABLED endpoint can't be stalled or unstalled */
  159. if (USB_EP_TX_DIS == (*reg & USB_EPTX_STAT)) return;
  160. if (stall) {
  161. EP_TX_STALL(reg);
  162. } else {
  163. /* if it's a doublebuffered endpoint */
  164. if ((USB_EP_KIND | USB_EP_BULK) == (*reg & (USB_EP_T_FIELD | USB_EP_KIND))) {
  165. /* set endpoint to VALID and clear DTOG_TX & SWBUF_TX */
  166. EP_DTX_UNSTALL(reg);
  167. } else {
  168. /* set endpoint to NAKED and clear DTOG_TX */
  169. EP_TX_UNSTALL(reg);
  170. }
  171. }
  172. } else {
  173. if (USB_EP_RX_DIS == (*reg & USB_EPRX_STAT)) return;
  174. if (stall) {
  175. EP_RX_STALL(reg);
  176. } else {
  177. /* if it's a doublebuffered endpoint */
  178. if ((USB_EP_KIND | USB_EP_BULK) == (*reg & (USB_EP_T_FIELD | USB_EP_KIND))) {
  179. /* set endpoint to VALID, clear DTOG_RX, set SWBUF_RX */
  180. EP_DRX_UNSTALL(reg);
  181. } else {
  182. /* set endpoint to VALID and clear DTOG_RX */
  183. EP_RX_UNSTALL(reg);
  184. }
  185. }
  186. }
  187. }
  188. bool ep_isstalled(uint8_t ep) {
  189. if (ep & 0x80) {
  190. return (USB_EP_TX_STALL == (USB_EPTX_STAT & *EPR(ep)));
  191. } else {
  192. return (USB_EP_RX_STALL == (USB_EPRX_STAT & *EPR(ep)));
  193. }
  194. }
  195. uint8_t connect(bool connect) {
  196. #if defined(USBD_DP_PORT) && defined(USBD_DP_PIN) && defined(STM32F3)
  197. uint32_t _t = USBD_DP_PORT->MODER & ~(0x03 << (2 * USBD_DP_PIN));
  198. if (connect) {
  199. _t |= (0x01 << (2 * USBD_DP_PIN));
  200. USBD_DP_PORT->BSRR = (0x0001 << USBD_DP_PIN);
  201. }
  202. USBD_DP_PORT->MODER = _t;
  203. #elif defined(USBD_DP_PORT) && defined(USBD_DP_PIN) && defined(STM32F1)
  204. #if (USBD_DP_PIN < 8)
  205. uint32_t _t = USBD_DP_PORT->CRL & ~(0x0F << (4 * USBD_DP_PIN));
  206. if (connect) {
  207. _t |= (0x02 << (4 * USBD_DP_PIN));
  208. USBD_DP_PORT->BSRR = (0x0001 << USBD_DP_PIN);
  209. } else {
  210. _t |= (0x04 << (4 * USBD_DP_PIN));
  211. }
  212. USBD_DP_PORT->CRL = _t;
  213. #else
  214. uint32_t _t = USBD_DP_PORT->CRH & ~(0x0F << (4 * (USBD_DP_PIN - 8)));
  215. if (connect) {
  216. _t |= (0x02 << (4 * (USBD_DP_PIN - 8)));
  217. USBD_DP_PORT->BSRR = (0x0001 << USBD_DP_PIN);
  218. } else {
  219. _t |= (0x04 << (4 * (USBD_DP_PIN - 8)));
  220. }
  221. USBD_DP_PORT->CRH = _t;
  222. #endif
  223. #endif
  224. return usbd_lane_unk;
  225. }
  226. void enable(bool enable) {
  227. if (enable) {
  228. set_gpiox();
  229. RCC->APB1ENR |= RCC_APB1ENR_USBEN;
  230. RCC->APB1RSTR |= RCC_APB1RSTR_USBRST;
  231. RCC->APB1RSTR &= ~RCC_APB1RSTR_USBRST;
  232. USB->CNTR = USB_CNTR_CTRM | USB_CNTR_RESETM | USB_CNTR_ERRM |
  233. #if !defined(USBD_SOF_DISABLED)
  234. USB_CNTR_SOFM |
  235. #endif
  236. USB_CNTR_SUSPM | USB_CNTR_WKUPM;
  237. } else if (RCC->APB1ENR & RCC_APB1ENR_USBEN) {
  238. RCC->APB1RSTR |= RCC_APB1RSTR_USBRST;
  239. RCC->APB1ENR &= ~RCC_APB1ENR_USBEN;
  240. /* disconnecting DP if configured */
  241. connect(0);
  242. }
  243. }
  244. void setaddr (uint8_t addr) {
  245. USB->DADDR = USB_DADDR_EF | addr;
  246. }
  247. bool ep_config(uint8_t ep, uint8_t eptype, uint16_t epsize) {
  248. volatile uint16_t *reg = EPR(ep);
  249. pma_table *tbl = EPT(ep);
  250. /* epsize should be 16-bit aligned */
  251. if (epsize & 0x01) epsize++;
  252. switch (eptype) {
  253. case USB_EPTYPE_CONTROL:
  254. *reg = USB_EP_CONTROL | (ep & 0x07);
  255. break;
  256. case USB_EPTYPE_ISOCHRONUS:
  257. *reg = USB_EP_ISOCHRONOUS | (ep & 0x07);
  258. break;
  259. case USB_EPTYPE_BULK:
  260. *reg = USB_EP_BULK | (ep & 0x07);
  261. break;
  262. case USB_EPTYPE_BULK | USB_EPTYPE_DBLBUF:
  263. *reg = USB_EP_BULK | USB_EP_KIND | (ep & 0x07);
  264. break;
  265. default:
  266. *reg = USB_EP_INTERRUPT | (ep & 0x07);
  267. break;
  268. }
  269. /* if it TX or CONTROL endpoint */
  270. if ((ep & 0x80) || (eptype == USB_EPTYPE_CONTROL)) {
  271. uint16_t _pma;
  272. _pma = get_next_pma(epsize);
  273. if (_pma == 0) return false;
  274. tbl->tx.addr = _pma;
  275. tbl->tx.cnt = 0;
  276. if ((eptype == USB_EPTYPE_ISOCHRONUS) ||
  277. (eptype == (USB_EPTYPE_BULK | USB_EPTYPE_DBLBUF))) {
  278. _pma = get_next_pma(epsize);
  279. if (_pma == 0) return false;
  280. tbl->tx1.addr = _pma;
  281. tbl->tx1.cnt = 0;
  282. EP_DTX_UNSTALL(reg);
  283. } else {
  284. EP_TX_UNSTALL(reg);
  285. }
  286. }
  287. if (!(ep & 0x80)) {
  288. uint16_t _rxcnt;
  289. uint16_t _pma;
  290. if (epsize > 62) {
  291. if (epsize & 0x1F) {
  292. epsize &= 0x1F;
  293. } else {
  294. epsize -= 0x20;
  295. }
  296. _rxcnt = 0x8000 | (epsize << 5);
  297. epsize += 0x20;
  298. } else {
  299. _rxcnt = epsize << 9;
  300. }
  301. _pma = get_next_pma(epsize);
  302. if (_pma == 0) return false;
  303. tbl->rx.addr = _pma;
  304. tbl->rx.cnt = _rxcnt;
  305. if ((eptype == USB_EPTYPE_ISOCHRONUS) ||
  306. (eptype == (USB_EPTYPE_BULK | USB_EPTYPE_DBLBUF))) {
  307. _pma = get_next_pma(epsize);
  308. if (_pma == 0) return false;
  309. tbl->rx0.addr = _pma;
  310. tbl->rx0.cnt = _rxcnt;
  311. EP_DRX_UNSTALL(reg);
  312. } else {
  313. EP_RX_UNSTALL(reg);
  314. }
  315. }
  316. return true;
  317. }
  318. void ep_deconfig(uint8_t ep) {
  319. pma_table *ept = EPT(ep);
  320. *EPR(ep) &= ~USB_EPREG_MASK;
  321. ept->rx.addr = 0;
  322. ept->rx.cnt = 0;
  323. ept->tx.addr = 0;
  324. ept->tx.cnt = 0;
  325. }
  326. static uint16_t pma_read (uint8_t *buf, uint16_t blen, pma_rec *rx) {
  327. uint16_t *pma = PMA(rx->addr);
  328. uint16_t rxcnt = rx->cnt & 0x03FF;
  329. rx->cnt &= ~0x3FF;
  330. if (blen > rxcnt) {
  331. blen = rxcnt;
  332. }
  333. rxcnt = blen;
  334. while (blen) {
  335. uint16_t _t = *pma;
  336. *buf++ = _t & 0xFF;
  337. if (--blen) {
  338. *buf++ = _t >> 8;
  339. pma += PMA_STEP;
  340. blen--;
  341. } else break;
  342. }
  343. return rxcnt;
  344. }
  345. int32_t ep_read(uint8_t ep, void *buf, uint16_t blen) {
  346. pma_table *tbl = EPT(ep);
  347. volatile uint16_t *reg = EPR(ep);
  348. switch (*reg & (USB_EPRX_STAT | USB_EP_T_FIELD | USB_EP_KIND)) {
  349. /* doublebuffered bulk endpoint */
  350. case (USB_EP_RX_VALID | USB_EP_BULK | USB_EP_KIND):
  351. /* switching SWBUF if EP is NAKED */
  352. switch (*reg & (USB_EP_DTOG_RX | USB_EP_SWBUF_RX)) {
  353. case 0:
  354. case (USB_EP_DTOG_RX | USB_EP_SWBUF_RX):
  355. *reg = (*reg & USB_EPREG_MASK) | USB_EP_SWBUF_RX;
  356. default:
  357. break;
  358. }
  359. if (*reg & USB_EP_SWBUF_RX) {
  360. return pma_read(buf, blen, &(tbl->rx1));
  361. } else {
  362. return pma_read(buf, blen, &(tbl->rx0));
  363. }
  364. /* isochronous endpoint */
  365. case (USB_EP_RX_VALID | USB_EP_ISOCHRONOUS):
  366. if (*reg & USB_EP_DTOG_RX) {
  367. return pma_read(buf, blen, &(tbl->rx1));
  368. } else {
  369. return pma_read(buf, blen, &(tbl->rx0));
  370. }
  371. /* regular endpoint */
  372. case (USB_EP_RX_NAK | USB_EP_BULK):
  373. case (USB_EP_RX_NAK | USB_EP_CONTROL):
  374. case (USB_EP_RX_NAK | USB_EP_INTERRUPT):
  375. {
  376. int32_t res = pma_read(buf, blen, &(tbl->rx));
  377. /* setting endpoint to VALID state */
  378. EP_RX_VALID(reg);
  379. return res;
  380. }
  381. /* invalid or not ready */
  382. default:
  383. return -1;
  384. }
  385. }
  386. static void pma_write(const uint8_t *buf, uint16_t blen, pma_rec *tx) {
  387. uint16_t *pma = PMA(tx->addr);
  388. tx->cnt = blen;
  389. while (blen > 1) {
  390. *pma = buf[1] << 8 | buf[0];
  391. pma += PMA_STEP;
  392. buf += 2;
  393. blen -= 2;
  394. }
  395. if (blen) *pma = *buf;
  396. }
  397. int32_t ep_write(uint8_t ep, void *buf, uint16_t blen) {
  398. pma_table *tbl = EPT(ep);
  399. volatile uint16_t *reg = EPR(ep);
  400. switch (*reg & (USB_EPTX_STAT | USB_EP_T_FIELD | USB_EP_KIND)) {
  401. /* doublebuffered bulk endpoint */
  402. case (USB_EP_TX_NAK | USB_EP_BULK | USB_EP_KIND):
  403. if (*reg & USB_EP_SWBUF_TX) {
  404. pma_write(buf, blen, &(tbl->tx1));
  405. } else {
  406. pma_write(buf, blen, &(tbl->tx0));
  407. }
  408. *reg = (*reg & USB_EPREG_MASK) | USB_EP_SWBUF_TX;
  409. break;
  410. /* isochronous endpoint */
  411. case (USB_EP_TX_VALID | USB_EP_ISOCHRONOUS):
  412. if (!(*reg & USB_EP_DTOG_TX)) {
  413. pma_write(buf, blen, &(tbl->tx1));
  414. } else {
  415. pma_write(buf, blen, &(tbl->tx0));
  416. }
  417. break;
  418. /* regular endpoint */
  419. case (USB_EP_TX_NAK | USB_EP_BULK):
  420. case (USB_EP_TX_NAK | USB_EP_CONTROL):
  421. case (USB_EP_TX_NAK | USB_EP_INTERRUPT):
  422. pma_write(buf, blen, &(tbl->tx));
  423. EP_TX_VALID(reg);
  424. break;
  425. /* invalid or not ready */
  426. default:
  427. return -1;
  428. }
  429. return blen;
  430. }
  431. uint16_t get_frame (void) {
  432. return USB->FNR & USB_FNR_FN;
  433. }
  434. void evt_poll(usbd_device *dev, usbd_evt_callback callback) {
  435. uint8_t _ev, _ep;
  436. uint16_t _istr = USB->ISTR;
  437. _ep = _istr & USB_ISTR_EP_ID;
  438. if (_istr & USB_ISTR_CTR) {
  439. volatile uint16_t *reg = EPR(_ep);
  440. if (*reg & USB_EP_CTR_TX) {
  441. *reg &= (USB_EPREG_MASK ^ USB_EP_CTR_TX);
  442. _ep |= 0x80;
  443. _ev = usbd_evt_eptx;
  444. } else {
  445. *reg &= (USB_EPREG_MASK ^ USB_EP_CTR_RX);
  446. _ev = (*reg & USB_EP_SETUP) ? usbd_evt_epsetup : usbd_evt_eprx;
  447. }
  448. } else if (_istr & USB_ISTR_RESET) {
  449. USB->ISTR &= ~USB_ISTR_RESET;
  450. USB->BTABLE = 0;
  451. for (int i = 0; i < 8; i++) {
  452. ep_deconfig(i);
  453. }
  454. _ev = usbd_evt_reset;
  455. #if !defined(USBD_SOF_DISABLED)
  456. } else if (_istr & USB_ISTR_SOF) {
  457. _ev = usbd_evt_sof;
  458. USB->ISTR &= ~USB_ISTR_SOF;
  459. #endif
  460. } else if (_istr & USB_ISTR_WKUP) {
  461. _ev = usbd_evt_wkup;
  462. USB->CNTR &= ~USB_CNTR_FSUSP;
  463. USB->ISTR &= ~USB_ISTR_WKUP;
  464. } else if (_istr & USB_ISTR_SUSP) {
  465. _ev = usbd_evt_susp;
  466. USB->CNTR |= USB_CNTR_FSUSP;
  467. USB->ISTR &= ~USB_ISTR_SUSP;
  468. } else if (_istr & USB_ISTR_ERR) {
  469. USB->ISTR &= ~USB_ISTR_ERR;
  470. _ev = usbd_evt_error;
  471. } else {
  472. return;
  473. }
  474. callback(dev, _ev, _ep);
  475. }
  476. static uint32_t fnv1a32_turn (uint32_t fnv, uint32_t data ) {
  477. for (int i = 0; i < 4 ; i++) {
  478. fnv ^= (data & 0xFF);
  479. fnv *= 16777619;
  480. data >>= 8;
  481. }
  482. return fnv;
  483. }
  484. uint16_t get_serialno_desc(void *buffer) {
  485. struct usb_string_descriptor *dsc = buffer;
  486. uint16_t *str = dsc->wString;
  487. uint32_t fnv = 2166136261;
  488. fnv = fnv1a32_turn(fnv, *(uint32_t*)(UID_BASE + 0x00));
  489. fnv = fnv1a32_turn(fnv, *(uint32_t*)(UID_BASE + 0x04));
  490. fnv = fnv1a32_turn(fnv, *(uint32_t*)(UID_BASE + 0x08));
  491. for (int i = 28; i >= 0; i -= 4 ) {
  492. uint16_t c = (fnv >> i) & 0x0F;
  493. c += (c < 10) ? '0' : ('A' - 10);
  494. *str++ = c;
  495. }
  496. dsc->bDescriptorType = USB_DTYPE_STRING;
  497. dsc->bLength = 18;
  498. return 18;
  499. }
  500. const struct usbd_driver usbd_devfs = {
  501. getinfo,
  502. enable,
  503. connect,
  504. setaddr,
  505. ep_config,
  506. ep_deconfig,
  507. ep_read,
  508. ep_write,
  509. ep_setstall,
  510. ep_isstalled,
  511. evt_poll,
  512. get_frame,
  513. get_serialno_desc,
  514. };
  515. #endif //USBD_STM32F103