⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lcdddc.c

📁 此代码为WCE5.0下显示器的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    LCDDDC2_I2CWriteClockLine(hGDO, hDDL, 1);                      // Set SCL high
    DDC2_I2C_DELAY();
    if (LCDDDC2_I2CWaitForClockLineHigh(hGDO, hDDL) == FALSE)
    {
        DALDEBUG((DALDBG_DETAIL, "LCDDDC2_I2CReadByte: SCL didn't take - ACK failed"));
        return FALSE;
    }
    LCDDDC2_I2CWriteClockLine(hGDO, hDDL, 0);                      // Set SCL low
    DDC2_I2C_DELAY();
    LCDDDC2_I2CWriteDataLine(hGDO, hDDL, 1);                       // Set SDA high
    DDC2_I2C_DELAY();

    return TRUE;
}   // LCDDDC2_I2CReadByte()

BOOLEAN
LCDDDC2_I2CWaitForClockLineHigh(
    HGDO hGDO,
    HDDL hDDL
    )
//
// DESCRIPTION:
//  Waits till SCL goes high (SCL low period can be stretched by slow monitors).
//
// PARAMETERS:
//  hDDL        Points to per-adapter device extension.
//
// RETURN VALUE:
//  TRUE        OK - SCL high.
//  FALSE       SCL didn't take.
//
{
    ULONG ulCount;

    DALASSERT(NULL != hDDL, "hDDL is NULL!");

    for (ulCount = 0; ulCount < DDC2_I2C_SCL_READ_RETRIES; ulCount++)
    {
        if (LCDDDC2_I2CReadClockLine(hGDO, hDDL) == TRUE)
            return TRUE;
        DDC2_I2C_DELAY();
    }

    return FALSE;
}   // LCDDDC2_I2CWaitForClockLineHigh

#endif  // _WIN32_WINNT >= 0x500

// Rage LT Pro and Rage Mobility:
//
//  DDC through GP_IO:
//
//  SCL = Pin GPIO13
//  SDA = Pin GPIO12
//
//  GP_IO  + 1: Bit 5 = SCL Read
//              Bit 4 = SDA Read
//
//  GP_IO  + 3: Bit 5 = SCL Direction, 0 = Input, 1 = Output
//              Bit 4 = SDA Direction, 0 = Input, 1 = Output
//
// Rage XL and Rage XC:
//
//  DDC through Test_IO register in LCD_INDEX.
//
// NOTE:
//  For DDC communication we are the I2C master and we drive the SCL line.
//  Setting I2C line to input direction drives it high (releases it high - default).
//  Setting I2C line to output direction drives it low (pulls it to ground).
//

//
// TODO: Verify if there is no conflict between I2C/GP_IO Interface functions and DDC Helper functions.
// If there is a chance of conflict we should use VideoPortSynchronizeExecution() callback functions for
// I2C read/write.
//

VOID
LCDDDC2_I2CWriteClockLine(
    HGDO hGDO,
    HDDL hDDL,
    UCHAR ucData
    )
//
// DESCRIPTION:
//  Sets DDC I2C clock line (SCL) low / high.
//
// PARAMETERS:
//  hDDL    Points to per-adapter device extension.
//  ucData  0 = drive SCL low, 1 = drive SCL high.
//
{
    LPGDO_RAGE_LCD hGDORageLCD;
    UCHAR          ucTemp;

    DALASSERT(NULL != hDDL, "hDDL is NULL!");

    hGDORageLCD = (LPGDO_RAGE_LCD)hGDO;

    ucData &= 0x01;     // Mask
    ucData ^= 0x01;     // Invert

    if( hGDORageLCD->ulChipFamily == FAMILY_LT_PRO||
        hGDORageLCD->ulChipFamily == FAMILY_RAGE_MOBILITY)
    {
        //
        // Set the SCL enable line.
        //

        ucTemp = (MMREADUCHAR(hGDORageLCD->lpMMR, GP_IO, 3) &
                      ~(0x20))| (ucData << 5);

        MMWRITEUCHAR(hGDORageLCD->lpMMR,
                     GP_IO, ucTemp, 3
                     );
    }
    else
    {
        //
        // Set SCL line.
        //
        // Set LCD_DATA register to index 28 (LCD_INDEX_TestIO).
        MMWRITEUCHAR(hGDORageLCD->lpMMR, LCD_INDEX, LCD_INDEX_TestIO, 0);

        //
        // Set the SCL enable line (Rage XL).
        //

        ucTemp = (MMREADUCHAR(hGDORageLCD->lpMMR, LCD_DATA, 1) &
                      ~(0x01))| ucData;
        if (ucData)
        {
            ucTemp &= ~(0x04);
        }

        MMWRITEUCHAR(hGDORageLCD->lpMMR,
                     LCD_DATA, ucTemp, 1
                     );

    }
}   // LCDDDC2_I2CWriteClockLine()

VOID
LCDDDC2_I2CWriteDataLine(
    HGDO hGDO,
    HDDL hDDL,
    UCHAR ucData
    )
//
// DESCRIPTION:
//  Sets DDC I2C data line (SDA) low / high.
//
// PARAMETERS:
//  hDDL        Points to per-adapter device extension.
//  ucData      0 = drive SDA low, 1 = drive SDA high.
//
{
    LPGDO_RAGE_LCD hGDORageLCD;
    UCHAR          ucTemp;

    DALASSERT(NULL != hDDL, "hDDL is NULL!");

    hGDORageLCD = (LPGDO_RAGE_LCD)hGDO;

    ucData &= 0x01;     // Mask
    ucData ^= 0x01;     // Invert

    if( hGDORageLCD->ulChipFamily == FAMILY_LT_PRO||
        hGDORageLCD->ulChipFamily == FAMILY_RAGE_MOBILITY)
    {
        //
        // Set the SDA enable line.
        //

        ucTemp = (MMREADUCHAR(hGDORageLCD->lpMMR, GP_IO, 3) &
                     ~(0x10)) | (ucData << 4);
        MMWRITEUCHAR(hGDORageLCD->lpMMR,
                     GP_IO, ucTemp, 3
                    );
    }
    else
    {
        //
        // Set SDA line.
        //
        // Set LCD_DATA register to index 28 (LCD_INDEX_TEST_IO).
        MMWRITEUCHAR(hGDORageLCD->lpMMR, LCD_INDEX, LCD_INDEX_TestIO, 0);

        //
        // Set the SDA enable line (Rage XL).
        //

        ucTemp = (MMREADUCHAR(hGDORageLCD->lpMMR, LCD_DATA, 1) &
                     ~(0x02)) | (ucData << 1);
        if (ucData)
        {
            ucTemp &= ~(0x08);
        }

        MMWRITEUCHAR(hGDORageLCD->lpMMR,
                     LCD_DATA, ucTemp, 1
                    );

    }

}   // LCDDDC2_I2CWriteDataLine()

BOOLEAN
LCDDDC2_I2CReadClockLine(
    HGDO hGDO,
    HDDL hDDL
    )
//
// DESCRIPTION:
//  Reads DDC I2C clock line (SCL).
//
// PARAMETERS:
//  hDDL  Points to per-adapter device extension.
//
// RETURN VALUE:
//  TRUE    SCL high.
//  FALSE   SCL low.
//
{
    LPGDO_RAGE_LCD hGDORageLCD;

    DALASSERT(NULL != hDDL, "hDDL is NULL!");

    hGDORageLCD = (LPGDO_RAGE_LCD)hGDO;

    if( hGDORageLCD->ulChipFamily == FAMILY_LT_PRO||
        hGDORageLCD->ulChipFamily == FAMILY_RAGE_MOBILITY)
    {
        //
        // Read from the SCL line and return.
        //
        return (BOOLEAN)((MMREADUCHAR(hGDORageLCD->lpMMR,
                                      GP_IO, 1) >> 5) & 0x01);
    }
    else
    {
        // Set LCD_DATA register to index 28 (LCD_INDEX_TEST_IO).
        MMWRITEUCHAR(hGDORageLCD->lpMMR, LCD_INDEX, LCD_INDEX_TestIO, 0);

        //
        // Read from the SCL line and return (Rage XL).
        //
        return (BOOLEAN)((MMREADUCHAR(hGDORageLCD->lpMMR,
                                      LCD_DATA, 1) >> 2) & 0x01);

    }

}   // LCDDDC2_I2CReadClockLine()

BOOLEAN
LCDDDC2_I2CReadDataLine(
    HGDO hGDO,
    HDDL hDDL
    )
//
// DESCRIPTION:
//  Reads DDC I2C data line (SDA).
//
// PARAMETERS:
//  hDDL    Points to per-adapter device extension.
//
// RETURN VALUE:
//  TRUE    SDA high.
//  FALSE   SDA low.
//
{
    LPGDO_RAGE_LCD hGDORageLCD;

    DALASSERT(NULL != hDDL, "hDDL is NULL!");

    hGDORageLCD = (LPGDO_RAGE_LCD)hGDO;

    if( hGDORageLCD->ulChipFamily == FAMILY_LT_PRO||
        hGDORageLCD->ulChipFamily == FAMILY_RAGE_MOBILITY)
    {
        //
        // Read from the SDA line and return.
        //
        return (BOOLEAN)((MMREADUCHAR(hGDORageLCD->lpMMR,
                                          GP_IO, 1) >> 4) & 0x01);
    }
    else
    {

        // Set LCD_DATA register to index 28 (LCD_INDEX_TEST_IO).
        MMWRITEUCHAR(hGDORageLCD->lpMMR, LCD_INDEX, LCD_INDEX_TestIO, 0);

        //
        // Read from the SDA line and return (Rage XL).
        //
        return (BOOLEAN)((MMREADUCHAR(hGDORageLCD->lpMMR,
                                      LCD_DATA, 1) >> 3) & 0x01);
    }

}   // LCDDDC2_I2CReadDataLine()

VOID
LCDWaitForVerticalBlank(
    HGDO hGDO,
    HDDL hDDL
    )
//
// DESCRIPTION:
//  Waits for beginning of new vertical blank.
//
// PARAMETERS:
//  hDDL    Points to per-adapter device extension.
//
{
    LPGDO_RAGE_LCD hGDORageLCD;

    DALASSERT(NULL != hDDL, "hDDL is NULL!");

    hGDORageLCD = (LPGDO_RAGE_LCD)hGDO;

    //
    // To do: Need to find out how to detect a v-blank for LCD panel.
    //

}

VOID
LCD_DDC2_Select_SOFTWARE_I2C(
    HGDO hGDO
    )
//
// DESCRIPTION:
//  Set I2C_SEL(0) bit to 1 (Use software I2C).
//
// PARAMETERS:
//  hDDL    Points to per-adapter device extension.
//
{
    LPGDO_RAGE_LCD      hGDORageLCD;
    ULONG               ulData;

    hGDORageLCD = (LPGDO_RAGE_LCD)hGDO;

    if( hGDORageLCD->ulChipFamily == FAMILY_LT_PRO||
        hGDORageLCD->ulChipFamily == FAMILY_RAGE_MOBILITY)
    {
        //
        // Restet bit 10, 12, 13, 26, 28, and 29 bits.
        //
        ulData = MMREADULONG(hGDORageLCD->lpMMR, GP_IO);
        ulData &= (~0x34003400);

        MMWRITEULONG(hGDORageLCD->lpMMR, GP_IO, ulData);

        //
        // Enable software I2C.
        //
        hGDORageLCD->ulI2CCntl1Data =
        ulData = MMREADULONG(hGDORageLCD->lpMMR, CNTL_1);
        ulData |= CNTL_1__I2C_SEL0;
        MMWRITEULONG(hGDORageLCD->lpMMR, CNTL_1, ulData);

        ulData &= (~CNTL_1__I2C_SEL1);
        MMWRITEULONG(hGDORageLCD->lpMMR, CNTL_1, ulData);

        //
        // Set software control for SCL and SDA.
        //
        hGDORageLCD->ulI2CCntl0Data =
        ulData = MMREADULONG(hGDORageLCD->lpMMR, CNTL_0);
        ulData |= CNTL_0__I2C_CNTL_SDA;
        MMWRITEULONG(hGDORageLCD->lpMMR, CNTL_0, ulData);

        ulData |= CNTL_0__I2C_CNTL_SCL;
        MMWRITEULONG(hGDORageLCD->lpMMR, CNTL_0, ulData);
    }

} // End of LCD_DDC2_Select_SOFTWARE_I2C

VOID
LCD_DDC2_Restore_SOFTWARE_I2C(
    HGDO hGDO
    )
//
// DESCRIPTION:
//  Restore I2C_CNTL_0 and I2C_CNTL_1 registers.
//
// PARAMETERS:
//  hDDL    Points to per-adapter device extension.
//
{
    LPGDO_RAGE_LCD      hGDORageLCD;

    hGDORageLCD = (LPGDO_RAGE_LCD)hGDO;

    if( hGDORageLCD->ulChipFamily == FAMILY_LT_PRO||
        hGDORageLCD->ulChipFamily == FAMILY_RAGE_MOBILITY)
    {
        //
        // Restore I2C_CNTL_0 register.
        //
        MMWRITEULONG(hGDORageLCD->lpMMR, CNTL_0, hGDORageLCD->ulI2CCntl0Data);

        //
        // Restore I2C_CNTL_1 register.
        //
        MMWRITEULONG(hGDORageLCD->lpMMR, CNTL_1, hGDORageLCD->ulI2CCntl1Data);
    }

} // End of LCD_DDC2_Restore_SOFTWARE_I2C

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -