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

📄 ser2440_hw.c

📁 2440开发板pb4.2增加两个串口需更改的文件。
💻 C
📖 第 1 页 / 共 5 页
字号:
					{
						RETAILMSG (1, (TEXT("SL_TxInt : Error : i = %d \r\n"), i));
					}
				}

				++pTxBuffer;
				(*pBufflen)++;
			}

			if (FifoModeReg&0x1) // FIFO Mode enabled.
			{
				unsigned int cnt = 0;
				for ( ;; )
				{
					unsigned int tmpreg;
					tmpreg = INREG(pHWHead, rUFSTAT);
//					RETAILMSG(DEBUGMODE, (TEXT("SL_TxInt : Waiting till tx buffer empty :  tmpreg = %x \r\n"), tmpreg));
					if ( (tmpreg & 0xf0) == 0) break; // waitint to empty the tx buffer empty...
					if ( cnt++ > 600000 )
					{
						RETAILMSG(DEBUGMODE, (TEXT("SL_TxInt : Reset TX FIFO :  tmpreg = %x \r\n"), tmpreg));
						//SETREG(pHWHead,rUFCON,0x6);    // tx, rx fifo reset
						SETREG(pHWHead,rUFCON,0x4);    // tx, rx fifo reset
						break;
					}
				}
				RETAILMSG(DEBUGMODE, (TEXT("SL_TxInt : Exit for loop \r\n")));
			}

		}
		else
		{
			RETAILMSG (1, (TEXT("SL_TxIntrEx: Not Send - rFifoStat[0x%x] TxFifoCnt[0x%x]\r\n"),
							rFifoStat, TxFifoCnt));
		}

		if (pHWHead->UseIrDA )
		{
			// IR is half-duplex.
			ClearPendingInts( pHWHead );
			EnSubINT(pHWHead, pHWHead->bRxINT);
			pHWHead->RxDiscard = FALSE;
		}

		// Enable xmit intr. We need to do this no matter what, 
		// since the MDD relies on one final interrupt before
		// returning to the application. 
		ClearPendingInts( pHWHead );

		EnINT(pHWHead, pHWHead->bINT);
		EnSubINT(pHWHead, pHWHead->bTxINT);
		pHWHead->fSW_EnTxINT = TRUE;  // FALSE;
	}
	except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
		EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
		// Hmm, not sure what would cause this.  Lets just tell
		// the MDD to go away until we get another TX
		// interrupt.
	}
	LeaveCriticalSection(&(pHWHead->RegCritSec));
	LeaveCriticalSection(&(pHWHead->TransmitCritSec));
	return;
}

//
// @doc OEM
// @func ULONG | SL_LineIntr | This routine is called from the MDD
//   whenever INTR_LINE is returned by SL_GetInterruptType.
// 
// @rdesc None
//
VOID
SL_LineIntr(
           PVOID pHead                // Hardware Head
           )
{
	PS2440_UART_INFO   pHWHead    = (PS2440_UART_INFO)pHead;

	RETAILMSG(DEBUGMODE,(TEXT("INTR_LINE \r\n")));

	ReadLSR( pHWHead );

	ClearINTPnd(pHWHead, pHWHead->bINT);
	ClearSubINTPnd(pHWHead, pHWHead->bErrINT);
	EnINT(pHWHead, pHWHead->bINT);
	EnSubINT(pHWHead, pHWHead->bErrINT);
}

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

    // S2440 does not have modem interrupt.
  
    RETAILMSG(DEBUGMODE,(TEXT("+SL_OtherIntr \r\n")));

    ReadMSR( pHWHead );

    EnterCriticalSection(&(pHWHead->RegCritSec));
    try {
        // If we are currently flowed off via CTS or DSR, then
        // we better signal the TX thread when one of them changes
        // so that TX can resume sending.
        if ( pHWHead->DSRFlowOff && (pHWHead->vUMSTAT & COM2440_MSR_DSR) ) {
            RETAILMSG (DEBUGMODE, (TEXT("**********************PutBytes, flowed on via DSR\n") ) );
            pHWHead->DSRFlowOff = FALSE;
            // DSR is set, so go ahead and resume sending            
            EnINT(pHWHead, pHWHead->bINT);
            EnSubINT(pHWHead, pHWHead->bTxINT | pHWHead->bRxINT | pHWHead->bErrINT);
            pHWHead->fSW_EnTxINT = TRUE;
            // Then simulate a TX intr to get things moving
            pHWHead->AddTXIntr = TRUE;
        }
        if ( pHWHead->CTSFlowOff && (pHWHead->vUMSTAT & COM2440_MSR_CTS) ) {
            RETAILMSG(DEBUGMODE, (TEXT("***********************PutBytes, flowed on via CTS\n") ) );
            pHWHead->CTSFlowOff = FALSE;
            // CTS is set, so go ahead and resume sending
            EnINT(pHWHead, pHWHead->bINT);
            EnSubINT(pHWHead, pHWHead->bTxINT | pHWHead->bRxINT | pHWHead->bErrINT);
            pHWHead->fSW_EnTxINT = TRUE;
            // Then simulate a TX intr to get things moving
            pHWHead->AddTXIntr = TRUE;
        }
        
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        // Just exit
    }

    LeaveCriticalSection(&(pHWHead->RegCritSec));

    RETAILMSG(DEBUGMODE,(TEXT("-SL_OtherIntr 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
SL_ModemIntr(
            PVOID pHead                // Hardware Head
            )
{
	PS2440_UART_INFO   pHWHead    = (PS2440_UART_INFO)pHead;
	INTERRUPT_TYPE      it = INTR_NONE;
	ULONG               win32status = 0;

	RETAILMSG (DEBUGMODE, (TEXT("SL_ModemIntr - pHWHead->OpenCount %d \r\n"), pHWHead->OpenCount));
	if ( !pHWHead->OpenCount ) {
		// We want to indicate a cable event.
		RETAILMSG (DEBUGMODE, (TEXT("Indicating RS232 Cable Event\r\n")));

		if ( IsAPIReady(SH_WMGR) ) {
			CeEventHasOccurred (NOTIFICATION_EVENT_RS232_DETECTED,NULL);
		}
	}
	else
	{
		RETAILMSG(1,(TEXT("+SL_ModemIntr 0x%X\r\n"), pHead));
		SL_OtherIntr(pHead);
	}
}

//  
// @doc OEM
// @func    ULONG | SL_GetStatus | 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
SL_GetStatus(
            PVOID    pHead,    // @parm PVOID returned by HWInit.
            LPCOMSTAT    lpStat    // Pointer to LPCOMMSTAT to hold status.
            )
{
    PS2440_UART_INFO pHWHead = (PS2440_UART_INFO)pHead;
    ULONG      RetVal  = pHWHead->CommErrors;

	RETAILMSG(1, (TEXT("+SL_GetStatus 0x%X\r\n"), pHead));
	pHWHead->CommErrors = 0; // Clear old errors each time

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

            if (pHWHead->DSRFlowOff)
                pHWHead->Status.fDsrHold = 1;
            else
                pHWHead->Status.fDsrHold = 0;

            // NOTE - I think what they really want to know here is
            // the amount of data in the MDD buffer, not the amount
            // in the UART itself.  Just set to 0 for now since the
            // MDD doesn't take care of this.
            pHWHead->Status.cbInQue  = 0;
            pHWHead->Status.cbOutQue = 0;

            memcpy(lpStat, &(pHWHead->Status), sizeof(COMSTAT));
        }
        except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
                EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
            RetVal = (ULONG)-1;
        }        
    } else
        RetVal = (ULONG)-1;

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

//
// @doc OEM
// @func    ULONG | SL_Reset | Perform any operations associated
//   with a device reset
//
// @rdesc    None.
//
VOID
SL_Reset(
        PVOID   pHead    // @parm PVOID returned by HWInit.
        )
{
	PS2440_UART_INFO pHWHead = (PS2440_UART_INFO)pHead;

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

	memset(&pHWHead->Status, 0, sizeof(COMSTAT));

	EnterCriticalSection(&(pHWHead->RegCritSec));
	try {
		DisEnINT(pHWHead, pHWHead->bINT);
		DisEnSubINT(pHWHead, pHWHead->bTxINT);
		//	if ( GetSubINTStatus(pHWHead) )
		pHWHead->fSW_EnTxINT = FALSE;
		pHWHead->RxDiscard = FALSE;
	}
	except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
		EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
		// Do nothing
	}
	LeaveCriticalSection(&(pHWHead->RegCritSec));

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

//
// @doc OEM
// @func    VOID | SL_GetModemStatus | Retrieves modem status.
//
// @rdesc    None.
//
VOID
SL_GetModemStatus(
                 PVOID   pHead,        // @parm PVOID returned by HWInit.
                 PULONG  pModemStatus    // @parm PULONG passed in by user.
                 )
{
	PS2440_UART_INFO pHWHead = (PS2440_UART_INFO)pHead;
	UINT8 ubModemStatus;

	RETAILMSG(DEBUGMODE,  (TEXT("SL_GetModemStatus:\r\n")));

	ReadMSR( pHWHead );
	ubModemStatus = (unsigned char)pHWHead->vUMSTAT;
	RETAILMSG(DEBUGMODE,  (TEXT("SL_GetModemStatus: ubModemStatus = 0x%x\r\n"), ubModemStatus));

	if ( ubModemStatus & COM2440_MSR_CTS )
		*pModemStatus |= MS_CTS_ON;
	if ( ubModemStatus & COM2440_MSR_DSR )  {
		*pModemStatus |= MS_DSR_ON;
		*pModemStatus |= MS_RLSD_ON;
	}

	RETAILMSG(DEBUGMODE,(TEXT("-SL_GetModemStatus 0x%X (stat x%X) \r\n"), pHead, *pModemStatus));
	return;
}

//
// @doc OEM
// @func    VOID | SL_PurgeComm | Purge RX and/or TX
// 
// @rdesc    None.
//

VOID
SL_PurgeComm(
            PVOID   pHead,        // @parm PVOID returned by HWInit.
            DWORD   fdwAction        // @parm Action to take. 
            )
{
	PS2440_UART_INFO pHWHead = (PS2440_UART_INFO)pHead;

	RETAILMSG(DEBUGMODE,(TEXT("+SL_PurgeComm 0x%X\r\n"), fdwAction));
	return;
}

//
// @doc OEM
// @func    BOOL | SL_XmitComChar | Transmit a char immediately
// 
// @rdesc    TRUE if succesful
//
BOOL
SL_XmitComChar(
              PVOID   pHead,    // @parm PVOID returned by HWInit.
              UCHAR   ComChar   // @parm Character to transmit. 
              )
{
	PS2440_UART_INFO pHWHead = (PS2440_UART_INFO)pHead;
	ULONG       rFifoStat, TxFifoCnt; 

	RETAILMSG (DEBUGMODE,(TEXT("+SL_XmitComChar 0x%X\r\n"), pHead));
	// Get critical section, then transmit when buffer empties
	RETAILMSG(DEBUGMODE, (TEXT("XmitComChar wait for CritSec %x.\r\n"),&(pHWHead->TransmitCritSec)));
	EnterCriticalSection(&(pHWHead->TransmitCritSec));
	RETAILMSG(DEBUGMODE, (TEXT("XmitComChar got CritSec %x.\r\n"),&(pHWHead->TransmitCritSec)));
	try {
		while ( TRUE ) {  // We know THR will eventually empty
			EnterCriticalSection(&(pHWHead->RegCritSec));
			// Write the character if we can
			rFifoStat = INREG(pHWHead,rUFSTAT);
			TxFifoCnt = (rFifoStat & SER2440_FIFOCNT_MASK_TX) >> 4;

			if (!(rFifoStat & SER2440_FIFOFULL_TX) && (TxFifoCnt < (SER2440_FIFO_DEPTH_TX-1))) {
				// FIFO is empty, send this character
				//OUTB(pHWHead, pData, ComChar);
				OUTREG(pHWHead,rUTXH,ComChar);
				// Make sure we release the register critical section
				LeaveCriticalSection(&(pHWHead->RegCritSec));

				RETAILMSG(DEBUGMODE, (TEXT("XmitComChar wrote x%X\r\n"),ComChar));
				break;
			}

			// If we couldn't write the data yet, then wait for a
			// TXINTR to come in and try it again.

			// Enable xmit intr.
			EnINT(pHWHead, pHWHead->bINT);
			EnSubINT(pHWHead, pHWHead->bTxINT | pHWHead->bRxINT | pHWHead->bErrINT);
			pHWHead->fSW_EnTxINT = TRUE;
			LeaveCriticalSection(&(pHWHead->RegCritSec));

			// Wait until the txintr has signalled.
			DEBUGMSG (ZONE_WRITE, (TEXT("XmitComChar WaitIntr x%X\r\n"),
						pHWHead->FlushDone));
			WaitForSingleObject(pHWHead->FlushDone, (ULONG)1000);
		}
	}
	except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
		EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
		// Make sure we release the register critical section
		LeaveCriticalSection(&(pHWHead->RegCritSec));
	}

	LeaveCriticalSection(&(pHWHead->TransmitCritSec));
	DEBUGMSG (ZONE_WRITE, (TEXT("XmitComChar released CritSec %x.\r\n"),
					&(pHWHead->TransmitCritSec)));

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

	return(TRUE);
}

//
// @doc OEM
// @func    BOOL | SL_PowerOff | Perform powerdown sequence.
// 
// @rdesc    TRUE if succesful
//
VOID
SL_PowerOff(
           PVOID   pHead        // @parm    PVOID returned by HWInit.
           )
{
	PS2440_UART_INFO   pHWHead   = (PS2440_UART_INFO)pHead;

	RETAILMSG(DEBUGMODE, (TEXT("SL_PowerOff \r\n")));
	pHWHead->sULCON = INREG(pHWHead, rULCON);
	pHWHead->sUCON  = INREG(pHWHead, rUCON);
	pHWHead->sUMCON = INREG(pHWHead, rUMCON);
	pHWHead->sUFCON = INREG(pHWHead, rUFCON);        
	pHWHead->sINTstat = (*(pHWHead->UART_INTSUBMASK) & (pHWHead->bTxINT | pHWHead->bRxINT));
}

//
// @doc OEM
// @func    BOOL | SL_PowerOn | Perform poweron sequence.
// 
// @rdesc    TRUE if succesful
//
VOID
SL_PowerOn(
          PVOID   pHead        // @parm    PVOID returned by HWInit.
          )
{
	PS2440_UART_INFO pHWHead = (PS2440_UART_INFO)pHead;

	// Restore any registers that we need
	RETAILMSG(DEBUGMODE, (TEXT("SL_PowerOn \r\n")));

	// In power handler context, so don't try to do a critical section
	OUTREG(pHWHead, rULCON, pHWHead->sULCON); 
	OUTREG(pHWHead, rUCON,  pHWHead->sUCON); 
	OUTREG(pHWHead, rUMCON, pHWHead->sUMCON); 
	OUTREG(pHWHead, rUFCON, pHWHead->sUFCON); 
	if((pHWHead->sINTstat) & (pHWHead->bTxINT))  {
		EnINT(pHWHead, pHWHead->bINT);
		EnSubINT(pHWHead, pHWHead->bTxINT);
		pHWHead->fSW_EnTxINT = TRUE;
		pHWHead->RxDiscard = FALSE;
	}
	if((pHWHead->sINTstat) & (pHWHead->bRxINT))
	{
		EnINT(pHWHead, pHWHead->bINT);
		EnSubINT(pHWHead, pHWHead->bRxINT);
	}

	// And we didn't save the Divisor Reg, so set baud rate
	// But d

⌨️ 快捷键说明

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