zoukankan      html  css  js  c++  java
  • 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++;
      }
    }
    

      

    接下去是usb_sil.c文件,这个文件主要是简单接口层的初始化,和端点的读写操作函数。总共有3个函数:USB_SIL_Init();USB_SIL_Write();USB_SIL_Read()。
    USB_SIL_Init()函数初始化USB设备的IP和端点。该函数在usb_prop.c的CustomHID_init()中被调用,总之,就是初始化了
    /*******************************************************************************
    * 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;						//返回接收到的数据长度
    }
    

      

  • 相关阅读:
    网络管理和nmcli命令的使用——网络接口配置-bonding实验步骤
    raid组合优缺点介绍和创建LVM实验个人笔记
    磁盘分区就是这么简单,电脑小白都能看懂的磁盘分区教程!
    C盘优化之桌面移动法,拯救你爆满的C盘!
    电脑软件打开也有讲究,电脑软件打开方式总结!
    电脑使用建议大全,注意这些细节可以让你的电脑更好用!
    CentOS服务器apache绑定多个域名的方法
    CentOS 7使用yum安装PHP5.6
    PhpMyAdmin 配置文件现在需要一个短语密码的解决方法
    CentOs 7.*中配置安装phpMyAdmin的完整步骤记录
  • 原文地址:https://www.cnblogs.com/prayer521/p/6682484.html
Copyright © 2011-2022 走看看