📄 pdd.c
字号:
DEBUGMSG(ZONE_FUNCTION, (L"-HWSetBreak\r\n"));
}
//------------------------------------------------------------------------------
//
// Function: HWReset
//
// This function performs any operations associated with a device reset.
//
static VOID HWReset(VOID *pvContext)
{
UARTPDD *pPdd = (UARTPDD*)pvContext;
DEBUGMSG(ZONE_FUNCTION, (L"+HWReset(0x%08x)\r\n", pvContext));
/* Modified BEGIN, by LONGCHEER SONGLIXIN, on: 2007-8-29 10:11:50 */
#if 0
EnterCriticalSection(&pPdd->hwCS);
// Enable interrupts
pPdd->intrMask = UART_IER_LINE|UART_IER_MODEM|UART_IER_RHR;
OUTREG8(&pPdd->pUARTRegs->IER, pPdd->intrMask);
LeaveCriticalSection(&pPdd->hwCS);
/*=========== replaced by ===================*/
#else
HWStartup(pPdd);
#endif
/* Modified END, by LONGCHEER SONGLIXIN, on: 2007-8-29 10:11:50 */
DEBUGMSG(ZONE_FUNCTION, (L"-HWReset\r\n"));
}
//------------------------------------------------------------------------------
//
// Function: HWGetModemStatus
//
// This function retrieves modem status.
//
static VOID HWGetModemStatus(VOID *pvContext, ULONG *pModemStat)
{
UARTPDD *pPdd = (UARTPDD*)pvContext;
UCHAR ucModemStat;
DEBUGMSG(ZONE_FUNCTION, (L"+HWGetModemStatus(0x%08x)\r\n", pvContext));
ucModemStat = ReadModemStat(pPdd);
*pModemStat = 0;
if ((ucModemStat & UART_MSR_NCTS) != 0) *pModemStat |= MS_CTS_ON;
if ((ucModemStat & UART_MSR_NDSR) != 0) *pModemStat |= MS_DSR_ON;
if ((ucModemStat & UART_MSR_NCD) != 0) *pModemStat |= MS_RLSD_ON;
DEBUGMSG(ZONE_FUNCTION, (L"-HWGetModemStatus(0x%08x)\r\n", *pModemStat));
}
//------------------------------------------------------------------------------
//
// Function: HWXmitComChar
//
// This function transmits a char immediately
//
static BOOL HWXmitComChar(VOID *pvContext, UCHAR ucCh)
{
UARTPDD *pPdd = (UARTPDD*)pvContext;
DEBUGMSG(ZONE_FUNCTION, (L"+HWXmitComChar(0x%08x, %d)\r\n", pvContext, ucCh));
EnterCriticalSection(&pPdd->txCS);
EnterCriticalSection(&pPdd->hwCS);
while (TRUE) { // We know THR will eventually empty
// Write the character if we can
if ((ReadLineStat(pPdd) & UART_LSR_TX_FIFO_E) != 0) {
// FIFO is empty, send this character
RegWrite(pPdd, XR20M1170REG_THR, ucCh);
// Enable TX interrupt
pPdd->intrMask |= UART_IER_THR;
RegWrite(pPdd, XR20M1170REG_IER, pPdd->intrMask);
break;
}
// If we couldn't write the data yet, then wait for a TX interrupt
pPdd->intrMask |= UART_IER_THR;
RegWrite(pPdd, XR20M1170REG_IER, pPdd->intrMask);
// Wait until the TX interrupt has signalled
WaitForSingleObject(pPdd->txEvent, 1000);
}
LeaveCriticalSection(&pPdd->hwCS);
LeaveCriticalSection(&pPdd->txCS);
DEBUGMSG(ZONE_FUNCTION, (L"-HWXmitComChar\r\n"));
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: HWGetStatus
//
// This function is called by the MDD to retrieve the contents of
// COMSTAT structure.
//
static ULONG HWGetStatus(VOID *pvContext, COMSTAT *pComStat)
{
ULONG ulRc = -1;
UARTPDD *pPdd = (UARTPDD*)pvContext;
DEBUGMSG(ZONE_FUNCTION, (L"+HWGetStatus(0x%08x, 0x%08x)\r\n", pvContext, pComStat));
if (pComStat == NULL) goto cleanUp;
pComStat->fCtsHold = pPdd->flowOffCTS ? 1 : 0;
pComStat->fDsrHold = pPdd->flowOffDSR ? 1 : 0;
pComStat->cbInQue = 0;
pComStat->cbOutQue = 0;
ulRc = pPdd->commErrors;
pPdd->commErrors = 0;
cleanUp:
DEBUGMSG(ZONE_FUNCTION, (L"-HWGetStatus(rc = %d)\r\n", ulRc));
return ulRc;
}
//------------------------------------------------------------------------------
static VOID HWGetCommProperties(VOID *pvContext, COMMPROP *pCommProp)
{
UARTPDD *pPdd = (UARTPDD*)pvContext;
DEBUGMSG(ZONE_FUNCTION, (L"+HWGetCommProperties(0x%08x, 0x%08x)\r\n", pvContext,pCommProp));
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 =
// On P2 DTR/DSR has a shortcut and RI/CD are not wired.
// PCF_DTRDSR | PCF_RLSD |
PCF_INTTIMEOUTS | PCF_PARITY_CHECK |
PCF_RTSCTS | PCF_SETXCHAR | PCF_SPECIALCHARS | PCF_TOTALTIMEOUTS |
PCF_XONXOFF;
pCommProp->dwSettableParams =
// On P2 RI/CD are not wired.
// SP_RLSD |
SP_BAUD | SP_DATABITS | SP_HANDSHAKING | SP_PARITY |
SP_PARITY_CHECK | 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"-HWGetCommProperties\r\n"));
}
//------------------------------------------------------------------------------
//
// Function: HWPurgeComm
//
// This function purges RX and/or TX
//
static VOID HWPurgeComm(VOID *pvContext, DWORD dwAction)
{
UARTPDD *pPdd = (UARTPDD*)pvContext;
UCHAR uFifoCtrl = 0;
DEBUGMSG(ZONE_FUNCTION, (L"+HWPurgeComm(0x%08x 0x%08x)\r\n", pvContext, dwAction));
EnterCriticalSection(&pPdd->hwCS);
if ((dwAction & PURGE_TXCLEAR) != 0) uFifoCtrl |= UART_FCR_TX_FIFO_CLEAR;
if ((dwAction & PURGE_RXCLEAR) != 0) uFifoCtrl |= UART_FCR_RX_FIFO_CLEAR;
RegWrite(pPdd, XR20M1170REG_FCR, UART_FCR_RX_FIFO_TRIG_8 | UART_FCR_TX_FIFO_TRIG_16 |\
uFifoCtrl | UART_FCR_FIFO_EN);
LeaveCriticalSection(&pPdd->hwCS);
DEBUGMSG(ZONE_FUNCTION, (L"-HWPurgeComm\r\n"));
}
//------------------------------------------------------------------------------
//
// Function: HWSetDCB
//
// 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(VOID *pvContext, DCB *pDCB)
{
UARTPDD *pPdd = (UARTPDD*)pvContext;
BOOL bRc = FALSE;
DEBUGMSG(ZONE_FUNCTION, (L"+HWSetDCB(0x%08x, 0x%08x\r\n", pvContext, pDCB));
// Check for same XON/XOFF characters...
if (
(pDCB->fOutX != 0 || pDCB->fInX != 0) &&
pDCB->XonChar == pDCB->XoffChar
) {
goto cleanUp;
}
// 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;
}
// Enable hardware auto RST/CTS modes...
if (pPdd->hwMode) {
if (pDCB->fRtsControl == RTS_CONTROL_HANDSHAKE) {
RETAILMSG(TRUE, (L"HWSetDCB: Set auto RTS\r\n"));
if (!SetAutoRTS(pPdd, TRUE)) goto cleanUp;
} else {
if (!SetAutoRTS(pPdd, FALSE)) goto cleanUp;
}
if (pDCB->fOutxCtsFlow) {
RETAILMSG(TRUE, (L"HWSetDCB: Set auto CTS\r\n"));
if (!SetAutoCTS(pPdd, TRUE)) goto cleanUp;
} else {
if (!SetAutoCTS(pPdd, TRUE)) goto cleanUp;
}
}
}
// Now that we have done the right thing, store this DCB
pPdd->dcb = *pDCB;
// All is fine
bRc = TRUE;
cleanUp:
DEBUGMSG(ZONE_FUNCTION, (L"-HWSetDCB(rc = %d)\r\n", bRc));
return bRc;
}
//------------------------------------------------------------------------------
//
// Function: HWSetCommTimeouts
//
// This function sets new values for the commTimeouts structure.
//
static ULONG HWSetCommTimeouts(VOID *pvContext, COMMTIMEOUTS *pCommTimeouts)
{
UARTPDD *pPdd = (UARTPDD*)pvContext;
DEBUGMSG(ZONE_FUNCTION, (L"+HWSetCommTimeouts()\r\n"));
pPdd->commTimeouts = *pCommTimeouts;
DEBUGMSG(ZONE_FUNCTION, (L"-HWSetCommTimeouts()\r\n"));
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: HWIOCtl
//
// This function process PDD IOCtl calls
//
static BOOL HWIOCtl(
VOID *pvContext, DWORD code, UCHAR *pInBuffer, DWORD inSize,
UCHAR *pOutBuffer, DWORD outSize, DWORD *pOutSize
) {
BOOL rc = FALSE;
UARTPDD *pPdd = (UARTPDD*)pvContext;
DEBUGMSG(ZONE_FUNCTION, (TEXT("+HWIOCtl()\r\n")));
switch (code) {
case IOCTL_SERIAL_SET_TIMEOUTS:
// Check input parameters
if (
pInBuffer == NULL || inSize < sizeof(COMMTIMEOUTS) ||
!CeSafeCopyMemory(
&pPdd->commTimeouts, pInBuffer, sizeof(COMMTIMEOUTS)
)
) {
SetLastError(ERROR_INVALID_PARAMETER);
break;
}
rc = TRUE;
break;
case IOCTL_SERIAL_GET_TIMEOUTS:
if (
pInBuffer == NULL || inSize < sizeof(COMMTIMEOUTS) ||
!CeSafeCopyMemory(
pInBuffer, &pPdd->commTimeouts, sizeof(COMMTIMEOUTS)
)
) {
SetLastError(ERROR_INVALID_PARAMETER);
break;
}
rc = TRUE;
break;
case IOCTL_POWER_CAPABILITIES:
if (pOutBuffer == NULL || outSize < sizeof(POWER_CAPABILITIES)) {
SetLastError(ERROR_INVALID_PARAMETER);
break;
}
__try {
POWER_CAPABILITIES *pPowerCaps = (POWER_CAPABILITIES*)pOutBuffer;
memset(pPowerCaps, 0, sizeof(POWER_CAPABILITIES));
pPowerCaps->DeviceDx = DX_MASK(D0)|DX_MASK(D3)|DX_MASK(D4);
rc = TRUE;
} __except(EXCEPTION_EXECUTE_HANDLER) {
DEBUGMSG(ZONE_ERROR, (L"ERROR: UART::HWIOCtl: "
L"Exception in IOCTL_POWER_CAPABILITIES\r\n"
));
}
break;
case IOCTL_POWER_QUERY:
if (pOutBuffer == NULL && outSize < sizeof(CEDEVICE_POWER_STATE)) {
SetLastError(ERROR_INVALID_PARAMETER);
break;
}
__try {
CEDEVICE_POWER_STATE dx = *(CEDEVICE_POWER_STATE*)pOutBuffer;
rc = VALID_DX(dx);
} __except(EXCEPTION_EXECUTE_HANDLER) {
DEBUGMSG(ZONE_ERROR, (L"ERROR: UART::HWIOCtl: "
L"Exception in IOCTL_POWER_QUERY\r\n"
));
}
break;
case IOCTL_POWER_SET:
if (pOutBuffer == NULL && outSize < sizeof(CEDEVICE_POWER_STATE)) {
SetLastError(ERROR_INVALID_PARAMETER);
break;
}
__try {
CEDEVICE_POWER_STATE dx = *(CEDEVICE_POWER_STATE*)pOutBuffer;
pPdd->externalDX = dx;
SetPower(pPdd, dx);
*(CEDEVICE_POWER_STATE*)pOutBuffer = pPdd->externalDX;
rc = TRUE;
} __except(EXCEPTION_EXECUTE_HANDLER) {
DEBUGMSG(ZONE_ERROR, (L"ERROR: UART::HWIOCtl: "
L"Exception in IOCTL_POWER_SET\r\n"
));
}
break;
case IOCTL_POWER_GET:
if (pOutBuffer == NULL && outSize < sizeof(CEDEVICE_POWER_STATE)) {
SetLastError(ERROR_INVALID_PARAMETER);
break;
}
__try {
*(CEDEVICE_POWER_STATE*)pOutBuffer = pPdd->externalDX;
rc = TRUE;
} __except(EXCEPTION_EXECUTE_HANDLER) {
DEBUGMSG(ZONE_ERROR, (L"ERROR: UART::HWIOCtl: "
L"Exception in IOCTL_POWER_GET\r\n"
));
}
break;
case IOCTL_XR20M1170_GPS_DOWNLOADBOOT:
gps_download(pPdd, 1);
HWStartup(pPdd);
break;
case IOCTL_XR20M1170_GPS_NORMALBOOT:
gps_download(pPdd, 0);
HWStartup(pPdd);
break;
case IOCTL_XR20M1170_ENABLE_LOOPBACK:
RegSetBit(pPdd, XR20M1170REG_MCR, BIT4);
break;
case IOCTL_XR20M1170_DISABLE_LOOPBACK:
RegClrBit(pPdd, XR20M1170REG_MCR, BIT4);
break;
}
DEBUGMSG(ZONE_FUNCTION, (TEXT("-HWIOCtl()\r\n")));
return rc;
}
//------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -