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

📄 lcdddc.c

📁 此代码为WCE5.0下显示器的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
        if (LCDDDC2_I2CWrite(lpDdcQueryContext->hGDO,
                             lpDdcQueryContext->hDDL,
                             ucEdidWriteAddress) == FALSE)
        {
            ucEdidWriteAddress = DDC2_I2C_MONITOR_ADDRESS_WRITE0;
            lpDdcQueryContext->ulLength = 21;           // EPR 35356, EPR 36724
            if (LCDDDC2_I2CWrite(lpDdcQueryContext->hGDO,
                                 lpDdcQueryContext->hDDL,
                                 ucEdidWriteAddress) == FALSE)
            {
                //
                // Restore I2C_CNTL_0 and I2C_CNTL_1 for "use software I2C".
                //
                LCD_DDC2_Restore_SOFTWARE_I2C(lpDdcQueryContext->hGDO);

                DALDEBUG((DALDBG_DETAIL, "LCDDDC2_QueryCallback: Can't write (110398) - DDC2 not supported"));
                return FALSE;
            }
        }
    }

    // EPR 35356
    // Read EDID from the monitor.
    //

    ZEROMEMORY(lpDdcQueryContext->lpucQueryBuffer,lpDdcQueryContext->ulLength);

    if (LCDDDC2_I2CRead(lpDdcQueryContext->hGDO,
                        lpDdcQueryContext->hDDL,
                        lpDdcQueryContext->lpucQueryBuffer,
                        lpDdcQueryContext->ulLength,
                        ucEdidWriteAddress) == FALSE)
    {
        //
        // Restore I2C_CNTL_0 and I2C_CNTL_1 for "use software I2C".
        //
        LCD_DDC2_Restore_SOFTWARE_I2C(lpDdcQueryContext->hGDO);

        DALDEBUG((DALDBG_DETAIL, "LCDDDC2_QueryCallback: Can't read - DDC2 not supported"));
        return FALSE;
    }

    //
    // Restore I2C_CNTL_0 and I2C_CNTL_1 for "use software I2C".
    //
    LCD_DDC2_Restore_SOFTWARE_I2C(lpDdcQueryContext->hGDO);

    return TRUE;
}   // LCDDETQueryCallback()

BOOLEAN
LCDDDC2_I2CStart(
    HGDO hGDO,
    HDDL hDDL
    )
//
// DESCRIPTION:
//  Starts I2C communication.
//
// PARAMETERS:
//  hDDL  Points to per-adapter device extension.
//
// RETURN VALUE:
//  TRUE        OK.
//  FALSE       Failed.
//
{
    ULONG ulRetry;

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

    //
    // The I2C communications start signal is a SDA high->low while the SCL is high.
    //

    for (ulRetry = 0; ulRetry <= DDC2_I2C_START_RETRIES; ulRetry++)
    {
        LCDDDC2_I2CWriteDataLine(hGDO, hDDL, 1);           // Set SDA high
        DDC2_I2C_DELAY();
        if (LCDDDC2_I2CReadDataLine(hGDO, hDDL) == FALSE)  // SDA didn't take - retry
            continue;
        LCDDDC2_I2CWriteClockLine(hGDO, hDDL, 1);          // Set SCL high
        DDC2_I2C_DELAY();
        if (LCDDDC2_I2CWaitForClockLineHigh(hGDO, hDDL) == FALSE)
        {
            DALDEBUG((DALDBG_DETAIL, "LCDDDC2_I2CStart: SCL didn't take"));
            break;
        }
        LCDDDC2_I2CWriteDataLine(hGDO, hDDL, 0);           // Set SDA low
        DDC2_I2C_DELAY();
        LCDDDC2_I2CWriteClockLine(hGDO, hDDL, 0);          // Set SCL low
        DDC2_I2C_DELAY();
        return TRUE;
    }

    DALDEBUG((DALDBG_DETAIL, "LCDDDC2_I2CStart: Failed"));
    return FALSE;
}   // LCDDDC2_I2CStart()

BOOLEAN
LCDDDC2_I2CStop(
    HGDO hGDO,
    HDDL hDDL
    )
//
// DESCRIPTION:
//  Stops I2C communication.
//
// PARAMETERS:
//  hDDL  Points to per-adapter device extension.
//
// RETURN VALUE:
//  TRUE        OK.
//  FALSE       Failed.
//
{
    DALASSERT(hDDL != NULL, "hDDL is NULL!");

    //
    // The I2C communications stop signal is a SDA low->high while the SCL is high.
    //

    LCDDDC2_I2CWriteDataLine(hGDO, hDDL, 0);               // Set SDA low
    DDC2_I2C_DELAY();
    LCDDDC2_I2CWriteClockLine(hGDO, hDDL, 1);              // Set SCL high
    DDC2_I2C_DELAY();
    if (LCDDDC2_I2CWaitForClockLineHigh(hGDO, hDDL) == FALSE)
    {
        DALDEBUG((DALDBG_DETAIL, "LCDDDC2_I2CStop: SCL didn't take"));
        return FALSE;
    }
    LCDDDC2_I2CWriteDataLine(hGDO, hDDL, 1);               // Set SDA high
    DDC2_I2C_DELAY();
    if (LCDDDC2_I2CReadDataLine(hGDO, hDDL) == FALSE)
    {
        DALDEBUG((DALDBG_DETAIL, "LCDDDC2_I2CStop: SDA didn't take"));
        return FALSE;
    }

    return TRUE;
}   // LCDDDC2_I2CStop()

BOOLEAN
LCDDDC2_I2CWrite(
    HGDO hGDO,
    HDDL hDDL,
    UCHAR ucEdidWriteByte
    )
//
// DESCRIPTION:
//  Writes data to the DDC2 monitor.
//
// PARAMETERS:
//  hDDL        Points to per-adapter device extension.
//  lpucBuffer  Points to data to be written.
//  ulLength    Number of bytes to write.
//
// RETURN VALUE:
//  TRUE        Write OK.
//  FALSE       Write failed.
//
{

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

    if (LCDDDC2_I2CStart(hGDO, hDDL) == FALSE)
        return FALSE;

    //
    // Write Edid write address.
    //
    if (LCDDDC2_I2CWriteByte(hGDO, hDDL, ucEdidWriteByte) == FALSE)
    {
        LCDDDC2_I2CStop(hGDO, hDDL);
        return FALSE;
    }

    //
    // Write out start address.
    //
    if (LCDDDC2_I2CWriteByte(hGDO, hDDL, 0) == FALSE)
    {
        LCDDDC2_I2CStop(hGDO, hDDL);
        return FALSE;
    }

    if (LCDDDC2_I2CStop(hGDO, hDDL) == FALSE)
        return FALSE;

    return TRUE;
}   // LCDDDC2_I2CWrite()

BOOLEAN
LCDDDC2_I2CWriteByte(
    HGDO hGDO,
    HDDL hDDL,
    UCHAR ucByte
    )
//
// DESCRIPTION:
//  Sends byte over I2C channel.
//
// PARAMETERS:
//  hDDL    Points to per-adapter device extension.
//  ucByte  Byte to write.
//
// RETURN VALUE:
//  TRUE        Write OK.
//  FALSE       Write failed.
//
{
    LONG lShift;
    BOOLEAN bAck;

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

    //
    // Bits are transmitted serially starting with the MSB.
    //

    for (lShift = 7; lShift >= 0; lShift--)
    {
        //
        // Transmitt data bit.
        //

        LCDDDC2_I2CWriteDataLine(hGDO, hDDL, (UCHAR)((ucByte >> lShift) & 0x01));  // Set SDA
        DDC2_I2C_DELAY();

        //
        // After each data bit we must send high->low SCL pulse.
        //

        LCDDDC2_I2CWriteClockLine(hGDO, hDDL, 1);              // Set SCL high
        DDC2_I2C_DELAY();
        if (LCDDDC2_I2CWaitForClockLineHigh(hGDO, hDDL) == FALSE)
        {
            DALDEBUG((DALDBG_DETAIL, "DDC2_I2CWriteByte: SCL didn't take"));
            return FALSE;
        }
        LCDDDC2_I2CWriteClockLine(hGDO, hDDL, 0);              // Set SCL low
        DDC2_I2C_DELAY();
    }

    //
    // The monitor sends ACK by preventing the SDA from going high after the clock pulse we use
    // to send our last data bit. If the SDA goes high after this bit, it is a NAK from the monitor.
    //

    LCDDDC2_I2CWriteDataLine(hGDO, hDDL, 1);                   // Set SDA high
    DDC2_I2C_DELAY();
    LCDDDC2_I2CWriteClockLine(hGDO, hDDL, 1);                  // Set SCL high
    DDC2_I2C_DELAY();
    if (LCDDDC2_I2CWaitForClockLineHigh(hGDO, hDDL) == FALSE)
    {
        DALDEBUG((DALDBG_DETAIL, "LCDDDC2_I2CWriteByte: SCL didn't take - ACK failed"));
        return FALSE;
    }
    bAck = LCDDDC2_I2CReadDataLine(hGDO, hDDL);                // Read ACK bit
    LCDDDC2_I2CWriteClockLine(hGDO, hDDL, 0);                  // Set SCL low
    DDC2_I2C_DELAY();

    if (TRUE == bAck)                                               // NAK from the monitor
    {
        DALDEBUG((DALDBG_DETAIL, "LCDDDC2_I2CWriteByte: NAK received"));
        return FALSE;
    }

    return TRUE;
}   // LCDDDC2_I2CWriteByte()

BOOLEAN
LCDDDC2_I2CRead(
    HGDO hGDO,
    HDDL hDDL,
    LPUCHAR lpucBuffer,
    ULONG ulLength,
    UCHAR ucEdidWriteByte
    )
//
// DESCRIPTION:
//  Reads data from the DDC2 monitor.
//
// PARAMETERS:
//  hDDL        Points to per-adapter device extension.
//  lpucBuffer  Points to storage for data.
//  ulLength    Number of bytes to read.
//
// RETURN VALUE:
//  TRUE        Read OK.
//  FALSE       Read failed.
//
{
    ULONG ulCount;

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

    if (LCDDDC2_I2CStart(hGDO, hDDL) == FALSE)
        return FALSE;

    //
    // Convert Edid Write Address to Edid Read Address.
    //
    ucEdidWriteByte |= 0x01;

    //
    // Tell the monitor that we want to listen to it.
    //

    if (LCDDDC2_I2CWriteByte(hGDO, hDDL, ucEdidWriteByte) == FALSE)
    {
        LCDDDC2_I2CStop(hGDO, hDDL);
        return FALSE;
    }

    //
    // On all but the last byte, we must send an ACK in order to ensure that the sending device will
    // send subsequent data bytes. On the last byte, we must send a NAK so that it will shut up.
    //

    for (ulCount = 0; ulCount < ulLength; ulCount++)
    {
        if (ulLength - 1 == ulCount)
        {
            if (LCDDDC2_I2CReadByte(hGDO, hDDL, lpucBuffer + ulCount, FALSE) == FALSE)  // Last byte
            {
                LCDDDC2_I2CStop(hGDO, hDDL);
                return FALSE;
            }
        }
        else
        {
            if (LCDDDC2_I2CReadByte(hGDO, hDDL, lpucBuffer + ulCount, TRUE) == FALSE)
            {
                LCDDDC2_I2CStop(hGDO, hDDL);
                return FALSE;
            }
        }
    }

    if (LCDDDC2_I2CStop(hGDO, hDDL) == FALSE)
        return FALSE;

    return TRUE;
}   // LCDDDC2_I2CRead()

BOOLEAN
LCDDDC2_I2CReadByte(
    HGDO hGDO,
    HDDL hDDL,
    LPUCHAR lpucByte,
    BOOLEAN bMore
    )
//
// DESCRIPTION:
//  Receives byte over I2C channel.
//
// PARAMETERS:
//  hDDL        Points to per-adapter device extension.
//  lpucByte    Points to storage for read byte.
//  bMore       TRUE if we want to continue reading, FALSE otherwise.
//
// RETURN VALUE:
//  TRUE        Read OK - received byte in lpucByte.
//  FALSE       Read failed.
//
// NOTE:
//  We don't have to relaese SDA high (input) before read. Before first bit is read
//  we always write address byte -- write releases SDA high on exit. For each subsequent
//  byte we're also OK since we release SDA high on exit from this routine.
//
{
    LONG lShift;

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

    *lpucByte = 0;

    //
    // The data bits are read from MSB to LSB. A data bit is read while the SCL is high.
    //

    for (lShift = 7; lShift >= 0; lShift--)
    {
        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"));
            return FALSE;
        }
        *lpucByte |= LCDDDC2_I2CReadDataLine(hGDO, hDDL) << lShift; // Read SDA
        LCDDDC2_I2CWriteClockLine(hGDO, hDDL, 0);                  // Set SCL low
        DDC2_I2C_DELAY();
    }

    //
    // Send the acknowledge bit. SDA low = ACK, SDA high = NAK.
    //

    if (TRUE == bMore)
        LCDDDC2_I2CWriteDataLine(hGDO, hDDL, 0);                   // Set SDA low - ACK
    else
        LCDDDC2_I2CWriteDataLine(hGDO, hDDL, 1);                   // Set SDA high - NAK
    DDC2_I2C_DELAY();

    //
    // Send a SCL high->low pulse, then release the SDA by setting it high.
    //

⌨️ 快捷键说明

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