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

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.  *  ======== dsk6x11_edma_ad535.c ========
  11.  * 
  12.  *  Driver for the ad535 codec on the TMS320C6x11 DSK. Requires the
  13.  *  generic TMS320C6x1x McBSP driver.
  14.  */
  15. #include <std.h>
  16. #include <iom.h>
  17. #include <csl.h>
  18. #include <csl_mcbsp.h>
  19. #include <csl_edma.h>
  20. #include <dsk6x11_edma_ad535.h>
  21. #include <c6x1x_edma_mcbsp.h>
  22. #define AD535RESET      0x0080          /* codec software reset */
  23. /*
  24.  * Since the AD535 codec is master on the DSK6X11 we don't want to enable
  25.  * the frame sync or sample rate generators since we don't use them (the
  26.  * codec is master means that the mcbsp is externally clocked).
  27.  */
  28. #define GENERICDEVPARAMS {                                                  
  29.     C6X1X_EDMA_MCBSP_VERSION_1,/* Version Number.*/                         
  30.     FALSE, /* True if buffers are in cacheable memory (set in mdBindDev) */ 
  31.     FALSE, /* Driver should not enable the McBSP sample rate generator */   
  32.     FALSE, /* Driver should not enable the McBSP frame sync generator */    
  33.     0,     /* IRQ id to use for the EDMA (set in mdBindDev) */              
  34.     NULL,  /* McBSP configuration for the codec (set in mdBindDev) */       
  35.     DSK6X11_EDMA_AD535_INTR_MASK_DEFAULT /* Interrupt mask for EDMA ISR */  
  36. }
  37. /* Structure containing port specific variables */
  38. typedef struct {
  39.         Ptr c6x1xPortObj;
  40.         Int edmaPriority;
  41. } PortObj, *PortHandle;
  42. /* Declare the port structure */
  43. /* Only Mcbsp 0 is used */
  44. static PortObj port;
  45. DSK6X11_EDMA_AD535_DevParams DSK6X11_EDMA_AD535_DEVPARAMS =
  46.                                  DSK6X11_EDMA_AD535_DEFAULT_DEVPARAMS;
  47. /* Local function prototypes */
  48. static Void codecControlWrite(MCBSP_Handle hMcbsp, Uns reg, Uns dataVal);
  49. static Uns spRead(MCBSP_Handle hMcbsp);
  50. static Void spWrite(MCBSP_Handle hMcbsp, Uns dataVal);
  51. /*
  52.  * Forward declaration of the IOM interface functions. They are only
  53.  * exposed via the IOM function table to avoid namespace pollution.
  54.  */
  55. static Int mdBindDev(Ptr *devp, Int devid, Ptr devParams);
  56. static Int mdCreateChan(Ptr *chanp, Ptr devp, String name, Int mode,
  57.                         Ptr chanParams, IOM_TiomCallback cbFxn, Ptr cbArg);
  58. static Int mdSubmitChan(Ptr chanp, IOM_Packet *packet);
  59. /*
  60.  * The codec driver function table. Notice how we copy most functions
  61.  * from the generic c6x1x edma mcbsp driver.
  62.  */
  63. IOM_Fxns DSK6X11_EDMA_AD535_FXNS = {
  64.     &mdBindDev,
  65.     NULL,
  66.     NULL,
  67.     &mdCreateChan,
  68.     NULL,
  69.     &mdSubmitChan
  70. };
  71. /*
  72.  * ======== mdBindDev ========
  73.  * This function allocates and configures the ad535 codec.
  74.  */
  75. static Int mdBindDev(Ptr *devp, Int devid, Ptr devParams)
  76. {
  77.     Int i;
  78.     MCBSP_Handle hMcbsp;
  79.     Int result;
  80.     DSK6X11_EDMA_AD535_DevParams *params =
  81.         (DSK6X11_EDMA_AD535_DevParams *) devParams;
  82.     C6X1X_EDMA_MCBSP_DevParams genericParams = GENERICDEVPARAMS;
  83.     MCBSP_Config mcbspCfg = {
  84.         MCBSP_FMKS(SPCR, FREE, NO)            |
  85.         MCBSP_FMKS(SPCR, SOFT, NO)            |
  86.         MCBSP_FMKS(SPCR, FRST, YES)           |
  87.         MCBSP_FMKS(SPCR, GRST, YES)           |
  88.         MCBSP_FMKS(SPCR, XINTM, XRDY)         |
  89.         MCBSP_FMKS(SPCR, XSYNCERR, NO)        |
  90.         MCBSP_FMKS(SPCR, XRST, YES)           |
  91.         MCBSP_FMKS(SPCR, DLB, OFF)            |
  92.         MCBSP_FMKS(SPCR, RJUST, RZF)          |
  93.         MCBSP_FMKS(SPCR, CLKSTP, DISABLE)     |
  94.         MCBSP_FMKS(SPCR, DXENA, OFF)          |
  95.         MCBSP_FMKS(SPCR, RINTM, RRDY)         |
  96.         MCBSP_FMKS(SPCR, RSYNCERR, NO)        |
  97.         MCBSP_FMKS(SPCR, RRST, YES),
  98.         MCBSP_FMKS(RCR, RPHASE, SINGLE)       |
  99.         MCBSP_FMKS(RCR, RFRLEN2, OF(0))       |
  100.         MCBSP_FMKS(RCR, RWDLEN2, 8BIT)        |
  101.         MCBSP_FMKS(RCR, RCOMPAND, MSB)        |
  102.         MCBSP_FMKS(RCR, RFIG, YES)            |
  103.         MCBSP_FMKS(RCR, RDATDLY, 1BIT)        |
  104.         MCBSP_FMKS(RCR, RFRLEN1, OF(0))       |
  105.         MCBSP_FMKS(RCR, RWDLEN1, 16BIT)       |
  106.         MCBSP_FMKS(RCR, RWDREVRS, DISABLE),
  107.         MCBSP_FMKS(XCR, XPHASE, SINGLE)       |
  108.         MCBSP_FMKS(XCR, XFRLEN2, OF(0))       |
  109.         MCBSP_FMKS(XCR, XWDLEN2, 8BIT)        |
  110.         MCBSP_FMKS(XCR, XCOMPAND, MSB)        |
  111.         MCBSP_FMKS(XCR, XFIG, YES)            |
  112.         MCBSP_FMKS(XCR, XDATDLY, 1BIT)        |
  113.         MCBSP_FMKS(XCR, XFRLEN1, OF(0))       |
  114.         MCBSP_FMKS(XCR, XWDLEN1, 16BIT)       |
  115.         MCBSP_FMKS(XCR, XWDREVRS, DISABLE),
  116.         MCBSP_SRGR_DEFAULT,    /* Default SRGR value */
  117.         MCBSP_MCR_DEFAULT,     /* Default MCR value */
  118.         MCBSP_RCER_DEFAULT,    /* Default RCER value */
  119.         MCBSP_XCER_DEFAULT,    /* Default XCER value */
  120.         MCBSP_PCR_DEFAULT      /* Default PCR value */
  121.     };
  122.     
  123.     /* If no device parameters are passed, use the defaults. */
  124.     if (params == NULL) {
  125.         params = &DSK6X11_EDMA_AD535_DEVPARAMS;
  126.     }
  127.     /* Check if the version is supported by the driver. */
  128.     if(params->versionId != DSK6X11_EDMA_AD535_VERSION_1){
  129.         /* Unsupported version */
  130.         return(IOM_EBADARGS);
  131.     }
  132.     /* Open McBSP port 0 and reset it. */
  133.     hMcbsp = MCBSP_open(MCBSP_DEV0, MCBSP_OPEN_RESET);
  134.     /*
  135.      * We can't abort or send an error code back from setup. Just send an
  136.      * error message to notify if an error occurs.
  137.      */
  138.     if (hMcbsp == INV) {
  139.         return (IOM_EALLOC);
  140.     }
  141.     /* Configure McBSP port 0 using the above specified parameters. */
  142.     MCBSP_config(hMcbsp, &mcbspCfg);
  143.     /*
  144.      * Temporarily enable the McBSP transmitter and receiver so
  145.      * that we can set up the codec.
  146.      */
  147.     MCBSP_start(hMcbsp, MCBSP_RCV_START | MCBSP_XMIT_START,
  148.                 MCBSP_SRGR_DEFAULT_DELAY);
  149.     /* Software reset the codec */
  150.     codecControlWrite(hMcbsp, 3, AD535RESET);
  151.     /* Configure the codec using the McBSP */
  152.     for (i=0; i < DSK6X11_EDMA_AD535_NUMREGS; i++) {
  153.         codecControlWrite(hMcbsp, i, params->reg[i]);
  154.     }
  155.     /* Close the McBSP so that the generic driver can claim it */
  156.     MCBSP_close(hMcbsp);
  157.     /* Set the IRQ id to use for EDMA (default is 8) */
  158.     genericParams.irqId = params->irqId;
  159.     
  160.     /* Set the interrupt mask to be used for EDMA ISR */
  161.     genericParams.intrMask = params->intrMask;
  162.     genericParams.cacheCalls = params->cacheCalls;
  163.     genericParams.mcbspCfgPtr = &mcbspCfg;
  164.     /* Call the generic mdBindDev to claim mcbsp port 0 */
  165.     result = (C6X1X_EDMA_MCBSP_FXNS.mdBindDev)(&port.c6x1xPortObj, 0,
  166.                                                &genericParams);
  167.     /* Store the edma priority in PortObj */
  168.     port.edmaPriority = params->edmaPriority;
  169.     *devp = &port;
  170.     return (result);
  171. }
  172. /*
  173.  * ======== mdCreateChan ========
  174.  * This function creates and configures a device channel.
  175.  */
  176. static Int mdCreateChan(Ptr *chanp, Ptr devp, String name, Int mode,
  177.                         Ptr chanParams, IOM_TiomCallback cbFxn, Ptr cbArg)
  178. {
  179.     Int result;
  180.     C6X1X_EDMA_MCBSP_ChanParams genericParams;
  181.     PortHandle localPort = (PortHandle) devp;
  182.     EDMA_Config edmaCfg = {
  183.         EDMA_FMKS(OPT, ESIZE, 16BIT)        |
  184.         EDMA_FMKS(OPT, 2DS, NO)             |
  185.         EDMA_FMKS(OPT, SUM, NONE)           |
  186.         EDMA_FMKS(OPT, 2DD, NO)             |
  187.         EDMA_FMKS(OPT, DUM, NONE)           |
  188.         EDMA_FMKS(OPT, TCINT, YES)          |
  189.         EDMA_FMK (OPT, TCC, NULL)           |
  190.         EDMA_FMKS(OPT, LINK, YES)           |
  191.         EDMA_FMKS(OPT, FS, NO),
  192.         EDMA_FMK (SRC, SRC, NULL),
  193.         EDMA_FMK (CNT, FRMCNT, NULL)        |
  194.         EDMA_FMK (CNT, ELECNT, NULL),
  195.         EDMA_FMK(DST, DST, NULL),
  196.         EDMA_FMKS(IDX, FRMIDX, DEFAULT)     |
  197.         EDMA_FMKS(IDX, ELEIDX, DEFAULT),
  198.         EDMA_FMK (RLD, ELERLD, NULL)        |
  199.         EDMA_FMK (RLD, LINK, NULL)
  200.     };
  201.         
  202.     if (mode == IOM_INPUT) {
  203.         edmaCfg.opt |= EDMA_FMK(OPT, DUM, EDMA_OPT_DUM_INC);
  204.     }
  205.     else {
  206.         edmaCfg.opt |= EDMA_FMK(OPT, SUM, EDMA_OPT_SUM_INC);
  207.     }
  208.     
  209.     /* set the edma transfer priority */
  210.     edmaCfg.opt |= EDMA_FMK(OPT, PRI, localPort->edmaPriority);
  211.     /*
  212.      * This codec is a mono codec, and therefore only uses 1 McBSP TDM
  213.      * channel.
  214.      */
  215.     genericParams.tdmChans = 1;
  216.     genericParams.edmaCfgPtr = &edmaCfg;
  217.     result = (C6X1X_EDMA_MCBSP_FXNS.mdCreateChan)(chanp, 
  218.                     localPort->c6x1xPortObj,name, mode,&genericParams, 
  219.                     cbFxn, cbArg);
  220.     return (result);
  221. }
  222. static Int mdSubmitChan(Ptr chanp, IOM_Packet *packet)
  223. {
  224.     Int i;
  225.     Int result;
  226.     MdUns *localBuf;
  227.     
  228.     if (packet->cmd == IOM_WRITE) {
  229.         /* Mask off the LSB */
  230.         localBuf = packet->addr;
  231.         for (i = 0; i < (packet->size / sizeof(MdUns)); i++) {
  232.             localBuf[i] = localBuf[i] & 0xFFFE;
  233.         }
  234.     }
  235.     
  236.     result = (C6X1X_EDMA_MCBSP_FXNS.mdSubmitChan)(chanp, packet);
  237.     return (result);
  238. }
  239. /*
  240.  *  ======== codecControlWrite ========
  241.  */
  242. static Void codecControlWrite(MCBSP_Handle hMcbsp, Uns reg, Uns data)
  243. {
  244.     Uns temp;
  245.         
  246.     temp = ((reg & 0x001F) << 8) | (data & 0x00ff);
  247.     spWrite(hMcbsp, 0);
  248.     spRead (hMcbsp);
  249.     spWrite(hMcbsp, 1);
  250.     spRead (hMcbsp);
  251.     spWrite(hMcbsp, temp);
  252.     spRead (hMcbsp);
  253.     spWrite(hMcbsp, 0);
  254.     spRead (hMcbsp);
  255. }
  256. /*
  257.  * ======== spWrite ========
  258.  * WARNING!  Unbounded while loop!
  259.  * spWrite() should only be called during init time.
  260.  */
  261. static Void spWrite(MCBSP_Handle hMcbsp, Uns dataVal)
  262. {
  263.     while(!(MCBSP_xrdy(hMcbsp))) {
  264.         /* wait for TX ready */
  265.     }
  266.     MCBSP_write(hMcbsp, dataVal);
  267. }
  268. /*
  269.  * ======== spRead ========
  270.  * WARNING!  Unbounded while loop!
  271.  * spRead() should only be called during init time.
  272.  */
  273. static Uns spRead(MCBSP_Handle hMcbsp)
  274. {
  275.     while(!(MCBSP_rrdy(hMcbsp))) {
  276.         /* wait for RX ready */
  277.     }
  278.     return MCBSP_read(hMcbsp);
  279. }
  280. /*
  281.  * ======== DSK6X11_EDMA_AD535_init ========
  282.  * This function initializes the driver's structures.
  283.  */
  284. Void DSK6X11_EDMA_AD535_init()
  285. {
  286.     /* Pass some IOM fxns straight to the generic driver */
  287.     DSK6X11_EDMA_AD535_FXNS.mdControlChan =
  288.         C6X1X_EDMA_MCBSP_FXNS.mdControlChan;
  289.     DSK6X11_EDMA_AD535_FXNS.mdDeleteChan = C6X1X_EDMA_MCBSP_FXNS.mdDeleteChan;
  290.     DSK6X11_EDMA_AD535_FXNS.mdUnBindDev = C6X1X_EDMA_MCBSP_FXNS.mdUnBindDev;
  291.     C6X1X_EDMA_MCBSP_init();
  292. }