📄 sdiocontrollerbase.cpp
字号:
{
pBlockCaps->WriteBlockSize = MINIMUM_BLOCK_TRANSFER_SIZE;
}
if (pBlockCaps->ReadBlockSize > MAXIMUM_BLOCK_TRANSFER_SIZE )
{
pBlockCaps->ReadBlockSize = MAXIMUM_BLOCK_TRANSFER_SIZE;
}
if (pBlockCaps->WriteBlockSize > MAXIMUM_BLOCK_TRANSFER_SIZE )
{
pBlockCaps->WriteBlockSize = MAXIMUM_BLOCK_TRANSFER_SIZE;
}
break;
case SDHCDGetSlotInfo:
DEBUGMSG (SDCARD_ZONE_INFO,(TEXT("SDHCDSlotOptionHandler option=SDHCDGetSlotInfo\r\n")));
RETAILMSG (WGH_SDCARD,(TEXT("SDHCDSlotOptionHandler option=SDHCDGetSlotInfo\r\n")));
if( OptionSize != sizeof(SDCARD_HC_SLOT_INFO) || pData == NULL )
{
status = SD_API_STATUS_INVALID_PARAMETER;
}
else
{
PSDCARD_HC_SLOT_INFO pSlotInfo = (PSDCARD_HC_SLOT_INFO)pData;
// set the slot capabilities
SDHCDSetSlotCapabilities(pSlotInfo, SD_SLOT_SD_4BIT_CAPABLE |
SD_SLOT_SD_1BIT_CAPABLE |
SD_SLOT_SDIO_CAPABLE |
SD_SLOT_SDIO_INT_DETECT_4BIT_MULTI_BLOCK);
SDHCDSetVoltageWindowMask(pSlotInfo, (SD_VDD_WINDOW_3_2_TO_3_3 | SD_VDD_WINDOW_3_3_TO_3_4));
// Set optimal voltage
SDHCDSetDesiredSlotVoltage(pSlotInfo, SD_VDD_WINDOW_3_2_TO_3_3);
SDHCDSetMaxClockRate(pSlotInfo, MAX_SDI_BUS_TRANSFER_SPEED);
// Set power up delay. We handle this in SetVoltage().
SDHCDSetPowerUpDelay(pSlotInfo, 300);
}
break;
default:
DEBUGMSG (SDCARD_ZONE_WARN,(TEXT("SDHCDSlotOptionHandler option=SD_API_STATUS_INVALID_PARAMETER\r\n")));
RETAILMSG (WGH_SDCARD,(TEXT("SDHCDSlotOptionHandler option=SD_API_STATUS_INVALID_PARAMETER\r\n")));
status = SD_API_STATUS_INVALID_PARAMETER;
}
DEBUGMSG (SDCARD_ZONE_FUNC,(TEXT("SDHCDSlotOptionHandler ends\r\n")));
RETAILMSG (WGH_SDCARD,(TEXT("SDHCDSlotOptionHandler ends\r\n")));
return status;
}
///////////////////////////////////////////////////////////////////////////////
// CSDIOControllerBase::BusRequestHandler - bus request handler
// Input: Slot - slot the request is going on
// pRequest - the request
//
// Output:
// Return: SD_API_STATUS Code
// Notes: The request passed in is marked as uncancelable, this function
// has the option of making the outstanding request cancelable
//
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS CSDIOControllerBase::BusRequestHandler(DWORD dwSlot, PSD_BUS_REQUEST pRequest)
{
DEBUGMSG (SDCARD_ZONE_FUNC,(TEXT("BusRequestHandler starts (CMD:%d)\r\n"), pRequest->CommandCode));
//RETAILMSG (WGH_SDCARD,(TEXT("BusRequestHandler starts (CMD:%x)\r\n"), pRequest->CommandCode));
RETAILMSG (WGH_SDCARD,(TEXT("BusRequestHandler starts (CMD:%d)\r\n"), pRequest->CommandCode));
RETAILMSG (FUSQ_DEBUG,(TEXT("BusRequestHandler starts (CMD:%x---------------)\r\n"), pRequest->CommandCode));
SD_API_STATUS status;
// Reset FIFO and status registers
vm_pSDIReg->SDIFSTA |= FIFO_RESET;
vm_pSDIReg->SDIDSTA = 0xffff;
vm_pSDIReg->SDIDCON = 0;
vm_pSDIReg->SDICSTA = 0xffff;
vm_pSDIReg->SDICCON = 0;
Start_SDI_Clock();
//----- 1. Determine the type of command (data vs. no data) and send the command -----
m_dwNumBytesToTransfer = pRequest->BlockSize * pRequest->NumBlocks;
RETAILMSG (FUSQ_DEBUG,(TEXT("BusRequestHandler starts (m_dwNumBytesToTransfer=:%d---------------)\r\n"), m_dwNumBytesToTransfer));
//----- 2 Can we schedule a DMA operation using the caller's buffer as-is? -----
if( ( m_dwDMAChannel == 0xffffffff ) || m_dwNumBytesToTransfer > MAXIMUM_DMA_TRANSFER_SIZE )
{
m_bUseDMAForTransfer = FALSE;
SetupPollingXfer(pRequest); // Use polling I/O routines for data transfer
}
else
{
if((IS_BUFFER_DWORD_ALIGNED(pRequest->pBlockBuffer)) && (IS_BUFFER_SIZE_A_DWORD_MULTPLE(pRequest->BlockSize)) )
{
m_DATATransferSize = 4; // DMA transfer size DWORD
if(pRequest->BlockSize == BYTES_PER_SECTOR)
m_bUseDMABurst = TRUE;
else
m_bUseDMABurst = FALSE;
}
else if ((IS_BUFFER_WORD_ALIGNED(pRequest->pBlockBuffer)) && (IS_BUFFER_SIZE_A_WORD_MULTPLE(pRequest->BlockSize)) )
{
m_DATATransferSize = 2; // DMA transfer size WORD
}
else
{
m_DATATransferSize = 1; // DMA transfer size BYTE
}
m_bUseDMAForTransfer = TRUE;
SetupDmaXfer(pRequest); // Use DMA for data transfer
}
if(pRequest->TransferClass == SD_COMMAND)
{
// Command only
status = SendCommand(pRequest->CommandCode, pRequest->CommandArgument, pRequest->CommandResponse.ResponseType, FALSE);
RETAILMSG (FUSQ_DEBUG,(TEXT("BusRequestHandler (0x%08x, 0x%04x, 0x%08x, 0x%04x, 0x%x) ---------starts\r\n"), this, pRequest->CommandCode, pRequest->CommandArgument, pRequest->CommandResponse.ResponseType, FALSE));
RETAILMSG(WGH_SDCARD, (TEXT("SDHCD:SDHCDBusRequestHandler() - ----------Command only--------\r\n")));
if(!SD_API_SUCCESS(status))
{
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SDHCDBusRequestHandler() - Error sending command:0x%02x\r\n"), pRequest->CommandCode));
RETAILMSG(WGH_SDCARD, (TEXT("SDHCD:SDHCDBusRequestHandler() - Error sending command:0x%02x\r\n"), pRequest->CommandCode));
goto BUS_REQUEST_COMPLETE;
}
//----- 2. Is this the first command sent to the card? If so, delay the 74 (or 80) clock cycles per the SD spec -----
if(m_bSendInitClocks)
{
m_bSendInitClocks = FALSE;
Wait_80_SDI_Clock_Cycles();
}
}
else
{
// Command with data transfer
status = SendCommand(pRequest->CommandCode, pRequest->CommandArgument, pRequest->CommandResponse.ResponseType, TRUE);
RETAILMSG(WGH_SDCARD, (TEXT("SDHCD:SDHCDBusRequestHandler() - ----------Command with data transfer--------\r\n")));
if(!SD_API_SUCCESS(status))
{
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SDHCDBusRequestHandler() - Error sending command:0x%02x\r\n"), pRequest->CommandCode));
RETAILMSG(WGH_SDCARD, (TEXT("SDHCD:SDHCDBusRequestHandler() - Error sending command:0x%02x\r\n"), pRequest->CommandCode));
goto BUS_REQUEST_COMPLETE;
}
}
//----- 3. Signal an IST that processes response information and cache our state -----
// NOTE: It is critical that this API NOT complete the bus request directly (which
// is why another thread is used). The bus driver expects bus requests to complete
// asynchronously and a stack overflow WILL eventually occur if this rule isn't honored.
SetEvent(m_hResponseReceivedEvent);
m_CurrentState = CommandSent;
status = SD_API_STATUS_PENDING;
BUS_REQUEST_COMPLETE:
DEBUGMSG (SDCARD_ZONE_FUNC,(TEXT("SDHCD:BusRequestHandler ends\r\n")));
RETAILMSG (WGH_SDCARD,(TEXT("SDHCD:BusRequestHandler ends\r\n")));
return status;
}
//-------------------------------------- Interrupt Service Threads---------------------------------------
///////////////////////////////////////////////////////////////////////////////
// CSDIOControllerBase::TransferIstThread - IST thread for DMA channel dedicated to SDIO
// Input: pController - the controller instance
// Output:
// Return: Thread exit code
// Notes:
///////////////////////////////////////////////////////////////////////////////
DWORD CSDIOControllerBase::TransferIstThread()
{
PSD_BUS_REQUEST pRequest = NULL; // the request to complete
SD_API_STATUS status;
if( m_DMAIstThreadPriority != 0xffffffff && !CeSetThreadPriority( GetCurrentThread(), m_DMAIstThreadPriority ) )
{
DEBUGMSG(SDCARD_ZONE_WARN,(TEXT("SDHCDriver:TransferIstThread(): warning, failed to set CEThreadPriority \r\n")));
RETAILMSG(WGH_SDCARD,(TEXT("SDHCDriver:TransferIstThread(): warning, failed to set CEThreadPriority \r\n")));
}
for(;;)
{
//----- 1. Wait for the command response -----
status = SD_API_STATUS_PENDING;
if(WaitForSingleObject(m_hResponseReceivedEvent, INFINITE) == WAIT_FAILED)
{
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCDriver:TransferIstThread(): Wait Failed!\r\n")));
RETAILMSG(WGH_SDCARD, (TEXT("SDHCDriver:TransferIstThread(): Wait Failed!\r\n")));
return FALSE;
}
RETAILMSG(WGH_SDCARD, (TEXT("SDHCDriver:TransferIstThread(): Wait SUCCESS!\r\n")));
if(m_bDriverShutdown)
{
DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("SDHCD:TransferIstThread(): Thread Exiting\r\n")));
RETAILMSG(WGH_SDCARD, (TEXT("SDHCD:TransferIstThread(): Thread Exiting\r\n")));
return FALSE;
}
//----- 2. Get and lock the current bus request -----
if(pRequest == NULL)
{
if((pRequest = SDHCDGetAndLockCurrentRequest(m_pHCContext, 0)) == NULL)
{
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SDHControllerIstThread() - Unable to get/lock current request!\r\n")));
RETAILMSG(WGH_SDCARD, (TEXT("SDHCD:SDHControllerIstThread() - Unable to get/lock current request!\r\n")));
status = SD_API_STATUS_INVALID_DEVICE_REQUEST;
goto TRANSFER_DONE;
}
}
//----- 3. Get the response information -----
if(pRequest->CommandResponse.ResponseType == NoResponse)
{
goto TRANSFER_DONE;
}
else{
status = GetCommandResponse(pRequest);
if(!SD_API_SUCCESS(status))
{
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SDHCDBusRequestHandler() - Error getting response for command:0x%02x\r\n"), pRequest->CommandCode));
RETAILMSG(WGH_SDCARD, (TEXT("SDHCD:SDHCDBusRequestHandler() - Error getting response for command:0x%02x\r\n"), pRequest->CommandCode));
goto TRANSFER_DONE;
}
}
//----- 4. SPECIAL CASE: The SD_CMD_STOP_TRANSMISSION that is sent after a SD_CMD_WRITE_MULTIPLE_BLOCK command -----
// requires a BUSY_CHECK
if( ( m_fHandleBusyCheckOnCommand38 && pRequest->CommandCode == SD_CMD_ERASE ) ||
( ( pRequest->CommandCode == SD_CMD_STOP_TRANSMISSION ) && ( m_dwLastTypeOfTransfer == SD_WRITE ) ) )
{
DWORD dwWaitCount = 0;
//----- 5. Wait until the I/O transfer is complete -----
while(!(vm_pSDIReg->SDIDSTA & BUSY_CHECKS_FINISH))
{
dwWaitCount++;
if( dwWaitCount > WAIT_TIME )
{
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SDHControllerIstThread() - timeout waiting for BUSY_CHECKS to finish!\r\n")));
RETAILMSG(WGH_SDCARD, (TEXT("SDHCD:SDHControllerIstThread() - timeout waiting for BUSY_CHECKS to finish!\r\n")));
status = SD_API_STATUS_DATA_TIMEOUT;
goto TRANSFER_DONE;
}
if( !IsCardPresent() )
{
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SDHControllerIstThread() - Card ejected!\r\n")));
RETAILMSG(WGH_SDCARD, (TEXT("SDHCD:SDHControllerIstThread() - Card ejected!\r\n")));
status = SD_API_STATUS_DEVICE_REMOVED;
goto TRANSFER_DONE;
}
if((vm_pSDIReg->SDIFSTA & FIFO_FAIL_ERROR))
{
vm_pSDIReg->SDIDSTA = BUSY_CHECKS_FINISH;
vm_pSDIReg->SDIFSTA &= FIFO_FAIL_ERROR;
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SDHControllerIstThread() - FIFO Error waiting for BUSY_CHECKS to finish!\r\n")));
RETAILMSG(WGH_SDCARD, (TEXT("SDHCD:SDHControllerIstThread() - FIFO Error waiting for BUSY_CHECKS to finish!\r\n")));
status = SD_API_STATUS_DATA_ERROR;
goto TRANSFER_DONE;
}
if((vm_pSDIReg->SDIDSTA & DATA_TRANSMIT_CRC_ERROR))
{
vm_pSDIReg->SDIDSTA = BUSY_CHECKS_FINISH | DATA_TRANSMIT_CRC_ERROR;
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SDHControllerIstThread() - Transmit CRC Error waiting for BUSY_CHECKS to finish!\r\n")));
RETAILMSG(WGH_SDCARD, (TEXT("SDHCD:SDHControllerIstThread() - Transmit CRC Error waiting for BUSY_CHECKS to finish!\r\n")));
status = SD_API_STATUS_DATA_ERROR;
goto TRANSFER_DONE;
}
if((vm_pSDIReg->SDIDSTA & DATA_RECEIVE_CRC_ERROR))
{
vm_pSDIReg->SDIDSTA = BUSY_CHECKS_FINISH | DATA_RECEIVE_CRC_ERROR;
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SDHControllerIstThread() - Receive CRC Error waiting for BUSY_CHECKS to finish!\r\n")));
RETAILMSG(WGH_SDCARD, (TEXT("SDHCD:SDHControllerIstThread() - Receive CRC Error waiting for BUSY_CHECKS to finish!\r\n")));
status = SD_API_STATUS_DATA_ERROR;
goto TRANSFER_DONE;
}
if((vm_pSDIReg->SDIDSTA & DATA_TIME_OUT))
{
vm_pSDIReg->SDIDSTA = BUSY_CHECKS_FINISH | DATA_TIME_OUT;
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SDHControllerIstThread() - Data timeout waiting for BUSY_CHECKS to finish!\r\n")));
RETAILMSG(WGH_SDCARD, (TEXT("SDHCD:SDHControllerIstThread() - Data timeout waiting for BUSY_CHECKS to finish!\r\n")));
status = SD_API_STATUS_DATA_TIMEOUT;
goto TRANSFER_DONE;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -