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

📄 pdd.c.bak

📁 基于WinCE 5.0 下的MIPS 32 内核的Au1200(AMD)的UART驱动
💻 BAK
📖 第 1 页 / 共 3 页
字号:
	return 0;
}

//------------------------------------------------------------------------------

static BOOL HWPowerOff(PVOID pContext)
{
	UARTPDD *pPdd = (UARTPDD *)pContext;

	// Save registers to be able power on
	pPdd->fifoCtrl = INP32(&pPdd->pPortBase->fifoctrl);
	pPdd->lineCtrl = INP32(&pPdd->pPortBase->linectrl);
	pPdd->mdmCtrl  = INP32(&pPdd->pPortBase->mdmctrl);
	pPdd->clkDiv   = INP32(&pPdd->pPortBase->clkdiv);

	// Disable device and clock
	OUT32(&pPdd->pPortBase->enable, 0);

	// Set flag
	pPdd->powerOff = TRUE;

	// We are done 
	return TRUE;
}

//------------------------------------------------------------------------------

static BOOL HWPowerOn(PVOID pContext)
{
	UARTPDD *pPdd = (UARTPDD *)pContext;

	// Do power-on only if there was power-off
	if (pPdd->powerOff) {

		// Allow device clock
		OUT32(&pPdd->pPortBase->enable, UART_ENABLE_CE);

		// Then device itself
		OUT32(&pPdd->pPortBase->enable, UART_ENABLE_CE|UART_ENABLE_E);

		// Restore any registers that we need
		OUT32(&pPdd->pPortBase->fifoctrl, pPdd->fifoCtrl);
		OUT32(&pPdd->pPortBase->linectrl, pPdd->lineCtrl);
		OUT32(&pPdd->pPortBase->mdmctrl,  pPdd->mdmCtrl);
		OUT32(&pPdd->pPortBase->clkdiv,   pPdd->clkDiv);

		// Reset flag   
		pPdd->powerOff = FALSE;
	}
	return TRUE;
}

//------------------------------------------------------------------------------
//
// Function:     HWClearDTR
//
// Description:  This function clears DTR.
//

static VOID HWClearDTR(PVOID pContext)
{
	UARTPDD *pPdd = (UARTPDD*)pContext;
	UCHAR mdmCtrl;

	DEBUGMSG(ZONE_FUNCTION, (L"+au1uart::HWClearDTR 0x%x\n", pContext));

	EnterCriticalSection(&pPdd->hwCS);
	mdmCtrl = INP32(&pPdd->pPortBase->mdmctrl);
	OUT32(&pPdd->pPortBase->mdmctrl, mdmCtrl & ~UART_MDMCTRL_DT);
	LeaveCriticalSection(&pPdd->hwCS);

	DEBUGMSG(ZONE_FUNCTION, (L"-au1uart::HWClearDTR\n"));
}

//------------------------------------------------------------------------------
//
// Function:     HWSetDTR
//
// Description:  This function sets DTR.
//

static VOID HWSetDTR(PVOID pContext)
{
	UARTPDD *pPdd = (UARTPDD*)pContext;
	UCHAR mdmCtrl;

	DEBUGMSG(ZONE_FUNCTION, (L"+au1uart::HWSetDTR 0x%x\n", pContext));

	EnterCriticalSection(&pPdd->hwCS);
	mdmCtrl = INP32(&pPdd->pPortBase->mdmctrl);
	OUT32(&pPdd->pPortBase->mdmctrl, mdmCtrl | UART_MDMCTRL_DT);
	LeaveCriticalSection(&pPdd->hwCS);

	DEBUGMSG(ZONE_FUNCTION, (L"-au1uart::HWSetDTR\n"));
}

//------------------------------------------------------------------------------
//
// Function:     HWClearRTS
//
// Description:  This function clears RTS.
//

static VOID HWClearRTS(PVOID pContext)
{
	UARTPDD *pPdd = (UARTPDD*)pContext;
	UCHAR mdmCtrl;

	DEBUGMSG(ZONE_FUNCTION, (L"+au1uart::HWClearRTS 0x%x\n", pContext));

	EnterCriticalSection(&pPdd->hwCS);
	mdmCtrl = INP32(&pPdd->pPortBase->mdmctrl);
	OUT32(&pPdd->pPortBase->mdmctrl, mdmCtrl & ~UART_MDMCTRL_RT);
	LeaveCriticalSection(&pPdd->hwCS);

	DEBUGMSG(ZONE_FUNCTION, (L"-au1uart::HWClearRTS\n"));
}

//------------------------------------------------------------------------------
//
// Function:     HWSetRTS
//
// Description:  This function sets RTS.
//

static VOID HWSetRTS(PVOID pContext)
{
	UARTPDD *pPdd = (UARTPDD*)pContext;
	UCHAR mdmCtrl;

	DEBUGMSG(ZONE_FUNCTION, (L"+au1uart::HWSetRTS 0x%x\n", pContext));

	EnterCriticalSection(&pPdd->hwCS);
	mdmCtrl = INP32(&pPdd->pPortBase->mdmctrl);
	OUT32(&pPdd->pPortBase->mdmctrl, mdmCtrl | UART_MDMCTRL_RT);
	LeaveCriticalSection(&pPdd->hwCS);

	DEBUGMSG(ZONE_FUNCTION, (L"-au1uart::HWSetRTS\n"));
}

//------------------------------------------------------------------------------

static BOOL HWEnableIR(PVOID pContext, ULONG baudRate)
{
	return TRUE;
}

//------------------------------------------------------------------------------

static BOOL HWDisableIR(PVOID pContext)
{
	return TRUE;
}

//------------------------------------------------------------------------------
//
// Function:     HWClearBreak
//
// Description:  This function clears break.
//

static VOID HWClearBreak(PVOID pContext)
{
	UARTPDD *pPdd = (UARTPDD*)pContext;
	UCHAR lineCtrl;

	DEBUGMSG(ZONE_FUNCTION, (L"+au1uart::HWClearBreak 0x%x\n", pContext));

	EnterCriticalSection(&pPdd->hwCS);
	lineCtrl = INP32(&pPdd->pPortBase->linectrl);
	OUT32(&pPdd->pPortBase->linectrl, lineCtrl&~UART_LINECTRL_SB);
	LeaveCriticalSection(&pPdd->hwCS);

	DEBUGMSG(ZONE_FUNCTION, (L"-au1uart::HWClearBreak\n"));
}

//------------------------------------------------------------------------------
//
// Function:     HWSetBreak
//
// Description:  This function sets break.
//

static VOID HWSetBreak(PVOID pContext)
{
	UARTPDD *pPdd = (UARTPDD*)pContext;
	UCHAR lineCtrl;

	DEBUGMSG(ZONE_FUNCTION, (L"+au1uart::HWSetBreak 0x%x\n", pContext));

	EnterCriticalSection(&pPdd->hwCS);
	lineCtrl = INP32(&pPdd->pPortBase->linectrl);
	OUT32(&pPdd->pPortBase->linectrl, lineCtrl|UART_LINECTRL_SB);
	LeaveCriticalSection(&pPdd->hwCS);

	DEBUGMSG(ZONE_FUNCTION, (L"-au1uart::HWSetBreak\n"));
}

//------------------------------------------------------------------------------
//
// Function:     HWReset
//
// Description:  This function performs any operations associated 
//               with a device reset.
//

static VOID HWReset(PVOID pContext)
{
	UARTPDD *pPdd = (UARTPDD*)pContext;

	DEBUGMSG(ZONE_FUNCTION, (L"+au1uart::HWReset 0x%x\n", pContext));

	EnterCriticalSection(&pPdd->hwCS);
	// Enable interrupts
	OUT32(&pPdd->pPortBase->inten, UART_INTEN_TX_OFF);
	LeaveCriticalSection(&pPdd->hwCS);

	DEBUGMSG(ZONE_FUNCTION, (L"-au1uart::HWReset\n"));
}

//------------------------------------------------------------------------------
//
// Function:     HWGetModemStatus
//
// Description:  This function retrieves modem status.
//

static VOID HWGetModemStatus(PVOID pContext, ULONG *pModemStat)
{
	UARTPDD *pPdd = (UARTPDD*)pContext;
	UCHAR modemStat;

	DEBUGMSG(ZONE_FUNCTION, (L"+au1uart::HWGetModemStatus 0x%x\n", pContext));

	modemStat = ReadModemStat(pPdd);

	*pModemStat = 0;
	if ((modemStat & UART_MDMSTAT_CT) != 0) *pModemStat |= MS_CTS_ON;
	if ((modemStat & UART_MDMSTAT_DS) != 0) *pModemStat |= MS_DSR_ON;
	if ((modemStat & UART_MDMSTAT_RI) != 0) *pModemStat |= MS_RING_ON;
	if ((modemStat & UART_MDMSTAT_CD) != 0) *pModemStat |= MS_RLSD_ON;

	DEBUGMSG(ZONE_FUNCTION, (L"-au1uart::HWGetModemStatus (0x%x)\n", *pModemStat));
}

//------------------------------------------------------------------------------
//
// Function:     HWXmitComChar
//
// Description:  This function transmits a char immediately
//

static BOOL HWXmitComChar(PVOID pContext, UCHAR ch)
{
	UARTPDD *pPdd = (UARTPDD*)pContext;

	DEBUGMSG(ZONE_FUNCTION, (L"+au1uart::HWXmitComChar 0x%x %d\n", pContext, ch));

	EnterCriticalSection(&pPdd->txCS);

	while (TRUE) {  // We know THR will eventually empty

		EnterCriticalSection(&pPdd->hwCS);

		// Write the character if we can
		if ((ReadLineStat(pPdd) & UART_LINESTAT_TT) != 0) {
			// FIFO is empty, send this character
			OUT32(&pPdd->pPortBase->txdata, ch);
			// Enable TX interrupt
			OUT32(&pPdd->pPortBase->inten, UART_INTEN_TX_ON);
			LeaveCriticalSection(&pPdd->hwCS);
			break;
		}

		// If we couldn't write the data yet, then wait for a TX interrupt
		OUT32(&pPdd->pPortBase->inten, UART_INTEN_TX_ON);
		LeaveCriticalSection(&pPdd->hwCS);

		// Wait until the TX interrupt has signalled
		WaitForSingleObject(pPdd->txEvent, (ULONG)1000);
	}

	LeaveCriticalSection(&pPdd->txCS);

	DEBUGMSG(ZONE_FUNCTION, (L"-au1uart::HWXmitComChar\n"));
	return TRUE;
}

//------------------------------------------------------------------------------
//  
// Function:     HWGetStatus
//
// Description:  This function is called by the MDD to retrieve the contents
//               of a COMSTAT structure.
//

static ULONG HWGetStatus(PVOID pContext, COMSTAT *pComStat)
{
	ULONG rc = -1;
	UARTPDD *pPdd = (UARTPDD*)pContext;

	DEBUGMSG(ZONE_FUNCTION, (L"+au1uart::HWGetStatus 0x%x\n", pContext));

	if (pComStat == NULL) goto cleanUp;

	pComStat->fCtsHold = pPdd->flowOffCTS ? 1 : 0;
	pComStat->fDsrHold = pPdd->flowOffDSR ? 1 : 0;
	pComStat->cbInQue  = 0;
	pComStat->cbOutQue = 0;

	rc = pPdd->commErrors;
	pPdd->commErrors = 0;

cleanUp:
	DEBUGMSG(ZONE_FUNCTION, (L"-au1uart::HWGetStatus %d\n", rc));
	return rc;
}

//------------------------------------------------------------------------------

static VOID HWGetCommProperties(PVOID pContext, COMMPROP *pCommProp)
{
	UARTPDD *pPdd = (UARTPDD*)pContext;

	DEBUGMSG(ZONE_FUNCTION, (L"+au1uart::HWGetCommProper 0x%x\n", pContext));

	memset(pCommProp, 0, sizeof(COMMPROP));
	pCommProp->wPacketLength = 0xffff;
	pCommProp->wPacketVersion = 0xffff;
	pCommProp->dwServiceMask = SP_SERIALCOMM;
	pCommProp->dwMaxTxQueue = 16;
	pCommProp->dwMaxRxQueue = 16;
	pCommProp->dwMaxBaud = BAUD_USER;
	pCommProp->dwProvSubType = PST_RS232;

	pCommProp->dwProvCapabilities = PCF_DTRDSR | PCF_INTTIMEOUTS | PCF_PARITY_CHECK | PCF_RLSD | 
	                                PCF_RTSCTS | PCF_SETXCHAR | PCF_SPECIALCHARS | 
	                                PCF_TOTALTIMEOUTS | PCF_XONXOFF;

	pCommProp->dwSettableParams = SP_BAUD | SP_DATABITS | SP_HANDSHAKING | SP_PARITY |
	                              SP_PARITY_CHECK | SP_RLSD | SP_STOPBITS;

	pCommProp->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 | BAUD_115200;

	pCommProp->wSettableData = DATABITS_5 | DATABITS_6 | DATABITS_7 | DATABITS_8;

	pCommProp->wSettableStopParity = STOPBITS_10 | STOPBITS_20 |
	                                 PARITY_NONE | PARITY_ODD | PARITY_EVEN | PARITY_SPACE |
	                                 PARITY_MARK;

	DEBUGMSG(ZONE_FUNCTION, (L"-au1uart::HWGetCommProper\n"));
}

//------------------------------------------------------------------------------
//
// Function:     HWPurgeComm
//
// Description:  This function purges RX and/or TX
// 

static VOID HWPurgeComm(PVOID pContext, DWORD action)
{
	UARTPDD *pPdd = (UARTPDD*)pContext;
	UCHAR fifoCtrl;

	DEBUGMSG(ZONE_FUNCTION, (L"+au1uart::HWPurgeComm 0x%x 0x%x\n", pContext, action));

	EnterCriticalSection(&pPdd->hwCS);
	fifoCtrl = INP32(&pPdd->pPortBase->fifoctrl);
	if ((action & PURGE_TXCLEAR) != 0) fifoCtrl |= UART_FIFOCTRL_TR;
	if ((action & PURGE_RXCLEAR) != 0) fifoCtrl |= UART_FIFOCTRL_RR;
	OUT32(&pPdd->pPortBase->fifoctrl, fifoCtrl);
	LeaveCriticalSection(&pPdd->hwCS);

	DEBUGMSG(ZONE_FUNCTION, (L"-au1uart::HWPurgeComm\n"));
}

//------------------------------------------------------------------------------
//
// Function:     HWSetDCB
//
// Description:  This function sets new values for DCB. It gets a DCB from
//               the MDD and compare it to the current DCB, and if any fields
//               have changed take appropriate action.
//

static BOOL HWSetDCB(PVOID pContext, DCB *pDCB)
{
	UARTPDD *pPdd = (UARTPDD*)pContext;
	BOOL ok = FALSE;

	DEBUGMSG(ZONE_FUNCTION, (L"+au1uart::HWSetDCB 0x%x\n", pContext));

	// If the device is open, scan for changes and do whatever
	// is needed for the changed fields.  if the device isn't
	// open yet, just save the DCB for later use by the open.
	if (pPdd->open) {

		if (pDCB->BaudRate != pPdd->dcb.BaudRate) {
			if (!SetBaudRate(pPdd, pDCB->BaudRate)) goto cleanUp;
		}

		if (pDCB->ByteSize != pPdd->dcb.ByteSize) {
			if (!SetWordLength(pPdd, pDCB->ByteSize)) goto cleanUp;
		}

		if (pDCB->Parity != pPdd->dcb.Parity) {
			if (!SetParity(pPdd, pDCB->Parity)) goto cleanUp;
		}

		if (pDCB->StopBits != pPdd->dcb.StopBits) {
			if (!SetStopBits(pPdd, pDCB->StopBits)) goto cleanUp;
		}
	}

	// Now that we have done the right thing, store this DCB
	pPdd->dcb = *pDCB;

	// All is fine
	ok = TRUE;

cleanUp:
	DEBUGMSG(ZONE_FUNCTION, (L"-au1uart::HWSetDCB %s\n", ok?L"TRUE":L"FALSE"));
	return ok;
}

//------------------------------------------------------------------------------
//
// Function:     HWSetCommTimeouts
//
// Description:  This function sets new values for the CommTimeouts structure.
//               For 16550 like chip there is nothing to do...
// 

static ULONG HWSetCommTimeouts(PVOID pContext, COMMTIMEOUTS *pCommTimeouts)
{
	return 0;
}

//------------------------------------------------------------------------------
//
// Function:     HWIOCtl
//
// Description:  This function process PDD IOCtl calls (none at moment)
//

static BOOL HWIOCtl(
	PVOID pContext, DWORD code, UCHAR *pInpBuffer, DWORD inpSize,
	UCHAR *pOutBuffer, DWORD outSize, DWORD *pOutSize
) {
	return FALSE;
}

//------------------------------------------------------------------------------

⌨️ 快捷键说明

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