您的位置:首页 > 其它

at91_sdcard源码分析(5)-中断处理

2014-03-23 22:49 316 查看
中断处理的执行代码在MCI_Handler函数中:

//------------------------------------------------------------------------------
/// Processes pending events on the given MCI driver.
/// \param pMci  Pointer to a MCI driver instance.
//------------------------------------------------------------------------------
void MCI_Handler(Mci *pMci)
{
    AT91S_MCI *pMciHw = pMci->pMciHw;
    MciCmd *pCommand = pMci->pCommand;
    unsigned int status;
    unsigned char i;
    #if defined(at91rm9200)
    unsigned int mciCr, mciSdcr, mciMr, mciDtor;
    #endif

    SANITY_CHECK(pMci);
    SANITY_CHECK(pMciHw);
    SANITY_CHECK(pCommand);

// Read the status register
//读取状态寄存器
    status = READ_MCI(pMciHw, MCI_SR) & READ_MCI(pMciHw, MCI_IMR);
    // TRACE_DEBUG("status %x\n\r", status);

    // Check if an error has occured
    if ((status & STATUS_ERRORS) != 0) {//传输有错误发生

        // Check error code
        if ((status & STATUS_ERRORS) == AT91C_MCI_RTOE) {//命令发送超时

            pCommand->status = MCI_STATUS_NORESPONSE;
        }
        // if the command is SEND_OP_COND the CRC error flag is always present
        // (cf : R3 response)
        else if (((status & STATUS_ERRORS) != AT91C_MCI_RCRCE)
                  || ((pCommand->cmd != SDCARD_APP_OP_COND_CMD)
                      && (pCommand->cmd != MMC_SEND_OP_COND_CMD))) {

            pCommand->status = MCI_STATUS_ERROR;
        }
    }

    // Check if a transfer has been completed
    if (((status & AT91C_MCI_CMDRDY) != 0)
        || ((status & AT91C_MCI_ENDRX) != 0)
        || ((status & AT91C_MCI_RXBUFF) != 0)
        || ((status & AT91C_MCI_ENDTX) != 0)
        || ((status & AT91C_MCI_BLKE) != 0)
        || ((status & AT91C_MCI_RTOE) != 0)) {

        if (((status & AT91C_MCI_ENDRX) != 0)
            || ((status & AT91C_MCI_RXBUFF) != 0)
            || ((status & AT91C_MCI_ENDTX) != 0)) {

            MCI_Enable(pMci, DISABLE);
        }

        /// On AT91RM9200-EK, if stop transmission, software reset MCI.
        #if defined(at91rm9200)
        if ((pCommand->cmd & AT91C_MCI_TRCMD_STOP) != 0) {
            mciMr = READ_MCI(pMciHw, MCI_MR);
            mciSdcr = READ_MCI(pMciHw, MCI_SDCR);
            mciDtor = READ_MCI(pMciHw, MCI_DTOR);
            WRITE_MCI(pMciHw, MCI_CR, AT91C_MCI_SWRST);
            // TRACE_DEBUG("reset MCI\n\r");

            WRITE_MCI(pMciHw, MCI_CR, AT91C_MCI_MCIDIS | AT91C_MCI_PWSDIS);
            WRITE_MCI(pMciHw, MCI_MR, mciMr);
            WRITE_MCI(pMciHw, MCI_SDCR, mciSdcr);
            WRITE_MCI(pMciHw, MCI_DTOR, mciDtor);
        }
        #endif

        // If no error occured, the transfer is successful
        if (pCommand->status == MCI_STATUS_PENDING) {//在命令发送前设置了这个值
            pCommand->status = 0;  //说明命令发送成功。
        }
#if 0
        if ((status & AT91C_MCI_CMDRDY) != 0)
            TRACE_DEBUG_WP(".");
        if ((status & AT91C_MCI_ENDRX) != 0)
            TRACE_DEBUG_WP("<");
        if ((status & AT91C_MCI_ENDTX) != 0)
            TRACE_DEBUG_WP("-");
        if ((status & AT91C_MCI_BLKE) != 0)
            TRACE_DEBUG_WP(">");
        TRACE_DEBUG_WP("\n\r");
#endif
        // Store the card response in the provided buffer
        if (pCommand->pResp) {//发送前设置了此变量
            unsigned char resSize;
            //判断接收的数据的大小
            switch (pCommand->resType) {
                case 1:
                resSize = 1;
                break;

                case 2:
                resSize = 4;
                break;

                case 3:
                resSize = 1;
                break;

                case 4:
                resSize = 1;
                break;

                case 5:
                resSize = 1;
                break;

                case 6:
                resSize = 1;
                break;

                case 7:
                resSize = 1;
                break;

                default:
                resSize = 0;
                break;
            }
            for (i=0; i < resSize; i++) { //读取接收的数据

                pCommand->pResp[i] = READ_MCI(pMciHw, MCI_RSPR[0]);
            }
        }

        // Disable interrupts
        WRITE_MCI(pMciHw, MCI_IDR, READ_MCI(pMciHw, MCI_IMR));

        // Release the semaphore
        pMci->semaphore++;  //释放信号量

        // Invoke the callback associated with the current command (if any)
        if (pCommand->callback) {//如果设置了callback,则调用它
            (pCommand->callback)(pCommand->status, pCommand);
        }
    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐