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

📄 ccser_pdd.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 C
📖 第 1 页 / 共 2 页
字号:
/*

  Copyright(c) 1998,1999 SIC/Hitachi,Ltd.

	Module Name:

		CCSer_pdd.c

	Revision History:

		26th April 1999		Released

*/
#include <windows.h>
#include <types.h>
#include <memory.h>
#include <serhw.h>
#include <ser16550.h>
#include <hw16550.h>
#include <serdbg.h>
#include <nkintr.h>

#include "ser_pdd.h"

//#include "mobytel.h"
#include "cc.h"
//#include "shx.h"
#include "macros.h"
extern DWORD dwHD64465Base;
// #define DBGMSG
#define DBGMSG NKDbgPrintfW

#define BAUD_TABLE_SIZE 23
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};
/*
UCHAR READ_PORT_UCHAR(PUCHAR port)
{
    UCHAR	bTemp;

    bTemp =(UCHAR) *(volatile unsigned short *)port;
    return bTemp;
}

VOID WRITE_PORT_UCHAR(PUCHAR port, UCHAR value)
{
//  DEBUGMSG (DBG_PORT_ACCESS, (TEXT("Setting Port @ 0x%X to 0x%X\r\n"), port, value));
    *(volatile unsigned short *)port = (unsigned short)value;
}
*/

// Miscellaneous internal routines.
PUCHAR
static
CCSer_InternalMapRegisterAddresses(
    ULONG   HWAddress,
    ULONG   Size
    )
{
	PUCHAR	ioPortBase; 

    DEBUGMSG(ZONE_FUNCTION, 
             (TEXT("+CCSer_InternalMapRegisterAddresses: adr=0x%x len=0x%x\r\n"),
			 HWAddress, Size));

	ioPortBase = VirtualAlloc(0, Size, MEM_RESERVE, PAGE_NOACCESS);
	if ( ioPortBase == NULL )
	{
		ERRORMSG(1, (TEXT("CCSer_InternalMapRegisterAddresses: VirtualAlloc failed!\r\n")));
	}
	else if ( !VirtualCopy((PVOID)ioPortBase, (PVOID)HWAddress, Size, PAGE_READWRITE|PAGE_NOCACHE) )
	{
		ERRORMSG(1, (TEXT("CCSer_InternalMapRegisterAddresses: VirtualCopy failed!\r\n")));
		VirtualFree( (PVOID)ioPortBase, 0, MEM_RELEASE );
		ioPortBase = 0;
	}

    DEBUGMSG(ZONE_FUNCTION, 
             (TEXT("-CCSer_InternalMapRegisterAddresses: mapped at 0x%x\r\n"),
              ioPortBase ));

    return ioPortBase;
}

static
BOOL
CCSerSetIRBaudRate(
    PSER_INFO   pHWHead,
    ULONG baud     // @parm     UINT16 what is the baud rate
    )
{
    DEBUGMSG (ZONE_INIT, (TEXT("Serial set IR Baud %d\r\n"),
                          baud));
        
    return TRUE;
}

/*
 *  NOTE : The caller should have set pHWHead->fIRMode.  It is not
 * set here, since power on/off may need to temporarily disable
 * the intefaces without actually overwriting the current recorded
 * mode.
 */
static
void
CCSerSetOutputMode(
    PSER_INFO   pHWHead,
    BOOL UseIR,     // @parm     BOOL Should we use IR interface
    BOOL Use9Pin    // @parm     BOOL Should we use Wire interface
    )
{
     // TODO - 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.
}

/*
 @doc OEM 
 @func PVOID | CCSerInit | Initializes device identified by argument.
 *  This routine sets information controlled by the user
 *  such as Line control and baud rate. It can also initialize events and
 *  interrupts, thereby indirectly managing initializing hardware buffers.
 *  Exported only to driver, called only once per process.
 *
 @rdesc The return value is a PVOID to be passed back into the HW
 dependent layer when HW functions are called.
 */
static
PVOID
CCSerInit(
    ULONG   Identifier,	// @parm Device identifier.
    PVOID	pMddHead	// @parm First argument to mdd callbacks.
    )
{
    PSER_INFO   pHWHead;
	// Note on defaults.  While the PC typcially considers COM1 to be at 
	// 3F8, irq4 and COM2 to be 2F8, irq3, NKPC uses COM1 internally for the
	// debugger.  So, when NK tells me to start "COM1" it really means the
	// first one that's available, which is what the PC calls COM2.  Confused?
	// The end result is that COM1 on NK is what the PC considers to be COM2.
	// But wait, there's more.  On a Puzzle, the debugger is on COM2 and the
	// COM1 for NK is ACTUALLY COM1.  So PCs need 2F8 for their port base
	// and Puzzles need 3F8.
	const UINT cDefaultCom1PortBase = 0x2F8;
	const UINT cDefaultComPortRange = 8;

     // Allocate for our main data structure and one of it's fields.
    pHWHead = (PSER_INFO)LocalAlloc( LMEM_ZEROINIT|LMEM_FIXED ,
                                         sizeof(SER_INFO) );
	if (!pHWHead)
		goto ALLOCFAILED;
     // This call will map the address space for the 16550 UART.  
    pHWHead->pBaseAddress   = CCSer_InternalMapRegisterAddresses(
        (dwHD64465Base + HD64465_UART_OFFSET), 0x400);
    
    pHWHead->pMddHead	  = pMddHead;

    pHWHead->cOpenCount   = 0;

     // Set up our Comm Properties data    
    pHWHead->CommProp.wPacketLength       = 0xffff;
    pHWHead->CommProp.wPacketVersion     = 0xffff;
    pHWHead->CommProp.dwServiceMask      = SP_SERIALCOMM;
    pHWHead->CommProp.dwReserved1	      = 0;
    pHWHead->CommProp.dwMaxTxQueue	      = 16;
    pHWHead->CommProp.dwMaxRxQueue	      = 16;
    pHWHead->CommProp.dwMaxBaud	      = BAUD_115200;
    pHWHead->CommProp.dwProvSubType      = PST_RS232;
    pHWHead->CommProp.dwProvCapabilities =
        PCF_DTRDSR | PCF_RLSD | PCF_RTSCTS |
        PCF_SETXCHAR |
        PCF_INTTIMEOUTS |
        PCF_PARITY_CHECK |
        PCF_SPECIALCHARS |
        PCF_TOTALTIMEOUTS |
        PCF_XONXOFF;
    pHWHead->CommProp.dwSettableBaud      =
		BAUD_075 | BAUD_110 | BAUD_150 | BAUD_300 | BAUD_600 |
		BAUD_1200 | BAUD_1800 |	BAUD_2400 | BAUD_4800 |
		BAUD_7200 | BAUD_9600 | BAUD_14400 |
		BAUD_19200 | BAUD_38400 | BAUD_56K | BAUD_128K |
		BAUD_115200 | BAUD_57600 | BAUD_USER;
    pHWHead->CommProp.dwSettableParams    =
        SP_BAUD | SP_DATABITS | SP_HANDSHAKING | SP_PARITY |
        SP_PARITY_CHECK | SP_RLSD | SP_STOPBITS;
    pHWHead->CommProp.wSettableData       =
        DATABITS_5 | DATABITS_6 | DATABITS_7 | DATABITS_8;
    pHWHead->CommProp.wSettableStopParity =
        STOPBITS_10 | STOPBITS_20 |
        PARITY_NONE | PARITY_ODD | PARITY_EVEN | PARITY_SPACE |
        PARITY_MARK;

     // Init 16550 info, register stride is 1 
    DEBUGMSG (ZONE_INIT, (TEXT("CCSerInit - Init 16550 data\r\n")));
    SL_Init( pHWHead, pHWHead->pBaseAddress, CC_16550_REG_STRIDE,
             EvaluateEventFlag, pMddHead, (PLOOKUP_TBL)&BaudTable);

    DEBUGMSG (ZONE_INIT,
              (TEXT("CCSerInit - Disabling UART Power\r\n")));
    pHWHead->fIRMode  = FALSE;   // Select wired by default
    CCSerSetOutputMode(pHWHead, FALSE, FALSE );    
    
    return pHWHead;
 
ALLOCFAILED:
    if ( pHWHead->pBaseAddress )
        VirtualFree(pHWHead->pBaseAddress, 0, MEM_RELEASE);
    
    LocalFree(pHWHead);
    return NULL;
}

/*
 @doc OEM
 @func ULONG | CCSerClose | This routine closes the device identified by the PVOID returned by CCSerInit.
 *  Not exported to users, only to driver.
 *
 @rdesc The return value is 0.
 */
static
ULONG
CCSerClose(
    PVOID   pHead	// @parm PVOID returned by CCSerInit.
    )
{
    PSER_INFO	pHWHead = (PSER_INFO)pHead;
    ULONG  uTries;

    DEBUGMSG (ZONE_CLOSE,(TEXT("+CCSerClose\r\n")));
    if( pHWHead->cOpenCount )
    {
        DEBUGMSG (ZONE_CLOSE, 
                  (TEXT("CCSerClose, closing device\r\n")));
        pHWHead->cOpenCount--;
        
         // while we are still transmitting, sleep.
        uTries = 0;
        while ( (uTries++ < 100) &&
                !(pHWHead->ser16550.LSR & SERIAL_LSR_TEMT) )
        {
            DEBUGMSG (ZONE_CLOSE, 
			(TEXT("CCSerClose, TX in progress, LSR 0x%X\r\n"),
                       pHWHead->ser16550.LSR));
            Sleep(10);
        }

         // When the device is closed, we power it down.
        DEBUGMSG (ZONE_CLOSE, 
                  (TEXT("CCSerClose - Powering down UART\r\n")));
        pHWHead->fIRMode  = FALSE;  
        CCSerSetOutputMode(pHWHead, FALSE, FALSE );
		
    }
    
    DEBUGMSG (ZONE_CLOSE,(TEXT("-CCSerClose\r\n")));
    return 0;
}

/*
 @doc OEM 
 @func PVOID | CCSerDeinit | Deinitializes device identified by argument.
 *  This routine frees any memory allocated by CCSerInit.

⌨️ 快捷键说明

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