Keyboard Shortcuts
ctrl + shift + ? :
Show all keyboard shortcuts
ctrl + g :
Navigate to a group
ctrl + shift + f :
Find
ctrl + / :
Quick actions
esc to dismiss
Likes
Search
Where does this noise/instability come from at and around 300MHz?
On Wed, Jun 30, 2021 at 11:31 AM, DiSlord wrote:
I've been using the Si5351 in another project and decided to test the chip at boot-up to find each individual chips (Si5351) possible PLL frequency range rather than having the 300MHz parameter be user settable. All I do is to do a quick boot-up sweep of each PLL (A and B) in the chip to find their min and max frequencies by monitoring the PLL lock bit in the chip. Each PLL typical takes around 600us to lock to a desired frequency, so if it takes longer than say 1ms to lock then I take that as being the PLL's min and max limits. I'm finding the PLL's usable frequency range (specified as 600MHz to 900MHz) in each can vary by quite a bit, so auto finding the real limits is very useful and handy. Rather than storing the min/max PLL limits for each of the two PLL's I use the same min/max limits for both PLL's - a range that reliably works for BOTH PLL's (ie, I use the worse case min/max scanned frequency range from the two PLL's). Doing this in the NanoVNA's when the user turns the device on would remove the guess work, chip variation, temperature PLL lock range dependency and the user command etc from the equation. Each individual unit would auto self select the 300MHz switch point. Could still keep a manual settings if desired I guess. |
This is the code I use to find the PLL min/max limits, but any desired code will do ..
uint32_t si5351a_pllLocked(const uint8_t pll, const uint32_t timeout_us) { uint8_t pll_bit; uint32_t locked_cycles = 0; if (rev_id == 0 || pll >= 2) return 0; // error switch (pll) { default: return 0; case 0: pll_bit = 1u << 5; break; // PLL-A case 1: pll_bit = 1u << 6; break; // PLL-B } if (timeout_us > 0) { // wait for the PLL to lock (with timeout) uint32_t lock_cycle = 0; //ITM->LAR = 0xC5ACCE55; // unlock the debug registers //CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; // DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; // turn on the cycle counter const uint32_t start_cycle = DWT->CYCCNT; // const uint32_t timeout_cycles = ((uint64_t)SystemCoreClock * timeout_us) / 1000000; const uint32_t lock_cycles = ((uint64_t)SystemCoreClock * 10) / 1000000; // PLL needs to stay locked for at least 10us while (1) { const uint32_t cycle = DWT->CYCCNT; const uint32_t cycles = cycle - start_cycle; if (cycles >= timeout_cycles) break; // timed out if (si5351a_read(SI5351_DEV_STATUS) & pll_bit) { // unlocked lock_cycle = 0; locked_cycles = 0; continue; } if (lock_cycle == 0) lock_cycle = cycle; // start of lock // length of time it's been locked locked_cycles = cycles - lock_cycle; if (locked_cycles >= lock_cycles) break; // been locked for long enough } } return (si5351a_read(SI5351_DEV_STATUS) & pll_bit) ? 0 : ((uint64_t)locked_cycles * 1000000) / SystemCoreClock; // 0 = unlocked, otherwise return the time it took to lock } void si5351a_findVCOLimits(void) { // scan the PLL's VCO's across a frequency range to find their min and max tuning limits const uint32_t start_Hz = xtal_Hz * 15; const uint32_t stop_Hz = xtal_Hz * 90; const uint32_t step_Hz = 20000000; // step the PLL's in 20MHz steps .. seems as good as any? /* uint32_t min_lock_time_us = 0; uint32_t max_lock_time_us = 0; */ uint8_t pll; min_pll_Hz = 0; max_pll_Hz = 0; // scan both PLL's across a wide frequency range for (pll = 0; pll < 2; pll++) { uint32_t min_Hz = 0; uint32_t max_Hz = 0; uint32_t fvco_Hz = start_Hz; // disable PLL INTEGER mode si5351a_write(SI5351_CLK_CONTROL + 6 + pll, si5351a_read(SI5351_CLK_CONTROL + 6 + pll) & ~(1u << 6)); // scan from low to high frequency while (fvco_Hz <= stop_Hz) { uint32_t pll_a; uint32_t pll_b; uint32_t pll_c; // calculate the PLL register values const uint32_t vco_Hz = calcPLL((uint64_t)fvco_Hz * SI5351_FREQ_MULT, &pll_a, &pll_b, &pll_c) / SI5351_FREQ_MULT; if (vco_Hz == fvco_Hz) { // set the PLL registers si5351a_setPLL(pll, pll_a, pll_b, pll_c, 1); // see if the PLL locks OK const uint32_t lock_time_us = si5351a_pllLocked(pll, 1500); // wait for up to 1.5ms for the PLL to lock .. avg around 618us, max around 1200us if (lock_time_us > 0) { // PLL acquired lock at this particular frequency if (min_Hz == 0) min_Hz = vco_Hz; // remeber the min frequency max_Hz = vco_Hz; // remeber the max frequenct } } fvco_Hz += step_Hz; } if (min_pll_Hz == 0 || min_pll_Hz < min_Hz) min_pll_Hz = min_Hz; if (max_pll_Hz == 0 || max_pll_Hz > max_Hz) max_pll_Hz = max_Hz; } } |
Just wondering if you hit the parts you're testing with a heat gun and/or freezing spray to see how how well the consumer level parts react.
toggle quoted message
Show quoted text
On Tuesday, August 17, 2021, 05:36:40 a.m. EDT, OneOfEleven <cmoss296@...> wrote:
On Wed, Jun 30, 2021 at 11:31 AM, DiSlord wrote: I've been using the Si5351 in another project and decided to test the chip at boot-up to find each individual chips (Si5351) possible PLL frequency range rather than having the 300MHz parameter be user settable. All I do is to do a quick boot-up sweep of each PLL (A and B) in the chip to find their min and max frequencies by monitoring the PLL lock bit in the chip. Each PLL typical takes around 600us to lock to a desired frequency, so if it takes longer than say 1ms to lock then I take that as being the PLL's min and max limits. I'm finding the PLL's usable frequency range (specified as 600MHz to 900MHz) in each can vary by quite a bit, so auto finding the real limits is very useful and handy. Rather than storing the min/max PLL limits for each of the two PLL's I use the same min/max limits for both PLL's - a range that reliably works for BOTH PLL's (ie, I use the worse case min/max scanned frequency range from the two PLL's). Doing this in the NanoVNA's when the user turns the device on would remove the guess work, chip variation, temperature PLL lock range dependency and the user command etc from the equation. Each individual unit would auto self select the 300MHz switch point. Could still keep a manual settings if desired I guess. |
to navigate to use esc to dismiss