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.

OMAP-L138: 使用UPP与FPGA通信问题

Part Number: OMAP-L138

uPP通道a接收,使用ddr,16bit,但是接收到的数据每次都会丢失从第512位开始的512个数据,FPGA生成8192个数据,仿真以后的波形和ILA显示的波形是一样的,数据传的都是一样的,不知道到底是哪的问题了

#include "OMAPL138.h"
#include "soc_OMAPL138.h"
#include "hw_types.h"
#include "psc.h"
#include "uart.h"
#include "delay.h"
#include "emifa.h"
#include "upp.h"
#include "interrupt.h"
#include "uartStdio.h"
#include "string.h"
#include "stdio.h"

/****************************************************************************/
/*                                                                          */
/*              宏定义                                                      */
/*                                                                          */
/****************************************************************************/
#define upp_line_size        (1024)
#define upp_line_count       (8)
#define upp_frame_size       (upp_line_size * upp_line_count)
#define upp_line_offset      (upp_line_size)

/****************************************************************************/
/*                                                                          */
/*              全局变量                                                    */
/*                                                                          */
/****************************************************************************/
volatile int upp_interrupt_count = 0;//中断标记
volatile int upp_error_count = 0;

//#pragma DATA_SECTION(upp_buffer, "ipc_shram")
#pragma DATA_ALIGN(upp_buffer, 8)
unsigned short upp_buffer[upp_frame_size];

uPPDMAConfig DMAConfig;

/****************************************************************************/
/*                                                                          */
/*              函数声明                                                    */
/*                                                                          */
/****************************************************************************/
static void InterruptInit(void);
static void EMIFAInit(void);
static void uPPInit(void);
static void uPPInterruptInit(void);
static void uPPIsr(void);
static void uPPTransferStart(void);

/****************************************************************************/
/*                                                                          */
/*              主函数                                                      */
/*                                                                          */
/****************************************************************************/

int main(void)
{
    int i, target_int_count = 1;

    // 中断初始化
    InterruptInit();

    // 初始化串口终端 使用串口2
    UARTStdioInit(1);

    // 定时器 初始化
    DelayTimerSetup();

    /* 打印串口终端信息*/
    UARTprintf("uPP Test Application.\r\n");

    // EMIFA 初始化
    EMIFAInit();

    *((short *) (SOC_EMIFA_CS5_ADDR + 2 * 1)) = 0;

    // uPP 初始化
    uPPInit();

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

    while (1)
    {
        // 启动uPP DMA传输
        uPPTransferStart();

        *((short *) (SOC_EMIFA_CS5_ADDR + 2 * 1)) = 1; // 启动数据生成

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

        *((short *) (SOC_EMIFA_CS5_ADDR + 2 * 1)) = 0;

        UARTprintf("uPP transfers...OK\r\n");
//
//        /*检查UPP传输的数据是否正确*/
//        for (i = 0; i < upp_frame_size; i = i + 2)
//        {
//            if (upp_buffer[i] != ((i / 2) + 1))
//            {
//                UARTprintf("Data mismatch in %d\n", i);
//                break;
//            }
//        }
    }
}

/****************************************************************************/
/*                                                                          */
/*                  中断初始化                                              */
/*                                                                          */
/****************************************************************************/
static void InterruptInit(void)
{
    IntAINTCInit();                      // 初始化 ARM 中断控制器
    IntMasterIRQEnable();                // 使能 IRQ(CPSR)
    IntGlobalEnable();                   // 使能中断(AINTC GER)
    IntIRQEnable();                      // 使能中断(AINTC HIER)
}

/****************************************************************************/
/*                                                                          */
/*              初始化 EMIFA                                                */
/*                                                                          */
/****************************************************************************/
static void EMIFAInit(void)
{
    // 使能 EMIFA 模块
    PSCModuleControl(SOC_PSC_0_REGS, HW_PSC_EMIFA, PSC_POWERDOMAIN_ALWAYS_ON,
                     PSC_MDCTL_NEXT_ENABLE);

    // 配置EMIFA相关复用引脚
    EMIFAPinMuxSetup();

    // 配置数据总线16bit
    EMIFAAsyncDevDataBusWidthSelect(SOC_EMIFA_0_REGS, EMIFA_CHIP_SELECT_5,
    EMIFA_DATA_BUSWITTH_16BIT);

    // 选着Normal模式
    EMIFAAsyncDevOpModeSelect(SOC_EMIFA_0_REGS, EMIFA_CHIP_SELECT_5,
    EMIFA_ASYNC_INTERFACE_NORMAL_MODE);

    // 禁止WAIT引脚
    EMIFAExtendedWaitConfig(SOC_EMIFA_0_REGS, EMIFA_CHIP_SELECT_5,
    EMIFA_EXTENDED_WAIT_DISABLE);

    // 配置W_SETUP/R_SETUP   W_STROBE/R_STROBE    W_HOLD/R_HOLD   TA等参数
    EMIFAWaitTimingConfig(SOC_EMIFA_0_REGS, EMIFA_CHIP_SELECT_5, EMIFA_ASYNC_WAITTIME_CONFIG(2, 3, 2, 2, 3, 2, 0));
}

/****************************************************************************/
/*                                                                          */
/*              初始化 uPP                                                  */
/*                                                                          */
/****************************************************************************/
static void uPPInit(void)
{
    // 使能 uPP 模块
    PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_UPP, PSC_POWERDOMAIN_ALWAYS_ON,
                     PSC_MDCTL_NEXT_ENABLE);

    // 配置uPP相关复用引脚
    uPPPinMuxSetup(uPP_CHA_16BIT);

    // uPP复位  软件复位
    uPPReset(SOC_UPP_0_REGS);

    // 数据格式配置   UPCTL,通道,16位,单边沿
    uPPDataFmtConfig(SOC_UPP_0_REGS, uPP_CHA, uPP_DataPackingFmt_LJZE | uPP_DataPacking_FULL |
                     uPP_InterfaceWidth_16BIT | uPP_DataRate_DOUBLE);

    // 通道配置  双边沿失能  单倍数据率交错模式失能  A接收
    uPPChannelConfig(SOC_UPP_0_REGS, uPP_DDRDEMUX_DISABLE | uPP_SDRTXIL_DISABLE |
                     uPP_CHN_ONE | uPP_ALL_RECEIVE);

    // 引脚配置 控制引脚都开启
    uPPPinConfig(SOC_UPP_0_REGS, uPP_CHA, uPP_PIN_ENABLE | uPP_PIN_WAIT | uPP_PIN_START);

    // DMA读脉冲串大小
    uPPThresholdConfig(SOC_UPP_0_REGS, uPP_DMA_CHI, uPP_Threshold_256Bytes);

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

    // 中断映射
    uPPInterruptInit();

    // uPP使能
    uPPEnable(SOC_UPP_0_REGS);

    // DMA通道参数
    DMAConfig.WindowAddress = (unsigned int *) ((int) upp_buffer);
    DMAConfig.LineCount = upp_line_count;
    DMAConfig.ByteCount = (upp_line_size * sizeof(unsigned short));
    DMAConfig.LineOffsetAddress = (upp_line_offset * sizeof(unsigned short));

    // 初始化接收区域
    memset(upp_buffer, 0x3F, upp_frame_size * sizeof(unsigned short));
}

/****************************************************************************/
/*                                                                          */
/*              uPP 中断初始化                                              */
/*                                                                          */
/****************************************************************************/
static void uPPInterruptInit(void)
{
    IntRegister(SYS_INT_UPP, uPPIsr);   // 注册中断服务函数
    IntChannelSet(SYS_INT_UPP, 8);   // 映射中断
    IntSystemEnable(SYS_INT_UPP);   // 使能中断
}

/****************************************************************************/
/*                                                                          */
/*              uPP 中断服务函数                                            */
/*                                                                          */
/****************************************************************************/
static void uPPIsr(void)
{
    unsigned int intr_dmai_status = 0;

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

    while(intr_dmai_status != 0)
    {
        // 清除 uPP 系统中断
#ifdef _TMS320C6X
        IntEventClear(SYS_INT_UPP_INT);
#else
        IntSystemStatusClear(SYS_INT_UPP);
#endif
        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++;
        }

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

    // 通知 CPU uPP 中断处理完毕以便后续事件可以产生
    uPPEndOfInt(SOC_UPP_0_REGS);
}



/****************************************************************************/
/*                                                                          */
/*              uPP DMA参数                                                 */
/*                                                                          */
/****************************************************************************/
static void uPPTransferStart(void)
{
    // uPP中断标志位清零
    upp_interrupt_count = 0;
    upp_error_count = 0;

    // uPP 通道启动接收
    uPPDMATransfer(SOC_UPP_0_REGS, uPP_DMA_CHI, &DMAConfig);
}