SD驱动开发问题:客户端驱动加载成功,但盘符显示不出来

liuysheng 2009-11-04 02:02:32
加精
SD驱动开发问题:客户端驱动加载成功,但盘符显示不出来???

有哪位牛人做过SD驱动吗?帮忙分析一下,谢谢!
详细现象:
1、 硬件平台是自己实验室研发的,OS为WINCE600;
2、 总线驱动、主控制驱动都能成功加载
——SD命令发送也成功:
CMD5-CMD0-CMD55+ACMD41-CMD0-CMD55+ACMD41-CMD2-CMD3-CMD9-CMD13-CMD7-CMD55+ACMD51-CMD55+ACMD42-CMD55+ACMD6。
3、客户端驱动加载成功,并且,我感觉系统也识别到了SD卡,由如下两点可知:
1>~_~_~_SDMemory: Idle Timeout Wakeup after 2000 MS //此行信息是idlethread线程中的信息,
2>在内存管理器中,能看到有SD的内存空间,当然,此处也有一个问题,我的SD卡是1G的,而内存管理器中显示是512M的??
4、分区驱动(partition Driver)组件也加了;;;;

希望有牛人帮忙指点,谢谢!!
...全文
1252 116 打赏 收藏 转发到动态 举报
写回复
用AI写文章
116 条回复
切换为时间正序
请发表友善的回复…
发表回复
liuysheng 2009-12-26
  • 打赏
  • 举报
回复
终于结帖可以了。。。呵呵!谢谢各位牛哥的指点、多谢朋友的关注,这几天终于将SD主控制驱动测试的差不多了,尽量稳定性,依然是个问题。。。但是,毕竟问题解决了:SD盘符出来了,热插拔实现了,读写也可以,在存储管理器中的加载卸载、格式化都可以用了。。。
谢谢大家,由于分值有限,,,只能大家一些分着点,希望朋友们见谅~~~
问题总结如下:
1、DMA配置很关键,特别是CRC、完成位等,当然,我现在弄的中断模式来使用DMA,还是不怎么稳定,不过,扫描方式,还可以的;
2、时钟,开始时,尽量调低,几位朋友提到过,等问题解决后,SD1.1的话,调到20MHZ左右比较好些
3、这次硬件一出了点小问题,CD寄存器不可用,后来,自己测时,才知道,只能通过GPIO接口,显别电平来获知是否有卡在内;
4、特别得关注CMD51命令,因为是第一次用DMA传小量数据,再者,就是CMD18,是第一次,用DMA传大块数据;
5、在SD启动前,会扫描一次整个SD卡,这点,我一开始,不大理解。。。
6、我开始用的NK启动方式为NOR,成功很低,后来换成了SD启动方式,基本上能一直启动,这点希望有借鉴的价值;
7、再次感谢大家,同时感谢我师兄。。。谢谢你们的帮助,谢谢
kyzf 2009-12-16
  • 打赏
  • 举报
回复
受益了
liuysheng 2009-12-16
  • 打赏
  • 举报
回复
已进入测试阶段,谢谢各位朋友的关注,寄希望能在近期测试通过,致谢!!
lihaixin 2009-12-12
  • 打赏
  • 举报
回复
什么原因啊,LZ,说一说,给后来者点个灯
liuysheng 2009-12-12
  • 打赏
  • 举报
回复
目前还在进一步调度、测试之中,结帖时,会尽量详细说明~~~另外,还得继续实现:热插拔、写保护,
希望各位能给点热插拔、写保护方面的建议,致谢!!
arm9linuxpp 2009-12-11
  • 打赏
  • 举报
回复
楼主的经历应该放在DMA上面,估计问题就出在DMA部分
liuysheng 2009-12-11
  • 打赏
  • 举报
回复
谢谢关注!!!现在盘符出来了,不过,时钟还有些问题,有时会一下子提到40M,过会一下子,马上就降下来了。。。时钟~~~~~希望能得到各位牛哥的继续帮助,

另外,希望各位能给点热插拔、写保护方面的建议,致谢!!
cdy2003 2009-12-10
  • 打赏
  • 举报
回复
比较专业,我顶
aadss 2009-12-10
  • 打赏
  • 举报
回复
友情帮顶
liuysheng 2009-12-10
  • 打赏
  • 举报
回复
大家给些实在的建议啊,DBR出来了,不过,还有小部分不正确。。。刚弄了个NK,ICE又出现问题了,无语了
ckl881003 2009-12-09
  • 打赏
  • 举报
回复
关注。。
shengyu137 2009-12-09
  • 打赏
  • 举报
回复
很好,值得借鉴。
yangzf123 2009-12-09
  • 打赏
  • 举报
回复
也是移植的S3C2440的。。修改后如下:
;------------ SDHC Driver -------------------------------------------------
; @CESYSGEN IF CE_MODULES_SDBUS
IF BSP_NOSDHC !
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\SDHC_SEP0718]
"Order"=dword:21
"Dll"="SEP0718_sdhc.dll"
"Prefix"="SDH"

"DMAChannel"=dword:0 ; DMA channel to use. Set to 0xffffffff to disable DMA
"DMAIrq"=dword:20
"DMA_IST_Priority"=dword:96

"SDIOIrq"=dword:14
"SDIO_IST_Priority"=dword:97

"PollingTimeout"=dword:100 ; 100 ms
"CardDetect_Thread_Priority"=dword:98

"CardDetectGPIO"="I" ; card detect on GPI6 091019_LYS
"CardDetectMask"=dword:1 ;SD_CDETECT[0] card detect 091020_LYS
"CardDetectFlag"=dword:0
"CardDetectControlMask"=dword:40 ;PORTI_GPIOSEL[6] card detect 091020_LYS
"CardDetectControlFlag"=dword:40 ;PORTI_GPIOSEL[6] card detect 091020_LYS
"CardDetectPullupMask"=dword:fffffeff
"CardDetectPullupFlag"=dword:100

"CardReadWriteGPIO"="E" ; card R/W on GPE2 091019_LYS
"CardReadWriteMask"=dword:100
"CardReadWriteFlag"=dword:100
"CardReadWriteControlMask"=dword:fffcffff
"CardReadWriteControlFlag"=dword:0
"CardReadWritePullupMask"=dword:fffffeff
"CardReadWritePullupFlag"=dword:100

"HandleBusyFinishOnCommand38"=dword:1
"DmaTransferTimeoutFactor"=dword:8
"DmaTransferTimeoutConstant"=dword:3000
ENDIF BSP_NOSDHC !
; @CESYSGEN ENDIF CE_MODULES_SDBUS
liuysheng 2009-12-09
  • 打赏
  • 举报
回复
现在传输的DBR结尾出现了“55aa”但是,中间还是大面积的0000。。。

而且时钟一直降不下来,,之前用示波器测过,会在正常值以下的。。同样的代码,现在测的结果是:CMD17时,时钟到了40M。。。明显是不对的
设置时钟的函数如下:
DWORD CSDIOControllerBase::SetClockRate(DWORD dwClockRate)
{
RETAILMSG(DEBUG_SD, (TEXT("-/-/-/SDHCB SetClockRate start, dwClockRate = 0x%x\n"),dwClockRate));
vm_pSDIReg->SD_APBCLKDIV = 0x2; //LYS 0x10


RETAILMSG(DEBUG_SD, (TEXT("In SetClockRate SD_APBCLKDIV = 0x%x,\n"),(DWORD)vm_pSDIReg->SD_APBCLKDIV));
/************
Right now in SEP0718 only support clock 25MHz.If set clk 25Mhz,it will tell kernel error!!!
***************/
DWORD dwMaxSDClk = APBCLK/((DWORD)vm_pSDIReg->SD_APBCLKDIV); //090404 XJW Add
RETAILMSG(DEBUG_SD, (TEXT("In SetClockRate dwMaxSDClk = 0x%x,\n"),dwMaxSDClk));
UINT32 temp; //090404 XJW Add
DWORD dwActualRate;
DWORD dwPrescale;
if((dwClockRate < 0) || (dwClockRate > SD_FULL_SPEED_RATE))
{
RETAILMSG(DEBUG_SD, (TEXT("SDHCDriver:SetClockRate() - invalid clock rate %d !\r\n"), dwClockRate));
goto DONE;
}

RETAILMSG(DEBUG_SD, (TEXT("dwClockRate=%8d\n"),(DWORD)dwClockRate));

//----- 2. Calculate the clock rate -----
// NOTE: Using the prescale value, the clock's baud rate is
// determined as follows: baud_rate = (PCLK / 2 / (prescale + 1))
//
// Hence, the prescale value can be computed as follows:
// prescale = ((PCLK / (2*baud_rate)) - 1
/************
Here dwMaxSDClk is not sure,may call kernel error
***************/
dwPrescale = dwClockRate ? ( (dwMaxSDClk / (2*dwClockRate))) : 0xff;
RETAILMSG(DEBUG_SD, (TEXT("In SetClockRate dwPrescale = 0x%x,\n"),dwPrescale));
if ((dwClockRate<=dwMaxSDClk)&&(dwClockRate>(dwMaxSDClk/2)))
{
RETAILMSG(DEBUG_SD, (TEXT("SDHCDriver:SetClockRate() - 舍入\n")));
dwPrescale = 0x0;
}
dwActualRate = dwPrescale ? (dwMaxSDClk / ( dwPrescale *2 )) :(dwMaxSDClk);
RETAILMSG(DEBUG_SD, (TEXT("In SetClockRate dwActualRate = 0x%x,\n"),dwActualRate));
// adjust the rate if too high
if( dwActualRate > dwClockRate )
{
dwPrescale++; // set to next supported lower rate
// recalculate the actual rate
dwActualRate = dwPrescale ? (dwMaxSDClk / ( dwPrescale *2 )) :(dwMaxSDClk);
RETAILMSG(DEBUG_SD, (TEXT("In adjust the rate if too high dwActualRate = 0x%x,\n"),dwActualRate));
}

// adjust the rate if too low
if( dwPrescale > 0xff )
{
dwPrescale = 0xff; // set to slowest supported rate
// recalculate the actual rate
dwActualRate = dwPrescale ? (dwMaxSDClk / ( dwPrescale *2 )) :(dwMaxSDClk);
RETAILMSG(DEBUG_SD, (TEXT("adjust the rate if too low dwActualRate = 0x%x,\n"),dwActualRate));
}

RETAILMSG(DEBUG_SD, (TEXT("******SetClockRate dwPrescale = 0x%x; dwActualRate = 0x%x\n"), dwPrescale, dwActualRate));
RETAILMSG(DEBUG_SD, (TEXT("Before fClockIsRunning SD_CLKENA = 0x%x\n"),(DWORD)vm_pSDIReg->SD_CLKENA));
BOOL fClockIsRunning = Is_SDI_Clock_Running();
RETAILMSG(DEBUG_SD, (TEXT("After fClockIsRunning SD_CLKENA = 0x%x\n"),(DWORD)vm_pSDIReg->SD_CLKENA));
RETAILMSG(DEBUG_SD, (TEXT(" fClockIsRunning= %d\n"), fClockIsRunning));

//----- 2. Make sure the clock is stopped -----
if( fClockIsRunning )
{
RETAILMSG(DEBUG_SD, (TEXT("adjust the rate if too low Stop_SDI_Clock\n")));
Stop_SDI_Clock();
}

// set the clock domain //090404 XJW Add
vm_pSDIReg->SD_CTYPE = 0x0; //set the card width as 1 bits
vm_pSDIReg->SD_CLKDIV =dwPrescale ; //set the clock frequency to less than 400K,25/(2*400K)=32
vm_pSDIReg->SD_CLKSRC = 0x0; //set the clock source
vm_pSDIReg->SD_CMD = 0x80202000; //update_clock_register_only
do
{
temp = ( vm_pSDIReg->SD_CMD ) & 0x80000000;
}while( temp == 0x80000000 ); //wait the command taken by CIU

RETAILMSG(DEBUG_SD, (TEXT("SDHCD:SetClockRate() - Clock rate set to %d Hz\n"), dwActualRate));

if( fClockIsRunning )
{
RETAILMSG(DEBUG_SD, (TEXT("adjust the rate if too low Start_SDI_Clock\n")));
Start_SDI_Clock();
}

// remember the current clock rate
m_dwClockRate = dwActualRate;

DONE:
RETAILMSG(DEBUG_SD, (TEXT("SDHCD:SetClockRate() -DONE- Clock rate set to %d Hz\n"), dwActualRate));
return m_dwClockRate;

}
hls_1980 2009-12-09
  • 打赏
  • 举报
回复
啊啊啊啊啊啊啊
oldCanISoftware 2009-12-09
  • 打赏
  • 举报
回复
up
xz22503c 2009-12-08
  • 打赏
  • 举报
回复
我整理一下,一会帖出来
skywalk_620802 2009-12-08
  • 打赏
  • 举报
回复
很有用的资料
liuhaifeng1976 2009-12-08
  • 打赏
  • 举报
回复
职业帮顶
cdcjk 2009-12-08
  • 打赏
  • 举报
回复
学习了
加载更多回复(95)

19,500

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 嵌入开发(WinCE)
社区管理员
  • 嵌入开发(WinCE)社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧