Files
player/Project/Src/USB/USB_APP/usbd_cdc_vcp.c

227 lines
5.3 KiB
C
Raw Normal View History

2025-06-27 00:32:57 +08:00
#include "usbd_cdc_vcp.h"
#include "string.h"
#include "stdarg.h"
#include "stdio.h"
#include "mymem.h"
//////////////////////////////////////////////////////////////////////////////////
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK STM32开发板
//usb vcp驱动代码
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//创建日期:2016/2/24
//版本V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2009-2019
//All rights reserved
//////////////////////////////////////////////////////////////////////////////////
//USB虚拟串口相关配置参数
LINE_CODING linecoding =
{
115200, //波特率
0x00, //停止位,默认1位
0x00, //校验位,默认无
0x08 //数据位,默认8位
};
u8 USART_PRINTF_Buffer[USB_USART_REC_LEN]; //usb_printf发送缓冲区
/* 传送数据时的格式 0xff,0xff开头,len_h,len_l长度,*/
static u8 USB_USART_RX_BUF[USB_USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.
static int USB_USART_RX_LEN =0;
static int USB_USART_RX_DONE=0;
extern uint8_t APP_Rx_Buffer []; //虚拟串口发送缓冲区(发给电脑)
extern uint32_t APP_Rx_ptr_in; //虚拟串口接收缓冲区(接收来自电脑的数据)
//虚拟串口配置函数(供USB内核调用)
CDC_IF_Prop_TypeDef VCP_fops =
{
VCP_Init,
VCP_DeInit,
VCP_Ctrl,
VCP_DataTx,
VCP_DataRx
};
//初始化VCP
//返回值:USBD_OK
uint16_t VCP_Init(void)
{
return USBD_OK;
}
//复位VCP
//返回值:USBD_OK
uint16_t VCP_DeInit(void)
{
return USBD_OK;
}
//控制VCP的设置
//buf:命令数据缓冲区/参数保存缓冲区
//len:数据长度
//返回值:USBD_OK
uint16_t VCP_Ctrl (uint32_t Cmd, uint8_t* Buf, uint32_t Len)
{
switch (Cmd)
{
case SEND_ENCAPSULATED_COMMAND:
break;
case GET_ENCAPSULATED_RESPONSE:
break;
case SET_COMM_FEATURE:
break;
case GET_COMM_FEATURE:
break;
case CLEAR_COMM_FEATURE:
break;
case SET_LINE_CODING:
linecoding.bitrate = (uint32_t)(Buf[0] | (Buf[1] << 8) | (Buf[2] << 16) | (Buf[3] << 24));
linecoding.format = Buf[4];
linecoding.paritytype = Buf[5];
linecoding.datatype = Buf[6];
//打印配置参数
// printf("linecoding.format:%d\r\n",linecoding.format);
// printf("linecoding.paritytype:%d\r\n",linecoding.paritytype);
// printf("linecoding.datatype:%d\r\n",linecoding.datatype);
// printf("linecoding.bitrate:%d\r\n",linecoding.bitrate);
break;
case GET_LINE_CODING:
Buf[0] = (uint8_t)(linecoding.bitrate);
Buf[1] = (uint8_t)(linecoding.bitrate >> 8);
Buf[2] = (uint8_t)(linecoding.bitrate >> 16);
Buf[3] = (uint8_t)(linecoding.bitrate >> 24);
Buf[4] = linecoding.format;
Buf[5] = linecoding.paritytype;
Buf[6] = linecoding.datatype;
break;
case SET_CONTROL_LINE_STATE:
break;
case SEND_BREAK:
break;
default:
break;
}
return USBD_OK;
}
//发送一个字节给虚拟串口(发给电脑)
//data:要发送的数据
//返回值:USBD_OK
uint16_t VCP_DataTx (uint8_t data)
{
APP_Rx_Buffer[APP_Rx_ptr_in]=data; //写入发送buf
APP_Rx_ptr_in++; //写位置加1
if(APP_Rx_ptr_in==APP_RX_DATA_SIZE) //超过buf大小了,归零.
{
APP_Rx_ptr_in = 0;
}
return USBD_OK;
}
//处理从USB虚拟串口接收到的数据
//databuffer:数据缓存区
//Nb_bytes:接收到的字节数.
//返回值:USBD_OK
uint16_t VCP_DataRx (uint8_t* Buf, uint32_t Len)
{
int i;
u8 res;
// for(i=0;i<Len;i++)
// {
// res=Buf[i];
// if ((res==0xff)&&(USB_USART_RX_LEN==0))
// {USB_USART_RX_BUF[USB_USART_RX_LEN]=res;USB_USART_RX_LEN++;}
// else if ((res==0xff)&&(USB_USART_RX_LEN==1))
// {USB_USART_RX_BUF[USB_USART_RX_LEN]=res;USB_USART_RX_LEN++;}
// else if ((USB_USART_RX_LEN<USB_USART_REC_LEN)&&(USB_USART_RX_LEN>1))
// { if (USB_USART_RX_DONE==0) {USB_USART_RX_BUF[USB_USART_RX_LEN]=res; USB_USART_RX_LEN++; }}
// if (USB_USART_RX_LEN==USB_USART_REC_LEN)
// { USB_USART_RX_DONE=1; }
// if ((((USB_USART_RX_BUF[2]<<8)|(USB_USART_RX_BUF[3]))==(USB_USART_RX_LEN-2))&&(USB_USART_RX_LEN>2))
// { USB_USART_RX_DONE=1; }
// USB_USART_RX_BUF[i]=Buf[i];
// Buf[i]=0;
// }
//把半个字节的数据整理成一个字节
Len/=2;
for (int i=0;i<Len;i++)
{
Buf[i]=(Buf[i*2]<<4)|(Buf[i*2+1]&0x0f);
}
extern void SysFile_UpdataByIrq (u8 *data,int len);
SysFile_UpdataByIrq (Buf,Len);
return USBD_OK;
}
//取得usb接收到的数据
int usb_getRecvData (u8 *buff,int buffLen)
{
int ret=0;
if (USB_USART_RX_DONE)
{
ret=buffLen;if (ret>USB_USART_RX_LEN) ret=USB_USART_RX_LEN;
mymemcpy (buff,USB_USART_RX_BUF,ret);
mymemset (USB_USART_RX_BUF,0,USB_USART_REC_LEN);
USB_USART_RX_DONE=0;
USB_USART_RX_LEN=0;
}
return ret;
}
//通过usb发送数据
int usb_sendData (u8 *buff,int buffLen)
{
int ret=0;
ret=buffLen;if (ret>USB_USART_REC_LEN) ret=USB_USART_REC_LEN;
for (int i=0;i<ret;i++) VCP_DataTx (buff[i]);
return ret;
}
//usb虚拟串口,printf 函数
//确保一次发送数据不超USB_USART_REC_LEN字节
void usb_printf(char* fmt,...)
{
u16 i,j;
va_list ap;
va_start(ap,fmt);
vsprintf((char*)USART_PRINTF_Buffer,fmt,ap);
va_end(ap);
i=strlen((const char*)USART_PRINTF_Buffer);//此次发送数据的长度
for(j=0;j<i;j++)//循环发送数据
{
VCP_DataTx(USART_PRINTF_Buffer[j]);
}
}