📄 pdd.c.bak
字号:
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 + -