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

📄 c5509_mmc.c

📁 MSP430与dsp接口技术1,编辑环境C语言,我运行过,好
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 *  Copyright 2003 by Texas Instruments Incorporated.
 *  All rights reserved. Property of Texas Instruments Incorporated.
 *  Restricted rights to use, duplicate or disclose this code are
 *  granted through contract.
 *  
 */
/* "@(#) DDK 1.11.00.00 11-04-03 (ddk-b13)" */
/*
 * 
 *  ======== c5509_mmc.c ========    
 *
 *
 */

#include <std.h>
#include <hwi.h>
#include <que.h>
#include <iom.h>
#include <c5509_mmc.h>


/*  Native Mode Defines  */
#define ENABLECLKPIN       1
#define DAT3EDGEDETECTION  0

/*  Number of Data Blocks */
#define NBLK               1

/*  Command Register Defines  */
#define CMDDCLR            0x8000
#define CMDDATA            0x2000
#define CMDWRITE           0x0800

/*  MMCST0 (Status Register 0)
 *  Register fields prefixed with register name: ST0
 */
#define ST0WPED            0x1000
#define ST0DATED           0x0800
#define ST0DRRDY           0x0400
#define ST0DXRDY           0x0200
#define ST0SPIERR          0x0100
#define ST0CRCRS           0x0080
#define ST0CRCRD           0x0040
#define ST0CRCWR           0x0020
#define ST0TOUTRS          0x0010
#define ST0TOUTRD          0x0008
#define ST0RSPDNE          0x0004
#define ST0BSYDNE          0x0002
#define ST0DATDNE          0x0001

/*  MMC IE Register Values
 *  These defines are used to capture the interrupts that
 *  are enabled in the corresponding operations being
 *  performed on the MMC
 */
#define REGVALMMCIEREAD    MMC_MMCCIE_RMK(1,1,1,1,1,1,1,1,0,1,1)
#define REGVALMMCIEWRITE   MMC_MMCCIE_RMK(1,0,1,0,1,1,0,1,1,0,0)
#define REGVALMMCIESTATUS  MMC_MMCCIE_RMK(1,1,1,1,1,0,0,0,0,1,0)


/*
 *  MMC State Defines
 *  These will be used to indicate the current state of a
 *  request in the overall state machine.
 *  Namespace definition for C5509_MMC_RdWrObj::stateParameter.
 *  Internal states prefixed with IST.
 */
#define ISTBASEVALUE       0x1000  /* Base value for this namespace */
#define ISTINVALID         (ISTBASEVALUE + 0)
                                   /*
                                    * Applicable to stateParameter
                                    * and atomicStatus
                                    */
#define ISTSENDREAD        (ISTBASEVALUE + 1)
#define ISTSENDWRITE       (ISTBASEVALUE + 2)
#define ISTGETSTATUS       (ISTBASEVALUE + 3)
#define ISTDATADONEREAD    (ISTBASEVALUE + 4)
#define ISTDATADONEWRITE   (ISTBASEVALUE + 5)
/*
 *  Namespace definition for C5509_MMC_RdWrObj::atomicStatus.
 */
#define ISTATOMICWRITE     (ISTBASEVALUE + 6)
#define ISTATOMICREAD      (ISTBASEVALUE + 7)

/*  Read and Write sector length (in WORDs)  */
#define SECLEN            C5509_MMC_SECLEN

/*  CPU interrupt number for MMC  */

#define INT7                7   /* DEV 0 */
#define INT13              13   /* DEV 1 */

/*  Operating Voltage 3.2-3.4V  */
#define OPVOLTAGE          0x00300000

#define CALLBACK(chan,packet,result)                                    \
            do {                                                        \
                (packet)->status = (result);                            \
                ((chan)->callback)((Ptr)(chan)->callbackArg, (packet)); \
            } while(0)

/* Driver Functions */
static Int mdBindDev(Ptr* devp, Int devid, Ptr devParams);
static Int mdControlChan(Ptr chanp, Uns cmd, Ptr arg);
static Int mdCreateChan(Ptr *chanp, Ptr devp, String name, Int mode, 
                Ptr chanParams, IOM_TiomCallback cbFxn, Ptr cbArg);
static Int mdDeleteChan(Ptr chanp);
static Int mdSubmitChan(Ptr chanp, IOM_Packet *pPacket);

/*  Helper Functions */
static Int abortFlush(C5509_MMC_ChanObj *pChan, Uns cmd, IOM_Packet *pPacket);
static Void issueReadWrite(IOM_Packet *pPacket, C5509_MMC_DevObj *ptrState);
static Void handlerReadWrite(IOM_Packet *pPacket, 
                C5509_MMC_DevObj *ptrState, Uns error);

/* MMC ISR */
static Void isrMMC(Ptr ptrAttr);

/*  MMC Reset Functions  */
static Int initMMC(C5509_MMC_DevObj *ptrState, C5509_MMC_DevParams *mmcParams);
static Int resetMMC(C5509_MMC_DevObj *ptrState);
static Int reinitializeMMC(C5509_MMC_DevObj *ptrState);

/*
 * Public Mini Driver interface table.
 */
IOM_Fxns C5509_MMC_FXNS =
{
    &mdBindDev,
    IOM_UNBINDDEVNOTIMPL,
    &mdControlChan,
    &mdCreateChan,
    &mdDeleteChan,
    &mdSubmitChan,
};


/*
 *  ======== mdBindDev ========
 *
 *  Creates an instance of MMC device. Will be called to bind the device.
 */

static Int mdBindDev(Ptr* devp, Int devid, Ptr devParams)
{
    C5509_MMC_DevObj    *mmcHandle;
    C5509_MMC_DevParams *mmcParams;
    HWI_Attrs           attrs;
    Int                 i;
    
    mmcParams = (C5509_MMC_DevParams *)devParams;
    mmcHandle = (C5509_MMC_DevObj *)(*devp);
    
    if (*devp == NULL) {
        return (IOM_EBADIO);
    }

    if (devParams == NULL) {
        return (IOM_EBADARGS);  /* requires device params */
    }

    /* Check the version number */
    if(mmcParams->versionId != C5509_MMC_VERSION_1){
        return(IOM_EBADARGS);
    }

    /*  Fill up mmcHandle with mmcParams  */
    mmcHandle->mmcDevNum = devid; /* MMC controller 0 or 1 */

    /*  Copy structure containing all driver config parameters.  */
    mmcHandle->drvrParams = mmcParams->drvrParams;

    mmcHandle->blockLen = mmcParams->devParams.blockLen;
    mmcHandle->currPacket = NULL;
    mmcHandle->cslMMC = NULL;

    mmcHandle->chOpenCount = 0;
    
    /*  Set all available channels as free  */
    for (i = 0; i < mmcHandle->drvrParams.noChan; i++) {
        mmcHandle->drvrParams.pChan[i].inUse = FALSE;
    }
    
    /*  Reset the MMC before using it  */
    if (initMMC (mmcHandle, mmcParams) != IOM_COMPLETED) {
        return (IOM_EBADIO);
    }
    
    /*  Create the pending request queue */
    QUE_new (&mmcHandle->pendList);
    
    /*  Enable the MMC Interrupt  */
    attrs.ier0mask = mmcParams->ier0Mask;
    attrs.ier1mask = mmcParams->ier1Mask;
    attrs.arg = (Arg)(*devp);
    HWI_dispatchPlug ((devid == 0) ? INT7 : INT13, (Fxn)isrMMC, &attrs);

    /* Successfully initialized, so return */
    return (IOM_COMPLETED);
}


/*
 *  ======== mdControlChan ========
 * 
 *  The Mini driver control function. 
 *  Currently supports 2 commands - querying media type and 
 *  reinitializing the MMC (after unplug/plug)
 */

static Int mdControlChan(Ptr chanp, Uns cmd, Ptr arg)
{
    C5509_MMC_ChanObj   *mmcChan;
    
    mmcChan = (C5509_MMC_ChanObj *)chanp;

    switch (cmd) {

        case MEDIA_CTRL_GETMEDIATYPE:
            *(Int *)arg = C5509_MMC_MEDIATYPE;
            return (IOM_COMPLETED);

        case MEDIA_CTRL_REINITIALIZE:
            if (reinitializeMMC (mmcChan->pHandle) != IOM_COMPLETED) {
                *(Int *)arg = MEDIA_NOTPRESENT;
            }
            else {
                *(Int *)arg = MEDIA_PRESENT;
            }

            return (IOM_COMPLETED);

        default:
            return (IOM_ENOTIMPL);
    }
}


/*
 *  ======== mdCreateChan ========
 *
 *  Creates an instance of channel object which will be used 
 *  in future for sending commands on a particular channel 
 */
 
static Int mdCreateChan(Ptr *chanp, Ptr devp, String name, Int mode, 
                        Ptr chanParams, IOM_TiomCallback cbFxn, Ptr cbArg)
{
    C5509_MMC_DevObj    *mmcHandle;
    C5509_MMC_ChanObj   *mmcChan;
    Int                 i;
    Int                 found;
    Uns                 intrMask;
     
    mmcHandle = (C5509_MMC_DevObj *)devp;
    found = -1;

    if (mode != IOM_INOUT) {
        return (IOM_EBADMODE);
    }
    
    /*
     *  inUse is not really checked in the ISR - so this serialization is
     *  primarily to avoid multiple application-level threads of control
     *  to gain access to the same resource
     */
    intrMask = HWI_disable();

    /*  Checking for free channels  */
    for (i = 0; i < mmcHandle->drvrParams.noChan; i++) {
        if (mmcHandle->drvrParams.pChan[i].inUse == FALSE) {
            found = i;
            mmcHandle->drvrParams.pChan[i].inUse = TRUE;

            if (mmcHandle->chOpenCount == 0) {
                IRQ_enable ((mmcHandle->mmcDevNum == 0) ? INT7 : INT13);
            }
            mmcHandle->chOpenCount++;

            break;
        }
    }
    
    HWI_restore (intrMask);

    /*  If no Channel is free, return error  */
    if (found == -1) {
        return (IOM_EALLOC);
    }
    
    /*  Allocate the channel and mark it as INUSE.  */
    mmcChan = &(mmcHandle->drvrParams.pChan[found]);
    mmcChan->mode = mode;
    mmcChan->pHandle = mmcHandle;
    mmcChan->callback = cbFxn; 
    mmcChan->callbackArg = cbArg;
    
    *chanp = &(mmcHandle->drvrParams.pChan[found]);
    
    return (IOM_COMPLETED);
}

/*
 *  ======== mdSubmitChan ========
 *  
 *  This function provides read,write,abort and flush 
 *  functionality to the application. 
 */
 
static Int mdSubmitChan(Ptr chanp, IOM_Packet *pPacket)
{
    C5509_MMC_ChanObj    *mmcChan;
    C5509_MMC_RdWrObj    *mediaStr;
    C5509_MMC_RdWrObj    *currStr;
    Int                  status;
    Uns                  intrMask;
    
    mmcChan = (C5509_MMC_ChanObj *)chanp;
    mediaStr = (C5509_MMC_RdWrObj *)pPacket->addr;
    mediaStr->pChan = (C5509_MMC_ChanObj *)chanp;
    
    switch (pPacket->cmd) {
        case IOM_READ:
        case IOM_WRITE:
        
            /*  initialize mediastr */
            mediaStr->count = 0;
            mediaStr->atomicStatus = ISTINVALID;

⌨️ 快捷键说明

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