Computer & RF Technology

Si5351Aの使い方と動作

Si5351AクロックジェネネータをFriskSDRのローカルや、NanoVNAの信号源として試用してみています。Si5351Aの仕様では、上限は200MHzまでとされていますが、実際に試してみたところ300MHzを越える周波数まで発生させられるようです。以前最初に試した様子を書きましたが、その後の知見をまとめておきます。

image

Si5351Aは、内部にPLLを二つ、さらにそれを分周した出力を三つ取り出すせるクロックジェネレータです。水晶と合わせて10x10mm以下の面積でコンパクトに実装することができます。

大変便利なチップなのですが、その設定は少しやっかいで、内部構成を理解していないとレジスタに与える設定値を決めることができません。最初の実験で試したように、Arduinoのライブラリは何種類かあるようですが、目的にはちょっと合いませんでしたので、参考にさせてもらいつつ、FriskSDRやNanoVNAを作るためにコードを作成してみましたので少し解説します。

image

Si5351Aは内部が二段構成になっており、前段のPLLと、後段の分周器(MultiSynth)を独立に設定しなければならなりません。PLLとMultiSynthは、それぞれフラクショナル(分数分周器)となっています。前段、後段それぞれに自由度があるので、同じ周波数を出力させるために、可能な設定は一意に決まりません。さらに、設定にあたっていくつか考慮しなければならない制約があります。

PLLとMultiSynthは似たような分数分周器となっており、その分周比は三つの整数を使って表現できます。

a + b / c

設定にあたってまず押さえておかねばならないのが、PLL側で生成可能な周波数が、600〜900MHzでなければならないことです。可変範囲が1.5倍の範囲ですので案外と狭いです。

一方、MultiSynth側にも制約があります。150MHz以上の出力を得るためには、1/4の固定分周比を使用する必要があることが明記されています(AN619 6p 4.2.2節)。では150MHz以下ならあとは自在かと思えば、実はまだ制約があり、分周比が8以下の分周比については、分数分周比が使えず、4,6,8の整数比の分周動作動作のみが可能となっています。PLLの下限が600MHzですから、150MHz以下を発生させようとすると、分周比を6を選択する必要があるのです。同様に、100MHz以下に設定したければ分周比を8以上に設定することになりますが、その範囲になるとMultiSynth側で分数分周比が使えるようになり、任意の周波数を設定する自由度がMultiSynth側に出てきます。そしてMultiSynthの分周の上限は1800ですので、600MHz/1800=333kHzで周波数の下限に達します。これ以下の周波数を設定しようとするなら今度はMultiSynthの後ろに用意されている2^Nの分周器Rを使う必要があります。Rは1/128まで設定可能ですから、下限は333kHz/128=およそ2.6kHzとなります。

以上のように、出力したい周波数範囲によって、設定の方針が違ってきます。まとめると次の様になります。 

  • 150MHz < Fout :MultiSynth=4とし、PLLを分数比で使い4xFoutに設定する

  • 100MHz < Fout < 150MHz :MultiSynth=6とし、PLLを分数比で使い6xFoutに設定する

  • 333kHz < Fout < 112.5MHz :1) MultiSynthを8以上任意(<=1800)の分数分周比で使用し、PLL側を整数比で固定する。2) MultiSynthを8以上の整数比Nで使用し、PLL側をNxFoutとなるよう設定する(PLLが600~900MHzに入るようNを決める)

  • 3kHz < Fout < 500kHz :Rを適切に決めて、後は同じ

RFアプリケーションであれば、Rを使用する必要は無さそうです。

ちなみに設定可能な周波数のレゾリューションは、設定値や設定方針によって変化しますが、およそ数10Hz単位での設定可能です。分数部分のbとcは20ビットの幅を持っていますので、PLLまたはMultiSynthの片側だけ数10Hz程度。あるいは(面倒ですが)両者を任意に設定する気があるなら、もっと細かい分解能が得られます(これが適用可能な周波数領域は112.5MHz以下に限られます)。もちろん低周波数なら、Rを大きく取るとレゾリューションもその分細かくなります。実はCLK入力にも1,2,4,8の分周器があるので、PLL側の設定解像度を上げられるのですが、PLL分周器の設定範囲(15-90)から制約を受けます。実用的にはCLK分周器は使用する必要は無いと思います。

生成する信号の質を考慮すると、可能なら整数比を使うとスプリアスが減ります。整数比の場合に適用する特別なビットがレジスタにあります。分数比を使う場合でも、できるだけ簡単な比になるようにすると良いようです。

以上のことから、係数を決定するには次のような方法が良いと思われます。PLLとMultiSynthそれぞれについて、設定したい周波数と、水晶やその他の条件から、a,b,cを決めます。そしてb,cがなるべく簡単な比になるようユークリッドの互除法を使って分子分母の最大公約数を求め、既約分数にします。さらにもし20ビットの範囲に納まらなかった場合は、精度が犠牲になりますが数値を丸めます。

PLLの設定は下記のようにします。MultiSynthを固定分周比(4または6)に設定して、PLLを4*freqまたは6*freqに設定します。

void
si5351_set_frequency_fixeddiv(int channel, int pll, int freq, int div)
{
   int32_t pllfreq = freq * div;
   int32_t multi = pllfreq / XTALFREQ;
   int32_t num = pllfreq - multi * XTALFREQ;
   int32_t denom = XTALFREQ;
   int32_t k = gcd(num, denom);
   num /= k;
   denom /= k;
   while (denom >= (1<<20)) {      num >>= 1;
     denom >>= 1;
   }
   si5351_setupPLL(pll, multi, num, denom);
   si5351_setupMultisynth(channel, pll, div, 0, 1);
}

PLLを固定し、MultiSynthを可変する場合には下記のようにします。

void
si5351_set_frequency_fixedpll(int channel, int pll, int pllfreq, int freq)
{
   int32_t div = pllfreq / freq; // range: 8 ~ 1800
   int32_t num = pllfreq - freq * div;
   int32_t denom = freq;
   int32_t k = gcd(num, denom);
   num /= k;
   denom /= k;
   while (denom >= (1<<20)) {      num >>= 1;
     denom >>= 1;
   }
   si5351_setupMultisynth(channel, pll, div, num, denom);
}

a,b,c(下記の式ではmulti,num,denom)を決めることができたら、下記の式に従ってP1,P2,P3を求め、それを8つのレジスタ(各8ビット)に配置します。

P1[17:0] = 128 * mult + floor(128*(num/denom)) - 512
P2[19:0] = 128 * num - denom * floor(128*(num/denom))
P3[19:0] = denom

それからレジスタ設定には順序があり、これに従わないと周波数切り替えの際にうまく設定されないことがありました(実際にハマった)。 データシート17pにある下記フローのようにします。

image

これらを合わせて、周波数の範囲により、設定方針を切り替えるため、例えば下記の様にします。

void
si5351_set_frequency(int channel, int pll, int freq)
{
 si5351_disable_output();
 if (freq <= 100000000) {
   si5351_setupPLL(pll, PLL_N, 0, 1);
   si5351_set_frequency_fixedpll(channel, pll, PLLFREQ, freq);
 } else if (freq < 150000000) {
   si5351_set_frequency_fixeddiv(channel, pll, freq, 6);
 } else {
   si5351_set_frequency_fixeddiv(channel, pll, freq, 4);
 }
 si5351_reset_pll();
 si5351_enable_output();
}

もし、周波数を可変する必要が無いなら、こんなコードは必要ありません。あらかじめレジスタ値を計算しておけば良いのです。Si5351AのI2Cは、自動インクリメント動作をするので、こんなデータを用意しておけば、まとめてデータを送ることができます。

static void
si5351_bulk_write(const uint8_t *buf, int len)
{
 int addr = SI5351_I2C_ADDR>>1;
 i2cAcquireBus(&I2CD1);
 (void)i2cMasterTransmitTimeout(&I2CD1, addr, buf, len, NULL, 0, 1000);
 i2cReleaseBus(&I2CD1);
}

// register addr, length, data, …
const uint8_t si5351_configs[] = {
 2, SI5351_REG_3_OUTPUT_ENABLE_CONTROL, 0xff,
 4, SI5351_REG_16_CLK0_CONTROL, SI5351_CLK_POWERDOWN, SI5351_CLK_POWERDOWN, SI5351_CLK_POWERDOWN,
 2, SI5351_REG_183_CRYSTAL_LOAD, SI5351_CRYSTAL_LOAD_8PF,
 // setup PLL (26MHz * 32 = 832MHz, 32/2-2=14)
 9, SI5351_REG_26_PLL_A, /*P3*/0, 1, /*P1*/0, 14, 0, /*P3/P2*/0, 0, 0,
 // RESET PLL
 2, SI5351_REG_177_PLL_RESET, SI5351_PLL_RESET_A | SI5351_PLL_RESET_B,
 // setup multisynth (832MHz / 104 = 8MHz, 104/2-2=50)
 9, SI5351_REG_58_MULTISYNTH2, /*P3*/0, 1, /*P1*/0, 50, 0, /*P2|P3*/0, 0, 0,
 2, SI5351_REG_18_CLK2_CONTROL, SI5351_CLK_DRIVE_STRENGTH_2MA | SI5351_CLK_INPUT_MULTISYNTH_N | SI5351_CLK_INTEGER_MODE,
 2, SI5351_REG_3_OUTPUT_ENABLE_CONTROL, 0,
 0 // sentinel
};

void
si5351_init(void)
{
 const uint8_t *p = si5351_configs;
 while (*p) {
   uint8_t len = *p++;
   si5351_bulk_write(p, len);
   p += len;
 }
}

上記を含めコードをgistに載せておきます。

https://gist.github.com/edy555/f1ee7ef44fe4f5c6f7618ac4cbbe66fb

ところで、以前スペクトラムはかなり綺麗と書きましたが、発生させる周波数によってかなり違いがあります。20MHz以下であればかなり綺麗ですが、周波数を上げるに従ってスプリアスが増えてきます。いくつかデータを取ってみましたので、参考に上げておきます。使っているのはNanoVNAで、ブリッジを通った出力なので、-10dBm程度となっています。水晶は26MHzのVCTCXOです。グラフの縦軸はdBと書いてありますがdBmです。

まずは以前も試した13MHz。Spanは6MHz、RBW10kHzです。2MHz上下に小さいSpurが見えてます。-70dBcくらいで、この周波数なら綺麗です。近傍の裾は測定系の位相ノイズです。

image

周波数をちょっと上げて20MHz。Spanは10MHz、RBWは10kHz。Spurのレベルがちょっと増えます。-4MHzにも出てきます。-62dBcくらい。

image

さらに上げて30MHz。かなりSpurが増えてきます。-60dBcくらい。

image

50MHz。あまり変りません。

image

100MHz。かなり増えてきます。-52dBcくらい。

image

100MHzからはSpan 50MHzを示します。RBWは500kHz。広くSpurが分布しています。

image

150MHz。Spurが-40dBcくらいですから、結構強くなってきました。Spurの位置は分数分周器の剰余の位置に来ますので、設定周波数によって大きく変化します。

image

200MHz。

image

300MHz。逆にSpurが減りました。

image

ちなみに260MHzだともっと綺麗になります。水晶から丁度10倍の周波数で、整数比の動作となっているからです。

image

ちなみに近傍の様子です。それぞれSpan 5MHz、RBW 10kHzです。

20MHz

image

100MHz

image

200MHz。ここまでは、近傍はほとんど差がありません(測定系の位相雑音程度)。

image

300MHz。近傍の位相ノイズが増えてきます。さすがに仕様範囲外ですので。

image

312MHz。このあたりが限界でした。位相ノイズが相当多くなっています。無理をしている様子がわかります。一方Spurのほうは逆にレベルが下がっています。

image

ここまではキャリア周辺を示しましたが、方形波ですからハーモニクスが大量に出ています。100MHzに設定し、1GHzまで見た場合こんな感じになります。もちろん奇数次が主ですが、偶数次もある程度存在します。

image

以上、Si5351Aの設定方法と、信号の質について紹介しました。設定方法は他にも選択肢があるので、合わせて信号の質は変化すると思いますが、傾向は参考になると思います。

低い周波数での出力は比較的綺麗ですが、高い周波数では注意が必要でしょう。もちろん基板レイアウトによって差が出てくるはずです。特に多出力を活用する場合は注意が必要です。販売されているいわゆるブレイクアウトボードの類では、RF的には駄目そうなものもありますので注意が必要です。

驚いたのは300MHz超まで出力可能なことでした。さすがに信号の品質的にはイマイチなので注意が必要ですが、例えばVNAが目的であれば問題になりませんし、せっかくのこの能力を活用したいと思っています。

リファレンス

comments powered by Disqus