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

📄 c5509_mmc.c

📁 MSP430与dsp接口技术1,编辑环境C语言,我运行过,好
💻 C
📖 第 1 页 / 共 3 页
字号:
            mediaStr->stateParameter = ISTINVALID;

            if (pPacket->cmd == IOM_WRITE && mediaStr->length != SECLEN) {
                pPacket->cmd = IOM_READ;
                mediaStr->atomicStatus = ISTATOMICREAD;
                mediaStr->stateParameter = ISTGETSTATUS;
            }

            intrMask = HWI_disable();

            /*  Que this request if already currPacket has something */
            if (mmcChan->pHandle->currPacket != NULL) {
                QUE_enqueue (&mmcChan->pHandle->pendList, pPacket);
                HWI_restore (intrMask);
            }
            else { 
                /* since there is nothing pending, process this request */
                mmcChan->pHandle->currPacket = pPacket;
                HWI_restore (intrMask);

                mediaStr->stateParameter = ISTGETSTATUS;
                _MMC_MMCCIE_SET (mmcChan->pHandle->mmcDevNum,
                    REGVALMMCIESTATUS);
                MMC_sendCmd (mmcChan->pHandle->cslMMC, MMC_SEND_STATUS,
                    mmcChan->pHandle->drvrParams.mmcCardId,
                    MMC_STUFF_BITS, 0);
            }

            return (IOM_PENDING);
        
        case IOM_FLUSH:
        case IOM_ABORT:
            pPacket->addr = (C5509_MMC_ChanObj *)mmcChan;

            intrMask = HWI_disable();

            if (mmcChan->pHandle->currPacket != NULL) {
                currStr = (C5509_MMC_RdWrObj *)
                                mmcChan->pHandle->currPacket->addr;

                /* 
                 *  if queue is empty and current packet is not for this 
                 *  channel, then just return 
                 */
                if (QUE_empty (&mmcChan->pHandle->pendList) &&
                        currStr->pChan != mediaStr->pChan) {
                    status = IOM_COMPLETED;
                    goto FLUSHDONE;
                }
            }
            else {
                /*  
                 *  this means current packet is null, 
                 *  check if the queue is empty, if so return
                 */
                if (QUE_empty (&mmcChan->pHandle->pendList)) {
                    status = IOM_COMPLETED;
                    goto FLUSHDONE;
                }
            }
        
            status = abortFlush (mmcChan, pPacket->cmd, pPacket);

FLUSHDONE:
            HWI_restore (intrMask);

            return (status);
            
        default:
            return (IOM_ENOTIMPL);
    }
}

/*
 *  ======== mdDeleteChan ========
 *
 *  Deletes an instance of a channel object
 */
 
static Int mdDeleteChan(Ptr chanp)
{
    C5509_MMC_ChanObj   *mmcChan;
    Uns                 intrMask;
    
    mmcChan = (C5509_MMC_ChanObj *)chanp;
    
    intrMask = HWI_disable();

    /*  Set the channel as free.  */
    mmcChan->inUse = FALSE;

    mmcChan->pHandle->chOpenCount--;
    if (mmcChan->pHandle->chOpenCount == 0) {
        IRQ_disable ((mmcChan->pHandle->mmcDevNum == 0) ? INT7 : INT13);
    }
    
    HWI_restore (intrMask);

    return (IOM_COMPLETED);
}

 
/*
 *  ======== abortFlush ========
 * 
 *  This function takes care of performing abort and flush operations
 *  on a given channel.
 *  This function is called with interrupts disabled.
 */

static Int abortFlush(C5509_MMC_ChanObj *mmcChan, Uns cmd, IOM_Packet *pPack)
{
    QUE_Elem           *qelem;
    QUE_Elem           *tempElem;
    QUE_Elem           *waitElem;
    IOM_Packet         *pPacket;
    C5509_MMC_RdWrObj  *mediaStr;
    Int                retval;

    waitElem = NULL;
    
    /* Unless a WRITE is pending in case of FLUSH this would not change */
    retval = IOM_COMPLETED;

    /* get pointer to first element in the queue */
    qelem = QUE_head (&mmcChan->pHandle->pendList);
    
    /* 
     *  Traverse through the request queue and identify
     *  the request for this particular channel. 
     *  For abort command, complete all the requests with
     *  an error status and remove them from the queue.
     *  For flush command, complete all read requests with
     *  error status and remove them from the queue.
     */
    while (qelem != &mmcChan->pHandle->pendList) {
        pPacket = (IOM_Packet *)qelem;
        mediaStr = (C5509_MMC_RdWrObj *)pPacket->addr;

        if (mediaStr->pChan == mmcChan) {
            if ((cmd == IOM_FLUSH && pPacket->cmd == IOM_READ &&
                    mediaStr->atomicStatus != ISTATOMICREAD) ||
                    cmd == IOM_ABORT) {
                Int    status;

                if (cmd == IOM_FLUSH) {
                    status = IOM_FLUSHED;
                }
                else {
                    status = IOM_ABORTED;
                }
                tempElem = qelem;
                qelem = QUE_next (qelem);
                QUE_remove (tempElem);
                CALLBACK (mediaStr->pChan, pPacket, status);

                continue;
            }
            /*  This element tracks the last pending write in the queue  */
            waitElem = qelem;
        }
        qelem = QUE_next(qelem);
    }

    /*
     *  Now insert IOM_FLUSH packet in the queue so that it is processed
     *  after all write-requests have completed
     */

    if (waitElem == NULL) {
        pPacket = mmcChan->pHandle->currPacket;
        mediaStr = (C5509_MMC_RdWrObj *)pPacket->addr;
        /*
         *  If a write operation is in progress on the current channel,
         *  wait for it to complete.
         */
        if ((mediaStr->pChan == mmcChan) &&
                ((pPacket->cmd == IOM_WRITE) ||
                 (pPacket->cmd == IOM_READ
                    && mediaStr->atomicStatus == ISTATOMICREAD))) {
            waitElem = QUE_head (&mmcChan->pHandle->pendList);
            QUE_insert (waitElem, pPack);
            retval = IOM_PENDING;
        }
    }
    else {
        waitElem = QUE_next (waitElem);
        QUE_insert (waitElem, pPack);
        retval = IOM_PENDING;
    }
    
    /*
     * if pPack is queued, it would be queued with pPack->status
     * as IOM_PENDING, which is also sematically correct
     */
    pPack->status = retval;
    
    return (retval);
}

/*
 *  ======== issueReadWrite ========
 *  
 *  Function for issuing the Read and Write Command
 *  Called from the ISR - in interrupt context.
 */

static Void issueReadWrite(IOM_Packet *pPacket, C5509_MMC_DevObj *ptrState)
{
    C5509_MMC_RdWrObj  *mediaStr;
    LgUns              address;
    LgUns              sectorNumber;
    MdUns              track;
    
    mediaStr = (C5509_MMC_RdWrObj *)pPacket->addr;
    sectorNumber = mediaStr->sectorNumber;
    address = sectorNumber << 9;

    if (pPacket->cmd == IOM_WRITE) {
        if ((mediaStr->length == SECLEN) || mediaStr->offset == 0) {
            track = mediaStr->buf[0];
        }
        else {
            /* in this case, atomicStatus == ISTATOMICWRITE */
            track = mediaStr->pChan->pHandle->buf[0];
        }

        /* check if the byte-order needs to change */
        if (ptrState->drvrParams.byteOrder == MEDIA_BYTESWAP) {
            track = MEDIA_SWAPBYTES (track);
        }

        /* load the data transmission register with the first word */
        _MMC_MMCDXR_SET (mediaStr->pChan->pHandle->mmcDevNum, track);
    }
    
    /*  Set the Number of Blocks needed to be read, in this case it is 1 */
    _MMC_MMCNBLK_SET (mediaStr->pChan->pHandle->mmcDevNum, NBLK);
    
    /*  Set the Block Length  */
    _MMC_MMCBLEN_SET (mediaStr->pChan->pHandle->mmcDevNum,
                      mediaStr->pChan->pHandle->blockLen);
    
    /*  Set the value of ARGL  */
    _MMC_MMCARGL_SET (mediaStr->pChan->pHandle->mmcDevNum,
                      (MdUns)(address & 0xFFFF));
    
    /*  Set the value of ARGH  */
    _MMC_MMCARGH_SET (mediaStr->pChan->pHandle->mmcDevNum,
                      (MdUns)((address >> 16) & 0xFFFF));
    
    /*  Check for COMMAND and send a READ or WRITE command.  */
    if (pPacket->cmd == IOM_WRITE) {
        _MMC_MMCCMD_SET (mediaStr->pChan->pHandle->mmcDevNum,
            MMC_WRITE_BLOCK | CMDDATA | CMDDCLR | CMDWRITE);
    }
    else if (pPacket->cmd == IOM_READ) {
        _MMC_MMCCMD_SET (mediaStr->pChan->pHandle->mmcDevNum,
            MMC_READ_SINGLE_BLOCK | CMDDATA | CMDDCLR);
    }
}

/*
 *  ======== handlerReadWrite ========
 *  
 *  Read and Write Data from and to the MMC 
 *  Called from the ISR - in interrupt context.
 */

static Void handlerReadWrite(IOM_Packet *pPacket,
                             C5509_MMC_DevObj *ptrState, Uns error)
{
    C5509_MMC_ChanObj *afChan;
    C5509_MMC_RdWrObj *mediaStr;
    MdUns             k; 
    Int               newRequest = 0;
    Int               track = 0;
    Int               flag = 1;
    
    mediaStr  = (C5509_MMC_RdWrObj *)pPacket->addr;
    
    /* 
     *  afChan is used to store the channel pointer as it 
     *  is not provided in the request for ABORT and FLUSH.
     *  So we need to store it so that it can be used to 
     *  call the callback function, in case of ABORT and FLUSH.
     */
    afChan = mediaStr->pChan;
    if (pPacket->cmd == IOM_READ) {
        k = _MMC_MMCDRR_GET (ptrState->mmcDevNum);
        
        /*  Loading the buffer with the new data.  */
        if (mediaStr->count < SECLEN) {
            if (mediaStr->count >= mediaStr->offset && 
                mediaStr->count < (mediaStr->length + mediaStr->offset)) {
                if (mediaStr->atomicStatus != ISTATOMICREAD) {
                    if (ptrState->drvrParams.byteOrder == MEDIA_BYTESWAP) {
                        mediaStr->buf[mediaStr->count - mediaStr->offset] =
                                                            MEDIA_SWAPBYTES(k);
                    }
                    else {
                        mediaStr->buf[mediaStr->count - mediaStr->offset] = k;
                    }
                }
            }
            else if (mediaStr->atomicStatus == ISTATOMICREAD) {
                ptrState->buf[mediaStr->count] = k;
            }
        }
        
        /*  Incrementing the count of words read by one.  */
        mediaStr->count++; 
        
        /*  
         *  If the entire sector has been read, set the 
         *  stateParameter to ISTDATADONEREAD
         */
        if (mediaStr->count >= SECLEN) {
            mediaStr->stateParameter = ISTDATADONEREAD;
        }
        
        /*  State where the request will call the callback.  */
        if (mediaStr->count > SECLEN) {
            if (error) {
                /*  Re-set the cmd, if it had been changed earlier */
                pPacket->cmd = (mediaStr->atomicStatus == ISTATOMICREAD)
                               ? IOM_WRITE
                               : IOM_READ;
                CALLBACK (mediaStr->pChan, pPacket, IOM_EBADIO); 

⌨️ 快捷键说明

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