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

📄 sdiocontrollerbase.cpp

📁 我自己编译的armv4i wince60模拟器的bps源文件,已经验证可以使用,欢迎下载
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                                                pBlockCaps->ReadBlockSize, pBlockCaps->ReadBlocks));

            DEBUGMSG(SDCARD_ZONE_INFO, (TEXT("SDHCD:SDHCDSlotOptionHandler() - Write Block Length: %d , Write Blocks: %d\n"), 
                                                pBlockCaps->WriteBlockSize, pBlockCaps->WriteBlocks));

            pBlockCaps = (PSD_HOST_BLOCK_CAPABILITY)pData;

            //----- Validate block transfer properties -----
            if (pBlockCaps->ReadBlockSize < MINIMUM_BLOCK_TRANSFER_SIZE )
            {
                pBlockCaps->ReadBlockSize = MINIMUM_BLOCK_TRANSFER_SIZE;
            }

            if (pBlockCaps->WriteBlockSize < MINIMUM_BLOCK_TRANSFER_SIZE )
            {
                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")));
            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")));
           status = SD_API_STATUS_INVALID_PARAMETER;

    }
    DEBUGMSG (SDCARD_ZONE_FUNC,(TEXT("SDHCDSlotOptionHandler ends")));
    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)"), pRequest->CommandCode));
    SD_API_STATUS   status;

    // Reset FIFO and status registers
    vm_pSDIReg->SDICON |= RESET_FIFO;
    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;

    //----- 2 Can we schedule a DMA operation using the caller's buffer as-is?  -----
    //
    //        There are two situations that we need to account for:
    //
    //             1) A non-DWORD aligned buffer
    //             2) A buffer whose "transfer size" isn't a multiple of sizeof(DWORD)
    //
    //        For the first case, an data-alignment exception will occur if the buffer is
    //        addressed at the non-DWORD aligned address.  For the second case, the SDI 
    //        controller will pad zeros into the remaining bytes of the last unfilled DWORD.  
    //        Practically, this means that the SD Card will get a corrupted data string.
    //
    //        To handle these two situations, we can simply use our polling I/O routines to
    //        fulfill the I/O request.
    //
    if( ( m_dwDMAChannel == 0xffffffff ) || (!IS_BUFFER_DWORD_ALIGNED(pRequest->pBlockBuffer)) || (!IS_BUFFER_SIZE_A_DWORD_MULTPLE(pRequest->BlockSize)) || m_dwNumBytesToTransfer > MAXIMUM_DMA_TRANSFER_SIZE )
    {   
        m_bUseDMAForTransfer = FALSE;
        SetupPollingXfer(pRequest);                     // Use polling I/O routines for data transfer
    }else{
        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);

        if(!SD_API_SUCCESS(status))
        {
            DEBUGMSG(SDCARD_ZONE_ERROR, (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);

        if(!SD_API_SUCCESS(status))
        {
            DEBUGMSG(SDCARD_ZONE_ERROR, (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")));
    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 \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!\n")));
            return FALSE;
        }

        if(m_bDriverShutdown) 
        {
            DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("SDHCD:TransferIstThread(): Thread Exiting\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")));
                status = SD_API_STATUS_INVALID_DEVICE_REQUEST;
                goto TRANSFER_DONE;
            }
        }

        //----- 3. 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;
            //----- 4. 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")));
                    status = SD_API_STATUS_DATA_TIMEOUT;
                    goto TRANSFER_DONE;
                }

                if( !IsCardPresent() )
                {
                    DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SDHControllerIstThread() - Card ejected!\r\n")));
                    status = SD_API_STATUS_DEVICE_REMOVED;
                    goto TRANSFER_DONE;
                }
                if((vm_pSDIReg->SDIDSTA & FIFO_FAIL_ERROR))
                {
                    vm_pSDIReg->SDIDSTA = BUSY_CHECKS_FINISH | FIFO_FAIL_ERROR;
                    DEBUGMSG(SDCARD_ZONE_ERROR, (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")));
                    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")));
                    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")));
                    status = SD_API_STATUS_DATA_TIMEOUT;
                    goto TRANSFER_DONE;
                }
            }
            vm_pSDIReg->SDIDSTA = BUSY_CHECKS_FINISH;
        }

        //----- 5. 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));
                goto TRANSFER_DONE;     
            }
        }

        //----- 6. If this is a data transfer, start the I/O operation; otherwise, finish the request -----
        if(pRequest->TransferClass == SD_COMMAND)
        {
            goto TRANSFER_DONE;
        }


        //----- 7. If this is a DMA transfer, we enable interrupts and wait for the DMA interrupt.  Otherwise, -----
        //         we use our polling routines to complete the I/O.
        if(m_bUseDMAForTransfer == FALSE)
        {

            //----- 8. Polling I/O, use our special routines to handle this request
            switch(pRequest->TransferClass)
            {
            case SD_READ:
                if(!PollingReceive(pRequest, m_dwNumBytesToTransfer))
                {
                    DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:BusRequestHandler() - PollingReceive() failed\r\n")));
                    goto TRANSFER_DONE;
                }
                break;

            case SD_WRITE:
                if(!PollingTransmit(pRequest, m_dwNumBytesToTransfer))
                {
                    DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:BusRequestHandler() - PollingReceive() failed\r\n")));
                    goto TRANSFER_DONE;
                }
                break;
            }

            status = SD_API_STATUS_SUCCESS;
        }else
        {


            //----- 9. For WRITE requests, be sure to copy the write data from the caller's buffer into DMA memory-----

⌨️ 快捷键说明

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