⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdhc_core.cpp

📁 NXP LPC3000系列 wince BSP包
💻 CPP
📖 第 1 页 / 共 4 页
字号:
		*(buff + 15) = (BYTE) (tmp >> 24);
		tmp = m_pSDCardRegs->sd_resp [1];
		*(buff + 8) = (BYTE) (tmp >> 0);
		*(buff + 9) = (BYTE) (tmp >> 8);
		*(buff + 10) = (BYTE) (tmp >> 16);
		*(buff + 11) = (BYTE) (tmp >> 24);
		tmp = m_pSDCardRegs->sd_resp [2];
		*(buff + 4) = (BYTE) (tmp >> 0);
		*(buff + 5) = (BYTE) (tmp >> 8);
		*(buff + 6) = (BYTE) (tmp >> 16);
		*(buff + 7) = (BYTE) (tmp >> 24);
		tmp = m_pSDCardRegs->sd_resp [3];
		*(buff + 0) = (BYTE) (tmp >> 0);
		*(buff + 1) = (BYTE) (tmp >> 8);
		*(buff + 2) = (BYTE) (tmp >> 16);
		*(buff + 3) = (BYTE) (tmp >> 24);
		break;

    case ResponseR3:
    case ResponseR4:
		*(buff + 0) = (BYTE) (START_BIT | TRANSMISSION_BIT | START_RESERVED);
		*(buff + 1) = (BYTE) (tmp >> 0);
		*(buff + 2) = (BYTE) (tmp >> 8);
		*(buff + 3) = (BYTE) (tmp >> 16);
		*(buff + 4) = (BYTE) (tmp >> 24);
		*(buff + 5) = (END_RESERVED | END_BIT);
		break;

    case ResponseR5:                
    case ResponseR6:
		*(buff + 0) = (BYTE) (START_BIT | TRANSMISSION_BIT | m_pSDCardRegs->sd_respcmd);
		*(buff + 1) = (BYTE) (tmp >> 0);
		*(buff + 2) = (BYTE) (tmp >> 8);
		*(buff + 3) = (BYTE) (tmp >> 16);
		*(buff + 4) = (BYTE) (tmp >> 24);
		*(buff + 5) = END_BIT;
		break;
	
	default:
		break;
	}
}

//------------------------------------------------------------------------------
//
// CompleteBusDataRequest
//
// Complete a data bus request
//
void sdCardController::CompleteBusDataRequest(SD_API_STATUS status,
											  PSD_BUS_REQUEST pRequest)
{
	// Complete request
    DEBUGMSG(1, (TEXT("CompleteBusDataRequest\r\n")));

	m_pSDCardRegs->sd_cmd = 0;
	m_pSDCardRegs->sd_dctrl = 0;
	m_pSDCardRegs->sd_mask0 = 0;
	m_pSDCardRegs->sd_clear = 0xFFFFF;

	// Verify transfer state?
	if ((m_TranCheckFlag == TRUE) || (m_ProgCheckFlag == TRUE))
	{
		status = sdCheckBusyStatus();
	}

	IndicateBusRequestComplete(pRequest, status);
}

//********************************************************************
// SD card driver callbacks
//********************************************************************

//------------------------------------------------------------------------------
//
// SDHCInitializeImpl
//
// Initialization callback
//
SD_API_STATUS sdCardController::SDHCInitializeImpl(void)
{
	DWORD threadID;
	PHYSICAL_ADDRESS pa;
	SD_API_STATUS status = SD_API_STATUS_INSUFFICIENT_RESOURCES;

    DEBUGMSG(SDHC_INIT_ZONE, (TEXT("sdCardController::SDHCInitializeImpl\r\n")));

	// All threads are initially non-existant
	m_detectThreadDone = TRUE;
	m_SD0ThreadDone = TRUE;

	// Map device registers
	pa.QuadPart = SD_BASE;
	m_pSDCardRegs = (SDCARD_REGS_T *) MmMapIoSpace(pa,
		sizeof (SDCARD_REGS_T), FALSE);
	pa.QuadPart = CLK_PM_BASE;
	m_pClkPwrRegs = (CLKPWR_REGS_T *) MmMapIoSpace(pa,
		sizeof (CLKPWR_REGS_T), FALSE);
	pa.QuadPart = SIC2_BASE;
	m_pINTCRegs = (INTC_REGS_T *) MmMapIoSpace(pa,
		sizeof (INTC_REGS_T), FALSE);
	pa.QuadPart = GPIO_BASE;
	m_pGPIORegs = (GPIO_REGS_T *) MmMapIoSpace(pa,
		sizeof (GPIO_REGS_T), FALSE);
	if ((m_pSDCardRegs == NULL) || (m_pClkPwrRegs == NULL) ||
		(m_pINTCRegs == NULL) || (m_pGPIORegs == NULL))
	{
        DEBUGMSG(SDHC_ERROR_ZONE, 
			(TEXT("sdCardController: ERROR: Failed to map registers\r\n")));
		goto cleanup;
	}

	// Setup SD card interface, this is setup, but will not be restored to
	// the original state if de-intialized later. Clocks are not enabled yet.
	m_pClkPwrRegs->clkpwr_ms_ctrl = (CLKPWR_MSCARD_MSDIO_PU_EN |
		CLKPWR_MSCARD_SDCARD_DIV(1));

	// Enable clock for SD block
	sdCardEnableClocks(TRUE);

	// Initial setup of SD card controller
	sdCardClearController();
	m_pSDCardRegs->sd_power = (SD_OPENDRAIN_EN | SD_POWER_OFF_MODE);
	m_pSDCardRegs->sd_clock = (SD_CLKDIV_MASK | SD_SDCLK_PWRSAVE);

	// Disable clock for SD block until a card is inserted
	sdCardEnableClocks(FALSE);

	// Setup GPIO1 as an interrupt pin with initial active low level interrupt response
	m_pINTCRegs->atr &= ~GPIO_IRQ_MASK; // Level sensitive
	m_pINTCRegs->apr &= ~GPIO_IRQ_MASK; // low sensitive

	// Map sysIntr value to the card detect interrupt
    if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &m_dwSDCDIrq,
		sizeof(m_dwSDCDIrq), &m_dwSysintrCD, sizeof(m_dwSysintrCD), NULL))
    {
		DEBUGMSG(SDHC_ERROR_ZONE,
			(TEXT("SDCardEventInit: Error obtaining SD detect SYSINTR value!\r\n")));
        m_dwSysintrCD = SYSINTR_UNDEFINED;
        goto cleanup;
    }

    // Create event for the interrupt
    m_hCardInsertInterruptEvent = CreateEvent(NULL, FALSE, FALSE,NULL);
    if (m_hCardInsertInterruptEvent == NULL) {
		DEBUGMSG(SDHC_ERROR_ZONE,
			(TEXT("SDCardEventInit: Error creating SD detect event!\r\n")));
        goto cleanup;
    }

    // initialize the card insertion interrupt event
    if (!InterruptInitialize (m_dwSysintrCD, m_hCardInsertInterruptEvent,
		NULL, 0)) {
		DEBUGMSG(SDHC_ERROR_ZONE,
			(TEXT("SDCardEventInit: Error initializing SD detect interrupt!\r\n")));
        goto cleanup;
    }

	// Start card detection thread
    m_DetectThreadKill = FALSE;
	m_detectThreadDone = FALSE;
	m_hCardInsertInterruptThread =  CreateThread(NULL, 0,
		(LPTHREAD_START_ROUTINE) StartDetectThread, this, 0, &threadID);
	if (m_hCardInsertInterruptThread == NULL)
	{
		DEBUGMSG(SDHC_ERROR_ZONE,
			(TEXT("SDHCInitializeImpl: Error creating detect thread!\r\n")));
        goto cleanup;
    }

	// Enable SD card detect interrupt
	InterruptDone(m_dwSysintrCD);

	// Create sysIntrs for SD card IRQs
    if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &m_dwIrq0, sizeof(m_dwIrq0),
		&m_dwSysIntr0, sizeof(m_dwSysIntr0), NULL))
    {
        DEBUGMSG(SDHC_ERROR_ZONE, 
			(TEXT("sdCardController: ERROR: Failed to request the SD0 sysintr.\r\n")));

        m_dwSysIntr0 = SYSINTR_UNDEFINED;
        goto cleanup;
    }

	// Create SD card events
	m_eventSD0 = CreateEvent(NULL, FALSE, FALSE, NULL);
	if (m_eventSD0 == NULL)
	{
		DEBUGMSG(SDHC_ERROR_ZONE, 
			(TEXT("sdCardController: ERROR: Failed to create SD0 handler event.\r\n")));
		m_eventSD0 = INVALID_HANDLE_VALUE;
        goto cleanup;
	}

	// Bind interrupt to events
	if (InterruptInitialize(m_dwSysIntr0, m_eventSD0, NULL, 0) == FALSE)
	{
		// Cannot initialize interrupt
		DEBUGMSG(SDHC_ERROR_ZONE, 
			(TEXT("sdCardController: ERROR: Cannot initialize SD0 interrupt\r\n")));
        goto cleanup;
	}

	status = SD_API_STATUS_SUCCESS;

cleanup:
    if (!SD_API_SUCCESS(status))
	{
        SDHCDeinitializeImpl();
    }

    return status;
}

//------------------------------------------------------------------------------
//
// SDHCDeinitializeImpl
//
// De-initialization callback
//
SD_API_STATUS sdCardController::SDHCDeinitializeImpl(void)
{
	int to;

	// Stop SD controller state machines
	if (m_pSDCardRegs != NULL)
	{
		m_pSDCardRegs->sd_cmd = 0;
		m_pSDCardRegs->sd_dctrl = 0;
	}

	// Shutdown hardware if enabled
	if (m_hardwareInitialized != FALSE)
	{
		sdHwShutdown();
	}

	// Disable power to the card
	if (m_pGPIORegs != NULL)
	{
		sdHwSlotPowerControl(m_pGPIORegs, FALSE);
	}

	// Return SD command and data interrupt resources
	if (m_eventSD0 != NULL)
	{
		CloseHandle(m_eventSD0);
		m_eventSD0 = NULL;
	}
	if (m_dwSysIntr0 != SYSINTR_UNDEFINED)
	{
		InterruptDisable(m_dwSysIntr0);
		KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &m_dwSysIntr0,
            sizeof(m_dwSysIntr0), NULL, 0, NULL);
		m_dwSysIntr0 = SYSINTR_UNDEFINED;
	}

	// Stop the card detect thread
	m_DetectThreadKill = TRUE;
	to = 20;
	while ((to > 0) && (m_detectThreadDone == FALSE))
	{
		SetEvent(m_hCardInsertInterruptEvent);
		Sleep(50);
	}

	// Close event handle
	if (m_hCardInsertInterruptEvent != NULL)
	{
		CloseHandle(m_hCardInsertInterruptEvent);
		m_hCardInsertInterruptEvent = NULL;
	}

	// Disable interrupt
	if (m_dwSDCDIrq != SYSINTR_UNDEFINED)
	{
		InterruptDisable(m_dwSDCDIrq);
		KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &m_dwSDCDIrq,
            sizeof(m_dwSDCDIrq), NULL, 0, NULL);
		m_dwSDCDIrq = SYSINTR_UNDEFINED;
	}

	// Unmap register space
	if (m_pGPIORegs != NULL)
	{
        MmUnmapIoSpace((PVOID) m_pGPIORegs, sizeof (GPIO_REGS_T));
		m_pGPIORegs = NULL;
	}
	if (m_pINTCRegs != NULL)
	{
        MmUnmapIoSpace((PVOID) m_pINTCRegs, sizeof (INTC_REGS_T));
		m_pINTCRegs = NULL;
	}
	if (m_pClkPwrRegs != NULL)
	{
        MmUnmapIoSpace((PVOID) m_pClkPwrRegs, sizeof (CLKPWR_REGS_T));
		m_pClkPwrRegs = NULL;
	}
	if (m_pSDCardRegs != NULL)
	{
        MmUnmapIoSpace((PVOID) m_pSDCardRegs, sizeof (SDCARD_REGS_T));
		m_pSDCardRegs = NULL;
	}

	return SD_API_STATUS_SUCCESS;
}

//------------------------------------------------------------------------------
//
// SDHCCancelIoHandlerImpl
//
// Cancel current request
//
BOOLEAN sdCardController::SDHCCancelIoHandlerImpl(UCHAR Slot,
												  PSD_BUS_REQUEST pRequest)
{
	// Does nothing
	DEBUGMSG(SDHC_INIT_ZONE,  (TEXT("SDHCCancelIoHandlerImpl\r\n")));
	return TRUE;
}

//------------------------------------------------------------------------------
//
// SDHCBusRequestHandlerImpl
//
// Handle a SD bus request
//
SD_API_STATUS sdCardController::SDHCBusRequestHandlerImpl(PSD_BUS_REQUEST pRequest)
{
    SD_API_STATUS   status;
    BOOL            fWriteTransferMode = FALSE;

    // acquire the device lock to protect from device removal
    SDHCDAcquireHCLock(m_pHCContext);

	status = ProcessRequest(pRequest);
    if(!SD_API_SUCCESS(status))
    {
        DEBUGMSG(SDHC_ERROR_ZONE, (TEXT("SDHCBusRequestHandlerImpl() - Error sending command:0x%02x\r\n"),
			pRequest->CommandCode));
        goto EXIT;      
    }

	// we will handle the response on another thread
    status = SD_API_STATUS_PENDING;

 EXIT:
    SDHCDReleaseHCLock(m_pHCContext);
    return status;
}

//------------------------------------------------------------------------------
//
// SDHCSlotOptionHandlerImpl
//
// Sd card slot function handler
//
SD_API_STATUS sdCardController::SDHCSlotOptionHandlerImpl(UCHAR SlotNumber, 
                                                          SD_SLOT_OPTION_CODE Option, 
                                                          PVOID pData,
                                                          ULONG OptionSize)
{
    SD_API_STATUS status = SD_API_STATUS_SUCCESS;

    SDHCDAcquireHCLock(m_pHCContext);

    switch (Option)
	{
	case SDHCDSetSlotPower:
		{
			//// this platform has 3.2V tied directly to the slot
			DEBUGMSG(SDHC_INIT_ZONE, (TEXT("SHCSDSlotOptionHandler : SDHCDSetSlotPower\r\n")));
	    }
		break;

	case SDHCDSetSlotInterface:
		{
			PSD_CARD_INTERFACE pInterface = (PSD_CARD_INTERFACE) pData;
	        sdCardSetInterface(pInterface);
	    }
		break;

	case SDHCDGetSlotInfo:
		if( OptionSize != sizeof(SDCARD_HC_SLOT_INFO) || pData == NULL )
	    {
		    status = SD_API_STATUS_INVALID_PARAMETER;
			DEBUGMSG(SDHC_ERROR_ZONE, 
				(TEXT("SHCSDSlotOptionHandler : SDHCDGetSlotInfo\r\n")));
	    }
		else
	    {
			PSDCARD_HC_SLOT_INFO pSlotInfo = (PSDCARD_HC_SLOT_INFO)pData;
			SDHCDSetSlotCapabilities( pSlotInfo, 
	            SD_SLOT_SD_1BIT_CAPABLE |
		        SD_SLOT_SD_4BIT_CAPABLE);

			SDHCDSetVoltageWindowMask(pSlotInfo, (SD_VDD_WINDOW_3_0_TO_3_1 | SD_VDD_WINDOW_3_1_TO_3_2 |
				SD_VDD_WINDOW_3_2_TO_3_3)); 

	        // Set optimal voltage
		    SDHCDSetDesiredSlotVoltage(pSlotInfo, SD_VDD_WINDOW_3_1_TO_3_2);     

	        // Set maximum supported clock rate
		    SDHCDSetMaxClockRate(pSlotInfo, m_dwMaxClockRate);

			// set power up delay
	        SDHCDSetPowerUpDelay(pSlotInfo, 100); 
		}
	    break;

	case SDHCDSetSlotPowerState:
		  DEBUGMSG(SDHC_INIT_ZONE, (TEXT("SHCSDSlotOptionHandler - SetSlotPowerState : on slot %d\r\n"),SlotNumber));
	    if( pData == NULL || OptionSize != sizeof(CEDEVICE_POWER_STATE) )
		  {
			  status = SD_API_STATUS_INVALID_PARAMETER;
	    }
		  else
	   {
		      PCEDEVICE_POWER_STATE pcps = (PCEDEVICE_POWER_STATE) pData;
			  m_PowerState = *pcps;
			  UpdateDevicePowerState();
	    }
		  break;

	case SDHCDGetSlotPowerState:
		DEBUGMSG(SDHC_INIT_ZONE, (TEXT("SHCSDSlotOptionHandler - GetSlotPowerState : on slot %d\r\n"),SlotNumber));
    if( pData == NULL || OptionSize != sizeof(CEDEVICE_POWER_STATE) )
    {
        status = SD_API_STATUS_INVALID_PARAMETER;
    }
    else
    {
        PCEDEVICE_POWER_STATE pcps = (PCEDEVICE_POWER_STATE) pData;
        *pcps = m_PowerState;
    }
    break;

	case SDHCDGetWriteProtectStatus:
    {
        PSD_CARD_INTERFACE pInterface = (PSD_CARD_INTERFACE) pData;
        pInterface->WriteProtected = sdHwCardWriteProtected(m_pGPIORegs);
	    DEBUGMSG(SDHC_INIT_ZONE, (TEXT("SHCSDSlotOptionHandler - SDHCDGetWriteProtectStatus : on slot %d (protect = %d)\r\n"),
			SlotNumber, pInterface->WriteProtected));
    }
	break;

	case SDHCDQueryBlockCapability:
    {
        PSD_HOST_BLOCK_CAPABILITY pBlockCaps = 
            (PSD_HOST_BLOCK_CAPABILITY)pData;

        DEBUGMSG(SDHC_INIT_ZONE, 
			(TEXT("SHCSDSlotOptionHandler: Read Block Length: %d , Requested read Blocks: %d\r\n"), 
            pBlockCaps->ReadBlockSize, pBlockCaps->ReadBlocks));
        DEBUGMSG(SDHC_INIT_ZONE, 
            (TEXT("SHCSDSlotOptionHandler: Write Block Length: %d , Requested write Blocks: %d\r\n"), 
            pBlockCaps->WriteBlockSize, pBlockCaps->WriteBlocks));

		// Up to a 2K blocksize
		if (pBlockCaps->ReadBlockSize < 1)
		{
			pBlockCaps->ReadBlockSize = 1;
		}
		if (pBlockCaps->ReadBlockSize > 1024)
		{
			pBlockCaps->ReadBlockSize = 1024;
		}
		if (pBlockCaps->WriteBlockSize < 1)
		{
			pBlockCaps->WriteBlockSize = 1;
		}
		if (pBlockCaps->WriteBlockSize > 1024)
		{
			pBlockCaps->WriteBlockSize = 1024;
		}

		pBlockCaps->ReadBlocks = 64;
		pBlockCaps->WriteBlocks = 64;
	}
    break;

	default:
		status = SD_API_STATUS_INVALID_PARAMETER;
		break;
	}

    SDHCDReleaseHCLock(m_pHCContext);
    return status;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -