嵌入式开发者社区

标题: FPGA和Omapl138的dsp核使用upp通信,总是出现uor错误中断,这... [打印本页]

作者: kevinjoyo    时间: 2017-6-26 14:26
标题: FPGA和Omapl138的dsp核使用upp通信,总是出现uor错误中断,这...
FPGA和Omapl138的dsp核使用upp通信,总是出现uor错误中断,这时为什么?  v0 {! T6 o8 G$ L- M/ V0 P
dsp使用i发送到fpga,fpga使用q发送数据到dsp,dsp的发送中断间隔是40us左右,经常收到uori错误,不知道是什么原因。示波器看每次upp发送时间都是很少的。upp中断服务程序如下:
5 Z# r$ V& Y& H5 _u32 UPP_Isr()5 \7 C6 `6 h/ s1 a
{! B1 D- T2 T5 f0 @! \: r
    Uint32 intr_status = upp_reg_hdl->UPIER;+ x" P; v7 ?4 n1 z2 R& C* C( h' b
    upp_reg_hdl->UPIER = intr_status;//clear* _% C+ b* r; J- i. B9 W4 O( K: y1 A
//    Log_print0(Diags_ENTRY | Diags_INFO, "--> UPP_Isr:");1 p1 A+ J: m' z! A+ }
    u32 ret=0;4 |8 p' {8 L9 q0 s4 v% y3 P7 |, E
* {- r: Z( O( P' K" w9 l! X8 i. L
    // inline functions( S, [) \2 }! W2 O: ]0 A, T8 }
    while (intr_status != 0)
% e" M7 X  v, I% `2 `    {' ]) M' T% T9 l0 p
        if (intr_status & CSL_UPP_UPISR_EOLI_MASK)//Line结束事件8 J- c- d; X4 V
        {
' k+ @9 o" ?/ K, W- y3 c, q- L//            Log_print0(Diags_INFO,"eoli.\n");
$ J3 Q6 n' {2 C, S; Y            upp_reg_hdl->UPIER = (CSL_UPP_UPISR_EOLI_MASK);
7 U6 ~7 a# O/ s        }
5 {: T  I5 k' c3 ]% y0 ~! {  E" F, w6 A6 v& |' A1 _
        if (intr_status & CSL_UPP_UPISR_EOWI_MASK)//Window结束事件& L3 ^. t0 V0 D0 y8 E1 \. Y& C9 m
        {
# C: y' p. E5 I- [$ M; ?            Log_print0(Diags_INFO,"eowi.\n");
8 J: O2 l0 @+ Q4 e" U            upp_reg_hdl->UPIER = (CSL_UPP_UPISR_EOWI_MASK);
( M* {3 U( l4 e1 Q: J' b2 ?            upp_interrupt_count++;
7 u( p& y7 x; N            upp_interrupt_eowi_count++;
5 [- o- Y, O& g/ Y% O; C$ N7 d2 n6 \% M6 A2 g& V
#if UPP_DIR_QI==0
6 X9 v2 r5 u0 g2 D* f/ H            upp_dma_receivestart();
. S$ N+ Y( `- v  M+ k            ret=1;
$ j" ~8 }, p6 S! ~$ C* [#endif
: g; o) y! U. @' d6 h5 d9 x! E        }& [1 W% g5 s( K" S2 X
' `0 B. I' P+ @5 d0 W
        if (intr_status & CSL_UPP_UPISR_ERRI_MASK)//内部总线错误事件7 \6 `+ I3 G& n3 a' p
        {
$ m% m. y4 I! k8 ^4 J4 `% V1 Z7 }            Log_print0(Diags_INFO,"erri.\n");
3 h. x1 [8 j3 R9 `$ G8 ^            upp_reg_hdl->UPIER = (CSL_UPP_UPISR_ERRI_MASK);; m( p$ @6 j5 J3 Q/ C
            upp_error_count++;( i* D( R+ l7 Q( y3 n2 A
        }
8 b5 y" c4 y: F
6 V9 o/ n' d2 T( Z1 b. n        if (intr_status & CSL_UPP_UPISR_UORI_MASK)//欠载或溢出事件# V) Z8 F5 R3 k+ i8 u: T
        {
, r' O7 f, A( M5 {' q4 W            Log_print0(Diags_INFO,"uori.\n");
1 H- {) \3 C- m* q' ?9 m            upp_reg_hdl->UPIER = (CSL_UPP_UPISR_UORI_MASK);
2 x+ x1 o2 M8 T. @# S            upp_error_count++;) H/ S/ R% j" k1 j
        }1 T( U9 L% t% v+ j/ j* r
: F- \* `: m* O( ]( J3 a3 {9 Q) `
        if (intr_status & CSL_UPP_UPISR_DPEI_MASK)//DMA编程错误事件. W9 ~) g; M- ^! Z$ a) ^6 A+ h
        {/ F0 f4 O' f8 a+ n2 r
            Log_print0(Diags_INFO,"dpei.\n");: i* B8 ^8 V( K4 g6 t' N6 c, }/ O
            upp_reg_hdl->UPIER = (CSL_UPP_UPISR_DPEI_MASK);5 i+ Z+ Y6 U. j' I+ }
            upp_error_count++;
1 s3 k  a4 u' q) W+ e3 _7 J! M6 B        }
0 l' Z5 K# {( J' s8 ~7 _: s
7 i2 Z0 W$ v; e" T& K        if (intr_status & CSL_UPP_UPISR_EOLQ_MASK)
3 J2 Y0 w5 W% m& r        {+ I4 x; G; _5 {) `2 a; i3 D
//            Log_print0(Diags_INFO,"eolq.\n");
7 Z- E1 p+ ]' W' o            upp_reg_hdl->UPIER = (CSL_UPP_UPISR_EOLQ_MASK);
( p( k+ U' p- w        }- {& z, Y; P9 I0 J, d% k8 Q

6 A& _3 Q( y: b: {. o        if (intr_status & CSL_UPP_UPISR_EOWQ_MASK)
) z# c* K+ ~: X! p$ R% o5 M2 i        {0 a/ S1 Z2 b8 N# e% \
//            Log_print0(Diags_INFO,"eowq.\n");- [; ^# C8 R! ?1 z6 f: x% @% D8 x
            upp_reg_hdl->UPIER = (CSL_UPP_UPISR_EOWQ_MASK);2 v) L% `; n5 @. @6 A
            upp_interrupt_count++;
% [9 E+ x* i0 g* H#if UPP_DIR_QI==1  o, {  m9 a/ |0 m$ ~* v' B. r
            upp_dma_receivestart();8 z' @- \! |2 W7 T8 v8 U
            ret=1;
1 K" R0 Z/ a) k#endif2 {& S, @! V/ X. u6 P& {
        }
. B4 D* h4 ]  f! _# V! D8 I5 K6 z# f
  }- m  O- \4 h+ O9 ]- e        if (intr_status & CSL_UPP_UPISR_ERRQ_MASK): _% L) Q- e- n* y3 z" [$ [
        {' C/ K  D( d! E
            Log_print0(Diags_INFO,"errq.\n");
+ ?% D( M$ f& x! `* \) v            upp_reg_hdl->UPIER = (CSL_UPP_UPISR_ERRQ_MASK);
3 p3 j4 {/ k5 z            upp_error_count++;
! E% G8 r4 `7 o& V& z3 E        }
6 Y* X0 A$ h& }! b: `& |  }" L- B) Q/ j
        if (intr_status & CSL_UPP_UPISR_UORQ_MASK): Q: `0 l# e% L7 h; q& z
        {% B# q  Q0 a6 q6 d2 Z
            Log_print0(Diags_INFO,"uorq.\n");9 A9 |5 y2 T1 d6 y
            upp_reg_hdl->UPIER = (CSL_UPP_UPISR_UORQ_MASK);
. P  l9 L: H( y3 J6 G! v& @            upp_error_count++;
$ g8 m& @' f4 j9 ?- U; ?: Z& D        }
3 F$ |( g. m2 ~2 @& j
5 G: d9 Q! F$ F7 X0 k% O/ l        if (intr_status & CSL_UPP_UPISR_DPEQ_MASK)) A' c8 M* o8 I
        {
: u! ]+ [' M% n9 Q  @( @/ i            Log_print0(Diags_INFO,"dpeq.\n");2 {. Q4 @6 n0 ]& \
            upp_reg_hdl->UPIER = (CSL_UPP_UPISR_DPEQ_MASK);
+ q! o2 k, u' f            upp_error_count++;
4 q. t  ~" i7 w. q1 I7 O        }7 X3 h4 F7 a$ n8 L1 ?; v
) u' j5 v! m- J1 ~2 Q
        // make sure all interrupts are handled
. T- `$ q9 Q0 w        intr_status = upp_reg_hdl->UPIER;7 X' N1 l, _+ A) c, b
    }( J) ]+ A5 s1 L# R$ C& {' e& }

: q2 {- {6 t2 w) o" B0 C    // finally: write 0 to EOI register
( o6 L: S5 ^- a2 ^7 j; P    upp_reg_hdl->UPEOI = 0;$ j0 ?3 O+ g$ u" N/ ~4 z+ J  S5 n
    return ret;
2 l( x" F; b* v" q4 o}6 g5 K( D3 `( V  _7 X
dsp发送区大小为512字节,发送txsize设置为256字节。使用的是单行,win窗口是512发送方式。发送调用upp_dma_sendstartQI(I):. ?' @/ e7 k* J# B
#define upp_dma_sendstartQI(x)     {\: y$ f- F2 a! b( y: }
    Wait_upp_SendReadyQI(x);    \
. s9 b  G$ e# b6 O, ^    upp_reg_hdl->UP##x##D0 = (u32)&g_uPPSend;      \% X, e! E. f6 \  B1 {" d- K9 a
    upp_reg_hdl->UP##x##D1 = ((u32)upp_line_count_s << 16) | (u32)upp_line_size_s*sizeof(s32);   \. O5 r6 x5 O3 O- m
    upp_reg_hdl->UP##x##D2 = (u32)upp_line_offset_s * sizeof(s32);\
! I. G4 b  I9 h; j    }
0 D3 b& ?0 F: s9 _9 j: U8 L& C, f; Z* K; B4 }3 l
9 D' u' q* O1 G' q
#define upp_dma_sendstart()     upp_dma_sendstartQI(I)
* i* J* y- z2 k3 i* U. k$ J( {: y8 Z& L- W: m5 j
' T4 ?% q7 V  j& H/ |) |0 D% Y5 ]
想知道uori错误是在什么情况下面出现的,好做出修改。# X2 f$ t5 u& z3 u! @" l
8 O% ^; c8 w4 s4 `7 G

" \3 L- x7 C5 N6 G3 M7 ^$ T+ J
作者: human    时间: 2017-6-26 21:47
明天发你例程参考一下。
作者: kevinjoyo    时间: 2017-6-30 15:14
不好意思,我没看出有什么区别,或者哪里设置错误了。不知道您的这个工程有没有试过dsp端40us周期性发送512字节数据给fpga,fpga不定时发送128字节给dsp,会不会出现uor这个错误。
作者: kevinjoyo    时间: 2017-7-28 12:00
1、dsp初始化upp设备后,在没有发送数据的情况下,dsp使用的upp的发送端start、enable信号一直是高电平,这是不正常的,应该是低电平才对。3 A+ _8 U2 r" a) _$ I
& u1 K# `' s1 H* }
2、在启动uppdma输出后,start信号的高电平有点长(如发间隔为50us,start的高电平达到45us,低电平才5us;start信号不应该是比较短的吗?看手册画的start信号是一个很短的高电平),而且enable信号一直是高从来没低过(数据传输完成,不应该降为低电平吗?),这是什么原因?
作者: Lewis    时间: 2017-7-28 16:38
出现uor错误,操作UPP过于频繁或者系统负载过大,可以尝试降低upp速率,或者加大upp的数据缓冲,降低upp操作频率
作者: kevinjoyo    时间: 2017-8-1 17:36
重新对着例程重新初始化upp设备,目前start、enable信号是正常的。目前是:发送数据有1*512Byte字节,每40us传输一次,接收为1*128Byte不定时FPGA检测硬件状态后上传。想问一下,TXSIZEA(B),RDSIZEI(Q),要怎样设置。试了各种组合,甚至将单速率传输由37.5Mhz降到25Mhz,upp的uori(q)错误一直都有发生(发送端)[attach]2647[/attach]
作者: kevinjoyo    时间: 2017-8-23 09:10
在网上找到关于uor错误的说明:https://support.criticallink.com ... sign_Considerations
作者: kevinjoyo    时间: 2017-8-23 09:28
当我们按照这个文档修改了uPP的发送时钟(syscfg0.syschip3修改为0,0使用pll0_sysclk2)[attach]2735[/attach],这时uPP就不会有uor错误;但是由此又产生了其他错误,因为使用async3_clksrc时钟源的设备都出错了,如图:[attach]2736[/attach],影响了timer2/3、uart1/2等设备。我们整个系统里面使用到了uart1/2、spi1,其他设备除了timer2/3都用做普通IO脚或其他设备去了。! W9 n' N' P2 y& C+ P/ H2 l5 g
3 R2 G* ]! [1 a6 {* y; s/ j" L

  {* r1 O5 Y! y8 l; z; q
作者: kevinjoyo    时间: 2017-8-23 09:50
然后我们就想自己软件层面根据SYS_CLK_CALC_OMAP-L138_C674X_AM18X_v1p3.xls,把我们系统的时钟计算了一遍之后,根据我们实际使用的时钟,在设置upp的发送时钟源时同时设置uart1/2(修改DLH、DLL)、spi1(修改spi_fmt4的prescale)设备的寄存器,这时这些设备都表现好像是正常的。修改代码在dsp端执行:; j0 d' I* I9 }  W" G1 q

: S- D7 h+ K# p( P- q( d* f1、如果在程序启动前使用SecureCRT.exe这个连接了系统的uart2,这时候输入是乱码的,需要断开重新连接才表现正常。0 Q0 x, o1 E$ R  n& D6 T. z
2、如果此时重新初始化uart1、spi1等设备时,这时候uart1的DLL/DLH寄存器就会按之前的时钟源重设了,spi1的prescale也被重设。+ ]1 a3 ]( S( I( K" X: _: }

: `1 v; J8 [1 G; |5 p所以,软件层面修改是不行的。现在希望就是linux系统启动的时候,自动将upp的发送时钟源设置(async3_clksrc)为pll0_sysclk2,同时将跟async3_clksrc相关设备使用的时钟源的频率值修正为与选择的一致,这样避免重新初始化这些外设时由于使用错误的频率值造成系统初始化对应寄存器为错误值。
作者: kevinjoyo    时间: 2017-8-23 10:00
dsp端修改时钟代码:9 z% {: ^  w2 h% z" K
  y, F% \- K% R4 r3 ]
    //设置upp外设时钟源 pll0_clock2
, l$ U& ~+ u; k& R0 q. K    u32 temp_reg  = HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_CFGCHIP3);: X' T1 }, B6 [" J$ [( ?
    //uPP时钟源不对8 }  }# N3 |2 i& @' Z" V
//    if(temp_reg &(SYSCFG_CFGCHIP3_UPP_TX_CLKSRC | SYSCFG_CFGCHIP3_ASYNC3_CLKSRC))
8 l: O) R6 R# }5 P    {8 g$ J) M+ j! M3 {
        HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_CFGCHIP3) = (temp_reg & ~(SYSCFG_CFGCHIP3_UPP_TX_CLKSRC | SYSCFG_CFGCHIP3_ASYNC3_CLKSRC));" m+ G' y. J" z- H
        //影响spi1,uart1/2,timer1/2等设备,重新配置* @. |5 {/ S) ]" J- k; |9 K
        //uart1,TS211的通信接口,使用38400,重设分频寄存器
+ C8 C" W# E7 t% ~        HWREG(SOC_UART_1_REGS + UART_DLH) = 0x01;  B" ^; h% h$ c. V" {  C
        HWREG(SOC_UART_1_REGS + UART_DLL) = 0x73+1;
9 q& W: e4 Q  d        //uart2,linux的通信接口,使用115200,重设分频寄存器
* H. K% B7 B& P        HWREG(SOC_UART_2_REGS + UART_DLL) = (0x7B+1);2 a4 n# L1 y3 i/ p+ O' F# P
        //spi1,arm与fpga通信使用
9 Y. P7 |: J7 ?: H8 x        temp_reg  = HWREG(SOC_SPI_1_REGS + SPI_SPIFMT(0)) & ~SPI_SPIFMT_PRESCALE;* k' w+ @1 b# o! Y6 R5 l
        HWREG(SOC_SPI_1_REGS + SPI_SPIFMT(0)) = (temp_reg | (SPI_SPIFMT_PRESCALE & ((27)<<SPI_SPIFMT_PRESCALE_SHIFT)));% S: \1 E- w( J+ y* [* S# d2 [- f
    }
# ~' _; t2 b. ]9 \7 K7 _! E, p; B* ]* p2 q3 e, [' h
uart1/2时钟图(分频值需要+1之后分高低字节填入DLL/DLH):
4 o) X% V/ g5 E" M% q+ S[attach]2738[/attach][attach]2739[/attach]. Q1 R. H7 j/ i/ t8 _) E
spi图:% W! n# Y- E) ]5 W) x: H4 [  A# ?
[attach]2740[/attach]2 @7 `- \5 x5 c# q3 S$ Q





欢迎光临 嵌入式开发者社区 (https://www.51ele.net/) Powered by Discuz! X3.4