尊敬的各位TI员工,各路大神:
我最近在调试OMAPL138 的UPP 程序时遇到了很棘手的问题,已经卡在这好几天了,各种办法,各种试,实在没辙了.请求各位指点,情况如下:
我使用的是ARM端与FPGA进行 双16位UPP通道的全双工通信.UPP配置为双16位 A发送 B接收双工模式.单速率.
首先ARM端采用A通道发送一帧数据,FPGA接收到后,再发送给ARM端B通道一帧数据.为了调试,后面就不发送和接收任何数据了.现在问题情况是:
1.发送接收的时序波形,发送接收的数据都对.两个发送和接收缓冲区数组的数据与波形数据完全一致,说明硬件外设没有任何问题.
2.我用仿真器跟踪每个寄存器的设置,状态寄存器,配置寄存器等等,每个都寄存器的每个位都一一核对,都没有问题.
3.但是就是进入到UPPIsr后,问题就来了.竟然就出不来了,此时外部硬件确认不发送和接受任何数据.为了配合调试我只发送和接收一次.UPPIsr按照官方提供的样例程序写的.尽管我查看那些寄存器该清除的标志位,都清除了.一步步跟踪都是对的.就是在执行UPP_UPEOI=0;后程序就又跳转到UPPIsr入口处执行.UPPIsr代码如下:
interrupt void UPPIsr(void)
{
unsigned long intr_status = HWREG(SOC_UPP_0_REGS + UPP_UPIER);
testupp+=1;
while (intr_status != 0)
{
if (intr_status & UPP_UPIER_EOLI) //DMA_I通道每一行发送结束引发的中断
{
HWREG(SOC_UPP_0_REGS + UPP_UPIER) =1<<UPP_UPIER_EOLI_SHIFT;
}
if (intr_status & UPP_UPIER_EOWI) //DMA_I通道达到WINDOW底部引发的中断
{
HWREG(SOC_UPP_0_REGS + UPP_UPIER) =1<<UPP_UPIER_EOWI_SHIFT;
Counter_UppTransmitInterrupt++;
Sign_UppTransmitInterrupt=1;
}
if (intr_status & UPP_UPIER_ERRI) //DMA_I故障引发的中断
{
HWREG(SOC_UPP_0_REGS + UPP_UPIER) =1<<UPP_UPIER_ERRI_SHIFT;
Counter_UppTransmitError++;
}
if (intr_status & UPP_UPIER_UORI) //DMA_I故障引发的中断
{
HWREG(SOC_UPP_0_REGS + UPP_UPIER) =1<<UPP_UPIER_UORI_SHIFT;
Counter_UppTransmitError++;
}
if (intr_status & UPP_UPIER_DPEI) //DMA_I故障引发的中断
{
HWREG(SOC_UPP_0_REGS + UPP_UPIER) =1<<UPP_UPIER_DPEI_SHIFT;
Counter_UppTransmitError++;
}
if (intr_status & UPP_UPIER_EOLQ) //DMA_Q通道每一行发送结束引发的中断
{
HWREG(SOC_UPP_0_REGS + UPP_UPIER) =1<<UPP_UPIER_EOLQ_SHIFT;
}
if (intr_status & UPP_UPIER_EOWQ) //DMA_Q通道达到WINDOW底部引发的中断
{
HWREG(SOC_UPP_0_REGS + UPP_UPIER) =1<<UPP_UPIER_EOWQ_SHIFT;
Counter_UppReceiveInterrupt++;
Sign_UppReceiveInterrupt=1;
}
if (intr_status & UPP_UPIER_ERRQ) //DMA_Q故障引发的中断
{
HWREG(SOC_UPP_0_REGS + UPP_UPIER) =1<<UPP_UPIER_ERRQ_SHIFT;
Counter_UppReceiveError++;
}
if (intr_status & UPP_UPIER_UORQ) //DMA_Q故障引发的中断
{
HWREG(SOC_UPP_0_REGS + UPP_UPIER) =1<<UPP_UPIER_UORQ_SHIFT;
Counter_UppReceiveError++;
}
if (intr_status & UPP_UPIER_DPEQ) //DMA_Q故障引发的中断
{
HWREG(SOC_UPP_0_REGS + UPP_UPIER) =1<<UPP_UPIER_DPEQ_SHIFT;
Counter_UppReceiveError++;
}
// make sure all interrupts are handled
intr_status = HWREG(SOC_UPP_0_REGS + UPP_UPIER);
}
// finally: write 0 to EOI register
HWREG(SOC_UPP_0_REGS + UPP_UPEOI) =0;
}
boss BAO:
在线等!
Tony Tang:
回复 boss BAO:
你是说执行到HWREG(SOC_UPP_0_REGS + UPP_UPEOI) =0;又回到ISR的开始吗?
你这个程序是基于starterware里的ISR写的吗?如果是,那么ISR函数前不要加interrupt关键字,因为starterware里这部分中断向量表的处理已加了interrupt了。
退出ISR时程序应该返回调用处,你这个ARM的程序?不是DSP的?在ISR里的时候查看一下中断返回地址寄存器里的地址是多少?
boss BAO:
回复 Tony Tang:
Tony Tang 感谢您的解答
Tony Tang你是说执行到HWREG(SOC_UPP_0_REGS + UPP_UPEOI) =0;又回到ISR的开始吗?
是的.
Tony Tang你这个程序是基于starterware里的ISR写的吗?
是基于技术手册里的样例(技术手册1534-1535页)我自己写的 .
Tony Tang如果是,那么ISR函数前不要加interrupt关键字,因为starterware里这部分中断向量表的处理已加了interrupt了
我已开始是没有interrupt关键字的,后加上的还是那样.
Tony Tang,你这个ARM的程序?不是DSP的?
是ARM程序,我现在还没有使用DSP,只使用了ARM ,我不知道这个Upp 中断处理这里是不是ARM 和DSP有没有什么特别注意的地方?因为我找的所有例子都是针对DSP的.
Tony Tang在ISR里的时候查看一下中断返回地址寄存器里的地址是多少?
我在进入ISR程序时,仿真器跟踪了R13,R14,PC 等寄存器.出程序时发现,PC最后被赋予的地址竟然还是IRQ_Handler入口,就是IRQ入口程序那里就又进入ISR了.我还开了TIMER2中断ISR,并没有任何问题.但这个UPPisr就不行.
另我不知道是用仿真器仿真运行对UPP是否有影响.
Tony Tang:
#1. 再次进来后,读取的中断状态是什么?还是说没有中断状态?
Jessieunsigned long intr_status = HWREG(SOC_UPP_0_REGS + UPP_UPIER);
#2. 作为测试,把最后一句注释掉看是否还会进来:
// finally: write 0 to EOI registerHWREG(SOC_UPP_0_REGS + UPP_UPEOI) =0;
MIKI JIANG:
回复 Tony Tang:
你好tony
我也有类似的情况,
我的配置:
仅仅使能EOWI和EOWQ两个中断。程序运行后一直进中断,
通过Uint32 intr_status = upp_int_status();
读回来的IER寄存器值为0x0000(没有中断标志!)
ISR显示EOLQ和EOLI有中断出现中断,
然后按照您说的额将EOI的注释掉,依旧能进入中断,
更甚着我在中断中禁止了EOWI和EOWQ两个中断,
但程序还是能进入中断。