1638|0

1140

帖子

0

TA的资源

纯净的硅(初级)

楼主
 

直接存储器访问(DMA)控制器——TMS320VC5509A [复制链接]

实例主要是两个文件: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文件没有任何的变动,也不需要任何的变动,直接拷贝就行了。

点赞 关注
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表