EFM32片内外设--USB MSD host framework

来源:互联网 发布:淘宝商城女装 编辑:程序博客网 时间:2024/05/21 21:37

近几日在帮客户移植USB MSD host的协议栈。发现一下子将100+K的代码从一颗M3移植到另外一颗M3,其实还真的不简单,主要是不同厂家的M3,外设区别太大了。辛苦将底层的硬件层描述完成之后,发现USB协议的写法相差过大。不得不对其进行了一些修改。言归正传,我们还是看一下EFM32的 MSD host的协议栈的框架吧。

1. 硬件原理图设计

参照reference manual中的USB章节内的HOST部分的原理框图即可。如下图所示:

只是这张图里面是用了一颗带电源管理的3V转5V的升压芯片,来作为管理VBUS的电源。如果板子上有5V,可以直接输入到电源管理芯片。

另外,就是要选择一颗基频为48MHz的晶振,用来给USB提供基准时钟源。

 

2.软件框架:

/* USB related data */
STATIC_UBUF(tmpBuf, 1024); // 定义一个给usb使用的缓冲区。 #define STATIC_UBUF( x, y ) EFM32_ALIGN( 4 ) static uint8_t x[((y)+3)&~3];

 

USBH_Init_TypeDef is = USBH_INIT_DEFAULT;

USBH_Init( &is ); //初始化USB协议栈

 

for (;;) 
{
  // Wait for ever on device attachment, 等待U盘插入

  // The second parameter is timeout in seconds, 0 means for ever
  if ( USBH_WaitForDeviceConnectionB( tmpBuf, 0 ) == USB_STATUS_OK )  
  {

    // Device is now connected and ready for enumeration ! //检测到U盘存在了

    if (MSDH_Init(tmpBuf, sizeof(tmpBuf)))
    {
           /* Initialize filesystem */
           FileResult = f_mount( 0, &Fatfs );
           if (FileResult  == FR_OK)

           {

                 //进行Fat文件操作

                 //FileResult  = f_open();

                 //FileResult  = f_read();

            }

       }

  }

  // Wait for disconnection
  while ( USBH_DeviceConnected() ){}

  // Disable USB peripheral, power down USB port.
  USBH_Stop();
}

单看如上的框架其实是比较简单的,但是还需要注意如下几点:

1.可以配置宏定义DEBUG_USB_API和USB_USE_PRINTF 来决定是否打开USB调试开关。一般调试时是不需要打开的。而默认提供的usbconfig.h头文件中会有如下的定义:

#ifndef NDEBUG
/* Debug USB API functions (illegal input parameters etc.)  */
#define DEBUG_USB_API       /* Uncomment to turn on  */

#define USB_USE_PRINTF      /* Uncomment to enable   */
#endif

因此在IAR中预先定义NDEBUG,来关闭USB调试输出。

 

2. USB协议栈中,默认使用了Timer0来作为基准时钟。如果要改动的话,需要修改em_usbtimer.c。就在这个文件的开头部分。在这个文件中,也实现了相应的中断响应函数。

 

3.如果需要过流保护的话,还需要在usbconfig.h里面,而外定义过流侦测的GPIO口。

#define USB_VBUSOVRCUR_PORT       gpioPortA
#define USB_VBUSOVRCUR_PIN        14
#define USB_VBUSOVRCUR_POLARITY   USB_VBUSOVRCUR_POLARITY_LOW

如果没有过流保护功能,则需要将USB_VBUSOVRCUR_PORT定义成USB_VBUSOVRCUR_PORT_NONE。

4.中断处理

在USB协议栈中,普遍使用了EMlib中的关中断函数和开中断函数,INT_Disable() 和 INT_Enable()。而不是直接使用__disable_irq()和__enable_irq()。

所以在主函数中,也请注意。

以上是目前的心得,可能还存在理解上的错误。也欢迎大家指出。

原创粉丝点击