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

📄 pdd.c

📁 Exar 公司 M1170 芯片 (i2c 转 串口)的 驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
    DEBUGMSG(ZONE_FUNCTION, (L"-HWSetBreak\r\n"));
}

//------------------------------------------------------------------------------
//
//  Function:  HWReset
//
//  This function performs any operations associated with a device reset.
//
static VOID HWReset(VOID *pvContext)
{
    UARTPDD *pPdd = (UARTPDD*)pvContext;

    DEBUGMSG(ZONE_FUNCTION, (L"+HWReset(0x%08x)\r\n", pvContext));

    /* Modified BEGIN, by LONGCHEER SONGLIXIN, on: 2007-8-29 10:11:50 */
    #if 0
    EnterCriticalSection(&pPdd->hwCS);
    // Enable interrupts
    pPdd->intrMask = UART_IER_LINE|UART_IER_MODEM|UART_IER_RHR;
    OUTREG8(&pPdd->pUARTRegs->IER, pPdd->intrMask);
    LeaveCriticalSection(&pPdd->hwCS);
    /*=========== replaced by ===================*/
    #else
    HWStartup(pPdd);
    #endif
    /* Modified END, by LONGCHEER SONGLIXIN, on: 2007-8-29 10:11:50 */

    DEBUGMSG(ZONE_FUNCTION, (L"-HWReset\r\n"));
}

//------------------------------------------------------------------------------
//
//  Function:  HWGetModemStatus
//
//  This function retrieves modem status.
//
static VOID HWGetModemStatus(VOID *pvContext, ULONG *pModemStat)
{
    UARTPDD *pPdd = (UARTPDD*)pvContext;
    UCHAR ucModemStat;

    DEBUGMSG(ZONE_FUNCTION, (L"+HWGetModemStatus(0x%08x)\r\n", pvContext));

    ucModemStat = ReadModemStat(pPdd);

    *pModemStat = 0;
    if ((ucModemStat & UART_MSR_NCTS) != 0) *pModemStat |= MS_CTS_ON;
    if ((ucModemStat & UART_MSR_NDSR) != 0) *pModemStat |= MS_DSR_ON;
    if ((ucModemStat & UART_MSR_NCD) != 0) *pModemStat |= MS_RLSD_ON;

    DEBUGMSG(ZONE_FUNCTION, (L"-HWGetModemStatus(0x%08x)\r\n", *pModemStat));
}

//------------------------------------------------------------------------------
//
//  Function:  HWXmitComChar
//
//  This function transmits a char immediately
//
static BOOL HWXmitComChar(VOID *pvContext, UCHAR ucCh)
{
    UARTPDD *pPdd = (UARTPDD*)pvContext;

    DEBUGMSG(ZONE_FUNCTION, (L"+HWXmitComChar(0x%08x, %d)\r\n", pvContext, ucCh));

    EnterCriticalSection(&pPdd->txCS);
    EnterCriticalSection(&pPdd->hwCS);

    while (TRUE) {  // We know THR will eventually empty

        // Write the character if we can
        if ((ReadLineStat(pPdd) & UART_LSR_TX_FIFO_E) != 0) {
            // FIFO is empty, send this character
            RegWrite(pPdd, XR20M1170REG_THR, ucCh);
            // Enable TX interrupt
            pPdd->intrMask |= UART_IER_THR;
            RegWrite(pPdd, XR20M1170REG_IER, pPdd->intrMask);
            break;
        }

        // If we couldn't write the data yet, then wait for a TX interrupt
        pPdd->intrMask |= UART_IER_THR;
        RegWrite(pPdd, XR20M1170REG_IER, pPdd->intrMask);

        // Wait until the TX interrupt has signalled
        WaitForSingleObject(pPdd->txEvent, 1000);

    }
    LeaveCriticalSection(&pPdd->hwCS);
    LeaveCriticalSection(&pPdd->txCS);

    DEBUGMSG(ZONE_FUNCTION, (L"-HWXmitComChar\r\n"));
    return TRUE;
}

//------------------------------------------------------------------------------
//
//  Function:  HWGetStatus
//
//  This function is called by the MDD to retrieve the contents of
//  COMSTAT structure.
//
static ULONG HWGetStatus(VOID *pvContext, COMSTAT *pComStat)
{
    ULONG ulRc = -1;
    UARTPDD *pPdd = (UARTPDD*)pvContext;

    DEBUGMSG(ZONE_FUNCTION, (L"+HWGetStatus(0x%08x, 0x%08x)\r\n", pvContext, pComStat));

    if (pComStat == NULL) goto cleanUp;

    pComStat->fCtsHold = pPdd->flowOffCTS ? 1 : 0;
    pComStat->fDsrHold = pPdd->flowOffDSR ? 1 : 0;
    pComStat->cbInQue  = 0;
    pComStat->cbOutQue = 0;

    ulRc = pPdd->commErrors;
    pPdd->commErrors = 0;

cleanUp:
    DEBUGMSG(ZONE_FUNCTION, (L"-HWGetStatus(rc = %d)\r\n", ulRc));
    return ulRc;
}

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

static VOID HWGetCommProperties(VOID *pvContext, COMMPROP *pCommProp)
{
    UARTPDD *pPdd = (UARTPDD*)pvContext;

    DEBUGMSG(ZONE_FUNCTION, (L"+HWGetCommProperties(0x%08x, 0x%08x)\r\n", pvContext,pCommProp));

    memset(pCommProp, 0, sizeof(COMMPROP));
    pCommProp->wPacketLength = 0xffff;
    pCommProp->wPacketVersion = 0xffff;
    pCommProp->dwServiceMask = SP_SERIALCOMM;
    pCommProp->dwMaxTxQueue = 16;
    pCommProp->dwMaxRxQueue = 16;
    pCommProp->dwMaxBaud = BAUD_USER;
    pCommProp->dwProvSubType = PST_RS232;
    pCommProp->dwProvCapabilities =
        // On P2 DTR/DSR has a shortcut and RI/CD are not wired.
        // PCF_DTRDSR | PCF_RLSD |
        PCF_INTTIMEOUTS | PCF_PARITY_CHECK |
        PCF_RTSCTS | PCF_SETXCHAR | PCF_SPECIALCHARS | PCF_TOTALTIMEOUTS |
        PCF_XONXOFF;
    pCommProp->dwSettableParams =
        // On P2 RI/CD are not wired.
        // SP_RLSD |
        SP_BAUD | SP_DATABITS | SP_HANDSHAKING | SP_PARITY |
        SP_PARITY_CHECK | SP_STOPBITS;
    pCommProp->dwSettableBaud =
        BAUD_075 | BAUD_110 | BAUD_150 | BAUD_300 | BAUD_600 | BAUD_1200 |
        BAUD_1800 | BAUD_2400 | BAUD_4800 | BAUD_7200 | BAUD_9600 | BAUD_14400 |
        BAUD_19200 | BAUD_38400 | BAUD_57600 | BAUD_115200;
    pCommProp->wSettableData =
        DATABITS_5 | DATABITS_6 | DATABITS_7 | DATABITS_8;
    pCommProp->wSettableStopParity =
        STOPBITS_10 | STOPBITS_20 |
        PARITY_NONE | PARITY_ODD | PARITY_EVEN | PARITY_SPACE |
        PARITY_MARK;

    DEBUGMSG(ZONE_FUNCTION, (L"-HWGetCommProperties\r\n"));
}

//------------------------------------------------------------------------------
//
//  Function:  HWPurgeComm
//
//  This function purges RX and/or TX
//
static VOID HWPurgeComm(VOID *pvContext, DWORD dwAction)
{
    UARTPDD *pPdd = (UARTPDD*)pvContext;
    UCHAR uFifoCtrl = 0;

    DEBUGMSG(ZONE_FUNCTION, (L"+HWPurgeComm(0x%08x 0x%08x)\r\n", pvContext, dwAction));

    EnterCriticalSection(&pPdd->hwCS);

    if ((dwAction & PURGE_TXCLEAR) != 0) uFifoCtrl |= UART_FCR_TX_FIFO_CLEAR;
    if ((dwAction & PURGE_RXCLEAR) != 0) uFifoCtrl |= UART_FCR_RX_FIFO_CLEAR;
    RegWrite(pPdd, XR20M1170REG_FCR, UART_FCR_RX_FIFO_TRIG_8 | UART_FCR_TX_FIFO_TRIG_16 |\
        uFifoCtrl | UART_FCR_FIFO_EN);

    LeaveCriticalSection(&pPdd->hwCS);

    DEBUGMSG(ZONE_FUNCTION, (L"-HWPurgeComm\r\n"));
}

//------------------------------------------------------------------------------
//
//  Function:  HWSetDCB
//
//  This function sets new values for DCB. It gets a DCB from the MDD and
//  compare it to the current DCB, and if any fields have changed take
//  appropriate action.
//
static BOOL HWSetDCB(VOID *pvContext, DCB *pDCB)
{
    UARTPDD *pPdd = (UARTPDD*)pvContext;
    BOOL bRc = FALSE;


    DEBUGMSG(ZONE_FUNCTION, (L"+HWSetDCB(0x%08x, 0x%08x\r\n", pvContext, pDCB));

    // Check for same XON/XOFF characters...
    if (
        (pDCB->fOutX != 0 || pDCB->fInX != 0) &&
        pDCB->XonChar == pDCB->XoffChar
    ) {
        goto cleanUp;
    }

    // If the device is open, scan for changes and do whatever
    // is needed for the changed fields.  if the device isn't
    // open yet, just save the DCB for later use by the open.
    if (pPdd->open) {

        if (pDCB->BaudRate != pPdd->dcb.BaudRate) {
            if (!SetBaudRate(pPdd, pDCB->BaudRate)) goto cleanUp;
        }

        if (pDCB->ByteSize != pPdd->dcb.ByteSize) {
            if (!SetWordLength(pPdd, pDCB->ByteSize)) goto cleanUp;
        }

        if (pDCB->Parity != pPdd->dcb.Parity) {
            if (!SetParity(pPdd, pDCB->Parity)) goto cleanUp;
        }

        if (pDCB->StopBits != pPdd->dcb.StopBits) {
            if (!SetStopBits(pPdd, pDCB->StopBits)) goto cleanUp;
        }

        // Enable hardware auto RST/CTS modes...
        if (pPdd->hwMode) {
            if (pDCB->fRtsControl == RTS_CONTROL_HANDSHAKE) {
                RETAILMSG(TRUE, (L"HWSetDCB: Set auto RTS\r\n"));
                if (!SetAutoRTS(pPdd, TRUE)) goto cleanUp;
            } else {
                if (!SetAutoRTS(pPdd, FALSE)) goto cleanUp;
            }
            if (pDCB->fOutxCtsFlow) {
                RETAILMSG(TRUE, (L"HWSetDCB: Set auto CTS\r\n"));
                if (!SetAutoCTS(pPdd, TRUE)) goto cleanUp;
            } else {
                if (!SetAutoCTS(pPdd, TRUE)) goto cleanUp;
            }
        }
    }
    // Now that we have done the right thing, store this DCB
    pPdd->dcb = *pDCB;

    // All is fine
    bRc = TRUE;

cleanUp:
    DEBUGMSG(ZONE_FUNCTION, (L"-HWSetDCB(rc = %d)\r\n", bRc));
    return bRc;
}

//------------------------------------------------------------------------------
//
//  Function:  HWSetCommTimeouts
//
//  This function sets new values for the commTimeouts structure.
//
static ULONG HWSetCommTimeouts(VOID *pvContext, COMMTIMEOUTS *pCommTimeouts)
{
    UARTPDD *pPdd = (UARTPDD*)pvContext;
    DEBUGMSG(ZONE_FUNCTION, (L"+HWSetCommTimeouts()\r\n"));
    pPdd->commTimeouts = *pCommTimeouts;
    DEBUGMSG(ZONE_FUNCTION, (L"-HWSetCommTimeouts()\r\n"));
    return TRUE;
}

//------------------------------------------------------------------------------
//
//  Function:  HWIOCtl
//
//  This function process PDD IOCtl calls
//
static BOOL HWIOCtl(
    VOID *pvContext, DWORD code, UCHAR *pInBuffer, DWORD inSize,
    UCHAR *pOutBuffer, DWORD outSize, DWORD *pOutSize
) {
    BOOL rc = FALSE;
    UARTPDD *pPdd = (UARTPDD*)pvContext;
    DEBUGMSG(ZONE_FUNCTION, (TEXT("+HWIOCtl()\r\n")));

    switch (code) {

    case IOCTL_SERIAL_SET_TIMEOUTS:
        // Check input parameters
        if (
            pInBuffer == NULL || inSize < sizeof(COMMTIMEOUTS) ||
            !CeSafeCopyMemory(
                &pPdd->commTimeouts, pInBuffer, sizeof(COMMTIMEOUTS)
            )
        ) {
            SetLastError(ERROR_INVALID_PARAMETER);
            break;
        }
        rc = TRUE;
        break;

    case IOCTL_SERIAL_GET_TIMEOUTS:
        if (
            pInBuffer == NULL || inSize < sizeof(COMMTIMEOUTS) ||
            !CeSafeCopyMemory(
                pInBuffer, &pPdd->commTimeouts, sizeof(COMMTIMEOUTS)
            )
        ) {
            SetLastError(ERROR_INVALID_PARAMETER);
            break;
        }
        rc = TRUE;
        break;

    case IOCTL_POWER_CAPABILITIES:
        if (pOutBuffer == NULL || outSize < sizeof(POWER_CAPABILITIES)) {
            SetLastError(ERROR_INVALID_PARAMETER);
            break;
        }
        __try {
            POWER_CAPABILITIES *pPowerCaps = (POWER_CAPABILITIES*)pOutBuffer;
            memset(pPowerCaps, 0, sizeof(POWER_CAPABILITIES));
            pPowerCaps->DeviceDx = DX_MASK(D0)|DX_MASK(D3)|DX_MASK(D4);
            rc = TRUE;
        } __except(EXCEPTION_EXECUTE_HANDLER) {
            DEBUGMSG(ZONE_ERROR, (L"ERROR: UART::HWIOCtl: "
                L"Exception in IOCTL_POWER_CAPABILITIES\r\n"
            ));
        }
        break;

    case IOCTL_POWER_QUERY:
        if (pOutBuffer == NULL && outSize < sizeof(CEDEVICE_POWER_STATE)) {
            SetLastError(ERROR_INVALID_PARAMETER);
            break;
        }
        __try {
            CEDEVICE_POWER_STATE dx = *(CEDEVICE_POWER_STATE*)pOutBuffer;
            rc = VALID_DX(dx);
        } __except(EXCEPTION_EXECUTE_HANDLER) {
            DEBUGMSG(ZONE_ERROR, (L"ERROR: UART::HWIOCtl: "
                L"Exception in IOCTL_POWER_QUERY\r\n"
            ));
        }
        break;

    case IOCTL_POWER_SET:
        if (pOutBuffer == NULL && outSize < sizeof(CEDEVICE_POWER_STATE)) {
            SetLastError(ERROR_INVALID_PARAMETER);
            break;
        }
        __try {
            CEDEVICE_POWER_STATE dx = *(CEDEVICE_POWER_STATE*)pOutBuffer;
            pPdd->externalDX = dx;
            SetPower(pPdd, dx);
            *(CEDEVICE_POWER_STATE*)pOutBuffer = pPdd->externalDX;
            rc = TRUE;
        } __except(EXCEPTION_EXECUTE_HANDLER) {
            DEBUGMSG(ZONE_ERROR, (L"ERROR: UART::HWIOCtl: "
                L"Exception in IOCTL_POWER_SET\r\n"
            ));
        }
        break;

    case IOCTL_POWER_GET:
        if (pOutBuffer == NULL && outSize < sizeof(CEDEVICE_POWER_STATE)) {
            SetLastError(ERROR_INVALID_PARAMETER);
            break;
        }
        __try {
            *(CEDEVICE_POWER_STATE*)pOutBuffer = pPdd->externalDX;
            rc = TRUE;
        } __except(EXCEPTION_EXECUTE_HANDLER) {
            DEBUGMSG(ZONE_ERROR, (L"ERROR: UART::HWIOCtl: "
                L"Exception in IOCTL_POWER_GET\r\n"
            ));
        }
        break;
    case IOCTL_XR20M1170_GPS_DOWNLOADBOOT:
        gps_download(pPdd, 1);
        HWStartup(pPdd);
        break;
    case IOCTL_XR20M1170_GPS_NORMALBOOT:
        gps_download(pPdd, 0);
        HWStartup(pPdd);
        break;
    case IOCTL_XR20M1170_ENABLE_LOOPBACK:
        RegSetBit(pPdd, XR20M1170REG_MCR, BIT4);
        break;
    case IOCTL_XR20M1170_DISABLE_LOOPBACK:
        RegClrBit(pPdd, XR20M1170REG_MCR, BIT4);
        break;
    }

    DEBUGMSG(ZONE_FUNCTION, (TEXT("-HWIOCtl()\r\n")));
    return rc;
}

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

⌨️ 快捷键说明

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