usbd_stm32l052_devfs.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484
  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. *
  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. #include <stdint.h>
  16. #include <stdbool.h>
  17. #include "stm32_compat.h"
  18. #include "usb.h"
  19. #if defined(USBD_STM32L052)
  20. #if defined(STM32F070x6) || defined(STM32F070xB) || \
  21. defined(STM32F042x6) || defined(STM32F048xx) || \
  22. defined(STM32F072xB) || defined(STM32F078xx)
  23. #define UID_OFFSET_0 0x00
  24. #define UID_OFFSET_1 0x04
  25. #define UID_OFFSET_2 0x08
  26. #else
  27. #define UID_OFFSET_0 0x00
  28. #define UID_OFFSET_1 0x04
  29. #define UID_OFFSET_2 0x14
  30. #endif
  31. #ifndef USB_PMASIZE
  32. #pragma message "PMA memory size is not defined. Use 1k by default"
  33. #define USB_PMASIZE 0x400
  34. #endif
  35. #define USB_EP_SWBUF_TX USB_EP_DTOG_RX
  36. #define USB_EP_SWBUF_RX USB_EP_DTOG_TX
  37. #define EP_TOGGLE_SET(epr, bits, mask) *(epr) = (*(epr) ^ (bits)) & (USB_EPREG_MASK | (mask))
  38. #define EP_TX_STALL(epr) EP_TOGGLE_SET((epr), USB_EP_TX_STALL, USB_EPTX_STAT)
  39. #define EP_RX_STALL(epr) EP_TOGGLE_SET((epr), USB_EP_RX_STALL, USB_EPRX_STAT)
  40. #define EP_TX_UNSTALL(epr) EP_TOGGLE_SET((epr), USB_EP_TX_NAK, USB_EPTX_STAT | USB_EP_DTOG_TX)
  41. #define EP_RX_UNSTALL(epr) EP_TOGGLE_SET((epr), USB_EP_RX_VALID, USB_EPRX_STAT | USB_EP_DTOG_RX)
  42. #define EP_DTX_UNSTALL(epr) EP_TOGGLE_SET((epr), USB_EP_TX_VALID, USB_EPTX_STAT | USB_EP_DTOG_TX | USB_EP_SWBUF_TX)
  43. #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)
  44. #define EP_TX_VALID(epr) EP_TOGGLE_SET((epr), USB_EP_TX_VALID, USB_EPTX_STAT)
  45. #define EP_RX_VALID(epr) EP_TOGGLE_SET((epr), USB_EP_RX_VALID, USB_EPRX_STAT)
  46. #define STATUS_VAL(x) (USBD_HW_BC | (x))
  47. typedef struct {
  48. uint16_t addr;
  49. uint16_t cnt;
  50. } pma_rec;
  51. typedef union pma_table {
  52. struct {
  53. pma_rec tx;
  54. pma_rec rx;
  55. };
  56. struct {
  57. pma_rec tx0;
  58. pma_rec tx1;
  59. };
  60. struct {
  61. pma_rec rx0;
  62. pma_rec rx1;
  63. };
  64. } pma_table;
  65. /** \brief Helper function. Returns pointer to the buffer descriptor table.
  66. */
  67. inline static pma_table *EPT(uint8_t ep) {
  68. return (pma_table*)((ep & 0x07) * 8 + USB_PMAADDR);
  69. }
  70. /** \brief Helper function. Returns pointer to the endpoint control register.
  71. */
  72. inline static volatile uint16_t *EPR(uint8_t ep) {
  73. return (uint16_t*)((ep & 0x07) * 4 + USB_BASE);
  74. }
  75. /** \brief Helper function. Returns next available PMA buffer.
  76. *
  77. * \param sz uint16_t Requested buffer size.
  78. * \return uint16_t Buffer address for PMA table.
  79. * \note PMA buffers grown from top to bottom like stack.
  80. */
  81. static uint16_t get_next_pma(uint16_t sz) {
  82. unsigned _result = USB_PMASIZE;
  83. for (int i = 0; i < 8; i++) {
  84. pma_table *tbl = EPT(i);
  85. if ((tbl->rx.addr) && (tbl->rx.addr < _result)) _result = tbl->rx.addr;
  86. if ((tbl->tx.addr) && (tbl->tx.addr < _result)) _result = tbl->tx.addr;
  87. }
  88. return (_result < (0x020U + sz)) ? 0 : (_result - sz);
  89. }
  90. static uint32_t getinfo(void) {
  91. if (!(RCC->APB1ENR & RCC_APB1ENR_USBEN)) return STATUS_VAL(0);
  92. if (USB->BCDR & USB_BCDR_DPPU) return STATUS_VAL(USBD_HW_ENABLED | USBD_HW_SPEED_FS);
  93. return STATUS_VAL(USBD_HW_ENABLED);
  94. }
  95. static void ep_setstall(uint8_t ep, bool stall) {
  96. volatile uint16_t *reg = EPR(ep);
  97. /* ISOCHRONOUS endpoint can't be stalled or unstalled */
  98. if (USB_EP_ISOCHRONOUS == (*reg & USB_EP_T_FIELD)) return;
  99. /* If it's an IN endpoint */
  100. if (ep & 0x80) {
  101. /* DISABLED endpoint can't be stalled or unstalled */
  102. if (USB_EP_TX_DIS == (*reg & USB_EPTX_STAT)) return;
  103. if (stall) {
  104. EP_TX_STALL(reg);
  105. } else {
  106. /* if it's a doublebuffered endpoint */
  107. if ((USB_EP_KIND | USB_EP_BULK) == (*reg & (USB_EP_T_FIELD | USB_EP_KIND))) {
  108. /* set endpoint to VALID and clear DTOG_TX & SWBUF_TX */
  109. EP_DTX_UNSTALL(reg);
  110. } else {
  111. /* set endpoint to NAKED and clear DTOG_TX */
  112. EP_TX_UNSTALL(reg);
  113. }
  114. }
  115. } else {
  116. if (USB_EP_RX_DIS == (*reg & USB_EPRX_STAT)) return;
  117. if (stall) {
  118. EP_RX_STALL(reg);
  119. } else {
  120. /* if it's a doublebuffered endpoint */
  121. if ((USB_EP_KIND | USB_EP_BULK) == (*reg & (USB_EP_T_FIELD | USB_EP_KIND))) {
  122. /* set endpoint to VALID, clear DTOG_RX, set SWBUF_RX */
  123. EP_DRX_UNSTALL(reg);
  124. } else {
  125. /* set endpoint to VALID and clear DTOG_RX */
  126. EP_RX_UNSTALL(reg);
  127. }
  128. }
  129. }
  130. }
  131. static bool ep_isstalled(uint8_t ep) {
  132. if (ep & 0x80) {
  133. return (USB_EP_TX_STALL == (USB_EPTX_STAT & *EPR(ep)));
  134. } else {
  135. return (USB_EP_RX_STALL == (USB_EPRX_STAT & *EPR(ep)));
  136. }
  137. }
  138. static void enable(bool enable) {
  139. if (enable) {
  140. RCC->APB1ENR |= RCC_APB1ENR_USBEN;
  141. RCC->APB1RSTR |= RCC_APB1RSTR_USBRST;
  142. RCC->APB1RSTR &= ~RCC_APB1RSTR_USBRST;
  143. #if defined(USBD_PINS_REMAP) && (defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F070x6))
  144. RCC->APB2ENR |= RCC_APB2ENR_SYSCFGCOMPEN;
  145. SYSCFG->CFGR1 |= SYSCFG_CFGR1_PA11_PA12_RMP; // remap USB pins for small packages
  146. #endif
  147. USB->CNTR = USB_CNTR_CTRM | USB_CNTR_RESETM | USB_CNTR_ERRM |
  148. #if !defined(USBD_SOF_DISABLED)
  149. USB_CNTR_SOFM |
  150. #endif
  151. USB_CNTR_SUSPM | USB_CNTR_WKUPM;
  152. } else if (RCC->APB1ENR & RCC_APB1ENR_USBEN) {
  153. USB->BCDR = 0;
  154. RCC->APB1RSTR |= RCC_APB1RSTR_USBRST;
  155. RCC->APB1ENR &= ~RCC_APB1ENR_USBEN;
  156. }
  157. }
  158. static uint8_t connect(bool connect) {
  159. uint8_t res;
  160. USB->BCDR = USB_BCDR_BCDEN | USB_BCDR_DCDEN;
  161. if (USB->BCDR & USB_BCDR_DCDET) {
  162. USB->BCDR = USB_BCDR_BCDEN | USB_BCDR_PDEN;
  163. if (USB->BCDR & USB_BCDR_PS2DET) {
  164. res = usbd_lane_unk;
  165. } else if (USB->BCDR & USB_BCDR_PDET) {
  166. USB->BCDR = USB_BCDR_BCDEN | USB_BCDR_SDEN;
  167. if (USB->BCDR & USB_BCDR_SDET) {
  168. res = usbd_lane_dcp;
  169. } else {
  170. res = usbd_lane_cdp;
  171. }
  172. } else {
  173. res = usbd_lane_sdp;
  174. }
  175. } else {
  176. res = usbd_lane_dsc;
  177. }
  178. USB->BCDR = (connect) ? USB_BCDR_DPPU : 0;
  179. return res;
  180. }
  181. static void setaddr (uint8_t addr) {
  182. USB->DADDR = USB_DADDR_EF | addr;
  183. }
  184. static bool ep_config(uint8_t ep, uint8_t eptype, uint16_t epsize) {
  185. volatile uint16_t *reg = EPR(ep);
  186. pma_table *tbl = EPT(ep);
  187. /* epsize must be 2-byte aligned */
  188. epsize = (~0x01U) & (epsize + 1);
  189. switch (eptype) {
  190. case USB_EPTYPE_CONTROL:
  191. *reg = USB_EP_CONTROL | (ep & 0x07);
  192. break;
  193. case USB_EPTYPE_ISOCHRONUS:
  194. *reg = USB_EP_ISOCHRONOUS | (ep & 0x07);
  195. break;
  196. case USB_EPTYPE_BULK:
  197. *reg = USB_EP_BULK | (ep & 0x07);
  198. break;
  199. case USB_EPTYPE_BULK | USB_EPTYPE_DBLBUF:
  200. *reg = USB_EP_BULK | USB_EP_KIND | (ep & 0x07);
  201. break;
  202. default:
  203. *reg = USB_EP_INTERRUPT | (ep & 0x07);
  204. break;
  205. }
  206. /* if it TX or CONTROL endpoint */
  207. if ((ep & 0x80) || (eptype == USB_EPTYPE_CONTROL)) {
  208. uint16_t _pma;
  209. _pma = get_next_pma(epsize);
  210. if (_pma == 0) return false;
  211. tbl->tx.addr = _pma;
  212. tbl->tx.cnt = 0;
  213. if ((eptype == USB_EPTYPE_ISOCHRONUS) ||
  214. (eptype == (USB_EPTYPE_BULK | USB_EPTYPE_DBLBUF))) {
  215. _pma = get_next_pma(epsize);
  216. if (_pma == 0) return false;
  217. tbl->tx1.addr = _pma;
  218. tbl->tx1.cnt = 0;
  219. EP_DTX_UNSTALL(reg);
  220. } else {
  221. EP_TX_UNSTALL(reg);
  222. }
  223. }
  224. if (!(ep & 0x80)) {
  225. uint16_t _rxcnt;
  226. uint16_t _pma;
  227. if (epsize > 62) {
  228. /* using 32-byte blocks. epsize must be 32-byte aligned */
  229. epsize = (~0x1FU) & (epsize + 0x1FU);
  230. _rxcnt = 0x8000 - 0x400 + (epsize << 5);
  231. } else {
  232. _rxcnt = epsize << 9;
  233. }
  234. _pma = get_next_pma(epsize);
  235. if (_pma == 0) return false;
  236. tbl->rx.addr = _pma;
  237. tbl->rx.cnt = _rxcnt;
  238. if ((eptype == USB_EPTYPE_ISOCHRONUS) ||
  239. (eptype == (USB_EPTYPE_BULK | USB_EPTYPE_DBLBUF))) {
  240. _pma = get_next_pma(epsize);
  241. if (_pma == 0) return false;
  242. tbl->rx0.addr = _pma;
  243. tbl->rx0.cnt = _rxcnt;
  244. EP_DRX_UNSTALL(reg);
  245. } else {
  246. EP_RX_UNSTALL(reg);
  247. }
  248. }
  249. return true;
  250. }
  251. static void ep_deconfig(uint8_t ep) {
  252. pma_table *ept = EPT(ep);
  253. *EPR(ep) &= ~USB_EPREG_MASK;
  254. ept->rx.addr = 0;
  255. ept->rx.cnt = 0;
  256. ept->tx.addr = 0;
  257. ept->tx.cnt = 0;
  258. }
  259. static uint16_t pma_read (uint8_t *buf, uint16_t blen, pma_rec *rx) {
  260. uint16_t tmp = 0;
  261. uint16_t *pma = (void*)(USB_PMAADDR + rx->addr);
  262. uint16_t rxcnt = rx->cnt & 0x03FF;
  263. rx->cnt &= ~0x3FF;
  264. for(int idx = 0; idx < rxcnt; idx++) {
  265. if ((idx & 0x01) == 0) {
  266. tmp = *pma++;
  267. }
  268. if (idx < blen) {
  269. buf[idx] = tmp & 0xFF;
  270. tmp >>= 8;
  271. } else {
  272. return blen;
  273. }
  274. }
  275. return rxcnt;
  276. }
  277. static int32_t ep_read(uint8_t ep, void *buf, uint16_t blen) {
  278. pma_table *tbl = EPT(ep);
  279. volatile uint16_t *reg = EPR(ep);
  280. switch (*reg & (USB_EPRX_STAT | USB_EP_T_FIELD | USB_EP_KIND)) {
  281. /* doublebuffered bulk endpoint */
  282. case (USB_EP_RX_VALID | USB_EP_BULK | USB_EP_KIND):
  283. /* switching SWBUF if EP is NAKED */
  284. switch (*reg & (USB_EP_DTOG_RX | USB_EP_SWBUF_RX)) {
  285. case 0:
  286. case (USB_EP_DTOG_RX | USB_EP_SWBUF_RX):
  287. *reg = (*reg & USB_EPREG_MASK) | USB_EP_SWBUF_RX;
  288. break;
  289. default:
  290. break;
  291. }
  292. if (*reg & USB_EP_SWBUF_RX) {
  293. return pma_read(buf, blen, &(tbl->rx1));
  294. } else {
  295. return pma_read(buf, blen, &(tbl->rx0));
  296. }
  297. /* isochronous endpoint */
  298. case (USB_EP_RX_VALID | USB_EP_ISOCHRONOUS):
  299. if (*reg & USB_EP_DTOG_RX) {
  300. return pma_read(buf, blen, &(tbl->rx1));
  301. } else {
  302. return pma_read(buf, blen, &(tbl->rx0));
  303. }
  304. /* regular endpoint */
  305. case (USB_EP_RX_NAK | USB_EP_BULK):
  306. case (USB_EP_RX_NAK | USB_EP_CONTROL):
  307. case (USB_EP_RX_NAK | USB_EP_INTERRUPT):
  308. {
  309. int32_t res = pma_read(buf, blen, &(tbl->rx));
  310. /* setting endpoint to VALID state */
  311. EP_RX_VALID(reg);
  312. return res;
  313. }
  314. /* invalid or not ready */
  315. default:
  316. return -1;
  317. }
  318. }
  319. static void pma_write(const uint8_t *buf, uint16_t blen, pma_rec *tx) {
  320. uint16_t *pma = (void*)(USB_PMAADDR + tx->addr);
  321. uint16_t tmp = 0;
  322. tx->cnt = blen;
  323. for (int idx=0; idx < blen; idx++) {
  324. tmp |= buf[idx] << ((idx & 0x01) ? 8 : 0);
  325. if ((idx & 0x01) || (idx + 1) == blen) {
  326. *pma++ = tmp;
  327. tmp = 0;
  328. }
  329. }
  330. }
  331. static int32_t ep_write(uint8_t ep, const void *buf, uint16_t blen) {
  332. pma_table *tbl = EPT(ep);
  333. volatile uint16_t *reg = EPR(ep);
  334. switch (*reg & (USB_EPTX_STAT | USB_EP_T_FIELD | USB_EP_KIND)) {
  335. /* doublebuffered bulk endpoint */
  336. case (USB_EP_TX_NAK | USB_EP_BULK | USB_EP_KIND):
  337. if (*reg & USB_EP_SWBUF_TX) {
  338. pma_write(buf, blen, &(tbl->tx1));
  339. } else {
  340. pma_write(buf, blen, &(tbl->tx0));
  341. }
  342. *reg = (*reg & USB_EPREG_MASK) | USB_EP_SWBUF_TX;
  343. break;
  344. /* isochronous endpoint */
  345. case (USB_EP_TX_VALID | USB_EP_ISOCHRONOUS):
  346. if (!(*reg & USB_EP_DTOG_TX)) {
  347. pma_write(buf, blen, &(tbl->tx1));
  348. } else {
  349. pma_write(buf, blen, &(tbl->tx0));
  350. }
  351. break;
  352. /* regular endpoint */
  353. case (USB_EP_TX_NAK | USB_EP_BULK):
  354. case (USB_EP_TX_NAK | USB_EP_CONTROL):
  355. case (USB_EP_TX_NAK | USB_EP_INTERRUPT):
  356. pma_write(buf, blen, &(tbl->tx));
  357. EP_TX_VALID(reg);
  358. break;
  359. /* invalid or not ready */
  360. default:
  361. return -1;
  362. }
  363. return blen;
  364. }
  365. static uint16_t get_frame (void) {
  366. return USB->FNR & USB_FNR_FN;
  367. }
  368. static void evt_poll(usbd_device *dev, usbd_evt_callback callback) {
  369. uint8_t _ev, _ep;
  370. uint16_t _istr = USB->ISTR;
  371. _ep = _istr & USB_ISTR_EP_ID;
  372. if (_istr & USB_ISTR_CTR) {
  373. volatile uint16_t *reg = EPR(_ep);
  374. if (*reg & USB_EP_CTR_TX) {
  375. *reg &= (USB_EPREG_MASK ^ USB_EP_CTR_TX);
  376. _ep |= 0x80;
  377. _ev = usbd_evt_eptx;
  378. } else {
  379. *reg &= (USB_EPREG_MASK ^ USB_EP_CTR_RX);
  380. _ev = (*reg & USB_EP_SETUP) ? usbd_evt_epsetup : usbd_evt_eprx;
  381. }
  382. } else if (_istr & USB_ISTR_RESET) {
  383. USB->ISTR &= ~USB_ISTR_RESET;
  384. USB->BTABLE = 0;
  385. for (int i = 0; i < 8; i++) {
  386. ep_deconfig(i);
  387. }
  388. _ev = usbd_evt_reset;
  389. #if !defined(USBD_SOF_DISABLED)
  390. } else if (_istr & USB_ISTR_SOF) {
  391. _ev = usbd_evt_sof;
  392. USB->ISTR &= ~USB_ISTR_SOF;
  393. #endif
  394. } else if (_istr & USB_ISTR_WKUP) {
  395. _ev = usbd_evt_wkup;
  396. USB->CNTR &= ~USB_CNTR_FSUSP;
  397. USB->ISTR &= ~USB_ISTR_WKUP;
  398. } else if (_istr & USB_ISTR_SUSP) {
  399. _ev = usbd_evt_susp;
  400. USB->CNTR |= USB_CNTR_FSUSP;
  401. USB->ISTR &= ~USB_ISTR_SUSP;
  402. } else if (_istr & USB_ISTR_ERR) {
  403. USB->ISTR &= ~USB_ISTR_ERR;
  404. _ev = usbd_evt_error;
  405. } else {
  406. return;
  407. }
  408. callback(dev, _ev, _ep);
  409. }
  410. static uint32_t fnv1a32_turn (uint32_t fnv, uint32_t data ) {
  411. for (int i = 0; i < 4 ; i++) {
  412. fnv ^= (data & 0xFF);
  413. fnv *= 16777619;
  414. data >>= 8;
  415. }
  416. return fnv;
  417. }
  418. static uint16_t get_serialno_desc(void *buffer) {
  419. struct usb_string_descriptor *dsc = buffer;
  420. uint16_t *str = dsc->wString;
  421. uint32_t fnv = 2166136261;
  422. fnv = fnv1a32_turn(fnv, *(uint32_t*)(UID_BASE + UID_OFFSET_0));
  423. fnv = fnv1a32_turn(fnv, *(uint32_t*)(UID_BASE + UID_OFFSET_1));
  424. fnv = fnv1a32_turn(fnv, *(uint32_t*)(UID_BASE + UID_OFFSET_2));
  425. for (int i = 28; i >= 0; i -= 4 ) {
  426. uint16_t c = (fnv >> i) & 0x0F;
  427. c += (c < 10) ? '0' : ('A' - 10);
  428. *str++ = c;
  429. }
  430. dsc->bDescriptorType = USB_DTYPE_STRING;
  431. dsc->bLength = 18;
  432. return 18;
  433. }
  434. __attribute__((externally_visible)) const struct usbd_driver usbd_devfs = {
  435. getinfo,
  436. enable,
  437. connect,
  438. setaddr,
  439. ep_config,
  440. ep_deconfig,
  441. ep_read,
  442. ep_write,
  443. ep_setstall,
  444. ep_isstalled,
  445. evt_poll,
  446. get_frame,
  447. get_serialno_desc,
  448. };
  449. #endif //USBD_STM32L052