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

📄 serio.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 C
📖 第 1 页 / 共 4 页
字号:
    PPERP_IO_SER_INFO   pHWHead = (PPERP_IO_SER_INFO)pHead;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("Serial PDD: Enter HWXmitComChar\r\n")));

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

            // Enable xmit intr.
            ENABLE_BITS8(ASICSiuRegs.siuie, SERIAL_IER_RDA | SERIAL_IER_RLS
                            | SERIAL_IER_MS | SERIAL_IER_THR);

            // Wait until the txintr has signalled.
            // WaitForSingleObject(pHWHead->FlushDone, (ULONG)-1);
            WaitForSingleObject(pHWHead->FlushDone, 1000);

            // Write the character if we can
            HWReadLSR( pHWHead );
            
            if( pHWHead->LSR & SERIAL_LSR_THRE ){

                REG8(ASICSiuRegs.siurb_th) = ComChar;

                break;
            }
    }

    return TRUE;
}

//***********************************************************************
// @doc OEM
// @func  ULONG | HWGetStatus | Hardware status api.
// *
// @rdesc The return is a ULONG, representing success (0) or failure (-1).
// * See Win32 documentation for ClearCommError for description of lpStat.
//***********************************************************************
ULONG
HWGetStatus(
    PVOID   pHead,  /* @parm PVOID returned by HWInit. */
    LPCOMSTAT   lpStat  /* @parm Pointer to LPCOMMSTAT to hold status.*/
    )
{
    PPERP_IO_SER_INFO pHWHead = (PPERP_IO_SER_INFO)pHead;
    ULONG RetVal = pHWHead->CommErrors;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("Serial PDD: Enter HWGetStatus\r\n")));

    pHWHead->CommErrors = 0; // Clear old errors each time

    if ( lpStat ){

        if (pHWHead->CTSFlowOff){

            pHWHead->Status.fCtsHold = 1;
        }
        else{
        
            pHWHead->Status.fCtsHold = 0;
        }

        if (pHWHead->DSRFlowOff){
        
            pHWHead->Status.fDsrHold = 1;
        }
        else{
        
            pHWHead->Status.fDsrHold = 0;
        }

        pHWHead->Status.cbInQue  = 0;
        pHWHead->Status.cbOutQue = 0;

        memcpy(lpStat, &(pHWHead->Status), sizeof(COMSTAT));

    }
    else{
    
        RetVal = (ULONG)-1;
    }

    return RetVal;
}

// ******************************************************************
// @doc OEM
// @func  ULONG | HWReset | Hardware reset api.
// *
// @rdesc This routine resets the COMSTAT status used by HWGetStatus.
// ******************************************************************
VOID
HWReset(
    PVOID   pHead   /* @parm PVOID returned by HWInit. */
    )
{
    PPERP_IO_SER_INFO pHWHead = (PPERP_IO_SER_INFO)pHead;
    USHORT      divisor = 120;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("Serial PDD: Enter HWReset\r\n")));

    // No longer called by MDD, just waiting to be removed from vtbl

    if(pHWHead->PortOpen){

        DEBUGMSG(ZONE_FUNCTION, (TEXT("Not Reset PortOpen Error!!\r\n")));

        return;
    }

    ENABLE_BITS8(ASICSiuRegs.siulc, SERIAL_LCR_DLAB);

    REG8(ASICSiuRegs.siurb_th) = (divisor & 0xff);

    REG8(ASICSiuRegs.siuie) = ((divisor >> 8) & 0xff);

    ENABLE_BITS8(ASICSiuRegs.siureset, SRESET);

    Sleep(20);

    DISABLE_BITS8(ASICSiuRegs.siureset, SRESET);

    DISABLE_BITS8(ASICSiuRegs.siulc, SERIAL_LCR_DLAB);

}

// ********************************************************
// @doc OEM
// @func  VOID | HWGetModemStatus | Retrieves modem status.
// *
// @rdesc See Win32 document for GetCommModemStatus.
// ********************************************************
VOID
HWGetModemStatus(
    PVOID   pHead,      /* @parm PVOID returned by HWInit. */
    PULONG  pModemStatus    /* @parm PULONG passed in by user. */
    )
{
    PPERP_IO_SER_INFO pHWHead = (PPERP_IO_SER_INFO)pHead;
    UCHAR ubModemStatus;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("Serial PDD: Enter HWGetModemStatus\r\n")));

    pHWHead->MSR = *((volatile UCHAR *)ASICSiuRegs.siums);
    ubModemStatus = pHWHead->MSR;

    if ( ubModemStatus & SERIAL_MSR_CTS ){

        *pModemStatus |= MS_CTS_ON;
    }

    if ( ubModemStatus & SERIAL_MSR_DSR ){
    
        *pModemStatus |= MS_DSR_ON;
    }

    if ( ubModemStatus & SERIAL_MSR_RI ){
    
        *pModemStatus |= MS_RING_ON;
    }

    if (!(REG16(VRGiuRegs.giupiod) & DCDINTR)) {
    
        *pModemStatus |= MS_RLSD_ON;
    }

    return;
}

// ***************************************************************
// @doc OEM
// @func  VOID | HWGetCommProperties | Retrieves Comm Properties.
// *
// @rdesc None.
// ***************************************************************
VOID
HWGetCommProperties(
    PVOID   pHead,      /* @parm PVOID returned by HWInit. */
    LPCOMMPROP  pCommProp   /* @parm Pointer to receive COMMPROP structure. */
    )
{
    PPERP_IO_SER_INFO pHWHead = (PPERP_IO_SER_INFO)pHead;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("Serial PDD: Enter HWGetCommProperties\r\n")));

    memcpy(pCommProp, &(pHWHead->CommProp), sizeof(COMMPROP));

    return;
}

// ***********************************************************************
// @doc OEM
// @func  VOID | HWPurgeComm | Purges comm device according to Win32 spec for
// * PURGE_TXABORT, PURGE_RXABORT, PURGE_TXCLEAR, PURGE_RXCLEAR (see
// * PurgeComm in the Win32 spec).
// *
// @rdesc None.
// ***********************************************************************
VOID
HWPurgeComm(
    PVOID   pHead,      /* @parm PVOID returned by HWInit. */
    DWORD   fdwAction       /* @parm Action to take. */
    )
{
    PPERP_IO_SER_INFO pHWHead = (PPERP_IO_SER_INFO)pHead;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("Serial PDD: Enter HWPurgeComm\r\n")));

    if (fdwAction & PURGE_TXABORT){

        DISABLE_BITS8(ASICSiuRegs.siuie, SERIAL_IER_THR);
    }
    
    // REVIEW THIS - I don't see how this could have terminated a pending read,
    // nor how RX interrupts would ever get turned back on.  I suspect that
    // RXABORT and TXABORT would both be better implemented inthe MDD.

//  if ( fdwAction & PURGE_RXABORT ) {
//      DISABLE_BITS8(ASICSiuRegs.siuie, SERIAL_IER_RDA );
//  }

    if ( fdwAction & PURGE_TXCLEAR ){

        ENABLE_BITS8(ASICSiuRegs.siuiid_fc, SERIAL_FCR_TXMT_RESET);

        REG8(ASICSiuRegs.siuiid_fc) = pHWHead->FCR;
    }

    if ( fdwAction & PURGE_RXCLEAR ){

        ENABLE_BITS8(ASICSiuRegs.siuiid_fc, SERIAL_FCR_RCVR_RESET);

        REG8(ASICSiuRegs.siuiid_fc) = pHWHead->FCR;
    }

    return;
}

// ****************************************************************
//
//  @doc OEM
//
//  @func BOOL  | HWSetDCB  | Set the Device Control Block
//
//  @parm PVOID | pHead     | PDD Device Context
//  @parm LPDCB | pDCB      | The device control block to set
//
//  @rdesc  Returns TRUE for success, FALSE for failure. If an error
//          occurs the caller can return the error using GetLastError()
//
//  @remark This function is called by the MDD after the user has called
//          the Win32 API SetCommState().
// *******************************************************************
BOOL
HWSetDCB(
    PVOID       pHead,
    LPDCB       pDCB
    )
{
    PPERP_IO_SER_INFO pHWHead = (PPERP_IO_SER_INFO)pHead;
    BOOL    RetVal   = TRUE;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("Serial PDD: Enter HWSetDCB\r\n")));

    EnterCriticalSection( &(pHWHead->CS));

    // 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( pHWHead->PortOpen ){
        // Note, fparity just says whether we should check
        // receive parity.  And the 16550 won't let us NOT
        // check parity if we generate it.  So this field
        // has no effect on the hardware.

        if( pDCB->BaudRate != pHWHead->dcb.BaudRate ){
        
            HWSetBaudRate( pHWHead, pDCB->BaudRate );
        }

        if( pDCB->ByteSize != pHWHead->dcb.ByteSize ){
        
            HWSetByteSize( pHWHead, pDCB->ByteSize );
        }

        if( pDCB->Parity != pHWHead->dcb.Parity ){
        
            HWSetParity( pHWHead, pDCB->Parity );
        }

        if( pDCB->StopBits != pHWHead->dcb.StopBits ){

            HWSetStopBits( pHWHead, pDCB->StopBits );
        }
    }

    // Now that we have done the right thing, store this DCB
    pHWHead->dcb = *pDCB;

    LeaveCriticalSection(&(pHWHead->CS));

    return RetVal;
}

// ****************************************************************
//
//  @doc OEM
//
//  @func BOOL | HWSetCommTimeouts | Set the communications timeouts
//
//  @parm PVOID | pHead | PDD device context (returned from HWInit())
//  @parm LPCOMMTIMEOUTS | lpCommTO | The CommTimeouts structure
//
//  @rdesc  Return TRUE if successful, FALSE if any error occurs.
//
//  @remark If the PDD needs to keep track of the CommTimeouts that
//          the user has specified then this should be stashed away
//          for later use.  In general it is recommended that PDD's
//          allow the MDD layer to manage the timeouts.
// *****************************************************************
BOOL
HWSetCommTimeouts(
    PVOID           pHead,
    LPCOMMTIMEOUTS  lpCommTO
    )
{

    DEBUGMSG(ZONE_FUNCTION, (TEXT("Serial PDD: Enter HWSetCommTimeouts\r\n")));

    return TRUE;
}

// **********************************************************************
//  @doc OEM
//  @func   BOOL | HWIoctl | Device IO control routine.
//  @parm DWORD | dwOpenData | value returned from COM_Open call
//  @parm DWORD | dwCode | io control code to be performed
//  @parm PBYTE | pBufIn | input data to the device
//  @parm DWORD | dwLenIn | number of bytes being passed in
//  @parm PBYTE | pBufOut | output data from the device
//  @parm DWORD | dwLenOut |maximum number of bytes to receive from device
//  @parm PDWORD | pdwActualOut | actual number of bytes received from device
//
//  @rdesc      Returns TRUE for success, FALSE for failure
//
//  @remark  The MDD will pass any unrecognized IOCTLs through to this function.
//************************************************************************
BOOL
HWIoctl(PVOID pHead,DWORD dwCode, PBYTE pBufIn, DWORD dwLenIn,
        PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut)
{
    BOOL RetVal = TRUE;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("Serial PDD: Enter HWIoctl\r\n")));

    switch (dwCode) {

        // Currently, no defined IOCTLs
        default:
            RetVal = FALSE;
            break;
    }

    return RetVal;
}

const
HW_VTBL PerpIoVTbl = {
    HWInit,
    HWDeinit,
    HWOpen,
    HWClose,
    HWGetBytes,
    HWGetRxStart,
    HWGetIntrType,
    HWClearOtherIntr,
    HWClearLineIntr,
    HWGetRxBufferSize,
    HWTxIntrHandler,
    HWPutBytes,
    HWPowerOff,
    HWPowerOn,
    HWClearDTR,
    HWSetDTR,
    HWClearRTS,
    HWSetRTS,
    HWEnableIR,
    HWDisableIR,
    HWClearBreak,
    HWSetBreak,
    HWXmitComChar,
    HWGetStatus,
    HWReset,
    HWGetModemStatus,
    HWGetCommProperties,
    HWPurgeComm,
    HWSetDCB,
    HWSetCommTimeouts,
    HWIoctl
    };

⌨️ 快捷键说明

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