[资料分享] 直接存储器访问(DMA)控制器——TMS320VC5509A

灞波儿奔   2020-2-6 18:49 楼主

实例主要是两个文件:dma.c和vectors.s55。

dma.c文件
/*
 *  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...... dma.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);
  }
}
需要注意的几点:

这个例子当中使用的DMRAM到DARAM之间的相互之间的DMA数据搬迁。故选择的是DMA_DMACCR_SYNC_NONE,如果是何McBSP联合使用的话,这边需要改成对应的同步事件。
DMA_FSETH(myhDma,DMACSR,FRAME,0),应当在每次中断发生后读DMACSR寄存器,清除即将发生的状态位。这一步不能忘记。
vectors.s55文件
;
;  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)"
        .sect ".vectors"
        .global _VECSTART
        .ref _c_int00
      .def nmi, int0, int1, int2, int3, int4, int5, int6
      .def int7, int8, int9, int10, int11, int12, int13
      .def int14, int15, int16, int17, int18, int19, int20
      .def int21, int22, int23, int24, int25, int26, int27
      .def int28, int29
 
_VECSTART:
        .ivec _c_int00,c54x_stk
nmi     .ivec no_isr
        nop_16
int0    .ivec no_isr
        nop_16
int1    .ivec no_isr
        nop_16
int2    .ivec no_isr
        nop_16
int3    .ivec no_isr
        nop_16
int4    .ivec no_isr
        nop_16
int5    .ivec no_isr
        nop_16
int6    .ivec no_isr
        nop_16
int7    .ivec no_isr
        nop_16
int8    .ivec no_isr
        nop_16
int9    .ivec no_isr
        nop_16
int10   .ivec no_isr
        nop_16
int11   .ivec no_isr
        nop_16
int12   .ivec no_isr
        nop_16
int13 .ivec no_isr
        nop_16
int14   .ivec no_isr
        nop_16
int15   .ivec no_isr
        nop_16
int16   .ivec no_isr
        nop_16
int17   .ivec no_isr
        nop_16
int18   .ivec no_isr
        nop_16
int19   .ivec no_isr
        nop_16
int20   .ivec no_isr
        nop_16
int21   .ivec no_isr
        nop_16
int22   .ivec no_isr
        nop_16
int23   .ivec no_isr
        nop_16
int24   .ivec no_isr
        nop_16
int25   .ivec no_isr
        nop_16
int26   .ivec no_isr
        nop_16
int27   .ivec no_isr
        nop_16
int28   .ivec no_isr
        nop_16
int29   .ivec no_isr
        nop_16
 
 
        .text
        .def no_isr
no_isr:
        b #no_isr
vectors.s55文件没有任何的变动,也不需要任何的变动,直接拷贝就行了。

回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复