xilinx PL测 DP 点屏 /接收(二)--RX

news/2024/5/4 23:31:06/文章来源:https://blog.csdn.net/weixin_36590806/article/details/128011413

环境:

a)硬件:官方ZCU106开发板 , tb-fmch-vfmc-dp子卡。

b)软件:vivado2021.1,vitis2021.1,裸机程序。

1、官方例程:

 

2、DP RX IP :

 

 

 

3、DP RX寄存器:

 

 

 

 

 

4、时钟:

 

5、像素:

Stream模式:

native模式:

 

6、timming:注意de非连续,每帧hsync个数和h_active一致。

 

 

7、vitis代码分析:

a)、iic使用ps测,和官方例程不一样,所以在MCDP6000这个文件夹定义iic:

PS侧iic初始化代码:iIc速率:100K

void ps_iic_init()

{

int Status;

XIicPs_Config *Config;

/*     * Initialize the IIC driver so that it's ready to use

 * Look up the configuration in the config table,

 * then initialize it.     */

Config = XIicPs_LookupConfig(XPAR_XIICPS_1_DEVICE_ID);

if (NULL == Config) {

printf("XIicPs_LookupConfig Failed\r\n");

return XST_FAILURE;

}

Status = XIicPs_CfgInitialize(&Iic, Config, Config->BaseAddress);

if (Status != XST_SUCCESS) {

printf("XIicPs_CfgInitialize Failed\r\n");

return XST_FAILURE;

}

/*     * Perform a self-test to ensure that the hardware was built correctly.     */

Status = XIicPs_SelfTest(&Iic);

if (Status != XST_SUCCESS) {

printf("XIicPs_SelfTest Failed\r\n");

return XST_FAILURE;

}

/*     * Set the IIC serial clock rate.     */

XIicPs_SetSClk(&Iic, 100000);

}

 

DP RX的初始化:

u32 Dprx_init(void)

{

u32 Status;

XDpRxSs_Config *ConfigPtr_rx;

xil_printf("config dp rx \n\r");

ConfigPtr_rx = XDpRxSs_LookupConfig(XDPRXSS_DEVICE_ID);

if (!ConfigPtr_rx) {

xil_printf("DPRXSS Lookup Config failed.\n\r");

return XST_FAILURE;

}

Status = XDpRxSs_CfgInitialize(&DpRxSsInst, ConfigPtr_rx,ConfigPtr_rx->BaseAddress);

if (Status != XST_SUCCESS) {

xil_printf("DPRXSS config initialization failed.\n\r");

return XST_FAILURE;

}

/* Check for SST/MST support */

if (DpRxSsInst.UsrOpt.MstSupport) {

xil_printf("INFO:DPRXSS is MST enabled. DPRXSS can be "    "switched to SST/MST\n\r");

} else {

xil_printf("INFO:DPRXSS is SST enabled. DPRXSS works "    "only in SST mode.\n\r");

}

xil_printf("Dprx_init   end .\n\r");

return XST_SUCCESS;

}

 

中断初始化:这里RX,TX都有包含

u32 DpSs_SetupIntrSystem(void)

{

u32 Status;

XINTC *IntcInstPtr = &IntcInst;

// Tx side

DpTxSs_SetupIntrSystem();

// Rx side

#ifdef DP_RX_EN

DpRxSs_SetupIntrSystem();

#endif

/* The configuration parameters of the interrupt controller */

XScuGic_Config *IntcConfig;

/* Initialize the interrupt controller

 * driver so that it is ready to use. */

IntcConfig = XScuGic_LookupConfig(XINTC_DEVICE_ID);

if (NULL == IntcConfig) {

xil_printf("XINTC_DEVICE_ID XScuGic_LookupConfig failed!\n\r");

return XST_FAILURE;

}

Status = XScuGic_CfgInitialize(IntcInstPtr, IntcConfig,    IntcConfig->CpuBaseAddress);

if (Status != XST_SUCCESS) {

xil_printf("XINTC_DEVICE_ID XScuGic_CfgInitialize failed!\n\r");

return XST_FAILURE;

}

/* Connect the device driver handler that will be called when an

 * interrupt for the device occurs, the handler defined

 * above performs the specific interrupt processing for the device.

 * */

#ifdef DP_RX_EN

Status = XScuGic_Connect(IntcInstPtr, XINTC_DPRXSS_DP_INTERRUPT_ID,    (Xil_InterruptHandler)XDpRxSs_DpIntrHandler,&DpRxSsInst);

if (Status != XST_SUCCESS) {

xil_printf("ERR: DP RX SS DP interrupt connect failed!\n\r");

return XST_FAILURE;

}

/* Enable the interrupt for the DP device */

XScuGic_Enable(IntcInstPtr, XINTC_DPRXSS_DP_INTERRUPT_ID);

#endif

/* Connect the device driver handler that will be called when an

 * interrupt for the device occurs, the handler defined above performs

 * the specific interrupt processing for the device

 */

Status = XScuGic_Connect(IntcInstPtr, XINTC_DPTXSS_DP_INTERRUPT_ID,    (Xil_InterruptHandler)XDpTxSs_DpIntrHandler,&DpTxSsInst);

if (Status != XST_SUCCESS) {

xil_printf("ERR: DP TX SS DP interrupt connect failed!\r\n");

return XST_FAILURE;

}

/* Enable the interrupt */

XScuGic_Enable(IntcInstPtr, XINTC_DPTXSS_DP_INTERRUPT_ID);

/* Initialize the exception table. */

Xil_ExceptionInit();

/* Register the interrupt controller handler with the exception

 * table.*/

Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)XINTC_HANDLER,IntcInstPtr);

/* Enable exceptions. */

Xil_ExceptionEnable();

return (XST_SUCCESS);

}

 

 

DP RX的中断申请:

u32 DpRxSs_SetupIntrSystem(void)

{

//    u32 Status;

//    XINTC *IntcInstPtr = &IntcInst;

/* Set callbacks for all the interrupts */

XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_DP_PWR_CHG_EVENT,            &DpRxSs_PowerChangeHandler, &DpRxSsInst);//2

XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_DP_NO_VID_EVENT,            &DpRxSs_NoVideoHandler, &DpRxSsInst);    //3

// XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_DP_VM_CHG_EVENT,            &DpRxSs_VmChangeHandler, &DpRxSsInst);

XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_DP_VBLANK_EVENT,                &DpRxSs_VerticalBlankHandler, &DpRxSsInst);//4

XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_DP_TLOST_EVENT,            &DpRxSs_TrainingLostHandler, &DpRxSsInst);//5

XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_DP_VID_EVENT,                &DpRxSs_VideoHandler, &DpRxSsInst);        //6

XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_DP_TDONE_EVENT,            &DpRxSs_TrainingDoneHandler, &DpRxSsInst);//9

XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_UNPLUG_EVENT,                &DpRxSs_UnplugHandler, &DpRxSsInst);    //17

XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_LINKBW_EVENT,                &DpRxSs_LinkBandwidthHandler, &DpRxSsInst);//18

XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_PLL_RESET_EVENT,            &DpRxSs_PllResetHandler, &DpRxSsInst);    //19

XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_DP_BW_CHG_EVENT,            &DpRxSs_BWChangeHandler, &DpRxSsInst);    //10

// XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_ACCESS_LINK_QUAL_EVENT,    &DpRxSs_AccessLinkQualHandler, &DpRxSsInst);

// XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_ACCESS_ERROR_COUNTER_EVENT,&DpRxSs_AccessErrorCounterHandler, &DpRxSsInst);

// XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_DP_CRC_TEST_EVENT,            &DpRxSs_CRCTestEventHandler, &DpRxSsInst);

// XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_DP_INFO_PKT_EVENT,            &DpRxSs_InfoPacketHandler, &DpRxSsInst);

// XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_DP_EXT_PKT_EVENT,            &DpRxSs_ExtPacketHandler, &DpRxSsInst);

/* Set custom timer wait */

XDpRxSs_SetUserTimerHandler(&DpRxSsInst, &CustomWaitUs, &TmrCtr);

return (XST_SUCCESS);

}

 

 

 

PHY的初始化:

u32 DpSs_PhyInit(u16 DeviceId)

{

XVphy_Config *ConfigPtr;

u32 Status;

/* Obtain the device configuration for the DisplayPort RX Subsystem */

ConfigPtr = XVphy_LookupConfig(DeviceId);

if (!ConfigPtr) {

return XST_FAILURE;

}

XVphy_DpInitialize(&VPhyInst, ConfigPtr, 0,

ONBOARD_REF_CLK,

ONBOARD_REF_CLK,

XVPHY_PLL_TYPE_QPLL1,

XVPHY_PLL_TYPE_CPLL,

DP_LINK_RATE);

//set the default vswing and pe for v0po

PLLRefClkSel (&VPhyInst, DP_LINK_RATE);

#if 1

    //setting vswing

    XVphy_SetTxVoltageSwing(&VPhyInst, 0, XVPHY_CHANNEL_ID_CH1,    XVPHY_GTHE4_DIFF_SWING_DP_V0P0);

    XVphy_SetTxVoltageSwing(&VPhyInst, 0, XVPHY_CHANNEL_ID_CH2,    XVPHY_GTHE4_DIFF_SWING_DP_V0P0);

    XVphy_SetTxVoltageSwing(&VPhyInst, 0, XVPHY_CHANNEL_ID_CH3,    XVPHY_GTHE4_DIFF_SWING_DP_V0P0);

    XVphy_SetTxVoltageSwing(&VPhyInst, 0, XVPHY_CHANNEL_ID_CH4,    XVPHY_GTHE4_DIFF_SWING_DP_V0P0);

    //setting postcursor

    XVphy_SetTxPostCursor(&VPhyInst, 0, XVPHY_CHANNEL_ID_CH1,    XVPHY_GTHE4_PREEMP_DP_L0);

    XVphy_SetTxPostCursor(&VPhyInst, 0, XVPHY_CHANNEL_ID_CH2,    XVPHY_GTHE4_PREEMP_DP_L0);

    XVphy_SetTxPostCursor(&VPhyInst, 0, XVPHY_CHANNEL_ID_CH3,    XVPHY_GTHE4_PREEMP_DP_L0);

    XVphy_SetTxPostCursor(&VPhyInst, 0, XVPHY_CHANNEL_ID_CH4,    XVPHY_GTHE4_PREEMP_DP_L0);

#endif

PHY_Two_byte_set (&VPhyInst, SET_RX_TO_2BYTE, SET_TX_TO_2BYTE);//SET_TX_TO_2BYTE

XVphy_ResetGtPll(&VPhyInst, 0, XVPHY_CHANNEL_ID_CHA, XVPHY_DIR_TX,(TRUE));

XVphy_BufgGtReset(&VPhyInst, XVPHY_DIR_TX,(TRUE));

XVphy_ResetGtPll(&VPhyInst, 0, XVPHY_CHANNEL_ID_CHA, XVPHY_DIR_TX,(FALSE));

XVphy_BufgGtReset(&VPhyInst, XVPHY_DIR_TX,(FALSE));

XVphy_ResetGtPll(&VPhyInst, 0, XVPHY_CHANNEL_ID_CHA, XVPHY_DIR_RX,(TRUE));

XVphy_BufgGtReset(&VPhyInst, XVPHY_DIR_RX,(TRUE));

XVphy_ResetGtPll(&VPhyInst, 0, XVPHY_CHANNEL_ID_CHA, XVPHY_DIR_RX,(FALSE));

XVphy_BufgGtReset(&VPhyInst, XVPHY_DIR_RX,(FALSE));

xil_printf("DpSs_PhyInit   end .\n\r");

Status = XVphy_ReadReg(XVPHY_BASEADDR, XVPHY_RX_INIT_STATUS_REG);

xil_printf("\n   DpSs_PhyInit  rx initialization Status 0x28 data = %x \n\r",Status);

    Status = XVphy_ReadReg(XVPHY_BASEADDR, XVPHY_PLL_LOCK_STATUS_REG);

    xil_printf("\n   DpSs_PhyInit  rx initialization Status 0x18 data = %x \n\r",Status);

return XST_SUCCESS;       

}

 

 

PHY的速率设置:

u32 config_phy(int LineRate_init_tx){

u32 Status=0;

//    u8 linerate;

//    u32 dptx_sts = 0;

switch(LineRate_init_tx){

case XDP_LINK_BW_SET_162GBPS:

Status = PHY_Configuration(&VPhyInst,PHY_User_Config_Table[(is_TX_CPLL) ? 0 : 3]);

break;

case XDP_LINK_BW_SET_270GBPS:

Status = PHY_Configuration(&VPhyInst,PHY_User_Config_Table[(is_TX_CPLL) ? 1 : 4]);

break;

case XDP_LINK_BW_SET_540GBPS:

Status = PHY_Configuration(&VPhyInst,PHY_User_Config_Table[(is_TX_CPLL) ? 2 : 5]);

break;

case XDP_LINK_BW_SET_810GBPS:

Status = PHY_Configuration(&VPhyInst,PHY_User_Config_Table[(is_TX_CPLL) ? 9 : 10]);

break;

}

xil_printf ("config_phy LineRate_init_tx = %x \r\n",LineRate_init_tx);

if (Status != XST_SUCCESS) {

xil_printf ("++++++++++ TX GT configuration encountered a failure +++++++\r\n");

}

return Status;

}

u32 PHY_Configuration(XVphy *InstancePtr,XVphy_User_Config PHY_User_Config_Table)

{

XVphy_PllRefClkSelType QpllRefClkSel;

XVphy_PllRefClkSelType CpllRefClkSel;

XVphy_PllType TxPllSelect;

XVphy_PllType RxPllSelect;

XVphy_ChannelId TxChId;

XVphy_ChannelId RxChId;

u8 QuadId = 0;

u32 Status = XST_FAILURE;

u32 retries = 0;

QpllRefClkSel   = PHY_User_Config_Table.QPLLRefClkSrc;

CpllRefClkSel   = PHY_User_Config_Table.CPLLRefClkSrc;

TxPllSelect     = PHY_User_Config_Table.TxPLL;

RxPllSelect     = PHY_User_Config_Table.RxPLL;

TxChId          = PHY_User_Config_Table.TxChId;

RxChId          = PHY_User_Config_Table.RxChId;

//Set the Ref Clock Frequency

XVphy_CfgQuadRefClkFreq(InstancePtr, QuadId, QpllRefClkSel,    PHY_User_Config_Table.QPLLRefClkFreqHz);

XVphy_CfgQuadRefClkFreq(InstancePtr, QuadId, CpllRefClkSel,    PHY_User_Config_Table.CPLLRefClkFreqHz);

XVphy_CfgLineRate(InstancePtr, QuadId, TxChId,    PHY_User_Config_Table.LineRateHz);

//    XVphy_CfgLineRate(InstancePtr, QuadId, RxChId,    PHY_User_Config_Table.LineRateHz);

// Initialize GT with ref clock and PLL selects

XVphy_PllInitialize(InstancePtr, QuadId, TxChId,QpllRefClkSel, CpllRefClkSel,TxPllSelect, RxPllSelect);

while (Status != XST_SUCCESS) {

Status = XVphy_ClkInitialize(InstancePtr, QuadId,   TxChId, XVPHY_DIR_TX);

if (retries > 100) {

retries = 0;

xil_printf ("exhausted\r\n");

break;

}

retries++;

}

// Initialize GT with ref clock and PLL selects

Status = XVphy_ClkInitialize(InstancePtr, QuadId, RxChId, XVPHY_DIR_RX);

XVphy_WriteReg(InstancePtr->Config.BaseAddr,XVPHY_PLL_RESET_REG,(XVPHY_PLL_RESET_CPLL_MASK | XVPHY_PLL_RESET_QPLL1_MASK)); // 0x06

XVphy_WriteReg(InstancePtr->Config.BaseAddr,XVPHY_PLL_RESET_REG, 0x0);

//    XVphy_ResetGtPll(InstancePtr, QuadId, RxChId, XVPHY_DIR_RX,(TRUE));

//    XVphy_ResetGtPll(InstancePtr, QuadId, RxChId, XVPHY_DIR_RX,(FALSE));

XVphy_ResetGtPll(InstancePtr, QuadId,XVPHY_CHANNEL_ID_CHA, XVPHY_DIR_TX,(FALSE));

//    Status =  XVphy_WaitForResetDone(&VPhyInst, 0, XVPHY_CHANNEL_ID_CHA, XVPHY_DIR_RX);

//    xil_printf("\n   step_phy  XVphy_WaitForResetDone Status = %x \n\r",Status);

//    Status = XVphy_WaitForPllLock(&VPhyInst, 0, XVPHY_CHANNEL_ID_CHA);

//    xil_printf("\n   step_phy  XVphy_WaitForPllLock Status = %x \n\r",Status);

Status = XVphy_WaitForPmaResetDone(InstancePtr, QuadId,    TxChId, XVPHY_DIR_TX);

Status += XVphy_WaitForPllLock(InstancePtr, QuadId, TxChId);

Status += XVphy_WaitForResetDone(InstancePtr, QuadId,TxChId, XVPHY_DIR_TX);

if (Status  != XST_SUCCESS) {

xil_printf ("++++TX GT config encountered error++++\r\n");

}

return Status;

}

 

 

DP RX速率,lane的数目设置:

u32 DPRx_step(void)

{

u32 Status;

u32 tmp_rd;

    /* Set Link rate and lane count to maximum */

    XDpRxSs_SetLinkRate(&DpRxSsInst, DP_LINK_RATE);

    XDpRxSs_SetLaneCount(&DpRxSsInst, DP_LANE_COUNT);

    /* Start DPRX Subsystem set */

    Status = XDpRxSs_Start(&DpRxSsInst);

    if (Status != XST_SUCCESS) {

        xil_printf("ERR:DPRX SS start failed\n\r");

        return XST_FAILURE;

    }

    xil_printf("\r\n  DPRx_step  done.\n\r");

    tmp_rd = XDp_ReadReg(DpRxSsInst.DpPtr->Config.BaseAddr, 0x4);

    tmp_rd |= tmp_rd | 0x06000000;

    XDp_WriteReg(DpRxSsInst.DpPtr->Config.BaseAddr, 0x4, tmp_rd);

    return (XST_SUCCESS);

}

 

DP RX 的开始training函数:

u32 DpRxSs_Setup(void)

{

    u32 ReadVal;

    u32 Status;

    /*Disable Rx*/

    XDp_WriteReg(DpRxSsInst.DpPtr->Config.BaseAddr, XDP_RX_LINK_ENABLE, 0x0);//hpd 拉低

    /*Setting BS Idle timeout value to long value*/

    XDp_WriteReg(DpRxSsInst.DpPtr->Config.BaseAddr,   XDP_RX_BS_IDLE_TIME, 0x047868C0);//这个参数,在某些应用上要适当的更改。

    /* Load Custom EDID */

    LoadEDID();

//    XDp_WriteReg(DpRxSsInst.DpPtr->Config.BaseAddr,    XDP_RX_INTERRUPT_MASK, 0xFFF87FFD);

    /*Disable All Interrupts*/

 //   XDp_RxInterruptDisable(DpRxSsInst.DpPtr, 0xFFFFFFFF);

    xil_printf("RX Link & Lane Capability is set to %x, %x\r\n",

                (XDp_ReadReg(DpRxSsInst.DpPtr->Config.BaseAddr ,XDP_RX_DPCD_LINK_BW_SET)),

                (XDp_ReadReg(DpRxSsInst.DpPtr->Config.BaseAddr,    XDP_RX_DPCD_LANE_COUNT_SET)));

    /*Enable Training related interrupts*/

   XDp_RxInterruptEnable(DpRxSsInst.DpPtr,

            XDP_RX_INTERRUPT_MASK_TP1_MASK|XDP_RX_INTERRUPT_MASK_TP2_MASK|

            XDP_RX_INTERRUPT_MASK_TP3_MASK|

            XDP_RX_INTERRUPT_MASK_POWER_STATE_MASK|

            XDP_RX_INTERRUPT_MASK_BW_CHANGE_MASK);

    /* Setting AUX Defer Count of Link Status Reads to 8 during Link Training

     * 8 Defer counts is chosen to handle worst case time interrupt service

     * load (PL system working at 100 MHz) when working with R5

     * */

    ReadVal = XDp_ReadReg(DpRxSsInst.DpPtr->Config.BaseAddr,XDP_RX_AUX_CLK_DIVIDER);

    ReadVal |= ReadVal | (AUX_DEFER_COUNT<<24);

    XDp_WriteReg(DpRxSsInst.DpPtr->Config.BaseAddr,    XDP_RX_AUX_CLK_DIVIDER, ReadVal);

//-------------------------------------------------------------------------------------------------------------------

    Status =  XVphy_WaitForResetDone(&VPhyInst, 0, XVPHY_CHANNEL_ID_CHA, XVPHY_DIR_RX);

    Status = XVphy_WaitForPllLock(&VPhyInst, 0, XVPHY_CHANNEL_ID_CHA);

    xil_printf("\n   step_dp_rx  XVphy_WaitForPllLock Status = %x \n\r",Status);

    xil_printf("\r\n addr =%x XDP_RX_PHY_STATUS = %x \r\n",XDP_RX_PHY_STATUS,XDp_ReadReg(XDPRXSS_BASEADDR, XDP_RX_PHY_STATUS));

    XScuGic_Enable(&IntcInst, XINTC_DPRXSS_DP_INTERRUPT_ID);

//resetting AUX logic. Needed for some Type C based connectors

XDp_WriteReg(DpRxSsInst.DpPtr->Config.BaseAddr, 0x1C, 0x80);

XDp_WriteReg(DpRxSsInst.DpPtr->Config.BaseAddr, 0x1C, 0x0);

  //********************************************

    if(LINK_TRAINING_DEBUG)

    {

        /*Updating Vswing Iteration Count*/

        RxTrainConfig.ChEqOption = 1;

        RxTrainConfig.ClockRecoveryOption = 2;

        RxTrainConfig.Itr1Premp = 0;

        RxTrainConfig.Itr2Premp = 0;

        RxTrainConfig.Itr3Premp = 0;

        RxTrainConfig.Itr4Premp = 0;

        RxTrainConfig.Itr5Premp = 0;

        RxTrainConfig.MinVoltageSwing = 1;

        RxTrainConfig.SetPreemp = 1;

        RxTrainConfig.SetVswing = 0;

        RxTrainConfig.VswingLoopCount = 3;

        XDp_WriteReg(DpRxSsInst.DpPtr->Config.BaseAddr,    XDP_RX_MIN_VOLTAGE_SWING,

                RxTrainConfig.MinVoltageSwing |

                (RxTrainConfig.ClockRecoveryOption << 2) |

                (RxTrainConfig.VswingLoopCount << 4) |

                (RxTrainConfig.SetVswing << 8) |

                (RxTrainConfig.ChEqOption << 10) |

                (RxTrainConfig.SetPreemp << 12) |

                (RxTrainConfig.Itr1Premp << 14) |

                (RxTrainConfig.Itr2Premp << 16) |

                (RxTrainConfig.Itr3Premp << 18) |

                (RxTrainConfig.Itr4Premp << 20) |

                (RxTrainConfig.Itr5Premp << 22)

                );

    }

    XDp_WriteReg(DpRxSsInst.DpPtr->Config.BaseAddr, XDP_RX_LINK_ENABLE, 0x1);//此时HPD会拉高,开始training

    xil_printf("\r\n  DpRxSs_Setup  done.\n\r");

    return XST_SUCCESS;

}

DP RX中断说明:

void DpRxSs_VerticalBlankHandler(void *InstancePtr)    //检测到v_blank,当检测到200个就表示接收到视频

{

//    xil_printf("\r\n   4     \r\n");

DpRxSsInst.VBlankCount++;

dp_rx_ok =0;

video_cnt =0;

if(DpRxSsInst.VBlankCount==200){

XDp_RxInterruptDisable(DpRxSsInst.DpPtr,        XDP_RX_INTERRUPT_MASK_VBLANK_MASK);

DpRxSsInst.VBlankCount=0;

XDp_RxDtgDis(DpRxSsInst.DpPtr);

XDp_RxDtgEn(DpRxSsInst.DpPtr);

XDp_RxSetLineReset(DpRxSsInst.DpPtr,1);

XDp_RxSetUserPixelWidth(DpRxSsInst.DpPtr,0x04);

xil_printf("\r\n   4   VBlankCount=200  \r\n");

video_flag = 1;

}

else if(DpRxSsInst.VBlankCount==80)

{

video_flag =0;

xil_printf("\r\n   4  VBlankCount= 80    \r\n");

}

else if(DpRxSsInst.VBlankCount==20)

{

video_flag =0;

xil_printf("\r\n   4  VBlankCount= 20    \r\n");

XDp_RxInterruptEnable(DpRxSsInst.DpPtr,0x80000000);

}

}

 

void DpRxSs_TrainingLostHandler(void *InstancePtr)

{

xil_printf("\r\n   5     \r\n");

XDp_RxGenerateHpdInterrupt(DpRxSsInst.DpPtr, 750);

XDpRxSs_AudioDisable(&DpRxSsInst);

sink_power_down(); // close dp tx

vdma_stop(); // close vdma write

video_flag =0;

dp_rx_ok=0;

dp_rx_lost=1;

}

void DpRxSs_VideoHandler(void *InstancePtr)   //此中断,在检测到不同的msa会进入此中断,如果一直在进入此中断,表示training ok,但是msa的数据异常,且在变化

{

xil_printf("\r\n   6     \r\n");

video_cnt++;

if((video_cnt==1)|(video_cnt==2))

dp_rx_ok = 1;

else

dp_rx_ok =0;

if(video_cnt==8)

{

//    XDp_RxGenerateHpdInterrupt(DpRxSsInst.DpPtr, 750);

XDp_WriteReg(DpRxSsInst.DpPtr->Config.BaseAddr, XDP_RX_LINK_ENABLE, 0x0);

usleep(250000);

XDp_WriteReg(DpRxSsInst.DpPtr->Config.BaseAddr, XDP_RX_LINK_ENABLE, 0x1);

}

if(0)//video_flag

{

xil_printf("\r\n   6     \r\n");

dp_rx_ok =1;

}

}

void DpRxSs_UnplugHandler(void *InstancePtr)

{

xil_printf("\r\n   17     \r\n");

video_flag =0;

/*Enable Training related interrupts*/

XDp_RxInterruptDisable(DpRxSsInst.DpPtr,  XDP_RX_INTERRUPT_MASK_ALL_MASK);

//    XDp_WriteReg(DpRxSsInst.DpPtr->Config.BaseAddr, XDP_RX_LINK_ENABLE, 0x0);

XDp_RxInterruptEnable(DpRxSsInst.DpPtr,

      XDP_RX_INTERRUPT_MASK_TP1_MASK |

      XDP_RX_INTERRUPT_MASK_TP2_MASK |

XDP_RX_INTERRUPT_MASK_TP3_MASK|

XDP_RX_INTERRUPT_MASK_POWER_STATE_MASK|

XDP_RX_INTERRUPT_MASK_CRC_TEST_MASK|

XDP_RX_INTERRUPT_MASK_BW_CHANGE_MASK);

XDp_RxGenerateHpdInterrupt(DpRxSsInst.DpPtr, 5000);

}

void DpRxSs_LinkBandwidthHandler(void *InstancePtr)    // 根据 tx发送的 速率,进行更改phy的速率

{

u32 Status;

//    xil_printf("\r\n   18     \r\n");

/*Program Video PHY to requested line rate*/

PLLRefClkSel (&VPhyInst, DpRxSsInst.UsrOpt.LinkRate);

XVphy_ResetGtPll(&VPhyInst, 0, XVPHY_CHANNEL_ID_CHA,XVPHY_DIR_RX,(TRUE));

XVphy_PllInitialize(&VPhyInst, 0, XVPHY_CHANNEL_ID_CHA,    ONBOARD_REF_CLK, ONBOARD_REF_CLK,XVPHY_PLL_TYPE_QPLL1, XVPHY_PLL_TYPE_CPLL);

Status = XVphy_ClkInitialize(&VPhyInst, 0,    XVPHY_CHANNEL_ID_CHA, XVPHY_DIR_RX);

if(Status != XST_SUCCESS)

xil_printf("XVphy_ClkInitialize failed\r\n");

}

 

void DpRxSs_PllResetHandler(void *InstancePtr)    //phy的速率更改后,重新复位。

{

//    xil_printf("\r\n   19     \r\n");

//    u32 ReadVal;

/* Issue resets to Video PHY - This API

 * called after line rate is programmed */

XVphy_BufgGtReset(&VPhyInst, XVPHY_DIR_RX,(TRUE));

XVphy_ResetGtPll(&VPhyInst, 0, XVPHY_CHANNEL_ID_CHA,         XVPHY_DIR_RX,(TRUE));

XVphy_ResetGtPll(&VPhyInst, 0, XVPHY_CHANNEL_ID_CHA,         XVPHY_DIR_RX, (FALSE));

XVphy_BufgGtReset(&VPhyInst, XVPHY_DIR_RX,(FALSE));

XVphy_WaitForResetDone(&VPhyInst, 0, XVPHY_CHANNEL_ID_CHA,      XVPHY_DIR_RX);

XVphy_WaitForPllLock(&VPhyInst, 0, XVPHY_CHANNEL_ID_CHA);

/*Enable all interrupts */

XDp_RxInterruptEnable(DpRxSsInst.DpPtr,   XDP_RX_INTERRUPT_MASK_ALL_MASK);

}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_224802.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

高通导航器软件开发包使用指南(9)

高通导航器软件开发包使用指南&#xff08;9&#xff09;8参数说明8.1最小条件参数8.2光学流量数据图8.3光学流量估算数据图8.4光学流量估算图8.5 pos_hold_mode内存8.6体积参数8.7障碍物输出参数8.8速度平滑曲线8参数说明 每辆车必须在适当的位置有运行时参数文件&#xff0c…

MCE | LYTAC 与靶向蛋白降解技术

靶向蛋白降解 (TPD) 是一种有效性的&#xff0c;高度选择性的诱发蛋白降解方式。近年来&#xff0c;以 PROTAC 为代表的 TPD 技术的研究如火如荼。PROTAC 主要降解的是胞内蛋白&#xff0c;实际上&#xff0c;有 40% 的基因产物为胞外和膜相关蛋白&#xff0c;如生长因子、细胞…

Java面向对象三大基本特征之多态

多态性是面向对象编程的又一个重要特征&#xff0c;那么多态是什么呢&#xff1f; 一、多态的概念 1.概念&#xff1a;多态是指在父类中定义的属性和方法被子类继承之后&#xff0c;可以具有不同的数据类型或表现出不同的行为&#xff0c;这使得同一个属性或方法在父类及其各…

数商云采购协同系统邀请招标实施步骤 | 助力建筑工程企业采购工作降本增效

建筑工程行业作为拉动我国工业发展与国民经济发展的重要支柱产业之一&#xff0c;目前已进入稳定发展阶段。在新基建热潮下&#xff0c;建筑工程行业加速向自动化、智能化方向发展&#xff0c;如何借助数字化技术提升管理水平&#xff0c;实现新价值增长&#xff0c;成为行业企…

220kV降压变电所电气部分初步设计33号

目录 1 绪论 5 &#xff11;.&#xff11; 概述 5 &#xff11;.&#xff12; 本次设计内容 5 &#xff11;.&#xff13; 本次设计任务 5 2 变电站总体分析 6 2.&#xff11;变电所总体分析 6 2.2主变压器选择 7 3 电气主接线选择 10 3.1 电气主接线的概念 10 3.2 电气主接…

【零基础入门SpringMVC】第一期——开篇导论

一、导论 $ 什么是MVC&#xff1f; MVC 是一种将软件按照 模型、视图、控制器来划分的一种架构思维MVC全称SpringWebMVC&#xff0c;那么M、V、C分别代表什么呢&#xff1f; M&#xff1a;Model 代表模型层&#xff0c;作用就是处理数据&#xff0c;在我们SpringMVC中&#x…

python自学入门(打卡十)2022-11-22

Pytest与Unittest区别 参考资料&#xff1a;https://blog.csdn.net/qq_33385691/article/details/112004487 pytest用例规则 文件名以test_.py文件和test.py 以test_开头的函数 以Test开头的类&#xff0c;test_开头的方法&#xff0c;并且不能带有__init_ 方法 所有的包pake…

​LabVIEW从另一个VI或通过VI服务器访问正在运行的可执行文件

​LabVIEW从另一个VI或通过VI服务器访问正在运行的可执行文件 有没有办法从另一个VI或可执行文件访问正在运行的LabVIEW可执行文件。例如&#xff0c;从显示控件获取值&#xff0c;为控件设置值&#xff0c;以及初始化运行LabVIEW可执行文件VI的前面板。 在正在运行的可执行文…

11.23二叉树

目录 一.笔试强训习题订正 1.选择题 2.编程题-组队竞赛 3.删除公共字符 解法1 哈希映射思想 解法2 暴力解法 解法3 substring解法replaceAll() 二.二叉树相关Oj题 1.二叉树的遍历 2.二叉树分层遍历 三.二叉树的最近公共祖先 1.思路一 2.思路2 四.将二叉搜索树转化…

web网页大作业——基于HTML+CSS+JavaScript制作摄影之家网站

&#x1f389;精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

java项目测试成功后部署到服务器上的相关问题

1.java项目是如何部署给用户使用的? 前提&#xff1a; 以一个web项目为例&#xff0c; 使用工具&#xff1a;开发工具&#xff1a;IDEA&#xff1b;Tomcat&#xff08;应用服务器&#xff09;&#xff1b;Navicat&#xff08;数据库&#xff09;&#xff1b;Jenkins&#xff…

鲲鹏devkit编译调试工具——《sudoku》作业解析

《sudoku》作业解析 本次实验以sudoku项目为例介绍鲲鹏编译调试插件的基本使用方法 本次实验的步骤主要为 获取源码安装鲲鹏编译调试插件服务器配置进行代码同步配置配置测试任务进行编译调试 接下来我们先获取本次实验所需要的源码 获取源码 sudoku项目已经上传到github使…

CVPR‘15 Joint action recognition and pose estimation from video

任务&#xff1a;action recognition and pose estimation 思路&#xff1a;对动作和姿态进行统一建模&#xff0c;将动作分成姿态&#xff0c;再将姿态分成part&#xff0c;学习三种level特征&#xff0c;通过动态规划有效的推断动作标签和姿态。 方法&#xff1a;统一建模…

鼠标经过图片在边框内放大动效

鼠标没有经过&#xff1a; 鼠标经过的时候&#xff0c;看图&#xff0c;应该可以看出变化吧&#xff01;图有放大的效果。 样式&#xff1a;图片由一个盒子包着&#xff0c;盒子加上overflow:hidden的样式&#xff0c;即可以保证图片在边框内放大。 然后给图片加上动画效果就可…

Vue常用知识点汇总

1. Vue常见的指令有哪些&#xff0c;有什么用 &#xff08;1&#xff09;v-text&#xff1a; 会替换掉元素里的内容&#xff1b; &#xff08;2&#xff09;v-html&#xff1a; 可以渲染html界面&#xff1b; &#xff08;3&#xff09;v-clock&#xff1a; 防止界面闪烁&…

JavaScript开发工具WebStorm入门教程:开始运行WebStorm(一)

WebStorm是一个JavaScript开发工具&#xff0c;用于JavaScript及其相关技术编码&#xff0c;包括TypeScript、React、Vue、Angular、Node.js、HTML和样式表。就像IntelliJ IDEA和其他JetBrains ide一样&#xff0c;WebStorm让您的开发体验更愉快&#xff0c;自动化日常工作&…

7种主流数据分析软件比较及经典教材推荐

前言 STATA 软件优点&#xff1a;Stata以其简单易懂和功能强大受到初学者和高级用户的普遍欢迎。使用时可以每次只输入一个命令&#xff0c;也可以通过一个Stata程序一次输入多个命令。这样的话即使发生错误&#xff0c;也较容易找出并加以修改。尽管Stata的数据管理能力没有…

用DIV+CSS技术设计我的家乡网站(web前端网页制作课作业)南宁绿城之都

家乡旅游景点网页作业制作 网页代码运用了DIV盒子的使用方法&#xff0c;如盒子的嵌套、浮动、margin、border、background等属性的使用&#xff0c;外部大盒子设定居中&#xff0c;内部左中右布局&#xff0c;下方横向浮动排列&#xff0c;大学学习的前端知识点和布局方式都有…

Xshell连接不上创建的虚拟机

1.输入ip a查看是否有对应的网卡ip 更改前&#xff1a; 更改后&#xff1a; 具体看下面博客的步骤&#xff0c;这里不详细赘述 (137条消息) Linux虚拟机联网步骤&#xff08;修改网络配置信息&#xff09;_袁梦码的博客-CSDN博客_怎么让linux虚拟机联网 2.关闭防火墙 永久关…

C语言实现冒泡排序(图解)

目录 一、冒泡排序是什么&#xff1f; 二、图解冒泡排序过程 三、代码实现 3.1易错点&#xff08;切记切记&#xff09; 四、优化 4.1优化代码 一、冒泡排序是什么&#xff1f; int arr[]{9,8,7,6,5,4,3,2,1,0} &#xff0c;像这样的数组&#xff0c;升序排序。 冒泡排序…