接着上一篇上传,这个是STM32配置CH375B时用到的接口函数

头文件:

#ifndef __BSP_CH375_H__
#define __BSP_CH375_H__#include "stm32f0xx_hal.h"
#include "config.h"#define CH375_EndPointNum    0
#define USBD_VID             1155
#define USBD_PID_FS          22352#define   UNKNOWN_USB_DEVICE  0xF1
#define UNKNOWN_USB_HID     0xF2#define CH375_DATA_PORT      GPIOA
#define CH375_DATA_OUTPUT()  CH375_DATA_PORT->MODER |= 0x5555
#define CH375_DATA_INPUT()   CH375_DATA_PORT->MODER &= 0xFFFF0000
#define CH375_DATA(x)        {CH375_DATA_PORT->ODR &= 0xFF00;CH375_DATA_PORT->ODR |= x&0xFF;}#define CH375_CS_1           CH375_CS_GPIO_Port->ODR |=  CH375_CS_Pin
#define CH375_CS_0           CH375_CS_GPIO_Port->ODR &= ~CH375_CS_Pin#define CH375_A0_1           CH375_A0_GPIO_Port->ODR |=  CH375_A0_Pin
#define CH375_A0_0           CH375_A0_GPIO_Port->ODR &= ~CH375_A0_Pin#define CH375_RD_1           CH375_RD_GPIO_Port->ODR |=  CH375_RD_Pin
#define CH375_RD_0           CH375_RD_GPIO_Port->ODR &= ~CH375_RD_Pin#define CH375_WR_1           CH375_WR_GPIO_Port->ODR |=  CH375_WR_Pin
#define CH375_WR_0           CH375_WR_GPIO_Port->ODR &= ~CH375_WR_Pin/* ********************************************************************************************************************* */
/* 硬件特性 */#define   CH375_MAX_DATA_LEN  0x40            /* 最大数据包的长度, 缓冲区的长度 *//* ********************************************************************************************************************* */
/* 命令代码 */#define   CMD_GET_IC_VER      0x01            /* 获取芯片及固件版本 */
/* 输出: 版本号( 位7为1, 位6为0, 位5~位0为版本号 ) */
/*           CH375B返回版本号的值为0B7H即版本号为37H */#define   CMD_ENTER_SLEEP     0x03            /* 进入睡眠状态 */#define CMD_SET_USB_SPEED   0x04            /* 设置USB总线速度, 在每次CMD_SET_USB_MODE设置USB工作模式时会自动恢复到12Mbps全速 */
/* 输入: 总线速度代码 */
/*           00H=12Mbps全速FullSpeed(默认值), 01H=1.5Mbps(仅修改频率), 02H=1.5Mbps低速LowSpeed */
#define CMD_SET_SYS_FREQ    CMD_SET_USB_SPEED#define    CMD_RESET_ALL         0x05          /* 执行硬件复位 */#define CMD_CHECK_EXIST     0x06            /* 测试工作状态 */
/* 输入: 任意数据 */
/* 输出: 输入数据的按位取反 */#define  CMD_GET_TOGGLE      0x0A            /* 获取OUT事务的同步状态 */
/* 输入: 数据1AH */
/* 输出: 同步状态 */
/*           位4为1则OUT事务同步, 否则OUT事务不同步 */#define CMD_CHK_SUSPEND     0x0B            /* 设备方式: 设置检查USB总线挂起状态的方式 */
/* 输入: 数据10H, 检查方式 */
/*                    00H=不检查USB挂起, 04H=以50mS为间隔检查USB挂起, 05H=以10mS为间隔检查USB挂起 */#define   CMD_DELAY_100US     0x0F            /* 并口方式: 延时100uS */
/* 输出: 延时期间输出0, 延时结束输出非0 */#define  CMD_SET_USB_ID      0x12            /* 设备方式: 设置USB厂商VID和产品PID */
/* 输入: 厂商ID低字节, 厂商ID高字节, 产品ID低字节, 产品ID高字节 */#define CMD_SET_USB_ADDR    0x13            /* 设置USB地址 */
/* 输入: 地址值 */#define    CMD_SET_USB_MODE    0x15            /* 设置USB工作模式 */
/* 输入: 模式代码 */
/*       00H=未启用的设备方式, 01H=已启用的设备方式并且使用外部固件模式, 02H=已启用的设备方式并且使用内置固件模式 */
/*       04H=未启用的主机方式, 05H=已启用的主机方式, 06H=已启用的主机方式并且自动产生SOF包, 07H=已启用的主机方式并且复位USB总线 */
/* 输出: 操作状态( CMD_RET_SUCCESS或CMD_RET_ABORT, 其它值说明操作未完成 ) */#define  CMD_SET_ENDP2         0x18          /* 设备方式: 设置USB端点0的接收器 */
/* 输入: 工作方式 */
/*           位7为1则位6为同步触发位, 否则同步触发位不变 */
/*           位3~位0为事务响应方式:  0000-就绪ACK, 1110-正忙NAK, 1111-错误STALL */#define  CMD_SET_ENDP3         0x19          /* 设备方式: 设置USB端点0的发送器 */
/* 输入: 工作方式 */
/*           位7为1则位6为同步触发位, 否则同步触发位不变 */
/*           位3~位0为事务响应方式:  0000~1000-就绪ACK, 1110-正忙NAK, 1111-错误STALL */#define CMD_SET_ENDP4         0x1A          /* 设备方式: 设置USB端点1的接收器 */
/* 输入: 工作方式 */
/*           位7为1则位6为同步触发位, 否则同步触发位不变 */
/*           位3~位0为事务响应方式:  0000-就绪ACK, 1110-正忙NAK, 1111-错误STALL */#define  CMD_SET_ENDP5         0x1B          /* 设备方式: 设置USB端点1的发送器 */
/* 输入: 工作方式 */
/*           位7为1则位6为同步触发位, 否则同步触发位不变 */
/*           位3~位0为事务响应方式:  0000~1000-就绪ACK, 1110-正忙NAK, 1111-错误STALL */#define CMD_SET_ENDP6         0x1C          /* 设置USB端点2/主机端点的接收器 */
/* 输入: 工作方式 */
/*           位7为1则位6为同步触发位, 否则同步触发位不变 */
/*           位3~位0为事务响应方式:  0000-就绪ACK, 1101-就绪但不返回ACK, 1110-正忙NAK, 1111-错误STALL */#define  CMD_SET_ENDP7         0x1D          /* 设置USB端点2/主机端点的发送器 */
/* 输入: 工作方式 */
/*           位7为1则位6为同步触发位, 否则同步触发位不变 */
/*           位3~位0为事务响应方式:  0000-就绪ACK, 1101-就绪但无须应答, 1110-正忙NAK, 1111-错误STALL */#define    CMD_GET_STATUS      0x22            /* 获取中断状态并取消中断请求 */
/* 输出: 中断状态 */#define   CMD_UNLOCK_USB      0x23            /* 设备方式: 释放当前USB缓冲区 */#define   CMD_RD_USB_DATA0    0x27            /* 从当前USB中断的端点缓冲区读取数据块 */
/* 输出: 长度, 数据流 */#define    CMD_RD_USB_DATA     0x28            /* 从当前USB中断的端点缓冲区读取数据块, 并释放缓冲区, 相当于 CMD_RD_USB_DATA0 + CMD_UNLOCK_USB */
/* 输出: 长度, 数据流 */#define    CMD_WR_USB_DATA3    0x29            /* 设备方式: 向USB端点0的发送缓冲区写入数据块 */
/* 输入: 长度, 数据流 */#define    CMD_WR_USB_DATA5    0x2A            /* 设备方式: 向USB端点1的发送缓冲区写入数据块 */
/* 输入: 长度, 数据流 */#define    CMD_WR_USB_DATA7    0x2B            /* 向USB端点2或者主机端点的发送缓冲区写入数据块 */
/* 输入: 长度, 数据流 *//* ************************************************************************** */
/* 以下命令用于USB主机方式, 只有CH375支持 */#define   CMD_SET_BAUDRATE    0x02            /* 主机方式 & 串口方式: 设置串口通讯波特率 */
/* 输入: 波特率分频系数, 波特率分频常数 */
/* 输出: 操作状态( CMD_RET_SUCCESS或CMD_RET_ABORT, 其它值说明操作未完成 ) */#define  CMD_GET_DEV_RATE    0x0A            /* 主机方式: 获取当前连接的USB设备的数据速率类型 */
/* 输入: 数据07H */
/* 输出: 数据速率类型 */
/*                    位4为1则是1.5Mbps低速USB设备, 否则是12Mbps全速USB设备 */#define  CMD_GET_MAX_LUN     0x0A            /* 主机方式: 获取USB存储器最大逻辑单元号 */
/* 输入: 数据38H */
/* 输出: 最大逻辑单元号 */#define    CMD_SET_RETRY         0x0B          /* 主机方式: 设置USB事务操作的重试次数 */
/* 输入: 数据25H, 重试次数 */
/*                    位7为0则收到NAK时不重试, 位7为1位6为0则收到NAK时无限重试, 位7为1位6为1则收到NAK时最多重试2秒, 位5~位0为超时后的重试次数 */#define  CMD_SET_DISK_LUN    0x0B            /* 主机方式: 设置USB存储器的当前逻辑单元号 */
/* 输入: 数据34H, 新的当前逻辑单元号(00H-0FH) */#define  CMD_SET_PKT_P_SEC   0x0B            /* 主机方式: 设置USB存储器的每扇区数据包总数 */
/* 输入: 数据39H, 新的每扇区数据包总数(08H,10H,20H,40H) */#define CMD_TEST_CONNECT    0x16            /* 主机方式: 检查USB设备连接状态 */
/* 输出: 状态( USB_INT_CONNECT或USB_INT_DISCONNECT或USB_INT_USB_READY, 其它值说明操作未完成 ) */#define CMD_ABORT_NAK         0x17          /* 主机方式: 放弃当前NAK的重试 */#define   CMD_CLR_STALL         0x41          /* 主机方式: 控制传输-清除端点错误 */
/* 输入: 端点号 */
/* 输出中断 */#define   CMD_SET_ADDRESS     0x45            /* 主机方式: 控制传输-设置USB地址 */
/* 输入: 地址值 */
/* 输出中断 */#define   CMD_GET_DESCR         0x46          /* 主机方式: 控制传输-获取描述符 */
/* 输入: 描述符类型 */
/* 输出中断 */#define   CMD_SET_CONFIG      0x49            /* 主机方式: 控制传输-设置USB配置 */
/* 输入: 配置值 */
/* 输出中断 */#define   CMD_AUTO_SETUP      0x4D            /* 主机方式: 自动配置USB设备 */
/* 输出中断 */#define   CMD_ISSUE_TKN_X     0x4E            /* 主机方式: 发出同步令牌, 执行事务, 该命令可代替 CMD_SET_ENDP6/CMD_SET_ENDP7 + CMD_ISSUE_TOKEN */
/* 输入: 同步标志, 事务属性 */
/*           同步标志的位7为主机端点IN的同步触发位, 位6为主机端点OUT的同步触发位, 位5~位0必须为0 */
/*           事务属性的低4位是令牌, 高4位是端点号 */
/* 输出中断 */#define   CMD_ISSUE_TOKEN     0x4F            /* 主机方式: 发出令牌, 执行事务 */
/* 输入: 事务属性 */
/*           低4位是令牌, 高4位是端点号 */
/* 输出中断 */#define   CMD_DISK_BOC_CMD    0x50            /* 主机方式: 对USB存储器执行BulkOnly传输协议的命令 */
/* 输出中断 */#define   CMD_DISK_INIT         0x51          /* 主机方式: 初始化USB存储器 */
/* 输出中断 */#define   CMD_DISK_RESET      0x52            /* 主机方式: 控制传输-复位USB存储器 */
/* 输出中断 */#define   CMD_DISK_SIZE         0x53          /* 主机方式: 获取USB存储器的容量 */
/* 输出中断 */#define   CMD_DISK_READ         0x54          /* 主机方式: 从USB存储器读数据块(以扇区为单位) */
/* 输入: LBA扇区地址(总长度32位, 低字节在前), 扇区数(01H~FFH) */
/* 输出中断 */#define   CMD_DISK_RD_GO      0x55            /* 主机方式: 继续执行USB存储器的读操作 */
/* 输出中断 */#define   CMD_DISK_WRITE      0x56            /* 主机方式: 向USB存储器写数据块(以扇区为单位) */
/* 输入: LBA扇区地址(总长度32位, 低字节在前), 扇区数(01H~FFH) */
/* 输出中断 */#define   CMD_DISK_WR_GO      0x57            /* 主机方式: 继续执行USB存储器的写操作 */
/* 输出中断 */#define   CMD_DISK_INQUIRY    0x58            /* 主机方式: 查询USB存储器特性 */
/* 输出中断 */#define   CMD_DISK_READY      0x59            /* 主机方式: 检查USB存储器就绪 */
/* 输出中断 */#define   CMD_DISK_R_SENSE    0x5A            /* 主机方式: 检查USB存储器错误 */
/* 输出中断 */#define   CMD_DISK_MAX_LUN    0x5D            /* 主机方式: 控制传输-获取USB存储器最大逻辑单元号 */
/* 输出中断 *//* ********************************************************************************************************************* */
/* 操作状态 */#define   CMD_RET_SUCCESS     0x51            /* 命令操作成功 */
#define CMD_RET_ABORT         0x5F          /* 命令操作失败 *//* ********************************************************************************************************************* */
/* USB中断状态 */#ifndef    USB_INT_EP0_SETUP/* 以下状态代码为特殊事件中断, 如果通过CMD_CHK_SUSPEND启用USB总线挂起检查, 那么必须处理USB总线挂起和睡眠唤醒的中断状态 */
#define USB_INT_USB_SUSPEND 0x05            /* USB总线挂起事件 */
#define USB_INT_WAKE_UP       0x06          /* 从睡眠中被唤醒事件 *//* 以下状态代码0XH用于USB设备方式 */
/*   内置固件模式下只需要处理: USB_INT_EP1_OUT, USB_INT_EP1_IN, USB_INT_EP2_OUT, USB_INT_EP2_IN */
/*   位7-位4为0000 */
/*   位3-位2指示当前事务, 00=OUT, 10=IN, 11=SETUP */
/*   位1-位0指示当前端点, 00=端点0, 01=端点1, 10=端点2, 11=USB总线复位 */
#define USB_INT_EP0_SETUP     0x0C          /* USB端点0的SETUP */
#define USB_INT_EP0_OUT       0x00          /* USB端点0的OUT */
#define USB_INT_EP0_IN        0x08          /* USB端点0的IN */
#define USB_INT_EP1_OUT       0x01          /* USB端点1的OUT */
#define USB_INT_EP1_IN        0x09          /* USB端点1的IN */
#define USB_INT_EP2_OUT       0x02          /* USB端点2的OUT */
#define USB_INT_EP2_IN        0x0A          /* USB端点2的IN */
/* USB_INT_BUS_RESET    0x0000XX11B */      /* USB总线复位 */
#define USB_INT_BUS_RESET1  0x03            /* USB总线复位 */
#define USB_INT_BUS_RESET2  0x07            /* USB总线复位 */
#define USB_INT_BUS_RESET3  0x0B            /* USB总线复位 */
#define USB_INT_BUS_RESET4  0x0F            /* USB总线复位 */#endif/* 以下状态代码2XH-3XH用于USB主机方式的通讯失败代码, 仅CH375支持 */
/*   位7-位6为00 */
/*   位5为1 */
/*   位4指示当前接收的数据包是否同步 */
/*   位3-位0指示导致通讯失败时USB设备的应答: 0010=ACK, 1010=NAK, 1110=STALL, 0011=DATA0, 1011=DATA1, XX00=超时 */
/* USB_INT_RET_ACK  0x001X0010B */          /* 错误:对于IN事务返回ACK */
/* USB_INT_RET_NAK  0x001X1010B */          /* 错误:返回NAK */
/* USB_INT_RET_STALL    0x001X1110B */      /* 错误:返回STALL */
/* USB_INT_RET_DATA0    0x001X0011B */      /* 错误:对于OUT/SETUP事务返回DATA0 */
/* USB_INT_RET_DATA1    0x001X1011B */      /* 错误:对于OUT/SETUP事务返回DATA1 */
/* USB_INT_RET_TOUT 0x001XXX00B */          /* 错误:返回超时 */
/* USB_INT_RET_TOGX 0x0010X011B */          /* 错误:对于IN事务返回数据不同步 */
/* USB_INT_RET_PID  0x001XXXXXB */          /* 错误:未定义 *//* 以下状态代码1XH用于USB主机方式的操作状态代码, 仅CH375支持 */
#ifndef USB_INT_SUCCESS
#define USB_INT_SUCCESS       0x14          /* USB事务或者传输操作成功 */
#define USB_INT_CONNECT       0x15          /* 检测到USB设备连接事件 */
#define USB_INT_DISCONNECT  0x16            /* 检测到USB设备断开事件 */
#define USB_INT_BUF_OVER      0x17          /* USB控制传输的数据太多, 缓冲区溢出 */
#define USB_INT_USB_READY     0x18          /* USB设备已经被初始化(已分配USB地址) */
#define USB_INT_DISK_READ     0x1D          /* USB存储器读数据块, 请求数据读出 */
#define USB_INT_DISK_WRITE  0x1E            /* USB存储器写数据块, 请求数据写入 */
#define USB_INT_DISK_ERR      0x1F          /* USB存储器操作失败 */
#endif/* ********************************************************************************************************************* */
/* 常用USB定义 *//* USB的包标识PID, 主机方式可能用到 */
#ifndef DEF_USB_PID_SETUP
#define DEF_USB_PID_NULL      0x00          /* 保留PID, 未定义 */
#define DEF_USB_PID_SOF       0x05
#define DEF_USB_PID_SETUP     0x0D
#define DEF_USB_PID_IN        0x09
#define DEF_USB_PID_OUT       0x01
#define DEF_USB_PID_ACK       0x02
#define DEF_USB_PID_NAK       0x0A
#define DEF_USB_PID_STALL     0x0E
#define DEF_USB_PID_DATA0     0x03
#define DEF_USB_PID_DATA1     0x0B
#define DEF_USB_PID_PRE       0x0C
#endif/* USB请求类型, 外置固件模式可能用到 */
#ifndef DEF_USB_REQ_TYPE
#define DEF_USB_REQ_READ      0x80          /* 控制读操作 */
#define DEF_USB_REQ_WRITE     0x00          /* 控制写操作 */
#define DEF_USB_REQ_TYPE      0x60          /* 控制请求类型 */
#define DEF_USB_REQ_STAND     0x00          /* 标准请求 */
#define DEF_USB_REQ_CLASS     0x20          /* 设备类请求 */
#define DEF_USB_REQ_VENDOR  0x40            /* 厂商请求 */
#define DEF_USB_REQ_RESERVE 0x60            /* 保留请求 */
#endif/* USB标准设备请求, RequestType的位6位5=00(Standard), 外置固件模式可能用到 */
#ifndef DEF_USB_GET_DESCR
#define DEF_USB_CLR_FEATURE 0x01
#define DEF_USB_SET_FEATURE 0x03
#define DEF_USB_GET_STATUS  0x00
#define DEF_USB_SET_ADDRESS 0x05
#define DEF_USB_GET_DESCR     0x06
#define DEF_USB_SET_DESCR     0x07
#define DEF_USB_GET_CONFIG  0x08
#define DEF_USB_SET_CONFIG  0x09
#define DEF_USB_GET_INTERF  0x0A
#define DEF_USB_SET_INTERF  0x0B
#define DEF_USB_SYNC_FRAME  0x0C
#endiftypedef union                     //请求包结构
{   struct{ uint8_t  bmRequestType;uint8_t  bRequest;uint16_t wValue;uint16_t wIndex;uint16_t wLength;}Req;uint8_t Req_buf[8];
}_REQUEST;#pragma pack(1)
typedef struct _USB_DEVICE_DESCRIPTOR
{uint8_t   bLength;uint8_t   bDescriptorType;uint16_t  bcdUSB;uint8_t   bDeviceClass;uint8_t   bDeviceSubClass;uint8_t   bDeviceProtocol;uint8_t   bMaxPacketSize0;uint16_t  idVendor;uint16_t  idProduct;uint16_t  bcdDevice;uint8_t   iManufacturer;uint8_t   iProduct;uint8_t   iSerialNumber;uint8_t   bNumConfigurations;
} USB_DEV_DESCR, *PUSB_DEV_DESCR;typedef struct _USB_CONFIG_DESCRIPTOR
{uint8_t   bLength;uint8_t   bDescriptorType;uint16_t  wTotalLength;uint8_t   bNumInterfaces;uint8_t   bConfigurationvalue;uint8_t   iConfiguration;uint8_t   bmAttributes;uint8_t   MaxPower;
} USB_CFG_DESCR, *PUSB_CFG_DESCR;typedef struct _USB_INTERF_DESCRIPTOR
{uint8_t   bLength;uint8_t   bDescriptorType;uint8_t   bInterfaceNumber;uint8_t   bAlternateSetting;uint8_t   bNumEndpoints;uint8_t   bInterfaceClass;uint8_t   bInterfaceSubClass;uint8_t   bInterfaceProtocol;uint8_t   iInterface;
}USB_ITF_DESCR, *PUSB_ITF_DESCR;typedef struct _USB_HID_DESCRIPTOR
{uint8_t   bLength;uint8_t   bDescriptorType1;uint16_t  bcdHID;uint8_t   bCountryCode;uint8_t   bNumDescriptors;uint8_t   bDescriptorType2;uint8_t   wItemLength;uint8_t   iInterface;
}USB_HID_DESCR, *PUSB_HID_DESCR;typedef struct _USB_ENDPOINT_DESCRIPTOR
{uint8_t   bLength;uint8_t   bDescriptorType;uint8_t   bEndpointAddress;uint8_t   bmAttributes;uint16_t  wMaxPacketSize;uint8_t   bInterval;
}USB_ENDP_DESCR, *PUSB_ENDP_DESCR;typedef struct _USB_CONFIG_DESCRIPTOR_LONG
{USB_CFG_DESCR cfg_descr;USB_ITF_DESCR itf_descr;USB_HID_DESCR hid_descr;USB_ENDP_DESCR endp_descr[4];
} USB_CFG_DESCR_LONG, *PUSB_CFG_DESCR_LONG;
#pragma pack()typedef enum
{Invalid_Device = 0,//未启用的 USB 设备方式(上电或复位后的默认方式);ExtFM_Device,      //已启用的 USB 设备方式,外部固件模式;IntFM_Device,      //已启用的 USB 设备方式,内置固件模式;Invalid_Host = 4,  //未启用的 USB 主机方式;NoSOF_Host,        //已启用的 USB 主机方式,不产生 SOF 包;AutoSOF_Host,      //已启用的 USB 主机方式,自动产生 SOF 包;RstBUS_Host,       //已启用的 USB 主机方式,复位 USB 总线;
}USB_Mode_Type;typedef struct
{uint8_t         Version;//版本号USB_Mode_Type   USB_Mode;uint8_t         Endp6_Mode;uint8_t         Endp7_Mode;uint8_t         USB_Buffer[64];uint8_t         USB_DataIn_Buffer[64];uint8_t         USB_DataIn_Length;uint8_t         USB_DataIn_Flag;
}CH375_USB_DEF;extern CH375_USB_DEF   CH375_USB_Info;uint8_t Bsp_CH375_Wait_INT(void);
uint8_t Bsp_CH375_Read_Data(void);
void Bsp_CH375_Write_Cmd(uint8_t cmd );
void Bsp_CH375_Write_Data(uint8_t data );
void BSP_CH375_Toggle_Send(void);
void BSP_CH375_Toggle_Recv(void);
void Bsp_CH375_Write_USBData( uint8_t len, uint8_t *buffer );
void Bsp_CH375_Set_Retry(uint8_t num);
bool Bsp_CH375_Set_USBMode(USB_Mode_Type mode);
bool Bsp_CH375_Reset_Device(void);uint8_t Bsp_CH375_SetConfig( uint8_t cfg );
uint8_t Bsp_CH375_SetAddr( uint8_t addr );
uint8_t Bsp_CH375_Get_USBDescr( uint8_t type );
uint8_t Bsp_CH375_IssueToken(uint8_t endp_and_pid);
uint8_t Bsp_CH375_Read_USBData( uint8_t *buffer );#endif

代码如下:

#include "bsp_ch375.h"
#include "bsp_init.h"
#include "bsp_delay.h"void Bsp_CH375_Write_Cmd(uint8_t cmd ) /* 向CH375的命令端口写入命令*/
{  Bsp_DelayUs(5);CH375_CS_0;CH375_A0_1;CH375_DATA(cmd);CH375_WR_0;Bsp_DelayUs(5);CH375_CS_1;CH375_WR_1;
}void Bsp_CH375_Write_Data(uint8_t data ) /* 向CH375的命令端口写入数据*/
{  Bsp_DelayUs(5);CH375_CS_0;CH375_A0_0;CH375_DATA(data);CH375_WR_0;Bsp_DelayUs(5);CH375_CS_1;CH375_WR_1;CH375_A0_1;
}uint8_t Bsp_CH375_Read_Data(void)
{uint8_t data;CH375_CS_0;CH375_A0_0;CH375_RD_0;CH375_DATA_INPUT();Bsp_DelayUs(5);data = CH375_DATA_PORT->IDR;CH375_CS_1;CH375_A0_1;CH375_RD_1;CH375_DATA_OUTPUT();return data;
}uint8_t Bsp_CH375_Get_INTStatus(void)
{uint8_t status;Bsp_CH375_Write_Cmd(CMD_GET_STATUS); status = Bsp_CH375_Read_Data();Debug_Log("USB interrupt status %d",status);return status;
}uint8_t Bsp_CH375_Wait_INT(void)
{Debug_Log("Wait for USB interrupt...")while(CH375_INT_GPIO_Port->IDR & CH375_INT_Pin);return Bsp_CH375_Get_INTStatus();
}uint8_t Bsp_CH375_Get_DeviceVersion(void)
{uint8_t version;Bsp_CH375_Write_Cmd(CMD_GET_IC_VER);Bsp_DelayUs(5);version = Bsp_CH375_Read_Data();version &= 0x7F;Debug_Log("USB version: 0x%X",version);return(version);
}bool Bsp_CH375_Set_USBMode(USB_Mode_Type mode) {  /* 设置CH375的工作模式 */uint8_t i;Bsp_CH375_Write_Cmd( CMD_SET_USB_MODE );Bsp_CH375_Write_Data(mode);CH375_USB_Info.Endp6_Mode = CH375_USB_Info.Endp7_Mode = 0x80;Bsp_DelayUs(5);for( i=0; i!=10; i++ ) {  /* 等待设置模式操作完成,不超过30uS */if( Bsp_CH375_Read_Data()==CMD_RET_SUCCESS ) {CH375_USB_Info.USB_Mode = mode;Debug_Log("Set USB Mode %d success",mode);return( TRUE );  /* 成功 */}}Debug_Log("Set USB Mode faild");return(FALSE);  /* CH375出错,例如芯片型号错或者处于串口方式或者不支持 */
}/* 数据同步 */
/* USB的数据同步通过切换DATA0和DATA1实现: 在设备端, CH372/CH375可以自动切换;在主机端, 必须由SET_ENDP6和SET_ENDP7命令控制CH375切换DATA0与DATA1.主机端的程序处理方法是为SET_ENDP6和SET_ENDP7分别提供一个全局变量,初始值均为80H, 每执行一次成功事务后将位6取反, 每执行一次失败事务后将其复位为80H. *//* 主机接收成功后,切换DATA0和DATA1实现数据同步 */
void BSP_CH375_Toggle_Recv(void)
{  Bsp_CH375_Write_Cmd(CMD_SET_ENDP6);Bsp_CH375_Write_Data(CH375_USB_Info.Endp6_Mode);CH375_USB_Info.Endp6_Mode ^= 0x40;Bsp_DelayUs(2);
}/* 主机发送成功后,切换DATA0和DATA1实现数据同步 */
void BSP_CH375_Toggle_Send(void)
{  Bsp_CH375_Write_Cmd(CMD_SET_ENDP7);Bsp_CH375_Write_Data(CH375_USB_Info.Endp7_Mode);CH375_USB_Info.Endp7_Mode ^= 0x40;Bsp_DelayUs(2);
}/* 主机接收失败后,复位设备端的数据同步到DATA0 */
uint8_t Bsp_CH375_ClrStall6(void)
{  Bsp_CH375_Write_Cmd( CMD_CLR_STALL );Bsp_CH375_Write_Data( CH375_EndPointNum | 0x80 );  /* 如果设备端不是CH37X芯片,那么需要修改端点号 */CH375_USB_Info.Endp6_Mode = 0x80;return( Bsp_CH375_Wait_INT() );
}/* 主机发送失败后,复位设备端的数据同步到DATA0 */
uint8_t Bsp_CH375_ClrStall7(void)
{  Bsp_CH375_Write_Cmd( CMD_CLR_STALL );Bsp_CH375_Write_Data( CH375_EndPointNum );  /* 如果设备端不是CH37X芯片,那么需要修改端点号 */CH375_USB_Info.Endp7_Mode=0x80;return( Bsp_CH375_Wait_INT() );
}/* 数据读写, 单片机读写CH372或者CH375芯片中的数据缓冲区 *//* 从CH37X读出数据块 */
uint8_t Bsp_CH375_Read_USBData( uint8_t *buffer )
{uint8_t  i, len;Bsp_CH375_Write_Cmd( CMD_RD_USB_DATA );  /* 从CH375的端点缓冲区读取接收到的数据 */len = Bsp_CH375_Read_Data();  /* 后续数据长度 */for ( i=0; i!=len; i++ ) *buffer++ = Bsp_CH375_Read_Data();return( len );
}/* 向CH37X写入数据块 */
void Bsp_CH375_Write_USBData( uint8_t len, uint8_t *buffer )
{  Bsp_CH375_Write_Cmd( CMD_WR_USB_DATA7 );  /* 向CH375的端点缓冲区写入准备发送的数据 */Bsp_CH375_Write_Data( len );  /* 后续数据长度, len不能大于64 */while( len-- ) Bsp_CH375_Write_Data( *buffer++ );
}/* 主机操作 *//* 执行USB事务 */
uint8_t Bsp_CH375_IssueToken(uint8_t endp_and_pid)
{  /* 执行完成后, 将产生中断通知单片机, 如果是USB_INT_SUCCESS就说明操作成功 */uint8_t status;Bsp_CH375_Write_Cmd(CMD_ISSUE_TOKEN);Bsp_CH375_Write_Data(endp_and_pid);  /* 高4位目的端点号, 低4位令牌PID */status=Bsp_CH375_Wait_INT();  /* 等待CH375操作完成 */if ( status!=USB_INT_SUCCESS && status!=USB_INT_USB_READY && ( endp_and_pid&0xF0) == (CH375_EndPointNum << 4) ) /* 操作失败,如果设备端不是CH37X芯片,那么需要修改端点号 */{  if ( (endp_and_pid&0x0F) == DEF_USB_PID_OUT ) Bsp_CH375_ClrStall7();  /* 复位设备端接收 */else if ( (endp_and_pid&0x0F) == DEF_USB_PID_IN ) Bsp_CH375_ClrStall6();  /* 复位设备端发送 */}return( status );
}/* 主机发送 */
void Bsp_CH375_Host_Send( uint8_t len, uint8_t *buffer )
{  Bsp_CH375_Write_USBData( len, buffer );BSP_CH375_Toggle_Send();if ( Bsp_CH375_IssueToken( ( CH375_EndPointNum << 4 ) | DEF_USB_PID_OUT )!=USB_INT_SUCCESS ) Error_Handler();  /* 如果设备端不是CH37X芯片,那么需要修改端点号 */
}/* 主机接收, 返回长度 */
uint8_t Bsp_CH375_Host_Recv( uint8_t *buffer )
{BSP_CH375_Toggle_Recv();if ( Bsp_CH375_IssueToken( ( CH375_EndPointNum << 4 ) | DEF_USB_PID_IN )!=USB_INT_SUCCESS ) Error_Handler();  /* 如果设备端不是CH37X芯片,那么需要修改端点号 */return( Bsp_CH375_Read_USBData( buffer ) );
}/* 从设备端获取描述符 */
uint8_t Bsp_CH375_Get_USBDescr( uint8_t type )
{ uint8_t status;Bsp_CH375_Write_Cmd( CMD_GET_DESCR );Bsp_CH375_Write_Data( type );  /* 描述符类型, 只支持1(设备)或者2(配置) */status = Bsp_CH375_Wait_INT();  /* 等待CH375操作完成 */return( status );
}
/* 设置设备端的USB地址 */
uint8_t Bsp_CH375_SetAddr( uint8_t addr )
{  uint8_t status;Bsp_CH375_Write_Cmd( CMD_SET_ADDRESS );  /* 设置USB设备端的USB地址 */Bsp_CH375_Write_Data( addr );  /* 地址, 从1到127之间的任意值, 常用2到20 */status=Bsp_CH375_Wait_INT();  /* 等待CH375操作完成 *//* 操作成功 */if ( status==USB_INT_SUCCESS ) {  Bsp_CH375_Write_Cmd( CMD_SET_USB_ADDR );  /* 设置USB主机端的USB地址 */Bsp_CH375_Write_Data( addr );  /* 当目标USB设备的地址成功修改后,应该同步修改主机端的USB地址 */}return( status );
}/* 设置设备端的USB配置 */
uint8_t Bsp_CH375_SetConfig( uint8_t cfg )
{  CH375_USB_Info.Endp6_Mode = CH375_USB_Info.Endp7_Mode = 0x80;  /* 复位USB数据同步标志 */Bsp_CH375_Write_Cmd( CMD_SET_CONFIG );  /* 设置USB设备端的配置值 */Bsp_CH375_Write_Data( cfg );  /* 此值取自USB设备的配置描述符中 */return( Bsp_CH375_Wait_INT() );  /* 等待CH375操作完成 */
}void Bsp_CH375_Set_Retry(uint8_t num)
{   Bsp_CH375_Write_Cmd( CMD_SET_RETRY); Bsp_CH375_Write_Data( 0x25);Bsp_CH375_Write_Data( num);Bsp_DelayUs(2);
}bool Bsp_CH375_Reset_Device(void)
{/* USB规范中未要求在USB设备插入后必须复位该设备,但是计算机的WINDOWS总是这样做,所以有些USB设备也要求在插入后必须先复位才能工作 */if(Bsp_CH375_Set_USBMode( RstBUS_Host ) == FALSE)return FALSE;  /* 复位USB设备,CH375向USB信号线的D+和D-输出低电平 */Bsp_DelayMs(10);if(Bsp_CH375_Set_USBMode( AutoSOF_Host ) == FALSE)return FALSE;  /* 结束复位 */Bsp_DelayMs(100);return TRUE;
}

STM32配置CH375B成HID Host模式读取自定义HID设备的数据 ——STM32配置CH375B接口函数相关推荐

  1. STM32配置CH375B成HID Host模式读取自定义HID设备的数据 ——STM32端口初始化

    最近产品需要一个USB主机测试治具,所以需要做一个USB HOST去读取HID设备的数据,由于以前也没做过USB方面的项目,对这一块也不是很熟悉,因此遇到了很多困难,所幸的是经过两天半的努力,最终完成 ...

  2. Android 读取外接储存设备的数据(如挂载的U盘,SD卡等)

    本篇文章,将围绕以下几点来讲解: 1:OTG是什么? 2:Android手机和一些Android系统的TV盒子对OTG的支持情况? 3:如何得知外接储存设备的插入和拔出的广播事件? 4:得到插入广播后 ...

  3. Android USB开发小结:host模式与accessory模式

    很早之前就想对Android USB的两种模式作个小结,但是一直没有空去搞,毕竟USB这块应该属于冷门方向,并且应用层能够做的比较少也很简单.最近刚好在做大疆无人机的二次开发,想着对USB连接检测这块 ...

  4. docker安装mysql并配置,Docker安装MySql-挂载外部数据和配置

    在上一篇中<在CentOS7中使用Docker安装MySql>中介绍了怎样在Docker中安装Mysql,但存在两个问题: 1.用户密码和字符集等的设置,需要安装完MySql后,进入到My ...

  5. 用python读取excel指定的列数据

    可以使用Python中的Pandas库来帮助你读取Excel指定的列数据.可以使用pandas.read_excel()函数,并指定要读取的列名称:df = pandas.read_excel(文件名 ...

  6. 【STM32笔记】HAL库低功耗模式配置(ADC唤醒无法使用、低功耗模式无法烧录解决方案)

    [STM32笔记]HAL库低功耗模式配置(ADC唤醒无法使用.低功耗模式无法烧录解决方案) [STM32笔记]低功耗模式配置及避坑汇总 一.低功耗模式简介 系统提供了多个低功耗模式,可在 CPU 不需 ...

  7. STM32的USB例程JoyStickMouse改成自定义HID设备

    简介 USB HID类是USB设备的一个标准设备类,包括的设备非常多.HID类设备定义它属于人机交互操作的设备,用于控制计算机操作的一些方面,如USB鼠标.USB键盘.USB游戏操纵杆等.但HID设备 ...

  8. Docker网络配置再学习之Host和none模式

    在之前的文章中,壹哥跟大家说过,关于Docker网络这一块的内容有很多,为了让大家搞清楚这个问题,壹哥准备搞几篇系列文章,来为各位小伙伴解惑.今天壹哥给大家带来的是Docker网络中host和none ...

  9. 62 stm32 usb自定义hid复合设备修改实验

    1.引言 最近因为项目需要,我们希望单片机既能有hid键盘功能,又能有hid设备的功能.即单片机的一个usb接口插入电脑后,电脑能识别出键盘设备和hid设备,两者同时存在的. 基于项目只是要求实现功能 ...

最新文章

  1. 遥遥无期还是近在咫尺?长文展望「大模型」商业化前景
  2. alert(1) to win 16
  3. hadoop 运行wordcount
  4. where/、trim/ 标签的使用
  5. LeetCode 366. Find Leaves of Binary Tree
  6. Confluence 6 workbox 通知包含了什么
  7. ZooKeeper程序员指南--使用ZooKeeper开发分布式应用程序
  8. 《Java多线程编程核心技术》读后感(十四)
  9. 程序员修神之路:问世间异步为何物?
  10. c# 对象json互相转换_Go语言进阶之路(六):内置JSON库和开源库gjson
  11. SpringBoot2.0应用(五):SpringBoot2.0整合MyBatis
  12. 【名牌电脑制作隐藏分区与释放隐藏分区的方法】
  13. matlab有限差分一维导热,一维导热方程-有限差分法-matlab实现.docx
  14. 制作字幕.html教程,自制字幕怎么做 字幕制作软件
  15. 计算机语言写信祝福语,写信祝福语
  16. 【兴趣书签】科幻小说——《走出一日囚》
  17. 蓍草占卜Python法
  18. 【雷达信号处理】---雷达分辨率
  19. 解开关于人工智能的六个迷思
  20. 《公司理财师专业能力》笔记

热门文章

  1. MES系统供应商评估报告-- Gartner出品
  2. 通过Spark Streaming的window操作实战模拟热点搜索词案例实战
  3. 【2073】三角形面积
  4. PE中Ghost 使用详解
  5. 前端工作随笔日记 Day01
  6. Excel速度问题探讨.
  7. NIST 网络安全相关标准 美国 (简单整理)
  8. linux lamp 搭建,LInux-Lamp搭建
  9. Kotlin ListView设置Adapter
  10. FreeEIM 网站地图 A