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

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.11.00.00 11-04-03 (ddk-b13)" */
  9. /*
  10.  *  ======== pio.c ========
  11.  */
  12. #include <std.h>
  13. #include <dev.h>
  14. #include <fxn.h>
  15. #include <hwi.h>
  16. #include <pip.h>
  17. #include <que.h>
  18. #include <sys.h>
  19. #include <iom.h>
  20. #include <pio.h>
  21. #include <string.h>     /* for memset() */
  22. static Void rxCallback(Arg arg, IOM_Packet *packet);
  23. static Void txCallback(Arg arg, IOM_Packet *packet);
  24. static Void transfer (PIO_Handle pio, Uns numFrames);
  25. #pragma CODE_SECTION(PIO_init, ".text:init");
  26. #pragma CODE_SECTION(PIO_new, ".text:init");
  27. #pragma CODE_SECTION(PIO_rxPrime, ".text:PIO_rx");
  28. #pragma CODE_SECTION(PIO_rxStart, ".text:PIO_rx");
  29. #pragma CODE_SECTION(PIO_txPrime, ".text:PIO_tx");
  30. #pragma CODE_SECTION(PIO_txStart, ".text:PIO_tx");
  31. #pragma CODE_SECTION(txCallback, ".text:PIO_tx");
  32. #pragma CODE_SECTION(rxCallback, ".text:PIO_rx");
  33. /* 
  34.  * These macros are used to work-around a problem with 'notifyWriter'
  35.  * calls from PIO_txStart() ...
  36.  */
  37. #ifdef _55_
  38. /* PIP_Obj structure is defined differently for 55x */
  39. #define getNotifyWriterFxn(pip)          ((pip)->readerSock.notifyFxn.fxn)
  40. #define setNotifyWriterFxn(pip, notify) 
  41.          ((pip)->readerSock.notifyFxn.fxn = (notify))
  42. #else
  43. #define getNotifyWriterFxn(pip)         ((pip)->notifyWriter.fxn)
  44. #define setNotifyWriterFxn(pip, notify) ((pip)->notifyWriter.fxn = (notify))
  45. #endif
  46. /*
  47.  *  ======== PIO_ATTRS ========
  48.  */
  49. PIO_Attrs PIO_ATTRS = {
  50.     0                           // arg to mdCreateChan
  51. };
  52. /*  ======== PIO_init ========
  53.  *
  54.  */
  55. Void PIO_init(Void)
  56. {
  57.     /*
  58.      *  Module initialization
  59.      */
  60. }
  61. /*
  62.  *  ======== PIO_new ========
  63.  */
  64. Void PIO_new(PIO_Handle pio, PIP_Handle pip, String name, Int mode,
  65.         PIO_Attrs *attrs)
  66. {
  67.     IOM_TiomCallback    cbFxn;
  68.     DEV_Device          *entry;
  69.     Int                 i, status;
  70.     if (attrs == NULL) {
  71.         attrs = &PIO_ATTRS;
  72.     }
  73.     /*
  74.      *  Find device structure in device table for device with name 'name'.
  75.      *  DEV_match() returns the remaining name string for use by the
  76.      *  mini-driver's create() function.
  77.      */
  78.     name = DEV_match(name, &entry);
  79.     if (entry == NULL) {
  80.         SYS_abort("PIO_new: DEV_match() failedn");
  81.     }
  82.     if (entry->type != DEV_IOMTYPE) {
  83.         SYS_abort("PIO_new: invalid device typen");
  84.     }
  85.     pio->pip = pip;
  86.     pio->fxns = (IOM_Fxns *)entry->fxns;
  87.     pio->mode = mode;
  88.     pio->submitCount = 0;
  89.     /* Initialize queue structures */
  90.     QUE_new(&pio->freeList);
  91.     /* Initialize the freeList with packets */
  92.     for (i=0; i < PIO_MAXPACKETS; i++)  {
  93.         QUE_put(&pio->freeList, &pio->packet[i]);
  94.     }
  95.     if (mode == IOM_INPUT) {
  96.         cbFxn = (IOM_TiomCallback)rxCallback;
  97.         pio->curdesc = PIP_getWriterCurdesc(pip);
  98.     }
  99.     else {
  100.         cbFxn = (IOM_TiomCallback)txCallback;
  101.         pio->curdesc = PIP_getReaderCurdesc(pip);
  102.     }
  103.     /* open the channel */
  104.     status = pio->fxns->mdCreateChan(&pio->mdChan, entry->devp,
  105.         name, mode, attrs->openArgs, cbFxn, pio);
  106.     if (status != IOM_COMPLETED) {
  107.         SYS_abort("PIO_new: mdCreateChan failed");
  108.     }
  109. }
  110. /*
  111.  *  ======== transfer ========
  112.  *  pio->submitCount
  113.  *  The count of frames submitted to the IO mini-driver is stored
  114.  *  in pio->submitCount. Transfer() looks ahead in the pipe using
  115.  *  the pipe descriptor.  The number of frames taken from the pipe
  116.  *  in this way is kept in pio->submitCount. Therefore the number of
  117.  *  frames available in the pipe is the number of frames indicated by
  118.  *  PIP_getReaderNumFrames() or PIP_getWriterNumFrames()
  119.  *  less the value of pio->submitCount.
  120.  */
  121. static Void transfer (PIO_Handle pio, Uns numFrames)
  122. {
  123.     PIP_Curdesc         *curdesc;
  124.     IOM_Packet          *packet;
  125.     IOM_TiomCallback    cbFxn;
  126.     Int                 status;
  127.     /*
  128.      * check to see if we have an available PIP frame and an IOM_Packet
  129.      * so that we can submit the I/O request to the mini-driver
  130.      */
  131.     if ((numFrames > pio->submitCount) && (pio->submitCount < PIO_MAXPACKETS)) {
  132.         packet = QUE_get(&pio->freeList);
  133.         /* assert(packet != &pio->freeList); */
  134.         curdesc = pio->curdesc;         // pipe descriptor
  135.         pio->curdesc = curdesc->next;   // next pipe descriptor
  136.         pio->submitCount++;             // increment counter
  137.         /* Initialize the packet */
  138.         packet->addr = curdesc->addr;
  139.         packet->size = curdesc->size * sizeof(Int);
  140.         if (pio->mode == IOM_INPUT) {
  141.             packet->cmd = IOM_READ;
  142.             cbFxn = (IOM_TiomCallback)rxCallback;
  143.         }
  144.         else if (pio->mode == IOM_OUTPUT) {
  145.             packet->cmd = IOM_WRITE;
  146.             cbFxn = (IOM_TiomCallback)txCallback;
  147.         }
  148.         status = pio->fxns->mdSubmitChan(pio->mdChan, packet);
  149.         if (status == IOM_COMPLETED) {
  150.             /*
  151.              * Since the mini-driver completed the I/O, the callback will
  152.              * not be called. We need to handle the callback ourselves.
  153.              * This call might cause recursive call back to transfer().
  154.              */
  155.             cbFxn(pio, packet);
  156.         }
  157.         else if (status < 0) {
  158.             /*
  159.              * This should never happen.  IOM mini drivers must be able
  160.              * to queue all submitted IOM_Packets.
  161.              */
  162.             SYS_abort("PIO: mdSubmitChan() failed!");
  163.         }
  164.     }
  165. }
  166. /*
  167.  *  ======== rxCallback ======== 
  168.  */
  169. static Void rxCallback (Arg arg, IOM_Packet *packet)
  170. {
  171.     PIO_Handle pio = (PIO_Handle)(arg);
  172.     PIP_Handle pip = pio->pip;
  173.     /*
  174.      * Must update the pipe before calling submit again.
  175.      * We have used the pointer to the next frame,
  176.      * but PIP_alloc has not been called yet.
  177.      */
  178.     PIP_alloc(pip);
  179.     /* set size and return completed frame - PIP needs size in words! */
  180.     PIP_setWriterSize(pip, packet->size / sizeof(Int));
  181.     PIP_put(pip);
  182.     /* decrement count of submitted frames */
  183.     pio->submitCount--;
  184.     /* Must put the packet back of the freeList */
  185.     QUE_put(&pio->freeList, packet);
  186.     /* start next transfer */
  187.     transfer(pio, PIP_getWriterNumFrames(pio->pip));
  188. }
  189. /*
  190.  *  ======== txCallback ======== 
  191.  */
  192. static Void txCallback (Arg arg, IOM_Packet *packet)
  193. {
  194.     PIO_Handle pio = (PIO_Handle)(arg);
  195.     PIP_Handle pip = pio->pip;
  196.     /*
  197.      * Must update the pipe before calling submit again.
  198.      * We have used the pointer to the next frame,
  199.      * but PIP_get has not been called yet.
  200.      */
  201.     PIP_get(pip);
  202.     /* return completed frame */
  203.     PIP_free(pip);
  204.     /* decrement count of submitted frames */
  205.     pio->submitCount--;
  206.     /* Must put the packet back of the freeList */
  207.     QUE_put(&pio->freeList, packet);
  208.     /* start next transfer */
  209.     transfer(pio, PIP_getReaderNumFrames(pio->pip));
  210. }
  211. /*
  212.  *  ======== PIO_rxPrime ======== 
  213.  *  submit one frame if receive not busy
  214.  */
  215. Void PIO_rxPrime (PIO_Handle pio)
  216. {
  217.     Uns imask;
  218.     imask = HWI_disable();
  219.     transfer(pio, PIP_getWriterNumFrames(pio->pip));
  220.     HWI_restore(imask);
  221. }
  222. /*
  223.  *  ======== PIO_rxStart ======== 
  224.  *  submit frames to receiver
  225.  *
  226.  *  CONSTRAINTS:
  227.  *  -  PIO_rxStart() may only be called in main() before interrupts
  228.  *     are enabled
  229.  */
  230. Void PIO_rxStart (PIO_Handle pio, Uns frameCount)
  231. {
  232.     for ( ; frameCount > 0; frameCount--) {
  233.         transfer(pio, PIP_getWriterNumFrames(pio->pip));
  234.     }
  235. }
  236. /*
  237.  *  ======== PIO_txPrime ======== 
  238.  *  submit one frame if transmit not busy
  239.  */
  240. Void PIO_txPrime (PIO_Handle pio)
  241. {
  242.     Uns imask;
  243.     imask = HWI_disable();
  244.     transfer(pio, PIP_getReaderNumFrames(pio->pip));
  245.     HWI_restore(imask);
  246. }
  247. /*
  248.  *  ======== PIO_txStart ======== 
  249.  *  submit initialized frames to transmitter
  250.  *
  251.  *  CONSTRAINTS:
  252.  *  -  PIO_txStart() may only be called in main() before interrupts
  253.  *     are enabled
  254.  */
  255. Void PIO_txStart (PIO_Handle pio, Uns frameCount, Uns initialValue)
  256. {
  257.     PIP_Handle  pip = pio->pip;
  258.     char        *buf;
  259.     Fxn         notifySave;
  260.     /*
  261.      * Work-around notifyWriter problem at startup.
  262.      * Without this work-around, the PIP_alloc() calls below cause
  263.      * notifyWriter to be called and the application to have incorrect
  264.      * view of the PIP state (application thinks an empty output frame
  265.      * is available when no frame is actually available).
  266.      */
  267.     notifySave = getNotifyWriterFxn(pip);
  268.     setNotifyWriterFxn(pip, (Fxn)FXN_F_nop);
  269.     for ( ; frameCount > 0; frameCount--) {
  270.         if (PIP_getWriterNumFrames(pip) <= 0) break;
  271.         PIP_alloc(pip);
  272.         buf = PIP_getWriterAddr(pip);
  273.         memset(buf, initialValue, PIP_getWriterSize(pip) * sizeof(Int));
  274.         PIP_put(pip);
  275.     }
  276.     /* restore notifyWriter function to its' configured state */
  277.     setNotifyWriterFxn(pip, notifySave);
  278. }