📄 sdhcslot.cpp
字号:
RETAILMSG(0,(TEXT("Before NORMAL_INT_STATUS_DMA : 0x%x\r\n"),ReadWord(SDHC_NORMAL_INT_STATUS))); // jylee
WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE, (ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) & ~(NORMAL_INT_STATUS_DMA)));
WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE,(ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) & ~(NORMAL_INT_STATUS_DMA)));
do{
WriteWord(SDHC_NORMAL_INT_STATUS, NORMAL_INT_STATUS_DMA);
RETAILMSG(0,(TEXT("Clear DMA interrupt : 0x%x\r\n"),ReadWord(SDHC_NORMAL_INT_STATUS))); // jylee
}while(ReadWord(SDHC_NORMAL_INT_STATUS) & NORMAL_INT_STATUS_DMA);
WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE, (ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) | NORMAL_INT_STATUS_DMA));
WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE, (ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) | NORMAL_INT_STATUS_DMA));
RETAILMSG(0,(TEXT("After NORMAL_INT_STATUS_DMA : 0x%x\r\n"),ReadWord(SDHC_NORMAL_INT_STATUS))); // jylee
RETAILMSG(0,(TEXT("-HandleRemoval\r\n"))); // jylee
// To diable the Data CRC error interrupt
WriteWord(SDHC_ERROR_INT_SIGNAL_ENABLE,0);
//WriteWord(SDHC_ERROR_INT_STATUS_ENABLE,0);
do
{
WriteWord(SDHC_ERROR_INT_STATUS,wErrIntStatus);
}while(ReadWord(SDHC_ERROR_INT_STATUS));
WriteWord(SDHC_ERROR_INT_SIGNAL_ENABLE,wErrIntSignalEn);
//WriteWord(SDHC_ERROR_INT_STATUS_ENABLE, wErrIntStatusEn);
RETAILMSG(CRC_DEBUG,(TEXT("ERROR_INT_STATUS : 0x%x\r\n"),ReadWord(SDHC_ERROR_INT_STATUS)));
}
v_gBspArgs->g_SDCardState = CARD_REMOVED;
SetEvent( v_gBspArgs->g_SDCardDetectEvent );
}
VOID
CSDHCSlotBase::HandleInsertion(
)
{
RETAILMSG(0,(TEXT("+HandleInsertion\r\n"))); // jylee
DWORD dwClockRate = SD_DEFAULT_CARD_ID_CLOCK_RATE;
WORD wErrIntSignalEn = ReadWord(SDHC_ERROR_INT_SIGNAL_ENABLE);
WORD wErrIntStatusEn = ReadWord(SDHC_ERROR_INT_STATUS_ENABLE);
g_initialInsertion = 0;
m_fCardPresent = TRUE;
// Apply the initial voltage to the card.
SetVoltage(GetMaxVddWindow());
// Send at least 74 clocks to the card over the course of at least 1 ms
// with allowance for power supply ramp-up time. (SD Phys Layer 6.4)
// Note that power supply ramp-up time occurs in SetVoltage().
RETAILMSG(0,(TEXT("+HandleInsertion()->SetClockRate(&dwClockRate)\n"))); // jylee
SetClockRate(&dwClockRate);
SDClockOn();
DWORD dwSleepMs = (74 / (dwClockRate / 1000)) + 1;
Sleep(dwSleepMs);
//while(1);
SDClockOff();
if (GetCapabilities().bits.DMA) {
RETAILMSG(0,(TEXT("Use DMA\n")));
PHYSICAL_ADDRESS SystemAddr = { 0 };
PVOID pvBuffer = AllocPhysBuffer(CB_DMA_BUFFER, &SystemAddr.LowPart);
if (pvBuffer) {
PHYSICAL_ADDRESS BusAddr;
// Translate physical address to logical (bus-relative) address.
BOOL fSuccess = TranslateSystemAddr(m_hBusAccess, m_interfaceType,
m_dwBusNumber, SystemAddr, &BusAddr);
if (fSuccess) {
RETAILMSG(0,(TEXT("Use DMA Success.\n")));
m_pbDmaBuffer= (PBYTE) pvBuffer;
m_paDmaBuffer = BusAddr.LowPart;
}
else {
// If we fail, we will simply fall back to PIO mode
FreePhysBuffer(pvBuffer);
}
}
}
// Interrupts are not enabled on a newly inserted card.
EnableSDIOInterrupts(FALSE);
// Indicate device arrival
IndicateSlotStateChange(DeviceInserted);
#if 1
WriteWord(SDHC_ERROR_INT_SIGNAL_ENABLE, (wErrIntSignalEn | (0x20))); //Command and Data CRC error disable
WriteWord(SDHC_ERROR_INT_STATUS_ENABLE, (wErrIntStatusEn | (0x20))); //Command and Data CRC error disable
#endif
RETAILMSG(0,(TEXT("HandleInsertion\r\n"))); // jylee
v_gBspArgs->g_SDCardState = CARD_INSERTED;
SetEvent( v_gBspArgs->g_SDCardDetectEvent );
}
BOOL
CSDHCSlotBase::HandleCommandComplete(
)
{
SETFNAME();
PSD_BUS_REQUEST pRequest;
BOOL fRet = FALSE;
int count = 0 ;
RETAILMSG(CRC_DEBUG,(TEXT("CSDHCSlotBase:: +HandleCommandComplete\r\n")));
// get the current request
pRequest = GetAndLockCurrentRequest();
DEBUGCHK(m_dwReadyInts == 0);
if (pRequest) {
RETAILMSG(0,(TEXT("CSDHCSlotBase::HandleCommandComplete pRequest\n")));
DEBUGCHK(pRequest->HCParam == 0);
SD_API_STATUS transferStatus = SD_API_STATUS_SUCCESS;
if (NoResponse != pRequest->CommandResponse.ResponseType) {
// Copy response over to request structure. Note that this is a
// bus driver buffer, so we do not need to SetProcPermissions
// or __try/__except.
UNALIGNED DWORD *pdwResponseBuffer = (PDWORD) (pRequest->CommandResponse.ResponseBuffer + 1); // Skip CRC
WORD wCommand = ReadWord(SDHC_COMMAND);
if ((wCommand & CMD_RESPONSE_R1B_R5B) == CMD_RESPONSE_R1B_R5B) {
// wait for Transfer Complete status, which indicate the busy wait is over.
// we should not handle this TXN_COMPLETE interrupt in IST in this case
#if 0
RETAILMSG(CRC_DEBUG,(TEXT("Waiting for RESPONSE_R1B_R5B\r\n")));
BOOL fSuccess = WaitForReg<WORD>(&CSDHCSlotBase::ReadWord, SDHC_NORMAL_INT_STATUS, NORMAL_INT_STATUS_TRX_COMPLETE, NORMAL_INT_STATUS_TRX_COMPLETE, 5000);
RETAILMSG(CRC_DEBUG, (_T("%s Go waiting for NORMAL_INT_STATUS_TRX_COMPLETE\r\n"), pszFname));
if (!fSuccess) {
RETAILMSG(1, (_T("%s Timeout waiting for NORMAL_INT_STATUS_TRX_COMPLETE\r\n"), pszFname));
DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s Timeout waiting for NORMAL_INT_STATUS_TRX_COMPLETE\r\n"),pszFname));
transferStatus = SD_API_STATUS_RESPONSE_TIMEOUT;
}
RETAILMSG(0,(TEXT("CSDHCSlotBase::HandleCommandComplete SoftwareReset\n")));
#endif
// Reset cmd and dat circuits
SoftwareReset(SOFT_RESET_CMD | SOFT_RESET_DAT);
}
pdwResponseBuffer[0] = ReadDword(SDHC_R0);
RETAILMSG(SDIO_DEBUG,(TEXT("Response : 0x%X\r\n"),pdwResponseBuffer[0]));
if (pRequest->CommandResponse.ResponseType == ResponseR2) {
pdwResponseBuffer[1] = ReadDword(SDHC_R2);
pdwResponseBuffer[2] = ReadDword(SDHC_R4);
pdwResponseBuffer[3] = ReadDword(SDHC_R6);
RETAILMSG(0,(TEXT("pdwResponseBuffer[1]= 0x%X\r\n"),pdwResponseBuffer[1]));
RETAILMSG(0,(TEXT("pdwResponseBuffer[2]= 0x%X\r\n"),pdwResponseBuffer[2]));
RETAILMSG(0,(TEXT("pdwResponseBuffer[3]= 0x%X\r\n"),pdwResponseBuffer[3]));
}
//2007.10.05 D.Baek
// CMD10
#if 0
if(pRequest->CommandCode == 10)
{
RETAILMSG(1,(TEXT("Manufacture ID : 0x%d\r\n"),pdwResponseBuffer[3]));
}
#endif
#if 0
if(pRequest->CommandCode == 13 || pRequest->CommandCode == 9 || pRequest->CommandCode == 6 || pRequest->CommandCode == 8)
{
RETAILMSG(1,(TEXT("Response : 0x%x\r\n"),pdwResponseBuffer[0]));
}
#endif
}
// check for command/response only
if (TRANSFER_IS_COMMAND_ONLY(pRequest)) {
IndicateBusRequestComplete(pRequest, transferStatus);
fRet = TRUE;
} else {
// handle data phase transfer
//pIOPreg->GPFDAT = (0x1<<7);
//WaitForReg<WORD>(&CSDHCSlotBase::ReadWord, SDHC_NORMAL_INT_STATUS, NORMAL_INT_STATUS_TRX_COMPLETE, NORMAL_INT_STATUS_TRX_COMPLETE);
pRequest->HCParam = 0;
fRet = FALSE;
}
}
// else request must have been canceled due to an error
//RETAILMSG(1,(TEXT("CSDHCSlotBase:: -HandleCommandComplete\r\n")));
return fRet;
}
VOID
CSDHCSlotBase::HandleErrors(
)
{
SD_API_STATUS status = SD_API_STATUS_SUCCESS;
RETAILMSG(0,(TEXT("[HSMMC] +HandleErrors\r\n")));
// 2007.06.10
// S/W workaround for the following problem
// Problem : When the interrupt is occurred, it is late to update the interrupt status register related to the interrupt source
while((ReadWord(SDHC_ERROR_INT_STATUS) ==0));
// get the current request
PSD_BUS_REQUEST pRequest = GetAndLockCurrentRequest();
//2007.10.10 D.Baek
if(pRequest == NULL)
{
status = SD_API_STATUS_UNSUCCESSFUL;
goto HandleErrors_Exit;
}
RETAILMSG(1,(TEXT("[HandleErrors] CMD %d\r\n"),pRequest->CommandCode));
WORD wErrorStatus = ReadWord(SDHC_ERROR_INT_STATUS);
RETAILMSG(CRC_DEBUG, (TEXT("CSDHCSlotBase::HandleErrors - ERROR INT STATUS=0x%04X\n\r"), wErrorStatus)); // jylee
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("HandleErrors - ERROR INT STATUS=0x%02X\n"), wErrorStatus));
if (pRequest) {
DumpRequest(pRequest, SDCARD_ZONE_ERROR);
}else
{
status = SD_API_STATUS_UNSUCCESSFUL;
goto HandleErrors_Exit;
}
DEBUGCHK( (wErrorStatus & ERR_INT_STATUS_VENDOR) == 0 );
if (wErrorStatus) {
if ( wErrorStatus & ERR_INT_STATUS_CMD_TIMEOUT ) {
RETAILMSG(1,(TEXT("CMD Timeout Error...\r\n")));
status = SD_API_STATUS_RESPONSE_TIMEOUT;
}
if ( wErrorStatus & ERR_INT_STATUS_CMD_CRC )
{
status = SD_API_STATUS_CRC_ERROR;
RETAILMSG(1,(TEXT("CMD CRC Error...\r\n")));
if ( wErrorStatus & ERR_INT_STATUS_CMD_TIMEOUT )
status = SD_API_STATUS_DEVICE_RESPONSE_ERROR;
}
if ( wErrorStatus & ERR_INT_STATUS_CMD_ENDBIT ) {
RETAILMSG(1,(TEXT("CMD ENDBIT Error...\r\n")));
status = SD_API_STATUS_RESPONSE_TIMEOUT;
}
if ( wErrorStatus & ERR_INT_STATUS_CMD_INDEX ) {
RETAILMSG(1,(TEXT("CMD INDEX Error...\r\n")));
status = SD_API_STATUS_DEVICE_RESPONSE_ERROR;
}
if ( wErrorStatus & ERR_INT_STATUS_DAT_TIMEOUT ) {
RETAILMSG(1,(TEXT("DAT Timeout Error...\r\n")));
status = SD_API_STATUS_DATA_TIMEOUT;
}
if ( wErrorStatus & ERR_INT_STATUS_DAT_CRC ) {
RETAILMSG(1,(TEXT("[HandleErrors] Data CRC Error...\r\n")));
status = SD_API_STATUS_CRC_ERROR;
}
if ( wErrorStatus & ERR_INT_STATUS_DAT_ENDBIT ) {
RETAILMSG(1,(TEXT("DAT END BIT Error...\r\n")));
status = SD_API_STATUS_DEVICE_RESPONSE_ERROR;
}
if ( wErrorStatus & ERR_INT_STATUS_BUS_POWER ) {
RETAILMSG(1,(TEXT("Bus Power Error...\r\n")));
status = SD_API_STATUS_DEVICE_RESPONSE_ERROR;
}
if ( wErrorStatus & ERR_INT_STATUS_AUTOCMD12 ) {
RETAILMSG(1,(TEXT("AUTOCMD12 Error...\r\n")));
status = SD_API_STATUS_DEVICE_RESPONSE_ERROR;
}
HandleErrors_Exit:
// Perform basic error recovery
WORD wErrIntSignal = ReadWord(SDHC_ERROR_INT_SIGNAL_ENABLE);
WriteWord(SDHC_ERROR_INT_SIGNAL_ENABLE, 0);
WORD wErrIntStatusEn = ReadWord(SDHC_ERROR_INT_STATUS_ENABLE);
WriteWord(SDHC_ERROR_INT_STATUS_ENABLE,0);
if (IS_CMD_LINE_ERROR(wErrorStatus)) {
// Reset CMD line
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("HandleErrors - Command line error (0x%x). Resetting CMD line.\r\n"), wErrorStatus));
RETAILMSG(1,(TEXT("CMD Line Error: 0x%x\r\n"),wErrorStatus)); // jylee
do
{
WriteWord(SDHC_ERROR_INT_STATUS, wErrorStatus);
} while(ReadWord(SDHC_ERROR_INT_STATUS) && (ReadWord(SDHC_NORMAL_INT_STATUS) & NORMAL_INT_STATUS_ERROR_INT));
RETAILMSG(1,(TEXT("CMD Line Error Status : 0x%x\r\n"),ReadWord(SDHC_ERROR_INT_STATUS)));
SoftwareReset(SOFT_RESET_CMD);
}
if (IS_DAT_LINE_ERROR(wErrorStatus)) {
// Reset DAT line
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("HandleErrors - Data line error (0x%x). Resetting DAT line.\r\n"), wErrorStatus));
RETAILMSG(CRC_DEBUG,(TEXT("Data Line Error(%x). Resetting DAT line\r\n"),wErrorStatus)); // jylee
// Make sure that the value of "Normal Interrupt Status register" is zero
do
{
WriteWord(SDHC_ERROR_INT_STATUS,wErrorStatus);
} while(ReadWord(SDHC_ERROR_INT_STATUS));
DWORD error_timeout = 5000;
do
{
WriteWord(SDHC_ERROR_INT_STATUS,wErrorStatus);
if((ReadWord(SDHC_NORMAL_INT_STATUS) & NORMAL_INT_STATUS_ERROR_INT))
{
error_timeout--;
}else
{
break;
}
if(error_timeout == 0)
{
RETAILMSG(1,(TEXT("[HandleErrors] Timeout...\r\n")));
}
}while(error_timeout != 0);
RETAILMSG(CRC_DEBUG,(TEXT("After while loop, Error Status : 0x%x\r\n"),ReadWord(SDHC_ERROR_INT_STATUS)));
SoftwareReset(SOFT_RESET_DAT);
}
RETAILMSG(CRC_DEBUG,(TEXT("SOFT_RESET_CMD : 0x%x\r\n"),ReadByte(SDHC_SOFT_RESET)));
#if 1
// clear all error status
do{
Write
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -