dma2.c

来自「dsp5509的dma使用例程」· C语言 代码 · 共 269 行

C
269
字号
/*
 *  Copyright 2002 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.
 *  
 */
/* "@(#) DSP/BIOS 4.80.208 12-06-02 (barracuda-l19)" */
/******************************************************************************\
*           Copyright (C) 2000 Texas Instruments Incorporated.
*                           All Rights Reserved
*------------------------------------------------------------------------------
* FILENAME...... dma2.c
* DATE CREATED.. 08/27/2001
*      MODIFIED. 08/28/2001
*      MODIFIED. 03/05/2002 Removed reference to PG2.0 DMA regs
\******************************************************************************/
#include <stdio.h>

#include <csl.h>
#include <csl_irq.h>
#include <csl_dma.h>

/* Constant defines transfer length */
//#define N     128
#define N   128

/* Place src and dst of DMA transfer in seperate memory section */
/* to better control placement in user specified memory range   */
#pragma DATA_SECTION(src1,"dmaMem")
Uint16 src1[N];
    
#pragma DATA_SECTION(src2,"dmaMem")
Uint16 src2[N];

#pragma DATA_SECTION(dst1, "dmaMem")
Uint16 dst1[N];

#pragma DATA_SECTION(dst2, "dmaMem")

#pragma CODE_SECTION (main, "saram1Section")
#pragma CODE_SECTION (taskFxn, "saram1Section")

Uint16 dst2[N];

/* Declare Reference for Start of Interrupt Vector Table */
/* This symbol is defined in the vectors.s55 file        */
extern VECSTART(void);

/* This example effects a two single-frame transfers of 128 */
/* elements from DARAM to DARAM, via DMA, using DMA auto-   */
/* initialization mode to effect the second transfer        */
/* The macro invocation reflect the settings required in    */
/* DMA control registers to make this happen.               */
                              
/*   DMACSDP       dstben    == 0                           */
/*                 dstpack   == 0                           */
/*                 dst       == 0                           */
/*                 srcben    == 0                           */
/*                 srcpack   == 0                           */
/*                 src       == 0                           */
/*                 datatype  == 1                           */
/*                                                          */
/*   DMACCR        dstamode  == 1                           */
/*                 srcamode  == 1                           */
/*                 endprog   == 0                           */
/*                 repeat    == 0                           */ 
/*                 autoinit  == 0                           */
/*                 en        == 0                           */
/*                 prio      == 0                           */
/*                 fs        == 0                           */
/*                 sync      == 0                           */
/*                                                          */
/*  DMACICR        blockie   == 1                           */
/*                 lastie    == 1                           */
/*                 frameie   == 1                           */
/*                 firsthalfie == 1                         */
/*                 dropie    == 1                           */
/*                 timeoutie == 1                           */

DMA_Config  myconfig = { 
  DMA_DMACSDP_RMK(
    DMA_DMACSDP_DSTBEN_NOBURST,
    DMA_DMACSDP_DSTPACK_OFF,
    DMA_DMACSDP_DST_DARAM,
    DMA_DMACSDP_SRCBEN_NOBURST,
    DMA_DMACSDP_SRCPACK_OFF,
    DMA_DMACSDP_SRC_DARAM,
    DMA_DMACSDP_DATATYPE_16BIT
  ),                                       /* DMACSDP  */
  DMA_DMACCR_RMK(
    DMA_DMACCR_DSTAMODE_POSTINC,
    DMA_DMACCR_SRCAMODE_POSTINC,
    DMA_DMACCR_ENDPROG_ON,
    DMA_DMACCR_REPEAT_OFF,
    DMA_DMACCR_AUTOINIT_ON,
    DMA_DMACCR_EN_STOP,
    DMA_DMACCR_PRIO_HI,
    DMA_DMACCR_FS_DISABLE,
    DMA_DMACCR_SYNC_NONE
  ),                                       /* DMACCR   */
  DMA_DMACICR_RMK(
    DMA_DMACICR_BLOCKIE_OFF,
    DMA_DMACICR_LASTIE_OFF,
    DMA_DMACICR_FRAMEIE_ON,
    DMA_DMACICR_FIRSTHALFIE_OFF,
    DMA_DMACICR_DROPIE_OFF,
    DMA_DMACICR_TIMEOUTIE_OFF
  ),                                       /* DMACICR  */
    (DMA_AdrPtr)&src1,                     /* DMACSSAL */
    0,                                     /* DMACSSAU */
    (DMA_AdrPtr)&dst1,                     /* DMACDSAL */
    0,                                     /* DMACDSAU */
    N,                                     /* DMACEN   */
    1,                                     /* DMACFN   */
    0,                                     /* DMACFI   */
    0                                      /* DMACEI   */
};

/* Define a DMA_Handle object */
interrupt void dmaIsr(void);
void taskFxn(void);

DMA_Handle myhDma;
int i, j;   
Uint16 err = 0;
Uint16 numTransfers = 0;
volatile Uint16 transferComplete = FALSE;

void main(void)
{
    /* Initializa CSL library - This is REQUIRED !!! */
    CSL_init();

    /* Set IVPD/IPVH to start of interrupt vector table */
    IRQ_setVecs((Uint32)(&VECSTART));
    
    /* Initialize source and destination buffers */
    for (i = 0; i <= (N - 1); i++) {
        dst1[i] = 0;
        dst2[i] = 0;
        src1[i] = i + 1;
        src2[i] = (i + 1) * 2;
    }

    /* Call function to effect transfer */
    taskFxn();
}

void taskFxn(void)
{
    Uint16 src1AddrHi, src1AddrLo;
    Uint16 src2AddrHi, src2AddrLo;
    Uint16 dst1AddrHi, dst1AddrLo;
    Uint16 dst2AddrHi, dst2AddrLo;
    Uint32 eventId;
    Uint16 old_intm;

    /* Open DMA Channel 1 setting registers to their power on defualts */
    myhDma = DMA_open(DMA_CHA1, DMA_OPEN_RESET);    

    /* Get Interrupt Event Id associated with this DMA */
    eventId = DMA_getEventId(myhDma);

    /* By default, the TMS320C55xx compiler assigns all data symbols word */
    /* addresses. The DMA however, expects all addresses to be byte       */
    /* addresses. Therefore, we must shift the address by 2 in order to   */
    /* change the word address to a byte address for the DMA transfer.    */ 
    src1AddrHi = (Uint16)(((Uint32)(myconfig.dmacssal)) >> 15) & 0xFFFFu;
    src1AddrLo = (Uint16)(((Uint32)(myconfig.dmacssal)) << 1) & 0xFFFFu;
    dst1AddrHi = (Uint16)(((Uint32)(myconfig.dmacdsal)) >> 15) & 0xFFFFu;
    dst1AddrLo = (Uint16)(((Uint32)(myconfig.dmacdsal)) << 1) & 0xFFFFu;

    src2AddrHi = (Uint16)(((Uint32)(&src2)) >> 15) & 0xFFFFu;
    src2AddrLo = (Uint16)(((Uint32)(&src2)) << 1) & 0xFFFFu;
    dst2AddrHi = (Uint16)(((Uint32)(&dst2)) >> 15) & 0xFFFFu;
    dst2AddrLo = (Uint16)(((Uint32)(&dst2)) << 1) & 0xFFFFu;

    myconfig.dmacssal = (DMA_AdrPtr)src1AddrLo;
    myconfig.dmacssau = src1AddrHi;
    myconfig.dmacdsal = (DMA_AdrPtr)dst1AddrLo;
    myconfig.dmacdsau = dst1AddrHi;

    /* Write configuration structure values to DMA control registers */
    DMA_config(myhDma, &myconfig);    


    /* Temporarily Disable All Interrupts */
    old_intm = IRQ_globalDisable();

    /* Clear any pending interrupts for DMA in IFR */
    IRQ_clear(eventId);

    /* Enable the DMA interrupt in IER register */
    IRQ_enable(eventId);
    
    /* Set Interrupt Vector Start Location */
    IRQ_setVecs(0x10000);
    
    /* Place ISR address in associated vector location */
    IRQ_plug(eventId, &dmaIsr);

    /* Enable all maskable interrupts */   
    IRQ_globalEnable();

    /* Enable DMA channel to begin transfer */
    DMA_start(myhDma);


    /* Wait for programmation bit, ENDPROG == 0, to make sure that device's   */
    /* configuration register set has already been copied to working set */
    while (DMA_FGETH(myhDma,DMACCR,ENDPROG)) {
        ;   
    }


    /* Write next set of configuration values to the DMA control regs */
    /* for next transfer */

    DMA_RSETH(myhDma,DMACSSAU,src2AddrHi);
    DMA_RSETH(myhDma,DMACSSAL,src2AddrLo);
    DMA_RSETH(myhDma,DMACDSAU,dst2AddrHi);
    DMA_RSETH(myhDma,DMACDSAL,dst2AddrLo);

    DMA_RSETH(myhDma,DMACEN, N);
    DMA_RSETH(myhDma,DMACFN, 1);
 
    /* Set programmation bit to 1, ENDPROG = 1) */

    DMA_FSETH(myhDma,DMACCR,ENDPROG,1);


    /* Wait for transfers to complete */
    while (!transferComplete) {
        ;   
    }

    /* Check data values to make sure transfer happened correctly */
    for (i = 0; i <= (N - 1); i++) {
        if ((dst1[i] != src1[i]) && (dst2[i] != src2[i])) {
            ++err;
        }
    }
            
    if (err) {
        printf(">>> Warning, DMA Example 2 Failed\n");
    }
    else {
        printf("...DMA Example 2 Complete\n");
    }
 
    /* Restore GLobal Interrupt Enable to Previous Setting */
    IRQ_globalRestore(old_intm);
    
    /* We are through with DMA, so close it */
    DMA_close(myhDma); 
}


/* DMA Interrupt Service Routine */
interrupt void dmaIsr(void) {
  ++numTransfers;
  DMA_FSETH(myhDma,DMACSR,FRAME,0);
  if (numTransfers == 2) {
    transferComplete = TRUE;
    DMA_stop(myhDma);
  }
}

⌨️ 快捷键说明

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