Merge pull request #10492 from iNavFlight/MrD_Update-OSD.md-for-8.0
[inav.git] / src / main / vcpf4 / usbd_cdc_vcp.c
blob15c1f7e39d9c44587674c68a3570fafe26db5875
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
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.
18 * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
19 ******************************************************************************
22 /* Includes ------------------------------------------------------------------*/
23 #include "usbd_cdc_vcp.h"
24 #include "stm32f4xx_conf.h"
25 #include <stdbool.h>
26 #include "drivers/time.h"
28 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
29 #pragma data_alignment = 4
30 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
32 __ALIGN_BEGIN USB_OTG_CORE_HANDLE USB_OTG_dev __ALIGN_END;
34 LINE_CODING g_lc;
36 extern __IO uint8_t USB_Tx_State;
37 __IO uint32_t bDeviceState = UNCONNECTED; /* USB device status */
39 /* These are external variables imported from CDC core to be used for IN transfer management. */
41 /* This is the buffer for data received from the MCU to APP (i.e. MCU TX, APP RX) */
42 extern uint8_t APP_Rx_Buffer[];
43 extern volatile uint32_t APP_Rx_ptr_out;
44 /* Increment this buffer position or roll it back to
45 start address when writing received data
46 in the buffer APP_Rx_Buffer. */
47 extern volatile uint32_t APP_Rx_ptr_in;
50 APP TX is the circular buffer for data that is transmitted from the APP (host)
51 to the USB device (flight controller).
53 static uint8_t APP_Tx_Buffer[APP_TX_DATA_SIZE];
54 static uint32_t APP_Tx_ptr_out = 0;
55 static uint32_t APP_Tx_ptr_in = 0;
57 /* Private function prototypes -----------------------------------------------*/
58 static uint16_t VCP_Init(void);
59 static uint16_t VCP_DeInit(void);
60 static uint16_t VCP_Ctrl(uint32_t Cmd, uint8_t* Buf, uint32_t Len);
61 static uint16_t VCP_DataTx(const uint8_t* Buf, uint32_t Len);
62 static uint16_t VCP_DataRx(uint8_t* Buf, uint32_t Len);
63 static void (*ctrlLineStateCb)(void* context, uint16_t ctrlLineState);
64 static void *ctrlLineStateCbContext;
65 static void (*baudRateCb)(void *context, uint32_t baud);
66 static void *baudRateCbContext;
69 CDC_IF_Prop_TypeDef VCP_fops = {VCP_Init, VCP_DeInit, VCP_Ctrl, VCP_DataTx, VCP_DataRx };
71 /* Private functions ---------------------------------------------------------*/
72 /**
73 * @brief VCP_Init
74 * Initializes the Media on the STM32
75 * @param None
76 * @retval Result of the opeartion (USBD_OK in all cases)
78 static uint16_t VCP_Init(void)
80 bDeviceState = CONFIGURED;
81 ctrlLineStateCb = NULL;
82 baudRateCb = NULL;
83 return USBD_OK;
86 /**
87 * @brief VCP_DeInit
88 * DeInitializes the Media on the STM32
89 * @param None
90 * @retval Result of the opeartion (USBD_OK in all cases)
92 static uint16_t VCP_DeInit(void)
94 bDeviceState = UNCONNECTED;
95 return USBD_OK;
98 void ust_cpy(LINE_CODING* plc2, const LINE_CODING* plc1)
100 plc2->bitrate = plc1->bitrate;
101 plc2->format = plc1->format;
102 plc2->paritytype = plc1->paritytype;
103 plc2->datatype = plc1->datatype;
107 * @brief VCP_Ctrl
108 * Manage the CDC class requests
109 * @param Cmd: Command code
110 * @param Buf: Buffer containing command data (request parameters)
111 * @param Len: Number of data to be sent (in bytes)
112 * @retval Result of the opeartion (USBD_OK in all cases)
114 static uint16_t VCP_Ctrl(uint32_t Cmd, uint8_t* Buf, uint32_t Len)
116 LINE_CODING* plc = (LINE_CODING*)Buf;
118 assert_param(Len>=sizeof(LINE_CODING));
120 switch (Cmd) {
121 /* Not needed for this driver, AT modem commands */
122 case SEND_ENCAPSULATED_COMMAND:
123 case GET_ENCAPSULATED_RESPONSE:
124 break;
126 // Not needed for this driver
127 case SET_COMM_FEATURE:
128 case GET_COMM_FEATURE:
129 case CLEAR_COMM_FEATURE:
130 break;
133 //Note - hw flow control on UART 1-3 and 6 only
134 case SET_LINE_CODING:
135 // If a callback is provided, tell the upper driver of changes in baud rate
136 if (plc && (Len == sizeof(*plc))) {
137 if (baudRateCb) {
138 baudRateCb(baudRateCbContext, plc->bitrate);
140 ust_cpy(&g_lc, plc); //Copy into structure to save for later
142 break;
145 case GET_LINE_CODING:
146 if (plc && (Len == sizeof(*plc))) {
147 ust_cpy(plc, &g_lc);
149 break;
152 case SET_CONTROL_LINE_STATE:
153 // If a callback is provided, tell the upper driver of changes in DTR/RTS state
154 if (plc && (Len == sizeof(uint16_t))) {
155 if (ctrlLineStateCb) {
156 ctrlLineStateCb(ctrlLineStateCbContext, *((uint16_t *)Buf));
159 break;
161 case SEND_BREAK:
162 /* Not needed for this driver */
163 break;
165 default:
166 break;
169 return USBD_OK;
172 /*******************************************************************************
173 * Function Name : Send DATA .
174 * Description : send the data received from the STM32 to the PC through USB
175 * Input : buffer to send, and the length of the buffer.
176 * Output : None.
177 * Return : None.
178 *******************************************************************************/
179 uint32_t CDC_Send_DATA(const uint8_t *ptrBuffer, uint32_t sendLength)
181 VCP_DataTx(ptrBuffer, sendLength);
182 return sendLength;
185 uint32_t CDC_Send_FreeBytes(void)
187 return APP_RX_DATA_SIZE - CDC_Receive_BytesAvailable();
191 * @brief VCP_DataTx
192 * CDC data to be sent to the Host (app) over USB
193 * @param Buf: Buffer of data to be sent
194 * @param Len: Number of data to be sent (in bytes)
195 * @retval Result of the operation: USBD_OK if all operations are OK else VCP_FAIL
197 static uint16_t VCP_DataTx(const uint8_t* Buf, uint32_t Len)
200 make sure that any paragraph end frame is not in play
201 could just check for: USB_CDC_ZLP, but better to be safe
202 and wait for any existing transmission to complete.
204 while (USB_Tx_State != 0);
206 for (uint32_t i = 0; i < Len; i++) {
207 // Stall if the ring buffer is full
208 while (((APP_Rx_ptr_in + 1) % APP_RX_DATA_SIZE) == APP_Rx_ptr_out) {
209 delay(1);
212 APP_Rx_Buffer[APP_Rx_ptr_in] = Buf[i];
213 APP_Rx_ptr_in = (APP_Rx_ptr_in + 1) % APP_RX_DATA_SIZE;
216 return USBD_OK;
219 /*******************************************************************************
220 * Function Name : Receive DATA .
221 * Description : receive the data from the PC to STM32 and send it through USB
222 * Input : None.
223 * Output : None.
224 * Return : None.
225 *******************************************************************************/
226 uint32_t CDC_Receive_DATA(uint8_t* recvBuf, uint32_t len)
228 uint32_t count = 0;
230 while (APP_Tx_ptr_out != APP_Tx_ptr_in && (count < len)) {
231 recvBuf[count] = APP_Tx_Buffer[APP_Tx_ptr_out];
232 APP_Tx_ptr_out = (APP_Tx_ptr_out + 1) % APP_TX_DATA_SIZE;
233 count++;
235 return count;
238 uint32_t CDC_Receive_BytesAvailable(void)
240 /* return the bytes available in the receive circular buffer */
241 return (APP_Tx_ptr_in + APP_TX_DATA_SIZE - APP_Tx_ptr_out) % APP_TX_DATA_SIZE;
245 * @brief VCP_DataRx
246 * Data received over USB OUT endpoint are sent over CDC interface
247 * through this function.
249 * @note
250 * This function will block any OUT packet reception on USB endpoint
251 * until exiting this function. If you exit this function before transfer
252 * is complete on CDC interface (ie. using DMA controller) it will result
253 * in receiving more data while previous ones are still not sent.
255 * @param Buf: Buffer of data to be received
256 * @param Len: Number of data received (in bytes)
257 * @retval Result of the opeartion: USBD_OK if all operations are OK else VCP_FAIL
259 static uint16_t VCP_DataRx(uint8_t* Buf, uint32_t Len)
261 if (CDC_Receive_BytesAvailable() + Len > APP_TX_DATA_SIZE) {
262 return USBD_FAIL;
265 for (uint32_t i = 0; i < Len; i++) {
266 APP_Tx_Buffer[APP_Tx_ptr_in] = Buf[i];
267 APP_Tx_ptr_in = (APP_Tx_ptr_in + 1) % APP_TX_DATA_SIZE;
270 return USBD_OK;
273 /*******************************************************************************
274 * Function Name : usbIsConfigured.
275 * Description : Determines if USB VCP is configured or not
276 * Input : None.
277 * Output : None.
278 * Return : True if configured.
279 *******************************************************************************/
280 uint8_t usbIsConfigured(void)
282 return (bDeviceState == CONFIGURED);
285 /*******************************************************************************
286 * Function Name : usbIsConnected.
287 * Description : Determines if USB VCP is connected ot not
288 * Input : None.
289 * Output : None.
290 * Return : True if connected.
291 *******************************************************************************/
292 uint8_t usbIsConnected(void)
294 return (bDeviceState != UNCONNECTED);
297 /*******************************************************************************
298 * Function Name : CDC_BaudRate.
299 * Description : Get the current baud rate
300 * Input : None.
301 * Output : None.
302 * Return : Baud rate in bps
303 *******************************************************************************/
304 uint32_t CDC_BaudRate(void)
306 return g_lc.bitrate;
309 /*******************************************************************************
310 * Function Name : CDC_SetBaudRateCb
311 * Description : Set a callback to call when baud rate changes
312 * Input : callback function and context.
313 * Output : None.
314 * Return : None.
315 *******************************************************************************/
316 void CDC_SetBaudRateCb(void (*cb)(void *context, uint32_t baud), void *context)
318 baudRateCbContext = context;
319 baudRateCb = cb;
322 /*******************************************************************************
323 * Function Name : CDC_SetCtrlLineStateCb
324 * Description : Set a callback to call when control line state changes
325 * Input : callback function and context.
326 * Output : None.
327 * Return : None.
328 *******************************************************************************/
329 void CDC_SetCtrlLineStateCb(void (*cb)(void *context, uint16_t ctrlLineState), void *context)
331 ctrlLineStateCbContext = context;
332 ctrlLineStateCb = cb;
335 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/