1 /**
2   ******************************************************************************
3   * @file           : usbd_cdc_if.c
4   * @version        : v2.0_Cube
5   * @brief          : Usb device for Virtual Com Port.
6   ******************************************************************************
7   * This notice applies to any and all portions of this file
8   * that are not between comment pairs USER CODE BEGIN and
9   * USER CODE END. Other portions of this file, whether
10   * inserted by the user or by software development tools
11   * are owned by their respective copyright owners.
12   *
13   * Copyright (c) 2018 STMicroelectronics International N.V.
14   * All rights reserved.
15   *
16   * Redistribution and use in source and binary forms, with or without
17   * modification, are permitted, provided that the following conditions are met:
18   *
19   * 1. Redistribution of source code must retain the above copyright notice,
20   *    this list of conditions and the following disclaimer.
21   * 2. Redistributions in binary form must reproduce the above copyright notice,
22   *    this list of conditions and the following disclaimer in the documentation
23   *    and/or other materials provided with the distribution.
24   * 3. Neither the name of STMicroelectronics nor the names of other
25   *    contributors to this software may be used to endorse or promote products
26   *    derived from this software without specific written permission.
27   * 4. This software, including modifications and/or derivative works of this
28   *    software, must execute solely and exclusively on microcontroller or
29   *    microprocessor devices manufactured by or for STMicroelectronics.
30   * 5. Redistribution and use of this software other than as permitted under
31   *    this license is void and will automatically terminate your rights under
32   *    this license.
33   *
34   * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
35   * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
36   * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
37   * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY
38   * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
39   * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
40   * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
42   * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
43   * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
44   * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
45   * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46   *
47   ******************************************************************************
48   */
49 
50 /* Includes ------------------------------------------------------------------*/
51 #include "usbd_cdc_if.h"
52 
53 /* USER CODE BEGIN INCLUDE */
54 #include <stdint.h>
55 #include <time.h>
56 #include "StmUtil.h"
57 #include "stm32l4xx_hal.h"
58 
59 /* USER CODE END INCLUDE */
60 
61 /* Private typedef -----------------------------------------------------------*/
62 /* Private define ------------------------------------------------------------*/
63 /* Private macro -------------------------------------------------------------*/
64 
65 /* USER CODE BEGIN PV */
66 /* Private variables ---------------------------------------------------------*/
67 
68 /* USER CODE END PV */
69 
70 /** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
71   * @brief Usb device library.
72   * @{
73   */
74 
75 /** @addtogroup USBD_CDC_IF
76   * @{
77   */
78 
79 /** @defgroup USBD_CDC_IF_Private_TypesDefinitions USBD_CDC_IF_Private_TypesDefinitions
80   * @brief Private types.
81   * @{
82   */
83 
84 /* USER CODE BEGIN PRIVATE_TYPES */
85 #define CDC_RTS_MASK   0x0002
86 #define CDC_DTR_MASK   0x0001
87 void TpmConnectionReset(void);
88 int TpmSignalEvent(uint8_t* Buf, uint32_t *Len);
89 
90 /* USER CODE END PRIVATE_TYPES */
91 
92 /**
93   * @}
94   */
95 
96 /** @defgroup USBD_CDC_IF_Private_Defines USBD_CDC_IF_Private_Defines
97   * @brief Private defines.
98   * @{
99   */
100 
101 /* USER CODE BEGIN PRIVATE_DEFINES */
102 /* Define size for the receive and transmit buffer over CDC */
103 /* It's up to user to redefine and/or remove those define */
104 #define APP_RX_DATA_SIZE  2048
105 #define APP_TX_DATA_SIZE  2048
106 typedef struct
107 {
108     uint8_t bReqType;
109     uint8_t bRequest;
110     uint16_t wVal;
111     uint16_t wIndex;
112     uint16_t wLength;
113 } USBD_SETUP_PKT, *PUSBD_SETUP_PKT;
114 extern RTC_HandleTypeDef hrtc;
115 /* USER CODE END PRIVATE_DEFINES */
116 
117 /**
118   * @}
119   */
120 
121 /** @defgroup USBD_CDC_IF_Private_Macros USBD_CDC_IF_Private_Macros
122   * @brief Private macros.
123   * @{
124   */
125 
126 /* USER CODE BEGIN PRIVATE_MACRO */
127 
128 /* USER CODE END PRIVATE_MACRO */
129 
130 /**
131   * @}
132   */
133 
134 /** @defgroup USBD_CDC_IF_Private_Variables USBD_CDC_IF_Private_Variables
135   * @brief Private variables.
136   * @{
137   */
138 /* Create buffer for reception and transmission           */
139 /* It's up to user to redefine and/or remove those define */
140 /** Received data over USB are stored in this buffer      */
141 uint8_t UserRxBufferFS[APP_RX_DATA_SIZE];
142 
143 /** Data to send over USB CDC are stored in this buffer   */
144 uint8_t UserTxBufferFS[APP_TX_DATA_SIZE];
145 
146 /* USER CODE BEGIN PRIVATE_VARIABLES */
147 
148 /* USER CODE END PRIVATE_VARIABLES */
149 
150 /**
151   * @}
152   */
153 
154 /** @defgroup USBD_CDC_IF_Exported_Variables USBD_CDC_IF_Exported_Variables
155   * @brief Public variables.
156   * @{
157   */
158 
159 extern USBD_HandleTypeDef hUsbDeviceFS;
160 
161 /* USER CODE BEGIN EXPORTED_VARIABLES */
162 USBD_CDC_LineCodingTypeDef LineCoding =
163 {
164     115200, /* baud rate*/
165     0x00,   /* stop bits-1*/
166     0x00,   /* parity - none*/
167     0x08    /* nb. of bits 8*/
168 };
169 volatile uint8_t CDC_RTS = 0;  // RequestToSend
170 volatile uint8_t CDC_DTR = 0;  // DataTerminalReady
171 
172 /* USER CODE END EXPORTED_VARIABLES */
173 
174 /**
175   * @}
176   */
177 
178 /** @defgroup USBD_CDC_IF_Private_FunctionPrototypes USBD_CDC_IF_Private_FunctionPrototypes
179   * @brief Private functions declaration.
180   * @{
181   */
182 
183 static int8_t CDC_Init_FS(void);
184 static int8_t CDC_DeInit_FS(void);
185 static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length);
186 static int8_t CDC_Receive_FS(uint8_t* pbuf, uint32_t *Len);
187 
188 /* USER CODE BEGIN PRIVATE_FUNCTIONS_DECLARATION */
189 
190 /* USER CODE END PRIVATE_FUNCTIONS_DECLARATION */
191 
192 /**
193   * @}
194   */
195 
196 USBD_CDC_ItfTypeDef USBD_Interface_fops_FS =
197 {
198   CDC_Init_FS,
199   CDC_DeInit_FS,
200   CDC_Control_FS,
201   CDC_Receive_FS
202 };
203 
204 /* Private functions ---------------------------------------------------------*/
205 /**
206   * @brief  Initializes the CDC media low layer over the FS USB IP
207   * @retval USBD_OK if all operations are OK else USBD_FAIL
208   */
CDC_Init_FS(void)209 static int8_t CDC_Init_FS(void)
210 {
211   /* USER CODE BEGIN 3 */
212   /* Set Application Buffers */
213   USBD_CDC_SetTxBuffer(&hUsbDeviceFS, UserTxBufferFS, 0);
214   USBD_CDC_SetRxBuffer(&hUsbDeviceFS, UserRxBufferFS);
215   return (USBD_OK);
216   /* USER CODE END 3 */
217 }
218 
219 /**
220   * @brief  DeInitializes the CDC media low layer
221   * @retval USBD_OK if all operations are OK else USBD_FAIL
222   */
CDC_DeInit_FS(void)223 static int8_t CDC_DeInit_FS(void)
224 {
225   /* USER CODE BEGIN 4 */
226   return (USBD_OK);
227   /* USER CODE END 4 */
228 }
229 
230 /**
231   * @brief  Manage the CDC class requests
232   * @param  cmd: Command code
233   * @param  pbuf: Buffer containing command data (request parameters)
234   * @param  length: Number of data to be sent (in bytes)
235   * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
236   */
CDC_Control_FS(uint8_t cmd,uint8_t * pbuf,uint16_t length)237 static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length)
238 {
239   /* USER CODE BEGIN 5 */
240     char parity[] = {'N', 'O', 'E', 'M', 'S'};
241     uint8_t stop[] = {1, 15, 2};
242     switch (cmd)
243     {
244     case CDC_SEND_ENCAPSULATED_COMMAND:
245 
246       break;
247 
248     case CDC_GET_ENCAPSULATED_RESPONSE:
249 
250       break;
251 
252     case CDC_SET_COMM_FEATURE:
253 
254       break;
255 
256     case CDC_GET_COMM_FEATURE:
257 
258       break;
259 
260     case CDC_CLEAR_COMM_FEATURE:
261 
262       break;
263 
264     /*******************************************************************************/
265     /* Line Coding Structure                                                       */
266     /*-----------------------------------------------------------------------------*/
267     /* Offset | Field       | Size | Value  | Description                          */
268     /* 0      | dwDTERate   |   4  | Number |Data terminal rate, in bits per second*/
269     /* 4      | bCharFormat |   1  | Number | Stop bits                            */
270     /*                                        0 - 1 Stop bit                       */
271     /*                                        1 - 1.5 Stop bits                    */
272     /*                                        2 - 2 Stop bits                      */
273     /* 5      | bParityType |  1   | Number | Parity                               */
274     /*                                        0 - None                             */
275     /*                                        1 - Odd                              */
276     /*                                        2 - Even                             */
277     /*                                        3 - Mark                             */
278     /*                                        4 - Space                            */
279     /* 6      | bDataBits  |   1   | Number Data bits (5, 6, 7, 8 or 16).          */
280     /*******************************************************************************/
281     case CDC_SET_LINE_CODING:
282     {
283         LineCoding.bitrate = pbuf[0] | (pbuf[1] << 8) | (pbuf[2] << 16) | (pbuf[3] << 24);
284         LineCoding.format = pbuf[4];
285         LineCoding.paritytype = pbuf[5];
286         LineCoding.datatype = pbuf[6];
287         dbgPrint("CDC_SET_LINE_CODING: %lu-%d%c%d\r\n", LineCoding.bitrate, LineCoding.datatype, parity[LineCoding.paritytype], stop[LineCoding.format]);
288         break;
289     }
290 
291     case CDC_GET_LINE_CODING:
292     {
293         pbuf[0] = (uint8_t)(LineCoding.bitrate);
294         pbuf[1] = (uint8_t)(LineCoding.bitrate >> 8);
295         pbuf[2] = (uint8_t)(LineCoding.bitrate >> 16);
296         pbuf[3] = (uint8_t)(LineCoding.bitrate >> 24);
297         pbuf[4] = LineCoding.format;
298         pbuf[5] = LineCoding.paritytype;
299         pbuf[6] = LineCoding.datatype;
300         dbgPrint("CDC_GET_LINE_CODING: %lu-%d%c%d\r\n", LineCoding.bitrate, LineCoding.datatype, parity[LineCoding.paritytype], stop[LineCoding.format]);
301         break;
302     }
303 
304     case CDC_SET_CONTROL_LINE_STATE:
305     {
306         PUSBD_SETUP_PKT setupPkt = (PUSBD_SETUP_PKT)pbuf;
307         CDC_RTS = ((setupPkt->wVal & CDC_RTS_MASK) != 0);
308         CDC_DTR = ((setupPkt->wVal & CDC_DTR_MASK) != 0);
309         dbgPrint("CDC_SET_CONTROL_LINE_STATE: RTS=%d, DTR=%d\r\n", CDC_RTS, CDC_DTR);
310         // Reset any ongoing cmd transfers
311         TpmConnectionReset();
312         break;
313     }
314 
315     case CDC_SEND_BREAK:
316 
317       break;
318 
319     default:
320       break;
321     }
322 
323     return (USBD_OK);
324   /* USER CODE END 5 */
325 }
326 
327 /**
328   * @brief  Data received over USB OUT endpoint are sent over CDC interface
329   *         through this function.
330   *
331   *         @note
332   *         This function will block any OUT packet reception on USB endpoint
333   *         untill exiting this function. If you exit this function before transfer
334   *         is complete on CDC interface (ie. using DMA controller) it will result
335   *         in receiving more data while previous ones are still not sent.
336   *
337   * @param  Buf: Buffer of data to be received
338   * @param  Len: Number of data received (in bytes)
339   * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
340   */
CDC_Receive_FS(uint8_t * Buf,uint32_t * Len)341 static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
342 {
343   /* USER CODE BEGIN 6 */
344     if(!TpmSignalEvent(Buf, Len))
345     {
346         return(USBD_FAIL);
347     }
348 
349   USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
350   USBD_CDC_ReceivePacket(&hUsbDeviceFS);
351   return (USBD_OK);
352   /* USER CODE END 6 */
353 }
354 
355 /**
356   * @brief  CDC_Transmit_FS
357   *         Data to send over USB IN endpoint are sent over CDC interface
358   *         through this function.
359   *         @note
360   *
361   *
362   * @param  Buf: Buffer of data to be sent
363   * @param  Len: Number of data to be sent (in bytes)
364   * @retval USBD_OK if all operations are OK else USBD_FAIL or USBD_BUSY
365   */
CDC_Transmit_FS(uint8_t * Buf,uint16_t Len)366 uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)
367 {
368   uint8_t result = USBD_OK;
369   /* USER CODE BEGIN 7 */
370   USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData;
371   if (hcdc->TxState != 0){
372     return USBD_BUSY;
373   }
374   USBD_CDC_SetTxBuffer(&hUsbDeviceFS, Buf, Len);
375   result = USBD_CDC_TransmitPacket(&hUsbDeviceFS);
376   /* USER CODE END 7 */
377   return result;
378 }
379 
380 /* USER CODE BEGIN PRIVATE_FUNCTIONS_IMPLEMENTATION */
381 
382 /* USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION */
383 
384 /**
385   * @}
386   */
387 
388 /**
389   * @}
390   */
391 
392 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
393