📄 serial.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: serial.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 BOOL BSPUartGetType( ULONG HWAddr, uartType_c * pType );
extern VOID BSPUartConfigTranceiver(ULONG HWAddr,BOOL bEnable);
extern BOOL BSPUartConfigureGPIO(ULONG HWAddr, BOOL bEnable);
extern UINT8 BSPSerGetChannelPriority();
extern BOOL BSPSerGetDMAIsEnabled(ULONG HWAddr);
extern BOOL BSPSerGetDMARequest(ULONG HWAddr, int* reqRx, int* reqTx);
extern VOID BSPGetDMABuffSize(UINT16* buffRx, UINT16 * buffTx);
//------------------------------------------------------------------------------
// External Variables
//------------------------------------------------------------------------------
// Defines
#define BAUD_TABLE_SIZE 23
//------------------------------------------------------------------------------
// Types
//------------------------------------------------------------------------------
// Global Variables
//------------------------------------------------------------------------------
// Local Variables
static const PAIRS BaudPairs[BAUD_TABLE_SIZE] = {
{50, 2307},
{75, 1538},
{110, 1049},
{135, 858},
{150, 769},
{300, 384},
{600, 192},
{1200, 96},
{1800, 64},
{2000, 58},
{2400, 48},
{3600, 32},
{4800, 24},
{7200, 16},
{9600, 12},
{12800, 9},
{14400, 8},
{19200, 6},
{23040, 5},
{28800, 4},
{38400, 3},
{57600, 2},
{115200, 1}
};
static const LOOKUP_TBL BaudTable = {BAUD_TABLE_SIZE, (PAIRS *) BaudPairs};
//------------------------------------------------------------------------------
// Local Functions
//------------------------------------------------------------------------------
//
// Function: MapDMABuffers
//
// Allocate and map DMA buffer
//
// Parameters:
// pSerHead[in] - hardware context
//
// Returns:
// Returns TRUE if successful, otherwise returns FALSE.
//
//------------------------------------------------------------------------------
BOOL MapDMABuffers(PSER_INFO pSerHead)
{
DMA_ADAPTER_OBJECT Adapter;
DEBUGMSG(ZONE_FUNCTION,(_T("Serial::MapDMABuffers+\r\n")));
pSerHead->pSerialVirtTxDMABufferAddr = NULL;
pSerHead->pSerialVirtRxDMABufferAddr = NULL;
memset(&Adapter, 0, sizeof(DMA_ADAPTER_OBJECT));
Adapter.InterfaceType = Internal;
Adapter.ObjectSize = sizeof(DMA_ADAPTER_OBJECT);
// Allocate a block of virtual memory (physically contiguous) for the Tx DMA buffers.
pSerHead->pSerialVirtTxDMABufferAddr = (PBYTE)HalAllocateCommonBuffer(&Adapter, ( pSerHead->txDMABufSize * SERIAL_MAX_DESC_COUNT_TX)
, &(pSerHead->SerialPhysTxDMABufferAddr), FALSE);
// Check if DMA buffer has been allocated
if (!(pSerHead->SerialPhysTxDMABufferAddr.LowPart) || !(pSerHead->pSerialVirtTxDMABufferAddr))
{
DEBUGMSG(ZONE_ERROR, (TEXT("Serial:MapDMABuffers() - Failed to allocate Tx DMA buffer.\r\n")));
return(FALSE);
}
// Allocate a block of virtual memory (physically contiguous) for the Rx DMA buffers.
pSerHead->pSerialVirtRxDMABufferAddr = (PBYTE)HalAllocateCommonBuffer(&Adapter, (pSerHead->rxDMABufSize * SERIAL_MAX_DESC_COUNT_RX)
, &(pSerHead->SerialPhysRxDMABufferAddr), FALSE);
// Check if DMA buffer has been allocated
if (!(pSerHead->SerialPhysRxDMABufferAddr.LowPart) || !(pSerHead->pSerialVirtRxDMABufferAddr))
{
DEBUGMSG(ZONE_ERROR, (TEXT("Serial:MapDMABuffers() - Failed to allocate Rx DMA buffer.\r\n")));
return(FALSE);
}
DEBUGMSG(ZONE_FUNCTION,(_T("Serial::MapDMABuffers-\r\n")));
return(TRUE);
}
//------------------------------------------------------------------------------
//
// Function: UnmapDMABuffers
//
// This function unmaps the DMA buffers previously mapped with the
// MapDMABuffers function.
//
// Parameters:
// pSerHead[in] - hardware context
//
// Returns:
// Returns TRUE if successful, otherwise returns FALSE.
//
//------------------------------------------------------------------------------
BOOL UnmapDMABuffers(PSER_INFO pSerHead)
{
PHYSICAL_ADDRESS phyAddr;
DEBUGMSG(ZONE_FUNCTION,(_T("Serial::UnmapDMABuffers+\r\n")));
if(pSerHead->pSerialVirtTxDMABufferAddr)
{
// Logical address parameter is ignored
phyAddr.QuadPart = 0;
HalFreeCommonBuffer(NULL, 0, phyAddr, (PVOID)(pSerHead->pSerialVirtTxDMABufferAddr), FALSE);
}
if(pSerHead->pSerialVirtRxDMABufferAddr)
{
// Logical address parameter is ignored
phyAddr.QuadPart = 0;
HalFreeCommonBuffer(NULL, 0, phyAddr, (PVOID)(pSerHead->pSerialVirtRxDMABufferAddr), FALSE);
}
pSerHead->pSerialVirtTxDMABufferAddr = NULL;
pSerHead->pSerialVirtRxDMABufferAddr = NULL;
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: DeinitChannelDMA
//
// This function deinitializes the DMA channel for output.
//
// Parameters:
// pSerHead[in] - hardware context
//
// Returns:
// Returns TRUE if successful, otherwise returns FALSE.
//
//------------------------------------------------------------------------------
BOOL DeinitChannelDMA(PSER_INFO pSerHead)
{
if (pSerHead->SerialDmaChanRx != 0)
{
DDKSdmaCloseChan(pSerHead->SerialDmaChanRx);
pSerHead->SerialDmaChanRx = 0;
}
if (pSerHead->SerialDmaChanTx != 0)
{
DDKSdmaCloseChan(pSerHead->SerialDmaChanTx);
pSerHead->SerialDmaChanTx = 0;
}
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: InitChannelDMA
//
// This function initializes the DMA channel for output.
//
// Parameters:
// pSerHead[in] - hardware context
//
// Returns:
// Returns TRUE if successful, otherwise returns FALSE.
//
//------------------------------------------------------------------------------
BOOL InitChannelDMA(PSER_INFO pSerHead)
{
BOOL rc = FALSE;
DEBUGMSG(ZONE_FUNCTION,(_T("Serial::InitChannelDMA+\r\n")));
// Open virtual DMA channels
pSerHead->SerialDmaChanRx = DDKSdmaOpenChan(pSerHead->SerialDmaReqRx, BSPSerGetChannelPriority(), NULL, pSerHead->irq);
DEBUGMSG(ZONE_FUNCTION,(_T("Channel Allocated(Rx) : %d\r\n"),pSerHead->SerialDmaChanRx));
if (!pSerHead->SerialDmaChanRx)
{
DEBUGMSG(ZONE_ERROR, (_T("ERROR:InitChannelDMA(Rx): SdmaOpenChan for input failed.\r\n")));
goto cleanUp;
}
// Allocate DMA chain buffer
if (!DDKSdmaAllocChain(pSerHead->SerialDmaChanRx, SERIAL_MAX_DESC_COUNT_RX))
{
DEBUGMSG(ZONE_ERROR, (_T("ERROR:InitChannelDMA(Rx): DDKSdmaAllocChain for input failed.\r\n")));
goto cleanUp;
}
// Open virtual DMA channels
pSerHead->SerialDmaChanTx = DDKSdmaOpenChan(pSerHead->SerialDmaReqTx, BSPSerGetChannelPriority(), NULL, pSerHead->irq );
DEBUGMSG(ZONE_FUNCTION,(_T("Channel Allocated(Tx) : %d\r\n"),pSerHead->SerialDmaChanTx));
if (!pSerHead->SerialDmaChanTx)
{
DEBUGMSG(ZONE_ERROR, (_T("ERROR:InitChannelDMA(Tx): SdmaOpenChan(Rx) for input failed.\r\n")));
goto cleanUp;
}
// Allocate DMA chain buffer
if (!DDKSdmaAllocChain(pSerHead->SerialDmaChanTx, SERIAL_MAX_DESC_COUNT_TX))
{
DEBUGMSG(ZONE_ERROR, (_T("ERROR:InitChannelDMA(Tx): DDKSdmaAllocChain for input failed.\r\n")));
goto cleanUp;
}
rc = TRUE;
cleanUp:
if (!rc)
{
DeinitChannelDMA(pSerHead);
}
DEBUGMSG(ZONE_FUNCTION,(_T("Serial::InitChannelDMA-\r\n")));
return rc;
}
//------------------------------------------------------------------------------
//
// Function: InitDMA
//
// Performs DMA channel intialization
//
// Parameters:
// pSerHead[in] - hardware context
//
// Returns:
// Returns TRUE if successful, otherwise returns FALSE.
//
//------------------------------------------------------------------------------
BOOL InitDMA(PSER_INFO pSerHead)
{
int reqRx, reqTx;
DEBUGMSG(ZONE_FUNCTION, (TEXT("CMX31Disk::InitDMA+\r\n")));
if (BSPSerGetDMARequest(pSerHead->dwIOBase, &reqRx, &reqTx) == FALSE)
{
DEBUGMSG(ZONE_ERROR, (TEXT("Serial:InitDMA() - Failed to map DMA request.\r\n")));
return FALSE;
}
pSerHead->SerialDmaReqRx = reqRx;
pSerHead->SerialDmaReqTx = reqTx;
pSerHead->awaitingTxDMACompBmp = 0;
// Map the DMA buffers into driver's virtual address space
if(!MapDMABuffers(pSerHead))
{
DEBUGMSG(ZONE_ERROR, (TEXT("Serial:InitDMA() - Failed to map DMA buffers.\r\n")));
return FALSE;
}
// Initialize the output DMA
if (!InitChannelDMA(pSerHead))
{
DEBUGMSG(ZONE_ERROR, (TEXT("Serial:InitDMA() - Failed to initialize output DMA.\r\n")));
UnmapDMABuffers(pSerHead);
return FALSE;
}
DEBUGMSG(ZONE_FUNCTION, (TEXT("Serial::InitDMA-\r\n")));
return TRUE ;
}
//------------------------------------------------------------------------------
//
// Function: DeInitDMA
//
// Performs DMA channel de-intialization
//
// Parameters:
// pSerHead[in] - hardware context
//
// Returns:
// Returns TRUE if successful, otherwise returns FALSE.
//
//------------------------------------------------------------------------------
BOOL DeInitDMA(PSER_INFO pSerHead)
{
if(!DeinitChannelDMA(pSerHead))
{
DEBUGMSG(ZONE_ERROR, (TEXT("Serial:DeinitChannelDMA() - Failed to deinitialize DMA.\r\n")));
return FALSE;
}
if(!UnmapDMABuffers(pSerHead))
{
DEBUGMSG(ZONE_ERROR, (TEXT("Serial:UnmapDMABuffers() - Failed to Unmap DMA buffers\r\n")));
return FALSE;
}
pSerHead->SerialDmaReqRx = 0;
pSerHead->SerialDmaReqTx = 0;
return TRUE ;
}
//-----------------------------------------------------------------------------
//
// Function: Ser_InternalMapRegisterAddresses
//
// This function retrieves the current
// properties of the communications device.
//
// Parameters:
// HWAddress
// [in] physical address of the hardware.
// Size
// [in] how much larger the address window is.
//
// Returns:
// This function returns the base virtual address
// that maps the base physical address for the range.
//
//-----------------------------------------------------------------------------
PUCHAR static Ser_InternalMapRegisterAddresses( ULONG HWAddress, ULONG Size )
{
PUCHAR ioPortBase = NULL;
ULONG inIoSpace = 1;
PHYSICAL_ADDRESS ioPhysicalBase = {HWAddress, 0};
DEBUGMSG(ZONE_FUNCTION, (TEXT("Ser_InternalMapRegisterAddresses : HalTranslateBusAddress\r\n")));
if (HalTranslateBusAddress(Isa, 0, ioPhysicalBase, &inIoSpace, &ioPhysicalBase)) {
if (!inIoSpace) {
if ((ioPortBase = (PUCHAR)MmMapIoSpace(ioPhysicalBase, Size, FALSE)) == NULL) {
DEBUGMSG(ZONE_ERROR, (TEXT("Error mapping I/O Ports\r\n")));
return (ioPortBase);
}
}
else {
ioPortBase = (PUCHAR)ioPhysicalBase.LowPart;
}
} else {
DEBUGMSG(ZONE_ERROR, (TEXT("Error translating I/O Ports.\r\n")));
return (ioPortBase);
}
DEBUGMSG(ZONE_FUNCTION, (TEXT("Ser_InternalMapRegisterAddresses : %d\r\n"), ioPortBase));
return (ioPortBase);
}
//-----------------------------------------------------------------------------
//
// Function: Ser_GetRegistryData
//
// This function takes the registry path provided
// to COM_Init and uses it to find this requested comm
// port's DeviceArrayIndex, the IOPort Base Address,
// and the interrupt number.
//
// Parameters:
// pSerHead
// [in] pointer to PSER_INFO structure.
// regKeyPath
// [in] the registry path passed in to COM_Init.
//
// Returns:
// TRUE if success. FALSE if failure.
//
//-----------------------------------------------------------------------------
static BOOL Ser_GetRegistryData( PSER_INFO pSerHead, LPCTSTR regKeyPath )
{
LONG regError;
HKEY hKey;
DWORD dwDataSize;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -