历史上的今天

今天是:2024年11月07日(星期四)

正在发生

2020年11月07日 | 关于stm32的USB学习笔记之usbcore.c

发布者:脑洞狂想 来源: eefocus关键字:stm32  USB学  usbcore 手机看文章 扫描二维码
随时随地手机看文章

#include   

#include "usbreg.h"  

#include "usbcore.h"  

#include "usbuser.h"  

#include "usbcfg.h"  

#include "usb.h"  

#include "usb_hw.h"  

#include "usbdesc.h"  

#include "hid.h"  

#include "hiduser.h"  

  

  

#define _DEBUG_  

#include "debug.h"  

  

#pragma diag_suppress 111,1441  

  

//用来指示USB设备的状态  

WORD    USB_DeviceStatus;  

//用来存储设备的地址  

BYTE    USB_DeviceAddress;  

//用来存储USB当前使用的设备的配置  

BYTE    USB_Configuration;  

//此配置使用端点  

DWORD USB_EndPointMask;  

//用于标志此端点是否已经被停止0~15依次代表15个端点  

DWORD USB_EndPointHalt;  

//此配置使用的接口数  

BYTE  USB_NumInterfaces;  

//每个接口可用的当前接口可替换值  

BYTE  USB_AltSetting[USB_IF_NUM];  

  

  

/*用于临时存储控制传输时的数据包*/  

USB_SETUP_PACKET SetupPacket;  

  

/*用于向主机发送数据的EP0的数据结构*/  

USB_EP_DATA EP0Data;  

/*EP0Buf用于向USB发送数据时用的缓冲区*/  

BYTE    EP0Buf[USB_MAX_PACKET0];  

  

/*功能:复位USB的一些数据标志 

 *参数:无 

 *返回值:无 

 */  

void    USB_ResetCore(void)  

{  

    //默认为总线供电,因为我们的USB现在不都是插在电脑上才能工作的么&^_^  

    USB_DeviceStatus    =   USB_POWER;    

    //在枚举之初地址当然是0  

    USB_DeviceAddress   =   0;  

    //配置描述符的标识从1开始,这里也先置为0  

    USB_Configuration   =   0;  

    //目前使用的是端点0  

    USB_EndPointMask    =   0x00010001;  

    //没有停止的端点  

    USB_EndPointHalt    =   0x00000000;  

}  

  

/*功能:建立阶段,读取建立数据包 

 *参数:无 

 *返回值:无 

 */  

void USB_SetupStage(void)  

{  

     USB_ReadEP(0x00,(BYTE*)&SetupPacket);  

}  

/*功能:建立阶段,In握手包 

 *参数:无 

 *返回值:无 

 */  

void USB_StatusInStage(void)  

{  

     USB_WriteEP(0x80,NULL,0);  

}  

/*功能:建立阶段,Out握手包 

 *参数:无 

 *返回值:无 

 */  

void USB_StatusOutStage(void)  

{  

     USB_ReadEP(0x00,EP0Buf);  

}  

/*功能:数据In阶段 

 *参数:无 

 *返回值:无 

 */  

void USB_DataInStage(void)  

{  

    DWORD   cnt;  

    //先计算引次要发送多少数据  

    if(EP0Data.Count > USB_MAX_PACKET0)  

        cnt = USB_MAX_PACKET0;  

    else  

        cnt = EP0Data.Count;  

    //这里写端点却主机读,则将Dir位置1  

    cnt = USB_WriteEP(0x80,EP0Data.pData,cnt);  

    EP0Data.pData   +=  cnt;  

    EP0Data.Count   -=  cnt;  

}  

/*功能:数据Out阶段 

 *参数:无 

 *返回值:无 

 */  

void USB_DataOutStage(void)  

{  

     DWORD  cnt;  

  

     cnt    =   USB_ReadEP(0x00,EP0Data.pData);  

     EP0Data.pData+=cnt;  

     EP0Data.Count-=cnt;  

}  

/*功能:获取USB设备的状态 

 *参数:无  

 *返回值:TRUE  --->成功 

 *       FALSE  --->错误 

 */  

__inline BOOL   USB_GetStatus(void)  

{  

    DWORD   n,m;  

      

    switch(SetupPacket.bmRequestType.BM.Recipient)  

    {  

        //接收端是设备  

        case REQUEST_TO_DEVICE:  

            //返回设备状态给他  

            EP0Data.pData = (BYTE *)&USB_DeviceStatus;  

            //将状态信息发送给主机  

            USB_DataInStage();  

            break;  

        //接收端是接口  

        case REQUEST_TO_INTERFACE:  

            /*配置描述符的标识从1开始,并且请求的接口号不能大于接口的数目,因为接口数目从0开始 

             *因为我们接口描述符中的接口号是一个字节所以这里wIndex中的数据中人低字节有效 

             */  

            if((USB_Configuration !=0)&&(SetupPacket.wIndex.WB.L < USB_NumInterfaces))  

            {     

                //清0两个字节,因为根据USB协议此处必须返回0  

                *((__packed WORD *)EP0Buf) = 0;   

                EP0Data.pData = EP0Buf;  

                //发送给主机  

                USB_DataInStage();  

            }  

            //此接口出现了错误  

            else  

                return  FALSE;  

            break;  

        case REQUEST_TO_ENDPOINT:  

            //端点号高1位0方向,低4位为端点号  

            n   = SetupPacket.wIndex.WB.L & 0x8f;  

            //m的高16位代表in端点的标志,低16位代表out端点的标志  

            m   = (n&0x80)?(1<<16 )<< (n&0x0f) :(1<            //如果配置标识不为0,或配置标识为0,但是是端点0时,才算正常  

            if((USB_Configuration !=0)||((n&0x0f)==0)&&(USB_EndPointMask & m))  

            {  

                //查看此端点是否已经停用  

                *((__packed WORD *)EP0Buf) = (USB_EndPointHalt &m )?1:0;  

                EP0Data.pData = EP0Buf;  

                //将数据发送给主机  

                USB_DataInStage();  

            }  

            //说明配置描述符出了问题  

            else  

                return  FALSE;  

            break;  

        default:  

            return  FALSE;  

    }     

    return TRUE;  

}  

/*功能:设置/清除USB设备的特征 

 *参数:sc 

            0----->清除 

            1----->设置 

 *返回值:TRUE  --->成功 

 *       FALSE  --->错误 

 */  

__inline BOOL USB_SetClrFeature(DWORD   sc)  

{  

    DWORD   n,m;  

    switch(SetupPacket.bmRequestType.BM.Recipient)  

    {  

        //接收端是设备,则清除或设置设备的特性  

        case REQUEST_TO_DEVICE:  

            if(SetupPacket.wValue.W == USB_FEATURE_REMOTE_WAKEUP)  

            {  

                if(sc)  

                {  

                    printf("设置设备远程唤醒特性rn");  

                    //设置USB状态为使能远程唤醒  

                    USB_DeviceStatus |= USB_GETSTATUS_REMOTE_WAKEUP;  

                    /*stm32硬件本身就支持远程唤醒,这里就不用设置了 

                     *当然,软件支不支持在于对中断屏蔽位的设置 

                     */  

                }     

                else  

                {  

                    printf("清除设备远程唤醒特性rn");  

                    USB_DeviceStatus &= ~USB_GETSTATUS_REMOTE_WAKEUP;  

                    /*stm32硬件本身就支持远程唤醒,这里就不用设置了 

                     *当然,软件支不支持在于对中断屏蔽位的设置 

[1] [2] [3] [4] [5] [6]
关键字:stm32  USB学  usbcore 引用地址:关于stm32的USB学习笔记之usbcore.c

上一篇:关于stm32的USB学习笔记之USB_HW.c
下一篇:STM32关于USB的相关寄存器

推荐阅读

集微网消息,存储市场风光无限将成昨天之景,如今NAND闪存价格暴跌,前景已今非昔比。虽然DRAM内存价格仍然坚挺,但是整体内存市场的下滑,DRAM仍坚挺多久或只是时间问题。很多存储器大厂也意识到NAND和DRAM价格下滑已是大势所趋,纷纷开始减少投资规模,控制产能。SK海力士表示,不但将自2018年底前开始减少投资规模,还将监控并调整2019年产能。同时三星...
  设计采用高性能单片机C8051F020为控制芯片,监控示波器面板上40个按键、3个编码开关及4个电位器的状态。分别介绍了键盘、编码开关和电位器的工作原理,以及其与单片机连接的硬件电路及软件编程的实现。按键部分采用一键多义的键盘程序设计方法,给出了键码匹配子程序流程图。  监控程序负责系统中全部硬件和软件资源的分配、调度工作,它提供用户接...
三星可能会在2021年1月份发布三星Galaxy S21系列,现在关于这款旗舰的细节陆续被曝出。  今天,业内人士@Ross Young爆料,三星Galaxy S21系列三款机型都提供了多种配色。  Galaxy S21有灰色、粉色、紫色和白色四种颜色,Galaxy S21+有黑色、银色、紫色和粉色四种颜色,超大杯Galaxy S21 Ultra仅有黑色和银色两种配色。  Ross Youn...
摆脱芯片供应短缺问题 双芯片代工策略见效 11月4日,高通股价飙涨逾12%,相较同业,高通在面对芯片更显得心应手,并看好明年业绩将持续成长。 高通执行长 Crisano Amon 于电话会议上表示,预计12月底供应问题将明显好转,明年下半年将有足够的供应满足需求,预期 2022财年EPS有望年增20%。 Lily点评:芯片短缺一直影响5G手机的出货量。高通作为全...

史海拾趣

问答坊 | AI 解惑

电脑鼠标识别原理???????

大家好!有没有高手知道电脑鼠标识别的原理呢?能否赐教!谢谢~…

查看全部问答∨

DSP程序优化方法(3)

6、提高CPU的并行性 ( 1)使用并行代码 尽可能把长的有依赖的代码链分解成几个可以在流水线执行单元中并行执行的没有依赖的代码链。很多高级语言,包括 C++ ,并不对产生的浮点表达式重新排序,因为那是一个相当复杂的过程。需要注意的是,重 ...…

查看全部问答∨

2006年 四川省大学生电子设计竞赛试题-无线调频对讲机(内江师院)

本帖最后由 paulhyde 于 2014-9-15 09:26 编辑 电子设计竞赛试题-无线调频对讲机 一、电子设计竞赛设计任务 设计一无线调频对讲机。 二、电子设计竞赛设计要求 1、基本要求: (1)、发射和接收频率范围:27MHz~31MHz(FM); (2) ...…

查看全部问答∨

初学者之-ARM的开发硬件选择

1. 如果你有做硬件和单片机的经验,建议自己做个最小系统板:假如你从没有做过ARM的开发,建议你一开始不要贪大求全,把所有的应用都做好,因为ARM的启动方式和dsp或单片机有所不同,往往会碰到各种问题,所以建议先布一个仅有Flash,SRAM或SDRAM、C ...…

查看全部问答∨

多片FPGA连接时管脚数目有限的难题

在用FPGA对ASIC做原型验证的时候,ASIC内部模块间的端口数目较大,而多片FPGA之间的管脚数目相对来说却比较有限,对于这个问题,大虾们是怎么解决的? 谢谢~…

查看全部问答∨

指令 cache 要等初试化DDR后才能打开吗? 打开后一定要开mmu吗?

instruction cache 要等初试化DDR后才能打开吗? 打开后一定要开mmu吗?…

查看全部问答∨

急求89C51读写24C16的原理和C语言源程序代码

做一个单片机设计,用到24C16,求它的用法 --------用89C51控制. 谢谢各位帮忙.…

查看全部问答∨

win4.2开发环境问题

现在用的vs2008做XP程序,买了昆仑通态的一体机,不想用昆仑通态的的那个东西, 软硬件环境 三星arm920,winCE4.2 请问大家都用什么编程环境啊?谢谢…

查看全部问答∨

要换Wolfson的音频怎么做

  主板是pxa270,以前用的是Ucb1400的驱动,现在换成Wolfson9715的,不知道 要怎么修改驱动,切换音频通道是怎么一回事?高手指点一下…

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved