i.MX27支持8GBSDHC卡驱动修改

转载请注明原帖地址及出自ARMCE,此为ARMCE定制原创稿

文章来源:http://www.armce.com/bbs/thread-885-1-1.html

最近需要给mx27加上SDHC驱动以支持SDHC的SD卡
网上许多关于2440支持SDHC的文章,借鉴很多,但是由于MX27驱动的特殊结构,需要做更多改动,详细如下:

平台wince6 R3

其实原理上都是一样:
1 使用SDBUS2驱动
2 底层增加对ResponseR7的支持

但是MX27驱动上有些特别的地方
首先是使用SDBUS2的驱动,我建议大家把这个驱动拷贝出来在bsp的drivers目录下编译,我觉得这样比较好,方便日后修改。
而且我重命名了SDBUS2的驱动
1 拷贝PUBLIC/COMMON/OAK/DRIVERS/SDCARD/SDBUS文件夹到bps的drivers目录
2 修改sources文件

 

 

 

  1. SYNCHRONIZE_BLOCK=1
  2. TARGETNAME=osdbus
  3. TARGETDEFNAME=SDBus2
  4. DEFFILE=$(TARGETDEFNAME).def
  5. TARGETTYPE=DYNLINK
  6. RELEASETYPE=PLATFORM
  7. DLLENTRY=_DllEntryCRTStartup
  8. SOURCES = sdbusreq.cpp /
  9.         sddevice.cpp /
  10.         sdbus.cpp /
  11.         sdslot.cpp /
  12.         sdclient.cpp /
  13.         sddevinf.cpp /
  14.         sdiofeat.cpp /
  15.         sdworki.cpp /
  16.         sddebug.cpp /
  17. TARGETLIBS=                                           /
  18.   $(_SYSGENOAKROOT)/lib/$(_CPUINDPATH)/defbuslib.lib  /
  19.   $(_SYSGENSDKROOT)/lib/$(_CPUINDPATH)/coredll.lib    /
  20.   $(_SYSGENOAKROOT)/lib/$(_CPUINDPATH)/ceddk.lib  
复制代码

注意这里我将这个dll命名为osdbus了,而不是sdbus或者sdbus2,以示区别

然后编译一下sdbus2目录,应该可以通过

2 在bsp的drivers目录的dirs下增加编译sdbus2目录,放在sdhc目录前面

3 修改PLATFORM/COMMON/SRC/SOC/FREESCALE/MX27_FSL_V1/DRIVERS/SDHC/sources文件

  1. TARGETNAME=sdhc_mx27_fsl_v1
  2. TARGETTYPE=LIBRARY
  3. INCLUDES= /
  4.     ../../inc; /
  5.     ../inc; /
  6.     $(_TARGETPLATROOT)/SRC/DRIVERS/sdbus2; /
  7.     ../../../common_fsl_v1/inc;
  8. CDEFINES=$(CDEFINES) -DCEDDK_USEDDKMACRO
  9. SOURCES = main.cpp /
  10.           sdcontrol.cpp
复制代码

这里主要将头文件目录改为$(_TARGETPLATROOT)/SRC/DRIVERS/sdbus2,而不是老的sdbus驱动

4 修改PLATFORM/COMMON/SRC/SOC/FREESCALE/MX27_FSL_V1/DRIVERS/INC/sdhc.h

  1. #include "SDCardDDK.h"
  2. //#include "sdbusdriver.h"
  3. #include "SDHCD.h"
复制代码

5 修改PLATFORM/COMMON/SRC/SOC/FREESCALE/MX27_FSL_V1/DRIVERS/SDHC/sdcontrol.cpp

  1. #include "csp.h"
  2. #include "sdhc.h"
  3. #include "sdbus.hpp"
  4. #include "sddevice.hpp"
复制代码

在SDHBusRequestHandler函数中增加对ResponseR7的支持

  1. case ResponseR5:
  2.     case ResponseR6:
  3.     case ResponseR7:
  4.         CSP_BITFINS(cmdatRegister, SDHC_CDC_FORMAT, 1);
复制代码

6 编译PLATFORM/COMMON/SRC/SOC/FREESCALE/MX27_FSL_V1/DRIVERS/SDHC目录
会发现有错误
原因在于sdcontrol.cpp中的SDControllerBusyWaitResponse函数中调用了

  1. cmdArg = (((DWORD)((SDDCGetClientDeviceFromHandle(pRequest->hDevice))->RelativeAddress)) << 16);
复制代码

这个函数的目的是查询卡的状态,等待卡busy结束,但是需要用到卡的地址
这里问题就来了,因为卡的地址(RCA)以前老的sdbus下是通过结构体获得的,现在新的sdbus2找不到这个结构体定义了,怎么把这个地址获得呢?
先考虑一个其他办法
把这个函数屏蔽掉

编译通过

7 修改PLATFORM/iMX27ADS/SRC/DRIVERS/SDHC/sources文件

  1. SOURCELIBS= /
  2.      $(_COMMONOAKROOT)/lib/$(_CPUINDPATH)/sdcardlib.lib /
  3.      $(_COMMONOAKROOT)/lib/$(_CPUINDPATH)/sdhclib.lib /
  4.      $(_TARGETPLATROOT)/lib/$(_CPUINDPATH)/osdbus.lib /
  5.      $(_PLATCOMMONLIB)/$(_CPUINDPATH)/sdhc_mx27_fsl_v1.lib
复制代码

增加osdbus.lib,去掉sdbus.lib

8 编译PLATFORM/iMX27ADS/SRC/DRIVERS/SDHC通过

9 修改platform.bib,增加

  1. #if defined IMGSDBUS2
  2. ; @CESYSGEN IF CE_MODULES_SDBUS2
  3.    sdbus.dll      $(_FLATRELEASEDIR)/osdbus.dll                 NK  SHK
  4. ; @CESYSGEN ENDIF CE_MODULES_SDBUS2
  5. #else
  6. ; @CESYSGEN IF CE_MODULES_SDBUS
  7.    sdbus.dll      $(_FLATRELEASEDIR)/sdbus.dll                  NK  SHK
  8. ; @CESYSGEN ENDIF CE_MODULES_SDBUS
  9. #endif
复制代码

增加对新的sdbus驱动支持

10 在vs2005的项目组件选择中,钩上


11 sysgen一下

进入系统会发现sdhc卡可以识别了,但是有一个问题,在写sdhc卡后经常出现死机

这时候我们需要回头修改下那个屏蔽的函数,就是说我们不能绕过等待卡busy的那个函数
关键问题就是如何获得sd卡地址
大家看这个函数
sdcontrol.cpp中的SDHBusRequestHandler
这里是处理所有命令的地方
在sd卡识别流程过程中,在激活卡的时候会有这个命令SD_CMD_SELECT_DESELECT_CARD,这里会将RCA作为参数传递进来
到这里大家就了解了,只要我们在这里截获SD_CMD_SELECT_DESELECT_CARD的参数,我们就能获得RCA了
而且SDControllerBusyWaitResponse这个函数只有SDHBusRequestHandler会调用,而且条件是

  1. if((pController->LastResponedR1b == ResponseR1b) &&
  2.                                         (pRequest->TransferClass != SD_COMMAND))
  3.     {
  4.                 DEBUGMSG(ZONE_INFO, (TEXT("SDHBusRequestHandler: wait for busy!/r/n")));
  5.                 status = SDControllerBusyWaitResponse(pController);
  6.                 if(status != SD_API_STATUS_SUCCESS)
  7.                 {
  8.                         SDHCDIndicateBusRequestComplete(pController->pHCContext, pRequest, SD_API_STATUS_DEVICE_BUSY);
  9.                         return SD_API_STATUS_DEVICE_BUSY;
  10.                 }
  11.     }
复制代码

就是说在传输模式才会用这个函数
而SD_CMD_SELECT_DESELECT_CARD命令是进入传输模式的必经之路,所以可以在传输模式之前获得RCA
添加一个全局变量g_wRCA
修改SDHBusRequestHandler,在入口处增加

  1. if(0 == g_wRCA) {
  2.         if(SD_CMD_SELECT_DESELECT_CARD == pRequest->CommandCode) {
  3.             g_wRCA = (WORD)(((pRequest->CommandArgument) & 0xffff0000) >> 16);
  4.             RETAILMSG(1, (TEXT("SDHBusRequestHandler: Get RCA = 0x%X!/r/n"), g_wRCA));
  5.         }
  6.     }
复制代码

然后修改SDControllerBusyWaitResponse

  1. if(0 == g_wRCA) {
  2.         return SD_API_STATUS_SUCCESS;
  3.     }
  4.    // return status;
  5.     DEBUGMSG(ZONE_FUNCTION, (TEXT("+SDControllerBusyWaitResponse for SDHC/MMC Controller driver/r/n")));
  6.     retryCount = DEFAULT_BUS_REQUEST_RETRY_COUNT;
  7.     pRequest = SDHCDGetAndLockCurrentRequest(pHCDevice->pHCContext, 0);
  8.     cmdArg = g_wRCA << 16;
复制代码

别忘了还要去在适当的地方清楚RCA的值,因为你的SD卡槽可能会换SD卡
我是在SDCardDetectIstThread中加的
只要检测到SD卡中断,无论是插入还是拔出,都将g_wRCA清零

  1. if (WaitForSingleObject(hCardInsertInterruptEvent, INFINITE) != WAIT_OBJECT_0)
  2.         {
  3.             ERRORMSG(ZONE_ERROR, (TEXT("SDCardDetectIstThread: Wait Failed!/r/n")));
  4.             return 0;
  5.         }
  6.         g_wRCA = 0;  
复制代码

好了,所有的都重新编译,这下子就正常了

对于CE5应该也是差不多的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值