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

📄 mupdd.c

📁 freescale i.mx31 BSP CE5.0全部源码
💻 C
📖 第 1 页 / 共 5 页
字号:
// Parameters:
//      None
//
// Returns:
//      None
//
//------------------------------------------------------------------------------
void MUGPI0IntrThread(void)
{
    MU_FUNCTION_ENTRY();
    
    MUGPI0ISRLoop(INFINITE);

    MU_FUNCTION_ENTRY();
    
    return;
}

//------------------------------------------------------------------------------
//
// Function: MUReadISRLoop
//
// This function is the interrupt handler that services 
// RX (receive) interrupts to the MCU side of the MU.
// It waits for the MU RX interrupt event, and then reads the
// receive registers.
//
// Parameters:
//      timeout
//          [in] Timeout value while waiting for MU RX interrupt.
//
// Returns:
//      None
//
//------------------------------------------------------------------------------
static void MUReadISRLoop(UINT32 timeout)
{
    MUShortMessage_c readMessage;
    DWORD msr;
    UINT8 i;

    MU_FUNCTION_ENTRY();

    // loop here
    while(TRUE)
    {
        DEBUGMSG (ZONE_INFO, (TEXT("%s: In the read loop\r\n"), __WFUNCTION__));
        if (WaitForSingleObject(g_hMURXIntrEvent, timeout) == WAIT_OBJECT_0)
        {
            // We have received a read interrupt.
            // Check status registers to determine how
            // many bytes to read.
            DEBUGMSG (ZONE_INFO, (TEXT("%s: Interrupt received\r\n"), __WFUNCTION__));

            // We check status registers starting at receive
            // register 3, counting down.  The highest receive 
            // register that has been signalled indicates the 
            // number of 32-bit words that are being read from 
            // the DSP.  Reading from the receive register MRRX
            // clears the status bit MRFX.
            msr = INREG32(&g_pMU->MSR);

            if (msr & MUStatusRegField_MRF3)
            {
                SetEvent(g_hMUReceive3FullEvent);
                readMessage.iLength = 4;
                readMessage.dwChunk[3] = INREG32(&g_pMU->MRR3);
                readMessage.dwChunk[2] = INREG32(&g_pMU->MRR2);
                readMessage.dwChunk[1] = INREG32(&g_pMU->MRR1);
                readMessage.dwChunk[0] = INREG32(&g_pMU->MRR0);
            }
            else if (msr & MUStatusRegField_MRF2)
            {
                SetEvent(g_hMUReceive2FullEvent);
                readMessage.iLength = 3;
                readMessage.dwChunk[2] = INREG32(&g_pMU->MRR2);
                readMessage.dwChunk[1] = INREG32(&g_pMU->MRR1);
                readMessage.dwChunk[0] = INREG32(&g_pMU->MRR0);
            }
            else if (msr & MUStatusRegField_MRF1)
            {
                SetEvent(g_hMUReceive1FullEvent);
                readMessage.iLength = 2;
                readMessage.dwChunk[1] = INREG32(&g_pMU->MRR1);
                readMessage.dwChunk[0] = INREG32(&g_pMU->MRR0);
            }
            else if (msr & MUStatusRegField_MRF0)
            {
                SetEvent(g_hMUReceive0FullEvent);
                readMessage.iLength = 1;
                readMessage.dwChunk[0] = INREG32(&g_pMU->MRR0);
            }
            else
            {
                DEBUGMSG (ZONE_INFO, 
                    (TEXT("%s: Error: Received RX Interrupt, but no receive status bits set.\r\n"), __WFUNCTION__));
            }

            for (i = 0; i < readMessage.iLength; i++)
            {
                DEBUGMSG(ZONE_INFO, (TEXT("%s: Read DWORD #%x to DSP: %x\r\n"),
                    __WFUNCTION__, i, readMessage.dwChunk[i]));
            }

            // Waiting on a write-enabled handle to a queue.
            // This will block if the receive queue is full.
            // Block if receive queue is full until the 
            // application reads from it.  During this time, additional
            // transmits from the DSP will be put on hold.
            WaitForSingleObject(g_hWriteReceiveQueue, INFINITE);

            // Now add newly read message to read message queue.
            // This will be processed when MUReadFromDSP is called.
            if (!WriteMsgQueue(g_hWriteReceiveQueue, &readMessage, sizeof(MUShortMessage_c), 
                MU_WRITE_TIMEOUT, 0))
            {
                DEBUGMSG (ZONE_INFO, 
                    (TEXT("%s: Error: Write to receive queue failed!  Error message 0x%x\r\n"), __WFUNCTION__, GetLastError()));
            }
        }
        else
        {
            // Timeout as requested
            DEBUGMSG (ZONE_INFO, (TEXT("%s: Time out\r\n"), __WFUNCTION__));
        }

        // Kernel call to unmask the interrupt so that it can be signalled again.
        InterruptDone(g_MURXIntr);
    }

    MU_FUNCTION_ENTRY();
    return;
}

//------------------------------------------------------------------------------
//
// Function: MUWriteISRLoop
//
// This function is the interrupt handler that services 
// TX (transmit) interrupts to the MCU side of the MU.
// It writes data to the DSP whenever there is data ready to be
// written and the DSP side receive registers are empty.
//
// Parameters:
//      timeout
//          [in] Timeout value while waiting for MU RX interrupt.
//
// Returns:
//      None
//
//------------------------------------------------------------------------------
static void MUWriteISRLoop(UINT32 timeout)
{
    UINT8 i;
    MUShortMessage_c writeMessage;
    DWORD bytesRead, flags, msr;
    BOOL interruptOff; // used to determine if we should return interrupt value
                       // to off state after waiting for transmit empty

    MU_FUNCTION_ENTRY();

    // loop here
    while(TRUE)
    {
        DEBUGMSG (ZONE_INFO, 
            (TEXT("%s: In the write loop, waiting on write message queue\r\n"), __WFUNCTION__));
        if (WaitForSingleObject(g_hReadTransmitQueue, timeout) == WAIT_OBJECT_0)
        {
            // We have data ready to be written to DSP
            DEBUGMSG (ZONE_INFO, 
                (TEXT("%s: Message ready to write in transmit queue.\r\n"), __WFUNCTION__));

            // First, check that Transmit registers are empty 
            // from previous write operations.
            if ((INREG32(&g_pMU->MSR) & 0xF00000) != 0xF00000)
            {
                DEBUGMSG (ZONE_ERROR, (TEXT("%s: Error: MU Transmit registers not empty.\r\n"), __WFUNCTION__));
            }

            // Read data from queue
            if (!ReadMsgQueue(g_hReadTransmitQueue, &writeMessage, sizeof(MUShortMessage_c),
                &bytesRead, 10, &flags))
            {
                DEBUGMSG(ZONE_ERROR, (TEXT("%s: Could not read from write queue!\r\n"),
                    __WFUNCTION__));
                continue;
            }

            for (i = 0; i < writeMessage.iLength; i++)
            {
                DEBUGMSG(ZONE_INFO, (TEXT("%s: Writing DWORD #%x to DSP: %x\r\n"),
                    __WFUNCTION__, i, writeMessage.dwChunk[i]));
            }

            // Now write data to transmit register
            switch (writeMessage.iLength)
            {
                case 1:
                    OUTREG32(&g_pMU->MTR0, writeMessage.dwChunk[0]);
                    if (EXTREG32BF(&g_pMU->MCR, MU_MCR_MTIE0) != 0)
                    {
                        // The required transmit empty interrupt is already on.
                        interruptOff = FALSE;
                    }
                    else
                    {
                        // The required transmit empty interrupt is off.  
                        // Turn it on and set boolean so that we turn
                        // it off once we have completed the write.
                        interruptOff = TRUE;
                        INSREG32BF(&g_pMU->MCR, MU_MCR_MTIE0, MU_MCR_MTIE0_ENABLE);
                    }
                    break;
                case 2:
                    OUTREG32(&g_pMU->MTR0, writeMessage.dwChunk[0]);
                    OUTREG32(&g_pMU->MTR1, writeMessage.dwChunk[1]);
                    if (EXTREG32BF(&g_pMU->MCR, MU_MCR_MTIE1) != 0)
                    {
                        // The required transmit empty interrupt is already on.
                        interruptOff = FALSE;
                    }
                    else
                    {
                        // The required transmit empty interrupt is off.  
                        // Turn it on and set boolean so that we turn
                        // it off once we have completed the write.
                        interruptOff = TRUE;
                        INSREG32BF(&g_pMU->MCR, MU_MCR_MTIE1, MU_MCR_MTIE1_ENABLE);
                    }
                    break;
                case 3:
                    OUTREG32(&g_pMU->MTR0, writeMessage.dwChunk[0]);
                    OUTREG32(&g_pMU->MTR1, writeMessage.dwChunk[1]);
                    OUTREG32(&g_pMU->MTR2, writeMessage.dwChunk[2]);
                    if (EXTREG32BF(&g_pMU->MCR, MU_MCR_MTIE2) != 0)
                    {
                        // The required transmit empty interrupt is already on.
                        interruptOff = FALSE;
                    }
                    else
                    {
                        // The required transmit empty interrupt is off.  
                        // Turn it on and set boolean so that we turn
                        // it off once we have completed the write.
                        interruptOff = TRUE;
                        INSREG32BF(&g_pMU->MCR, MU_MCR_MTIE2, MU_MCR_MTIE2_ENABLE);
                    }
                    break;
                case 4:
                    OUTREG32(&g_pMU->MTR0, writeMessage.dwChunk[0]);
                    OUTREG32(&g_pMU->MTR1, writeMessage.dwChunk[1]);
                    OUTREG32(&g_pMU->MTR2, writeMessage.dwChunk[2]);
                    OUTREG32(&g_pMU->MTR3, writeMessage.dwChunk[3]);
                    if (EXTREG32BF(&g_pMU->MCR, MU_MCR_MTIE3) != 0)
                    {
                        // The required transmit empty interrupt is already on.
                        interruptOff = FALSE;
                    }
                    else
                    {
                        // The required transmit empty interrupt is off.  
                        // Turn it on and set boolean so that we turn
                        // it off once we have completed the write.
                        interruptOff = TRUE;
                        INSREG32BF(&g_pMU->MCR, MU_MCR_MTIE3, MU_MCR_MTIE3_ENABLE);
                    }
                    break;
                default:
                    DEBUGMSG(ZONE_ERROR, 
                        (TEXT("%s: Invalid write message length: %d.  Discarding message.\r\n"),
                        __WFUNCTION__, writeMessage.iLength));
                    continue;
            }

            // Reset transmit empty event so that we do not get a stale event
            // signaled.
            ResetEvent(g_hMUTXIntrEvent);

            // Kernel call to unmask the interrupt so that it can be signaled again.
            // This prevents any stale interrupts from inappropriately 
            // causing the thread to continue.
            InterruptDone(g_MUTXIntr);

            // Now wait for transmit empty interrupt (i.e., wait for
            // transmitted data to be read) before completing write 
            // sequence and moving on to next message.
            if (WaitForSingleObject(g_hMUTXIntrEvent, timeout) != WAIT_OBJECT_0)
            {
                // Timeout as requested
                DEBUGMSG (ZONE_INFO, (TEXT("%s: Time out\r\n"), __WFUNCTION__));
            }

            // We have data ready to be written to DSP
            DEBUGMSG (ZONE_INFO, 
                (TEXT("%s: Message ready to write in transmit queue.\r\n"), __WFUNCTION__));

            // Turn off transmit empty interrupt since it was not on before.
            if (interruptOff)
            {            
                switch (writeMessage.iLength)
                {
                    case 1:
                        INSREG32BF(&g_pMU->MCR, MU_MCR_MTIE0, MU_MCR_MTIE0_ENABLE);
                        break;
                    case 2:
                        INSREG32BF(&g_pMU->MCR, MU_MCR_MTIE1, MU_MCR_MTIE1_ENABLE);
                        break;
                    case 3:
                        INSREG32BF(&g_pMU->MCR, MU_MCR_MTIE2, MU_MCR_MTIE2_ENABLE);
                        break;
                    case 4:
                        INSREG32BF(&g_pMU->MCR, MU_MCR_MTIE3, MU_MCR_MTIE3_ENABLE);
                        break;
                }
            }

            // Set event for transmit empty interrupts.
            msr = INREG32(&g_pMU->MSR);
            if (msr & MUCtrlRegField_MTIE3)
            {
                SetEvent(g_hMUTransmit3EmptyEvent);
            }

            if (msr & MUCtrlRegField_MTIE2)
            {
                SetEvent(g_hMUTransmit2EmptyEvent);
            }

            if (msr & MUCtrlRegField_MTIE1)
            {
                SetEvent(g_hMUTransmit1EmptyEvent);
            }

            if (msr & MUCtrlRegField_MTIE0)
            {
                SetEvent(g_hMUTransmit0EmptyEvent);
            }
        }
    }

    MU_FUNCTION_ENTRY();
    return;
}

//------------------------------------------------------------------------------
//
// Function: MUGPI3ISRLoop
//
// This function is the interrupt handler that services 
// General Purpose Interrupt 3, signaling an event and
// setting an event associated with the interrupt.
//
// Parameters:
//      timeout
//          [in] Timeout value while waiting for MU GPI3 interrupt.
//
// Returns:
//      None
//
//------------------------------------------------------------------------------
static void MUGPI3ISRLoop(UINT32 timeout)
{
    MU_FUNCTION_ENTRY();

    // loop here
    while(TRUE)
    {
        DEBUGMSG (ZONE_INFO, 
            (TEXT("%s: In the loop, waiting on GPI3\r\n"), __WFUNCTION__));

        if (WaitForSingleObject(g_hMUGPI3IntrEvent, timeout) != WAIT_OBJECT_0)
        {
            // Timeout as requested
            DEBUGMSG (ZONE_INFO, (TEXT("%s: Time out\r\n"), __WFUNCTION__));
            continue;
        }

        SetEvent(g_hMUGPI3Event);

        // Lock access to MU while we reset status bit for GPI3
        EnterCriticalSection(&g_csMULock);

        INSREG32BF(&g_pMU->MSR, MU_MSR_MGIP3, 1); // Write 1 to clear

        LeaveCriticalSection(&g_csMULock);

        InterruptDone(g_MUGPI3Intr);
    }
}

//------------------------------------------------------------------------------
//
// Function: MUGPI2ISRLoop
//
// This function is the interrupt handler that services 
// General Purpose Interrupt 2, signaling an event and
// setting an event associated with the interrupt.
//
// Parameters:
//      timeout
//          [in] Timeout value while waiting for MU GPI2 interrupt.
//
// Returns:
//      None
//
//------------------------------------------------------------------------------
static void MUGPI2ISRLoop(UINT32 timeout)
{
    MU_FUNCTION_ENTRY();

    // loop here
    while(TRUE)
    {
        DEBUGMSG (ZONE_INFO, 
            (TEXT("%s: In the loop, waiting on GPI2\r\n"), __WFUNCTION__));

        if (WaitForSingleObject(g_hMUGPI2IntrEvent, timeout) !=

⌨️ 快捷键说明

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