📄 serialhw.c
字号:
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//------------------------------------------------------------------------------
//
// Copyright (C) 2004, Motorola Inc. All Rights Reserved
//
//------------------------------------------------------------------------------
//
// Copyright (C) 2004, Freescale Semiconductor, Inc. All Rights Reserved
// THIS SOURCE CODE IS CONFIDENTIAL AND PROPRIETARY AND MAY NOT
// BE USED OR DISTRIBUTED WITHOUT THE WRITTEN PERMISSION OF
// Freescale Semiconductor, Inc.
//
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//
// File: serialhw.c
//
// This file implements the device specific functions for zeus serial device.
//
//------------------------------------------------------------------------------
#include <windows.h>
#include <types.h>
#include <memory.h>
#include <nkintr.h>
#include <serhw.h>
#include <memory.h>
#include <notify.h>
#include <devload.h>
#include <ceddk.h>
#include <windev.h>
#include "mxarm11.h"
#include "uart.h"
#include "serial.h"
//------------------------------------------------------------------------------
// External Functions
extern UCHAR BSPUartCalRFDIV( ULONG* pRefFreq );
extern BOOL BSPUartEnableClock(ULONG HWAddr, BOOL bEnable);
extern VOID BSPIrdaEnable();
extern VOID BSPIrdaSetMode(irMode_c mode);
extern BOOL BSPSerAcquireDMAReqGpr(ULONG HWAddr);
extern BOOL BSPSerRestoreDMAReqGpr(ULONG HWAddr);
//------------------------------------------------------------------------------
// External Variables
//------------------------------------------------------------------------------
// Defines
//------------------------------------------------------------------------------
// Types
//------------------------------------------------------------------------------
// Global Variables
//------------------------------------------------------------------------------
// Local Variables
//------------------------------------------------------------------------------
// Local Functions
//-----------------------------------------------------------------------------
//
// Function: SL_CalculateRFDIV
//
// This function is used to calculate RFDIV setting.
//
// Parameters:
// pRefFreq
// [in/out] Pointer to reference frequency
//
// Returns:
// RFDIV setting.
//
//-----------------------------------------------------------------------------
UCHAR SL_CalculateRFDIV( ULONG* pRefFreq )
{
UCHAR RFDIV=0;
RFDIV = BSPUartCalRFDIV(pRefFreq);
if (RFDIV <= 6)
RFDIV = 6-RFDIV;
else
RFDIV = 6;
return RFDIV;
}
//-----------------------------------------------------------------------------
//
// Function: SL_ReadModemStatus
//
// This function is used to read the modem status.
//
// Parameters:
// pContext
// [in] Pointer to device head.
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
VOID SL_ReadModemStatus( PVOID pContext )
{
PUART_INFO pHWHead = (PUART_INFO)pContext;
ULONG Events = 0;
DEBUGMSG(ZONE_FUNCTION,(TEXT("SL_ReadModemStatus+\r\n")));
EnterCriticalSection(&(pHWHead->RegCritSec));
try {
// Save the value in a shadow
pHWHead->sUSR1 = INREG32(&pHWHead->pUartReg->USR1);
pHWHead->sUSR2 = INREG32(&pHWHead->pUartReg->USR2);
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
pHWHead->sUSR1 = 0;
pHWHead->sUSR2 = 0;
}
LeaveCriticalSection(&(pHWHead->RegCritSec));
// For changes, we use callback to evaluate the event
// CTS(RTS) status change
if (pHWHead->sUSR1 & CSP_BITFVAL(UART_USR1_RTSD,UART_USR1_RTSD_SET)) {
OUTREG32(&(pHWHead->pUartReg->USR1), CSP_BITFVAL(UART_USR1_RTSD, UART_USR1_RTSD_SET));
DEBUGMSG(ZONE_FUNCTION,(TEXT("EV_CTS\r\n")));
Events |= EV_CTS;
}
// DSR(DTR) status change
if (pHWHead->sUSR1 & CSP_BITFVAL(UART_USR1_DTRD,UART_USR1_DTRD_SET)) {
OUTREG32(&(pHWHead->pUartReg->USR1),CSP_BITFVAL(UART_USR1_DTRD, UART_USR1_DTRD_SET));
DEBUGMSG(ZONE_FUNCTION,(TEXT("EV_DSR\r\n")));
if (pHWHead->sUSR2 & CSP_BITFVAL(UART_USR2_DTRF, UART_USR2_DTRF_SET))
{
pHWHead->bDSR = TRUE;
OUTREG32(&(pHWHead->pUartReg->USR2), CSP_BITFVAL(UART_USR2_DTRF, UART_USR2_DTRF_SET));
}
else {
// pHWHead->bDSR = FALSE;
}
Events |= EV_DSR;
}
// RI status change (always 0 as DCE)
if (pHWHead->sUSR2 & CSP_BITFVAL(UART_USR2_RIDELT,UART_USR2_RIDELT_SET)) {
OUTREG32(&(pHWHead->pUartReg->USR2),CSP_BITFVAL(UART_USR2_RIDELT, UART_USR2_RIDELT_SET));
DEBUGMSG(ZONE_FUNCTION,(TEXT("EV_RING\r\n")));
Events |= EV_RING;
}
// DCD status change (always 0 as DCE)
if (pHWHead->sUSR2 & CSP_BITFVAL(UART_USR2_DCDDELT,UART_USR2_DCDDELT_SET)) {
OUTREG32(&(pHWHead->pUartReg->USR2),CSP_BITFVAL(UART_USR2_DCDDELT, UART_USR2_DCDDELT_SET));
DEBUGMSG(ZONE_FUNCTION,(TEXT("EV_RLSD\r\n")));
Events |= EV_RLSD;
}
if (Events) {
pHWHead->EventCallback(pHWHead->pMDDContext, Events);
}
DEBUGMSG(ZONE_FUNCTION,(TEXT("SL_ReadModemStatus-\r\n")));
return;
}
//-----------------------------------------------------------------------------
//
// Function: SL_ReadLineStatus
//
// This function is used to read the line status.
//
// Parameters:
// pContext
// [in] Pointer to device head.
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
VOID SL_ReadLineStatus( PVOID pContext )
{
PUART_INFO pHWHead = (PUART_INFO)pContext;
ULONG LineEvents = 0;
DEBUGMSG(ZONE_FUNCTION,(TEXT("SL_ReadLineStatus+\r\n")));
EnterCriticalSection(&(pHWHead->RegCritSec));
try {
//Keep the value in a shadow
pHWHead->sUSR1 = INREG32(&pHWHead->pUartReg->USR1);
pHWHead->sUSR2 = INREG32(&pHWHead->pUartReg->USR2);
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
pHWHead->sUSR1 = 0;
pHWHead->sUSR2 = 0;
}
LeaveCriticalSection(&(pHWHead->RegCritSec));
if (pHWHead->sUSR1 & CSP_BITFVAL(UART_USR1_FRAMERR, UART_USR1_FRAMERR_SET)) {
DEBUGMSG(ZONE_ERROR, (TEXT("Error frame\r\n")));
//Clear interrupt;
OUTREG32(&(pHWHead->pUartReg->USR1),CSP_BITFVAL(UART_USR1_FRAMERR, UART_USR1_FRAMERR_SET));
pHWHead->CommErrors |= CE_FRAME;
LineEvents |= EV_ERR;
}
if (pHWHead->sUSR1 & CSP_BITFVAL(UART_USR1_PARITYERR, UART_USR1_PARITYERR_SET)) {
DEBUGMSG(ZONE_ERROR, (TEXT("Error parity\r\n")));
//Clear interrupt;
OUTREG32(&(pHWHead->pUartReg->USR1),CSP_BITFVAL(UART_USR1_PARITYERR, UART_USR1_PARITYERR_SET));
pHWHead->CommErrors |= CE_RXPARITY;
LineEvents |= EV_ERR;
}
if (pHWHead->sUSR2 & CSP_BITFVAL(UART_USR2_ORE, UART_USR2_ORE_SET)) {
DEBUGMSG(ZONE_ERROR, (TEXT("Error Overrun\r\n")));
//Clear interrupt;
OUTREG32(&(pHWHead->pUartReg->USR2),CSP_BITFVAL(UART_USR2_ORE, UART_USR2_ORE_SET));
pHWHead->DroppedBytes++;
pHWHead->CommErrors |= CE_OVERRUN;
LineEvents |= EV_ERR;
}
if (pHWHead->sUSR2 & CSP_BITFVAL(UART_USR2_BRCD, UART_USR2_BRCD_SET)) {
DEBUGMSG(ZONE_ERROR, (TEXT("Error Break detect!!!\r\n")));
//Clear interrupt;
OUTREG32(&(pHWHead->pUartReg->USR2),CSP_BITFVAL(UART_USR2_BRCD, UART_USR2_BRCD_SET));
LineEvents |= EV_BREAK;
}
// Let WaitCommEvent know about this error
if (LineEvents) {
pHWHead->EventCallback(pHWHead->pMDDContext, LineEvents);
}
DEBUGMSG(ZONE_FUNCTION,(TEXT("SL_ReadLineStatus-\r\n")));
return;
}
//-----------------------------------------------------------------------------
//
// Function: SL_SetOutputMode
//
// This function sets the serial device mode (IR/non-IR).
//
// Parameters:
// pContext
// [in] Pointer to device head.
// UseIR
// [in] Should we use IR interface.
// Use9Pin
// [in] Should we use Wire interface.
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
VOID SL_SetOutputMode( PVOID pContext, BOOL UseIR, BOOL Use9Pin )
{
PUART_INFO pHWHead = (PUART_INFO)pContext;
EnterCriticalSection(&(pHWHead->RegCritSec));
try {
// If you support IR, here you need to set the interface to either IR mode
// or normal serial. Note that it is possible for both BOOLs to
// be false (i.e. power down), but never for both to be TRUE.
if (UseIR) {
//Enable IR interface;
INSREG32BF(&pHWHead->pUartReg->UCR1, UART_UCR1_IREN, UART_UCR1_IREN_ENABLE);
//Set IrDA reception to active low;
OUTREG32( &(pHWHead->pUartReg->UCR4), INREG32(&(pHWHead->pUartReg->UCR4))&~CSP_BITFMASK(UART_UCR4_INVR) );
//Set IrDA transmission to active low;
OUTREG32( &pHWHead->pUartReg->UCR3, INREG32(&pHWHead->pUartReg->UCR3)&~CSP_BITFMASK(UART_UCR3_INVT) );
}
else {
//Disable IR interface;
OUTREG32( &pHWHead->pUartReg->UCR1, INREG32(&pHWHead->pUartReg->UCR1)&~CSP_BITFMASK(UART_UCR1_IREN) );
}
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
}
LeaveCriticalSection(&(pHWHead->RegCritSec));
return;
}
//-----------------------------------------------------------------------------
//
// Function: SL_ClearPendingInts
//
// This function is used to clear any pending
// interrupts. It is called from Init and PostInit
// to make sure we start out in a known state.
//
// Parameters:
// pContext
// [in] Pointer to device head.
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
VOID SL_ClearPendingInts( PVOID pContext )
{
PUART_INFO pHWHead = (PUART_INFO)pContext;
DEBUGMSG(ZONE_FUNCTION,(TEXT("SL_ClearPendingInts+\r\n")));
EnterCriticalSection(&(pHWHead->RegCritSec));
try {
//USR1
OUTREG32(&pHWHead->pUartReg->USR1,CSP_BITFVAL(UART_USR1_PARITYERR, UART_USR1_PARITYERR_SET) |
CSP_BITFVAL(UART_USR1_RTSD, UART_USR1_RTSD_SET) |
CSP_BITFVAL(UART_USR1_ESCF, UART_USR1_ESCF_SET) |
CSP_BITFVAL(UART_USR1_FRAMERR, UART_USR1_FRAMERR_SET) |
CSP_BITFVAL(UART_USR1_AGTIM, UART_USR1_AGTIM_SET) |
CSP_BITFVAL(UART_USR1_DTRD, UART_USR1_DTRD_SET) |
CSP_BITFVAL(UART_USR1_AIRINT, UART_USR1_AIRINT_SET) |
CSP_BITFVAL(UART_USR1_AWAKE, UART_USR1_AWAKE_SET));
//USR2
OUTREG32(&pHWHead->pUartReg->USR2,CSP_BITFVAL(UART_USR2_ADET, UART_USR2_ADET_SET) |
CSP_BITFVAL(UART_USR2_DTRF, UART_USR2_DTRF_SET) |
CSP_BITFVAL(UART_USR2_IDLE,UART_USR2_IDLE_SET) |
CSP_BITFVAL(UART_USR2_ACST, UART_USR2_IDLE_SET) |
CSP_BITFVAL(UART_USR2_RIDELT, UART_USR2_RIDELT_SET) |
CSP_BITFVAL(UART_USR2_IRINT, UART_USR2_IRINT_SET) |
CSP_BITFVAL(UART_USR2_WAKE, UART_USR2_WAKE_SET) |
CSP_BITFVAL(UART_USR2_DCDDELT, UART_USR2_DCDDELT_SET) |
CSP_BITFVAL(UART_USR2_RTSF, UART_USR2_RTSF_SET) |
CSP_BITFVAL(UART_USR2_BRCD, UART_USR2_BRCD_SET) |
CSP_BITFVAL(UART_USR2_ORE, UART_USR2_ORE_SET));
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
}
LeaveCriticalSection(&(pHWHead->RegCritSec));
DEBUGMSG(ZONE_FUNCTION,(TEXT("SL_ClearPendingInts-\r\n")));
}
//-----------------------------------------------------------------------------
//
// Function: SL_SetStopBits
//
// This routine sets the Stop Bits for the device.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -