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

📄 config.cpp

📁 Wince4.2 BSP for SH4 engineering development board
💻 CPP
📖 第 1 页 / 共 4 页
字号:

    if (g_dwCursorAreaOffset
        < g_dwFrameBufferOffset + g_dwFrameBufferSize) {
        // If the top of the cursor area is within the frame buffer,
        // the video memory space is not enough.
        RETAILMSG(1,
            (TEXT("AMADisp: Not enough video memory space.\r\n")));
        return FALSE;
    }

    g_dwDisplayClock = dwDisplayClock;
    g_dwCursorBlinkFrames = dwFrameRate / 2; // 0.5s for each pattern

    // Linear-tile hardware translation setup
    // Like Q2SD, HD64404 GE can render only to the tilemapped screen.
    // In HD64404, the hardware translates tilemapped frame buffer to
    // linear bitmap screen, so the WinCE GWES can handle it directly.

    // Linear-tile translation address
    AMADispMode[0].MPXIFRegs[MPXIF_LTAD] =
        g_dwVideoMemoryOffset & 0x07F80000;
    // Linear-tile translation bit mask, used to extend translation area
    AMADispMode[0].MPXIFRegs[MPXIF_LTAM] =
        0x07F80000 & (1 + ~g_dwVideoMemorySize); // video memory size

    AMADispMode[0].DORegs[DO_DSAR0H ] =      // display start address for FB0
        (g_dwFrameBufferOffset & 0x03FF0000) >> 16
        | (g_dwFrameBufferOffset & 0x04000000) >> 10;
    AMADispMode[0].DORegs[DO_DSAR0L ] =
        g_dwFrameBufferOffset & 0x0000FC00;
    AMADispMode[0].DORegs[DO_DSAR1H ] =      // display start address for FB1
        (g_dwFrameBufferOffset & 0x03FF0000) >> 16
        | (g_dwFrameBufferOffset & 0x04000000) >> 10;
    AMADispMode[0].DORegs[DO_DSAR1L ] =
        g_dwFrameBufferOffset & 0x0000FC00;
    // WSAR requires 32kB alignment. (worst case)
    AMADispMode[0].GERegs[GE_WSAR   ] =      // rendering work start address
        (g_dwWorkAreaOffset >> 16) | (g_dwWorkAreaOffset & 0xE000);

    // CSARn requires 2kB (32x32) or 8kB (64x64) alignment.
    AMADispMode[0].DORegs[DO_CSAR1  ] =      // cursor 1 pattern address
        (g_dwCursorAreaOffset & 0x04000000) >> 10
        | (g_dwCursorAreaOffset & 0x03FF0000) >> 16
        | (g_dwCursorAreaOffset & 0x0000F800);
    AMADispMode[0].DORegs[DO_CSAR2  ] =      // cursor 2 pattern address
        ((g_dwCursorAreaOffset + CURSOR_BYTES * 2) & 0x04000000) >> 10
        | ((g_dwCursorAreaOffset + CURSOR_BYTES * 2) & 0x03FF0000) >> 16
        | ((g_dwCursorAreaOffset + CURSOR_BYTES * 2) & 0x0000F800);

    // GPEMode parameter setup
    // mode id
    AMADispMode[0].gpeMode.modeId = 0;
    // screen width in pixels
    AMADispMode[0].gpeMode.width = dwScreenWidth;
    // screen height in lines
    AMADispMode[0].gpeMode.height = dwScreenHeight;
    // color depth, bit per pixel
    AMADispMode[0].gpeMode.Bpp = dwBpp;
    // screen refresh rate
    AMADispMode[0].gpeMode.frequency = dwFrameRate;
    // pixel format in GPE style
    AMADispMode[0].gpeMode.format =
        dwBpp == 8 ? gpe8Bpp : gpe16Bpp;

    return GPEEnableDriver( iEngineVersion, cj, pded, pEngCallbacks );
}


//
// CalcInternalPLLParams
//
// - This function searches applicatable HD64404 display clock PLL parameters
// to get nearest frequency from requested.
BOOL CalcInternalPLLParams(
    DWORD       dwBaseFreq,
    DWORD       dwTargetFreq,
    DWORD       *pdwOutputFreq,
    DWORD       *pdwDivN,
    DWORD       *pdwDivA,
    DWORD       *pdwDivB,
    DWORD       *pdwDivC,
    DWORD       *pdwDivP )
{

    DWORD dwN; // This is not altered.
    DWORD dwA, dwAMin, dwAMax;
    DWORD dwB, dwBMin, dwBMax;
    DWORD dwC, dwCMin, dwCMax;
    DWORD dwP;

    DWORD dwSearchStatus; // O means not found, other means found.
    DWORD dwCurA, dwCurB, dwCurC, dwCurP;
    LONG lErrPermil, lCurErrPermil; // 1 Permil = 1/1000
    DWORD dwOscFreq, dwOutputFreq, dwCurOutputFreq;

    // This function assumes that each of DivN, DivA, DivB, DivC, and DivP
    // parameters are in available range, or REG_NOTSPECIFIED that means the
    // corresponding registry key is omitted. Specified parameters are not
    // altered while searching available PLL configurations.

    // Feedback divider N
    if (*pdwDivN == REG_NOTSPECIFIED) dwN = 1;
    else dwN = *pdwDivN;

    // Input divider A
    if (*pdwDivA == REG_NOTSPECIFIED) {
        // DivA is not specified. This allows scanning DivA.
        dwAMin = 1;
        dwAMax = 16;
    }
    else {
        // DivA is specified. DivA is fixed.
        dwAMin = *pdwDivA;
        dwAMax = *pdwDivA;
    }

    // Feedback divider B
    if (*pdwDivB == REG_NOTSPECIFIED) {
        // DivB is not specified. This allows scanning DivB.
        dwBMin = 1;
        dwBMax = 16;
    }
    else {
        // DivB is specified. DivB is fixed.
        dwBMin = *pdwDivB;
        dwBMax = *pdwDivB;
    }

    // Output divider C
    if (*pdwDivC == REG_NOTSPECIFIED) {
        // DivC is not specified. This allows scanning DivC.
        dwCMin = 1;
        dwCMax = 4;
    }
    else {
        // DivC is specified. DivC is fixed.
        dwCMin = *pdwDivC;
        dwCMax = *pdwDivC;
    }

    dwSearchStatus = 0; // This means available set is not found.
    lCurErrPermil = 1000; // Current minimum error, set to enough large.

    // Main loop for searching PLL parameters.
    for (dwA = dwAMin; dwA <= dwAMax; dwA++) {
        for (dwB = dwBMin; dwB <= dwBMax; dwB++) {
            for (dwC = dwCMin; dwC <= dwCMax; dwC++) {

                // VCO oscillation frequency check
                if (*pdwDivP == REG_NOTSPECIFIED) {
                    // Both 1 and 2 are available for DivP.
                    dwOscFreq = dwBaseFreq * dwB / dwA;
                    if (dwOscFreq * 2 > DO_PLL_VCOHIGH) goto NotAvail; // P=1
                    else if (dwOscFreq * 2 >= DO_PLL_VCOLOW) dwP = 1;
                    else if (dwOscFreq * 4 >= DO_PLL_VCOLOW) dwP = 2;
                    else goto NotAvail;
                }
                else {
                    // check with specified DivP
                    dwP = *pdwDivP;
                    dwOscFreq = dwBaseFreq * dwB / dwA * (1 << dwP);
                    if (dwOscFreq < DO_PLL_VCOLOW
                        || dwOscFreq > DO_PLL_VCOHIGH) goto NotAvail;
                }

                // Total feedback divisor must be lower or equal 32.
                if (dwN * dwB * (1 << dwP) > 32) goto NotAvail;

                // Calculate output frequency and error rate.
                dwOutputFreq = dwBaseFreq * dwN / dwA * dwB / dwC;
                lErrPermil =
                    ((LONG)dwOutputFreq - (LONG)dwTargetFreq)
                    / (LONG)(dwTargetFreq / 1000);

                // Error rate must be within -3.0% to 3.0%.
                if (lErrPermil > 30 || lErrPermil < -30) goto NotAvail;

                DEBUGMSG(GPE_ZONE_HW,
                    (TEXT("A=%d B=%d C=%d DCLK=%d, %d.%d percent error.\r\n"),
                    dwA, dwB, dwC, dwOutputFreq, lErrPermil / 10,
                    abs(lErrPermil) - abs(lErrPermil / 10) * 10));

                // Store PLL parameters if this set provides lowest error
                // or this is the first available set.
                if (abs(lErrPermil) < abs(lCurErrPermil)
                    || dwSearchStatus == 0) {
                    dwSearchStatus = 1; // available parameter set is found
                    dwCurA = dwA;
                    dwCurB = dwB;
                    dwCurC = dwC;
                    dwCurP = dwP;
                    dwCurOutputFreq = dwOutputFreq;
                    lCurErrPermil = lErrPermil;
                }

NotAvail:       ; // Try next combination if the loop have not reached to end.

            }
        }
    }

    if (!dwSearchStatus) { // Failed to find parameter set.
        RETAILMSG(1,
            (TEXT("AMADisp: Failed to find available PLL parameter set.\r\n")));
        return FALSE;
    }
    else { // Available parameter set is found.
        DEBUGMSG(1,
            (TEXT("AMADisp: Available PLL parameter set is found.\r\n")));
        DEBUGMSG(1,
            (TEXT("AMADisp: A=%d, B=%d, C=%d, N=%d, P=%d, DisplayClock=%d.\r\n"),
            dwCurA, dwCurB, dwCurC, dwN, dwCurP, dwCurOutputFreq));
        *pdwOutputFreq = dwCurOutputFreq;
        *pdwDivA = dwCurA;
        *pdwDivB = dwCurB;
        *pdwDivC = dwCurC;
        *pdwDivN = dwN;
        *pdwDivP = dwCurP;
        return TRUE;
    }
}


//
// CalcICD2053PLLParams
//
// - This function searches applicatable ICD2053 clock generator PLL
// parameters to get nearest frequency from requested.
BOOL CalcICD2053PLLParams(
    DWORD       dwBaseFreq,
    DWORD       dwTargetFreq,
    DWORD       *pdwOutputFreq,
    DWORD       *pdwDivP,
    DWORD       *pdwDivQ,
    DWORD       *pdwMux )
{

    DWORD dwP, dwPMin, dwPMax;
    DWORD dwQ, dwQMin, dwQMax;
    DWORD dwM, dwMMin, dwMMax;

    DWORD dwSearchStatus; // O means not found, other means found.
    DWORD dwCurP, dwCurQ, dwCurM;
    LONG lErrPermil, lCurErrPermil; // 1 Permil = 1/1000
    DWORD dwOscFreq, dwOutputFreq, dwCurOutputFreq;
    DWORD dwTemp;

    // This function assumes that each of DivP, DivQ and Mux parameters are in
    // available range, or REG_NOTSPECIFIED that means the corresponding
    // registry key is omitted. Specified parameters are not altered while
    // searching available PLL configurations.

    // Feedback divider P
    if (*pdwDivP == REG_NOTSPECIFIED) {
        // DivP is not specified. This allows scanning DivP.
        dwPMin = 4;
        dwPMax = 130;
    }
    else {
        // DivP is specified. DivP is fixed.
        dwPMin = *pdwDivP;
        dwPMax = *pdwDivP;
    }

    // Input divider Q
    if (*pdwDivQ == REG_NOTSPECIFIED) {
        // DivQ is not specified. This allows scanning DivQ.
        dwQMin = 3;
        dwQMax = 129;
    }
    else {
        // DivQ is specified. DivQ is fixed.
        dwQMin = *pdwDivQ;
        dwQMax = *pdwDivQ;
    }

    // Output multiplexer M
    if (*pdwMux == REG_NOTSPECIFIED) {
        // Mux is not specified. This allows scanning Mux.
        dwMMin = 0;
        dwMMax = 7;
    }
    else {
        // Mux is specified. Mux is fixed.
        dwMMin = *pdwMux;
        dwMMax = *pdwMux;
    }

    dwSearchStatus = 0; // This means available set is not found.
    lCurErrPermil = 1000; // Current minimum error, set to enough large.

    // Main loop for searching PLL parameters.
    for (dwP = dwPMin; dwP <= dwPMax; dwP++) {
        for (dwQ = dwQMin; dwQ <= dwQMax; dwQ++) {
            for (dwM = dwMMin; dwM <= dwMMax; dwM++) {

                // Divided reference frequency must be in 200kHz - 1MHz.
                dwTemp = dwBaseFreq / dwQ;
                if (dwTemp < 200000 || dwTemp > 1000000) goto NotAvail;

                // VCO oscillation frequency check
                dwOscFreq = dwBaseFreq * 2 * dwP / dwQ;
                if (dwOscFreq < 50000000 || dwOscFreq > 150000000)
                    goto NotAvail;

                // Calculate output frequency and error rate.
                dwOutputFreq = dwOscFreq / (1 << dwM);
                lErrPermil =
                    ((LONG)dwOutputFreq - (LONG)dwTargetFreq)
                    / (LONG)(dwTargetFreq / 1000);

                // Error rate must be within -3.0% to 3.0%.
                if (lErrPermil > 30 || lErrPermil < -30) goto NotAvail;

                DEBUGMSG(GPE_ZONE_HW,
                    (TEXT("P=%d Q=%d M=%d DCLK=%d, %d.%d percent error.\r\n"),
                    dwP, dwQ, dwM, dwOutputFreq, lErrPermil / 10,
                    abs(lErrPermil) - abs(lErrPermil / 10) * 10));

                // Store PLL parameters if this set provides lowest error
                // or this is the first available set.
                if (abs(lErrPermil) < abs(lCurErrPermil)
                    || dwSearchStatus == 0) {
                    dwSearchStatus = 1; // available parameter set is found
                    dwCurP = dwP;
                    dwCurQ = dwQ;
                    dwCurM = dwM;
                    dwCurOutputFreq = dwOutputFreq;
                    lCurErrPermil = lErrPermil;
                }

NotAvail:       ; // Try next combination if the loop have not reached to end.

            }
        }
    }

    if (!dwSearchStatus) { // Failed to find parameter set.
        RETAILMSG(1,
            (TEXT("AMADisp: No available PLL parameter set.\r\n")));
        return FALSE;
    }
    else { // Available parameter set is found.
        DEBUGMSG(1,
            (TEXT("AMADisp: Available PLL parameter set is found.\r\n")));
        DEBUGMSG(1,
            (TEXT("AMADisp: P=%d, Q=%d, M=%d, DisplayClock=%d.\r\n"),
            dwCurP, dwCurQ, dwCurM, dwCurOutputFreq));
        *pdwOutputFreq = dwCurOutputFreq;
        *pdwDivP = dwCurP;
        *pdwDivQ = dwCurQ;
        *pdwMux = dwCurM;
        return TRUE;
    }
}

⌨️ 快捷键说明

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