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

📄 scif0.c

📁 WinCE5.0BSP for Renesas SH7770
💻 C
📖 第 1 页 / 共 2 页
字号:
// 
// @rdesc This routine returns a bitmask indicating which interrupts
//   are currently pending.
//
INTERRUPT_TYPE
SCIF0GetInterruptType(
    PVOID pHead      // Pointer to hardware head
    )
{
    PSCIF_INFO	pHWHead = (PSCIF_INFO)pHead;
    PDMA_INFO	pTxDma = pHWHead -> pTxDma;
    PDMA_INFO   pRxDma = pHWHead -> pRxDma;

    INTERRUPT_TYPE interrupts;
    USHORT	FSR;
    USHORT	LSR;

    DEBUGMSG (ZONE_THREAD,
              (TEXT("+SerGetInterruptType 0x%X\r\n"), pHead));
    try
    {
        FSR = READ_REGISTER_USHORT(pHWHead -> pFSR);
        LSR = READ_REGISTER_USHORT(pHWHead -> pLSR);
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        FSR = 0;
        LSR = 0;
    }

	// Clear InterruptType
    interrupts = INTR_NONE;

	// Check ErrorFlag
    if ( LSR & SCIF_LSR_ORER ||
//		FSR & (SCIF_SSR_BRK|SCIF_SSR_FER|SCIF_SSR_PER) ){
		FSR & (SCIF_SSR_ER|SCIF_SSR_BRK|SCIF_SSR_FER|SCIF_SSR_PER) ){
	
		DEBUGMSG(ZONE_THREAD,(TEXT("ERROR - FSR : 0x%x  LSR : 0x%x\r\n"),FSR,LSR));
					
        interrupts = INTR_LINE;

    }else if ( LSR & SCIF_LSR_TO ){
		interrupts = INTR_RX;
//		DEBUGMSG(ZONE_THREAD,(TEXT("SCIF Receive timeout FSR[%04x] LSR[%04x]\r\n"),FSR,LSR));
//		WRITE_REGISTER_USHORT(pHWHead -> pLSR,
//			READ_REGISTER_USHORT(pHWHead -> pLSR) & ~(SCIF_LSR_TO));

	// DMA Transfer complate (Receive)
    }else if (*(pRxDma -> pvDINTSR) & (0x00000001 << (pRxDma -> Ch))){
        interrupts = INTR_RX;
		WRITE_REGISTER_ULONG(pRxDma -> pvDINTCR, 0x00000001 << (pRxDma -> Ch));

	// DMA Transfer complate (Transmit)
    }else if (*(pTxDma -> pvDINTSR) & (0x00000001 << (pTxDma -> Ch))){
        interrupts = INTR_TX;
		WRITE_REGISTER_ULONG(pTxDma -> pvDINTCR, 0x00000001 << (pTxDma -> Ch));
		SetEvent(pHWHead->FlushDone);
    }

    if (pHWHead->AddTXIntr) {
        interrupts |= INTR_TX;
        pHWHead->AddTXIntr = FALSE;
    }

    DEBUGMSG (ZONE_THREAD,
          (TEXT("-SerGetInterruptType 0x%X, 0x%X\r\n"),
             pHead, interrupts));

    return interrupts;
}


#pragma optimize("", off)  
//
// @doc OEM
// @func ULONG | SerTXIntr | This routine is called from the new MDD
//   whenever INTR_TX is returned by SerGetInterruptType.  It is responsible
//   for loading up the TX FIFO with next block of data.
// 
// @rdesc None
//
VOID
SCIF0TxIntr(
    PVOID pHead,                // Hardware Head
    PUCHAR pTxBuffer,          // @parm Pointer to receive buffer
    ULONG *pBuffLen            // @parm In = max bytes to transmit, out = bytes transmitted
    )
{
	PSCIF_INFO pHWHead = (PSCIF_INFO)pHead;
	DWORD	byteCount, transCount;
	DWORD	dcr_value;
	USHORT	SPTR;
	UCHAR  dmy;

    DEBUGMSG (ZONE_WRITE, (TEXT("+PutBytes - sent %d.\r\n"),
                           *pBuffLen));
	if( *pBuffLen == 0 ){
		return;
	}

    // If CTS flow control is desired, check cts. If clear, don't send,
    // but loop.  When CTS comes back on, the OtherInt routine will
    // detect this and re-enable TX interrupts (causing Flushdone).
    // For finest granularity, we would check this in the loop below,
    // but for speed, I check it here (up to 8 xmit characters before
    // we actually flow off.

    if ( pHWHead->dcb.fOutxCtsFlow )
    {
        SPTR = ReadModemStatus( pHWHead );
        // We don't need to explicitly read the MSR, since we always enable
        // IER_MS, which ensures that we will get an interrupt and read
        // the MSR whenever CTS, DSR, TERI, or DCD change.

        if(! (pHWHead->SPTR & SCIF_SPTR_CTS) )
        {
            DEBUGMSG (ZONE_WRITE|ZONE_FLOW,
                      (TEXT("PutBytes, flowed off via CTS\n") ) );

            pHWHead->CTSFlowOff = TRUE;  // Record flowed off state
            WRITE_REGISTER_USHORT(pHWHead -> pSCR, READ_REGISTER_USHORT(pHWHead -> pSCR) & ~SCIF_SCR_TIE);
            // disable TX interrupts shile flowed off

            // We could return a positive value here, which would
            // cause the MDD to periodically check the flow control
            // status.  However, we don't need to since we know that
            // the DCTS interrupt will cause the MDD to call us, and we
            // will subsequently fake a TX interrupt to the MDD, causing
            // him to call back into PutBytes.
			*pBuffLen = 0;
            return;

        }

    }

    EnterCriticalSection(&(pHWHead->TransmitCritSec));

    if ( SCIF0_TXBUFFER_SIZE < *pBuffLen ){
        byteCount = SCIF0_TXBUFFER_SIZE;
    }else{
        byteCount = *pBuffLen;
    }

    DEBUGMSG (ZONE_WRITE | ZONE_THREAD,
              (TEXT("Put Bytes - Write max of %d bytes\r\n"),
               byteCount));

	*pBuffLen = 0;
    for( transCount = 0; byteCount; byteCount-- ){
 	*(pHWHead -> pTxBuff + (transCount++)) = *(pTxBuffer++);
        (*pBuffLen)++;
    }
    dmy = *(pHWHead -> pTxBuff + transCount - 1);	// Coherency measures  

//	WRITE_REGISTER_USHORT(pHWHead -> pSCR, READ_REGISTER_USHORT(pHWHead -> pSCR) & ~SCIF_SCR_TE);

    dcr_value = DCR_DPDS_8BIT		|
				DCR_DDRMD_MODULE	|
				DCR_DPDAM_FIX	 	|
				DCR_DMDL_PERIPHERAL	|
				DCR_SPDS_8BIT		|
				DCR_SDRMD_MODULE	|
				DCR_SPDAM_FIX		|
				DCR_SMDL_MEMORY		|
				DCR_DIP_1PAGE		|
				DCR_ACMD_DISABLE	|
				DCR_CT_DISABLE		|
				DCR_PKMD_DISABLE	|
				DCR_BTMD_ENABLE		|
				DCR_DTAU_BYTE		|
				DCR_DTAC_DISABLE	;	

	try {
		dma_SetPage(pHWHead -> pTxDma, 0, SCIF0_TX_BUFFER_BASE, SCIF0_REGBASE + SCIF_SCFTDR_OFFSET, (ULONG)transCount);
		dma_SetPort(pHWHead -> pTxDma, DPTR_DDPT_SCIF0);
		dma_SetControl(pHWHead -> pTxDma, dcr_value);
		dma_SetCommand(pHWHead -> pTxDma, DCMDR_DMEN);
		dma_InterruptEnable(pHWHead -> pTxDma);
	}
	except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
		EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
    }

    LeaveCriticalSection(&(pHWHead->TransmitCritSec));

    DEBUGMSG (ZONE_WRITE, (TEXT("-PutBytes - sent %d.\r\n"),
                           *pBuffLen));

    return;
}
#pragma optimize("", on)


//
// @doc OEM
// @func ULONG | SCIF0_OtherIntr | This routine is called from the MDD
//   whenever INTR_MODEM is returned by SCIF_GetInterruptType.
// 
// @rdesc None
//
VOID
SCIF0OtherIntr(
    PVOID pHead                // Hardware Head
    )
{
    PSCIF_INFO   pHWHead	= (PSCIF_INFO)pHead;
    USHORT MSR;

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

    MSR = (USHORT)ReadModemStatus( pHWHead );
    try
    {
        if ( pHWHead -> CTSFlowOff && (MSR & SCIF_SPTR_CTS) ){
            pHWHead -> CTSFlowOff = FALSE;
            WRITE_REGISTER_USHORT(pHWHead -> pSCR, READ_REGISTER_USHORT(pHWHead -> pSCR) | SCIF_SCR_TIE);
            pHWHead -> AddTXIntr = TRUE;
        }
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        // Just exit
    }
    

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


//
// @doc OEM
// @func ULONG | SL_OtherIntr | This routine is called from the MDD
//   whenever INTR_MODEM is returned by SL_GetInterruptType.
// 
// @rdesc None
//
VOID
SCIF0ModemIntr(
            PVOID pHead                // Hardware Head
            )
{
    SCIF0OtherIntr(pHead);
}


//  
// @doc OEM
// @func	ULONG | SerGetStatus | This structure is called by the MDD
//   to retrieve the contents of a COMSTAT structure.
//
// @rdesc	The return is a ULONG, representing success (0) or failure (-1).
//
ULONG
SCIF0GetStatus(
    PVOID	pHead,	// @parm PVOID returned by HWInit.
    LPCOMSTAT	lpStat	// Pointer to LPCOMMSTAT to hold status.
    )
{
    PSCIF_INFO pHWHead = (PSCIF_INFO)pHead;
    ULONG	  RetVal  = pHWHead->CommErrors;
    
    DEBUGMSG (ZONE_FUNCTION,
              (TEXT("+SCIF0GetStatus 0x%X\r\n"), pHead));

    pHWHead->CommErrors = 0; // Clear old errors each time

    if ( lpStat )
    {
        if ( pHWHead -> CTSFlowOff )
            pHWHead -> Status.fCtsHold = 1;
        else
            pHWHead -> Status.fCtsHold = 0;

        if ( pHWHead -> CommCharInQueue )
            pHWHead -> Status.fTxim = TRUE;
        else
            pHWHead -> Status.fTxim = FALSE;
        memcpy(lpStat, &(pHWHead->Status), sizeof(COMSTAT));
    }
    else
        RetVal = (ULONG)-1;

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


/*
 @doc OEM
 @func BOOL | SCIF_EnableIR | This routine enables ir.
 *  Not exported to users, only to driver.
 *
 @rdesc Returns TRUE if successful, FALSEotherwise.
 */
BOOL
SCIF0EnableIR(
    PVOID   pHead, // @parm PVOID returned by HWinit.
    ULONG   BaudRate  // @parm ULONG baudrate.
    )
{
    return FALSE;
}

/*
 @doc OEM
 @func BOOL | SCIF_DisableIR | This routine disable the ir.
 *  Not exported to users, only to driver.
 *
 @rdesc Returns TRUE if successful, FALSEotherwise.
 */
BOOL
SCIF0DisableIR(
    PVOID   pHead /*@parm PVOID returned by HWinit. */
    )
{
    return FALSE;
}


const
HW_VTBL SCIF0IoVTbl = {
    SCIF0Init,
    SCIF_PostInit,
    SCIF_Deinit,
    SCIF0Open,
    SCIF_Close,
    SCIF0GetInterruptType,
    SCIF_RxIntr,
    SCIF0TxIntr,
    SCIF0ModemIntr,
    SCIF_LineIntr,
    SCIF_GetRxBufferSize,
    SCIF_PowerOff,
    SCIF_PowerOn,
    SCIF_ClearDTR,
    SCIF_SetDTR,
    SCIF0ClearRTS,
    SCIF0SetRTS,
    SCIF0EnableIR,
    SCIF0DisableIR,
    SCIF_ClearBreak,
    SCIF_SetBreak,
    SCIF_XmitComChar,
    SCIF0GetStatus,
    SCIF_Reset,
    SCIF_GetModemStatus,
    SCIF_GetCommProperties,
    SCIF_PurgeComm,
    SCIF_SetDCB,
    SCIF_SetCommTimeouts,
    SCIF_Ioctl};

PHWOBJ
GetSerialObject(
               DWORD DeviceArrayIndex
               )
{
    PHWOBJ pSerObj;

    // We do not have a statically allocated array of HWObjs.  Instead, we 
    // allocate a new HWObj for each instance of the driver.  The MDD will 
    // always call GetSerialObj/HWInit/HWDeinit in that order, so we can do 
    // the alloc here and do any subsequent free in HWDeInit.

    // Allocate space for the HWOBJ.
    pSerObj = (PHWOBJ)LocalAlloc( LPTR, sizeof(HWOBJ) );
    if ( !pSerObj )
        return (NULL);

    // Fill in the HWObj structure that we just allocated.
    if( DeviceArrayIndex == 0 ){
        pSerObj->BindFlags = THREAD_AT_INIT;     // Have MDD create thread when device is first opened.
//        pSerObj->BindFlags = THREAD_IN_PDD;            // We take care of our own IST
        pSerObj->dwIntID   = SYSINTR_SCIF0;            // SysIntr is filled in at init time
        pSerObj->pFuncTbl  = (HW_VTBL *) &SCIF0IoVTbl; // Return pointer to appropriate functions
    }
    else{
        pSerObj->BindFlags = THREAD_AT_INIT;     // Have MDD create thread when device is first opened.
//        pSerObj->BindFlags = THREAD_IN_PDD;            // We take care of our own IST
        pSerObj->dwIntID   = SYSINTR_IR;               // SysIntr is filled in at init time
        pSerObj->pFuncTbl  = (HW_VTBL *) &SCIF3IoVTbl; // Return pointer to appropriate functions
    }

    // Now return this structure to the MDD.
    return (pSerObj);
}

⌨️ 快捷键说明

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