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

📄 scif3.c

📁 WinCE5.0BSP for Renesas SH7770
💻 C
📖 第 1 页 / 共 2 页
字号:
//
//  Copyright(C) Renesas Technology Corp. 1999-2004. All rights reserved.
//
//  Serial(SCIF3) driver for ITS-DS7
//
//  FILE      : scif3.c
//  CREATED   : 2002.06.26
//  MODIFIED  : 2004.09.01
//  AUTHOR    : Renesas Technology Corp.
//  HARDWARE  : RENESAS ITS-DS7
//  HISTORY   : 
//              2003.06.20
//              - Created release code.
//                (based on Serial driver for ITS-DS4 Source Kit Ver.1.2.0 for WCE 4.2)
//              2003.10.27
//              - The timing which permits reception is changed
//              - Changed for corresponding to COM_MDD2.
//              - Bug fixed. (fail,etc in CETK)
//              2004.09.01
//              - Created release code for WCE5.0.
//

#include <windows.h>
#include <types.h>
#include <ceddk.h>
#include <memory.h>
#include <notify.h>
#include <serhw.h>
#include <nkintr.h>
#include <oalintr.h>
#include <devload.h>
#include <windev.h>
#undef ZONE_INIT
#include <serdbg.h>
#include <celog.h> 
#include <its_ds7.h>
#include <drv_glob.h>
#include <sh7770.h>
#include "..\inc\scif.h"

#define RX_FLOW_CONTROL 1

extern BOOL SCIF_PostInit(
         PVOID   pHead   // @parm PVOID returned by SerInit.
         );

// Miscellaneous internal routines. (scif_cmn.c)
extern PUCHAR Ser_InternalMapRegisterAddresses(
				ULONG   HWAddress,
				ULONG   Size );

extern const HW_VTBL SCIF3IoVTbl;
/*
 @doc OEM 
 @func PVOID | SerInit | 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
SCIF3Init(
       ULONG   Identifier, // @parm Device identifier.
       PVOID   pMddHead,   // @parm First argument to mdd callbacks.
       PHWOBJ  pHWObj      // @parm Pointer to our own HW OBJ for this device

       )
{
    PSCIF_INFO   pHWHead;

     // Allocate for our main data structure and one of it's fields.
    pHWHead = (PSCIF_INFO)LocalAlloc( LMEM_ZEROINIT|LMEM_FIXED , sizeof(SCIF_INFO) );
    if ( !pHWHead )
        goto ALLOCFAILED;

    if ( ! Ser_GetRegistryData(pHWHead, (LPCTSTR)Identifier) ) {
        DEBUGMSG (ZONE_INIT|ZONE_ERROR,
                  (TEXT("SCIF3Init - Unable to read registry data.  Failing Init !!! \r\n")));
        goto ALLOCFAILED;
    }

     // This call will map the address space for the 16550 UART.  
    if ( !(pHWHead->pBaseAddress   = Ser_InternalMapRegisterAddresses(
        SCIF3_REGBASE, SCIF3_REGSIZE )) )
		goto ALLOCFAILED;

    pHWHead -> pSMR    = (volatile USHORT *)((PVBYTE)pHWHead -> pBaseAddress + SCIF_SCSMR_OFFSET);
    pHWHead -> pBRR    = (volatile BYTE *)((PVBYTE)pHWHead -> pBaseAddress   + SCIF_SCBRR_OFFSET);
    pHWHead -> pSCR    = (volatile USHORT *)((PVBYTE)pHWHead -> pBaseAddress + SCIF_SCSCR_OFFSET);
    pHWHead -> pFTDR   = (volatile BYTE *)((PVBYTE)pHWHead -> pBaseAddress   + SCIF_SCFTDR_OFFSET);
    pHWHead -> pFSR    = (volatile USHORT *)((PVBYTE)pHWHead -> pBaseAddress + SCIF_SCFSR_OFFSET);
    pHWHead -> pFRDR   = (volatile BYTE *)((PVBYTE)pHWHead -> pBaseAddress   + SCIF_SCFRDR_OFFSET);
    pHWHead -> pFCR    = (volatile USHORT *)((PVBYTE)pHWHead -> pBaseAddress + SCIF_SCFCR_OFFSET);
    pHWHead -> pFDR    = (volatile USHORT *)((PVBYTE)pHWHead -> pBaseAddress + SCIF_SCFDR_OFFSET);
    pHWHead -> pSPTR   = (volatile USHORT *)((PVBYTE)pHWHead -> pBaseAddress + SCIF_SCSPTR_OFFSET);
    pHWHead -> pLSR    = (volatile USHORT *)((PVBYTE)pHWHead -> pBaseAddress + SCIF_SCLSR_OFFSET);
    pHWHead -> pBRGDL  = (volatile USHORT *)((PVBYTE)pHWHead -> pBaseAddress + SCIF_BRG_DL);
    pHWHead -> pBRGCKS = (volatile USHORT *)((PVBYTE)pHWHead -> pBaseAddress + SCIF_BRG_CKS);
    pHWHead -> pSCSMR  = (volatile USHORT *)((PVBYTE)pHWHead -> pBaseAddress + SCIF_IRDA_SCSMR);

	DEBUGMSG(ZONE_INIT, (TEXT("BaseAddress 0x%x\r\n"), pHWHead -> pBaseAddress));
	DEBUGMSG(ZONE_INIT, (TEXT("SMR 0x%x\r\n"), READ_REGISTER_USHORT(pHWHead -> pSMR)));
	DEBUGMSG(ZONE_INIT, (TEXT("BRR 0x%x\r\n"), READ_REGISTER_UCHAR(pHWHead -> pBRR)));
	DEBUGMSG(ZONE_INIT, (TEXT("SCR 0x%x\r\n"), READ_REGISTER_USHORT(pHWHead -> pSCR)));
	DEBUGMSG(ZONE_INIT, (TEXT("FTDR 0x%x\r\n"), READ_REGISTER_UCHAR(pHWHead -> pFTDR)));
	DEBUGMSG(ZONE_INIT, (TEXT("FSR 0x%x\r\n"), READ_REGISTER_USHORT(pHWHead -> pFSR)));
	DEBUGMSG(ZONE_INIT, (TEXT("FRDR 0x%x\r\n"), READ_REGISTER_UCHAR(pHWHead -> pFRDR)));
	DEBUGMSG(ZONE_INIT, (TEXT("FCR 0x%x\r\n"), READ_REGISTER_USHORT(pHWHead -> pFCR)));
	DEBUGMSG(ZONE_INIT, (TEXT("FDR 0x%x\r\n"), READ_REGISTER_USHORT(pHWHead -> pFDR)));
	DEBUGMSG(ZONE_INIT, (TEXT("SPTR 0x%x\r\n"), READ_REGISTER_USHORT(pHWHead -> pSPTR)));
	DEBUGMSG(ZONE_INIT, (TEXT("LSR0x%x\r\n"), READ_REGISTER_USHORT(pHWHead -> pLSR)));
	DEBUGMSG(ZONE_INIT, (TEXT("BRGDL 0x%x\r\n"), READ_REGISTER_USHORT(pHWHead -> pBRGDL)));
	DEBUGMSG(ZONE_INIT, (TEXT("BRGCKS 0x%x\r\n"), READ_REGISTER_USHORT(pHWHead -> pBRGCKS)));
	DEBUGMSG(ZONE_INIT, (TEXT("SCSMR 0x%x\r\n"), READ_REGISTER_USHORT(pHWHead -> pSCSMR)));

    pHWHead -> EventCallback = (EVENT_FUNC)EvaluateEventFlag;
    pHWHead -> pMddHead	     = pMddHead;
    pHWHead -> pHWObj        = pHWObj;
    pHWHead -> OpenCount     = 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;
#if (SH7770_REVISION == SH7770_1STCUT)
    pHWHead->CommProp.dwMaxBaud	         = BAUD_38400;
#else
    pHWHead->CommProp.dwMaxBaud	         = BAUD_115200;
#endif
    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;
#if (SH7770_REVISION == SH7770_1STCUT)
    pHWHead->CommProp.dwSettableBaud     = BAUD_9600 |
                                           BAUD_19200 |
                                           BAUD_38400;
#else
    pHWHead->CommProp.dwSettableBaud     = BAUD_9600 |
                                           BAUD_19200 |
                                           BAUD_38400 |
                                           BAUD_57600 |
                                           BAUD_115200;
#endif
    pHWHead->CommProp.dwSettableParams   = SP_BAUD |
                                           SP_DATABITS |
                                           SP_HANDSHAKING |
                                           SP_PARITY |
                                           SP_PARITY_CHECK |
                                           SP_STOPBITS;
    pHWHead->CommProp.wSettableData      = DATABITS_7 |
                                           DATABITS_8;
    pHWHead->CommProp.wSettableStopParity = STOPBITS_10 |
                                            STOPBITS_20 |
                                            PARITY_NONE |
                                            PARITY_ODD  |
                                            PARITY_EVEN;

	if ( !(pHWHead -> FlushDone = CreateEvent(0, FALSE, FALSE, NULL)) )
		goto ALLOCFAILED;

	if ( !(pHWHead -> pTxBuff = (PBYTE)Ser_InternalMapRegisterAddresses
				( SCIF3_TX_BUFFER_BASE, SCIF3_TXBUFFER_SIZE )) )
		goto ALLOCFAILED;
	if ( !(pHWHead -> pRxBuff = (PBYTE)Ser_InternalMapRegisterAddresses
				( SCIF3_RX_BUFFER_BASE, SCIF3_RXBUFFER_SIZE * 2 )) )
		goto ALLOCFAILED;

	if ( !dma_Init(CH_TX_SCIF3, &(pHWHead -> pTxDma)) )
		goto ALLOCFAILED;

	if ( !dma_Init(CH_RX_SCIF3, &(pHWHead -> pRxDma)) )
		goto ALLOCFAILED;

    pHWHead -> ulRxDmaRegBase = SCIF3_REGBASE + SCIF_SCFRDR_OFFSET;
    pHWHead -> ulRxDmaBuffBase1 = SCIF3_RX_BUFFER_BASE;
    pHWHead -> ulRxDmaBuffBase2 = SCIF3_RX_BUFFER_BASE + SCIF3_RXBUFFER_SIZE;
    pHWHead -> ulRxDmaBuffSize = SCIF3_RXBUFFER_SIZE;
    pHWHead -> dwRxDmaPort =  DPTR_SDPT_SCIF3;

    pHWHead -> bFirstBaudRate = FALSE;

    InitializeCriticalSection(&(pHWHead->TransmitCritSec));
    InitializeCriticalSection(&(pHWHead->RegCritSec));
    pHWHead->PowerDown = FALSE;
    pHWHead->bSuspendResume = FALSE;

    DEBUGMSG (ZONE_INIT,
              (TEXT("SCIF_Init - Disabling UART Power\r\n")));
    pHWHead->fIRMode  = FALSE;   // Select wired by default

	return pHWHead;
 
ALLOCFAILED:
    if ( pHWHead -> pBaseAddress )
        VirtualFree((PVOID)pHWHead -> pBaseAddress, 0, MEM_RELEASE);
    if ( pHWHead -> FlushDone )
	CloseHandle( pHWHead -> FlushDone ); 
    if ( pHWHead -> pTxBuff )
        VirtualFree((PVOID)pHWHead -> pTxBuff, 0, MEM_RELEASE);
    if ( pHWHead -> pRxBuff )
        VirtualFree((PVOID)pHWHead -> pRxBuff, 0, MEM_RELEASE);
	
    LocalFree( pHWHead );
    return NULL;
}



/*
 @doc OEM
 @func BOOL | SerOpen | This routine is called when the port is opened.
 *  Not exported to users, only to driver.
 *
 @rdesc Returns TRUE if successful, FALSEotherwise.
 */
static
BOOL
SCIF3Open(
       PVOID   pHead /*@parm PVOID returned by Serinit. */
       )
{

    PSCIF_INFO	pHWHead = (PSCIF_INFO)pHead;
    DWORD	dcr_value;

     // Disallow multiple simultaneous opens
    if( pHWHead->OpenCount )
        return FALSE;

    pHWHead->OpenCount++;

    DEBUGMSG (ZONE_OPEN,
              (TEXT("SCIF3_Open - Selecting Non IR Mode\r\n")));

    pHWHead->fIRMode  = FALSE;   // Select wired by default

    pHWHead->SMR = 0;
    pHWHead->FCR = 0;
    pHWHead->BRR = 0;
    pHWHead->SCR = 0;
    pHWHead->BRGDL = 0;
    pHWHead->BRGCKS = 0;
    pHWHead->DroppedBytes = 0;
    pHWHead->CTSFlowOff = FALSE;  // Not flowed off yet
    pHWHead->DSRFlowOff = FALSE;  // Not flowed off yet
    pHWHead->CommErrors   = 0;
    pHWHead->ModemStatus  = 0;

    WRITE_REGISTER_USHORT(pHWHead -> pSCR, 0);
    WRITE_REGISTER_USHORT(pHWHead -> pFSR, 0);
    WRITE_REGISTER_UCHAR(pHWHead -> pBRR, 0);

    pHWHead->ulReceiveDmaBufferPointer = 0;

    WRITE_REGISTER_USHORT(pHWHead -> pFCR, SCIF_FCR_TFRST | SCIF_FCR_RFRST);

    WRITE_REGISTER_USHORT(pHWHead -> pSMR, SCIF_SMR_ASYNC|SCIF_SMR_CKS_1|SCIF_SMR_8BIT|SCIF_SMR_1STOP);

	// Set Default Value
	pHWHead->dcb.BaudRate = 9600;
	pHWHead->dcb.ByteSize = DATABITS_8;
	pHWHead->dcb.StopBits = ONESTOPBIT;
	pHWHead->dcb.Parity   = NOPARITY;

    SCIF_SetBaudRate(pHWHead, pHWHead -> dcb.BaudRate);
    SCIF_SetByteSize(pHWHead, pHWHead -> dcb.ByteSize);
    SCIF_SetStopBits(pHWHead, pHWHead -> dcb.StopBits);
    SCIF_SetParity(  pHWHead, pHWHead -> dcb.Parity);

//    WRITE_REGISTER_USHORT(pHWHead -> pFCR, SCIF_FCR_RSTRG_15 | SCIF_FCR_RTRG_4 | SCIF_FCR_TTRG_0);
    WRITE_REGISTER_USHORT(pHWHead -> pFCR, SCIF_FCR_RSTRG_15 | SCIF_FCR_RTRG_14 | SCIF_FCR_TTRG_0);

    WRITE_REGISTER_USHORT(pHWHead -> pSCR, SCIF_SCR_CKE_2);
    dcr_value = DCR_DPDS_8BIT		|
				DCR_DDRMD_MODULE	|
				DCR_DPDAM_FIX	 	|
				DCR_DMDL_MEMORY		|
				DCR_SPDS_8BIT		|
				DCR_SDRMD_MODULE	|
				DCR_SPDAM_FIX		|
				DCR_SMDL_PERIPHERAL	|
				DCR_DIP_2PAGE		|
				DCR_ACMD_ENABLE		|
				DCR_CT_ENABLE		|
				DCR_PKMD_DISABLE	|
				DCR_BTMD_DISABLE	|
				DCR_DTAU_BYTE		|
				DCR_DTAC_DISABLE	;	

    dma_SetPage(pHWHead -> pRxDma, 0, pHWHead -> ulRxDmaRegBase,
				   pHWHead -> ulRxDmaBuffBase1, pHWHead -> ulRxDmaBuffSize);
    dma_SetPage(pHWHead -> pRxDma, 1, pHWHead -> ulRxDmaRegBase,
				   pHWHead -> ulRxDmaBuffBase2, pHWHead -> ulRxDmaBuffSize); 
    dma_SetPort(pHWHead -> pRxDma, pHWHead -> dwRxDmaPort);
    dma_SetControl(pHWHead -> pRxDma, dcr_value);
    dma_SetCommand(pHWHead -> pRxDma, DCMDR_DMEN);
    
#if (SH7770_REVISION == SH7770_1STCUT)
		WRITE_REGISTER_USHORT(pHWHead -> pSCR,
				 SCIF_SCR_TOIE|SCIF_SCR_TE|SCIF_SCR_RE|SCIF_SCR_REIE|SCIF_SCR_CKE_2|SCIF_SCR_RIE);
#else
		WRITE_REGISTER_USHORT(pHWHead -> pSCR,
				 SCIF_SCR_TOIE|SCIF_SCR_TE|SCIF_SCR_RE|SCIF_SCR_REIE|SCIF_SCR_CKE_2);
#endif
		
    dma_InterruptEnable(pHWHead -> pRxDma);

    return TRUE;
}



//
// @doc OEM
// @func VOID | SCIF_ClearRTS | This routine clears RTS.
// 
// @rdesc None.
// 
VOID
SCIF3ClearRTS(
    PVOID   pHead // @parm PVOID returned by HWinit.
    )
{
    PSCIF_INFO   pHWHead   = (PSCIF_INFO)pHead;

    DEBUGMSG (ZONE_FUNCTION, (TEXT("+SerClearRTS, 0x%X\r\n"), pHead));
    EnterCriticalSection(&(pHWHead->RegCritSec));
    try {
    	// Clear RTS
        USHORT SPR = READ_REGISTER_USHORT(pHWHead -> pSPTR);
        SPR &= ~SCIF_SPTR_RTS;
        WRITE_REGISTER_USHORT(pHWHead -> pSPTR, SPR);
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        // Just exit
    }
    LeaveCriticalSection(&(pHWHead->RegCritSec));

    DEBUGMSG (ZONE_FUNCTION, (TEXT("-SerClearRTS, 0x%X\r\n"), pHead));
}

//
// @doc OEM
// @func VOID | SCIF_SetRTS | This routine sets RTS.
// 
// @rdesc None.
//
VOID
SCIF3SetRTS(

⌨️ 快捷键说明

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