usb_32v0.c 13 KB

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