usb_32v1.c 13 KB

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