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

📄 async_mmc.c

📁 DSP/BIOS Driver Developer Kit 1.11 The DSP/BIOS Driver Developer Kit (DDK) provides a selection of
💻 C
字号:
/*
 *  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)" */
/*
 *  ======== async_mmc.c ========
 * 
 *  MMC Driver Async Test for the MMC on a C5509 DSP EVM.
 *  The test is to transfer data from DSP memory to the MMC card
 *  (MMC write) or from the MMC card to DSP memory (MMC read)
 *  Data values placed in the memory are based on channel number, such as 
 *  0x00010001 transfered for channel one, 0x00050005 for channel 5.
 *  
 *  User defines the following parameters:
 *  
 *  -- CHANNUM: Number of channels to be opened
 *  -- MMCREQNUM: Number of IOPs for each channel
 *  -- TRANSFERCOUNT: # of words to be transfered
 */
#include <stdio.h>
#include <std.h>
#include <log.h>
#include <sys.h>
#include <tsk.h>

#include <gio.h>
#include <iom.h>
#include <async.h>

#include <csl_mmc.h>
#include <c5509_mmc.h>   

/*  Test Configuration Parameters */
#define CHANNUM        4   /* Maximum number of channels */
        /* A task is spawned for each channel */
#define MMCREQNUM      4   /* Depth of each request queue */
        /* Constraint: MMCREQNUM must always be even */

/* interrupt mask definitions */
#define C5509_MMC_IER0_MASK_DEFAULT 1
#define C5509_MMC_IER1_MASK_DEFAULT 1

extern LOG_Obj   trace;

/*  Reserve space for channels */
static C5509_MMC_ChanObj  chans[CHANNUM];

/*  Globals  */
C5509_MMC_DevObj    C5509_MMC_devObj;

/*  Bind Parameters  */
C5509_MMC_DevParams  C5509_MMC_devParams = {
    /* devParams */
    C5509_MMC_VERSION_1, /* Version number */
    0,    /* Enable/disable DMA for data read/write */
    0,    /* dat3EdgeDetection -- DUMMY */
    0,    /* Determines if MMC goes IDLE during IDLE instr */
    0,    /* enableClkPin -- DUMMY */
    2,    /* CPU CLK to MMC function clk divide down */
    3,    /* MMC function clk to memory clk divide down */
    0,    /* 
           *  No. memory clks to wait before response timeout
           *  Zero indicates no timeout.
           */
    0,    /* 
           *  No. memory clks to wait before data timeout 
           *  Zero indicates no timeout.
           */
    512,   /* Length of DATA block to be read in BYTEs*/     

    /* drvrParams */
    2,     /* RCA - set by the application */
    CHANNUM,                 /* maximum number of channels required */
    MEDIA_BYTENORMAL,        /* MEDIA_[BYTESWAP|BYTENORMAL] */
    0,     /* DMA channel number used for READ operations */  
    0,     /* DMA channel number used for WRITE operations */
    NULL,  /* Buffer for DMA read */
    NULL,  /* Buffer for DMA write */
    chans,  /* Array of (noChan number of) Channel Objs */
    C5509_MMC_IER0_MASK_DEFAULT,
    C5509_MMC_IER1_MASK_DEFAULT
};

/* User defined constants */
#define TRANSFERCOUNT           C5509_MMC_SECLEN

#define SLEEPTIME               10

typedef struct CallbackObj {
    Int   chanNum;     /* trace the channel number */
    Int   reqNum;      /* index for trace submitted request */
    Int   cmd;         /* IOM_READ/IOM_WRITE */
    MdUns value;       /* value to write to memory, then read it back */  
    Bool  packetFree;  /* if the packet is free to use */ 
} CallbackObj;

static Void chanCallback(Ptr arg, Int status, Ptr reqp, Uns size);
static Void chanTsk(Arg chanNum);
static Void setMem(Int count, MdUns *memAddr, MdUns value);
static Bool verifyData(Int chanNum, Ptr reqp, MdUns value);

static GIO_Handle   gio[CHANNUM];

/* Declare here so that the stack space is conserved */
static MdUns globalSectorBuffers[CHANNUM][MMCREQNUM][C5509_MMC_SECLEN];

/*
 *  ======== main ========
 */
Void main()
{   
    TSK_Attrs tskAttrs[CHANNUM];
    GIO_Attrs gioAttrs[CHANNUM];
    Int       i;
    
    for (i = 0; i < CHANNUM; i++) {
        /* GIO_Attrs init */
        gioAttrs[i].nPackets = MMCREQNUM;
        gioAttrs[i].timeout = SYS_FOREVER; 
    }

    /* create IOM objs */
    for (i = 0; i < CHANNUM; i++) {
        gio[i] = ASYNC_create("/udevMmc0", IOM_INOUT, NULL, NULL, &gioAttrs[i]);
        if (gio[i] == NULL) {
            LOG_printf (&trace, "ERROR: GIO_create NULL!");
        }
    }
    
    /* create tasks */
    for (i = 0; i < CHANNUM; i++) {
        tskAttrs[i] = TSK_ATTRS;
        if (TSK_create ((Fxn)chanTsk, &tskAttrs[i], (Arg)i) == NULL) {
            LOG_printf (&trace, "ERROR: TSK_create NULL!");
        }
    }     
    
    LOG_printf (&trace, "Exitting main");  
    /* fall into DSP/BIOS idle loop */
    return;
}

/*
 *  ======== chanCallback ========
 *  Handle callback
 */
static Void chanCallback(Ptr arg, Int status, Ptr reqp, Uns size)
{
    CallbackObj    *pCallback = (CallbackObj *)arg;
    MEDIA_RdWrObj  *req = (MEDIA_RdWrObj *)reqp;
    Int            chanNum = pCallback->chanNum;

    /*
     * if this callback is for ASYNC_read, then check 
     * if read value = written value 
     */
    if (pCallback->cmd == IOM_READ) {
        if (verifyData(chanNum, req, pCallback->value)) {
            LOG_printf (&trace, "[%d] verifyData OK!", chanNum);
        }
        else {
            LOG_printf (&trace, "[%d] ERROR: verifyData Failed!", chanNum);
        }
    }

    pCallback->packetFree = TRUE;
}

/*
 *  ======== chanTsk ========
 */
static Void chanTsk(Arg channelNumber)
{
    Uns              size;
    Int              status;
    MEDIA_RdWrObj    req[MMCREQNUM];
    MEDIA_RdWrObj    *curReq;
    GIO_AppCallback  gioCallback[MMCREQNUM]; 
    CallbackObj      callback[MMCREQNUM];
    MdUns            value; 
    Int              submitReqIndex;
    Int              j;
    Int              chanNum;
    Int              yieldCount;

    chanNum = ArgToInt(channelNumber);

    value = (MdUns)(chanNum | 0xAA00);

    /* First set write req, then set read request */
    /* A paired write and read operate on the same sectorNumber */
    for (j = 0; j < MMCREQNUM; j = j + 2) {
        /* MMC write : DSP->MMC Card */        
        req[j].buf = globalSectorBuffers[chanNum][j];
        req[j].address = chanNum * 100 + j;
        req[j].subAddress = 0;
        req[j].length = C5509_MMC_SECLEN;
        callback[j].cmd = IOM_WRITE;
           
        /* MMC read : MMC Card->DSP */
        req[j + 1].buf = globalSectorBuffers[chanNum][j + 1];
        req[j + 1].address = chanNum * 100 + j;
        req[j + 1].subAddress = 0;     
        req[j + 1].length = C5509_MMC_SECLEN;
        callback[j + 1].cmd = IOM_READ;
    }

    for (j = 0; j < MMCREQNUM; j++) {
        callback[j].chanNum = chanNum;
        callback[j].reqNum = j;
        callback[j].value = value;
        callback[j].packetFree = TRUE;

        gioCallback[j].fxn = (GIO_TappCallback)chanCallback;
        gioCallback[j].arg = (Ptr)(&callback[j]);
    }

    submitReqIndex = 0;
    for (;;) {
        yieldCount = 0;
        LOG_printf (&trace, "[%d] IsPacketFreeAt [%d]",
            chanNum, submitReqIndex);

        while (!callback[submitReqIndex].packetFree) {
            yieldCount++;
            TSK_sleep (SLEEPTIME);
        }
        LOG_printf (&trace, "[%d] Slept [%d] times", chanNum, yieldCount);
        
        callback[submitReqIndex].packetFree = FALSE;

        curReq = (MEDIA_RdWrObj *)(&req[submitReqIndex]);
        
        if (callback[submitReqIndex].cmd == IOM_WRITE) {
            /*  
             * set dsp memory value as chanNum chanNum ...
             * (for example: 0x0001 0x0001 ... for Chan1) 
             */ 
            setMem(TRANSFERCOUNT, curReq->buf, value);

            /* MMC write: DSP->MMC. Write the value to MMC card */
            size = sizeof (*curReq);
            status = ASYNC_write(gio[chanNum], curReq, &size, 
                    &gioCallback[submitReqIndex]);
            if (status < 0) {
                LOG_printf (&trace, "[%d] ERROR: ASYNC_write status [%d]",
                    chanNum, status);
            }
        } else {  /* IOM_READ */
            /* first set dsp mem value to default 0xDEAD */
            setMem(TRANSFERCOUNT, curReq->buf, 0xDEAD);
        
            /* MMC read: MMC->DSP. Readback MMC card contents to DSP memory */
            size = sizeof (*curReq);
            status = ASYNC_read(gio[chanNum], curReq, &size, 
                    &gioCallback[submitReqIndex]);
            if (status < 0) {
                LOG_printf (&trace, "[%d] ERROR: ASYNC_read status [%d]", 
                    chanNum, status);
            }
        }

        submitReqIndex++;
        if (submitReqIndex == MMCREQNUM) {
            submitReqIndex = 0;
        }

        TSK_yield (); /* Yield control to another task */
    }
}

/*
 *  ======== setMem ========
 *  Set memory value
 */
static Void setMem(Int count, MdUns *memAddr, MdUns value)
{
    MdUns *tempMem = (MdUns *)memAddr;
    Int   i;
    
    for (i = 0; i < count; i++) {
        *tempMem = value;
        tempMem++;
    }   
}

/*
 *  ======== verifyData ========
 *  Verify read back data 
 */
static Bool verifyData(Int chanNum, Ptr reqp, MdUns value)
{
    MEDIA_RdWrObj *req;
    MdUns         *addr; 
    Int           i;
    
    req = (MEDIA_RdWrObj *)reqp;
    
    if (req != NULL) {
       addr = (MdUns *)req->buf;
       for (i = 0; i < req->length; i++) {
           if (*addr != value) {
               LOG_printf (&trace, "[%d] ERROR: in verifyData at addr [0x%x]", 
                       chanNum, addr);
               return FALSE;
           }
           addr++;
       }
    }
    return TRUE;
}

⌨️ 快捷键说明

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