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

📄 pfclass.cpp

📁 freescale i.mx31 BSP CE5.0全部源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    writeDMAChannelParam(ch, 0, 1, 1<<14); //Variable data set to 0. NSB set  63-32
    writeDMAChannelParam(ch, 0, 2, 0); //Variable data set to 0.   95-64
    writeDMAChannelParam(ch, 0, 3, ((pChannelParams->iWidth-1) << 12) |
            ((pChannelParams->iHeight-1) << 24)); // 127-96
    writeDMAChannelParam(ch, 0, 4, ((pChannelParams->iHeight-1) >> 8)); // 160-128

    // Notice we do not write row 1, words 0 or 1, as these 
    // words control the DMA channel buffers.  This data
    // is written when PfStartChannel is called.
    writeDMAChannelParam(ch, 1, 2,
        ((pChannelParams->iBitsPerPixelCode) |
        ((pChannelParams->iLineStride - 1)<<3) |
        (pChannelParams->iFormatCode<<17) |
        (pChannelParams->iPixelBurstCode<<25))); // 95-64
    writeDMAChannelParam(ch, 1, 3, 2); // SAT code of 0x10 = 32 bit memory access

    // Cede control of IPU_IMA registers by writing 0 to IPU_IMA_ADDR
    OUTREG32(&P_IPU_REGS->IPU_IMA_ADDR, 0);

    PF_FUNCTION_EXIT();
    return;
}


//-----------------------------------------------------------------------------
//
// Function: PfEnable
//
// Enable the Image Converter and the IDMAC channels we will need.
//
// Parameters:
//      None.
//
// Returns:
//      None.
//
//-----------------------------------------------------------------------------
void PfClass::PfEnable(void)
{
    UINT32 oldVal, newVal, iMask, iBitval;

    PF_FUNCTION_ENTRY();

    // Protect access to IPU_CONF register.
    // Set the bit to enable the PF.

    // Compute bitmask and shifted bit value for IPU_CONF register
    iMask = CSP_BITFMASK(IPU_IPU_CONF_PF_EN);
    iBitval = CSP_BITFVAL(IPU_IPU_CONF_PF_EN, IPU_IPU_CONF_PF_EN_ENABLE);

    // Use interlocked function to enable the PF.
    do
    {
        oldVal = INREG32(&P_IPU_REGS->IPU_CONF);
        newVal = (oldVal & (~iMask)) | iBitval;
    } while (InterlockedTestExchange((LPLONG)&P_IPU_REGS->IPU_CONF, 
                oldVal, newVal) != oldVal);

    dumpIpuRegisters(P_IPU_REGS);

    PF_FUNCTION_EXIT();
}

//-----------------------------------------------------------------------------
//
// Function: PfDisable
//
// Disable the Post-filtering unit.
//
// Parameters:
//      None.
//
// Returns:
//      None.
//
//-----------------------------------------------------------------------------
void PfClass::PfDisable(void)
{
    UINT32 oldVal, newVal, iMask, iBitval;

    PF_FUNCTION_ENTRY();

    // Protect access to IPU_CONF register.
    // Set the bit to disable the PF.

    // Compute bitmask and shifted bit value for IPU_CONF register
    iMask = CSP_BITFMASK(IPU_IPU_CONF_PF_EN);
    iBitval = CSP_BITFVAL(IPU_IPU_CONF_PF_EN, IPU_IPU_CONF_PF_EN_DISABLE);

    // Use interlocked function to disable PF.
    do
    {
        oldVal = INREG32(&P_IPU_REGS->IPU_CONF);
        newVal = (oldVal & (~iMask)) | iBitval;
    } while (InterlockedTestExchange((LPLONG)&P_IPU_REGS->IPU_CONF, 
                oldVal, newVal) != oldVal);

    PF_FUNCTION_EXIT();
}

//------------------------------------------------------------------------------
//
// Function: PfClearInterruptStatus
//
// This function is used to clear the PF interrupt status and signal to the
// kernel that interrupt processing is completed.
//
// Parameters:
//      clearBitmask
//          [in] Mask of bits in status register to clear
//
// Returns:
//      None
//
//------------------------------------------------------------------------------
void PfClass::PfClearInterruptStatus(DWORD clearBitmask)
{
    PF_FUNCTION_ENTRY();

    // Clear Interrupt Status Bits
    OUTREG32(&P_IPU_REGS->IPU_INT_STAT_1, clearBitmask);

    PF_FUNCTION_EXIT();
}

//------------------------------------------------------------------------------
//
// Function: PfIntrThread
//
// This function is the IST thread.
//
// Parameters:
//      None
//
// Returns:
//      None
//
//---------------------------------------------------------------------
void PfClass::PfIntrThread(LPVOID lpParameter)
{
    PfClass *pPf = (PfClass *)lpParameter;

    PF_FUNCTION_ENTRY();

    pPf->PfISRLoop(INFINITE);

    PF_FUNCTION_EXIT();
}

//------------------------------------------------------------------------------
//
// Function: PfISRLoop
//
// This function is the interrupt handler for the Post-filterer.
// It waits for the End-Of-Frame (EOF) interrupt, and signals
// the EOF event registered by the user of the post-filterer.
//
// Parameters:
//      timeout
//          [in] Timeout value while waiting for EOF interrupt.
//
// Returns:
//      None
//
//---------------------------------------------------------------------
void PfClass::PfISRLoop(UINT32 timeout)
{
    DWORD statReg1, chanMask;
    DWORD dwIntrCnt = 0;
    UINT32 oldVal, newVal, iMask, iBitval;

    PF_FUNCTION_ENTRY();

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

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

            statReg1 = INREG32(&P_IPU_REGS->IPU_INT_STAT_1);
            //dumpInterruptRegisters(P_IPU_REGS);
            if (statReg1 & 0xE0000000) // check PF channel status bits only
            {
                // EOF for Post-processor
                DEBUGMSG (ZONE_DEVICE, (TEXT("%s:*** Post-filtering End of frame interrupt ***\r\n"), __WFUNCTION__));

                if (!m_bRunning)
                {
                    // Don't do anything else.  We do not want to re-enable
                    // the buffer ready bits since we are stopping.
                    dwIntrCnt = 0;
                }
                else
                {
                    // Determine which channels have completed

                    // Check Y Output Channel
                    chanMask = 0x20000000;
                    if ((statReg1 & chanMask) & chanMask)
                    {
                        // Y output channel completed
                        dwIntrCnt++;
                        PfClearInterruptStatus(chanMask);
                    }

                    // Check U Output Channel
                    chanMask = 0x40000000;
                    if ((statReg1 & chanMask) & chanMask)
                    {
                        // U output channel completed
                        dwIntrCnt++;
                        PfClearInterruptStatus(chanMask);
                    }

                    // Check V Output Channel
                    chanMask = 0x80000000;
                    if ((statReg1 & chanMask) & chanMask)
                    {
                        // V output channel completed
                        dwIntrCnt++;
                        PfClearInterruptStatus(chanMask);
                    }

                    // PF operation is only done if we have received
                    // 3 interrupts (Y, U, and V output channels)
                    if (dwIntrCnt > 2)
                    {
                        // Clear all PF-related Status bits
                        chanMask = 0xE0000000;
                        PfClearInterruptStatus(chanMask);

                        if (!PfStopChannel())
                        {
                            DEBUGMSG (ZONE_DEVICE, (TEXT("%s: Could not properly stop PF channel!\r\n"), __WFUNCTION__));
                        }

                        // Trigger PF EOF event
                        SetEvent(m_hEOFEvent);

                        dwIntrCnt = 0;
                    }
                    else
                    {
                        // Re-enable interrupt control bits so
                        // that we can continue to receive PF interrupts.

                        // Protect access to IPU_INT_CTRL_1 register.

                        // Compute bitmask and shifted bit value for IPU_INT_CTRL_1 register
                        iMask = CSP_BITFMASK(IPU_DMA_CHA_DMAPF_5)
                            | CSP_BITFMASK(IPU_DMA_CHA_DMAPF_6)
                            | CSP_BITFMASK(IPU_DMA_CHA_DMAPF_7);
                        iBitval = CSP_BITFVAL(IPU_DMA_CHA_DMAPF_5, IPU_ENABLE)
                            | CSP_BITFVAL(IPU_DMA_CHA_DMAPF_6, IPU_ENABLE)
                            | CSP_BITFVAL(IPU_DMA_CHA_DMAPF_7, IPU_ENABLE);

                        // enable IPU interrupts for channels 29, 30, 31 (PF Y, U, and V Output)
                        do
                        {
                            oldVal = INREG32(&P_IPU_REGS->IPU_INT_CTRL_1);
                            newVal = (oldVal & (~iMask)) | iBitval;
                        } while (InterlockedTestExchange((LPLONG)&P_IPU_REGS->IPU_INT_CTRL_1, 
                                oldVal, newVal) != oldVal);
                    }
                }

            }

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

    }

    PF_FUNCTION_EXIT();
    return;
}

//------------------------------------------------------------------------------
//
// Function: dumpChannelParams
//
//
//
// Parameters:
//      None
//
// Returns:
//      None
//
//---------------------------------------------------------------------
static void dumpChannelParams(pPfIDMACChannelParams pChannelParams)
{
    DEBUGMSG (ZONE_DEVICE, (TEXT("Width       = %x\r\n"), pChannelParams->iWidth));
    DEBUGMSG (ZONE_DEVICE, (TEXT("Height      = %x\r\n"), pChannelParams->iHeight));
    DEBUGMSG (ZONE_DEVICE, (TEXT("BPP Code    = %x\r\n"), pChannelParams->iBitsPerPixelCode));
    DEBUGMSG (ZONE_DEVICE, (TEXT("Line Stride = %x\r\n"), pChannelParams->iLineStride));
    DEBUGMSG (ZONE_DEVICE, (TEXT("Format Code = %x\r\n"), pChannelParams->iFormatCode));
    DEBUGMSG (ZONE_DEVICE, (TEXT("Pixel Burst = %x\r\n"), pChannelParams->iPixelBurstCode));
    return;
}


//------------------------------------------------------------------------------
//
// Function: dumpInterruptRegisters
//
//
//
// Parameters:
//      None
//
// Returns:
//      None
//
//---------------------------------------------------------------------
static void dumpInterruptRegisters(PCSP_IPU_REGS pIPU)
{
    DEBUGMSG (ZONE_DEVICE, (TEXT("%s: IPU_INT_STAT_1: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->IPU_INT_STAT_1)));
    DEBUGMSG (ZONE_DEVICE, (TEXT("%s: IPU_INT_STAT_2: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->IPU_INT_STAT_2)));
    DEBUGMSG (ZONE_DEVICE, (TEXT("%s: IPU_INT_STAT_3: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->IPU_INT_STAT_3)));
    DEBUGMSG (ZONE_DEVICE, (TEXT("%s: IPU_INT_STAT_4: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->IPU_INT_STAT_4)));
    DEBUGMSG (ZONE_DEVICE, (TEXT("%s: IPU_INT_STAT_5: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->IPU_INT_STAT_5)));
    return;
}

//------------------------------------------------------------------------------
//
// Function: dumpIpuRegisters
//
//
//
// Parameters:
//      None
//
// Returns:
//      None
//
//---------------------------------------------------------------------
static void dumpIpuRegisters(PCSP_IPU_REGS pIPU)
{
    DEBUGMSG (ZONE_DEVICE, (TEXT("%s: IPU_CONF: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->IPU_CONF)));
    DEBUGMSG (ZONE_DEVICE, (TEXT("%s: IPU_CHA_BUF0_RDY: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->IPU_CHA_BUF0_RDY)));
    DEBUGMSG (ZONE_DEVICE, (TEXT("%s: IPU_CHA_BUF1_RDY: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->IPU_CHA_BUF1_RDY)));
    DEBUGMSG (ZONE_DEVICE, (TEXT("%s: IPU_CHA_DB_MODE_SEL: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->IPU_CHA_DB_MODE_SEL)));
    DEBUGMSG (ZONE_DEVICE, (TEXT("%s: IPU_CHA_CUR_BUF: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->IPU_CHA_CUR_BUF)));
    DEBUGMSG (ZONE_DEVICE, (TEXT("%s: IPU_FS_PROC_FLOW: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->IPU_FS_PROC_FLOW)));
    DEBUGMSG (ZONE_DEVICE, (TEXT("%s: IPU_FS_DISP_FLOW: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->IPU_FS_DISP_FLOW)));
    DEBUGMSG (ZONE_DEVICE, (TEXT("%s: IPU_TASK_STAT: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->IPU_TASK_STAT)));
    DEBUGMSG (ZONE_DEVICE, (TEXT("%s: IPU_INT_CTRL_1: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->IPU_INT_CTRL_1)));
    DEBUGMSG (ZONE_DEVICE, (TEXT("%s: IPU_INT_STAT_1: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->IPU_INT_STAT_1)));
    DEBUGMSG (ZONE_DEVICE, (TEXT("%s: IPU_INT_STAT_2: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->IPU_INT_STAT_2)));
    DEBUGMSG (ZONE_DEVICE, (TEXT("%s: IPU_INT_STAT_3: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->IPU_INT_STAT_3)));
    DEBUGMSG (ZONE_DEVICE, (TEXT("%s: IPU_INT_STAT_5: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->IPU_INT_STAT_5)));
    DEBUGMSG (ZONE_DEVICE, (TEXT("%s: PF_CONF: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->PF_CONF)));
    DEBUGMSG (ZONE_DEVICE, (TEXT("%s: SDC_COM_CONF: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->SDC_COM_CONF)));
    DEBUGMSG (ZONE_DEVICE, (TEXT("%s: SDC_FG_POS: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->SDC_FG_POS)));
    DEBUGMSG (ZONE_DEVICE, (TEXT("%s: IDMAC_CHA_BUSY: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->IDMAC_CHA_BUSY)));
}

static void ReadVfDMA(PCSP_IPU_REGS pIPU)
{
    int i;
    UINT32 data;

    // Software-controlled access to IMA registers
    // IMA registers may only be accessed if IMA_ADDR is
    // set to 0.

    while (1)
    {
        if (INREG32(&pIPU->IPU_IMA_ADDR) == 0)
        {
            // Try to set IPU_IMA registers.
            if (InterlockedTestExchange((LPLONG)&pIPU->IPU_IMA_ADDR, 0, 1) == 0)
            {
                // Successfully set IMA_ADDR.
                break;
            }
        }
        // IPU_IMA controlled by another process.
        // Surrender CPU and then try again.
        Sleep(0);
    }

    OUTREG32(&pIPU->IPU_IMA_ADDR,
            CSP_BITFVAL( IPU_IPU_IMA_ADDR_MEM_NU, IPU_IMA_ADDR_MEM_NU_CPM) |
            CSP_BITFVAL( IPU_IPU_IMA_ADDR_ROW_NU, 2)|
            CSP_BITFVAL( IPU_IPU_IMA_ADDR_WORD_NU, 0));

    for (i = 0; i < 132; i += 32)
    {
        data = INREG32(&pIPU->IPU_IMA_DATA);
        DEBUGMSG(ZONE_ERROR,
                 (TEXT("%s(): Word0, bits %d - %d: %x\r\n"), __WFUNCTION__, i, i+32, data));
    }

    OUTREG32(&pIPU->IPU_IMA_ADDR,
            CSP_BITFVAL( IPU_IPU_IMA_ADDR_MEM_NU, IPU_IMA_ADDR_MEM_NU_CPM) |
            CSP_BITFVAL( IPU_IPU_IMA_ADDR_ROW_NU, 3)|
            CSP_BITFVAL( IPU_IPU_IMA_ADDR_WORD_NU, 0));

    for (i = 0; i < 132; i += 32)
    {
        data = INREG32(&pIPU->IPU_IMA_DATA);
        DEBUGMSG(ZONE_ERROR,
                 (TEXT("%s(): Word1, bits %d - %d: %x\r\n"), __WFUNCTION__, i, i+32, data));
    }

    // Cede control of IPU_IMA registers by writing 0 to IPU_IMA_ADDR
    OUTREG32(&pIPU->IPU_IMA_ADDR, 0);
}

⌨️ 快捷键说明

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