📄 sdcontrol.cpp
字号:
// Clear interrupt status by writing 1 to the corresponsing bit only
OUTREG32(&pHCDevice->pSDMMCRegisters->STATUS, CSP_BITFVAL(SDHC_SR_ECR, 1));
//Check for response time-out or crc error.If found, retry again
if (EXTREG32BF(&pHCDevice->pSDMMCRegisters->STATUS, SDHC_SR_TORESP))
{
// Clear status by writing 1
OUTREG32(&pHCDevice->pSDMMCRegisters->STATUS, CSP_BITFVAL(SDHC_SR_TORESP, 1));
retryCount --;
status = SD_API_STATUS_RESPONSE_TIMEOUT;
ERRORMSG(ZONE_ERROR, (TEXT("SDControllerBusyResponseThread: Status Command timeout\r\n")));
continue;
}
if (EXTREG32BF(&pHCDevice->pSDMMCRegisters->STATUS, SDHC_SR_RSPCERR))
{
// Clear status by writing 1
OUTREG32(&pHCDevice->pSDMMCRegisters->STATUS, CSP_BITFVAL(SDHC_SR_RSPCERR, 1));
retryCount --;
status = SD_API_STATUS_CRC_ERROR;
ERRORMSG(ZONE_ERROR, (TEXT("SDControllerBusyResponseThread: response CRC error\r\n")));
continue;
}
memset(responseBuffer, 0, (SDH_RESPONSE_FIFO_DEPTH - 5));
// read in the response words from the response fifo.
for (ii = 2; ii >= 0; ii--)
{
// read from the fifo
responseBuffer[ii] =INREG16(&pHCDevice->pSDMMCRegisters->RES_FIFO);
DEBUGMSG(ZONE_INFO, (TEXT("responseBuffer[%d]=0x%x\r\n"),ii,responseBuffer[ii]));
}
tempBuffer = (PUCHAR)responseBuffer;
memcpy((&CardStatus), &tempBuffer[1], sizeof(SD_CARD_STATUS));
DEBUGMSG(ZONE_INFO, (TEXT("CardStatus=0x%x\r\n"),SD_STATUS_CURRENT_STATE(CardStatus)));
}while ( (SD_STATUS_CURRENT_STATE (CardStatus) != CardState) && (retryCount > 0) );
CardStatus = CardState = 0;
return status;
}
//------------------------------------------------------------------------------
//
// Function: SDHCancelIoHandler
//
// io cancel handler
//
// Parameters:
// pHostContext[in] - host controller context
// Slot[in] - slot the request is going on
// pRequest[in] - the request to be cancelled
//
// Returns:
// TRUE if the request was cancelled
//
//------------------------------------------------------------------------------
BOOLEAN SDHCancelIoHandler(PSDCARD_HC_CONTEXT pHCContext,
DWORD Slot,
PSD_BUS_REQUEST pRequest)
{
PSDH_HARDWARE_CONTEXT pController;
DEBUGMSG(ZONE_FUNCTION, (TEXT("+SDHCancelIoHandler \n"))) ;
// for now, we should never get here because all requests are non-cancelable
// the hardware supports timeouts so it is impossible for the controller to get stuck
DEBUG_ASSERT(FALSE);
// get our extension
pController = GetExtensionFromHCDContext(PSDH_HARDWARE_CONTEXT, pHCContext);
// release the lock before we complete the request
SDHCDReleaseHCLock(pHCContext);
// complete the request with a cancelled status
SDHCDIndicateBusRequestComplete(pHCContext,pRequest, SD_API_STATUS_CANCELED);
DEBUGMSG(ZONE_FUNCTION, (TEXT("-SDHCancelIoHandler \n"))) ;
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: SDHBusRequestHandler
//
// bus request handler. The request passed in is marked as uncancelable, this function
// has the option of making the outstanding request cancelable
//
// Parameters:
// pHostContext[in] - host controller context
// Slot[in] - slot the request is going on
// pRequest[in] - the request to be cancelled
//
// Returns:
// SD_API_STATUS Code
//
//------------------------------------------------------------------------------
SD_API_STATUS SDHBusRequestHandler(PSDCARD_HC_CONTEXT pHCContext,
DWORD Slot,
PSD_BUS_REQUEST pRequest)
{
PSDH_HARDWARE_CONTEXT pController; // our controller
DWORD cmdatRegister=0; // CMDAT register
DWORD status;
// get our extension
pController = GetExtensionFromHCDContext(PSDH_HARDWARE_CONTEXT, pHCContext);
DEBUGMSG(ZONE_FUNCTION, (TEXT("+ SDHBusRequestHandler \r\n")));
DEBUGMSG(ZONE_COMMAND, (TEXT("SDHBusRequestHandler - CMD:%d ARG:0x%08X, TxClass: %d\r\n"),
pRequest->CommandCode, pRequest->CommandArgument, pRequest->TransferClass));
//check for card redy for next command
if((pController->LastResponedR1b == ResponseR1b) &&
(pRequest->TransferClass != SD_COMMAND))
{
DEBUGMSG(ZONE_INFO, (TEXT("SDHBusRequestHandler: wait for busy!\r\n")));
status = SDControllerBusyWaitResponse(pController);
if(status != SD_API_STATUS_SUCCESS)
{
SDHCDIndicateBusRequestComplete(pController->pHCContext, pRequest, SD_API_STATUS_DEVICE_BUSY);
return SD_API_STATUS_DEVICE_BUSY;
}
}
// Handle for ACMD 42/23. Our SDHC expects no reponse but spec say R1.
if ( (pRequest->CommandCode == SD_CMD_LOCK_UNLOCK && pController->fAppCommandSent == TRUE) ||
(pRequest->CommandCode == SD_ACMD_SET_WR_BLOCK_ERASE_COUNT && pController->fAppCommandSent == TRUE))
{
pRequest->CommandResponse.ResponseType = NoResponse;
}
pController->LastResponedR1b = pRequest->CommandResponse.ResponseType;
// set the command
INSREG32BF(&pController->pSDMMCRegisters->CMD, SDHC_CMD_CMD, pRequest->CommandCode);
// set the argument
OUTREG32(&pController->pSDMMCRegisters->ARG, pRequest->CommandArgument);
//Set the response type
switch (pRequest->CommandResponse.ResponseType)
{
case NoResponse:
CSP_BITFINS(cmdatRegister, SDHC_CDC_FORMAT, 0);
break;
//MX27 spec does not have busy bit register set.
//Need to check busy bit Hw implementation and handling.This affects commands with
//response R1b and for SDIOAbort transfers.
case ResponseR1b:
case ResponseR1:
case ResponseR5:
case ResponseR6:
CSP_BITFINS(cmdatRegister, SDHC_CDC_FORMAT, 1);
break;
case ResponseR2:
CSP_BITFINS(cmdatRegister, SDHC_CDC_FORMAT, 2);
break;
case ResponseR3:
case ResponseR4:
// R4 is really same as an R3 response on an MMC controller (non-CRC)
// Note: sdbus send for R4 although specs say R3
CSP_BITFINS(cmdatRegister, SDHC_CDC_FORMAT, 3);
break;
default:
ERRORMSG(ZONE_ERROR, (TEXT("SDHBusRequestHandler failed (Invalid parameter)\n")));
return SD_API_STATUS_INVALID_PARAMETER;
}
// check for Command Only
if ((SD_COMMAND != pRequest->TransferClass))
{
// its a command with a data phase
CSP_BITFINS(cmdatRegister, SDHC_CDC_DE, 1);
DWORD m_dwNumBytesToTransfer ;
m_dwNumBytesToTransfer = pRequest->NumBlocks * pRequest->BlockSize;
//adjust tranfer mode for SDHC tranfer performamce
if ( (pController->f4BitMode == TRUE && m_dwNumBytesToTransfer < 64 ) ||
(pController->f4BitMode == FALSE && m_dwNumBytesToTransfer < 16))
{
pController->fDMATransfer = FALSE;
} else
{
#if DMA
pController->fDMATransfer = TRUE;
#else
pController->fDMATransfer = FALSE;
#endif //DMA
}
// check for write
if (SD_WRITE == pRequest->TransferClass)
{
//Indicate that it is write process
CSP_BITFINS(cmdatRegister, SDHC_CDC_WR, 1);
OUTREG32(&pController->pSDMMCRegisters->STATUS, 0xFFFFFFFF);
// Enable Write operation Done interrupt
INSREG32BF(&pController->pSDMMCRegisters->INT_CNTR, SDHC_INT_WODONE, 1);
//check for DMA or ARM transfer
if (pController->fDMATransfer == TRUE)
{
BOOL fNoException;
fNoException = SDPerformSafeCopy( (void*)pController->DmaLogicalAddressTX, pRequest->pBlockBuffer, m_dwNumBytesToTransfer );
if (fNoException == FALSE)
{
ERRORMSG(ZONE_ERROR, (TEXT("Write buffer access violation ERROR\r\n")));
return SD_API_STATUS_ACCESS_VIOLATION;
}
DDKDmacSetTransCount(pController->DmaReqTxCH, m_dwNumBytesToTransfer);
// Clear DMAC status regs in order to restart channel.
DDKDmacClearChannelIntr(pController->DmaReqTxCH);
}
}
else if (SD_READ == pRequest->TransferClass)
{
//Specify the Read Time Out value
INSREG32BF(&pController->pSDMMCRegisters->READ_TO, SDHC_READTO_TO, pController->ulReadTimeout);
OUTREG32(&pController->pSDMMCRegisters->STATUS, 0xFFFFFFFF);
// Enable Read Operation Done interrupt
INSREG32BF(&pController->pSDMMCRegisters->INT_CNTR, SDHC_INT_RODONE, 1);
//check for DMA or ARM transfer
if (pController->fDMATransfer == TRUE)
{
DDKDmacSetTransCount(pController->DmaReqRxCH, m_dwNumBytesToTransfer);
// Clear DMAC status regs in order to restart channel.
DDKDmacClearChannelIntr(pController->DmaReqRxCH);
}
}
// set transfer length
INSREG32BF(&pController->pSDMMCRegisters->BLK_LEN, SDHC_BL_BL, pRequest->BlockSize);
// Set Number of Blocks
INSREG32BF(&pController->pSDMMCRegisters->NOB, SDHC_NOB_NOB, pRequest->NumBlocks);
}
else
{
//no data associated with this command
// set transfer length
INSREG32BF(&pController->pSDMMCRegisters->BLK_LEN, SDHC_BL_BL, 0);
// Set Number of Blocks
INSREG32BF(&pController->pSDMMCRegisters->NOB, SDHC_NOB_NOB, 0);
}
//clear interrupt status
OUTREG32(&pController->pSDMMCRegisters->STATUS, 0xFFFFFFFF);
// Enable End Command Response interrupt
INSREG32BF(&pController->pSDMMCRegisters->INT_CNTR, SDHC_INT_ECR, 1);
// check to see if we need to append the 80 clocks (i.e. this is the first transaction)
if (pController->SendInitClocks)
{
pController->SendInitClocks = FALSE;
CSP_BITFINS(cmdatRegister, SDHC_CDC_INIT, 1);
}
// check to see if we need to enable wide bus (4 bit) data transfer mode
CSP_BITFINS(cmdatRegister, SDHC_CDC_BW, pController->BusWidthSetting);
DEBUGMSG(ZONE_INFO, (TEXT("SDHBusRequestHandler - CMD_DAT_CONT: 0x%08X\r\n"), cmdatRegister));
if(pController->pSDMMCRegisters->STATUS != 0x30000100 )
{
DEBUGMSG(ZONE_INFO, (TEXT("Clear STATUS REG!- pSDMMCRegisters->STATUS :0x%08X\r\n"),pController->pSDMMCRegisters->STATUS));
OUTREG32(&pController->pSDMMCRegisters->STATUS, 0xFFFFFFFF);
OUTREG32(&pController->pSDMMCRegisters->STATUS, 0xFFFFFFFF);
}
pController->SDCommandStatus = SD_COMMAND_STATUS_CMD;
// write the CMDAT register
OUTREG32(&pController->pSDMMCRegisters->CMD_DAT_CONT, cmdatRegister);
DEBUGMSG(ZONE_FUNCTION, (TEXT("- SDHBusRequestHandler - Request Sent\r\n")));
return SD_API_STATUS_PENDING;
}
//------------------------------------------------------------------------------
//
// Function: SDHSlotOptionHandler
//
// handler for slot option changes
//
// Parameters:
// pHostContext[in] - host controller context
// SlotNumber[in] - the slot the change is being applied to
// Option[in] - the option code
// pData[in] - data associated with the option
// OptionSize[in] - size of option data
//
// Returns:
// SD_API_STATUS Code
//
//------------------------------------------------------------------------------
SD_API_STATUS SDHSlotOptionHandler(PSDCARD_HC_CONTEXT pHCContext,
DWORD SlotNumber,
SD_SLOT_OPTION_CODE Option,
PVOID pData,
ULONG OptionSize)
{
SD_API_STATUS status = SD_API_STATUS_SUCCESS; // status
PSDH_HARDWARE_CONTEXT pController; // the controller
PSD_HOST_BLOCK_CAPABILITY pBlockCaps; // queried block capabilities
// get our extension
pController = GetExtensionFromHCDContext(PSDH_HARDWARE_CONTEXT, pHCContext);
switch (Option)
{
case SDHCDAckSDIOInterrupt:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -