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

📄 isr.cpp

📁 这个是串口驱动程序开发包
💻 CPP
📖 第 1 页 / 共 3 页
字号:
                                    // the code outside the main loop that
                                    // catches problems chips like the
                                    // SMC and the Winbond.
                                    m_TXHolding &= ~SERIAL_TX_XOFF;
                                }
                            }
                            goto ReceiveDoLineStatus;
                        }
                        // Check to see if we should note
                        // the receive character or special
                        // character event.
                        if (m_IsrWaitMask) 
                        {
                            if (m_IsrWaitMask & SERIAL_EV_RXCHAR) 
                                m_HistoryMask |= SERIAL_EV_RXCHAR;

                            if ((m_IsrWaitMask & SERIAL_EV_RXFLAG) &&
                                (m_SpecialChars.EventChar == ReceivedChar)) 
                            {
                                m_HistoryMask |= SERIAL_EV_RXFLAG;
                            }

                            if (m_IrpMaskLocation && m_HistoryMask) 
                            {
                                *m_IrpMaskLocation = m_HistoryMask;
                                m_IrpMaskLocation = NULL;
                                m_HistoryMask = 0;

                                m_CurrentWaitIrp.Information() = sizeof(ULONG);
                                m_KdDpc_CommWait.InsertQueue();
                            }
                        }

                        PutChar(ReceivedChar);

                        // If we're doing line status and modem
                        // status insertion then we need to insert
                        // a zero following the character we just
                        // placed into the buffer to mark that this
                        // was reception of what we are using to
                        // escape.
                        if (m_EscapeChar &&(m_EscapeChar==ReceivedChar)) 
                            PutChar(SERIAL_LSRMST_ESCAPE);

ReceiveDoLineStatus:    ;

                        if (!(ProcessLSR() &
                              SERIAL_LSR_DR)) 
                        {
                            // No more characters, get out of the
                            // loop.
                            break;
                        }
                    } while (TRUE);
                    break;

                case SERIAL_IIR_THR:
doTrasmitStuff:;
                    m_HoldingEmpty = TRUE;

                    if (m_WriteLength || m_TransmitImmediate ||
                        m_SendXoffChar || m_SendXonChar) 
                    {
                        // Even though all of the characters being
                        // sent haven't all been sent, this variable
                        // will be checked when the transmit queue is
                        // empty.  If it is still true and there is a
                        // wait on the transmit queue being empty then
                        // we know we finished transmitting all characters
                        // following the initiation of the wait since
                        // the code that initiates the wait will set
                        // this variable to false.
                        //
                        // One reason it could be false is that
                        // the writes were cancelled before they
                        // actually started, or that the writes
                        // failed due to timeouts.  This variable
                        // basically says a character was written
                        // by the isr at some point following the
                        // initiation of the wait.
                        m_EmptiedTransmit = TRUE;

                        // If we have output flow control based on
                        // the modem status lines, then we have to do
                        // all the modem work before we output each
                        // character. (Otherwise we might miss a
                        // status line change.)

                        if (m_HandFlow.ControlHandShake &
                            SERIAL_OUT_HANDSHAKEMASK) 
                        {
                            HandleModemUpdate(TRUE);
                        }

                        // We can only send the xon character if
                        // the only reason we are holding is because
                        // of the xoff.  (Hardware flow control or
                        // sending break preclude putting a new character
                        // on the wire.)

                        if (m_SendXonChar &&
                            !(m_TXHolding & ~SERIAL_TX_XOFF)) 
                        {
                            if ((m_HandFlow.FlowReplace & SERIAL_RTS_MASK) ==
                                 SERIAL_TRANSMIT_TOGGLE) 
                            {
                                // We have to raise if we're sending
                                // this character.
                                SetRTS();

                                m_PerfStats.TransmittedCount++;
                                m_pController->WriteByte(TRANSMIT_HOLDING_REGISTER, m_SpecialChars.XonChar);

                                m_KdDpc_StartTimerLowerRTSDpc.InsertQueue()
                                    ? m_CountOfTryingToLowerRTS++ : 0;
                            } 
                            else 
                            {
                                m_PerfStats.TransmittedCount++;
                                m_pController->WriteByte(TRANSMIT_HOLDING_REGISTER, m_SpecialChars.XonChar);
                            }

                            m_SendXonChar = FALSE;
                            m_HoldingEmpty = FALSE;

                            // If we send an xon, by definition we
                            // can't be holding by Xoff.

                            m_TXHolding &= ~SERIAL_TX_XOFF;

                            // If we are sending an xon char then
                            // by definition we can't be "holding"
                            // up reception by Xoff.

                            m_RXHolding &= ~SERIAL_RX_XOFF;

                        } 
                        else if (m_SendXoffChar && !m_TXHolding) 
                        {
                            if ((m_HandFlow.FlowReplace &
                                 SERIAL_RTS_MASK) ==
                                 SERIAL_TRANSMIT_TOGGLE) 
                            {

                                // We have to raise if we're sending
                                // this character.
                                SetRTS();

                                m_PerfStats.TransmittedCount++;
                                m_pController->WriteByte(TRANSMIT_HOLDING_REGISTER, m_SpecialChars.XoffChar);
                                m_KdDpc_StartTimerLowerRTSDpc.InsertQueue()
                                    ? m_CountOfTryingToLowerRTS++ : 0;
                            } 
                            else 
                            {
                                m_PerfStats.TransmittedCount++;
                                m_pController->WriteByte(TRANSMIT_HOLDING_REGISTER, m_SpecialChars.XoffChar);
                            }

                            // We can't be sending an Xoff character
                            // if the transmission is already held
                            // up because of Xoff.  Therefore, if we
                            // are holding then we can't send the char.

                            // If the application has set xoff continue
                            // mode then we don't actually stop sending
                            // characters if we send an xoff to the other
                            // side.

                            if (!(m_HandFlow.FlowReplace & SERIAL_XOFF_CONTINUE)) 
                            {
                                m_TXHolding |= SERIAL_TX_XOFF;

                                if ((m_HandFlow.FlowReplace & SERIAL_RTS_MASK) ==
                                     SERIAL_TRANSMIT_TOGGLE) 
                                {
                                    m_KdDpc_StartTimerLowerRTSDpc.InsertQueue()
                                        ? m_CountOfTryingToLowerRTS++ : 0;
                                }
                            }

                            m_SendXoffChar = FALSE;
                            m_HoldingEmpty = FALSE;

                        // Even if transmission is being held
                        // up, we should still transmit an immediate
                        // character if all that is holding us
                        // up is xon/xoff (OS/2 rules).

                        } 
                        else if (m_TransmitImmediate && 
                            (!m_TXHolding || (m_TXHolding == SERIAL_TX_XOFF))) 
                        {
                            m_TransmitImmediate = FALSE;

                            if ((m_HandFlow.FlowReplace & SERIAL_RTS_MASK) ==
                                 SERIAL_TRANSMIT_TOGGLE) 
                            {
                                // We have to raise if we're sending this character.
                                SetRTS();

                                m_PerfStats.TransmittedCount++;
                                m_pController->WriteByte(TRANSMIT_HOLDING_REGISTER, m_ImmediateChar);
                                m_KdDpc_StartTimerLowerRTSDpc.InsertQueue() ? m_CountOfTryingToLowerRTS++ : 0;
                            } 
                            else 
                            {
                                m_PerfStats.TransmittedCount++;
                                m_pController->WriteByte(TRANSMIT_HOLDING_REGISTER, m_ImmediateChar);
                            }

                            m_HoldingEmpty = FALSE;
                            m_KdDpc_CompleteImmediate.InsertQueue();

                        } 
                        else if (!m_TXHolding) 
                        {
                            ULONG amountToWrite;
                            if (m_FifoPresent) 
                            {
                                amountToWrite = (m_TxFifoAmount < m_WriteLength) ?
                                                m_TxFifoAmount : m_WriteLength;
                            } 
                            else 
                                amountToWrite = 1;
                            if ((m_HandFlow.FlowReplace & SERIAL_RTS_MASK) ==
                                 SERIAL_TRANSMIT_TOGGLE) 
                            {
                                // We have to raise if we're sending
                                // this character.

                                SetRTS();

                                if (amountToWrite == 1)
                                {
                                    m_PerfStats.TransmittedCount++;
                                    m_pController->WriteByte(TRANSMIT_HOLDING_REGISTER, *(m_WriteCurrentChar));
                                } 
                                else 
                                {
                                    m_PerfStats.TransmittedCount += amountToWrite;
                                    m_pController->WriteByte(TRANSMIT_HOLDING_REGISTER,
                                                             m_WriteCurrentChar,
                                                             amountToWrite);
                                }
                                m_KdDpc_StartTimerLowerRTSDpc.InsertQueue()
                                    ? m_CountOfTryingToLowerRTS++ : 0;
                            } 
                            else 
                            {
                                if (amountToWrite == 1) 
                                {
                                    m_PerfStats.TransmittedCount++;
                                    m_pController->WriteByte(TRANSMIT_HOLDING_REGISTER, *(m_WriteCurrentChar));
                                } 
                                else 
                                {
                                    m_PerfStats.TransmittedCount +=
                                        amountToWrite;
                                    m_pController->WriteByte(TRANSMIT_HOLDING_REGISTER,
                                                             m_WriteCurrentChar,
                                                             amountToWrite);
                                }
                            }

                            m_HoldingEmpty = FALSE;
                            m_WriteCurrentChar += amountToWrite;
                            m_WriteLength -= amountToWrite;

                            if (!m_WriteLength) 
                            {
                                // No More characters left.  This
                                // write is complete.  Take care
                                // when updating the information field,
                                // we could have an xoff counter masquerading
                                // as a write irp.

                                m_CurrentWriteIrp.Information() =
                                    m_CurrentWriteIrp.MajorFunction()==IRP_MJ_WRITE ?
                                        m_CurrentWriteIrp.WriteLength() : 1 ;

                                m_KdDpc_CompleteWrite.InsertQueue();
                            }
                        }
                    }
                    break;

                case SERIAL_IIR_MS:
                    HandleModemUpdate(FALSE);
                    break;
            }

        } while (!((InterruptIdReg = m_pController->ReadByte(INTERRUPT_IDENT_REGISTER))
                    & SERIAL_IIR_NO_INTERRUPT_PENDING));

        // Besides catching the WINBOND and SMC chip problems this
        // will also cause transmission to restart incase of an xon
        // char being received.  Don't remove.

        if (ProcessLSR() & SERIAL_LSR_THRE) 
        {
            if (!m_TXHolding && (m_WriteLength || m_TransmitImmediate)) 
                goto doTrasmitStuff;
        }
    }
    return ServicedAnInterrupt;
}

VOID KdSerialDevice::PutChar( IN UCHAR CharToPut )

/*++

Routine Description:

    This routine, which only runs at device level, takes care of
    placing a character into the typeahead (receive) buffer.

--*/

{
    // If we have dsr sensitivity enabled then
    // we need to check the modem status register
    // to see if it has changed.

    if (m_HandFlow.ControlHandShake &
        SERIAL_DSR_SENSITIVITY) 
    {
        HandleModemUpdate(FALSE);
        if (m_RXHolding & SERIAL_RX_DSR) 
        {
            // We simply act as if we haven't
            // seen the character if we have dsr
            // sensitivity and the dsr line is low.
            return;
        }
    }

    // If the xoff counter is non-zero then decrement it.
    // If the counter then goes to zero, complete that irp.

    if (m_CountSinceXoff) 
    {
        m_CountSinceXoff--;
        if (!m_CountSinceXoff) 
        {
            m_CurrentXoffIrp.Status() = STATUS_SUCCESS;
            m_CurrentXoffIrp.Information() = 0;
            m_KdDpc_XoffCountComplete.InsertQueue();
        }
    }

    // Check to see if we are copying into the
    // users buffer or into the interrupt buffer.
    //
    // If we are copying into the user buffer
    // then we know there is always room for one more.
    // (We know this because if there wasn't room
    // then that read would have completed and we
    // would be using the interrupt buffer.)
    //
    // If we are copying into the interrupt buffer
    // then we will need to check if we have enough
    // room.

⌨️ 快捷键说明

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