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

📄 ipu_base.cpp

📁 freescale i.mx31 BSP CE5.0全部源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    {
        phyAddr.QuadPart = CSP_BASE_REG_PA_IPU;

        // Map peripheral physical address to virtual address
        g_pIPU = (PCSP_IPU_REGS) MmMapIoSpace(phyAddr, sizeof(CSP_IPU_REGS),
            FALSE);

        // Check if virtual mapping failed
        if (g_pIPU == NULL)
        {
            DEBUGMSG(ZONE_ERROR,
                (_T("Init:  MmMapIoSpace failed!\r\n")));
            goto cleanUp;
        }
    }

    rc = TRUE;

cleanUp:
    // If initialization failed, be sure to clean up
    if (!rc) IpuDealloc();

    IPU_FUNCTION_EXIT();
    return rc;
}


//-----------------------------------------------------------------------------
//
// Function:  PrpIpuDealloc
//
// This function deallocates the data structures required for interaction
// with the IPU hardware.
//
// Parameters:
//      None.
//
// Returns:
//      Returns TRUE.
//
//-----------------------------------------------------------------------------
static void IpuDealloc(void)
{
    IPU_FUNCTION_ENTRY();

    // Unmap peripheral registers
    if (g_pIPU)
    {
        MmUnmapIoSpace(g_pIPU, sizeof(CSP_IPU_REGS));
        g_pIPU = NULL;
    }

    IPU_FUNCTION_EXIT();
}


//------------------------------------------------------------------------------
//
// Function: IpuIntrInit
//
// This function initializes the g_pIntrGroupMask array with
// the appropriate interrupt group masks.
//
// Parameters:
//      None
//
// Returns:
//      None
//
//-----------------------------------------------------------------------------
static BOOL IpuIntrInit(void)
{
    DWORD ipuIrq;
    BOOL ret = FALSE;

    IPU_FUNCTION_ENTRY();

    DEBUGMSG(ZONE_INIT, (TEXT("%s: CreateEvent for IPU Interrupt\r\n"), __WFUNCTION__));
    g_hIpuIntrEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    if (g_hIpuIntrEvent == NULL)
    {
        DEBUGMSG(ZONE_ERROR,
            (TEXT("%s: CreateEvent for IPU Interrupt failed\r\n"), __WFUNCTION__));
        return ret;
    }

    // IRQ is defined at SOC level
    ipuIrq = IPUGetIRQ();

    // Translate IRQ to SYSINTR
    if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &ipuIrq, sizeof(ipuIrq),
        &g_ipuIntr, sizeof(g_ipuIntr), NULL))
    {
        DEBUGMSG(ZONE_ERROR,
            (TEXT("%s: Request SYSINTR failed (IPU Interrupt)\r\n"), __WFUNCTION__));
        return ret;
    }

    if(!InterruptInitialize(g_ipuIntr, g_hIpuIntrEvent, NULL, 0))
    {
        CloseHandle(g_hIpuIntrEvent);
        g_hIpuIntrEvent = NULL;
        DEBUGMSG(ZONE_ERROR,
            (TEXT("%s: Interrupt initialization failed! (IPU Interrupt)\r\n"), __WFUNCTION__));
        return ret;
    }

    // Create events to facilitate communication of 
    // interrupt status with drivers for IPU sub-modules.
    // Event names are shared between the common IPU code and
    // the Prp and Pp drivers through event strings found in Ipu.h
    DEBUGMSG(ZONE_INIT, (TEXT("%s: CreateEvent for Pre-processor Interrupt event\r\n"), __WFUNCTION__));
    g_hPrpIntrEvent = CreateEvent(NULL, FALSE, FALSE, IPU_PRP_INTR_EVENT);
    if (g_hPrpIntrEvent == NULL)
    {
        DEBUGMSG(ZONE_ERROR,
            (TEXT("%s: CreateEvent for Pre-processor Interrupt Event failed\r\n"), __WFUNCTION__));
        return ret;
    }

    DEBUGMSG(ZONE_INIT, (TEXT("%s: CreateEvent for Post-processor Interrupt event\r\n"), __WFUNCTION__));
    g_hPpIntrEvent = CreateEvent(NULL, FALSE, FALSE, IPU_PP_INTR_EVENT);
    if (g_hPpIntrEvent == NULL)
    {
        DEBUGMSG(ZONE_ERROR,
            (TEXT("%s: CreateEvent for Post-processor Interrupt Event failed\r\n"), __WFUNCTION__));
        return ret;
    }

    DEBUGMSG(ZONE_INIT, (TEXT("%s: CreateEvent for Post-filtering Interrupt event\r\n"), __WFUNCTION__));
    g_hPfIntrEvent = CreateEvent(NULL, FALSE, FALSE, IPU_PF_INTR_EVENT);
    if (g_hPfIntrEvent == NULL)
    {
        DEBUGMSG(ZONE_ERROR,
            (TEXT("%s: CreateEvent for Post-filtering Interrupt Event failed\r\n"), __WFUNCTION__));
        return ret;
    }

    DEBUGMSG(ZONE_INIT, (TEXT("%s: CreateEvent for SDC Background plane Interrupt event\r\n"), __WFUNCTION__));
    g_hSDCBGIntrEvent = CreateEvent(NULL, FALSE, FALSE, IPU_SDC_BG_INTR_EVENT);
    if (g_hSDCBGIntrEvent == NULL)
    {
        DEBUGMSG(ZONE_ERROR,
            (TEXT("%s: CreateEvent for SDC Background plane Interrupt Event failed\r\n"), __WFUNCTION__));
        return ret;
    }

    DEBUGMSG(ZONE_INIT, (TEXT("%s: CreateEvent for SDC Foreground plane Interrupt event\r\n"), __WFUNCTION__));
    g_hSDCFGIntrEvent = CreateEvent(NULL, FALSE, FALSE, IPU_SDC_FG_INTR_EVENT);
    if (g_hSDCFGIntrEvent == NULL)
    {
        DEBUGMSG(ZONE_ERROR,
            (TEXT("%s: CreateEvent for SDC Foreground plane Interrupt Event failed\r\n"), __WFUNCTION__));
        return ret;
    }

    DEBUGMSG(ZONE_INIT, (TEXT("%s: CreateEvent for ADC Interrupt event\r\n"), __WFUNCTION__));
    g_hADCIntrEvent = CreateEvent(NULL, FALSE, FALSE, IPU_ADC_INTR_EVENT);
    if (g_hADCIntrEvent == NULL)
    {
        DEBUGMSG(ZONE_ERROR,
            (TEXT("%s: CreateEvent for ADC Interrupt Event failed\r\n"), __WFUNCTION__));
        return ret;
    }

    g_phIntrHdlr[IPU_INT_DMAIC_0] = g_hPrpIntrEvent;
    g_phIntrHdlr[IPU_INT_DMAIC_1] = g_hPrpIntrEvent;
    g_phIntrHdlr[IPU_INT_DMAIC_2] = g_hPpIntrEvent;
    g_phIntrHdlr[IPU_INT_DMAIC_3] = g_hPrpIntrEvent;
    g_phIntrHdlr[IPU_INT_DMAIC_4] = g_hPpIntrEvent;
    g_phIntrHdlr[IPU_INT_DMAIC_5] = g_hPpIntrEvent;
    g_phIntrHdlr[IPU_INT_DMAIC_6] = g_hPrpIntrEvent;
    g_phIntrHdlr[IPU_INT_DMAIC_7] = g_hPrpIntrEvent;
    g_phIntrHdlr[IPU_INT_DMAIC_8] = g_hPrpIntrEvent;
    g_phIntrHdlr[IPU_INT_DMAIC_9] = g_hPrpIntrEvent;
    g_phIntrHdlr[IPU_INT_DMAIC_10] = g_hPrpIntrEvent;
    g_phIntrHdlr[IPU_INT_DMAIC_11] = g_hPrpIntrEvent;
    g_phIntrHdlr[IPU_INT_DMAIC_12] = g_hPpIntrEvent;
    g_phIntrHdlr[IPU_INT_DMAIC_13] = g_hPpIntrEvent;
    g_phIntrHdlr[IPU_INT_DMASDC_0] = g_hSDCBGIntrEvent;
    g_phIntrHdlr[IPU_INT_DMASDC_1] = g_hSDCFGIntrEvent;
    g_phIntrHdlr[IPU_INT_DMASDC_2] = 0;
    g_phIntrHdlr[IPU_INT_DMASDC_3] = 0;
    g_phIntrHdlr[IPU_INT_DMAADC_2] = g_hADCIntrEvent;
    g_phIntrHdlr[IPU_INT_DMAADC_3] = g_hADCIntrEvent;
    g_phIntrHdlr[IPU_INT_DMAADC_4] = g_hADCIntrEvent;
    g_phIntrHdlr[IPU_INT_DMAADC_5] = g_hADCIntrEvent;
    g_phIntrHdlr[IPU_INT_DMAADC_6] = g_hADCIntrEvent;
    g_phIntrHdlr[IPU_INT_DMAADC_7] = g_hADCIntrEvent;
    g_phIntrHdlr[IPU_INT_DMAPF_0] = g_hPfIntrEvent;
    g_phIntrHdlr[IPU_INT_DMAPF_1] = g_hPfIntrEvent;
    g_phIntrHdlr[IPU_INT_DMAPF_2] = g_hPfIntrEvent;
    g_phIntrHdlr[IPU_INT_DMAPF_3] = g_hPfIntrEvent;
    g_phIntrHdlr[IPU_INT_DMAPF_4] = g_hPfIntrEvent;
    g_phIntrHdlr[IPU_INT_DMAPF_5] = g_hPfIntrEvent;
    g_phIntrHdlr[IPU_INT_DMAPF_6] = g_hPfIntrEvent;
    g_phIntrHdlr[IPU_INT_DMAPF_7] = g_hPfIntrEvent;

    g_pIntrGroupMask[IPU_INT_DMAIC_0] = PRP_ENC_DMA_CHA_MASK;
    g_pIntrGroupMask[IPU_INT_DMAIC_1] = PRP_VF_DMA_CHA_MASK;
    g_pIntrGroupMask[IPU_INT_DMAIC_2] = PP_DMA_CHA_MASK;
    g_pIntrGroupMask[IPU_INT_DMAIC_3] = PRP_VF_DMA_CHA_MASK;
    g_pIntrGroupMask[IPU_INT_DMAIC_4] = PP_DMA_CHA_MASK;
    g_pIntrGroupMask[IPU_INT_DMAIC_5] = PP_DMA_CHA_MASK;
    g_pIntrGroupMask[IPU_INT_DMAIC_6] = 0;
    g_pIntrGroupMask[IPU_INT_DMAIC_7] = 0;
    g_pIntrGroupMask[IPU_INT_DMAIC_8] = PRP_ENC_ROT_DMA_CHA_MASK;
    g_pIntrGroupMask[IPU_INT_DMAIC_9] = PRP_VF_ROT_DMA_CHA_MASK;
    g_pIntrGroupMask[IPU_INT_DMAIC_10] = PRP_ENC_ROT_DMA_CHA_MASK;
    g_pIntrGroupMask[IPU_INT_DMAIC_11] = PRP_VF_ROT_DMA_CHA_MASK;
    g_pIntrGroupMask[IPU_INT_DMAIC_12] = PP_ROT_DMA_CHA_MASK;
    g_pIntrGroupMask[IPU_INT_DMAIC_13] = PP_ROT_DMA_CHA_MASK;
    g_pIntrGroupMask[IPU_INT_DMASDC_0] = SDC_BG_DMA_CHA_MASK;
    g_pIntrGroupMask[IPU_INT_DMASDC_1] = SDC_FG_DMA_CHA_MASK;
    g_pIntrGroupMask[IPU_INT_DMASDC_2] = 0;
    g_pIntrGroupMask[IPU_INT_DMASDC_3] = 0;
    g_pIntrGroupMask[IPU_INT_DMAADC_2] = ADC_DMA_CHA_MASK;
    g_pIntrGroupMask[IPU_INT_DMAADC_3] = ADC_DMA_CHA_MASK;
    g_pIntrGroupMask[IPU_INT_DMAADC_4] = ADC_DMA_CHA_MASK;
    g_pIntrGroupMask[IPU_INT_DMAADC_5] = ADC_DMA_CHA_MASK;
    g_pIntrGroupMask[IPU_INT_DMAADC_6] = ADC_DMA_CHA_MASK;
    g_pIntrGroupMask[IPU_INT_DMAADC_7] = ADC_DMA_CHA_MASK;
    g_pIntrGroupMask[IPU_INT_DMAPF_0] = PF_DMA_CHA_MASK;
    g_pIntrGroupMask[IPU_INT_DMAPF_1] = PF_DMA_CHA_MASK;
    g_pIntrGroupMask[IPU_INT_DMAPF_2] = PF_DMA_CHA_MASK;
    g_pIntrGroupMask[IPU_INT_DMAPF_3] = PF_DMA_CHA_MASK;
    g_pIntrGroupMask[IPU_INT_DMAPF_4] = PF_DMA_CHA_MASK;
    g_pIntrGroupMask[IPU_INT_DMAPF_5] = PF_DMA_CHA_MASK;
    g_pIntrGroupMask[IPU_INT_DMAPF_6] = PF_DMA_CHA_MASK;
    g_pIntrGroupMask[IPU_INT_DMAPF_7] = PF_DMA_CHA_MASK;

    ret = TRUE;

    IPU_FUNCTION_EXIT();

    return ret;
}

//------------------------------------------------------------------------------
//
// Function: IpuIntrThread
//
// This function is the IPU IST thread.
//
// Parameters:
//      None
//
// Returns:
//      None
//
//-----------------------------------------------------------------------------
static void IpuIntrThread(LPVOID lpParameter)
{
    IPU_FUNCTION_ENTRY();

    IpuISRLoop(INFINITE);

    IPU_FUNCTION_EXIT();
}



//-----------------------------------------------------------------------------
//
// Function: IpuISRLoop
//
// This function is the interrupt handler for the Preprocessor.
// It waits for the End-Of-Frame (EOF) interrupt, and signals
// the EOF event registered by the user of the preprocessor.
//
// Parameters:
//      timeout
//          [in] Timeout value while waiting for EOF interrupt.
//
// Returns:
//      None
//
//-----------------------------------------------------------------------------
static void IpuISRLoop(UINT32 timeout)
{
    DWORD ctrlReg1, statReg1, statReg5, clearCtrlBits, int_src;
    UINT32 oldCtrl, newCtrl;

    IPU_FUNCTION_ENTRY();

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

        if (WaitForSingleObject(g_hIpuIntrEvent, timeout) == WAIT_OBJECT_0)
        {
            DEBUGMSG (ZONE_INFO, (TEXT("%s: Interrupt received\r\n"), __WFUNCTION__));

            ctrlReg1 = INREG32(&g_pIPU->IPU_INT_CTRL_1);
            statReg1 = INREG32(&g_pIPU->IPU_INT_STAT_1);
            statReg5 = INREG32(&g_pIPU->IPU_INT_STAT_5);
            clearCtrlBits = 0;

            int_src = 31 - _CountLeadingZeros(statReg1 & ctrlReg1);

            // If interrupt source is valid
            if (int_src < IPU_INT_MAX_ID)
            {

                // Clear interrupt control bits so we do not
                // continue to receive this interrupt.  The signalled
                // driver is responsible for re-enabling these bits.
                clearCtrlBits = g_pIntrGroupMask[int_src];

                // Use interlocked function to update control registers
                do
                {
                    oldCtrl = INREG32(&g_pIPU->IPU_INT_CTRL_1);
                    newCtrl = oldCtrl & ~clearCtrlBits;
                } while (InterlockedTestExchange((LPLONG) &g_pIPU->IPU_INT_CTRL_1, 
                            oldCtrl, newCtrl) != oldCtrl);

                // If client event installed
                if (g_phIntrHdlr[int_src] != NULL)
                {
                    // Signal registered event 
                    // Note:  Rescheduling may occur and could result in more
                    //        interrupts pending.
                    SetEvent(g_phIntrHdlr[int_src]);
                }
                else
                {
                    DEBUGMSG(ZONE_ERROR, (_T("No IPU submodule event registered for interrupt source = %d\r\n"), int_src));
                }

            }
            else if (_CountLeadingZeros(statReg1 & ctrlReg1) == 32)
            {
                DEBUGMSG(ZONE_INFO, (_T("No interrupt source?\r\n")));
            }
            else
            {
                DEBUGMSG(ZONE_ERROR, (_T("Invalid IPU interrupt source (%d)\r\n"), int_src));
            }

            if (statReg5 & 0xFFFF)
            {
                // TODO: Properly Handle Error Cases
                DEBUGMSG (ZONE_INFO, (TEXT("%s: Error Interrupt received!\r\n"), __WFUNCTION__));
                if (INREG32(&g_pIPU->IPU_INT_STAT_5) & 0x3800)
                {
                    DEBUGMSG (ZONE_INFO, (TEXT("%s: Frame Lost.\r\n"), __WFUNCTION__));
                    // Clear frame drop interrupt registers
                    OUTREG32(&g_pIPU->IPU_INT_STAT_5, 0x3800);
                    DEBUGMSG (ZONE_INFO, (TEXT("%s: Cleared INT_STAT_5: %x\r\n"),
                            __WFUNCTION__, INREG32(&g_pIPU->IPU_INT_STAT_5)));
                }
                else
                {
                    DEBUGMSG (ZONE_INFO, (TEXT("%s: Other error.\r\n"), __WFUNCTION__));
                }
            }

            // Kernel call to unmask the interrupt so that it can be signalled again
            InterruptDone(g_ipuIntr);
        }
        else
        {
            DEBUGMSG (ZONE_INFO, (TEXT("%s: Time out\r\n"), __WFUNCTION__));
        }

    }

    IPU_FUNCTION_EXIT();
    return;
}

⌨️ 快捷键说明

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