This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

C6748 SYSBIOS UPP接收FPGA数据,不进DMA中断,哪里配置错误?代码贴出来了,帮看看

Other Parts Discussed in Thread: SYSBIOS

修改SYSBIOS官方例程UPP_B_TO_A,想修改成单通道接收,但不再进入DMA中断了。下面是我配置和中断服务程序部分与task中的代码,能告诉我哪里配置错了嘛
/* 中断服务函数 */
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);
}

Void HWIInit(Void)
{
// 动态创建硬件中断
Hwi_Params hwiParams;
Hwi_Params_init(&hwiParams);
hwiParams.eventId = SYS_INT_UPP_INT;
hwiParams.enableInt = true;
Hwi_create(C674X_MASK_INT4, uPPIsr, &hwiParams, NULL);
}

Void taskMain(UArg arg1, UArg arg2)
{
int target_int_count = 1;
// A 通道参数 接收
transposeParA.WindowAddress = (unsigned int *)((int)upp_buffer_a);
transposeParA.LineCount = upp_line_count;
transposeParA.ByteCount = (upp_line_size*sizeof(unsigned short));
transposeParA.LineOffsetAddress = (upp_line_offset*sizeof(unsigned short));

while(1)
{
// uPP A 通道启动接收
uPPDMATransfer(SOC_UPP_0_REGS, uPP_DMA_CHI, &transposeParA);
// // 等待 uPP 传输完毕
while (upp_interrupt_count < target_int_count)
{
}
}
}

  • 请问“但不再进入DMA中断了”是指第一次能进,后面的中断进不了?
  • 一次都没有进入,debug打断点了,一次都没有进入。
  • 请看一下UPIES寄存器里有没有使能中断?UPIER寄存器的是多少,有没有中断发生? CPU GIE, IER, IFR中断标志位有没有置1?
  • 不知道这个寄存器在哪里查看。 但之前官方UPP_B_TO_A是可以正常进入DMA中断的,我只是将通道配置从两个配置成1个,应该不设计中断使能那块吧。下面是例程代码。
    /****************************************************************************/
    /* */
    /* 中断服务函数 */
    /* */
    /****************************************************************************/
    Void uPPIsr(UArg arg)
    {
    unsigned int intr_dmai_status, intr_dmaq_status;

    // 取得 DMA 中断状态
    intr_dmai_status = uPPIntStatus(SOC_UPP_0_REGS, uPP_DMA_CHI);
    intr_dmaq_status = uPPIntStatus(SOC_UPP_0_REGS, uPP_DMA_CHQ);

    while(intr_dmai_status != 0 || intr_dmaq_status != 0)
    {
    if (intr_dmai_status & uPP_INT_EOL)
    {
    uPPIntClear(SOC_UPP_0_REGS, uPP_DMA_CHI, uPP_INT_EOL);
    }

    if (intr_dmai_status & uPP_INT_EOW)
    {
    uPPIntClear(SOC_UPP_0_REGS, uPP_DMA_CHI, uPP_INT_EOW);
    upp_interrupt_count++;
    }

    if (intr_dmai_status & uPP_INT_ERR)
    {
    uPPIntClear(SOC_UPP_0_REGS, uPP_DMA_CHI, uPP_INT_ERR);
    upp_error_count++;
    }

    if (intr_dmai_status & uPP_INT_UOR)
    {
    uPPIntClear(SOC_UPP_0_REGS, uPP_DMA_CHI, uPP_INT_UOR);
    upp_error_count++;
    }

    if (intr_dmai_status & uPP_INT_DPE)
    {
    uPPIntClear(SOC_UPP_0_REGS, uPP_DMA_CHI, uPP_INT_DPE);
    upp_error_count++;
    }

    if (intr_dmaq_status & uPP_INT_EOL)
    {
    uPPIntClear(SOC_UPP_0_REGS, uPP_DMA_CHQ, uPP_INT_EOL);
    }

    if (intr_dmaq_status & uPP_INT_EOW)
    {
    uPPIntClear(SOC_UPP_0_REGS, uPP_DMA_CHQ, uPP_INT_EOW);
    upp_interrupt_count++;
    }

    if (intr_dmaq_status & uPP_INT_ERR)
    {
    uPPIntClear(SOC_UPP_0_REGS, uPP_DMA_CHQ, uPP_INT_ERR);
    upp_error_count++;
    }

    if (intr_dmaq_status & uPP_INT_UOR)
    {
    uPPIntClear(SOC_UPP_0_REGS, uPP_DMA_CHQ, uPP_INT_UOR);
    upp_error_count++;
    }

    if (intr_dmaq_status & uPP_INT_DPE)
    {
    uPPIntClear(SOC_UPP_0_REGS, uPP_DMA_CHQ, uPP_INT_DPE);
    upp_error_count++;
    }

    // uPP 中断将多个事件组合为同一中断源
    // 判断是否全部事情被处理完毕
    intr_dmai_status = uPPIntStatus(SOC_UPP_0_REGS, uPP_DMA_CHI);
    intr_dmaq_status = uPPIntStatus(SOC_UPP_0_REGS, uPP_DMA_CHQ);
    }

    // 通知 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_CHB_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);

    uPPDataFmtConfig(SOC_UPP_0_REGS, uPP_CHB, 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_DUPLEX0);

    //通道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);

    uPPPinConfig(SOC_UPP_0_REGS, uPP_CHB, uPP_PIN_ENABLE | uPP_PIN_WAIT | uPP_PIN_START);

    // 时钟配置
    // uPPCLK = (CPUCLK / 2) / (2 * (DIV + 1) (DIV = 0, 1, 2, 3 ... 15)
    // 456MHz 主频下支持的时钟 114MHz、57MHz、38MHz、28.5MHz、22.8MHz ......
    uPPClkConfig(SOC_UPP_0_REGS, uPP_CHB, 57000000, 228000000, uPP_PIN_PHASE_NORMAL);
    uPPClkConfig(SOC_UPP_0_REGS, uPP_CHA, 57000000, 228000000, uPP_PIN_PHASE_INVERT);//uPP_PIN_PHASE_NORMAL

    // 空闲输出配置
    uPPIdleValueConfig(SOC_UPP_0_REGS, uPP_CHB, 0xAAAA);

    // 中断使能
    uPPIntEnable(SOC_UPP_0_REGS, uPP_DMA_CHI, uPP_INT_EOW);
    uPPIntEnable(SOC_UPP_0_REGS, uPP_DMA_CHQ, uPP_INT_EOW);

    // uPP使能
    uPPEnable(SOC_UPP_0_REGS);
    }

    /****************************************************************************/
    /* */
    /* 初始化 */
    /* */
    /****************************************************************************/
    Void PeriphInit(Void)
    {
    OmaplFpgauPPSetup();
    }

    Void HWIInit(Void)
    {
    // 动态创建硬件中断
    Hwi_Params hwiParams;

    Hwi_Params_init(&hwiParams);
    hwiParams.eventId = SYS_INT_UPP_INT;
    hwiParams.enableInt = true;

    Hwi_create(C674X_MASK_INT6, uPPIsr, &hwiParams, NULL);
    }

    Void ThreadInit(Void)
    {
    // 硬件中断
    HWIInit();
    }

    /****************************************************************************/
    /* */
    /* 缓存配置 */
    /* */
    /****************************************************************************/
    void CacheInit()
    {
    Cache_Size cacheSize;

    cacheSize.l1pSize = Cache_L1Size_32K;
    cacheSize.l1dSize =Cache_L1Size_32K;
    cacheSize.l2Size = Cache_L2Size_256K;

    Cache_setSize(&cacheSize);
    }

    Void taskMain(UArg arg1, UArg arg2)
    {
    int i, target_int_count = 2;
    char ch[2], put_char[50];

    // 计数器(用于性能测试)
    long long t_start, t_stop, t_overhead;
    TSCL = 0;
    TSCH = 0;
    t_start = _itoll(TSCH, TSCL);
    t_stop = _itoll(TSCH, TSCL);
    t_overhead = t_stop - t_start;

    // A 通道参数 接收
    transposeParA.WindowAddress = (unsigned int *)((int)upp_buffer_a);
    transposeParA.LineCount = upp_line_count;
    transposeParA.ByteCount = (upp_line_size*sizeof(unsigned short));
    transposeParA.LineOffsetAddress = (upp_line_offset*sizeof(unsigned short));

    // B 通道参数 发送
    transposeParB.WindowAddress = (unsigned int *)((int)upp_buffer_b);
    transposeParB.LineCount = upp_line_count;
    transposeParB.ByteCount = (upp_line_size*sizeof(unsigned short));
    transposeParB.LineOffsetAddress = (upp_line_offset*sizeof(unsigned short));

    while(1)
    {
    upp_error_count = 0;
    upp_interrupt_count = 0;

    // 初始化数据
    UARTPuts("\tResetting uPP buffers...\r\n",-2);
    for (i = 0; i < upp_frame_size; i++)
    {
    upp_buffer_b[i] = i;
    upp_buffer_a[i] = 0xDEAD;
    }

    Cache_wb((void *)upp_buffer_a, sizeof(upp_buffer_a), Cache_Type_ALLD, TRUE);
    Cache_wb((void *)upp_buffer_b, sizeof(upp_buffer_b), Cache_Type_ALLD, TRUE);

    UARTprintf ("\tStarting uPP transfers...\r\n");

    // uPP通信速度测试
    // 计数开始值
    t_start = _itoll(TSCH, TSCL);

    // uPP A 通道启动接收
    uPPDMATransfer(SOC_UPP_0_REGS, uPP_DMA_CHI, &transposeParA);
    // uPP B 通道启动发送
    uPPDMATransfer(SOC_UPP_0_REGS, uPP_DMA_CHQ, &transposeParB);

    Cache_inv((void *)upp_buffer_a, sizeof(upp_buffer_a), Cache_Type_ALLD, TRUE);

    // 等待 uPP 传输完毕
    while (upp_interrupt_count < target_int_count && upp_error_count == 0)
    {

    }

    // 计数结束值
    t_stop = _itoll(TSCH, TSCL);

    sprintf(put_char,"\tuPP Communication Speed: %f MB/s \n",
    (float)upp_frame_size * 2 / 1024 / 1024 * 456000000/((t_stop - t_start) - t_overhead));
    UARTPuts(put_char, -2);

    /* 检查 uPP 传输的数据是否正确 */
    if(upp_interrupt_count == 2 && upp_error_count == 0)
    {
    for(i = 0; i < upp_frame_size; i++)
    {
    if(upp_buffer_a[i] != upp_buffer_b[i])
    {
    upp_error_count++;
    }
    }
    }

    /* 报告通信结果 */
    if(upp_error_count != 0)
    {
    UARTPuts("\tData mismatch in buffers.\n", -2);
    UARTprintf( "\tupp_error_count=%d\n",upp_error_count);
    }
    else
    {
    UARTPuts("\tuPP transfers complete!\n",-2);
    }

    UARTPuts("\tDo you want to print all the data?(y/n)",-2);
    UARTGets(ch,2);
    UARTPuts("\n", -2);

    if(ch[0] == 'y')
    {
    /* 打印全部读到的数据 */
    for(i = 0; i < upp_frame_size; i++)
    {
    UARTprintf("upp_buffer_a[%d] = %d ", i, upp_buffer_a[i]);
    i++;
    if((i % 5) == 0)
    {
    UARTPuts("\n", -2);
    }
    }
    }

    UARTPuts("\r\n\r\n",-2);
    }
    }

    /****************************************************************************/
    /* */
    /* 主函数 */
    /* */
    /****************************************************************************/
    Int main()
    {
    Task_Handle task;
    Error_Block eb;
    Task_Params taskParams;

    // 外设初始化
    PeriphInit();

    // 线程初始化
    ThreadInit();

    /* 初始化串口终端 使用串口2 */
    UARTStdioInit();
    UARTprintf( "\r\n" );
    UARTprintf( "=================================================\r\n" );
    UARTprintf( "=== UPP Communication Demo : Start\r\n" );
    UARTprintf( "=================================================\r\n" );

    // 初始化参数
    Error_init(&eb);
    // 创建主任务
    Task_Params_init(&taskParams);
    taskParams.priority = 8;
    taskParams.stackSize = 8192;

    task = Task_create(taskMain, &taskParams, &eb);
    if (task == NULL)
    {
    System_printf("Task create failed!\n");
    BIOS_exit(0);
    }

    // 使能中断
    Hwi_enable();

    // 启动 SYS/BIOS 系统
    BIOS_start();

    return(0);
    }
  • 请看一下TRM的upp章节,这些寄存器的定义都有详细的说明。
    www.ti.com/.../spruh79c.pdf

    我查了UPP_B_TO_A这个例程不是TI的,是创龙的吧?这个是自环程序,您现在改成单通道是要和外部器件通信了,让您检查上面的中断寄存器是想看一下中断有没有发生,如果没有发生,就要去查FPGA那块有没有给UPP正确的时序;如果发生了,说明FPGA那块没问题,那要检查DSP这块为什么没有响应中断。
  • 你好,之前不进中断是由于dsp与fpga通讯有协议的,我没有启动fpga发送数据,目前第一次是可以进入DMA中断的,但之后就不再进入了