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

📄 sdiocontrollerbase.cpp

📁 2440 SD卡驱动源码第二部分继续上传
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            {
                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 + -