cdc_loop.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. #include <stdint.h>
  2. #include <stdbool.h>
  3. #include <string.h>
  4. #include "stm32.h"
  5. #include "usb.h"
  6. #include "inc/usb_cdc.h"
  7. #define CDC_EP0_SIZE 0x08
  8. #define CDC_RXD_EP 0x01
  9. #define CDC_TXD_EP 0x82
  10. #define CDC_DATA_SZ 0x40
  11. #define CDC_NTF_EP 0x83
  12. #define CDC_NTF_SZ 0x08
  13. #define CDC_LOOPBACK
  14. struct cdc_config {
  15. struct usb_config_descriptor config;
  16. struct usb_interface_descriptor comm;
  17. struct usb_cdc_header_desc cdc_hdr;
  18. struct usb_cdc_call_mgmt_desc cdc_mgmt;
  19. struct usb_cdc_acm_desc cdc_acm;
  20. struct usb_cdc_union_desc cdc_union;
  21. struct usb_endpoint_descriptor comm_ep;
  22. struct usb_interface_descriptor data;
  23. struct usb_endpoint_descriptor data_eprx;
  24. struct usb_endpoint_descriptor data_eptx;
  25. } __attribute__((packed));
  26. static const struct usb_device_descriptor device_desc = {
  27. .bLength = sizeof(struct usb_device_descriptor),
  28. .bDescriptorType = USB_DTYPE_DEVICE,
  29. .bcdUSB = VERSION_BCD(2,0,0),
  30. .bDeviceClass = USB_CLASS_CDC,
  31. .bDeviceSubClass = USB_SUBCLASS_NONE,
  32. .bDeviceProtocol = USB_PROTO_NONE,
  33. .bMaxPacketSize0 = CDC_EP0_SIZE,
  34. .idVendor = 0x0483,
  35. .idProduct = 0x5740,
  36. .bcdDevice = VERSION_BCD(1,0,0),
  37. .iManufacturer = 1,
  38. .iProduct = 2,
  39. .iSerialNumber = INTSERIALNO_DESCRIPTOR,
  40. .bNumConfigurations = 1,
  41. };
  42. static const struct cdc_config config_desc = {
  43. .config = {
  44. .bLength = sizeof(struct usb_config_descriptor),
  45. .bDescriptorType = USB_DTYPE_CONFIGURATION,
  46. .wTotalLength = sizeof(struct cdc_config),
  47. .bNumInterfaces = 2,
  48. .bConfigurationValue = 1,
  49. .iConfiguration = NO_DESCRIPTOR,
  50. .bmAttributes = USB_CFG_ATTR_RESERVED | USB_CFG_ATTR_SELFPOWERED,
  51. .bMaxPower = USB_CFG_POWER_MA(100),
  52. },
  53. .comm = {
  54. .bLength = sizeof(struct usb_interface_descriptor),
  55. .bDescriptorType = USB_DTYPE_INTERFACE,
  56. .bInterfaceNumber = 0,
  57. .bAlternateSetting = 0,
  58. .bNumEndpoints = 1,
  59. .bInterfaceClass = USB_CLASS_CDC,
  60. .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM,
  61. .bInterfaceProtocol = USB_CDC_PROTO_V25TER,
  62. .iInterface = NO_DESCRIPTOR,
  63. },
  64. .cdc_hdr = {
  65. .bFunctionLength = sizeof(struct usb_cdc_header_desc),
  66. .bDescriptorType = USB_DTYPE_CS_INTERFACE,
  67. .bDescriptorSubType = USB_DTYPE_CDC_HEADER,
  68. .bcdCDC = VERSION_BCD(1,1,0),
  69. },
  70. .cdc_mgmt = {
  71. .bFunctionLength = sizeof(struct usb_cdc_call_mgmt_desc),
  72. .bDescriptorType = USB_DTYPE_CS_INTERFACE,
  73. .bDescriptorSubType = USB_DTYPE_CDC_CALL_MANAGEMENT,
  74. .bmCapabilities = 0,
  75. .bDataInterface = 1,
  76. },
  77. .cdc_acm = {
  78. .bFunctionLength = sizeof(struct usb_cdc_acm_desc),
  79. .bDescriptorType = USB_DTYPE_CS_INTERFACE,
  80. .bDescriptorSubType = USB_DTYPE_CDC_ACM,
  81. .bmCapabilities = 0,
  82. },
  83. .cdc_union = {
  84. .bFunctionLength = sizeof(struct usb_cdc_union_desc),
  85. .bDescriptorType = USB_DTYPE_CS_INTERFACE,
  86. .bDescriptorSubType = USB_DTYPE_CDC_UNION,
  87. .bMasterInterface0 = 0,
  88. .bSlaveInterface0 = 1,
  89. },
  90. .comm_ep = {
  91. .bLength = sizeof(struct usb_endpoint_descriptor),
  92. .bDescriptorType = USB_DTYPE_ENDPOINT,
  93. .bEndpointAddress = CDC_NTF_EP,
  94. .bmAttributes = USB_EPTYPE_INTERRUPT,
  95. .wMaxPacketSize = CDC_NTF_SZ,
  96. .bInterval = 0xFF,
  97. },
  98. .data = {
  99. .bLength = sizeof(struct usb_interface_descriptor),
  100. .bDescriptorType = USB_DTYPE_INTERFACE,
  101. .bInterfaceNumber = 1,
  102. .bAlternateSetting = 0,
  103. .bNumEndpoints = 2,
  104. .bInterfaceClass = USB_CLASS_CDC_DATA,
  105. .bInterfaceSubClass = USB_SUBCLASS_NONE,
  106. .bInterfaceProtocol = USB_PROTO_NONE,
  107. .iInterface = NO_DESCRIPTOR,
  108. },
  109. .data_eprx = {
  110. .bLength = sizeof(struct usb_endpoint_descriptor),
  111. .bDescriptorType = USB_DTYPE_ENDPOINT,
  112. .bEndpointAddress = CDC_RXD_EP,
  113. .bmAttributes = USB_EPTYPE_BULK,
  114. .wMaxPacketSize = CDC_DATA_SZ,
  115. .bInterval = 0x01,
  116. },
  117. .data_eptx = {
  118. .bLength = sizeof(struct usb_endpoint_descriptor),
  119. .bDescriptorType = USB_DTYPE_ENDPOINT,
  120. .bEndpointAddress = CDC_TXD_EP,
  121. .bmAttributes = USB_EPTYPE_BULK,
  122. .wMaxPacketSize = CDC_DATA_SZ,
  123. .bInterval = 0x01,
  124. },
  125. };
  126. static const struct usb_string_descriptor lang_desc = USB_ARRAY_DESC(USB_LANGID_ENG_US);
  127. static const struct usb_string_descriptor manuf_desc_en = USB_STRING_DESC("Open source USB stack for STM32");
  128. static const struct usb_string_descriptor prod_desc_en = USB_STRING_DESC("CDC Loopback demo");
  129. static const struct usb_string_descriptor *const dtable[] = {
  130. &lang_desc,
  131. &manuf_desc_en,
  132. &prod_desc_en,
  133. };
  134. usbd_device udev;
  135. uint32_t ubuf[0x20];
  136. uint8_t dbuf[0x100];
  137. static struct usb_cdc_line_coding cdc_line = {
  138. .dwDTERate = 38400,
  139. .bCharFormat = USB_CDC_1_STOP_BITS,
  140. .bParityType = USB_CDC_NO_PARITY,
  141. .bDataBits = 8,
  142. };
  143. static usbd_respond cdc_getdesc (usbd_ctlreq *req, void **address, uint16_t *length) {
  144. const uint8_t dtype = req->wValue >> 8;
  145. const uint8_t dnumber = req->wValue & 0xFF;
  146. const void* desc;
  147. uint16_t len = 0;
  148. switch (dtype) {
  149. case USB_DTYPE_DEVICE:
  150. desc = &device_desc;
  151. break;
  152. case USB_DTYPE_CONFIGURATION:
  153. desc = &config_desc;
  154. len = sizeof(config_desc);
  155. break;
  156. case USB_DTYPE_STRING:
  157. if (dnumber < 3) {
  158. desc = dtable[dnumber];
  159. } else {
  160. return usbd_fail;
  161. }
  162. break;
  163. default:
  164. return usbd_fail;
  165. }
  166. if (len == 0) {
  167. len = ((struct usb_header_descriptor*)desc)->bLength;
  168. }
  169. *address = (void*)desc;
  170. *length = len;
  171. return usbd_ack;
  172. };
  173. static usbd_respond cdc_control(usbd_device *dev, usbd_ctlreq *req, usbd_rqc_callback *callback) {
  174. if (((USB_REQ_RECIPIENT | USB_REQ_TYPE) & req->bmRequestType) != (USB_REQ_INTERFACE | USB_REQ_CLASS)) return usbd_fail;
  175. switch (req->bRequest) {
  176. case USB_CDC_SET_CONTROL_LINE_STATE:
  177. return usbd_ack;
  178. case USB_CDC_SET_LINE_CODING:
  179. memmove( req->data, &cdc_line, sizeof(cdc_line));
  180. return usbd_ack;
  181. case USB_CDC_GET_LINE_CODING:
  182. dev->status.data_ptr = &cdc_line;
  183. dev->status.data_count = sizeof(cdc_line);
  184. return usbd_ack;
  185. default:
  186. return usbd_fail;
  187. }
  188. }
  189. static void cdc_rxonly (usbd_device *dev, uint8_t event, uint8_t ep) {
  190. usbd_ep_read(dev, ep, dbuf, CDC_DATA_SZ);
  191. }
  192. static void cdc_txonly(usbd_device *dev, uint8_t event, uint8_t ep) {
  193. uint8_t _t = dev->driver->frame_no();
  194. memset(dbuf, _t, CDC_DATA_SZ);
  195. usbd_ep_write(dev, ep, dbuf, CDC_DATA_SZ);
  196. }
  197. static void cdc_loopback (usbd_device *dev, uint8_t event, uint8_t ep) {
  198. #define WAIT_TX 0x01
  199. #define WAIT_RX 0x02
  200. static uint16_t rpos = 0;
  201. static uint8_t flags = WAIT_RX;
  202. int _t;
  203. switch (event) {
  204. read_delayed:
  205. case usbd_evt_eprx:
  206. if (rpos > (sizeof(dbuf) - CDC_DATA_SZ)) {
  207. /* buffer overflow. stop accepting data */
  208. flags &= ~WAIT_RX;
  209. } else {
  210. _t = usbd_ep_read(dev, CDC_RXD_EP, &dbuf[rpos], CDC_DATA_SZ);
  211. if (_t > 0) {
  212. rpos += _t;
  213. }
  214. }
  215. if (flags & WAIT_TX) break;
  216. flags |= WAIT_TX;
  217. case usbd_evt_eptx:
  218. if (rpos > 0) {
  219. _t = (rpos > CDC_DATA_SZ) ? CDC_DATA_SZ : rpos;
  220. _t = usbd_ep_write(dev, CDC_TXD_EP, &dbuf[0], _t);
  221. memmove(&dbuf[0], &dbuf[_t], (rpos - _t));
  222. rpos -= _t;
  223. } else {
  224. flags &= ~WAIT_TX;
  225. if (flags & WAIT_RX) break;
  226. flags |= WAIT_RX;
  227. goto read_delayed;
  228. }
  229. default:
  230. break;
  231. }
  232. }
  233. static usbd_respond cdc_setconf (usbd_device *dev, uint8_t cfg) {
  234. switch (cfg) {
  235. case 0:
  236. /* deconfiguring device */
  237. usbd_ep_deconfig(dev, CDC_RXD_EP);
  238. usbd_ep_deconfig(dev, CDC_TXD_EP);
  239. usbd_ep_deconfig(dev, CDC_NTF_EP);
  240. usbd_reg_endpoint(dev, CDC_RXD_EP, 0);
  241. usbd_reg_endpoint(dev, CDC_TXD_EP, 0);
  242. return usbd_ack;
  243. case 1:
  244. /* configuring device */
  245. usbd_ep_config(dev, CDC_RXD_EP, USB_EPTYPE_BULK | USB_EPTYPE_DBLBUF, CDC_DATA_SZ);
  246. usbd_ep_config(dev, CDC_TXD_EP, USB_EPTYPE_BULK | USB_EPTYPE_DBLBUF, CDC_DATA_SZ);
  247. usbd_ep_config(dev, CDC_NTF_EP, USB_EPTYPE_INTERRUPT, CDC_NTF_SZ);
  248. #if defined(CDC_LOOPBACK)
  249. usbd_reg_endpoint(dev, CDC_RXD_EP, cdc_loopback);
  250. usbd_reg_endpoint(dev, CDC_TXD_EP, cdc_loopback);
  251. #else
  252. usbd_reg_endpoint(dev, CDC_RXD_EP, cdc_rxonly);
  253. usbd_reg_endpoint(dev, CDC_TXD_EP, cdc_txonly);
  254. usbd_ep_write(dev, CDC_TXD_EP, 0, 0);
  255. #endif
  256. return usbd_ack;
  257. default:
  258. return usbd_fail;
  259. }
  260. }
  261. static void cdc_init_usbd(void) {
  262. usbd_init(&udev, &usbd_hw, CDC_EP0_SIZE, ubuf, sizeof(ubuf));
  263. usbd_reg_config(&udev, cdc_setconf);
  264. usbd_reg_control(&udev, cdc_control);
  265. usbd_reg_descr(&udev, cdc_getdesc);
  266. }
  267. static void cdc_init_rcc(void) {
  268. BST(RCC->APB1ENR, RCC_APB1ENR_PWREN);
  269. BMD(PWR->CR, PWR_CR_VOS, PWR_CR_VOS_0);
  270. WBC(PWR->CSR, PWR_CSR_VOSF);
  271. /* set FLASH latency to 1 */
  272. #if defined(STM32L1)
  273. BST(FLASH->ACR, FLASH_ACR_ACC64);
  274. #endif
  275. BST(FLASH->ACR, FLASH_ACR_LATENCY);
  276. /* set PLL clock HSI * 6/4 (24 MHz) */
  277. BMD(RCC->CFGR, RCC_CFGR_PLLDIV | RCC_CFGR_PLLMUL | RCC_CFGR_PLLSRC, RCC_CFGR_PLLDIV3 | RCC_CFGR_PLLMUL6);
  278. BST(RCC->CR, RCC_CR_HSION);
  279. WBS(RCC->CR, RCC_CR_HSIRDY);
  280. BST(RCC->CR, RCC_CR_PLLON);
  281. WBS(RCC->CR, RCC_CR_PLLRDY);
  282. /* switch clock to PLL */
  283. BMD(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_PLL);
  284. WVL(RCC->CFGR, RCC_CFGR_SWS, RCC_CFGR_SWS_PLL);
  285. }
  286. void __libc_init_array(void) {
  287. }
  288. void SystemInit(void) {
  289. cdc_init_rcc();
  290. }
  291. void main(void) {
  292. cdc_init_usbd();
  293. usbd_control(&udev, usbd_cmd_enable);
  294. usbd_control(&udev, usbd_cmd_connect);
  295. while(1) {
  296. usbd_poll(&udev);
  297. }
  298. }