PageRenderTime 28ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/Libmaple/libmaple/libmaple/usbF4/VCP/usbd_cdc_vcp.c

https://gitlab.com/edelmaks/AeroQuad
C | 422 lines | 249 code | 48 blank | 125 comment | 34 complexity | c2dbcaed272294f7866a2b0b1d2e9d14 MD5 | raw file
  1. /**
  2. ******************************************************************************
  3. * @file usbd_cdc_vcp.c
  4. * @author MCD Application Team
  5. * @version V1.0.0
  6. * @date 22-July-2011
  7. * @brief Generic media access Layer.
  8. ******************************************************************************
  9. * @attention
  10. *
  11. * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  12. * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  13. * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  14. * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  15. * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  16. * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  17. *
  18. * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
  19. ******************************************************************************
  20. */
  21. #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
  22. #pragma data_alignment = 4
  23. #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
  24. /* Includes ------------------------------------------------------------------*/
  25. #include "usbd_cdc_vcp.h"
  26. //#include "stm32f4_discovery.h"
  27. /* Private typedef -----------------------------------------------------------*/
  28. /* Private define ------------------------------------------------------------*/
  29. /* Private macro -------------------------------------------------------------*/
  30. /* Private variables ---------------------------------------------------------*/
  31. LINE_CODING linecoding =
  32. {
  33. 115200, /* baud rate*/
  34. 0x00, /* stop bits-1*/
  35. 0x00, /* parity - none*/
  36. 0x08 /* nb. of bits 8*/
  37. };
  38. //USART_InitTypeDef USART_InitStructure;
  39. /* These are external variables imported from CDC core to be used for IN
  40. transfer management. */
  41. extern uint8_t APP_Rx_Buffer []; /* Write CDC received data in this buffer.
  42. These data will be sent over USB IN endpoint
  43. in the CDC core functions. */
  44. extern volatile int APP_Rx_ptr_in; /* Increment this pointer or roll it back to
  45. start address when writing received data
  46. in the buffer APP_Rx_Buffer. */
  47. extern volatile int APP_Rx_ptr_out;
  48. #define UsbRecBufferSize 2048
  49. uint8_t UsbRecBuffer[UsbRecBufferSize];
  50. volatile int UsbRecRead = 0;
  51. volatile int UsbRecWrite = 0;
  52. volatile int VCP_DTRHIGH = 0;
  53. uint8_t UsbTXBlock = 0;
  54. uint32_t VCPBytesAvailable(void) {
  55. return (UsbRecWrite - UsbRecRead + UsbRecBufferSize) % UsbRecBufferSize;
  56. }
  57. uint8_t VCPGetByte(void) {
  58. if(UsbRecWrite == UsbRecRead) {
  59. return 0;
  60. } else {
  61. uint8_t c = UsbRecBuffer[UsbRecRead++];
  62. if(UsbRecRead == UsbRecBufferSize) {
  63. UsbRecRead = 0;
  64. }
  65. return c;
  66. }
  67. }
  68. /* Private function prototypes -----------------------------------------------*/
  69. static uint16_t VCP_Init (void);
  70. static uint16_t VCP_DeInit (void);
  71. static uint16_t VCP_Ctrl (uint32_t Cmd, uint8_t* Buf, uint32_t Len);
  72. uint16_t VCP_DataTx (uint8_t* Buf, uint32_t Len);
  73. static uint16_t VCP_DataRx (uint8_t* Buf, uint32_t Len);
  74. static uint16_t VCP_COMConfig(uint8_t Conf);
  75. CDC_IF_Prop_TypeDef VCP_fops =
  76. {
  77. VCP_Init,
  78. VCP_DeInit,
  79. VCP_Ctrl,
  80. VCP_DataTx,
  81. VCP_DataRx
  82. };
  83. /* Private functions ---------------------------------------------------------*/
  84. /**
  85. * @brief VCP_Init
  86. * Initializes the Media on the STM32
  87. * @param None
  88. * @retval Result of the opeartion (USBD_OK in all cases)
  89. */
  90. static uint16_t VCP_Init(void)
  91. {
  92. return USBD_OK;
  93. }
  94. /**
  95. * @brief VCP_DeInit
  96. * DeInitializes the Media on the STM32
  97. * @param None
  98. * @retval Result of the opeartion (USBD_OK in all cases)
  99. */
  100. static uint16_t VCP_DeInit(void)
  101. {
  102. return USBD_OK;
  103. }
  104. /**
  105. * @brief VCP_SetUSBTxBlocking
  106. * Set USB blocking mode for output buffer overrun
  107. * @param Mode: 0: non blocking, 1: blocking
  108. * @retval None
  109. */
  110. void VCP_SetUSBTxBlocking(uint8_t Mode)
  111. {
  112. UsbTXBlock = Mode;
  113. }
  114. /**
  115. * @brief VCP_Ctrl
  116. * Manage the CDC class requests
  117. * @param Cmd: Command code
  118. * @param Buf: Buffer containing command data (request parameters)
  119. * @param Len: Number of data to be sent (in bytes)
  120. * @retval Result of the opeartion (USBD_OK in all cases)
  121. */
  122. static uint16_t VCP_Ctrl (uint32_t Cmd, uint8_t* Buf, uint32_t Len)
  123. {
  124. switch (Cmd)
  125. {
  126. case SEND_ENCAPSULATED_COMMAND:
  127. /* Not needed for this driver */
  128. break;
  129. case GET_ENCAPSULATED_RESPONSE:
  130. /* Not needed for this driver */
  131. break;
  132. case SET_COMM_FEATURE:
  133. /* Not needed for this driver */
  134. break;
  135. case GET_COMM_FEATURE:
  136. /* Not needed for this driver */
  137. break;
  138. case CLEAR_COMM_FEATURE:
  139. /* Not needed for this driver */
  140. break;
  141. case SET_LINE_CODING:
  142. linecoding.bitrate = (uint32_t)(Buf[0] | (Buf[1] << 8) | (Buf[2] << 16) | (Buf[3] << 24));
  143. linecoding.format = Buf[4];
  144. linecoding.paritytype = Buf[5];
  145. linecoding.datatype = Buf[6];
  146. /* Set the new configuration */
  147. VCP_COMConfig(OTHER_CONFIG);
  148. break;
  149. case GET_LINE_CODING:
  150. Buf[0] = (uint8_t)(linecoding.bitrate);
  151. Buf[1] = (uint8_t)(linecoding.bitrate >> 8);
  152. Buf[2] = (uint8_t)(linecoding.bitrate >> 16);
  153. Buf[3] = (uint8_t)(linecoding.bitrate >> 24);
  154. Buf[4] = linecoding.format;
  155. Buf[5] = linecoding.paritytype;
  156. Buf[6] = linecoding.datatype;
  157. break;
  158. case SET_CONTROL_LINE_STATE:
  159. linecoding.bitrate = (uint32_t)(Buf[0] | (Buf[1] << 8));
  160. if(Buf[0] & 1) {
  161. VCP_DTRHIGH = 1;
  162. }
  163. /* Not needed for this driver */
  164. break;
  165. case SEND_BREAK:
  166. /* Not needed for this driver */
  167. break;
  168. default:
  169. break;
  170. }
  171. return USBD_OK;
  172. }
  173. /**
  174. * @brief VCP_DataTx
  175. * CDC received data to be send over USB IN endpoint are managed in
  176. * this function.
  177. * @param Buf: Buffer of data to be sent
  178. * @param Len: Number of data to be sent (in bytes)
  179. * @retval Result of the operation: USBD_OK if all operations are OK else VCP_FAIL
  180. */
  181. uint16_t VCP_DataTx (uint8_t* Buf, uint32_t Len)
  182. {
  183. while(Len-- > 0) {
  184. if(UsbTXBlock) {
  185. while ((APP_Rx_ptr_in - APP_Rx_ptr_out + APP_RX_DATA_SIZE) % APP_RX_DATA_SIZE + 1 >= APP_RX_DATA_SIZE)
  186. ;
  187. } else {
  188. if ((APP_Rx_ptr_in - APP_Rx_ptr_out + APP_RX_DATA_SIZE) % APP_RX_DATA_SIZE + 1 >= APP_RX_DATA_SIZE) {
  189. return USBD_BUSY;
  190. }
  191. }
  192. APP_Rx_Buffer[APP_Rx_ptr_in++] = *Buf++;
  193. /* To avoid buffer overflow */
  194. if(APP_Rx_ptr_in == APP_RX_DATA_SIZE)
  195. {
  196. APP_Rx_ptr_in = 0;
  197. }
  198. }
  199. return USBD_OK;
  200. }
  201. typedef volatile unsigned long vu32;
  202. typedef struct {
  203. vu32 CPUID;
  204. vu32 ICSR;
  205. vu32 VTOR;
  206. vu32 AIRCR;
  207. vu32 SCR;
  208. vu32 CCR;
  209. vu32 SHPR[3];
  210. vu32 SHCSR;
  211. vu32 CFSR;
  212. vu32 HFSR;
  213. vu32 DFSR;
  214. vu32 MMFAR;
  215. vu32 BFAR;
  216. vu32 AFSR;
  217. } SCB_TypeDef;
  218. #define AIRCR_RESET 0x05FA0000
  219. #define AIRCR_RESET_REQ (AIRCR_RESET | (u32)0x04);
  220. #define SCS_BASE ((u32)0xE000E000)
  221. #define SCB_BASE (SCS_BASE + 0x0D00)
  222. void systemHardReset(void) {
  223. SCB_TypeDef* rSCB = (SCB_TypeDef *) SCB_BASE;
  224. typedef void (*funcPtr)(void);
  225. /* Reset */
  226. rSCB->AIRCR = (u32)AIRCR_RESET_REQ;
  227. /* Should never get here */
  228. while (1) {
  229. asm volatile("nop");
  230. }
  231. }
  232. /**
  233. * @brief VCP_DataRx
  234. * Data received over USB OUT endpoint are sent over CDC interface
  235. * through this function.
  236. *
  237. * @note
  238. * This function will block any OUT packet reception on USB endpoint
  239. * until exiting this function. If you exit this function before transfer
  240. * is complete on CDC interface (ie. using DMA controller) it will result
  241. * in receiving more data while previous ones are still not sent.
  242. *
  243. * @param Buf: Buffer of data to be received
  244. * @param Len: Number of data received (in bytes)
  245. * @retval Result of the opeartion: USBD_OK if all operations are OK else VCP_FAIL
  246. */
  247. static uint16_t VCP_DataRx (uint8_t* Buf, uint32_t Len)
  248. {
  249. if(VCP_DTRHIGH) {
  250. if(Len >= 4) {
  251. if(Buf[0] == '1' && Buf[1] == 'E' && Buf[2] == 'A' && Buf[3] == 'F') {
  252. Len = 0;
  253. *(int*)0x20000BFC = 0x4AFC6BB2;
  254. systemHardReset();
  255. }
  256. }
  257. }
  258. VCP_DTRHIGH = 0;
  259. while(Len-- > 0) {
  260. UsbRecBuffer[UsbRecWrite] = *Buf++;
  261. if(UsbRecWrite == UsbRecBufferSize) {
  262. UsbRecWrite = 0;
  263. } else {
  264. UsbRecWrite ++;
  265. }
  266. }
  267. return USBD_OK;
  268. }
  269. /**
  270. * @brief VCP_COMConfig
  271. * Configure the COM Port with default values or values received from host.
  272. * @param Conf: can be DEFAULT_CONFIG to set the default configuration or OTHER_CONFIG
  273. * to set a configuration received from the host.
  274. * @retval None.
  275. */
  276. static uint16_t VCP_COMConfig(uint8_t Conf)
  277. {
  278. #if 0
  279. if (Conf == DEFAULT_CONFIG)
  280. {
  281. /* EVAL_COM1 default configuration */
  282. /* EVAL_COM1 configured as follow:
  283. - BaudRate = 115200 baud
  284. - Word Length = 8 Bits
  285. - One Stop Bit
  286. - Parity Odd
  287. - Hardware flow control disabled
  288. - Receive and transmit enabled
  289. */
  290. USART_InitStructure.USART_BaudRate = 115200;
  291. USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  292. USART_InitStructure.USART_StopBits = USART_StopBits_1;
  293. USART_InitStructure.USART_Parity = USART_Parity_Odd;
  294. USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  295. USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  296. /* Configure and enable the USART */
  297. STM_EVAL_COMInit(COM1, &USART_InitStructure);
  298. /* Enable the USART Receive interrupt */
  299. USART_ITConfig(EVAL_COM1, USART_IT_RXNE, ENABLE);
  300. }
  301. else
  302. {
  303. /* set the Stop bit*/
  304. switch (linecoding.format)
  305. {
  306. case 0:
  307. USART_InitStructure.USART_StopBits = USART_StopBits_1;
  308. break;
  309. case 1:
  310. USART_InitStructure.USART_StopBits = USART_StopBits_1_5;
  311. break;
  312. case 2:
  313. USART_InitStructure.USART_StopBits = USART_StopBits_2;
  314. break;
  315. default :
  316. VCP_COMConfig(DEFAULT_CONFIG);
  317. return (USBD_FAIL);
  318. }
  319. /* set the parity bit*/
  320. switch (linecoding.paritytype)
  321. {
  322. case 0:
  323. USART_InitStructure.USART_Parity = USART_Parity_No;
  324. break;
  325. case 1:
  326. USART_InitStructure.USART_Parity = USART_Parity_Even;
  327. break;
  328. case 2:
  329. USART_InitStructure.USART_Parity = USART_Parity_Odd;
  330. break;
  331. default :
  332. VCP_COMConfig(DEFAULT_CONFIG);
  333. return (USBD_FAIL);
  334. }
  335. /*set the data type : only 8bits and 9bits is supported */
  336. switch (linecoding.datatype)
  337. {
  338. case 0x07:
  339. /* With this configuration a parity (Even or Odd) should be set */
  340. USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  341. break;
  342. case 0x08:
  343. if (USART_InitStructure.USART_Parity == USART_Parity_No)
  344. {
  345. USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  346. }
  347. else
  348. {
  349. USART_InitStructure.USART_WordLength = USART_WordLength_9b;
  350. }
  351. break;
  352. default :
  353. VCP_COMConfig(DEFAULT_CONFIG);
  354. return (USBD_FAIL);
  355. }
  356. USART_InitStructure.USART_BaudRate = linecoding.bitrate;
  357. USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  358. USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  359. /* Configure and enable the USART */
  360. STM_EVAL_COMInit(COM1, &USART_InitStructure);
  361. }
  362. #endif
  363. return USBD_OK;
  364. }
  365. /**
  366. * @brief EVAL_COM_IRQHandler
  367. *
  368. * @param None.
  369. * @retval None.
  370. */
  371. void EVAL_COM_IRQHandler(void)
  372. {
  373. }
  374. /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/