async_mmc.c
上传用户:dahaojd
上传日期:2008-01-29
资源大小:14357k
文件大小:10k
源码类别:

DSP编程

开发平台:

C/C++

  1. /*
  2.  *  Copyright 2003 by Texas Instruments Incorporated.
  3.  *  All rights reserved. Property of Texas Instruments Incorporated.
  4.  *  Restricted rights to use, duplicate or disclose this code are
  5.  *  granted through contract.
  6.  *  
  7.  */
  8. /* "@(#) DDK 1.10.00.23 07-02-03 (ddk-b12)" */
  9. /*
  10.  *  ======== async_mmc.c ========
  11.  * 
  12.  *  MMC Driver Async Test for the MMC on a C5509 DSP EVM.
  13.  *  The test is to transfer data from DSP memory to the MMC card
  14.  *  (MMC write) or from the MMC card to DSP memory (MMC read)
  15.  *  Data values placed in the memory are based on channel number, such as 
  16.  *  0x00010001 transfered for channel one, 0x00050005 for channel 5.
  17.  *  
  18.  *  User defines the following parameters:
  19.  *  
  20.  *  -- CHANNUM: Number of channels to be opened
  21.  *  -- MMCREQNUM: Number of IOPs for each channel
  22.  *  -- TRANSFERCOUNT: # of words to be transfered
  23.  */
  24. #include <stdio.h>
  25. #include <std.h>
  26. #include <log.h>
  27. #include <sys.h>
  28. #include <tsk.h>
  29. #include <gio.h>
  30. #include <iom.h>
  31. #include <async.h>
  32. #include <csl_mmc.h>
  33. #include <c5509_mmc.h>   
  34. /*  Test Configuration Parameters */
  35. #define CHANNUM        4   /* Maximum number of channels */
  36.         /* A task is spawned for each channel */
  37. #define MMCREQNUM      4   /* Depth of each request queue */
  38.         /* Constraint: MMCREQNUM must always be even */
  39. /* interrupt mask definitions */
  40. #define C5509_MMC_IER0_MASK_DEFAULT 1
  41. #define C5509_MMC_IER1_MASK_DEFAULT 1
  42. extern LOG_Obj   trace;
  43. /*  Reserve space for channels */
  44. static C5509_MMC_ChanObj  chans[CHANNUM];
  45. /*  Globals  */
  46. C5509_MMC_DevObj    C5509_MMC_devObj;
  47. /*  Bind Parameters  */
  48. C5509_MMC_DevParams  C5509_MMC_devParams = {
  49.     /* devParams */
  50.     C5509_MMC_VERSION_1, /* Version number */
  51.     0,    /* Enable/disable DMA for data read/write */
  52.     0,    /* dat3EdgeDetection -- DUMMY */
  53.     0,    /* Determines if MMC goes IDLE during IDLE instr */
  54.     0,    /* enableClkPin -- DUMMY */
  55.     2,    /* CPU CLK to MMC function clk divide down */
  56.     3,    /* MMC function clk to memory clk divide down */
  57.     0,    /* 
  58.            *  No. memory clks to wait before response timeout
  59.            *  Zero indicates no timeout.
  60.            */
  61.     0,    /* 
  62.            *  No. memory clks to wait before data timeout 
  63.            *  Zero indicates no timeout.
  64.            */
  65.     512,   /* Length of DATA block to be read in BYTEs*/     
  66.     /* drvrParams */
  67.     2,     /* RCA - set by the application */
  68.     CHANNUM,                 /* maximum number of channels required */
  69.     MEDIA_BYTENORMAL,        /* MEDIA_[BYTESWAP|BYTENORMAL] */
  70.     0,     /* DMA channel number used for READ operations */  
  71.     0,     /* DMA channel number used for WRITE operations */
  72.     NULL,  /* Buffer for DMA read */
  73.     NULL,  /* Buffer for DMA write */
  74.     chans,  /* Array of (noChan number of) Channel Objs */
  75.     C5509_MMC_IER0_MASK_DEFAULT,
  76.     C5509_MMC_IER1_MASK_DEFAULT
  77. };
  78. /* User defined constants */
  79. #define TRANSFERCOUNT           C5509_MMC_SECLEN
  80. #define SLEEPTIME               10
  81. typedef struct CallbackObj {
  82.     Int   chanNum;     /* trace the channel number */
  83.     Int   reqNum;      /* index for trace submitted request */
  84.     Int   cmd;         /* IOM_READ/IOM_WRITE */
  85.     MdUns value;       /* value to write to memory, then read it back */  
  86.     Bool  packetFree;  /* if the packet is free to use */ 
  87. } CallbackObj;
  88. static Void chanCallback(Ptr arg, Int status, Ptr reqp, Uns size);
  89. static Void chanTsk(Arg chanNum);
  90. static Void setMem(Int count, MdUns *memAddr, MdUns value);
  91. static Bool verifyData(Int chanNum, Ptr reqp, MdUns value);
  92. static GIO_Handle   gio[CHANNUM];
  93. /* Declare here so that the stack space is conserved */
  94. static MdUns globalSectorBuffers[CHANNUM][MMCREQNUM][C5509_MMC_SECLEN];
  95. /*
  96.  *  ======== main ========
  97.  */
  98. Void main()
  99. {   
  100.     TSK_Attrs tskAttrs[CHANNUM];
  101.     GIO_Attrs gioAttrs[CHANNUM];
  102.     Int       i;
  103.     
  104.     for (i = 0; i < CHANNUM; i++) {
  105.         /* GIO_Attrs init */
  106.         gioAttrs[i].nPackets = MMCREQNUM;
  107.         gioAttrs[i].timeout = SYS_FOREVER; 
  108.     }
  109.     /* create IOM objs */
  110.     for (i = 0; i < CHANNUM; i++) {
  111.         gio[i] = ASYNC_create("/udevMmc0", IOM_INOUT, NULL, NULL, &gioAttrs[i]);
  112.         if (gio[i] == NULL) {
  113.             LOG_printf (&trace, "ERROR: GIO_create NULL!");
  114.         }
  115.     }
  116.     
  117.     /* create tasks */
  118.     for (i = 0; i < CHANNUM; i++) {
  119.         tskAttrs[i] = TSK_ATTRS;
  120.         if (TSK_create ((Fxn)chanTsk, &tskAttrs[i], (Arg)i) == NULL) {
  121.             LOG_printf (&trace, "ERROR: TSK_create NULL!");
  122.         }
  123.     }     
  124.     
  125.     LOG_printf (&trace, "Exitting main");  
  126.     /* fall into DSP/BIOS idle loop */
  127.     return;
  128. }
  129. /*
  130.  *  ======== chanCallback ========
  131.  *  Handle callback
  132.  */
  133. static Void chanCallback(Ptr arg, Int status, Ptr reqp, Uns size)
  134. {
  135.     CallbackObj    *pCallback = (CallbackObj *)arg;
  136.     MEDIA_RdWrObj  *req = (MEDIA_RdWrObj *)reqp;
  137.     Int            chanNum = pCallback->chanNum;
  138.     /*
  139.      * if this callback is for ASYNC_read, then check 
  140.      * if read value = written value 
  141.      */
  142.     if (pCallback->cmd == IOM_READ) {
  143.         if (verifyData(chanNum, req, pCallback->value)) {
  144.             LOG_printf (&trace, "[%d] verifyData OK!", chanNum);
  145.         }
  146.         else {
  147.             LOG_printf (&trace, "[%d] ERROR: verifyData Failed!", chanNum);
  148.         }
  149.     }
  150.     pCallback->packetFree = TRUE;
  151. }
  152. /*
  153.  *  ======== chanTsk ========
  154.  */
  155. static Void chanTsk(Arg channelNumber)
  156. {
  157.     Uns              size;
  158.     Int              status;
  159.     MEDIA_RdWrObj    req[MMCREQNUM];
  160.     MEDIA_RdWrObj    *curReq;
  161.     GIO_AppCallback  gioCallback[MMCREQNUM]; 
  162.     CallbackObj      callback[MMCREQNUM];
  163.     MdUns            value; 
  164.     Int              submitReqIndex;
  165.     Int              j;
  166.     Int              chanNum;
  167.     Int              yieldCount;
  168.     chanNum = ArgToInt(channelNumber);
  169.     value = (MdUns)(chanNum | 0xAA00);
  170.     /* First set write req, then set read request */
  171.     /* A paired write and read operate on the same sectorNumber */
  172.     for (j = 0; j < MMCREQNUM; j = j + 2) {
  173.         /* MMC write : DSP->MMC Card */        
  174.         req[j].buf = globalSectorBuffers[chanNum][j];
  175.         req[j].address = chanNum * 100 + j;
  176.         req[j].subAddress = 0;
  177.         req[j].length = C5509_MMC_SECLEN;
  178.         callback[j].cmd = IOM_WRITE;
  179.            
  180.         /* MMC read : MMC Card->DSP */
  181.         req[j + 1].buf = globalSectorBuffers[chanNum][j + 1];
  182.         req[j + 1].address = chanNum * 100 + j;
  183.         req[j + 1].subAddress = 0;     
  184.         req[j + 1].length = C5509_MMC_SECLEN;
  185.         callback[j + 1].cmd = IOM_READ;
  186.     }
  187.     for (j = 0; j < MMCREQNUM; j++) {
  188.         callback[j].chanNum = chanNum;
  189.         callback[j].reqNum = j;
  190.         callback[j].value = value;
  191.         callback[j].packetFree = TRUE;
  192.         gioCallback[j].fxn = (GIO_TappCallback)chanCallback;
  193.         gioCallback[j].arg = (Ptr)(&callback[j]);
  194.     }
  195.     submitReqIndex = 0;
  196.     for (;;) {
  197.         yieldCount = 0;
  198.         LOG_printf (&trace, "[%d] IsPacketFreeAt [%d]",
  199.             chanNum, submitReqIndex);
  200.         while (!callback[submitReqIndex].packetFree) {
  201.             yieldCount++;
  202.             TSK_sleep (SLEEPTIME);
  203.         }
  204.         LOG_printf (&trace, "[%d] Slept [%d] times", chanNum, yieldCount);
  205.         
  206.         callback[submitReqIndex].packetFree = FALSE;
  207.         curReq = (MEDIA_RdWrObj *)(&req[submitReqIndex]);
  208.         
  209.         if (callback[submitReqIndex].cmd == IOM_WRITE) {
  210.             /*  
  211.              * set dsp memory value as chanNum chanNum ...
  212.              * (for example: 0x0001 0x0001 ... for Chan1) 
  213.              */ 
  214.             setMem(TRANSFERCOUNT, curReq->buf, value);
  215.             /* MMC write: DSP->MMC. Write the value to MMC card */
  216.             size = sizeof (*curReq);
  217.             status = ASYNC_write(gio[chanNum], curReq, &size, 
  218.                     &gioCallback[submitReqIndex]);
  219.             if (status < 0) {
  220.                 LOG_printf (&trace, "[%d] ERROR: ASYNC_write status [%d]",
  221.                     chanNum, status);
  222.             }
  223.         } else {  /* IOM_READ */
  224.             /* first set dsp mem value to default 0xDEAD */
  225.             setMem(TRANSFERCOUNT, curReq->buf, 0xDEAD);
  226.         
  227.             /* MMC read: MMC->DSP. Readback MMC card contents to DSP memory */
  228.             size = sizeof (*curReq);
  229.             status = ASYNC_read(gio[chanNum], curReq, &size, 
  230.                     &gioCallback[submitReqIndex]);
  231.             if (status < 0) {
  232.                 LOG_printf (&trace, "[%d] ERROR: ASYNC_read status [%d]", 
  233.                     chanNum, status);
  234.             }
  235.         }
  236.         submitReqIndex++;
  237.         if (submitReqIndex == MMCREQNUM) {
  238.             submitReqIndex = 0;
  239.         }
  240.         TSK_yield (); /* Yield control to another task */
  241.     }
  242. }
  243. /*
  244.  *  ======== setMem ========
  245.  *  Set memory value
  246.  */
  247. static Void setMem(Int count, MdUns *memAddr, MdUns value)
  248. {
  249.     MdUns *tempMem = (MdUns *)memAddr;
  250.     Int   i;
  251.     
  252.     for (i = 0; i < count; i++) {
  253.         *tempMem = value;
  254.         tempMem++;
  255.     }   
  256. }
  257. /*
  258.  *  ======== verifyData ========
  259.  *  Verify read back data 
  260.  */
  261. static Bool verifyData(Int chanNum, Ptr reqp, MdUns value)
  262. {
  263.     MEDIA_RdWrObj *req;
  264.     MdUns         *addr; 
  265.     Int           i;
  266.     
  267.     req = (MEDIA_RdWrObj *)reqp;
  268.     
  269.     if (req != NULL) {
  270.        addr = (MdUns *)req->buf;
  271.        for (i = 0; i < req->length; i++) {
  272.            if (*addr != value) {
  273.                LOG_printf (&trace, "[%d] ERROR: in verifyData at addr [0x%x]", 
  274.                        chanNum, addr);
  275.                return FALSE;
  276.            }
  277.            addr++;
  278.        }
  279.     }
  280.     return TRUE;
  281. }