SWM341_usbd.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514
  1. /******************************************************************************************************************************************
  2. * 文件名称: SWM341_usbd.c
  3. * 功能说明: SWM341单片机的USB设备功能驱动库
  4. * 技术支持: http://www.synwit.com.cn/e/tool/gbook/?bid=1
  5. * 注意事项:
  6. * 版本日期: V1.1.0 2020年11月3日
  7. * 升级记录:
  8. *
  9. *
  10. *******************************************************************************************************************************************
  11. * @attention
  12. *
  13. * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH CODING INFORMATION
  14. * REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A RESULT, SYNWIT SHALL NOT BE HELD LIABLE
  15. * FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
  16. * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONN-
  17. * -ECTION WITH THEIR PRODUCTS.
  18. *
  19. * COPYRIGHT 2012 Synwit Technology
  20. *******************************************************************************************************************************************/
  21. #include <string.h>
  22. #include "SWM341.h"
  23. #include "SWM341_usbd.h"
  24. USBD_Info_t USBD_Info;
  25. static uint8_t *CtrlIn_Ptr = 0;
  26. static uint8_t *CtrlOut_Ptr = 0;
  27. static volatile uint32_t CtrlIn_Size = 0;
  28. static volatile uint32_t CtrlOut_Size = 0;
  29. static volatile uint32_t CtrlOut_Limit = 0;
  30. /******************************************************************************************************************************************
  31. * 函数名称: USBD_Init()
  32. * 功能说明: USB Device 初始化
  33. * 输 入: 无
  34. * 输 出: 无
  35. * 注意事项: 无
  36. ******************************************************************************************************************************************/
  37. void USBD_Init(void)
  38. {
  39. uint8_t ep_reg = 0, ep_nbr, ep_dir, ep_type, cfg, intf, alt;
  40. uint16_t ep_pksz;
  41. uint8_t *pCfg = USBD_Info.DescConfig;
  42. uint32_t total_len = pCfg[2] + (pCfg[3] << 8);
  43. uint32_t epie = 0x00010001;
  44. SYS->USBCR = 0;
  45. for(int i = 0; i < CyclesPerUs; i++) __NOP();
  46. SYS->USBCR |= (1 << SYS_USBCR_RST48M_Pos); __DSB();
  47. SYS->USBCR |= (1 << SYS_USBCR_RST12M_Pos); __DSB();
  48. SYS->USBCR |= (1 << SYS_USBCR_RSTPLL_Pos); __DSB();
  49. SYS->USBCR &= ~SYS_USBCR_ROLE_Msk;
  50. SYS->USBCR |= (USBD_Info.Mode << SYS_USBCR_ROLE_Pos);
  51. SYS->USBCR |= (1 << SYS_USBCR_VBUS_Pos);
  52. SYS->CLKEN0 |= (0x01 << SYS_CLKEN0_USB_Pos);
  53. USBD_EPConfig(ep_reg++, 0, USB_EP_IN, USB_EP_CTRL, USBD_Info.CtrlPkSiz, 0, 0, 0); // Control In
  54. USBD_EPConfig(ep_reg++, 0, USB_EP_OUT, USB_EP_CTRL, USBD_Info.CtrlPkSiz, 0, 0, 0); // Control Out
  55. while(pCfg < (USBD_Info.DescConfig + total_len))
  56. {
  57. switch(pCfg[1])
  58. {
  59. case USB_DESC_CONFIG:
  60. cfg = pCfg[5];
  61. break;
  62. case USB_DESC_INTERFACE:
  63. intf = pCfg[2];
  64. alt = pCfg[3];
  65. break;
  66. case USB_DESC_ENDPOINT:
  67. ep_nbr = pCfg[2] & 0x0F;
  68. ep_dir = pCfg[2] & USB_EP_IN;
  69. ep_type = pCfg[3] & 0x03;
  70. ep_pksz = pCfg[4] + (pCfg[5] << 8);
  71. USBD_EPConfig(ep_reg++, ep_nbr, ep_dir, ep_type, ep_pksz, cfg, intf, alt);
  72. epie |= (1 << ep_nbr) << (ep_dir ? 0 : 16);
  73. break;
  74. }
  75. pCfg += pCfg[0];
  76. }
  77. USBD->FFTHR = (0xFFF << 16) | (0x000 << 0); // 无用
  78. USBD->DEVCR = (USBD_Info.Speed << USBD_DEVCR_SPEED_Pos) |
  79. (1 << USBD_DEVCR_DEVICE_Pos) |
  80. (1 << USBD_DEVCR_CSRDONE_Pos);
  81. USBD->DEVIE = (1 << USBD_DEVIE_RST_Pos) |
  82. (1 << USBD_DEVIE_SETUP_Pos) |
  83. (1 << USBD_DEVIE_SETCFG_Pos);
  84. USBD->EPIE = epie;
  85. SYS->USBPHYCR &= ~SYS_USBPHYCR_OPMODE_Msk;
  86. SYS->USBPHYCR |= (0 << SYS_USBPHYCR_OPMODE_Pos); //Normal Operation
  87. }
  88. /******************************************************************************************************************************************
  89. * 函数名称: USBD_EPConfig()
  90. * 功能说明: USB Device Endpoint Configure
  91. * 输 入: uint8_t ep_reg Endpoint Register
  92. * uint8_t ep_nbr Endpoint Number used by host
  93. * uint8_t ep_dir Endpoint Direction, 0 Out 1 In
  94. * uint8_t ep_type Endpoint Type, 0 Control 1 Isochronous 2 Bulk 3 Interrupt
  95. * uint16_t ep_pksz Maximum packet size in byte
  96. * uint8_t cfg Configuration number to which this endpoint belongs
  97. * uint8_t intf Interface number to which this endpoint belongs
  98. * uint8_t alt Alternate setting to which this endpoint belongs
  99. * 输 出: 无
  100. * 注意事项: 无
  101. ******************************************************************************************************************************************/
  102. void USBD_EPConfig(uint8_t ep_reg, uint8_t ep_nbr, uint8_t ep_dir, uint8_t ep_type, uint16_t ep_pksz, uint8_t cfg, uint8_t intf, uint8_t alt)
  103. {
  104. ep_dir = ep_dir ? 1 : 0; // for USB_EP_IN、USB_EP_OUT
  105. USBD->EPCFG[ep_reg] = (ep_nbr << USBD_EPCFG_EPNR_Pos) |
  106. (ep_dir << USBD_EPCFG_DIR_Pos) |
  107. (ep_type << USBD_EPCFG_TYPE_Pos) |
  108. (cfg << USBD_EPCFG_CFG_Pos) |
  109. (intf << USBD_EPCFG_INTF_Pos) |
  110. (alt << USBD_EPCFG_ALT_Pos) |
  111. (ep_pksz << USBD_EPCFG_PKSZ_Pos);
  112. if(ep_dir == USB_EP_OUT)
  113. {
  114. USBD->OUTEP[ep_nbr].RXCR = 0;
  115. USBD->OUTEP[ep_nbr].RXCR = USBD_RXCR_FLUSHFF_Msk;
  116. }
  117. else
  118. {
  119. USBD->INEP[ep_nbr].TXCR = 0;
  120. USBD->INEP[ep_nbr].TXCR = USBD_TXCR_FLUSHFF_Msk;
  121. }
  122. }
  123. /******************************************************************************************************************************************
  124. * 函数名称: USBD_Open()
  125. * 功能说明: USB Device 打开
  126. * 输 入: 无
  127. * 输 出: 无
  128. * 注意事项: 无
  129. ******************************************************************************************************************************************/
  130. void USBD_Open(void)
  131. {
  132. NVIC_EnableIRQ(USB_IRQn);
  133. }
  134. /******************************************************************************************************************************************
  135. * 函数名称: USBD_Close()
  136. * 功能说明: USB Device 关闭
  137. * 输 入: 无
  138. * 输 出: 无
  139. * 注意事项: 无
  140. ******************************************************************************************************************************************/
  141. void USBD_Close(void)
  142. {
  143. NVIC_DisableIRQ(USB_IRQn);
  144. }
  145. void USBD_StandardRequest(USB_Setup_Packet_t * pSetup);
  146. void USBD_GetDescriptor(USB_Setup_Packet_t * pSetup);
  147. static USB_Setup_Packet_t Setup_Packet;
  148. USB_Setup_Packet_t * pUSB_Setup = &Setup_Packet;
  149. /******************************************************************************************************************************************
  150. * 函数名称: USBD_ProcessSetupPacket()
  151. * 功能说明: 处理Setup包
  152. * 输 入: 无
  153. * 输 出: 无
  154. * 注意事项: 无
  155. ******************************************************************************************************************************************/
  156. void USBD_ProcessSetupPacket(void)
  157. {
  158. ((volatile uint32_t *)pUSB_Setup)[0] = USBD->SETUPD1;
  159. ((volatile uint32_t *)pUSB_Setup)[1] = USBD->SETUPD2;
  160. switch(pUSB_Setup->bRequestType & 0x60)
  161. {
  162. case USB_REQ_STANDARD:
  163. USBD_StandardRequest(pUSB_Setup);
  164. break;
  165. case USB_REQ_CLASS:
  166. if(USBD_Info.pClassRequest_Callback != NULL)
  167. {
  168. USBD_Info.pClassRequest_Callback(pUSB_Setup);
  169. }
  170. break;
  171. case USB_REQ_VENDOR:
  172. if(USBD_Info.pVendorRequest_Callback != NULL)
  173. {
  174. USBD_Info.pVendorRequest_Callback(pUSB_Setup);
  175. }
  176. break;
  177. default:
  178. /* Setup error, stall the device */
  179. USBD_Stall0();
  180. break;
  181. }
  182. }
  183. /******************************************************************************************************************************************
  184. * 函数名称: USBD_StandardRequest()
  185. * 功能说明: 处理标准请求
  186. * 输 入: 无
  187. * 输 出: 无
  188. * 注意事项: GetDescriptor、SetDescriptor、SyncFrame之外的标准命令USB模块自动处理,无需用户代码参与
  189. ******************************************************************************************************************************************/
  190. void USBD_StandardRequest(USB_Setup_Packet_t * pSetup)
  191. {
  192. if(pSetup->bRequestType & 0x80) // Device to host
  193. {
  194. switch(pSetup->bRequest)
  195. {
  196. case USB_GET_DESCRIPTOR:
  197. USBD_GetDescriptor(pSetup);
  198. /* Status stage */
  199. USBD_RxReady(0);
  200. break;
  201. default:
  202. /* Setup error, stall the device */
  203. USBD_Stall0();
  204. break;
  205. }
  206. }
  207. else // Host to device
  208. {
  209. switch(pSetup->bRequest)
  210. {
  211. default:
  212. /* Setup error, stall the device */
  213. USBD_Stall0();
  214. break;
  215. }
  216. }
  217. }
  218. /******************************************************************************************************************************************
  219. * 函数名称: USBD_GetDescriptor()
  220. * 功能说明: 处理标准请求GetDescriptor
  221. * 输 入: 无
  222. * 输 出: 无
  223. * 注意事项: 无
  224. ******************************************************************************************************************************************/
  225. void USBD_GetDescriptor(USB_Setup_Packet_t * pSetup)
  226. {
  227. #define min(a, b) ((a)<(b) ? (a) : (b))
  228. switch(pSetup->wValue >> 8)
  229. {
  230. case USB_DESC_DEVICE:
  231. USBD_PrepareCtrlIn(USBD_Info.DescDevice, min(pSetup->wLength, USBD_Info.DescDevice[0]));
  232. break;
  233. case USB_DESC_CONFIG:
  234. {
  235. uint16_t total_len = USBD_Info.DescConfig[2] + (USBD_Info.DescConfig[3] << 8);
  236. USBD_PrepareCtrlIn(USBD_Info.DescConfig, min(pSetup->wLength, total_len));
  237. break;
  238. }
  239. case USB_DESC_STRING:
  240. {
  241. uint8_t index = pSetup->wValue & 0xFF;
  242. if(index < 6)
  243. {
  244. USBD_PrepareCtrlIn(USBD_Info.DescString[index], min(pSetup->wLength, USBD_Info.DescString[index][0]));
  245. }
  246. else if((index == 0xEE) && USBD_Info.DescOSString)
  247. {
  248. USBD_PrepareCtrlIn(USBD_Info.DescOSString, min(pSetup->wLength, USBD_Info.DescOSString[0]));
  249. }
  250. else
  251. {
  252. /* Not support. Reply STALL. */
  253. USBD_Stall0();
  254. }
  255. break;
  256. }
  257. case USB_DESC_BOS:
  258. {
  259. uint16_t total_len = USBD_Info.DescBOS[2] + (USBD_Info.DescBOS[3] << 8);
  260. USBD_PrepareCtrlIn(USBD_Info.DescBOS, min(pSetup->wLength, total_len));
  261. break;
  262. }
  263. case USB_DESC_HID:
  264. {
  265. uint8_t index = pSetup->wIndex & 0xFF;
  266. uint16_t offset = USBD_Info.DescHIDOffset[index];
  267. uint8_t *descHID = &USBD_Info.DescConfig[offset];
  268. USBD_PrepareCtrlIn(descHID, min(pSetup->wLength, descHID[0]));
  269. break;
  270. }
  271. case USB_DESC_HID_RPT:
  272. {
  273. uint8_t index = pSetup->wIndex & 0xFF;
  274. uint16_t offset = USBD_Info.DescHIDOffset[index];
  275. uint8_t *descHID = &USBD_Info.DescConfig[offset];
  276. uint16_t report_len = descHID[7] + (descHID[8] << 8);
  277. USBD_PrepareCtrlIn(USBD_Info.DescHIDReport[index], min(pSetup->wLength, report_len));
  278. break;
  279. }
  280. default:
  281. /* Not support. Reply STALL.*/
  282. USBD_Stall0();
  283. break;
  284. }
  285. }
  286. /******************************************************************************************************************************************
  287. * 函数名称: USBD_PrepareCtrlIn()
  288. * 功能说明: Prepare the first Control IN pipe
  289. * 输 入: 无
  290. * 输 出: 无
  291. * 注意事项: 无
  292. ******************************************************************************************************************************************/
  293. void USBD_PrepareCtrlIn(uint8_t buf[], uint32_t size)
  294. {
  295. CtrlIn_Ptr = buf;
  296. CtrlIn_Size = size;
  297. USBD_CtrlIn();
  298. }
  299. /******************************************************************************************************************************************
  300. * 函数名称: USBD_CtrlIn()
  301. * 功能说明: Repeat Control IN pipe. This function processes the remained data of Control IN transfer
  302. * 输 入: 无
  303. * 输 出: 无
  304. * 注意事项: 无
  305. ******************************************************************************************************************************************/
  306. void USBD_CtrlIn(void)
  307. {
  308. static uint8_t ZeroLenPk = 0;
  309. if(CtrlIn_Size)
  310. {
  311. /* Process remained data */
  312. if(CtrlIn_Size > USBD_Info.CtrlPkSiz)
  313. {
  314. USBD_TxWrite(0, CtrlIn_Ptr, USBD_Info.CtrlPkSiz);
  315. CtrlIn_Ptr += USBD_Info.CtrlPkSiz;
  316. CtrlIn_Size -= USBD_Info.CtrlPkSiz;
  317. }
  318. else
  319. {
  320. USBD_TxWrite(0, CtrlIn_Ptr, CtrlIn_Size);
  321. if(CtrlIn_Size == USBD_Info.CtrlPkSiz)
  322. {
  323. ZeroLenPk = 1;
  324. }
  325. CtrlIn_Ptr = 0;
  326. CtrlIn_Size = 0;
  327. }
  328. }
  329. else
  330. {
  331. /* For the case of data size is integral times maximum packet size */
  332. if(ZeroLenPk)
  333. {
  334. ZeroLenPk = 0;
  335. USBD_TxWrite(0, 0, 0);
  336. }
  337. }
  338. }
  339. /******************************************************************************************************************************************
  340. * 函数名称: USBD_PrepareCtrlOut()
  341. * 功能说明: Prepare the first Control OUT pipe
  342. * 输 入: 无
  343. * 输 出: 无
  344. * 注意事项: 无
  345. ******************************************************************************************************************************************/
  346. void USBD_PrepareCtrlOut(uint8_t *buf, uint32_t size)
  347. {
  348. CtrlOut_Ptr = buf;
  349. CtrlOut_Size = 0u;
  350. CtrlOut_Limit = size;
  351. USBD_RxReady(0);
  352. }
  353. /******************************************************************************************************************************************
  354. * 函数名称: USBD_CtrlOut()
  355. * 功能说明: Repeat Control OUT pipe. This function processes the successive Control OUT transfer
  356. * 输 入: 无
  357. * 输 出: 无
  358. * 注意事项: 无
  359. ******************************************************************************************************************************************/
  360. void USBD_CtrlOut(void)
  361. {
  362. if(CtrlOut_Size < CtrlOut_Limit)
  363. {
  364. uint16_t size = USBD_RxRead(CtrlOut_Ptr, CtrlOut_Limit - CtrlOut_Size);
  365. CtrlOut_Ptr += size;
  366. CtrlOut_Size += size;
  367. if(CtrlOut_Size < CtrlOut_Limit)
  368. {
  369. USBD_RxReady(0);
  370. }
  371. }
  372. }
  373. /******************************************************************************************************************************************
  374. * 函数名称: USBD_TxWrite()
  375. * 功能说明: 将要发送到主机的数据写入端点的FIFO
  376. * 输 入: uint8_t epnr endpoint number
  377. * uint8_t *data 要写入FIFO的数据
  378. * uint16_t size 要写入数据的个数
  379. * 输 出: 无
  380. * 注意事项: 无
  381. ******************************************************************************************************************************************/
  382. void USBD_TxWrite(uint8_t epnr, uint8_t *data, uint16_t size)
  383. {
  384. __disable_irq();
  385. USBD->INEP[epnr].TXCR = (1 << USBD_TXCR_FLUSHFF_Pos);
  386. USBD->INEP[epnr].TXTRSZ = size;
  387. if(size) USBD_memcpy((uint8_t *)USBD->TXBUF[epnr], data, size);
  388. USBD->INEP[epnr].TXCR = (1 << USBD_TXCR_FFRDY_Pos);
  389. __enable_irq();
  390. }
  391. /******************************************************************************************************************************************
  392. * 函数名称: USBD_RxRead()
  393. * 功能说明: 读取接收到的数据
  394. * 输 入: uint8_t *buff 读取到的数据存入buff
  395. * uint16_t size buff大小
  396. * 输 出: uint16_t 实际读取到数据的个数
  397. * 注意事项: 无
  398. ******************************************************************************************************************************************/
  399. uint16_t USBD_RxRead(uint8_t *buff, uint16_t size)
  400. {
  401. __disable_irq();
  402. uint16_t real_size = (USBD->RXSR & USBD_RXSR_TRSZ_Msk) >> USBD_RXSR_TRSZ_Pos;
  403. if(size > real_size)
  404. size = real_size;
  405. USBD_memcpy(buff, (uint8_t *)USBD->RXBUF, size);
  406. __enable_irq();
  407. return size;
  408. }
  409. /******************************************************************************************************************************************
  410. * 函数名称: USBD_memcpy()
  411. * 功能说明: 访问 USB Buffer 的 memcpy
  412. * 输 入: void *destin 目的地址
  413. * void *source 源地址
  414. * uint32_t nByte 拷贝字节数
  415. * 输 出: 无
  416. * 注意事项: 访问 USB Buffer 必须使用 USBD_memcpy,不能使用库函数 memcpy
  417. ******************************************************************************************************************************************/
  418. void USBD_memcpy(uint8_t *destin, uint8_t *source, uint32_t nByte)
  419. {
  420. while(nByte > 3)
  421. {
  422. *((uint32_t *)destin) = *((uint32_t *)source);
  423. destin += 4;
  424. source += 4;
  425. nByte -= 4;
  426. }
  427. while(nByte > 1)
  428. {
  429. *((uint16_t *)destin) = *((uint16_t *)source);
  430. destin += 2;
  431. source += 2;
  432. nByte -= 2;
  433. }
  434. while(nByte > 0)
  435. {
  436. *destin = *source;
  437. destin += 1;
  438. source += 1;
  439. nByte -= 1;
  440. }
  441. }