现在传输的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/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;
}