4545|3

83

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

困扰很久的DMA中断问题 [复制链接]

本帖最后由 dontium 于 2015-1-23 13:35 编辑

采用5509A 和AIC23实现音频采集,I2C通信配置AIC23,然后通过McBSP0接受数据。并通过DMA传输到内存处理。现在的问题是DMA中断有时可以进去,有时进不去。大多时候是进不去。可以确定AIC23和McBSP0在正常工作,因为DRR寄存器的值在不断更新。但是DMA传完一帧后,进不去中断。查看寄存器,IFR相应位已经置1了,怎么就是进不去ISR呢?下面是我的程序,由CSL例程修改而来,ISR里修改DMA配置,实现pingpong切换。
#include <csl.h>

#include <csl_irq.h>

#include <csl_dma.h>

#include <csl_mcbsp.h>
#include \"5509.h\"
//---------Global constants---------

/* Constant defines transfer length */

#define N   128



//---------Global data definition---------


#pragma DATA_SECTION(dst1, \"dmaMem\"

Uint16 dst1[N];

#pragma DATA_SECTION(dst2, \"dmaMem\"

#pragma CODE_SECTION (main, \"saram1Section\"

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

int dst2[N];

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_PERIPH,

    DMA_DMACSDP_DATATYPE_16BIT

  ),                                       /* DMACSDP  */

  DMA_DMACCR_RMK(

    DMA_DMACCR_DSTAMODE_POSTINC,

    DMA_DMACCR_SRCAMODE_CONST,

    DMA_DMACCR_ENDPROG_ON,

    DMA_DMACCR_REPEAT_OFF,

    DMA_DMACCR_AUTOINIT_ON,

    DMA_DMACCR_EN_STOP,

    DMA_DMACCR_PRIO_LOW,

    DMA_DMACCR_FS_DISABLE,
    //DMA_DMACCR_FS_ENABLE,

    DMA_DMACCR_SYNC_REVT0
    //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  */

                                            /* DMACSSAL */

    (DMA_AdrPtr)(MCBSP_ADDR(DRR10)),
    0,                                     /* DMACSSAU */

    (DMA_AdrPtr)&dst1,                     /* DMACDSAL */

    0,                                     /* DMACDSAU */

    N,                                     /* DMACEN   */

    1,                                     /* DMACFN   */

    0,                                     /* DMACFI   */

    0                                      /* DMACEI   */

};



DMA_Handle myhDma;

int i, j;   

volatile Uint16 transferComplete = FALSE;

static int pingpong=0;

Uint16 src1AddrHi, src1AddrLo;

Uint16 src2AddrHi, src2AddrLo;

Uint16 dst1AddrHi, dst1AddrLo;

Uint16 dst2AddrHi, dst2AddrLo;

Uint32 eventId;

Uint16 old_intm;

//---------Function prototypes---------

/* Declare Reference for Start of Interrupt Vector Table */

/* This symbol is defined in the vectors.s55 file        */

extern VECSTART(void);

/* Define a DMA_Handle object */

interrupt void dmaIsr(void);

void DMA_init(void);

//---------main routine---------

void main(void)

{

    /* Initializa CSL library - This is REQUIRED !!! */

    CSL_init();

    EMIF_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 = 0;

        dst2 = 0;

    }

    /* Call function to effect transfer */

    AIC23_Init();
    DMA_init();
   while(1);
}



void DMA_init(void)

{

   
    /* 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);

    src1AddrHi = (Uint16)(((Uint32)(MCBSP_ADDR(DRR10))) >> 15) & 0xFFFFu;

    src1AddrLo = (Uint16)(((Uint32)(MCBSP_ADDR(DRR10))) << 1) & 0xFFFFu;

    dst1AddrHi = (Uint16)(((Uint32)(&dst1)) >> 15) & 0xFFFFu;

    dst1AddrLo = (Uint16)(((Uint32)(&dst1)) << 1) & 0xFFFFu;



    src2AddrHi = (Uint16)(((Uint32)(MCBSP_ADDR(DRR10))) >> 15) & 0xFFFFu;

    src2AddrLo = (Uint16)(((Uint32)(MCBSP_ADDR(DRR10))) << 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);
    //DMA_getConfig(myhDma,&config1);
    /* 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((Uint32)(0x10000));

    /* Place ISR address in associated vector location */

    IRQ_plug(eventId, &dmaIsr);

    /* Enable all maskable interrupts */   

    IRQ_globalEnable();
    IRQ_globalRestore(old_intm);

    /* 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);


    /* Restore GLobal Interrupt Enable to Previous Setting */

    //IRQ_globalRestore(old_intm);

   
}



/* DMA Interrupt Service Routine */

interrupt void dmaIsr(void) {

  IRQ_clear(eventId);
  old_intm = IRQ_globalDisable();

  DMA_FSETH(myhDma,DMACSR,FRAME,0);
  if(pingpong)
  {
        while (DMA_FGETH(myhDma,DMACCR,ENDPROG));
                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);

            DMA_FSETH(myhDma,DMACCR,ENDPROG,1);

        }
        else
        {
        while (DMA_FGETH(myhDma,DMACCR,ENDPROG));
                DMA_RSETH(myhDma,DMACSSAU,src1AddrHi);

            DMA_RSETH(myhDma,DMACSSAL,src1AddrLo);

            DMA_RSETH(myhDma,DMACDSAU,dst1AddrHi);

            DMA_RSETH(myhDma,DMACDSAL,dst1AddrLo);

            DMA_RSETH(myhDma,DMACEN, N);

            DMA_RSETH(myhDma,DMACFN, 1);


            DMA_FSETH(myhDma,DMACCR,ENDPROG,1);

        }

        pingpong=!pingpong;

    IRQ_globalRestore(old_intm);

        IRQ_enable(eventId);

}

最新回复

哈哈,已经调试通了。 求人不如求己 over   详情 回复 发表于 2008-7-9 04:16
点赞 关注

回复
举报

71

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
本帖最后由 dontium 于 2015-1-23 13:35 编辑

我的中断向量表文件:vectors_dma2.s55
*

* Copyright (C) 2003 Texas Instruments Incorporated

* All Rights Reserved

*

*

*---------vectors_dma2.s55---------

*

* Assembly file to set up interrupt vector table

*



        .sect \".vectors\"



*------------------------------------------------------------------------------

* Global symbols defined here and exported out of this file

*------------------------------------------------------------------------------



        .global _VECSTART



*------------------------------------------------------------------------------

* Global symbols referenced in this file but defined somewhere else.

* Remember that your interrupt service routines need to be referenced here.

*------------------------------------------------------------------------------

        .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



*------------------------------------------------------------------------------

* This is a dummy interrupt service routine used to initialize the IST.

*------------------------------------------------------------------------------

        .text

        .def no_isr

no_isr:

        b #no_isr
*------------------------------------------------------------------------------


 
 
 

回复

87

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
没有人遇到类似问题啊?
我将配置里的控制寄存器CCR的repeat值改为1,也就是采用自动重复加载配置的模式,那么数据传输没有任何问题。
现在想在传输一帧后发送DMA中断给CPU,CPU进行处理。同时要在ISR里修改配置的目的地址。就是进不去中断。
 
 
 

回复

60

帖子

0

TA的资源

一粒金砂(初级)

4
 
哈哈,已经调试通了。
求人不如求己
over
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

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

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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

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

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

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