TI中文支持网
TI专业的中文技术问题搜集分享网站

5535DMA问题

我看了一个C55XX系列的DSP的DMA配置成ping-pong模式的例子,设置断点进行调试,理论上应该是先是ping,后是pong交替进行,但是在调试的时候并不是交替的,只有第一次是的,后面总是好几次pong后在是ping,要么就是好几次ping后再是pong,请问这是什么原因呢?请问还有没有相关的DMAping-pong的例子,有没有那种不是CSL编写的,谢谢!

Tony Tang:

Chunhua,

下面是我几年前做的C55的DMA的PING-PONG的例子,我想可以根据其大体思路对比看看你的程序的问题在哪吧。

#pragma DATA_ALIGN(gBufferRcvPing,128);#pragma DATA_ALIGN(gBufferRcvPong,128);#pragma DATA_ALIGN(gBufferXmtPing,128);#pragma DATA_ALIGN(gBufferXmtPong,128);#pragma DATA_ALIGN(gBufferXmtPingMic,128);#pragma DATA_ALIGN(gBufferXmtPongMic,128);

#pragma DATA_SECTION(gBufferRcvPing, ".gBufferRcvPing");#pragma DATA_SECTION(gBufferRcvPong, ".gBufferRcvPong");#pragma DATA_SECTION(gBufferXmtPing, ".gBufferXmtPing");#pragma DATA_SECTION(gBufferXmtPong, ".gBufferXmtPong");#pragma DATA_SECTION(gBufferXmtPingMic, ".gBufferXmtPingMic");#pragma DATA_SECTION(gBufferXmtPongMic, ".gBufferXmtPongMic");  short gBufferRcvPing[BUFFSIZE];short gBufferRcvPong[BUFFSIZE];short gBufferXmtPing[BUFFSIZE];short gBufferXmtPong[BUFFSIZE];short gBufferXmtPingMic[BUFFSIZE];short gBufferXmtPongMic[BUFFSIZE];

Uint16 eventIdRcv;Uint16 eventIdXmt;Uint16 eventIdXmtMic;

DMA_Handle hDmaXmt;DMA_Handle hDmaRcv;DMA_Handle hDmaXmtMic;

int pingOrPong = PING;int pingorpong = PING;int pingorpongMic = PING;Uint32 addr;Uint32 xmt_addr;Uint32 xmtmic_addr;ptr_MessageStr* ptr_Me;

RING_ID rdBuf;RING_ID rdBufMic;short *buffer;short *bufferMic;

DMA_Config  gDmaConfigXmt = {   DMA_DMACSDP_RMK(    DMA_DMACSDP_DSTBEN_NOBURST,    DMA_DMACSDP_DSTPACK_OFF,    DMA_DMACSDP_DST_PERIPH,    DMA_DMACSDP_SRCBEN_NOBURST,    DMA_DMACSDP_SRCPACK_OFF,    DMA_DMACSDP_SRC_DARAM,    DMA_DMACSDP_DATATYPE_16BIT  ),                                       /* Source/Destination Register – DMACSDP  */  DMA_DMACCR_RMK(    DMA_DMACCR_DSTAMODE_CONST,    DMA_DMACCR_SRCAMODE_POSTINC,    DMA_DMACCR_ENDPROG_OFF,    DMA_DMACCR_REPEAT_ALWAYS,    DMA_DMACCR_AUTOINIT_ON,    DMA_DMACCR_EN_STOP,    DMA_DMACCR_PRIO_HI,    DMA_DMACCR_FS_DISABLE,    DMA_DMACCR_SYNC_XEVT1  ),                                       /* Control Register – DMACCR   */  DMA_DMACICR_RMK(    DMA_DMACICR_BLOCKIE_ON,    DMA_DMACICR_LASTIE_OFF,    DMA_DMACICR_FRAMEIE_OFF,    DMA_DMACICR_FIRSTHALFIE_OFF,    DMA_DMACICR_DROPIE_OFF,    DMA_DMACICR_TIMEOUTIE_OFF  ),                                       /* Interrupt Control Register – DMACICR  */    0,                /* Lower Source Address – DMACSSAL */    0,                                     /* Upper Source Address – DMACSSAU */    0,                            /* Lower Destination Address – DMACDSAL */    0,                                     /* Upper Destination Address – DMACDSAU */    BUFFSIZE,                              /* Element Number – DMACEN   */    1,                                     /* Frame Number – DMACFN   */    0,                                     /* Frame Index – DMACFI   */    0                                      /* Element Index – DMACEI   */};

DMA_Config  gDmaConfigRcv = {   DMA_DMACSDP_RMK(    DMA_DMACSDP_DSTBEN_NOBURST,    DMA_DMACSDP_DSTPACK_OFF,    DMA_DMACSDP_DST_DARAM,         //OK    DMA_DMACSDP_SRCBEN_NOBURST,    //OK    DMA_DMACSDP_SRCPACK_OFF,       //OK    DMA_DMACSDP_SRC_PERIPH,      //OK    DMA_DMACSDP_DATATYPE_16BIT   //OK  ),                                       /* Source/Destination Register – DMACSDP  */  DMA_DMACCR_RMK(    DMA_DMACCR_DSTAMODE_POSTINC,    DMA_DMACCR_SRCAMODE_CONST,    DMA_DMACCR_ENDPROG_OFF,    DMA_DMACCR_REPEAT_ALWAYS,    DMA_DMACCR_AUTOINIT_ON,    DMA_DMACCR_EN_STOP,    DMA_DMACCR_PRIO_HI,    DMA_DMACCR_FS_DISABLE,    DMA_DMACCR_SYNC_REVT0  ),                                       /* Control Register – 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  ),                                       /* Interrupt Control Register – DMACICR  */    0,                /* Lower Source Address – DMACSSAL */    0,                                     /* Upper Source Address – DMACSSAU */    0,                            /* Lower Destination Address – DMACDSAL */    0,                                     /* Upper Destination Address – DMACDSAU */    BUFFSIZE,                              /* Element Number – DMACEN   */    1,                                     /* Frame Number – DMACFN   */    0,                                     /* Frame Index – DMACFI   */    0                                      /* Element Index – DMACEI   */};

DMA_Config  gDmaConfigXmtMic = {   DMA_DMACSDP_RMK(    DMA_DMACSDP_DSTBEN_NOBURST,    DMA_DMACSDP_DSTPACK_OFF,    DMA_DMACSDP_DST_PERIPH,    DMA_DMACSDP_SRCBEN_NOBURST,    DMA_DMACSDP_SRCPACK_OFF,    DMA_DMACSDP_SRC_DARAM,    DMA_DMACSDP_DATATYPE_16BIT  ),                                       /* Source/Destination Register – DMACSDP  */  DMA_DMACCR_RMK(    DMA_DMACCR_DSTAMODE_CONST,    DMA_DMACCR_SRCAMODE_POSTINC,    DMA_DMACCR_ENDPROG_OFF,    DMA_DMACCR_REPEAT_ALWAYS,    DMA_DMACCR_AUTOINIT_ON,    DMA_DMACCR_EN_STOP,    DMA_DMACCR_PRIO_HI,    DMA_DMACCR_FS_DISABLE,    DMA_DMACCR_SYNC_XEVT0  ),                                       /* Control Register – DMACCR   */  DMA_DMACICR_RMK(    DMA_DMACICR_BLOCKIE_ON,    DMA_DMACICR_LASTIE_OFF,    DMA_DMACICR_FRAMEIE_OFF,    DMA_DMACICR_FIRSTHALFIE_OFF,    DMA_DMACICR_DROPIE_OFF,    DMA_DMACICR_TIMEOUTIE_OFF  ),                                       /* Interrupt Control Register – DMACICR  */    0,                /* Lower Source Address – DMACSSAL */    0,                                     /* Upper Source Address – DMACSSAU */    0,                            /* Lower Destination Address – DMACDSAL */    0,                                     /* Upper Destination Address – DMACDSAU */    BUFFSIZE,                              /* Element Number – DMACEN   */    1,                                     /* Frame Number – DMACFN   */    0,                                     /* Frame Index – DMACFI   */    0                                      /* Element Index – DMACEI   */};

void initDma(){

 ptr_Me = (ptr_MessageStr*)0xc0; buffer = (short*)0x1300; bufferMic = (short*)0x1400; // Open DMA channels hDmaXmt = DMA_open(0,DMA_OPEN_RESET); hDmaRcv = DMA_open(1,DMA_OPEN_RESET); hDmaXmtMic = DMA_open(2,DMA_OPEN_RESET);  /* 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 in order to        */    /* change the word address to a byte address for the DMA transfer.    */      gDmaConfigXmt.dmacssal = (DMA_AdrPtr)(((Uint32)(&gBufferXmtPing)<<1)&0x00FFFF);      /* Lower Source Address */     gDmaConfigXmt.dmacssau = (Uint16)((((Uint32)(&gBufferXmtPing)<<1)&0xFF0000) >> 16);     /* Upper Source Address */

     gDmaConfigXmt.dmacdsal = (DMA_AdrPtr)(((Uint32)(&_MCBSP_DXR11)<<1)&0x00FFFF);   /* Lower Destination Address */     gDmaConfigXmt.dmacdsau = (Uint16)((((Uint32)(&_MCBSP_DXR11)<<1)&0xFF0000) >> 16);   /* Upper Destination Address */  // Receive      gDmaConfigRcv.dmacssal = (DMA_AdrPtr)(((Uint32)(&_MCBSP_DRR10)<<1)&0x00FFFF);   /* Lower Source Address */     gDmaConfigRcv.dmacssau = (Uint16)((((Uint32)(&_MCBSP_DRR10)<<1)&0xFF0000) >> 16);   /* Upper Source Address */

     gDmaConfigRcv.dmacdsal = (DMA_AdrPtr)(((Uint32)(&gBufferRcvPing)<<1)&0x00FFFF);   /* Lower Destination Address */     gDmaConfigRcv.dmacdsau = (Uint16)((((Uint32)(&gBufferRcvPing)<<1)&0xFF0000) >> 16);     /* Upper Destination Address */

     gDmaConfigXmtMic.dmacssal = (DMA_AdrPtr)(((Uint32)(&gBufferXmtPingMic)<<1)&0x00FFFF);      /* Lower Source Address */     gDmaConfigXmtMic.dmacssau = (Uint16)((((Uint32)(&gBufferXmtPingMic)<<1)&0xFF0000) >> 16);     /* Upper Source Address */

     gDmaConfigXmtMic.dmacdsal = (DMA_AdrPtr)(((Uint32)(&_MCBSP_DXR10)<<1)&0x00FFFF);   /* Lower Destination Address */     gDmaConfigXmtMic.dmacdsau = (Uint16)((((Uint32)(&_MCBSP_DXR10)<<1)&0xFF0000) >> 16);   /* Upper Destination Address */ 

 // Write values from DMA config structure to DMA channel control registers DMA_config(hDmaXmt, &gDmaConfigXmt); DMA_config(hDmaRcv, &gDmaConfigRcv); DMA_config(hDmaXmtMic,&gDmaConfigXmtMic);  rdBuf = rngCreate(BUFFSIZE*10); if(!rdBuf)  LOG_printf(&TestLOG, "rngCreate err!"); rngFlush (rdBuf);   rdBufMic = rngCreate(BUFFSIZE*10); if(!rdBufMic)  LOG_printf(&TestLOG, "rngMicCreate err!"); rngFlush (rdBufMic);}  void processBuffer(void){ short pingPong;// Int16 switch2;  // Read DIP switch 2//    switch2 = DSK5510_DIP_get(2);  // Get mailbox value pingPong = SWI_getmbox();  // Determine current pingPong state    if(pingPong==PING){

  ptr_Me->rcv_flag = 0x5555;     CHIP_FSET(ST3_55, HINT, 0);  CHIP_FSET(ST3_55, HINT, 1);

//        copyData(gBufferRcvPing, gBufferXmtPing, BUFFSIZE);

//  copyData(gBufferRcvPing, buffer, BUFFSIZE);     // Reprogram config regs for PingL     addr = ((Uint32)gBufferRcvPing) << 1;     DMA_RSETH(hDmaRcv, DMACDSAL, addr & 0xffff);     DMA_RSETH(hDmaRcv, DMACDSAU, (addr >> 16) & 0xffff);/*     addr = ((Uint32)gBufferXmtPing) << 1;         DMA_RSETH(hDmaXmt, DMACSSAL, addr & 0xffff);     DMA_RSETH(hDmaXmt, DMACSSAU, (addr >> 16) & 0xffff);     */     //LOG_printf(&TestLOG, "PING");        }        else{    ptr_Me->rcv_flag = 0xaaaa;  CHIP_FSET(ST3_55, HINT, 0);  CHIP_FSET(ST3_55, HINT, 1);//        copyData(gBufferRcvPong, gBufferXmtPong, BUFFSIZE);//     copyData(gBufferRcvPing, buffer+BUFFSIZE, BUFFSIZE);     // Reprogram config regs for PongL     addr = ((Uint32)gBufferRcvPong) << 1;     DMA_RSETH(hDmaRcv, DMACDSAL, addr & 0xffff);     DMA_RSETH(hDmaRcv, DMACDSAU, (addr >> 16) & 0xffff);/*     addr = ((Uint32)gBufferXmtPong) << 1;         DMA_RSETH(hDmaXmt, DMACSSAL, addr & 0xffff);     DMA_RSETH(hDmaXmt, DMACSSAU, (addr >> 16) & 0xffff); */          //LOG_printf(&TestLOG, "PONG");        }}

void dmaHwi(void){    // Read the DMA status registers to clear it so new interrupts will be seen    DMA_RGETH(hDmaRcv, DMACSR);        // Determine if current state is PING or PONG    if(pingOrPong==PING){      // Post SWI thread to process PING data  SWI_or(&processBufferSwi, PING);    pingOrPong = PONG; }  else{   // Post SWI thread to process PONG data  SWI_or(&processBufferSwi, PONG);    pingOrPong = PING; }}

void XmtprocessBuffer(void){ short pingPong; pingPong = SWI_getmbox();  if(pingPong==PING) { // DMA_start(hDmaXmt);  if(!rngIsEmpty(rdBuf))  {   rngBufGet(rdBuf,gBufferXmtPing,BUFFSIZE);  }  else    LOG_printf(&TestLOG, "rng buf is empty!"); // DMA_RSETH(hDmaXmt,DMACEN,(Uint16)ptr_Me->xmt_length);  xmt_addr = ((Uint32)gBufferXmtPing) << 1;          DMA_RSETH(hDmaXmt, DMACSSAL, xmt_addr & 0xffff);      DMA_RSETH(hDmaXmt, DMACSSAU, (xmt_addr >> 16) & 0xffff);     // DMA_start(hDmaXmt); } else { // DMA_start(hDmaXmt);  if(!rngIsEmpty(rdBuf))  {   rngBufGet(rdBuf,gBufferXmtPong,BUFFSIZE);  }  else    LOG_printf(&TestLOG, "rng buf is empty!"); // DMA_RSETH(hDmaXmt,DMACEN,(Uint16)ptr_Me->xmt_length);  xmt_addr = ((Uint32)gBufferXmtPong) << 1;          DMA_RSETH(hDmaXmt, DMACSSAL, xmt_addr & 0xffff);      DMA_RSETH(hDmaXmt, DMACSSAU, (xmt_addr >> 16) & 0xffff);     // DMA_start(hDmaXmt); }}

void XmtprocessBufferMic(void){ short pingPong; pingPong = SWI_getmbox();  if(pingPong==PING) { // DMA_start(hDmaXmt);  if(!rngIsEmpty(rdBufMic))   rngBufGet(rdBufMic,gBufferXmtPingMic,BUFFSIZE);  else    LOG_printf(&TestLOG, "rng buf is empty!"); // DMA_RSETH(hDmaXmt,DMACEN,(Uint16)ptr_Me->xmt_length);  xmtmic_addr = ((Uint32)gBufferXmtPingMic) << 1;          DMA_RSETH(hDmaXmtMic, DMACSSAL, xmtmic_addr & 0xffff);      DMA_RSETH(hDmaXmtMic, DMACSSAU, (xmtmic_addr >> 16) & 0xffff);     // DMA_start(hDmaXmt); } else { // DMA_start(hDmaXmt);  if(!rngIsEmpty(rdBufMic))   rngBufGet(rdBufMic,gBufferXmtPongMic,BUFFSIZE);  else    LOG_printf(&TestLOG, "rng buf is empty!"); // DMA_RSETH(hDmaXmt,DMACEN,(Uint16)ptr_Me->xmt_length);  xmtmic_addr = ((Uint32)gBufferXmtPongMic) << 1;          DMA_RSETH(hDmaXmtMic, DMACSSAL, xmtmic_addr & 0xffff);      DMA_RSETH(hDmaXmtMic, DMACSSAU, (xmtmic_addr >> 16) & 0xffff);     // DMA_start(hDmaXmt); }}

void hpiHwi(void){ if(!rngIsFull(rdBufMic)) {  rngBufPut(rdBufMic,buffer,BUFFSIZE); // LOG_printf(&TestLOG, "hpHwi %d\n", rngNBytes(rdBufMic));  } else  LOG_printf(&TestLOG, "rng buf is full!\n");

 if(!rngIsFull(rdBuf)) {  rngBufPut(rdBuf,buffer,BUFFSIZE); // LOG_printf(&TestLOG, "hpHwi %d\n", rngNBytes(rdBuf));  } else  LOG_printf(&TestLOG, "rng buf is full!\n");}

void dmaXmtHwi(void){ DMA_RGETH(hDmaXmt, DMACSR);  if(pingorpong==PING){      // Post SWI thread to process PING data  SWI_or(&XmtprocessBufferSwi, PING);    pingorpong = PONG; }  else{   // Post SWI thread to process PONG data  SWI_or(&XmtprocessBufferSwi, PONG);    pingorpong = PING; }}

void dmaXmtMicHwi(void){ DMA_RGETH(hDmaXmtMic, DMACSR);  if(pingorpongMic==PING){      // Post SWI thread to process PING data  SWI_or(&XmtprocessBufferMicSwi, PING);    pingorpongMic = PONG; }  else{   // Post SWI thread to process PONG data  SWI_or(&XmtprocessBufferMicSwi, PONG);    pingorpongMic = PING; }}

 

赞(0)
未经允许不得转载:TI中文支持网 » 5535DMA问题
分享到: 更多 (0)