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

📄 sdiocontrollerbase.cpp

📁 S3C2440A的windows ce 5.0 bsp包
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    PUCHAR              respBuff;       // response buffer
    DWORD dwWaitCount = 0;

    //----- 1. Wait for the response information to get arrive at the controller -----
    while(!(vm_pSDIReg->SDICSTA & RESPONSE_RECEIVED))
    {
        dwWaitCount++;
        if( dwWaitCount > WAIT_TIME )
        {
            DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:GetCommandResponse() - timeout waiting for command response!\r\n")));
            return SD_API_STATUS_RESPONSE_TIMEOUT;
        }

        if( !IsCardPresent() )
        {
            DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:GetCommandResponse() - Card ejected!\r\n")));
            return SD_API_STATUS_DEVICE_REMOVED;
        }
        if(vm_pSDIReg->SDICSTA & COMMAND_TIMED_OUT)
        {
            vm_pSDIReg->SDICSTA = COMMAND_TIMED_OUT;                // Clear the error
            DEBUGMSG (SDCARD_ZONE_ERROR,(TEXT("GetCommandResponse returned SD_API_STATUS_RESPONSE_TIMEOUT (COMMAND_TIMED_OUT)\r\n")));
            return SD_API_STATUS_RESPONSE_TIMEOUT;
        }

        if(vm_pSDIReg->SDIDSTA & CRC_CHECK_FAILED)
        {
            vm_pSDIReg->SDIDSTA = CRC_CHECK_FAILED;             // Clear the error
            DEBUGMSG (SDCARD_ZONE_ERROR,(TEXT("GetCommandResponse returned SD_API_STATUS_CRC_ERROR (CRC_CHECK_FAILED)\r\n")));
            return SD_API_STATUS_CRC_ERROR;
        }

        if(vm_pSDIReg->SDIDSTA & DATA_TRANSMIT_CRC_ERROR)
        {
            vm_pSDIReg->SDIDSTA = DATA_TRANSMIT_CRC_ERROR;      // Clear the error
            DEBUGMSG (SDCARD_ZONE_ERROR,(TEXT("getSDICommandResponse returned SD_API_STATUS_CRC_ERROR (DATA_TRANSMIT_CRC_ERROR)\r\n")));
            return SD_API_STATUS_CRC_ERROR; 
        }

        if(vm_pSDIReg->SDIDSTA & DATA_RECEIVE_CRC_ERROR)
        {
            vm_pSDIReg->SDIDSTA = DATA_RECEIVE_CRC_ERROR;           // Clear the error
            DEBUGMSG (SDCARD_ZONE_ERROR,(TEXT("GetCommandResponse returned SD_API_STATUS_CRC_ERROR (DATA_RECEIVE_CRC_ERROR)\r\n")));
            return SD_API_STATUS_CRC_ERROR;
        }

        if(vm_pSDIReg->SDIDSTA & DATA_TIME_OUT)
        {
            vm_pSDIReg->SDIDSTA = DATA_TIME_OUT;                    // Clear the error
            DEBUGMSG (SDCARD_ZONE_ERROR,(TEXT("GetCommandResponse returned SD_API_STATUS_DATA_TIMEOUT (DATA_TIME_OUT)\r\n")));
            return SD_API_STATUS_DATA_TIMEOUT;
        }
    }
    vm_pSDIReg->SDICSTA = RESPONSE_RECEIVED;                        // Clear the status 


    //----- 2. Copy the response information to our "response buffer" -----
    //         NOTE: All START_BIT and TRANSMISSION_BIT bits ='0'. All END_BIT bits ='0'. All RESERVED bits ='1'
    respBuff = pRequest->CommandResponse.ResponseBuffer;
    switch(pRequest->CommandResponse.ResponseType)
    {
        case NoResponse:
            break;

        case ResponseR1:                
        case ResponseR1b:
            //--- SHORT RESPONSE (48 bits total)--- 
            // Format: { START_BIT(1) | TRANSMISSION_BIT(1) | COMMAND_INDEX(6) | CARD_STATUS(32) | CRC7(7) | END_BIT(1) }
            // NOTE: START_BIT and TRANSMISSION_BIT = 0, END_BIT = 1
            //
            *(respBuff    ) = (BYTE)(START_BIT | TRANSMISSION_BIT | pRequest->CommandCode);
            *(respBuff + 1) = (BYTE)(vm_pSDIReg->SDIRSP0      );
            *(respBuff + 2) = (BYTE)(vm_pSDIReg->SDIRSP0 >> 8 );
            *(respBuff + 3) = (BYTE)(vm_pSDIReg->SDIRSP0 >> 16);
            *(respBuff + 4) = (BYTE)(vm_pSDIReg->SDIRSP0 >> 24);
            *(respBuff + 5) = (BYTE)(END_RESERVED | END_BIT);
            break;

        case ResponseR3:
        case ResponseR4:
            //--- SHORT RESPONSE (48 bits total)--- 
            // Format: { START_BIT(1) | TRANSMISSION_BIT(1) | RESERVED(6) | CARD_STATUS(32) | RESERVED(7) | END_BIT(1) }
            //
            *(respBuff    ) = (BYTE)(START_BIT | TRANSMISSION_BIT | START_RESERVED);
            *(respBuff + 1) = (BYTE)(vm_pSDIReg->SDIRSP0      );
            *(respBuff + 2) = (BYTE)(vm_pSDIReg->SDIRSP0 >> 8 );
            *(respBuff + 3) = (BYTE)(vm_pSDIReg->SDIRSP0 >> 16);
            *(respBuff + 4) = (BYTE)(vm_pSDIReg->SDIRSP0 >> 24);
            *(respBuff + 5) = (BYTE)(END_RESERVED | END_BIT);   
            break;

        case ResponseR5:                
        case ResponseR6:
            //--- SHORT RESPONSE (48 bits total)--- 
            // Format: { START_BIT(1) | TRANSMISSION_BIT(1) | COMMAND_INDEX(6) | RCA(16) | CARD_STATUS(16) | CRC7(7) | END_BIT(1) }
            //
            *(respBuff    ) = (BYTE)(START_BIT | TRANSMISSION_BIT | pRequest->CommandCode);
            *(respBuff + 1) = (BYTE)(vm_pSDIReg->SDIRSP0      );
            *(respBuff + 2) = (BYTE)(vm_pSDIReg->SDIRSP0 >> 8 );
            *(respBuff + 3) = (BYTE)(vm_pSDIReg->SDIRSP0 >> 16);
            *(respBuff + 4) = (BYTE)(vm_pSDIReg->SDIRSP0 >> 24);
            *(respBuff + 5) = (BYTE)(vm_pSDIReg->SDIRSP1 >> 24);   
            break;

        case ResponseR2:
            //--- LONG RESPONSE (136 bits total)--- 
            // Format: { START_BIT(1) | TRANSMISSION_BIT(1) | RESERVED(6) | CARD_STATUS(127) | END_BIT(1) }
            //
            // NOTE: In this implementation, the caller doesn't require the upper 8 bits of reserved data.
            //       Consequently, these bits aren't included and the response info is copied directly into
            //       the beginning of the supplied buffer.      
            //
            //*(respBuff    )   = (BYTE)(START_BIT | TRANSMISSION_BIT | START_RESERVED);
            //
            *(respBuff + 0) = (BYTE)(vm_pSDIReg->SDIRSP3      );
            *(respBuff + 1) = (BYTE)(vm_pSDIReg->SDIRSP3 >> 8 );
            *(respBuff + 2) = (BYTE)(vm_pSDIReg->SDIRSP3 >> 16);
            *(respBuff + 3) = (BYTE)(vm_pSDIReg->SDIRSP3 >> 24);

            *(respBuff + 4) = (BYTE)(vm_pSDIReg->SDIRSP2      );
            *(respBuff + 5) = (BYTE)(vm_pSDIReg->SDIRSP2 >> 8 );
            *(respBuff + 6) = (BYTE)(vm_pSDIReg->SDIRSP2 >> 16);
            *(respBuff + 7) = (BYTE)(vm_pSDIReg->SDIRSP2 >> 24);

            *(respBuff + 8) = (BYTE)(vm_pSDIReg->SDIRSP1      );
            *(respBuff + 9) = (BYTE)(vm_pSDIReg->SDIRSP1 >> 8 );
            *(respBuff + 10)= (BYTE)(vm_pSDIReg->SDIRSP1 >> 16);
            *(respBuff + 11)= (BYTE)(vm_pSDIReg->SDIRSP1 >> 24);

            *(respBuff + 12)= (BYTE)(vm_pSDIReg->SDIRSP0      );
            *(respBuff + 13)= (BYTE)(vm_pSDIReg->SDIRSP0 >> 8 );
            *(respBuff + 14)= (BYTE)(vm_pSDIReg->SDIRSP0 >> 16);
            *(respBuff + 15)= (BYTE)(vm_pSDIReg->SDIRSP0 >> 24);
            break;

        default:
            DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:GetCmdResponse(): Unrecognized response type!\r\n")));
            break;
    }

    DEBUGMSG (SDHC_RESPONSE_ZONE,(TEXT("GetCommandResponse returned SD_API_STATUS_SUCCESS\r\n")));
    return SD_API_STATUS_SUCCESS;
}


/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:       CSDIOControllerBase::SetupDmaXfer()

Description:    Prepares the SDI device for a transfer

Returns:        SD_API_STATUS code.
-------------------------------------------------------------------*/
BOOL CSDIOControllerBase::SetupDmaXfer(PSD_BUS_REQUEST pRequest)
{
    //----- 1. Check the parameters -----
    if(!pRequest)
    {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SetupDmaXfer() - Invalid parameters!\r\n")));
        return FALSE;
    }

    //----- 2. Setup the SD/MMC controller according to the type of transfer -----
    switch(pRequest->TransferClass)
    {
    case SD_READ:

        //********* 3. READ request *********
        m_dwLastTypeOfTransfer = SD_READ;

        //----- 3a. Reset the FIFO -----
        vm_pSDIReg->SDIDTIMER   = MAX_DATABUSY_TIMEOUT;        
        vm_pSDIReg->SDIBSIZE      = pRequest->BlockSize;
        Stop_SDIO_DMA_Channel();

        switch( m_dwDMAChannel )
        {
        case 0:
            //----- 3b. Initialize the DMA channel for input mode -----
	        if (m_DATATransferSize == 4)
	            vm_pDMAreg->DISRC0   = (int)MMCFIFO_DWORD_PHYS;   
	        else if (m_DATATransferSize == 2)
	            vm_pDMAreg->DISRC0   = (int)MMCFIFO_WORD_PHYS;
	        else
	            vm_pDMAreg->DISRC0   = (int)MMCFIFO_BYTE_PHYS;
            vm_pDMAreg->DISRCC0 |= (SOURCE_PERIPHERAL_BUS | FIXED_SOURCE_ADDRESS); // Source is periperal bus, fixed addr
            vm_pDMAreg->DIDST0   = (int)m_pDMABufferPhys.LowPart;
            vm_pDMAreg->DIDSTC0 &= ~(DESTINATION_PERIPHERAL_BUS | FIXED_DESTINATION_ADDRESS); // Destination is system bus, increment addr
            //----- 3c. Configure the DMA channel's transfer characteristics: handshake, sync PCLK, interrupt, -----
            //         single RX, single service,, MMC request, no auto-reload, word (32 bits), RX count
   	        vm_pDMAreg->DCON0  = (  HANDSHAKE_MODE | GENERATE_INTERRUPT | MMC_DMA0 | DMA_TRIGGERED_BY_HARDWARE 
	       	                            | NO_DMA_AUTO_RELOAD );
	        if (m_DATATransferSize == 4)
	        	if (m_bUseDMABurst)
    	        	vm_pDMAreg->DCON0  |= ( SELECT_BURST_TRANSFER | TRANSFER_WORD | ((pRequest->BlockSize >> 4) * pRequest->NumBlocks));
	        	else
    	        	vm_pDMAreg->DCON0  |= ( TRANSFER_WORD | ((pRequest->BlockSize >> 2) * pRequest->NumBlocks));
	        else if (m_DATATransferSize == 2)
    	        vm_pDMAreg->DCON0  |= ( TRANSFER_HALF_WORD | ((pRequest->BlockSize >> 1) * pRequest->NumBlocks));
	        else
    	        vm_pDMAreg->DCON0  |= ( TRANSFER_BYTE | ((pRequest->BlockSize) * pRequest->NumBlocks));
            break;

        case 1:
            //----- 3b. Initialize the DMA channel for input mode -----
	        if (m_DATATransferSize == 4)
	            vm_pDMAreg->DISRC1   = (int)MMCFIFO_DWORD_PHYS;   
	        else if (m_DATATransferSize == 2)
	            vm_pDMAreg->DISRC1   = (int)MMCFIFO_WORD_PHYS;
	        else
	            vm_pDMAreg->DISRC1   = (int)MMCFIFO_BYTE_PHYS;
            vm_pDMAreg->DISRCC1    |= (SOURCE_PERIPHERAL_BUS | FIXED_SOURCE_ADDRESS);              // Source is periperal bus, fixed addr
            vm_pDMAreg->DIDST1 = (int)m_pDMABufferPhys.LowPart; 
            vm_pDMAreg->DIDSTC1 &= ~(DESTINATION_PERIPHERAL_BUS | FIXED_DESTINATION_ADDRESS);  // Destination is system bus, increment addr
            //----- 3c. Configure the DMA channel's transfer characteristics: handshake, sync PCLK, interrupt, -----
            //         single RX, single service,, MMC request, no auto-reload, word (32 bits), RX count
   	        vm_pDMAreg->DCON1  = (  HANDSHAKE_MODE | GENERATE_INTERRUPT | MMC_DMA0 | DMA_TRIGGERED_BY_HARDWARE 
	       	                            | NO_DMA_AUTO_RELOAD );
	        if (m_DATATransferSize == 4)
	        	if (m_bUseDMABurst)
    	        	vm_pDMAreg->DCON1  |= ( SELECT_BURST_TRANSFER | TRANSFER_WORD | ((pRequest->BlockSize >> 4) * pRequest->NumBlocks));
	        	else
    	        	vm_pDMAreg->DCON1  |= ( TRANSFER_WORD | ((pRequest->BlockSize >> 2) * pRequest->NumBlocks));
	        else if (m_DATATransferSize == 2)
    	        vm_pDMAreg->DCON1  |= ( TRANSFER_HALF_WORD | ((pRequest->BlockSize >> 1) * pRequest->NumBlocks));
	        else
    	        vm_pDMAreg->DCON1  |= ( TRANSFER_BYTE | ((pRequest->BlockSize) * pRequest->NumBlocks));
            break;

        case 2:
            //----- 3b. Initialize the DMA channel for input mode -----
	        if (m_DATATransferSize == 4)
	            vm_pDMAreg->DISRC2   = (int)MMCFIFO_DWORD_PHYS;   
	        else if (m_DATATransferSize == 2)
	            vm_pDMAreg->DISRC2   = (int)MMCFIFO_WORD_PHYS;
	        else
	            vm_pDMAreg->DISRC2   = (int)MMCFIFO_BYTE_PHYS;
            vm_pDMAreg->DISRCC2    |= (SOURCE_PERIPHERAL_BUS | FIXED_SOURCE_ADDRESS);              // Source is periperal bus, fixed addr
            vm_pDMAreg->DIDST2 = (int)m_pDMABufferPhys.LowPart; 
            vm_pDMAreg->DIDSTC2 &= ~(DESTINATION_PERIPHERAL_BUS | FIXED_DESTINATION_ADDRESS);  // Destination is system bus, increment addr
            //----- 3c. Configure the DMA channel's transfer characteristics: handshake, sync PCLK, interrupt, -----
            //         single RX, single service,, MMC request, no auto-reload, word (32 bits), RX count
   	        vm_pDMAreg->DCON2  = (  HANDSHAKE_MODE | GENERATE_INTERRUPT | MMC_DMA0 | DMA_TRIGGERED_BY_HARDWARE 
	       	                            | NO_DMA_AUTO_RELOAD );
	        if (m_DATATransferSize == 4)
	        	if (m_bUseDMABurst)
    	        	vm_pDMAreg->DCON2  |= ( SELECT_BURST_TRANSFER | TRANSFER_WORD | ((pRequest->BlockSize >> 4) * pRequest->NumBlocks));
	        	else
    	        	vm_pDMAreg->DCON2  |= ( TRANSFER_WORD | ((pRequest->BlockSize >> 2) * pRequest->NumBlocks));
	        else if (m_DATATransferSize == 2)
    	        vm_pDMAreg->DCON2  |= ( TRANSFER_HALF_WORD | ((pRequest->BlockSize >> 1) * pRequest->NumBlocks));
	        else
    	        vm_pDMAreg->DCON2  |= ( TRANSFER_BYTE | ((pRequest->BlockSize) * pRequest->NumBlocks));
            break;

        case 3:
            //----- 3b. Initialize the DMA channel for input mode -----
	        if (m_DATATransferSize == 4)
	            vm_pDMAreg->DISRC3   = (int)MMCFIFO_DWORD_PHYS;   
	        else if (m_DATATransferSize == 2)
	            vm_pDMAreg->DISRC3   = (int)MMCFIFO_WORD_PHYS;
	        else
	            vm_pDMAreg->DISRC3   = (int)MMCFIFO_BYTE_PHYS;
            vm_pDMAreg->DISRCC3    |= (SOURCE_PERIPHERAL_BUS | FIXED_SOURCE_ADDRESS);              // Source is periperal bus, fixed addr
            vm_pDMAreg->DIDST3 = (int)m_pDMABufferPhys.LowPart; 
            vm_pDMAreg->DIDSTC3 &= ~(DESTINATION_PERIPHERAL_BUS | FIXED_DESTINATION_ADDRESS);  // Destination is system bus, increment addr
            //----- 3c. Configure the DMA channel's transfer characteristics: handshake, sync PCLK, interrupt, -----
            //         single RX, single service,, MMC request, no auto-reload, word (32 bits), RX count
   	        vm_pDMAreg->DCON3  = (  HANDSHAKE_MODE | GENERATE_INTERRUPT | MMC_DMA0 | DMA_TRIGGERED_BY_HARDWARE 
	       	                            | NO_DMA_AUTO_RELOAD );
	        if (m_DATATransferSize == 4)
	        	if (m_bUseDMABurst)
    	        	vm_pDMAreg->DCON3  |= ( SELECT_BURST_TRANSFER | TRANSFER_WORD | ((pRequest->BlockSize >> 4) * pRequest->NumBlocks));
	        	else
    	        	vm_pDMAreg->DCON3  |= ( TRANSFER_WORD | ((pRequest->BlockSize >> 2) * pRequest->NumBlocks));
	        else if (m_DATATransferSize == 2)
    	        vm_pDMAreg->DCON3  |= ( TRANSFER_HALF_WORD | ((pRequest->BlockSize >> 1) * pRequest->NumBlocks));
	        else
    	        vm_pDMAreg->DCON3  |= ( TRANSFER_BYTE | ((pRequest->BlockSize) * pRequest->NumBlocks));
            break;

        default:
            ASSERT(0); // invalid DMA Channel... we should never get here
        }   

        //----- 3d. Setup the controller and DMA channel appropriately -----
       	vm_pSDIReg->SDIDCON   = RECEIVE_AFTER_COMMAND | TRANSFER_BLOCK_MODE | Get_SDI_Bus_Width() | DMA_ENABLE | DATA_TRANS_START | DATA_RECEIVE_START | pRequest->NumBlocks;
        if (m_DATATransferSize == 4)
        	if (m_bUseDMABurst)
        		vm_pSDIReg->SDIDCON  |= (BURST4_ENABLE | DATA_SIZE_WORD);
        	else
        		vm_pSDIReg->SDIDCON  |= DATA_SIZE_WORD;
        else if(m_DATATransferSize == 2)
         	vm_pSDIReg->SDIDCON  |= DATA_SIZE_HWORD;
        else
        	vm_pSDIReg->SDIDCON  |= DATA_SIZE_BYTE;

        break;
    
    case SD_WRITE:

        //********* 4. WRITE request *********
        m_dwLastTypeOfTransfer = SD_WRITE;

        //----- 4a. Reset the FIFO -----
        vm_pSDIReg->SDIDTIMER   = MAX_DATABUSY_TIMEOUT;        
        vm_pSDIReg->SDIBSIZE      = pRequest->BlockSize;
      

⌨️ 快捷键说明

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