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

news2024/12/24 2:41:42

环境:

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.coloradmin.cn/o/32252.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CentOS 6.6系统怎么安装?CentOS Linux系统安装配置图解教程

服务器相关设置如下&#xff1a; 操作系统&#xff1a;CentOS 6.6 64位 IP地址&#xff1a;192.168.21.129 网关&#xff1a;192.168.21.2 DNS&#xff1a;8.8.8.8 8.8.4.4 备注&#xff1a; CentOS 6.6系统镜像有32位和64位两个版本&#xff0c;并且还有专门针对服务器优化过的…

【端到端存储解决方案】Weka,让企业【文件存储】速度飞起来!

一、HK-Weka概述 虹科WekaIO&#xff08;简称HK-Weka&#xff09;是一个可共享、可扩展的文件存储系统解决方案&#xff0c;其并行文件系统WekaFS支持NVMeoF的flash-native并行文件系统、比传统的NAS存储及本地存储更快。 HK-Weka后端主机被配置为集群&#xff0c;它与安装在应…

在Mysql中新建序列Sequence

在Oracle数据库中想要一个连续的自增数据类型的值&#xff0c;可以通过创建一个sequence来实现。而在Mysql数据库中并没有sequence&#xff0c;如想要在Mysql中像Oracle那样使用序列&#xff0c;该如何操作呢&#xff1f;&#xff08;可以使用mysql中的自增主键&#xff09; 1、…

哪个牌子的led灯质量好?2022LED护眼台灯最好的品牌有哪些

谈及led灯的品牌&#xff0c;就不得不提一些比较专业的厂商了&#xff0c;特别是在护眼照明领域&#xff0c;明基、南卡、飞利浦、松下等品牌都有不俗的实力&#xff0c;出产的led护眼台灯在业内都有广泛的知名度&#xff0c;在消费者领域也是好评连连。那么它们到底好在哪儿呢…

蓝牙协议栈分层

一、分层 BLE协议栈主要用来对你的应用数据进行层层封包&#xff0c;以生成一个满足BLE协议的空中数据包&#xff0c;也就是说&#xff0c;把应用数据包裹在一系列的帧头&#xff08;header&#xff09;和帧尾&#xff08;tail&#xff09;中。 BLE协议栈主要由如下几部分组成…

达梦日志分析工具DMLOG使用

达梦日志分析工具DMLOG1.使用工具的目的2.适用范围3.工具描述4.开启跟踪日志记录执行SQL5.使用条件及限制6.使用说明6.1使用前准备6.2使用方法和步骤7.结果解读1.使用工具的目的 分析SQL是DBA或者数据库服务人员很重要的工作。达梦数据库通过开启SVR_LOG捕捉数据库中运行的所有…

SpringBoot+Vue项目实现高校学生健康打卡系统

文末获取源码 开发语言&#xff1a;Java 使用框架&#xff1a;spring boot 前端技术&#xff1a;JavaScript、Vue.js 、css3 开发工具&#xff1a;IDEA/MyEclipse/Eclipse、Visual Studio Code 数据库&#xff1a;MySQL 5.7/8.0 数据库管理工具&#xff1a;phpstudy/Navicat JD…

双通道PID控制器用于热离子发电器中真空度和温度的同时控制

摘要&#xff1a;本文针对真空型热离子能量转换器&#xff08;发电装置&#xff09;中真空压力和温度的关联性复杂控制&#xff0c;提出一个简便的控制方式和控制系统的解决方案&#xff0c;控制系统仅采用一个双通道高精度PID调节器。方案的核心技术思路是将一个可调参量转换为…

接口类型太多了,很多网工总是分不清

交换机光模块的最强科普 以太网交换机常用的光模块有四个&#xff0c;分别是SFP&#xff08;Small Form-factor Pluggabletransceiver&#xff09; 小封装可插拔收发器&#xff0c;GBIC&#xff08;GigaBit Interface Converter&#xff09;千兆以太网接口转换器&#xff0c;X…

往USBKey里面导入双证书专题:概念介绍、执行逻辑

相关概念 国密证书 国密的双证书体系&#xff0c;将证书按照使用目的的不同划分为加密证书和签名证书两种&#xff0c;也就是两对公私钥&#xff0c;二者本质一致&#xff0c;均为SM2密钥对&#xff0c;区别仅体现在用法国密CA体系中&#xff0c;加密密钥对由CA产生&#xff…

力扣刷题记录141.1-----34. 在排序数组中查找元素的第一个和最后一个位置

目录一、题目二、代码三、运行结果一、题目 二、代码 class Solution { public:vector<int> searchRange(vector<int>& nums, int target) {int i,j;int left,right,middle;vector<int> return_vector(2,-1);if(nums.size()<3){for(i0;i<nums.si…

mysql转sqlite3实战+部署sqlite3应用

文章目录场景mysql脚本转sqlite31.新建个sqlite3的文件并使用navicat连接准备好mysql并连接上使用navicat数据传输传输完后&#xff0c;设置主键自增修改应用程序1.添加sqlite3的驱动包2.修改sqlite3的jdbc连接配置文件3.全局替换Date类型字段为String类型4.全局替换 sql文件中…

达摩院WIDER FACE榜首近两年人脸检测MogFace CVPR论文深入解读

一、开源 1.&#xff09;论文链接&#xff1a;https://openaccess.thecvf.com/content/CVPR2022/papers/Liu_MogFace_Towards_a_Deeper_Appreciation_on_Face_Detection_CVPR_2022_paper.pdf 2.&#xff09;代码模型&#xff1a;ModelScope 魔搭社区 3.&#xff09;可玩应用…

新知实验室_初探腾讯云音视频

本文目标&#xff1a; 了解 TRTC 的基本概念 初步运行 demo 调用 API 完成进入视频房间 完成多人进入同一房间 一、腾讯 TRTC 可能有些同学并不知道 RTC 的相关概念&#xff0c; 这里先简单说一下。 WebRTC(web Real-Time Communication) 是指网站实时音视频通话技术。 这项技…

Shopro商城 高级版 Fastadmin和Uniapp进行开发的多平台商城(微信公众号、微信小程序、H5网页、Android-App、IOS-App)

Shopro商城无加密的开源源码(可用于自营外包项目(多主体)、可用于外包定制开发项目) shopro 商城&#xff0c;一款基于 uni-app 的前端模板商城。目前适配了&#xff08;小程序apph5公众号&#xff09;。 主要功能&#xff1a;登录、注册、签到、富文本、分类、购物车、筛选、…

CI/CD docker compose 部署 humpback - single mode

最近想搭一搭个人服务器&#xff0c;其中有很多东西都是通过 docker 来管理&#xff0c;每次都手动输入命令比较麻烦&#xff0c;需要一个轻量级的容器管理工具来直观轻松的管理容器和镜像。于是便相中了 humpback。 Humpback humpback 相关的详细介绍请自助传送 架构 主要组…

【无线传感器】WSN 查找两个节点之间的最短路径并发送数据(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

前后端分离项目,vue+uni-app+php+mysql教室预约系统设计与实现(H5移动项目)

功能模块 【后台管理功能模块】 系统设置&#xff1a;设置关于我们、联系我们、加入我们、法律声明 广告管理&#xff1a;设置小程序首页轮播图广告和链接 留言列表&#xff1a;所有用户留言信息列表&#xff0c;支持删除 会员列表&#xff1a;查看所有注册会员信息&#xff0c…

【力扣】787. K 站中转内最便宜的航班加权——有向图最短路径

前言 我感觉这题比较有代表性&#xff0c;所以记录一下&#xff0c;这题是加权有向图中求最短路径的问题。 题目 787. K 站中转内最便宜的航班 动态规划 假设有一条路径是[src, i, ..., j, dst]&#xff0c;解法一子问题的定义是[src, i, ..., j]&#xff0c;解法二子问题…

面经汇总--校招--北京顺丰同城

文章目录&#x1f525;1.一面&#x1f525;2.二面&#x1f525;3. 三面&#x1f525;4. 结果&#x1f525;1.一面 你对Spring aop的理解 面向切面编程&#xff0c;可以对某个方法前后加入自己想执行的方法函数。底层是动态代理&#xff0c;默认jdk动态代理&#xff0c;没有实现…