您的位置: OpenADSP社区论坛 -> Blackfin专区 -> 新手上路 -> [求助]SPORT0、SPORT1同时使用时关于DMA的问... 
本帖共有1563个阅读者
发表帖子 发表投票 回复主题
[求助]SPORT0、SPORT1同时使用时关于DMA的问题
Ancients(论坛新手)
Ancients
头衔:社区公民
帮派:无帮无派
帖数:9
金钱:31
积分:10
注册时间:2011/10/4
楼主信息 | 留言 | Email | 主页 | 编辑 | 管理 | 离线
[求助]SPORT0、SPORT1同时使用时关于DMA的问题

实验目的是要通过SPORT0的接收部分利用AC23的ADC采集音频,然后通过SPORT1发送部分发送,再通过SPORT1的接收部分接收后,利用SPORT0的发送部分发给AC23的DAC转换成音频信号,目前SPORT1的发送部分和接收部分用导线直连,程序使用了两个中断,但目前现象是能够检测到SPORT1发送部分确实发送出了信号,但是AC23的DAC输出无信号,不确定问题到底是出在SPORT1接受部分还是SPORT0发送部分,程序代码如下,是利用光盘中的AUDIO的代码改写的,请各位高手多多指教!

#include <cdefBF533.h>
#include <ccblkfn.h>
#include <sysreg.h>
#include "audio_talkthrough.h"
#include "audio_regdef.h"
#include "fract.h"
#define POLC  0x00004000
#define PORT_CFG_2_3_EXT_FS 0x00000020
#define XFR_TYPE_NON_ITU656 0x0000000C
#define SLEN_32 0x001f
/****************************************************************************
* 名称 :Init_Timers
* 功能 :初始化TIMER0 为PWM模式。
* 入口参数 :无
* 出口参数 :无
****************************************************************************/
void Init_Timers(void)
{
*pTIMER0_CONFIG  = 0x0019;
*pTIMER0_PERIOD  = 0x00800000;
*pTIMER0_WIDTH  = 0x00400000;
*pTIMER_ENABLE  = 0x0001;
}

/*void Init_Sport0(void)
{
*pSPORT0_RCR1 = RSFSE | RFSR  | RCKFE;
*pSPORT0_RCR2 = SLEN_32;

*pSPORT0_TCR1 = TSFSE | TFSR | LATFS | TCKFE;
*pSPORT0_TCR2 = SLEN_32;
}*/

void Init_Sport0(void)
{
*pSPORT0_RCLKDIV = 19;
*pSPORT0_RFSDIV = 63;
*pSPORT0_RCR1 = RSFSE | IRFS  | IRCLK;
*pSPORT0_RCR2 = SLEN_32;

*pSPORT0_TCLKDIV = 19;
*pSPORT0_TFSDIV = 63;
*pSPORT0_TCR1 = TSFSE | ITFS | LATFS | TCKFE;
*pSPORT0_TCR2 = SLEN_32;
}

void Init_Sport1(void)
{
*pSPORT1_RCLKDIV = 19;
*pSPORT1_RFSDIV = 63;
*pSPORT1_RCR1 = RSFSE | RFSR  | RCKFE;
*pSPORT1_RCR2 = SLEN_32;

*pSPORT1_TCLKDIV = 19;
*pSPORT1_TFSDIV = 63;
*pSPORT1_TCR1 = TSFSE | ITFS | LATFS | ITCLK;
*pSPORT1_TCR2 = SLEN_32;
}

void Init_DMA(void)
{
*pDMA1_PERIPHERAL_MAP = 0x1000;
*pDMA1_CONFIG = WNR | WDSIZE_32 | DI_EN | FLOW_1;
*pDMA1_START_ADDR = (void *)iRxBuffer1;
*pDMA1_X_COUNT = 4;
*pDMA1_X_MODIFY = 4;

*pDMA2_PERIPHERAL_MAP = 0x2000;
*pDMA2_CONFIG = WDSIZE_32 | FLOW_1;
*pDMA2_START_ADDR = (void *)iTxBuffer1;
*pDMA2_X_COUNT = 4;
*pDMA2_X_MODIFY = 4;

*pDMA3_PERIPHERAL_MAP = 0x3000;
*pDMA3_CONFIG = WNR | WDSIZE_32 | DI_EN | FLOW_1;
*pDMA3_START_ADDR = (void *)iRxBuffer2;
*pDMA3_X_COUNT = 4;
*pDMA3_X_MODIFY = 4;

*pDMA4_PERIPHERAL_MAP = 0x4000;
*pDMA4_CONFIG = WDSIZE_32 | FLOW_1;
*pDMA4_START_ADDR = (void *)iTxBuffer2;
*pDMA4_X_COUNT = 4;
*pDMA4_X_MODIFY = 4;
}

void Enable_DMA_Sport(void)
{
*pDMA4_CONFIG = (*pDMA4_CONFIG | DMAEN);
*pDMA3_CONFIG = (*pDMA3_CONFIG | DMAEN);
*pDMA2_CONFIG = (*pDMA2_CONFIG | DMAEN);
*pDMA1_CONFIG = (*pDMA1_CONFIG | DMAEN);

*pSPORT0_TCR1  = (*pSPORT0_TCR1 | TSPEN);
*pSPORT0_RCR1  = (*pSPORT0_RCR1 | RSPEN);
*pSPORT1_RCR1  = (*pSPORT1_RCR1 | RSPEN);
*pSPORT1_TCR1  = (*pSPORT1_TCR1 | TSPEN);

}

void Init_Interrupts(void)
{
*pSIC_IAR0 = 0xffffffff;
*pSIC_IAR1 = (0xffffff2f & 0xfff32fff);
*pSIC_IAR2 = 0xffffffff;

register_handler(ik_ivg9, Sport0_RX_ISR);
register_handler(ik_ivg10, Sport1_RX_ISR);

*pSIC_IMASK = (0x00000200 | 0x00001800);
}
        


/*void Process_Data(void)
{
iChannel0LeftOut = iChannel0LeftIn;
iChannel0RightOut = iChannel0RightIn;
iChannel1LeftOut = iChannel1LeftIn;
iChannel1RightOut = iChannel1RightIn;
}*/

EX_INTERRUPT_HANDLER(Sport0_RX_ISR)
{
*pDMA1_IRQ_STATUS = 0x0001;

iTxBuffer2[1] = iRxBuffer1[1];
iTxBuffer2[2] = iRxBuffer1[2];
iTxBuffer2[3] = iRxBuffer1[3];
iTxBuffer2[4] = iRxBuffer1[4];

//iTxBuffer1[1] = iRxBuffer2[1];
//iTxBuffer1[2] = iRxBuffer2[2];
//iTxBuffer1[3] = iRxBuffer2[3];
//iTxBuffer1[4] = iRxBuffer2[4];
}

EX_INTERRUPT_HANDLER(Sport1_RX_ISR)
{
*pDMA3_IRQ_STATUS = 0x0001;

iTxBuffer1[1] = iRxBuffer2[1];
iTxBuffer1[2] = iRxBuffer2[2];
iTxBuffer1[3] = iRxBuffer2[3];
iTxBuffer1[4] = iRxBuffer2[4];
}
如果去掉Sport1的中断,把EX_INTERRUPT_HANDLER(Sport0_RX_ISR)中屏蔽掉的语句都添加上,那么能实现实验目的中阐述的功能,但是因为实际使用中SPORT1的接收部分和发送部分不是直连关系,而是有一定的延迟,所以为了避免不同步才设想启用两个中断。



「该帖子被 Ancients 在 2011-10-19 23:29:13 编辑过」

这家伙很懒,什么也没有留下!
等级:论坛新手 参考IP地址:*.*.*.*
2011/10/19 23:25:24
尊贵身份标志
andy(论坛版主)
andy
头衔:社区公民
帮派:无帮无派
帖数:2287
金钱:11132
积分:2263
注册时间:2011/6/8
1信息 | 留言 | Email | 主页 | 编辑 | 管理 | 离线

可以按照下面方法去查该问题:

1. 在两个中断函数中打两个断点,每次只打一个函数断点。运行代码,看看是否都能进入这两个中断函数,确定你SPORT0到SPORT1数据传输没有问题。

2. 你的中断屏蔽开关*pSIC_IMASK = (0x00000200 | 0x00001800);,打开了SPORT1的传输中断,代码中没有用到,建议关掉。

3. 检查最后传输到iTxBuffer1[] 的数据是否正确或是否有数据。

4. 将中断代码屏蔽,将SPORT1及SPORT0的接收功能关闭,单独测试SPORT0传输功能,看是否正常。


这家伙很懒,什么也没有留下!
等级:论坛版主 参考IP地址:*.*.*.*
2011/10/20 9:50:44
Ancients(论坛新手)
Ancients
头衔:社区公民
帮派:无帮无派
帖数:9
金钱:31
积分:10
注册时间:2011/10/4
2信息 | 留言 | Email | 主页 | 编辑 | 管理 | 离线
好的,晚上回去试一试,SPORT0\的传输功能应该是好的,因为光盘里面那个AUDIO代码是跑通了的。

这家伙很懒,什么也没有留下!
等级:论坛新手 参考IP地址:*.*.*.*
2011/10/20 10:08:14
Ancients(论坛新手)
Ancients
头衔:社区公民
帮派:无帮无派
帖数:9
金钱:31
积分:10
注册时间:2011/10/4
3信息 | 留言 | Email | 主页 | 编辑 | 管理 | 离线
andy版您好,按照您的方法进行测试,发现不能进入SPORT1的发送中断,但是能够正确进入SPORT0的发送中断,之后使用单步运行测试发现程序在SPORT0的中断服务程序里面循环起来了(即执行完iTxBuffer2[4] = iRxBuffer1[4];之后又回到了*pDMA1_IRQ_STATUS = 0x0001;如此循环往复),还请andy版指导一下有没有什么办法解决...

这家伙很懒,什么也没有留下!
等级:论坛新手 参考IP地址:*.*.*.*
2011/10/20 17:35:33
尊贵身份标志
andy(论坛版主)
andy
头衔:社区公民
帮派:无帮无派
帖数:2287
金钱:11132
积分:2263
注册时间:2011/6/8
4信息 | 留言 | Email | 主页 | 编辑 | 管理 | 离线

原因很简单,由于你SPORT0中断等级高,SPORT1中断等级低,在大量数据处理 时,SPORT0始终会处于优先状态,所以SPORT1不会进中断,你可以这样做:

1. 每次进入SPORT0中断后,通过*pSIC_IMASK 寄存器将SPORT0中断关闭,将SPORT1中断打开。待SPORT1产生中断后再将SPORT0中断打开,将SPORT1中断关闭。

2. 如果发现数据有丢失的话,建议采用乒乓buffer机制,即sport1采集一个buffer的数据,sport0发送另一个buffer的数据。通过标志位将采集和发送的buffer错开,反复交错。


这家伙很懒,什么也没有留下!
等级:论坛版主 参考IP地址:*.*.*.*
2011/10/20 23:50:25
Ancients(论坛新手)
Ancients
头衔:社区公民
帮派:无帮无派
帖数:9
金钱:31
积分:10
注册时间:2011/10/4
5信息 | 留言 | Email | 主页 | 编辑 | 管理 | 离线

哦,谢谢andy版指点,估计真是数据量大了之后的原因,因为后来尝试把两个中断都设置成了9级,结果都不正常了,明天先试验下解决方法一,解决方法2的话估计还要再研究下,估计到时候还要andy版多指教啊!


这家伙很懒,什么也没有留下!
等级:论坛新手 参考IP地址:*.*.*.*
2011/10/20 23:53:20
skylove(论坛新手)
skylove
头衔:社区公民
帮派:无帮无派
帖数:2
金钱:110
积分:2
注册时间:2011/9/30
6信息 | 留言 | Email | 主页 | 编辑 | 管理 | 离线

你的代码写错了,中断序号错了。SPORT1不在IVG10。


这家伙很懒,什么也没有留下!
等级:论坛新手 参考IP地址:*.*.*.*
2012/9/25 23:08:26
尊贵身份标志
andy(论坛版主)
andy
头衔:社区公民
帮派:无帮无派
帖数:2287
金钱:11132
积分:2263
注册时间:2011/6/8
7信息 | 留言 | Email | 主页 | 编辑 | 管理 | 离线

楼上的很细心,确实接收中断等级配置错误,需要将:*pSIC_IAR1 = (0xffffff2f & 0xfff32fff);
改为*pSIC_IAR1 = (0xffffff2f & 0xfff33fff);


这家伙很懒,什么也没有留下!
等级:论坛版主 参考IP地址:*.*.*.*
2012/9/26 8:31:06
Powered by OpenADSP Copyright © 2010 www.Openadsp.com. All rights reserved.159135 Call, 1 Queries, Processed in 0.031250 second(s),