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

📄 uartser.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 C
📖 第 1 页 / 共 4 页
字号:
             // in the UART itself.  Just set to 0 for now since the
             // MDD doesn't take care of this.
            pHWHead->Status.cbInQue  = 0;
            pHWHead->Status.cbOutQue = 0;

            memcpy(lpStat, &(pHWHead->Status), sizeof(COMSTAT));
        }
        except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
                EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
            RetVal = (ULONG)-1;
        }        
    }
    else
        RetVal = (ULONG)-1;

    DEBUGMSG (ZONE_FUNCTION,
              (TEXT("-HW_SA1100GetStatus 0x%X\r\n"), pHead));
    return RetVal;
}

//
// @doc OEM
// @func    ULONG | HW_SA1100Reset | Perform any operations associated
//   with a device reset
//
// @rdesc   None.
//
VOID
HW_SA1100Reset(
    PVOID   pHead   // @parm PVOID returned by HWInit.
    )
{
    PSER_HW_INFO pHWHead = (PSER_HW_INFO)pHead;

//RETAILMSG(1,(TEXT("+HW_SA1100Reset 0x%X\r\n"), pHead));
    DEBUGMSG (ZONE_FUNCTION,(TEXT("+HW_SA1100Reset 0x%X\r\n"), pHead));

    memset(&pHWHead->Status, 0, sizeof(COMSTAT));
    try {
        HW_EnableTxRx(pHWHead);
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
    }
    
    DEBUGMSG (ZONE_FUNCTION,(TEXT("-HW_SA1100Reset 0x%X\r\n"), pHead));
//SA_DumpSerialRegisters(pHWHead);
}

void HW_SA1100ICPEnableUart(PVOID pHead,BOOL EnableUart)                // Hardware Head
{
    PSER_HW_INFO   pHWHead  = (PSER_HW_INFO)pHead;

//RETAILMSG(1,(TEXT("\t**** +HW_SA1100ICPEnableUart ******\r\n")));
    IOW_REG_FIELD (struct  utcr4Bits, &pHWHead->pUART->utcr4, lpm, 0);
    IOW_REG_FIELD (struct  utcr4Bits, &pHWHead->pUART->utcr4, hse, (EnableUart ? 0 : 1));
    pHWHead->bIr=!EnableUart;
}

void HW_SA1100EnableICPTxd(PSER_HW_INFO pHWHead,BOOL enable)
{
    IOW_REG_FIELD (struct  utcr3Bits, &pHWHead->pUART->utcr3, txe, (enable ? 1 : 0));
//SA_DumpSerialRegisters(pHWHead);
}
//
// @doc OEM
// @func    VOID | HW_SA1100PurgeComm | Purge RX and/or TX
// 
// @rdesc   None.
//

VOID
HW_SA1100PurgeComm(
    PVOID   pHead,      // @parm PVOID returned by HWInit.
    DWORD   fdwAction       // @parm Action to take. 
    )
{
    PSER_HW_INFO pHWHead = (PSER_HW_INFO)pHead;

//RETAILMSG(1,(TEXT("+HW_SA1100PurgeComm 0x%X\r\n"), pHead));
    DEBUGMSG (ZONE_FUNCTION,(TEXT("+HW_SA1100PurgeComm 0x%X\r\n"), pHead));
    try {
            // nor how RX interrupts would ever get turned back on.  I suspect that
            // RXABORT and TXABORT would both be better implemented in the MDD.
        if (fdwAction & PURGE_RXABORT) {
            IOW_REG_FIELD (struct  utcr3Bits, &pHWHead->pUART->utcr3, rie, 0);
        }    
        if (fdwAction & PURGE_TXCLEAR) {
                // Write the TX reset bit.  It is self clearing
            IOW_REG_FIELD (struct  utcr3Bits, &pHWHead->pUART->utcr3, txe, 0);
        }
        if (fdwAction & PURGE_RXCLEAR) {
                // Write the RX reset bit.  It is self clearing
            IOW_REG_FIELD (struct  utcr3Bits, &pHWHead->pUART->utcr3, rxe, 0);
        }
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
    }
    HW_EnableTxRx(pHWHead);
    DEBUGMSG (ZONE_FUNCTION,(TEXT("-HW_SA1100PurgeComm 0x%X\r\n"), pHead));
//SA_DumpSerialRegisters(pHWHead);
}

//
// @doc OEM
// @func    BOOL | HW_SA1100XmitComChar | Transmit a char immediately
// 
// @rdesc   TRUE if succesful
//
BOOL
HW_SA1100XmitComChar(
    PVOID   pHead,    // @parm PVOID returned by HWInit.
    UCHAR   ComChar   // @parm Character to transmit. 
    )
{
    PSER_HW_INFO pHWHead = (PSER_HW_INFO)pHead;
    
//RETAILMSG(1,(TEXT("+HW_SA1100XmitComChar 0x%X\r\n"), pHead));
    DEBUGMSG (ZONE_FUNCTION,(TEXT("+HW_SA1100XmitComChar 0x%X\r\n"), pHead));

     // Get critical section, then transmit when buffer empties
    DEBUGMSG (ZONE_WRITE, (TEXT("XmitComChar wait for CritSec %x.\r\n"),&(pHWHead->TransmitCritSec)));
    EnterCriticalSection(&(pHWHead->TransmitCritSec));
    DEBUGMSG (ZONE_WRITE, (TEXT("XmitComChar got CritSec %x.\r\n"),&(pHWHead->TransmitCritSec)));
    try {
        while(TRUE) { // We know THR will eventually empty
             // Write the character if we can
            SA_ReadSR1(pHWHead);
            if(pHWHead->pUART->utsr1.tnf) {
            
    // pHWHead->pUART->utdr.data=ComChar;
    IOW_REG_FIELD (struct  utdrBits, &pHWHead->pUART->utdr, data, ComChar);
                DEBUGMSG (ZONE_WRITE, (TEXT("XmitComChar wrote x%X\r\n"),ComChar));
                break;
            }

                // If we couldn't write the data yet, then wait for a
                // TXINTR to come in and try it again.
            
                // Enable xmit intr.
           IOW_REG_FIELD (struct  utcr3Bits, & pHWHead->pUART->utcr3, tie, 1);
                 // Wait until the txintr has signalled.
            DEBUGMSG (ZONE_WRITE, (TEXT("XmitComChar WaitIntr x%X\r\n"),pHWHead->FlushDone));
//RETAILMSG(1,(TEXT("+HW_SA1100XmitComChar Waiting for TxReadyr\n")));
           WaitForSingleObject(pHWHead->FlushDone, (ULONG)1000);
//RETAILMSG(1,(TEXT("+HW_SA1100XmitComChar Awoke on TxReadyr\n")));
        }
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
    }
    
    LeaveCriticalSection(&(pHWHead->TransmitCritSec));
    DEBUGMSG (ZONE_WRITE, (TEXT("XmitComChar released CritSec %x.\r\n"),
                           &(pHWHead->TransmitCritSec)));
    DEBUGMSG (ZONE_FUNCTION,
              (TEXT("-HW_SA1100XmitComChar 0x%X\r\n"), pHead));
//SA_DumpSerialRegisters(pHWHead);
    return TRUE;
}

//
// @doc OEM
// @func    BOOL | HW_SA1100PowerOff | Perform powerdown sequence.
//
VOID
HW_SA1100PowerOff(
    PVOID   pHead       // @parm    PVOID returned by HWInit.
    )
{
    PSER_HW_INFO pHWHead = (PSER_HW_INFO)pHead;
/*
    pHWHead->uartPowerRegs.utcr0=pHWHead->pUART->utcr0;
    pHWHead->uartPowerRegs.utcr3=pHWHead->pUART->utcr3;
    if (pHWHead->bIr) {
      pHWHead->uartPowerRegs.utcr4=pHWHead->pUART->utcr4;       // ICP device only
    }
*/
    pHWHead->PowerDownFlag=TRUE;
}

//
// @doc OEM
// @func    BOOL | HW_SA1100PowerOn | Perform poweron sequence.
// 
VOID
HW_SA1100PowerOn(
    PVOID   pHead       // @parm    PVOID returned by HWInit.
    )
{
    PSER_HW_INFO pHWHead = (PSER_HW_INFO)pHead;
/*
    if (pHWHead->PowerDownFlag==TRUE) {
        pHWHead->PowerDownFlag=FALSE;
        pHWHead->pUART->utcr0=pHWHead->uartPowerRegs.utcr0;
        pHWHead->pUART->utcr3=pHWHead->uartPowerRegs.utcr3;
        if (pHWHead->bIr) {
            pHWHead->pUART->utcr4=pHWHead->uartPowerRegs.utcr4;     // ICP device only
        }
    }
//RETAILMSG(1,(TEXT("+HW_SA1100PowerOn 0x%X\r\n"), pHead));

    // And we didn't save the Divisor Reg, so set baud rate
    // But don't call HW_SA1100SetBaud, since it does DebugMsg.
    // Call our internal function instead.
    SA_SetBaudRate(pHWHead,pHWHead->dcb.BaudRate);
*/
}

//
// @doc OEM
// @func    BOOL | HW_SA1100SetDCB | Sets new values for DCB.  This
// routine gets a DCB from the MDD.  It must then compare
// this to the current DCB, and if any fields have changed take
// appropriate action.
// 
// @rdesc   ULONG
//
BOOL
HW_SA1100SetDCB(
    PVOID   pHead,      // @parm    PVOID returned by HWInit.
    LPDCB   lpDCB       // @parm    Pointer to DCB structure
    )
{
    PSER_HW_INFO pHWHead = (PSER_HW_INFO)pHead;
    BOOL retval = TRUE;
    
//RETAILMSG(1,(TEXT("+HW_SA1100SetDCB 0x%X\r\n"), pHead));
    DEBUGMSG (ZONE_FUNCTION,(TEXT("+HW_SA1100SetDCB 0x%X\r\n"), pHead));

         // 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->OpenCount) {
        if( lpDCB->BaudRate != pHWHead->dcb.BaudRate ) {
            HW_SA1100SetBaudRate( pHWHead, lpDCB->BaudRate );
//RETAILMSG(1,(TEXT("+HW_SA1100SetDCB BaudRate\r\n")));
        }
        if( lpDCB->ByteSize != pHWHead->dcb.ByteSize ) {
//RETAILMSG(1,(TEXT("+HW_SA1100SetDCB ByteSize\r\n")));
            HW_SA1100SetByteSize( pHWHead, lpDCB->ByteSize );
        }
        if( lpDCB->Parity != pHWHead->dcb.Parity ) {
//RETAILMSG(1,(TEXT("+HW_SA1100SetDCB Parity\r\n")));
            HW_SA1100SetParity( pHWHead, lpDCB->Parity );
        }
        if( lpDCB->StopBits != pHWHead->dcb.StopBits ) {
//RETAILMSG(1,(TEXT("+HW_SA1100SetDCB StopBits\r\n")));
            HW_SA1100SetStopBits( pHWHead, lpDCB->StopBits );
        }
         // Don't worry about fOutxCtsFlow.  It is a flag which
         // will be examined every time we load the TX buffer.
         // No special action required here.
    }
        // Now that we have done the right thing, store this DCB
    pHWHead->dcb = *lpDCB;
    DEBUGMSG (ZONE_FUNCTION,(TEXT("-HW_SA1100SetDCB 0x%X\r\n"), pHead));
//SA_DumpSerialRegisters(pHWHead);
    return retval;
}

//
// @doc OEM
// @func    BOOL | HW_SA1100SetCommTimeouts | Sets new values for the
// CommTimeouts structure. routine gets a DCB from the MDD.  It
// must then compare this to the current DCB, and if any fields
// have changed take appropriate action.
// 
// @rdesc   ULONG
//
ULONG HW_SA1100SetCommTimeouts(
    PVOID   pHead,      // @parm    PVOID returned by HWInit.
    LPCOMMTIMEOUTS   lpCommTimeouts // @parm Pointer to CommTimeout structure
    )
{
    PSER_HW_INFO pHWHead = (PSER_HW_INFO)pHead;
    ULONG retval = 0;
    
//RETAILMSG(1,(TEXT("+HW_SA1100SetCommTimeouts 0x%X\r\n"), pHead));
    DEBUGMSG (ZONE_FUNCTION,(TEXT("+HW_SA1100SetCommTimeout 0x%X\r\n"), pHead));
         // OK, first check for any changes and act upon them
    if( lpCommTimeouts->WriteTotalTimeoutMultiplier !=
        pHWHead->CommTimeouts.WriteTotalTimeoutMultiplier ) {
    }
         // Now that we have done the right thing, store this DCB
    pHWHead->CommTimeouts = *lpCommTimeouts;
    DEBUGMSG (ZONE_FUNCTION,(TEXT("-HW_SA1100SetCommTimeout 0x%X\r\n"), pHead));
    return retval;
}

//
//  @doc OEM
//  @func   BOOL | HW_SA1100Ioctl | 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
HW_SA1100Ioctl(PVOID pHead, DWORD dwCode,PBYTE pBufIn,DWORD dwLenIn,
              PBYTE pBufOut,DWORD dwLenOut,PDWORD pdwActualOut)
{
    BOOL RetVal = TRUE;
//RETAILMSG(1,(TEXT("+HW_SA1100Ioctl 0x%X\r\n"), pHead));
    DEBUGMSG (ZONE_FUNCTION, (TEXT("+HW_SA1100Ioctl 0x%X\r\n"), pHead));
    switch (dwCode) {
            // Currently, no defined IOCTLs
        default:
            RetVal = FALSE;
            DEBUGMSG (ZONE_FUNCTION, (TEXT(" Unsupported ioctl 0x%X\r\n"), dwCode));
            break;            
    }
    DEBUGMSG (ZONE_FUNCTION, (TEXT("-HW_SA1100Ioctl 0x%X\r\n"), pHead));
    return RetVal;
}
BOOL
HW_SA1100TransmitterBusy(
    PVOID  pHead
    )
{
    PSER_HW_INFO   pHWHead   = (PSER_HW_INFO)pHead;
    
    try {
        return (!(pHWHead->pUART->utsr0.tfs) || (pHWHead->pUART->utsr1.tby) || (!(pHWHead->pUART->utsr1.tnf)));
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
    }
	return TRUE;  // Busy,If fail
}

⌨️ 快捷键说明

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