6748与FPGA通过upp通信

背景:FPGA控制四路ADC采集数据(16bit),采样率128k,数据经过FPGA时加入高16位的标识符标记其来源,32位的数据通过UPP传输给DSP,此时DSP的UPP内置DMA设置为8bit接收模式(I通道),upp外部时钟为12MHz,将L1、L2、DDR2都设置为缓存,缓存窗buffer设置为1280byte × 6行,line_offset为1280byte

问题:

根据DSP计算结果来看,参与DSP计算的数据严重滞后于ADC采集到的数据。(如定位时,目标耗时3s从12点钟方向移动到1点钟方向,DSP结果的变化趋势与目标一致,但是该趋势耗费的时间可能为1min),觉得应该是缓存的数据更新没跟上,怎么才能保证DSP每次参与计算的数据都是最新的呢?(每个循环都启动DMA传输)


8 个回复

  • 状元 186657 points
    图片显示不出来,要插入图片,试试用pingpong buffer。
  • user4511301
    将L1、L2、DDR2都设置为缓存

    你的意思是说将DDR设为可被Cache吧。

    我觉得可能是没做Cache一致操作造成的。

    建议:

    #1.  为了验证我的猜测,将buffer改到SHARERAM,即0x8000 0000开始的那一块128KB的空间,或者在L2上留出一块做RAM,将uPP的buffer放在上面。再看计算结果如何。

    #2. 如果按#1没问题了,那么就是Cache的一致性维护问题,在每次计算完,做一次Cache invalid操作。

    http://processors.wiki.ti.com/index.php/Main_Page

    Think Over Before Asking.

    http://www.catb.org/~esr/faqs/smart-questions.html#goal

  • 回复 Tony Tang:

    您好,我们是把DDR都设为“可被cache”了,在每次计算完成都做了cache invalid操作。会不会是因为FPGA给UPP的时钟太快导致的,平均下来FPGA在1s内给DSP的数据,足够DSP计算30s了。而FPGA还源源不断地往DSP里塞...
  • 回复 Shine:

    您好,我们暂时不考虑pingpong操作~
  • 回复 user4511301:

    首贴中的Cache invalid的位置不是太合理吧。直接放在upp transfer后,我不知道upp transfer函数里是否有等待传输完成。可以的话,把你的数据,及处理流程描述一下。

    为什么不能用ping pong buffer, UPP是很容易做ping pong buffer操作的啊。

    http://processors.wiki.ti.com/index.php/Main_Page

    Think Over Before Asking.

    http://www.catb.org/~esr/faqs/smart-questions.html#goal

  • 回复 Tony Tang:

    数据就是(每次FPGA通过UPP发送1280*6*32bit,upp传输完成后,cache invalid,进行下一步解算,uart传给上位机),不断循环括号内的流程。我们想upp传输完成后,在进行解算的这段时间内,让dsp忽略掉fpga过来的数据。因为看到在接收模式下I/Q通道可以输出一个WAIT来忽略掉传输过来的数据,尝试利用CHA(接收模式)的WAIT给fpga一个信号,fpga收到该信号后停止发送,但是发现相应的管脚没有WAIT输出。

  • 回复 Tony Tang:

    请问有没有ping pang buffer的例程可以参考啊?刚接触fpga和dsp的upp通信,水平实在有限...
  • 您好,能将upp配置那块的代码发一下嘛,我也想配置成单通道一直接收,可是修改官方例程uppBtoA,修改成单通道,就不再进入DMA中断了。下面是我配置和中断服务程序部分,while(1)中的代码和您贴出来的一样。能告诉我哪里配置错了嘛
    /* 中断服务函数 */
    Void uPPIsr(UArg arg)
    {
    unsigned int intr_dmai_status;
    // 取得 DMA 中断状态
    intr_dmai_status = uPPIntStatus(SOC_UPP_0_REGS, uPP_DMA_CHI);
    while(intr_dmai_status != 0 )//|| intr_dmaq_status != 0)
    {
    if (intr_dmai_status & uPP_INT_EOW)
    {
    uPPIntClear(SOC_UPP_0_REGS, uPP_DMA_CHI, uPP_INT_EOW);
    upp_interrupt_count++;
    }
    // 判断是否全部事情被处理完毕
    intr_dmai_status = uPPIntStatus(SOC_UPP_0_REGS, uPP_DMA_CHI);
    }
    // 通知 CPU uPP 中断处理完毕以便后续事件可以产生
    uPPEndOfInt(SOC_UPP_0_REGS);
    }
    /* uPP 初始化 */
    void OmaplFpgauPPSetup(void)
    {
    // 外设使能
    PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_UPP, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);
    // 引脚复用配置
    uPPPinMuxSetup(uPP_CHA_8BIT);
    // uPP复位
    uPPReset(SOC_UPP_0_REGS);
    // 数据格式配置
    uPPDataFmtConfig(SOC_UPP_0_REGS, uPP_CHA, uPP_DataPackingFmt_LJZE | uPP_DataPacking_FULL
    | uPP_InterfaceWidth_8BIT | uPP_DataRate_SINGLE);
    // 通道配置
    uPPChannelConfig(SOC_UPP_0_REGS, uPP_DDRDEMUX_DISABLE | uPP_SDRTXIL_DISABLE | uPP_CHN_TWO
    | uPP_ALL_RECEIVE);
    //通道DLB配置 ZM APPEND
    uPPDLBConfig(SOC_UPP_0_REGS, UPP_UPDLB_BA);
    // 引脚配置
    uPPPinConfig(SOC_UPP_0_REGS, uPP_CHA, uPP_PIN_TRIS | uPP_PIN_ENABLE | uPP_PIN_WAIT | uPP_PIN_START);
    // 中断使能
    uPPIntEnable(SOC_UPP_0_REGS, uPP_DMA_CHI, uPP_INT_EOW);
    // uPP使能
    uPPEnable(SOC_UPP_0_REGS);
    }