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

📄 scif.c

📁 Wince4.2 BSP for SH4 engineering development board
💻 C
📖 第 1 页 / 共 5 页
字号:
	/* Reset the FIFOs */
	WRITE_REGISTER_USHORT(pHWHead->pFCR, (READ_REGISTER_USHORT(pHWHead->pFCR) |
		(SCIF_SCFCR_TFRST | SCIF_SCFCR_RFRST))); 

    /* Get defaults from the DCB structure */
    SCIF_SetBaudRate( pHead, pHWHead->dcb.BaudRate );
    SCIF_SetByteSize( pHead, pHWHead->dcb.ByteSize );
    SCIF_SetStopBits( pHead, pHWHead->dcb.StopBits );
    SCIF_SetParity( pHead, pHWHead->dcb.Parity );

	/* We now need to wait for the time it takes one bit to transfer */
	BusyWait(AdjustMicroSecondsToLoopCount((1000000/pHWHead->dcb.BaudRate)+1));

	/*
	 * enable the FIFOs and set the trigger values, we are accepting
	 * the defaults for the receive trigger (1) and the transmit
	 * trigger (8).  
	 * Also, enable the Modem Control Signals. This allows for handshaking
	 * and for breaks.
	 */

    WRITE_REGISTER_USHORT(pHWHead->pFCR, ( SCIF_SCFCR_RTRG_14 | SCIF_SCFCR_TTRG_8));      
        
	/* 
	 * Enable Line Error and Receive Interrupts 
	 */

	WRITE_REGISTER_USHORT(pHWHead->pSCR, ((READ_REGISTER_USHORT(pHWHead->pSCR) &
		~SCIF_SCSCR_TIE) | SCIF_SCSCR_RIE));
		

	/* Here we enable the transmit bit as well */
	WRITE_REGISTER_USHORT(pHWHead->pSCR, (READ_REGISTER_USHORT(pHWHead->pSCR) | 
		( SCIF_SCSCR_TE | SCIF_SCSCR_RE)));	 
		
	/* we need to setup the clock source, this makes it choice 0 */
	WRITE_REGISTER_USHORT(pHWHead->pSCR, (READ_REGISTER_USHORT(pHWHead->pSCR) &
		~SCIF_SCSCR_CKE_2)); 

}

//
/////////////////// Start of exported entrypoints ////////////////
//

/*****************************************************************************
*	FUNCTION :		SCIF_Open		
*	DESCRIPTION :	configures SCIF for default behavior
*	INPUTS :		The pointer to the hardware struct
*	OUTPUTS :		None
*	DESIGN NOTES :	
*	CAUTIONS :		
*****************************************************************************/
BOOL SCIF_Open(
    PVOID   pHead)				/* PVOID returned by SCIF_init */
{
	PSCIF_INFO pHWHead = (PSCIF_INFO)pHead;

    DEBUGMSG(ZONE_FUNCTION,(TEXT("SERIAL : +SCIF_Open 0x%X\r\n"), pHead));

     /* If the device is already open, all we do is increment count */
    if( pHWHead->OpenCount++ )
    {
        DEBUGMSG (ZONE_OPEN,
                  (TEXT("-SCIF_Open 0x%X (%d opens)\r\n"),
                   pHead, pHWHead->OpenCount));
        return (FALSE);
    }
    pHWHead->DroppedBytes = 0;
    pHWHead->DSRFlowOff = FALSE;  // Not flowed off yet
    pHWHead->CTSFlowOff = FALSE;
    pHWHead->CommErrors   = 0;
	pHWHead->LSR = 0x0000; 
	InitPort(pHead);

	// Now we are ready
	SCIF_SetRTS((PVOID)pHWHead);
	SCIF_SetDTR((PVOID)pHWHead);

	DEBUGMSG(ZONE_OPEN, (TEXT("SERIAL : The serial device is open\r\n")));
    
    DEBUGMSG (ZONE_FUNCTION,
              (TEXT("SERIAL : -SCIF_Open 0x%X\r\n"), pHead));

	return(TRUE);
}



/*****************************************************************************
*	FUNCTION :		SCIF_Close
*	DESCRIPTION :	just keeps track of the open count
*	INPUTS :		The pointer to the hardware struct
*	OUTPUTS :		None
*	DESIGN NOTES :	
*	CAUTIONS :		
*****************************************************************************/
ULONG SCIF_Close(PVOID   pHead )
{
    PSCIF_INFO pHWHead = (PSCIF_INFO)pHead;

    DEBUGMSG (ZONE_FUNCTION,
              (TEXT("+SCIF_Close 0x%X\r\n"), pHead));

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

	if (pHWHead->OpenCount <= 0)
	{
		/* First we need to disable transmit and receive */
		/* DH- leave TE enabled-floating line can cause spurious transmission */
		WRITE_REGISTER_USHORT(pHWHead->pSCR, (READ_REGISTER_USHORT(pHWHead->pSCR)  & 
			(~SCIF_SCSCR_RE & ~SCIF_SCSCR_RIE & ~SCIF_SCSCR_TIE))); 
		DEBUGMSG (ZONE_CLOSE,
            (TEXT("SERIAL : The Serial device has been closed\r\n")));
	}

	pHWHead->LastClose = GetTickCount();
    pHWHead->CTSFlowOff = FALSE;
    
    DEBUGMSG (ZONE_FUNCTION,
              (TEXT("SERIAL : -SCIF_Close 0x%X\r\n"), pHead));

	return(TRUE);
}

/*****************************************************************************
*	FUNCTION :		SCIF_Init		
*	DESCRIPTION :	Initialize the SCIF port (mainly addresses, not port)
*	INPUTS :		The registry ID and the pointer to the top of MDD
*	OUTPUTS :		Pointer to HW SCIF structure
*	DESIGN NOTES :	The HW struct is based loosely on the 16550 struct 
*					because they have similar functionality
*	CAUTIONS :		
*****************************************************************************/

PVOID SCIF_Init(
    ULONG	Identifier,									/* Registry Identifier */
	PVOID	pMddHead)									/* Serial Port Structure */
{
    PSCIF_INFO  pHWHead = NULL;							/* Pointer to SCIF info */
	PVBYTE	pRegBase = NULL;							/* Base reg pointer */
	PVBYTE	pPortBase = NULL;							/* Base Port reg */
	PVBYTE	pIntArea1 = NULL;							/* Base Port reg */
	BOOL ret;											/* return value */


    DEBUGMSG (ZONE_FUNCTION,(TEXT("SERIAL : +SCIF_INIT, 0x%X\r\n"), pHWHead));

	dwClockFreq = GetClockFrequency(CPUPeripheralClock) ;	
	
	pHWHead = VirtualAlloc(NULL,						/* any location */
					sizeof(SCIF_INFO),					/* big enough for SCIF struct */
					MEM_COMMIT,							/* commit the memory */
					PAGE_READWRITE);					/* It is for rd/wr use */

	if (pHWHead == NULL)
	{
		goto error_handler;
	}
	
	pRegBase = (PVBYTE)VirtualAlloc(NULL,				/* any location */
					SCIF_REGSIZE, 						/* all SCIF regs */
					MEM_RESERVE,						/* reserve the memory */
					PAGE_NOACCESS);						/* Cannot be used */

	if (pRegBase == NULL)
	{
		DEBUGMSG(ZONE_INIT, (TEXT("SERIAL : Failed to Allocate RegBase in SCIF module\r\n")));
		goto error_handler;
	}
	
	ret = VirtualCopy((PVOID)pRegBase,					/* mem adress */
					(BYTE*)SCIF_REGBASE,				/* addr to bind to */
					SCIF_REGSIZE,						/* length */
					PAGE_READWRITE | PAGE_NOCACHE);		/* options */
	if (ret != TRUE)
	{
		DEBUGMSG(ZONE_INIT, (TEXT("SERIAL : Failed to Bind RegBase in SCIF module\r\n")));
		goto error_handler;
	}


    pPortBase = (PVBYTE)VirtualAlloc(NULL,				/* any location */ 
					PORTREG_SIZE, 						/* all SCIF regs */
					MEM_RESERVE,						/* reserve the memory */
					PAGE_NOACCESS);						/* Cannot be used */

	if (pPortBase == NULL)
	{
		DEBUGMSG(ZONE_INIT, (TEXT("SERIAL : Failed to Allocate PortBase in SCIF module\r\n")));
		goto error_handler;
	}
	
	ret = VirtualCopy((PVOID)pPortBase,					/* mem adress */
					(BYTE*)PORT_BASE,					/* addr to bind to */
					PORTREG_SIZE,						/* length */
					PAGE_READWRITE | PAGE_NOCACHE);		/* options */
	if (ret != TRUE)
	{
		DEBUGMSG(ZONE_INIT, (TEXT("SERIAL : Failed to Bind PortBase in SCIF module\r\n")));
		goto error_handler;
	}


    pIntArea1 = (PVBYTE)VirtualAlloc(NULL,				/* any location */
					INTC_AREA_7_REGSIZE, 		    	/* all SCIF regs */
					MEM_RESERVE,						/* reserve the memory */
					PAGE_NOACCESS);						/* Cannot be used */

	if (pIntArea1 == NULL)
	{
		DEBUGMSG(ZONE_INIT, (TEXT("SERIAL : Failed to Allocate pIntArea1 in SCIF module\r\n")));
		goto error_handler;
	
	}
	
	ret = VirtualCopy((PVOID)pIntArea1,					/* mem adress */
					(BYTE*)INTC_AREA_7_REGBASE,			/* addr to bind to */
					INTC_AREA_7_REGSIZE,				/* length */
					PAGE_READWRITE | PAGE_NOCACHE);		/* options */
	if (ret != TRUE)
	{
		DEBUGMSG(ZONE_INIT, (TEXT("SERIAL : Failed to Bind PortBase in SCIF module\r\n")));
		goto error_handler;
	}

	DEBUGMSG(ZONE_INIT, (TEXT("SERIAL : SCIF_Init:All addresses Allocated and Bound\r\n")));

    /* Set up pointers to SCIF registers */
    pHWHead->pSMR		= (PVSHORT)((PVBYTE)pRegBase + SCIF_SCSMR2_OFFSET);
    pHWHead->pBRR		= pRegBase + SCIF_SCBRR2_OFFSET;   
	pHWHead->pSCR		= (PVSHORT)((PVBYTE)pRegBase + SCIF_SCSCR2_OFFSET);    
    pHWHead->pFTDR		= (PVBYTE)((PVBYTE)pRegBase + SCIF_SCFTDR2_OFFSET);
    pHWHead->pSSR		= (PVSHORT)((PVBYTE)pRegBase + SCIF_SCFSR2_OFFSET);
    pHWHead->pFDR		= (PVSHORT)((PVBYTE)pRegBase + SCIF_SCFDR2_OFFSET);
    pHWHead->pFCR		= (PVSHORT)((PVBYTE)pRegBase + SCIF_SCFCR2_OFFSET);
    pHWHead->pLSR		= (PVSHORT)((PVBYTE)pRegBase + SCIF_SCLSR2_OFFSET); 
    pHWHead->pFRDR		= pRegBase + SCIF_SCFRDR2_OFFSET;   
	pHWHead->pSCSPTR	= (PVSHORT)((PVBYTE)pPortBase + SCIF_SCSPTR2_OFFSET);

	pHWHead->pRegBase	= pRegBase;
	pHWHead->pPortBase	= pPortBase;  
	pHWHead->pIntArea1  = (PVSHORT)pIntArea1;

    /*Store info for speaking to the MDD callback function */
    pHWHead->pMddHead = pMddHead;

    /* Now set up remaining fields */
    
	/*
	 * we need to assign the initial values for the the modem signals. 
	 * as all of the modem signals are active-low, so... we will set these 
	 * values to 1, so we will know if they go low
	 */
	if ((pHWHead->FlushDone	= CreateEvent(0, FALSE, FALSE, NULL)) == NULL)
	{
		DEBUGMSG(ZONE_INIT, (TEXT("SERIAL : Failed to create FlushDone event\r\n")));
		goto error_handler;
	}

    pHWHead->OpenCount	= 0;
    
	/* Initialize Critical Section that is used to check the Modem control signals  */
	InitializeCriticalSection(&(pHWHead->ModemCritSect));

	/* Initialize the critical sections that will guard the parts of
     * the transmit buffer.
     */
    InitializeCriticalSection(&(pHWHead->TransmitCritSec));


    
	/* we need to setup the structure to report our properties */
	pHWHead->CommProp.wPacketLength = 0xffff;
	pHWHead->CommProp.wPacketVersion = 0xffff;
	pHWHead->CommProp.dwServiceMask = SP_SERIALCOMM;
	pHWHead->CommProp.dwReserved1 = 0;
	pHWHead->CommProp.dwMaxTxQueue = FIFO_SIZE;
	pHWHead->CommProp.dwMaxRxQueue = FIFO_SIZE;
	pHWHead->CommProp.dwMaxBaud = BAUD_57600;
	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_57600;

	pHWHead->CommProp.dwSettableParams =
		SP_BAUD | SP_DATABITS | SP_HANDSHAKING | SP_PARITY |
		SP_PARITY_CHECK | SP_RLSD | SP_STOPBITS;

	pHWHead->CommProp.wSettableData =
		DATABITS_7 | DATABITS_8;

	pHWHead->CommProp.wSettableStopParity =
		STOPBITS_10 | STOPBITS_20 | PARITY_NONE | PARITY_ODD |
		PARITY_EVEN;

	pHWHead->CommProp.dwCurrentTxQueue = FIFO_SIZE;

	pHWHead->CommProp.dwCurrentRxQueue = FIFO_SIZE;

	/* 
	 * we need to setup the SC port so that we can read the 
	 * signals.  
	 */
	WRITE_REGISTER_USHORT(pHWHead->pSCSPTR, SCSPTR_RTS_EN|SCSPTR_BEN|SCSPTR_BDATAH);
	WRITE_REGISTER_USHORT(pHWHead->pLSR, 0x0000); 
	/* we need to ensure that the serial port is turned off, all ints disabled */
	WRITE_REGISTER_USHORT(pHWHead->pSCR, SCIF_SCSCR_CKE_0);	/* turns everything off */
	/* Now we need to set the DTR and RTS so that there is nothing until rewuested*/
	SCIF_SetRTS((PVOID)pHWHead);
	SCIF_SetDTR((PVOID)pHWHead);

	/* DH- always have TE enabled-floating line can cause spurious transmission */
	WRITE_REGISTER_USHORT(pHWHead->pSCR,
		(READ_REGISTER_USHORT(pHWHead->pSCR) | SCIF_SCSCR_TE));
    DEBUGMSG (ZONE_CLOSE,(TEXT("SERIAL : -SCIF_INIT, 0x%X\r\n"), pHWHead));


    // Event Object for Polling
    pHWHead->hModemLinePollingEvent = CreateEvent(0, FALSE, FALSE, NULL);
    if(pHWHead->hModemLinePollingEvent == NULL) {
        DEBUGMSG(ZONE_INIT|ZONE_ERROR, (TEXT("SCIF_INIT: Failed to create hModemLinePollingEvent event.\r\n")));
        goto error_handler;
    }
    
    // Event Object for Polling for concerning of stop of LinePollingThread
    pHWHead->hKillOKEvent = CreateEvent(0, FALSE, FALSE, NULL);
    if(pHWHead->hKillOKEvent == NULL) {
        DEBUGMSG(ZONE_INIT|ZONE_ERROR, (TEXT("SCIF_INIT: Failed to create hKillOKEvent event.\r\n")));
        goto error_handler;
    }

    // Create ModemLinePollingThread
    ret = InitPollingThread(pHWHead);
    if(ret == FALSE) {
        DEBUGMSG(ZONE_INIT|ZONE_ERROR, (TEXT("SCIF_INIT : Fail to create ModemLinePollingThread.\r\n")));
        goto error_handler;
    }

	return (pHWHead);

error_handler:
	/* this will handle us bailing on this routine */
	if (pHWHead != NULL)
	{
		if (pHWHead->FlushDone)
			CloseHandle(pHWHead->FlushDone);

        if(pHWHead->hModemLinePollingEvent)
            CloseHandle(pHWHead->hModemLinePollingEvent);
            
        if(pHWHead->hKillOKEvent)
            CloseHandle(pHWHead->hKillOKEvent);

		VirtualFree(pHWHead, sizeof(SCIF_INFO), MEM_DECOMMIT);
		
	}

	if (pRegBase != NULL)
	{
		VirtualFree((BYTE*)pRegBase, 0, MEM_RELEASE);
	}

	if (pPortBase != NULL) 
	{
		VirtualFree((BYTE*)pPortBase, 0, MEM_RELEASE);
	}
	if (pIntArea1 != NULL)
	{
		VirtualFree((BYTE*)pIntArea1, 0, MEM_RELEASE);
	}
	return (NULL);
	
}

/*****************************************************************************
*	FUNCTION :		SCIF_Deinit()
*	DESCRIPTION :	Releasees memory for port
*	INPUTS :		The pointer to the HW struct
*	OUTPUTS :		none
*	DESIGN NOTES :	
*	CAUTIONS :		

⌨️ 快捷键说明

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