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

📄 ser16552.c

📁 2440 wince uart source code
💻 C
📖 第 1 页 / 共 5 页
字号:


//
// This is a reverse lookup table which can be used to determine
// the FIFO trigger level from the 2 bit value stored in the FCR
//
#define HIGH_WATER_SIZE     4

static const
PAIRS   HighWaterPairs[HIGH_WATER_SIZE] = {
    {SERIAL_1_BYTE_HIGH_WATER, 0},
    {SERIAL_4_BYTE_HIGH_WATER, 4},
    {SERIAL_8_BYTE_HIGH_WATER, 8},
    {SERIAL_14_BYTE_HIGH_WATER, 14}
};

static const
LOOKUP_TBL  HighWaterTable = {HIGH_WATER_SIZE, (PAIRS *) HighWaterPairs};



int SerMapRegisterAddresses3( )
{

	v_pIOPRegs1= VirtualAlloc(0, sizeof(IOPreg), MEM_RESERVE, PAGE_NOACCESS);
	if (v_pIOPRegs1== NULL) 
	{
	    DEBUGMSG (1,(TEXT("[16c552] v_pIOPRegs is not allocated\n\r")));
	    RETAILMSG (1,(TEXT("[16c552] v_pIOPRegs is not allocated\n\r")));

		return FALSE;
	}
	if (!VirtualCopy((PVOID)v_pIOPRegs1,(PVOID)IOP_BASE, sizeof(IOPreg), PAGE_READWRITE|PAGE_NOCACHE)) {
	    DEBUGMSG (1,(TEXT("[16c552] v_pIOPRegs is not mapped\n\r")));
	     RETAILMSG (1,(TEXT("[16c552] v_pIOPRegs is not mapped\n\r")));
		goto Ser16c552_fail;
	}
	DEBUGMSG (1,(TEXT("[16c552] v_pIOPRegs is mapped to %x\n\r"), v_pIOPRegs1));
	RETAILMSG (1,(TEXT("[16c552] v_pIOPRegs is mapped to %x\n\r"), v_pIOPRegs1));

	v_pIOPRegs1->rGPFCON = (v_pIOPRegs1->rGPFCON & ~(0x3<<6)) | (0x2<<6); 				//GPF3==EINT3
	v_pIOPRegs1->rGPFUP = (v_pIOPRegs1->rGPFUP	| (0x1<<3));    							// Disable pull-up.
   	v_pIOPRegs1->rEXTINT0=(v_pIOPRegs1->rEXTINT0 & ~(0xf<<12)) | (0x4<<12); 				// Rising edge triggered.


  
	return TRUE;


Ser16c552_fail:
    if (v_pIOPRegs1) {
        VirtualFree((PVOID)v_pIOPRegs1,0, MEM_RELEASE);
    }
    
	return FALSE;
}
//
/////////////////// Start of exported entrypoints ////////////////
//
#define WATERMAKER_ENTRY 2

VOID
SL_Openq(
       PVOID   pHead // @parm PVOID returned by HWinit.
       )
{    
	PSER16550_INFO pHWHead = (PSER16550_INFO)pHead;

     RETAILMSG (QYDEBUG, (TEXT("+SL_Openq 0x%X\r\n"), pHWHead));
    
    // If the device is already open, all we do is increment count
    if ( pHWHead->OpenCount++ ) {
        RETAILMSG (QYDEBUG,
                  (TEXT("-SL_Openq 0x%X (%d opens)\r\n"),
                   pHead, pHWHead->OpenCount));
        return ;
    }

    pHWHead->FCR = 0;
    pHWHead->IER = 0;
    pHWHead->IIR = 0;
    pHWHead->LSR = 0;
    pHWHead->MSR = 0;
    pHWHead->DroppedBytes = 0;
    pHWHead->CTSFlowOff = FALSE;  // Not flowed off yet
    pHWHead->DSRFlowOff = FALSE;  // Not flowed off yet
    pHWHead->CommErrors   = 0;
    pHWHead->ModemStatus  = 0;

    EnterCriticalSection(&(pHWHead->RegCritSec));
  
    try {
 
	OUTB(pHWHead, pIER, (UCHAR)IER_NORMAL_INTS);
        OUTB(pHWHead, pMCR, (UCHAR)0x2B);//   AFC=1,DTR=1,RTS=1
    
RETAILMSG(QYDEBUG,(TEXT("SERIAL3 Register pMCR=0x%x\r\n "),INB(pHWHead, pMCR)));
		// Set default framing bits.
       OUTB(pHWHead, pLCR, SERIAL_8_DATA | SERIAL_1_STOP | SERIAL_NONE_PARITY);
	RETAILMSG(QYDEBUG,(TEXT("SERIAL3 Register LCR(0x03)=0x%x\r\n "),INB(pHWHead, pLCR)));
   

        // Get defaults from the DCB structure
        //设置波特率,默认9600
        SL_SetBaudRateq( pHead, pHWHead->dcb.BaudRate );

        SL_SetByteSizeq( pHead, pHWHead->dcb.ByteSize );
  
        SL_SetStopBitsq( pHead, pHWHead->dcb.StopBits );

        SL_SetParityq( pHead, pHWHead->dcb.Parity );

        //
        // A 16450 (which is pretty much a FIFO-less 16550) can be supported by
        // not initializing the FIFO.
        //
        if (pHWHead->ChipID == CHIP_ID_16550) {
            // Set up to use 16550 fifo for 14 byte interrupt granularity.
            // Shadow the FCR bitmask since reading this location is the IIR

            pHWHead->FCR = 0;
	
		
            OUTB(pHWHead, pIIR_FCR, (pHWHead->FCR | SERIAL_FCR_RCVR_RESET | SERIAL_FCR_TXMT_RESET) );
   
        }

   
        // MDD and calls post init.  
        SL_PostInitq(pHWHead);
        ReadMSRq(pHWHead);
        ReadLSRq(pHWHead);

#ifdef DEBUG
        if ( ZONE_INIT )
            DumpSerialRegistersq(pHWHead);
#endif
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        // Just get out of here.
    }
  
//OUTB(pHWHead, pMCR, (UCHAR)0x29);//   AFC=1,DTR=1,RTS=1
    LeaveCriticalSection(&(pHWHead->RegCritSec));

    DEBUGMSG (ZONE_OPEN,
              (TEXT("-SL_Open 0x%X, IIR 0x%X\r\n"), pHead, pHWHead->IIR));
RETAILMSG(QYDEBUG,(TEXT("SERIAL3 Register pMCR=0x%x\r\n "),INB(pHWHead, pMCR)));
    RETAILMSG(QYDEBUG,(TEXT("-SL_Openq() END \r\n")));//=====QM:0419
}
VOID
SL_Closeq(
        PVOID   pHead // @parm PVOID returned by HWinit.
        )
{
    PSER16550_INFO pHWHead = (PSER16550_INFO)pHead;

    RETAILMSG(QYDEBUG,
              (TEXT("+SL_Close 0x%X\r\n"), pHead));

    if ( pHWHead->OpenCount )
        pHWHead->OpenCount--;

    EnterCriticalSection(&(pHWHead->RegCritSec));
    try {
        // Disable all interrupts and clear MCR.

  //      OUTB(pHWHead, pIER, (UCHAR)0); 
     //     OUTB(pHWHead, pMCR, (UCHAR)0);
  //****
  	   OUTB(pHWHead, pIER, (UCHAR)0x01); 
         OUTB(pHWHead, pMCR, (UCHAR)0x2B);


        pHWHead->IIR   = INB(pHWHead, pIIR_FCR);        
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        // Just get out of here.
    }
    LeaveCriticalSection(&(pHWHead->RegCritSec));
    RETAILMSG(QYDEBUG,
              (TEXT("-SL_Close 0x%X\r\n"), pHead));
}


VOID
SL_Initq(
       PVOID   pHead, // @parm points to device head
       PUCHAR  pRegBase, // Pointer to 16550 register base
       UINT8   RegStride, // Stride amongst the 16550 registers
       EVENT_FUNC EventCallback, // This callback exists in MDD
       PVOID   pMddHead,   // This is the first parm to callback
       PLOOKUP_TBL   pBaudTable  // BaudRate Table
       )
{
    PSER16550_INFO   pHWHead   = (PSER16550_INFO)pHead;
    RETAILMSG(QYDEBUG,(TEXT("+SL_Initq, 0x%X\r\n"), pHWHead));
    RETAILMSG(QYDEBUG,(TEXT("+SL_Initq, 0x%X\r\n"), pHead));

    // Set up pointers to 16550 registers
  pHWHead->pData    = pRegBase + (RegStride * RECEIVE_BUFFER_REGISTER);
    pHWHead->pIER     = pRegBase + (RegStride * INTERRUPT_ENABLE_REGISTER);
    pHWHead->pIIR_FCR = pRegBase + (RegStride * INTERRUPT_IDENT_REGISTER);
    pHWHead->pLCR     = pRegBase + (RegStride * LINE_CONTROL_REGISTER);
    pHWHead->pMCR     = pRegBase + (RegStride * MODEM_CONTROL_REGISTER);
    pHWHead->pLSR     = pRegBase + (RegStride * LINE_STATUS_REGISTER);
    pHWHead->pMSR     = pRegBase + (RegStride * MODEM_STATUS_REGISTER);
    pHWHead->pScratch = pRegBase + (RegStride * SCRATCH_REGISTER);
	
	//	if (!SerMapRegisterAddresses3())
//RETAILMSG( ,(TEXT("+SL_Initq, 0x%X\r\n"), pHead));
		
	/*RETAILMSG(QYDEBUG,(TEXT("pHWHead->pIER  = %X\r\n"),pHWHead->pIER ));
	RETAILMSG(QYDEBUG,(TEXT("pHWHead->pIIR_FCR  = %X\r\n"),pHWHead->pIIR_FCR ));
	RETAILMSG(QYDEBUG,(TEXT("pHWHead->pLCR  = %X\r\n"),pHWHead->pLCR ));
	RETAILMSG(QYDEBUG,(TEXT("pHWHead->pMCR = %X\r\n"),pHWHead->pMCR ));
	RETAILMSG(QYDEBUG,(TEXT("pHWHead->pLSR   = %X\r\n"),pHWHead->pLSR  ));
	RETAILMSG(QYDEBUG,(TEXT(" pHWHead->pMSR  = %X\r\n"), pHWHead->pMSR ));
	RETAILMSG(QYDEBUG,(TEXT("pHWHead->pIER  = %X\r\n"),pHWHead->pScratch ));
	*/

    // Store info for callback function
    pHWHead->EventCallback = EventCallback;
    pHWHead->pMddHead = pMddHead;

    // Now set up remaining fields
    if ( pBaudTable != NULL ){
        pHWHead->pBaudTable = (LOOKUP_TBL *) pBaudTable;
    RETAILMSG(QYDEBUG,(TEXT("pBaudTable != NULL  0x%X\r\n")));
    	}
    else
        pHWHead->pBaudTable = (LOOKUP_TBL *) &SER_BaudTable;
        pHWHead->FlushDone   = CreateEvent(0, FALSE, FALSE, NULL);

    pHWHead->OpenCount = 0;
     RETAILMSG(QYDEBUG,(TEXT("OpenCount  0x%X\r\n")));


	//OUTB(pHWHead, pIER, (UCHAR)2);
	 //RETAILMSG(QYDEBUG,(TEXT("pIER=  0x%X\r\n"),INB(pHWHead,pIER)));

	OUTB(pHWHead, pIER, 0x0f);
	RETAILMSG(QYDEBUG,(TEXT("pIER  0x%X\r\n"),INB(pHWHead, pIER)));
	
    // Don't allow any interrupts till PostInit.
   OUTB(pHWHead, pIER, (UCHAR)0);
//****
	 OUTB(pHWHead, pIER, (UCHAR)IER_NORMAL_INTS);
      OUTB(pHWHead, pMCR, 0x2b);//   MAX3244 
      RETAILMSG(QYDEBUG,(TEXT("pIER  0x%X\r\n"),INB(pHWHead, pIER)));


    InitializeCriticalSection(&(pHWHead->TransmitCritSec));
    InitializeCriticalSection(&(pHWHead->RegCritSec));
    // Clear any interrupts which may be pending.  Normally only
    // happens if we were warm reset.
    ClearPendingIntsq( pHWHead );
   RETAILMSG(QYDEBUG,(TEXT("-SL_INITq, 0x%d\r\n"), pHWHead));
}



BOOL
SL_PostInitq(
           PVOID   pHead // @parm PVOID returned by HWinit.
           )
{
    PSER16550_INFO   pHWHead   = (PSER16550_INFO)pHead;

    RETAILMSG(QYDEBUG,(TEXT("+SL_PostInit, 0x%X\r\n"), pHWHead));
    
    // Since we are just a library which might get used for 
    // builtin ports which init at boot, or by PCMCIA ports
    // which init at Open, we can't do anything too fancy.
    // Lets just make sure we cancel any pending interrupts so
    // that if we are being used with an edge triggered PIC, he
    // will see an edge after the MDD hooks the interrupt.
    //清除全部中断标志和中断源
    ClearPendingIntsq( pHWHead );
    
	
    RETAILMSG(QYDEBUG,(TEXT("-SL_PostInit, 0x%X\r\n"), pHWHead));
    return(TRUE);
}

VOID
SL_ClearBreakq(
             PVOID   pHead // @parm PVOID returned by HWinit.
             )
{
    PSER16550_INFO   pHWHead   = (PSER16550_INFO)pHead;

    RETAILMSG(QYDEBUG, (TEXT("+SL_ClearBreak, 0x%X\r\n"), pHead));

    EnterCriticalSection(&(pHWHead->RegCritSec));
    try {
        unsigned char byte;

        byte = INB(((PSER16550_INFO)pHead), pLCR);
        OUTB(((PSER16550_INFO)pHead), pLCR, byte & ~SERIAL_LCR_BREAK);
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        // Just exit
    }
    LeaveCriticalSection(&(pHWHead->RegCritSec));

    RETAILMSG(QYDEBUG, (TEXT("-SL_ClearBreak, 0x%X\r\n"), pHead));
}

VOID
SL_SetBreakq(
           PVOID   pHead // @parm PVOID returned by HWinit.
           )
{
    PSER16550_INFO   pHWHead   = (PSER16550_INFO)pHead;

    RETAILMSG(QYDEBUG, (TEXT("+SL_SetBreak, 0x%X\r\n"), pHead));

    EnterCriticalSection(&(pHWHead->RegCritSec));
    try {
        unsigned char byte;

        byte = INB(((PSER16550_INFO)pHead), pLCR);
      OUTB(((PSER16550_INFO)pHead), pLCR, byte | SERIAL_LCR_BREAK);
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        // Just exit
    }
    LeaveCriticalSection(&(pHWHead->RegCritSec));

    RETAILMSG(QYDEBUG, (TEXT("-SL_SetBreak, 0x%X\r\n"), pHead));
}

BOOL
SetBaudRateq(
           PVOID   pHead,
           ULONG   BaudRate
           )
{
    PSER16550_INFO    pHWHead = (PSER16550_INFO)pHead;
    USHORT        divisor;
    UCHAR        lcr;
	RETAILMSG(QYDEBUG,(TEXT("+SerBaudRateq()\r\n")));
    // **** Warning ***** Make no system calls, called in power context
    divisor = DivisorOfRateq(pHead, BaudRate);
	RETAILMSG(QYDEBUG,(TEXT("BaudRate=0x%x\r\n"),divisor));
    if ( divisor ) {
       
      lcr = INB(pHWHead, pLCR);
	RETAILMSG(QYDEBUG,(TEXT("	+  lcr  lcr  LCR =0X%X\r\n"),lcr));
       RETAILMSG(QYDEBUG,(TEXT("	+SER16550 Register LCR =0X%X\r\n"),INB(pHWHead, pLCR)));

     OUTB(pHWHead, pLCR, lcr | SERIAL_LCR_DLAB);
 
     OUTB(pHWHead, pData, divisor & 0xff); //pData is DivLatch Lo       
     OUTB(pHWHead, pIER, (divisor >> 8) & 0xff); //pIER is DivLatch Hi

     OUTB(pHWHead, pLCR, lcr);
     RETAILMSG(QYDEBUG,(TEXT("	+SER16550 Register LCR =0X%X\r\n"),INB(pHWHead, pLCR)));
     //****
     OUTB(pHWHead, pIER, 0x01);
 
        RETAILMSG(QYDEBUG,(TEXT("-SerBaudRateq(S)\r\n")));
       return( TRUE );
    
    } else {
    	RETAILMSG(QYDEBUG,(TEXT("-SerBaudRateq(F)\r\n")));
        return( FALSE );
    }

}


BOOL
SL_SetBaudRateq(
              PVOID   pHead,    // @parm     PVOID returned by HWInit

⌨️ 快捷键说明

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