From c1ebb093588bb1b9584873d9b59e693416a95528 Mon Sep 17 00:00:00 2001 From: TuxMonkey <8196772+tuxmonkey@user.noreply.gitee.com> Date: Tue, 25 Nov 2025 14:40:40 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E8=A7=84=E8=8C=83=20usbvpc?= =?UTF-8?q?=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- USB_DEVICE/App/usbd_cdc_if.c | 184 ++++++++++++++++++--------------- USB_DEVICE/App/usbd_cdc_if.h | 10 +- User_Code/bsp/usbvpc/bsp_vpc.c | 34 +++++- User_Code/bsp/usbvpc/bsp_vpc.h | 34 ++++-- 4 files changed, 165 insertions(+), 97 deletions(-) diff --git a/USB_DEVICE/App/usbd_cdc_if.c b/USB_DEVICE/App/usbd_cdc_if.c index 05d9f50..35a28ab 100644 --- a/USB_DEVICE/App/usbd_cdc_if.c +++ b/USB_DEVICE/App/usbd_cdc_if.c @@ -31,7 +31,8 @@ /* USER CODE BEGIN PV */ /* Private variables ---------------------------------------------------------*/ - +static USBCallback tx_cbk = NULL; +static USBCallback rx_cbk = NULL; /* USER CODE END PV */ /** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY @@ -123,9 +124,13 @@ extern USBD_HandleTypeDef hUsbDeviceHS; */ static int8_t CDC_Init_HS(void); + static int8_t CDC_DeInit_HS(void); -static int8_t CDC_Control_HS(uint8_t cmd, uint8_t* pbuf, uint16_t length); -static int8_t CDC_Receive_HS(uint8_t* pbuf, uint32_t *Len); + +static int8_t CDC_Control_HS(uint8_t cmd, uint8_t *pbuf, uint16_t length); + +static int8_t CDC_Receive_HS(uint8_t *pbuf, uint32_t *Len); + static int8_t CDC_TransmitCplt_HS(uint8_t *pbuf, uint32_t *Len, uint8_t epnum); /* USER CODE BEGIN PRIVATE_FUNCTIONS_DECLARATION */ @@ -138,11 +143,11 @@ static int8_t CDC_TransmitCplt_HS(uint8_t *pbuf, uint32_t *Len, uint8_t epnum); USBD_CDC_ItfTypeDef USBD_Interface_fops_HS = { - CDC_Init_HS, - CDC_DeInit_HS, - CDC_Control_HS, - CDC_Receive_HS, - CDC_TransmitCplt_HS + CDC_Init_HS, + CDC_DeInit_HS, + CDC_Control_HS, + CDC_Receive_HS, + CDC_TransmitCplt_HS }; /* Private functions ---------------------------------------------------------*/ @@ -153,12 +158,12 @@ USBD_CDC_ItfTypeDef USBD_Interface_fops_HS = */ static int8_t CDC_Init_HS(void) { - /* USER CODE BEGIN 8 */ - /* Set Application Buffers */ - USBD_CDC_SetTxBuffer(&hUsbDeviceHS, UserTxBufferHS, 0); - USBD_CDC_SetRxBuffer(&hUsbDeviceHS, UserRxBufferHS); - return (USBD_OK); - /* USER CODE END 8 */ + /* USER CODE BEGIN 8 */ + /* Set Application Buffers */ + USBD_CDC_SetTxBuffer(&hUsbDeviceHS, UserTxBufferHS, 0); + USBD_CDC_SetRxBuffer(&hUsbDeviceHS, UserRxBufferHS); + return (USBD_OK); + /* USER CODE END 8 */ } /** @@ -168,9 +173,9 @@ static int8_t CDC_Init_HS(void) */ static int8_t CDC_DeInit_HS(void) { - /* USER CODE BEGIN 9 */ - return (USBD_OK); - /* USER CODE END 9 */ + /* USER CODE BEGIN 9 */ + return (USBD_OK); + /* USER CODE END 9 */ } /** @@ -180,70 +185,70 @@ static int8_t CDC_DeInit_HS(void) * @param length: Number of data to be sent (in bytes) * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL */ -static int8_t CDC_Control_HS(uint8_t cmd, uint8_t* pbuf, uint16_t length) +static int8_t CDC_Control_HS(uint8_t cmd, uint8_t *pbuf, uint16_t length) { - /* USER CODE BEGIN 10 */ - switch(cmd) - { - case CDC_SEND_ENCAPSULATED_COMMAND: + /* USER CODE BEGIN 10 */ + switch (cmd) + { + case CDC_SEND_ENCAPSULATED_COMMAND: - break; + break; - case CDC_GET_ENCAPSULATED_RESPONSE: + case CDC_GET_ENCAPSULATED_RESPONSE: - break; + break; - case CDC_SET_COMM_FEATURE: + case CDC_SET_COMM_FEATURE: - break; + break; - case CDC_GET_COMM_FEATURE: + case CDC_GET_COMM_FEATURE: - break; + break; - case CDC_CLEAR_COMM_FEATURE: + case CDC_CLEAR_COMM_FEATURE: - break; + break; - /*******************************************************************************/ - /* Line Coding Structure */ - /*-----------------------------------------------------------------------------*/ - /* Offset | Field | Size | Value | Description */ - /* 0 | dwDTERate | 4 | Number |Data terminal rate, in bits per second*/ - /* 4 | bCharFormat | 1 | Number | Stop bits */ - /* 0 - 1 Stop bit */ - /* 1 - 1.5 Stop bits */ - /* 2 - 2 Stop bits */ - /* 5 | bParityType | 1 | Number | Parity */ - /* 0 - None */ - /* 1 - Odd */ - /* 2 - Even */ - /* 3 - Mark */ - /* 4 - Space */ - /* 6 | bDataBits | 1 | Number Data bits (5, 6, 7, 8 or 16). */ - /*******************************************************************************/ - case CDC_SET_LINE_CODING: + /*******************************************************************************/ + /* Line Coding Structure */ + /*-----------------------------------------------------------------------------*/ + /* Offset | Field | Size | Value | Description */ + /* 0 | dwDTERate | 4 | Number |Data terminal rate, in bits per second*/ + /* 4 | bCharFormat | 1 | Number | Stop bits */ + /* 0 - 1 Stop bit */ + /* 1 - 1.5 Stop bits */ + /* 2 - 2 Stop bits */ + /* 5 | bParityType | 1 | Number | Parity */ + /* 0 - None */ + /* 1 - Odd */ + /* 2 - Even */ + /* 3 - Mark */ + /* 4 - Space */ + /* 6 | bDataBits | 1 | Number Data bits (5, 6, 7, 8 or 16). */ + /*******************************************************************************/ + case CDC_SET_LINE_CODING: - break; + break; - case CDC_GET_LINE_CODING: + case CDC_GET_LINE_CODING: - break; + break; - case CDC_SET_CONTROL_LINE_STATE: + case CDC_SET_CONTROL_LINE_STATE: - break; + break; - case CDC_SEND_BREAK: + case CDC_SEND_BREAK: - break; + break; - default: - break; - } + default: + break; + } - return (USBD_OK); - /* USER CODE END 10 */ + return (USBD_OK); + /* USER CODE END 10 */ } /** @@ -261,13 +266,13 @@ static int8_t CDC_Control_HS(uint8_t cmd, uint8_t* pbuf, uint16_t length) * @param Len: Number of data received (in bytes) * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAILL */ -static int8_t CDC_Receive_HS(uint8_t* Buf, uint32_t *Len) +static int8_t CDC_Receive_HS(uint8_t *Buf, uint32_t *Len) { - /* USER CODE BEGIN 11 */ - USBD_CDC_SetRxBuffer(&hUsbDeviceHS, &Buf[0]); - USBD_CDC_ReceivePacket(&hUsbDeviceHS); - return (USBD_OK); - /* USER CODE END 11 */ + /* USER CODE BEGIN 11 */ + USBD_CDC_SetRxBuffer(&hUsbDeviceHS, &Buf[0]); + USBD_CDC_ReceivePacket(&hUsbDeviceHS); + return (USBD_OK); + /* USER CODE END 11 */ } /** @@ -277,18 +282,19 @@ static int8_t CDC_Receive_HS(uint8_t* Buf, uint32_t *Len) * @param Len: Number of data to be sent (in bytes) * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL or USBD_BUSY */ -uint8_t CDC_Transmit_HS(uint8_t* Buf, uint16_t Len) +uint8_t CDC_Transmit_HS(uint8_t *Buf, uint16_t Len) { - uint8_t result = USBD_OK; - /* USER CODE BEGIN 12 */ - USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceHS.pClassData; - if (hcdc->TxState != 0){ - return USBD_BUSY; - } - USBD_CDC_SetTxBuffer(&hUsbDeviceHS, Buf, Len); - result = USBD_CDC_TransmitPacket(&hUsbDeviceHS); - /* USER CODE END 12 */ - return result; + uint8_t result = USBD_OK; + /* USER CODE BEGIN 12 */ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *) hUsbDeviceHS.pClassData; + if (hcdc->TxState != 0) + { + return USBD_BUSY; + } + USBD_CDC_SetTxBuffer(&hUsbDeviceHS, Buf, Len); + result = USBD_CDC_TransmitPacket(&hUsbDeviceHS); + /* USER CODE END 12 */ + return result; } /** @@ -305,16 +311,24 @@ uint8_t CDC_Transmit_HS(uint8_t* Buf, uint16_t Len) */ static int8_t CDC_TransmitCplt_HS(uint8_t *Buf, uint32_t *Len, uint8_t epnum) { - uint8_t result = USBD_OK; - /* USER CODE BEGIN 14 */ - UNUSED(Buf); - UNUSED(Len); - UNUSED(epnum); - /* USER CODE END 14 */ - return result; + uint8_t result = USBD_OK; + /* USER CODE BEGIN 14 */ + UNUSED(Buf); + UNUSED(Len); + UNUSED(epnum); + if (tx_cbk) + tx_cbk(*Len); + /* USER CODE END 14 */ + return result; } /* USER CODE BEGIN PRIVATE_FUNCTIONS_IMPLEMENTATION */ +uint8_t *CDCInitRxbufferNcallback(USBCallback transmit_cbk, USBCallback recv_cbk) +{ + tx_cbk = transmit_cbk; + rx_cbk = recv_cbk; + return UserRxBufferHS; +} /* USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION */ diff --git a/USB_DEVICE/App/usbd_cdc_if.h b/USB_DEVICE/App/usbd_cdc_if.h index e643b34..9ca111f 100644 --- a/USB_DEVICE/App/usbd_cdc_if.h +++ b/USB_DEVICE/App/usbd_cdc_if.h @@ -24,7 +24,11 @@ #define __USBD_CDC_IF_H__ #ifdef __cplusplus - extern "C" { +extern "C" +{ + + + #endif /* Includes ------------------------------------------------------------------*/ @@ -65,6 +69,7 @@ */ /* USER CODE BEGIN EXPORTED_TYPES */ +typedef void (*USBCallback)(uint16_t); /* USER CODE END EXPORTED_TYPES */ @@ -106,9 +111,10 @@ extern USBD_CDC_ItfTypeDef USBD_Interface_fops_HS; * @{ */ -uint8_t CDC_Transmit_HS(uint8_t* Buf, uint16_t Len); +uint8_t CDC_Transmit_HS(uint8_t *Buf, uint16_t Len); /* USER CODE BEGIN EXPORTED_FUNCTIONS */ +uint8_t *CDCInitRxbufferNcallback(USBCallback transmit_cbk, USBCallback recv_cbk); /* USER CODE END EXPORTED_FUNCTIONS */ diff --git a/User_Code/bsp/usbvpc/bsp_vpc.c b/User_Code/bsp/usbvpc/bsp_vpc.c index e386376..a96b0dd 100644 --- a/User_Code/bsp/usbvpc/bsp_vpc.c +++ b/User_Code/bsp/usbvpc/bsp_vpc.c @@ -1,5 +1,31 @@ -// -// Created by tuxmonkey on 2025/10/28. -// +/** + * @file bsp_vpc.c + * @author your name (you@domain.com) + * @brief usb是单例bsp,因此不保存实例 + * @version 0.1 + * @date 2023-02-09 + * + * @copyright Copyright (c) 2023 + * + */ -#include "bsp_vpc.h" \ No newline at end of file +#include "bsp_vpc.h" +#include "bsp_log.h" +#include "bsp_dwt.h" + +static uint8_t *bsp_usb_rx_buffer; // 接收到的数据会被放在这里,buffer size为2048 +// 注意usb单个数据包(Full speed模式下)最大为64byte,超出可能会出现丢包情况 + +uint8_t *USBInit(USB_Init_Config_s usb_conf) +{ + // usb的软件复位(模拟拔插)在usbd_conf.c中的HAL_PCD_MspInit()中 + bsp_usb_rx_buffer = CDCInitRxbufferNcallback(usb_conf.tx_cbk, usb_conf.rx_cbk); // 获取接收数据指针 + // usb的接收回调函数会在这里被设置,并将数据保存在bsp_usb_rx_buffer中 + LOGINFO("USB init success"); + return bsp_usb_rx_buffer; +} + +void USBTransmit(uint8_t *buffer, uint16_t len) +{ + CDC_Transmit_HS(buffer, len); // 发送 +} diff --git a/User_Code/bsp/usbvpc/bsp_vpc.h b/User_Code/bsp/usbvpc/bsp_vpc.h index acfd097..5c42d93 100644 --- a/User_Code/bsp/usbvpc/bsp_vpc.h +++ b/User_Code/bsp/usbvpc/bsp_vpc.h @@ -1,8 +1,30 @@ -// -// Created by tuxmonkey on 2025/10/28. -// +/** +* @file bsp_vpc.h + * @author your name (you@domain.com) + * @brief 提供对usb vpc(virtal com port)的操作接口,hid和msf考虑后续添加 + * @attention 这一版usb修改了usbd_cdc_if.c中的CDC_Receive_FS函数,若使用cube生成后会被覆盖.后续需要由usbcdciftemplate创建一套自己的模板 + * @version 0.1 + * @date 2025-11-25 + * + * @copyright Copyright (c) 2025 + * + */ +#pragma once +#include "usb_device.h" +#include "usbd_cdc.h" +#include "usbd_conf.h" +#include "usbd_desc.h" +#include "usbd_cdc_if.h" -#ifndef TRONONEH7_SCAFFOLD_BSP_VPC_H -#define TRONONEH7_SCAFFOLD_BSP_VPC_H +typedef struct +{ + USBCallback tx_cbk; + USBCallback rx_cbk; +} USB_Init_Config_s; -#endif //TRONONEH7_SCAFFOLD_BSP_VPC_H \ No newline at end of file +/* @note 虚拟串口的波特率/校验位/数据位等动态可变,取决于上位机的设定 */ +/* 使用时不需要关心这些设置(作为从机) */ + +uint8_t *USBInit(USB_Init_Config_s usb_conf); // bsp初始化时调用会重新枚举设备 + +void USBTransmit(uint8_t *buffer, uint16_t len); // 通过usb发送数据