PageRenderTime 65ms CodeModel.GetById 33ms RepoModel.GetById 1ms app.codeStats 0ms

/windcatcher/tempunincluded3/usbhw.c

https://github.com/FlameN/STM32RUNO
C | 507 lines | 232 code | 110 blank | 165 comment | 29 complexity | 3d52373df69ce8b8aa3ddbbcbd987b54 MD5 | raw file
  1. /*----------------------------------------------------------------------------
  2. * U S B - K e r n e l
  3. *----------------------------------------------------------------------------
  4. * Name: USBHW.C
  5. * Purpose: USB Hardware Layer Module for ST STM32F10x
  6. * Version: V1.10
  7. *----------------------------------------------------------------------------
  8. * This file is part of the uVision/ARM development tools.
  9. * This software may only be used under the terms of a valid, current,
  10. * end user licence from KEIL for a compatible version of KEIL software
  11. * development tools. Nothing else gives you the right to use it.
  12. *
  13. * Copyright (c) 2005-2007 Keil Software.
  14. *---------------------------------------------------------------------------*/
  15. /* Double Buffering is not yet supported */
  16. #include "stm32f10x.h" // stm32f10x definitions
  17. #include "type.h"
  18. #include "usb.h"
  19. #include "usbcfg.h"
  20. #include "usbreg.h"
  21. #include "usbhw.h"
  22. #include "usbuser.h"
  23. #define EP_BUF_ADDR (sizeof(EP_BUF_DSCR)*USB_EP_NUM) /* Endpoint Buffer Start Address */
  24. /* Pointer to Endpoint Buffer Descriptors */
  25. EP_BUF_DSCR *pBUF_DSCR = (EP_BUF_DSCR *)USB_PMA_ADDR;
  26. /* Endpoint Free Buffer Address */
  27. WORD FreeBufAddr;
  28. /*
  29. * Reset Endpoint
  30. * Parameters: EPNum: Endpoint Number
  31. * EPNum.0..3: Address
  32. * EPNum.7: Dir
  33. * Return Value: None
  34. */
  35. void EP_Reset (DWORD EPNum) {
  36. DWORD num, val;
  37. num = EPNum & 0x0F;
  38. val = EPxREG(num);
  39. if (EPNum & 0x80) { /* IN Endpoint */
  40. EPxREG(num) = val & (EP_MASK | EP_DTOG_TX);
  41. } else { /* OUT Endpoint */
  42. EPxREG(num) = val & (EP_MASK | EP_DTOG_RX);
  43. }
  44. }
  45. /*
  46. * Set Endpoint Status
  47. * Parameters: EPNum: Endpoint Number
  48. * EPNum.0..3: Address
  49. * EPNum.7: Dir
  50. * stat: New Status
  51. * Return Value: None
  52. */
  53. void EP_Status (DWORD EPNum, DWORD stat) {
  54. DWORD num, val;
  55. num = EPNum & 0x0F;
  56. val = EPxREG(num);
  57. if (EPNum & 0x80) { /* IN Endpoint */
  58. EPxREG(num) = (val ^ (stat & EP_STAT_TX)) & (EP_MASK | EP_STAT_TX);
  59. } else { /* OUT Endpoint */
  60. EPxREG(num) = (val ^ (stat & EP_STAT_RX)) & (EP_MASK | EP_STAT_RX);
  61. }
  62. }
  63. /*
  64. * USB Initialize Function
  65. * Called by the User to initialize USB
  66. * Return Value: None
  67. */
  68. void USB_Init (void) {
  69. RCC->APB1ENR |= (1 << 23); /* enable clock for USB */
  70. /* Enable USB Interrupts */
  71. NVIC->IP [5] |= 0x00000010; /* set priority lower than SVC */
  72. NVIC->ISER[0] |= (1 << (USB_LP_CAN1_RX0_IRQn & 0x1F));
  73. /* Control USB connecting via SW */
  74. RCC->APB2ENR |= (1 << 5); /* enable clock for GPIOD */
  75. GPIOD->CRL &= ~0x00000F00; /* clear port PD2 */
  76. GPIOD->CRL |= 0x00000700; /* PD2 General purpose output open-drain, max speed 50 MHz */
  77. GPIOD->BRR = 0x0004; /* reset PD2 (set to low) */
  78. }
  79. /*
  80. * USB Connect Function
  81. * Called by the User to Connect/Disconnect USB
  82. * Parameters: con: Connect/Disconnect
  83. * Return Value: None
  84. */
  85. void USB_Connect (BOOL con) {
  86. CNTR = CNTR_FRES; /* Force USB Reset */
  87. ISTR = 0; /* Clear Interrupt Status */
  88. if (con) {
  89. CNTR = CNTR_RESETM; /* USB Reset Interrupt Mask */
  90. } else {
  91. CNTR = CNTR_FRES | CNTR_PDWN; /* Switch Off USB Device */
  92. }
  93. }
  94. /*
  95. * USB Reset Function
  96. * Called automatically on USB Reset
  97. * Return Value: None
  98. */
  99. void USB_Reset (void) {
  100. /* Double Buffering is not yet supported */
  101. ISTR = 0; /* Clear Interrupt Status */
  102. CNTR = CNTR_CTRM | CNTR_RESETM |
  103. (USB_SUSPEND_EVENT ? CNTR_SUSPM : 0) |
  104. (USB_WAKEUP_EVENT ? CNTR_WKUPM : 0) |
  105. (USB_ERROR_EVENT ? CNTR_ERRM : 0) |
  106. (USB_ERROR_EVENT ? CNTR_PMAOVRM : 0) |
  107. (USB_SOF_EVENT ? CNTR_SOFM : 0) |
  108. (USB_SOF_EVENT ? CNTR_ESOFM : 0);
  109. FreeBufAddr = EP_BUF_ADDR;
  110. BTABLE = 0x00; /* set BTABLE Address */
  111. /* Setup Control Endpoint 0 */
  112. pBUF_DSCR->ADDR_TX = FreeBufAddr;
  113. FreeBufAddr += USB_MAX_PACKET0;
  114. pBUF_DSCR->ADDR_RX = FreeBufAddr;
  115. FreeBufAddr += USB_MAX_PACKET0;
  116. if (USB_MAX_PACKET0 > 62) {
  117. pBUF_DSCR->COUNT_RX = ((USB_MAX_PACKET0 << 5) - 1) | 0x8000;
  118. } else {
  119. pBUF_DSCR->COUNT_RX = USB_MAX_PACKET0 << 9;
  120. }
  121. EPxREG(0) = EP_CONTROL | EP_RX_VALID;
  122. DADDR = DADDR_EF | 0; /* Enable USB Default Address */
  123. }
  124. /*
  125. * USB Suspend Function
  126. * Called automatically on USB Suspend
  127. * Return Value: None
  128. */
  129. void USB_Suspend (void) {
  130. CNTR |= CNTR_FSUSP; /* Force Suspend */
  131. CNTR |= CNTR_LPMODE; /* Low Power Mode */
  132. }
  133. /*
  134. * USB Resume Function
  135. * Called automatically on USB Resume
  136. * Return Value: None
  137. */
  138. void USB_Resume (void) {
  139. /* Performed by Hardware */
  140. }
  141. /*
  142. * USB Remote Wakeup Function
  143. * Called automatically on USB Remote Wakeup
  144. * Return Value: None
  145. */
  146. void USB_WakeUp (void) {
  147. CNTR &= ~CNTR_FSUSP; /* Clear Suspend */
  148. }
  149. /*
  150. * USB Remote Wakeup Configuration Function
  151. * Parameters: cfg: Enable/Disable
  152. * Return Value: None
  153. */
  154. void USB_WakeUpCfg (BOOL cfg) {
  155. /* Not needed */
  156. }
  157. /*
  158. * USB Set Address Function
  159. * Parameters: adr: USB Address
  160. * Return Value: None
  161. */
  162. void USB_SetAddress (DWORD adr) {
  163. DADDR = DADDR_EF | adr;
  164. }
  165. /*
  166. * USB Configure Function
  167. * Parameters: cfg: Configure/Deconfigure
  168. * Return Value: None
  169. */
  170. void USB_Configure (BOOL cfg) {
  171. cfg = cfg;
  172. }
  173. /*
  174. * Configure USB Endpoint according to Descriptor
  175. * Parameters: pEPD: Pointer to Endpoint Descriptor
  176. * Return Value: None
  177. */
  178. void USB_ConfigEP (USB_ENDPOINT_DESCRIPTOR *pEPD) {
  179. /* Double Buffering is not yet supported */
  180. DWORD num, val;
  181. num = pEPD->bEndpointAddress & 0x0F;
  182. val = pEPD->wMaxPacketSize;
  183. if (pEPD->bEndpointAddress & USB_ENDPOINT_DIRECTION_MASK) {
  184. (pBUF_DSCR + num)->ADDR_TX = FreeBufAddr;
  185. val = (val + 1) & ~1;
  186. } else {
  187. (pBUF_DSCR + num)->ADDR_RX = FreeBufAddr;
  188. if (val > 62) {
  189. val = (val + 31) & ~31;
  190. (pBUF_DSCR + num)->COUNT_RX = ((val << 5) - 1) | 0x8000;
  191. } else {
  192. val = (val + 1) & ~1;
  193. (pBUF_DSCR + num)->COUNT_RX = val << 9;
  194. }
  195. }
  196. FreeBufAddr += val;
  197. switch (pEPD->bmAttributes & USB_ENDPOINT_TYPE_MASK) {
  198. case USB_ENDPOINT_TYPE_CONTROL:
  199. val = EP_CONTROL;
  200. break;
  201. case USB_ENDPOINT_TYPE_ISOCHRONOUS:
  202. val = EP_ISOCHRONOUS;
  203. break;
  204. case USB_ENDPOINT_TYPE_BULK:
  205. val = EP_BULK;
  206. if (USB_DBL_BUF_EP & (1 << num)) {
  207. val |= EP_KIND;
  208. }
  209. break;
  210. case USB_ENDPOINT_TYPE_INTERRUPT:
  211. val = EP_INTERRUPT;
  212. break;
  213. }
  214. val |= num;
  215. EPxREG(num) = val;
  216. }
  217. /*
  218. * Set Direction for USB Control Endpoint
  219. * Parameters: dir: Out (dir == 0), In (dir <> 0)
  220. * Return Value: None
  221. */
  222. void USB_DirCtrlEP (DWORD dir) {
  223. /* Not needed */
  224. }
  225. /*
  226. * Enable USB Endpoint
  227. * Parameters: EPNum: Endpoint Number
  228. * EPNum.0..3: Address
  229. * EPNum.7: Dir
  230. * Return Value: None
  231. */
  232. void USB_EnableEP (DWORD EPNum) {
  233. EP_Status(EPNum, EP_TX_VALID | EP_RX_VALID);
  234. }
  235. /*
  236. * Disable USB Endpoint
  237. * Parameters: EPNum: Endpoint Number
  238. * EPNum.0..3: Address
  239. * EPNum.7: Dir
  240. * Return Value: None
  241. */
  242. void USB_DisableEP (DWORD EPNum) {
  243. EP_Status(EPNum, EP_TX_DIS | EP_RX_DIS);
  244. }
  245. /*
  246. * Reset USB Endpoint
  247. * Parameters: EPNum: Endpoint Number
  248. * EPNum.0..3: Address
  249. * EPNum.7: Dir
  250. * Return Value: None
  251. */
  252. void USB_ResetEP (DWORD EPNum) {
  253. EP_Reset(EPNum);
  254. }
  255. /*
  256. * Set Stall for USB Endpoint
  257. * Parameters: EPNum: Endpoint Number
  258. * EPNum.0..3: Address
  259. * EPNum.7: Dir
  260. * Return Value: None
  261. */
  262. void USB_SetStallEP (DWORD EPNum) {
  263. EP_Status(EPNum, EP_TX_STALL | EP_RX_STALL);
  264. }
  265. /*
  266. * Clear Stall for USB Endpoint
  267. * Parameters: EPNum: Endpoint Number
  268. * EPNum.0..3: Address
  269. * EPNum.7: Dir
  270. * Return Value: None
  271. */
  272. void USB_ClrStallEP (DWORD EPNum) {
  273. EP_Status(EPNum, EP_TX_VALID | EP_RX_VALID);
  274. }
  275. /*
  276. * Read USB Endpoint Data
  277. * Parameters: EPNum: Endpoint Number
  278. * EPNum.0..3: Address
  279. * EPNum.7: Dir
  280. * pData: Pointer to Data Buffer
  281. * Return Value: Number of bytes read
  282. */
  283. DWORD USB_ReadEP (DWORD EPNum, BYTE *pData) {
  284. /* Double Buffering is not yet supported */
  285. DWORD num, cnt, *pv, n;
  286. num = EPNum & 0x0F;
  287. pv = (DWORD *)(USB_PMA_ADDR + 2*((pBUF_DSCR + num)->ADDR_RX));
  288. cnt = (pBUF_DSCR + num)->COUNT_RX & EP_COUNT_MASK;
  289. for (n = 0; n < (cnt + 1) / 2; n++) {
  290. *((__attribute__((packed)) WORD *)pData) = *pv++;
  291. pData += 2;
  292. }
  293. EP_Status(EPNum, EP_RX_VALID);
  294. return (cnt);
  295. }
  296. /*
  297. * Write USB Endpoint Data
  298. * Parameters: EPNum: Endpoint Number
  299. * EPNum.0..3: Address
  300. * EPNum.7: Dir
  301. * pData: Pointer to Data Buffer
  302. * cnt: Number of bytes to write
  303. * Return Value: Number of bytes written
  304. */
  305. DWORD USB_WriteEP (DWORD EPNum, BYTE *pData, DWORD cnt) {
  306. /* Double Buffering is not yet supported */
  307. DWORD num, *pv, n;
  308. num = EPNum & 0x0F;
  309. pv = (DWORD *)(USB_PMA_ADDR + 2*((pBUF_DSCR + num)->ADDR_TX));
  310. for (n = 0; n < (cnt + 1) / 2; n++) {
  311. *pv++ = *((__attribute__((packed)) WORD *)pData);
  312. pData += 2;
  313. }
  314. (pBUF_DSCR + num)->COUNT_TX = cnt;
  315. EP_Status(EPNum, EP_TX_VALID);
  316. return (cnt);
  317. }
  318. /*
  319. * Get USB Last Frame Number
  320. * Parameters: None
  321. * Return Value: Frame Number
  322. */
  323. DWORD USB_GetFrame (void) {
  324. return (FNR & FNR_FN);
  325. }
  326. /*
  327. * USB Interrupt Service Routine
  328. */
  329. void USB_LP_CAN1_RX0_IRQHandler (void) {
  330. DWORD istr, num, val;
  331. istr = ISTR;
  332. /* USB Reset Request */
  333. if (istr & ISTR_RESET) {
  334. USB_Reset();
  335. #if USB_RESET_EVENT
  336. USB_Reset_Event();
  337. #endif
  338. ISTR = ~ISTR_RESET;
  339. }
  340. /* USB Suspend Request */
  341. if (istr & ISTR_SUSP) {
  342. USB_Suspend();
  343. #if USB_SUSPEND_EVENT
  344. USB_Suspend_Event();
  345. #endif
  346. ISTR = ~ISTR_SUSP;
  347. }
  348. /* USB Wakeup */
  349. if (istr & ISTR_WKUP) {
  350. USB_WakeUp();
  351. #if USB_WAKEUP_EVENT
  352. USB_WakeUp_Event();
  353. #endif
  354. ISTR = ~ISTR_WKUP;
  355. }
  356. /* Start of Frame */
  357. if (istr & ISTR_SOF) {
  358. #if USB_SOF_EVENT
  359. USB_SOF_Event();
  360. #endif
  361. ISTR = ~ISTR_SOF;
  362. }
  363. #if USB_ERROR_EVENT
  364. /* PMA Over/underrun */
  365. if (istr & ISTR_PMAOVR) {
  366. USB_Error_Event(1);
  367. ISTR = ~ISTR_PMAOVR;
  368. }
  369. /* Error: No Answer, CRC Error, Bit Stuff Error, Frame Format Error */
  370. if (istr & ISTR_ERR) {
  371. USB_Error_Event(0);
  372. ISTR = ~ISTR_ERR;
  373. }
  374. #endif
  375. /* Endpoint Interrupts */
  376. while ((istr = ISTR) & ISTR_CTR) {
  377. ISTR = ~ISTR_CTR;
  378. num = istr & ISTR_EP_ID;
  379. val = EPxREG(num);
  380. if (val & EP_CTR_RX) {
  381. EPxREG(num) = val & ~EP_CTR_RX & EP_MASK;
  382. if (USB_P_EP[num]) {
  383. if (val & EP_SETUP) {
  384. USB_P_EP[num](USB_EVT_SETUP);
  385. } else {
  386. USB_P_EP[num](USB_EVT_OUT);
  387. }
  388. }
  389. }
  390. if (val & EP_CTR_TX) {
  391. EPxREG(num) = val & ~EP_CTR_TX & EP_MASK;
  392. if (USB_P_EP[num]) {
  393. USB_P_EP[num](USB_EVT_IN);
  394. }
  395. }
  396. }
  397. }