Shop OBEX P1 Docs P2 Docs Learn Events
NCO settings calculator - Unexpected result — Parallax Forums

NCO settings calculator - Unexpected result

I coded up a calculator to help pick WXPIN and WYPIN settings for NCO Frequency smart pin mode.

Was thinking that the WXPIN setting is totally useless because my calculator was always telling me that the best setting was WXPIN=1.

This is with P2 frequency equals 160 MHz.

But while testing, when I put in 2 MHz for desired frequency, I got 5 for the best WXPIN setting.
See this screenshot for 200 kHz result.

Seems very strange, but maybe correct?

720 x 776 - 39K

Comments

  • RaymanRayman Posts: 14,640

    Here's my simple code to calculate WXPIN and WYPIN settings in C++.
    It's just brute force looking for a better WXPIN... Maybe there's a better way?

    void CObjectNCO::CalculateNCO()
    {
        UpdateData(true);
        CString sp2f=m_pDoc->m_sP2Freq;
        int np2f = _wtoi(sp2f);
    
        int nFreqDesired = _wtoi(m_sDesiredFreq);
    
        if (nFreqDesired > (np2f/2))
        {
            CString mess;
            mess.Format(L"Error:  Desired frequency (%d) cannot be greater than half P2 Frequency (%d)", nFreqDesired, np2f/2);
            AfxMessageBox(mess);
            return;
        }
    
        int wx = 1;
        int wy = (np2f/2) / nFreqDesired;
        wy = 0x80000000 / wy;
        double factual = (wy / (0x80000000 * 1.0)) * (np2f / 2.0);
        int ifact = (int)factual;
        int delta = abs(nFreqDesired - ifact);
        int bestx = wx;
        int bestdelta = delta;
    
    
        for (int x = 2; x < 133; x++)
        {//look for a better x..  Will we ever find one?
            wy = (np2f / 2/x) / nFreqDesired;
            if (wy == 0)
                break;
            wy = 0x80000000 / wy;
            factual = (wy / (0x80000000 * 1.0)) * (np2f / 2.0/x);
            ifact = (int)factual;
            delta = abs(nFreqDesired - ifact);
    
            if (delta < bestdelta)
            {
                bestx = x;
                bestdelta = delta;
            }
        }
    
    
        wx = bestx;
        wy = (np2f / 2 / wx) / nFreqDesired;
    
    
        if (wy == 1)
        {//at upper limit of 32-bit int
            wy = 0x80000000;
            factual = (np2f / 2.0/wx);
        }
        else
        {
            wy = 0x80000000 / wy;
            factual = (wy / (0x80000000 * 1.0)) * (np2f / 2.0 / wx);
        }
        ifact = (int)factual;
    
    
    
        m_sWXPIN.Format(L"%08X", wx);
        m_sWYPIN.Format(L"%08X", wy);
    
        //m_sActualFrequency.Format(L"%d", ifact);
        m_sActualFrequency.Format(L"%f", factual);
    
        UpdateData(false);
    
    
    }
    
    
  • AribaAriba Posts: 2,690

    Seems very strange, but maybe correct?

    Yes that is correct:
    160 / 2 = 80, so we need 1/80 of sysclock
    80 = 5 * 16, so if you divide by 5 the phase accumulator of the NCO must divide by 16, which is exactly possible, while 1/80 is not exact possible, only 1 / 80.000000298...

    Andy

Sign In or Register to comment.