STM32 usb_mem.c和usb_sil.c文件的分析
转:http://blog.csdn.net/u011318735/article/details/17424515
这两个c文件都还算是很简单的,先讲讲usb_mem.c这个文件。从文件名就能知道跟内存有关,这个文件主要定义了两个函数,一个读双缓冲区PMA的数据PMAToUserBufferCopy(),另一个是写数据到双缓冲区PMA,UserToPMABufferCopy。如果,当你的usb设备接收到了数据,当然数据存放在PMA中了,我们要读出数据就要用到PMAToUserBufferCopy()函数了,如果我们想要发送数据给usb主机,就要将你要发送的数据拷贝到PMA缓冲区中了,这样才能发送出去,原理跟串口类似。
/*******************************************************************************
* Function Name : UserToPMABufferCopy
* Description : 从用于内存区拷贝数据到PMA(数据包内存区)
* Input : pbUsrBuf:指向用户的内存区
* wPMABufAddr:要拷贝到PMA的wPMABufAddr地址处
* wNBytes: 要拷贝的数据长度(单位:字)
* Output : None.
* Return : None .
*******************************************************************************/
void UserToPMABufferCopy(uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
{
uint32_t n = (wNBytes + 1) >> 1; //n = (wNBytes + 1) / 2,表示多少字
uint32_t i, temp1, temp2;
uint16_t *pdwVal;
pdwVal = (uint16_t *)(wPMABufAddr * 2 + PMAAddr); //pdwVal存放要将数据存放的地址
for (i = n; i != 0; i--) //开始考被数据
{
temp1 = (uint16_t) * pbUsrBuf;
pbUsrBuf++;
temp2 = temp1 | (uint16_t) * pbUsrBuf << 8; //整合2个16bit数据
*pdwVal++ = temp2; //把整合的数据拷贝PMA内
pdwVal++; //目的指针指向下一个地址
pbUsrBuf++; //源指针指向下一地址
}
}
/*******************************************************************************
* Function Name : PMAToUserBufferCopy
* Description : Copy a buffer from user memory area to packet memory area (PMA)
* Input : pbUsrBuf指向用户的内存区
* wPMABufAddr PAM的地址
* wNBytes要拷贝的字节数
* Output : None.
* Return : None.
*******************************************************************************/
void PMAToUserBufferCopy(uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
{
uint32_t n = (wNBytes + 1) >> 1; //n = (wNBytes + 1) / 2,表示多少字
uint32_t i;
uint32_t *pdwVal;
pdwVal = (uint32_t *)(wPMABufAddr * 2 + PMAAddr); //从PAM区中去读1字数据
for (i = n; i != 0; i--)
{
*(uint16_t*)pbUsrBuf++ = *pdwVal++; //拷贝用户的内存区中
pbUsrBuf++;
}
}
/*******************************************************************************
* Function Name : USB_SIL_Init
* Description : 初始化USB设备IP和端点
* Input : None.
* Output : None.
* Return : Status.
*******************************************************************************/
uint32_t USB_SIL_Init(void)
{
#ifndef STM32F10X_CL /* USB interrupts initialization */
/* clear pending interrupts */
_SetISTR(0); //禁止所有的中断
wInterrupt_Mask = IMR_MSK;
/* set interrupts mask */
_SetCNTR(wInterrupt_Mask); //使能一些中断 #else /* Perform OTG Device initialization procedure (including EP0 init) */
OTG_DEV_Init(); //执行初始化程序OTG设备(包括EP0初始化) #endif /* STM32F10X_CL */ return 0;
}
还有的就是两个端点读写数据函数了,端点写函数USB_SIL_Write()共有三个参数:uint8_t bEpAddr, uint8_t* pBufferPointer, uint32_t wBufferSize,所以写调用写函数时,要指明端点号、要写数据地址,和要写的数据长度。读函数USB_SIL_Read()只有两个参数:端点号、数要保存的据区地址。
/*******************************************************************************
* Function Name : USB_SIL_Write
* Description : 往选中的端点中写入数据
* Input : bEpAddr:非控制端点的地址
* pBufferPointer:指向要写入端点的缓冲数据
* wBufferSize:要写入的数据长度(单位:字节)
* Output : None.
* Return : Status.
*******************************************************************************/
uint32_t USB_SIL_Write(uint8_t bEpAddr, uint8_t* pBufferPointer, uint32_t wBufferSize)
{
#ifndef STM32F10X_CL UserToPMABufferCopy(pBufferPointer, GetEPTxAddr(bEpAddr & 0x7F), wBufferSize);//把用户数据拷贝到PMA中 SetEPTxCount((bEpAddr & 0x7F), wBufferSize); //更新数据长度的控制寄存器 #else PCD_EP_Write (bEpAddr, pBufferPointer, wBufferSize); //使用使用PCD接口层函数来写入选择的端点 #endif /* STM32F10X_CL */ return 0;
} /*******************************************************************************
* Function Name : USB_SIL_Read
* Description : 从选中的端点中读出数据
* Input : bEpAddr:非控制端点的地址
* pBufferPointer:指向要保存的数据区地址
* Output : None.
* Return : 返回读出来的数据长度(单位:字节)
*******************************************************************************/
uint32_t USB_SIL_Read(uint8_t bEpAddr, uint8_t* pBufferPointer)
{
uint32_t DataLength = 0; #ifndef STM32F10X_CL DataLength = GetEPRxCount(bEpAddr & 0x7F); //从选中的端点中获取接收的数据长度 PMAToUserBufferCopy(pBufferPointer, GetEPRxAddr(bEpAddr & 0x7F), DataLength);//从PMA拷贝数据到用户区 #else USB_OTG_EP *ep; ep = PCD_GetOutEP(bEpAddr); //获取选中端点的结构体指针 DataLength = ep->xfer_len; //获取接收到的数据长度 PCD_EP_Read (bEpAddr, pBufferPointer, DataLength); //使用PCD接口层函数读取选中的端口 #endif /* STM32F10X_CL */ return DataLength; //返回接收到的数据长度
}
STM32 usb_mem.c和usb_sil.c文件的分析的更多相关文章
- STM32入门系列-库目录及文件介绍
已经介绍了过了CMSIS标准,ST公司按照这个标准设计了一套基于STM32F10x的固件库,我们可以直接在ST公司的官网进行下载,现在给大家STM32最新固件库v3.5,在网盘上给大家提供了下载包,链 ...
- PE文件学习系列笔记四-C++实现PE文件的分析
合肥程序员群:49313181. 合肥实名程序员群:128131462 (不愿透露姓名和信息者勿加入) Q Q:408365330 E-Mail:egojit@qq.com 综述: 首 ...
- 教程-Delphi资源文件(全面分析于使用)
Delphi资源文件(全面分析之位图.光标.图标.AVI.JPEG.Wave) 几乎每个Windows应用程序都使用图标.图片.光标等资源.资源是程序的一部分,但是它是不可执行代码.下面我们就详细 ...
- 【JVM】Java中的JavaCore/HeapDump文件及其分析方法
产生时间 Java程序运行时,有时会产生JavaCore及HeapDump文件,它一般发生于Java程序遇到致命问题的情况下. 有时致命问题发生后,Java应用不会死掉,还能继续运行: 但有时致命问题 ...
- 对stm32f373XX的startup.s的文件的分析
;******************** (C) COPYRIGHT 2012 STMicroelectronics ********************;* File Name : start ...
- Android.mk文件简单分析
Android.mk文件简单分析 一个Android.mk文件用来向编译系统描写叙述须要编译的源码.详细来说:该文件是GNUMakefile的一小部分.会被编译系统解析一次或多次. 能够在每个Andr ...
- /etc/rc.d/init.d/functions文件详细分析
/etc/rc.d/init.d/functions文件详细分析 functions这个脚本是给/etc/init.d里边的文件使用的(可理解为全局文件). 提供了一些基础的功能,看看里边究竟有些什么 ...
- opencart 单入口文件简单分析
opencart 单入口文件简单分析 opencart是基于mvcl的商城系统,据说是一个外国有人单独开发.比较牛叉.但是又不大符合国人习惯,目前国内opencart社区也是不少. 简单分析了下单 ...
- quick-cocos2d-x教程3:程序框架内文件夹分析之docs文件夹
如今我们分析框架中的docs文件夹.看看这个文档文件夹中,究竟放了那些对我们实用的东西. docs文件夹分析 UPGRADE_TO_2_2_3.md 就是讲升级的变化.详细说明:quick-cocos ...
随机推荐
- 如何在Linux上面安装GCC 4.1.2
安装步骤: 1.首先下载GCC 4.1.2的source code package: $ wget http://mirrors.ustc.edu.cn/gnu/gcc/gcc-4.1.2/gcc-4 ...
- js获取checkbox中所有选中值及input后面所跟的文本
<html> <head> <meta http-equiv="Content-Type" content="text/html; char ...
- [Unity-6] GameObject有时候渲染不出来
问题描写叙述:在做游戏的过程中遇到了这样一个问题.一个怪物,假设让他出如今屏幕的中央是没问题的,可是让他出如今屏幕的边缘的位置发现他没有出现. 问题原因:经过检查发现,我给这个GameObject加入 ...
- [Javascipt] Immediately-Invoker 2
Now the people at Poplar Puzzles would like you to treat an array of functions like a Queue, passing ...
- 给MySQL中某表增加一个新字段,设为主键值为自动增长。
alter table test_tb add ID int(10) primary key AUTO_INCREMENT; 设定完成后,原有记录的该字段会增加并自动设上值.以后的值会在已有记录的最 ...
- Solr添加SolrDocument报错
今天写了一个solr入库接口,使用了SolrServer.addBean接口,结果报错:Caused by: org.apache.solr.client.solrj.impl.HttpSolrSer ...
- WebService SOAP、Restful和HTTP(post/get)请求区别
web service(SOAP) Webservice的一个最基本的目的就是提供在各个不同平台的不同应用系统的协同工作能力. Web service 就是一个应用程序,它向外界暴露出一个能够通过We ...
- Java中的软(弱)引用
一.Java中的强.软.弱.虚引用 在JDK中我们能够看到有一个java.lang.ref的包.这个包中就是Java中实现强.软.弱.虚引用的包,例如以下: PhantomReference 虚引用: ...
- Cannot load supported formats: Cannot run program "svn"
Cannot load supported formats: Cannot run program "svn" CreateTime--2018年4月26日11:32:37 A ...
- 30、java中递归算法
1.已知有一个数列f(0)=1,f(1)=4,f(n+2)=2*f(n+1)+f(n),其中n是大于0的正数,求f(10)的值. 分析:设x=n+2 => f(x)=2*f(n-1)+f(n-2 ...