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

📄 mpu.cpp

📁 提供了一个对mpu401芯片的接口的midi uart miniport的wdm驱动程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
            _DbgPrintF(DEBUGLVL_TERSE,("SynchronizedMPUWrite failed (0x%08x)",ntStatus));
            break;
        }
    }
//    if (context->Miniport->m_NumCaptureStreams)
    {
            readStatus = MPUInterruptServiceRoutine(InterruptSync,PVOID(context->Miniport));
    }
    return ntStatus;
}

#define kMPUPollTimeout 2

#pragma code_seg()
/*****************************************************************************
 * TryLegacyMPU()
 *****************************************************************************
 * See if the MPU401 is free.
 */
BOOLEAN
TryLegacyMPU
(
    IN      PUCHAR      PortBase
)
{
    BOOLEAN success;
    USHORT  numPolls;
    UCHAR   status;

    _DbgPrintF(DEBUGLVL_BLAB, ("TryLegacyMPU"));
    numPolls = 0;

    while (numPolls < kMPUPollTimeout)
    {
        status = READ_PORT_UCHAR(PortBase + MPU401_REG_STATUS);
                                       
        if (UartFifoOkForWrite(status)) // Is this a good time to write data?
        {
            break;
        }
        numPolls++;
    }
    if (numPolls >= kMPUPollTimeout)
    {
        success = FALSE;
        _DbgPrintF(DEBUGLVL_BLAB, ("TryLegacyMPU failed"));
    }
    else
    {
        success = TRUE;
    }

    return success;
}

#pragma code_seg()
/*****************************************************************************
 * WriteLegacyMPU()
 *****************************************************************************
 * Write a byte out to the MPU401.
 */
NTSTATUS
WriteLegacyMPU
(
    IN      PUCHAR      PortBase,
    IN      BOOLEAN     IsCommand,
    IN      UCHAR       Value
)
{
    _DbgPrintF(DEBUGLVL_BLAB, ("WriteLegacyMPU"));
    NTSTATUS ntStatus = STATUS_IO_DEVICE_ERROR;

    if (!PortBase)
    {
        _DbgPrintF(DEBUGLVL_TERSE, ("O: PortBase is zero\n"));
        return ntStatus;
    }
    PUCHAR deviceAddr = PortBase + MPU401_REG_DATA;

    if (IsCommand)
    {
        deviceAddr = PortBase + MPU401_REG_COMMAND;
    }

    ULONGLONG startTime = PcGetTimeInterval(0);
    
    while (PcGetTimeInterval(startTime) < GTI_MILLISECONDS(50))
    {
        UCHAR status
        = READ_PORT_UCHAR(PortBase + MPU401_REG_STATUS);

        if (UartFifoOkForWrite(status)) // Is this a good time to write data?
        {                               // yep (Jon comment)
            WRITE_PORT_UCHAR(deviceAddr,Value);
#if kTurnOnKdPrint
            KdPrint(("'Mi:O: %02X\n",Value));
#endif //   kTurnOnKdPrint
            _DbgPrintF(DEBUGLVL_BLAB, ("WriteLegacyMPU emitted 0x%02x",Value));
            ntStatus = STATUS_SUCCESS;
            break;
        }
    }
    return ntStatus;
}

#pragma code_seg()
/*****************************************************************************
 * CMiniportMidiStreamUart::Read()
 *****************************************************************************
 * Reads incoming MIDI data.
 */
STDMETHODIMP
CMiniportMidiStreamUart::
Read
(
    IN      PVOID   BufferAddress,
    IN      ULONG   Length,
    OUT     PULONG  BytesRead
)
{
    ASSERT(BufferAddress);
    ASSERT(BytesRead);

    *BytesRead = 0;
    if (m_fCapture)
    {
        DEFERREDREADCONTEXT context;
        context.BufferAddress   = BufferAddress;
        context.Length          = Length;
        context.BytesRead       = BytesRead;
        context.pMPUInputBufferHead = &(m_pMiniport->m_MPUInputBufferHead);
        context.MPUInputBufferTail = m_pMiniport->m_MPUInputBufferTail;
        context.MPUInputBuffer     = m_pMiniport->m_MPUInputBuffer;

        if (*(context.pMPUInputBufferHead) != context.MPUInputBufferTail)
        {
            //
            //  More data is available.
            //  No need to touch the hardware, just read from our SW FIFO.
            //
            return (DeferredLegacyRead(m_pMiniport->m_pInterruptSync,PVOID(&context)));
        }
        else
        {
            return STATUS_SUCCESS;
        }
    }
    else
    {
        return STATUS_INVALID_DEVICE_REQUEST;
    }
}

#pragma code_seg()
/*****************************************************************************
 * DeferredLegacyRead()
 *****************************************************************************
 * Synchronized routine to read incoming MIDI data.
 * We have already read the bytes in, and now the Port wants them.
 */
NTSTATUS
DeferredLegacyRead
(
    IN      PINTERRUPTSYNC  InterruptSync,
    IN      PVOID           DynamicContext
)
{
    ASSERT(InterruptSync);
    ASSERT(DynamicContext);

    PDEFERREDREADCONTEXT context = PDEFERREDREADCONTEXT(DynamicContext);

    ASSERT(context->BufferAddress);
    ASSERT(context->BytesRead);


    NTSTATUS ntStatus = STATUS_SUCCESS;
    PUCHAR  pDest = PUCHAR(context->BufferAddress);
    PULONG  pMPUInputBufferHead = context->pMPUInputBufferHead;
    ULONG   MPUInputBufferTail = context->MPUInputBufferTail;
    ULONG   bytesRead = 0;

    ASSERT(pMPUInputBufferHead);
    ASSERT(context->MPUInputBuffer);

    while  (    (*pMPUInputBufferHead != MPUInputBufferTail)
            &&  (bytesRead < context->Length) )
    {
        *pDest = context->MPUInputBuffer[*pMPUInputBufferHead];

        pDest++;
        bytesRead++;
        *pMPUInputBufferHead = *pMPUInputBufferHead + 1;
        //
        //  Wrap FIFO position when reaching the buffer size.
        //
        if (*pMPUInputBufferHead >= kMPUInputBufferSize)
        {
            *pMPUInputBufferHead = 0;
        }
    }
    *context->BytesRead = bytesRead;

    return ntStatus;
}

#pragma code_seg()
/*****************************************************************************
 * MPUInterruptServiceRoutine()
 *****************************************************************************
 * ISR.
 */
NTSTATUS
MPUInterruptServiceRoutine
(
    IN      PINTERRUPTSYNC  InterruptSync,
    IN      PVOID           DynamicContext
)
{
    _DbgPrintF(DEBUGLVL_BLAB, ("MPUInterruptServiceRoutine"));
    ULONGLONG   startTime;

    ASSERT(DynamicContext);

    NTSTATUS            ntStatus;
    BOOL                newBytesAvailable;
    CMiniportMidiUart   *that;

    that = (CMiniportMidiUart *) DynamicContext;
    newBytesAvailable = FALSE;
    ntStatus = STATUS_UNSUCCESSFUL;

    UCHAR portStatus = 0xff;

    //
    // Read the MPU status byte.
    //
    if (that->m_pPortBase)
    {
        portStatus =
            READ_PORT_UCHAR(that->m_pPortBase + MPU401_REG_STATUS);

        //
        // If there is outstanding work to do and there is a port-driver for
        // the MPU miniport...
        //
        if (UartFifoOkForRead(portStatus) && that->m_pPort)
        {
            startTime = PcGetTimeInterval(0);
            while ( (PcGetTimeInterval(startTime) < GTI_MILLISECONDS(50)) 
                &&  (UartFifoOkForRead(portStatus)) )
            {
                UCHAR uDest = READ_PORT_UCHAR(that->m_pPortBase + MPU401_REG_DATA);
                if (    (that->m_KSStateInput == KSSTATE_RUN)
                   &&   (that->m_NumCaptureStreams)
                   )
                {
#if kTurnOnKdPrint
                    KdPrint(("'Mi:\t\tI: %02X\n",uDest));
#endif //   kTurnOnKdPrint
                    ULONG buffHead = that->m_MPUInputBufferHead;
                    if (   (that->m_MPUInputBufferTail + 1 == buffHead)
                        || (that->m_MPUInputBufferTail + 1 - kMPUInputBufferSize == buffHead))
                    {
                        _DbgPrintF(DEBUGLVL_TERSE,("*****MPU Input Buffer Overflow*****"));
                    }
                    else
                    {
                        newBytesAvailable = TRUE;
                        //  ...place the data in our FIFO...
                        that->m_MPUInputBuffer[that->m_MPUInputBufferTail] = uDest;
                        ASSERT(that->m_MPUInputBufferTail < kMPUInputBufferSize);
                        
                        that->m_MPUInputBufferTail++;
                        if (that->m_MPUInputBufferTail >= kMPUInputBufferSize)
                        {
                            that->m_MPUInputBufferTail = 0;
                        }
                    }
                }
#if kTurnOnKdPrint
                else
                {
                    KdPrint(("'Mi:\t\tI: %02X XXX\n",uDest));
                }
#endif //   kTurnOnKdPrint
                //
                // Look for more MIDI data.
                //
                portStatus =
                    READ_PORT_UCHAR(that->m_pPortBase + MPU401_REG_STATUS);
            }   //  either there's no data or we ran too long
            if (newBytesAvailable)
            {
                //
                // ...notify the MPU port driver that we have bytes.
                //
                that->m_pPort->Notify(that->m_pServiceGroup);
            }
            ntStatus = STATUS_SUCCESS;
        }
    }

    return ntStatus;
}

⌨️ 快捷键说明

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