中断处理的执行代码在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); } } }