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

📄 serial.c

📁 freescale i.mx31 BSP CE5.0全部源码
💻 C
📖 第 1 页 / 共 3 页
字号:
//------------------------------------------------------------------------------
//
//  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 + -