前回ATSAMD21G18の内蔵OSCの出力を空いているクロックジェネレータを経由して外部端子に出力してみました。そのとき気になったのは「Xiaoボード、外付け32Kの振動子積んでたよね、使ってないの?」という件。今回はお休みしていたらしいXTALに活を入れて起動し、前回同様の方法で周波数を確認してみます。使えるの?
※「AT SAMの部屋」 投稿順indexはこちら
Go言語ソースをマイコン上でも使えるようにできるTinyGoを使わせていただいてSeeduino Xiaoボード上で自主トレ中です。
ここまでの調査結果をまとめると、Seeduino Xiaoボード上でTinyGoを使って生成したオブジェクトを走らせた場合、デフォルトでは内蔵OSCが生成するクロックばかり使われているようでした。内蔵の32Kオシレータの生成するクロックを測ってみると精度はイマイチ?(イマ2くらい?)
Xiaoボードの実装面はメタルの蓋が被っているので直接見ることができないのですが、回路図を見る限り外付けの32.768kHzの発振子も接続されております。ハードウエアが存在するのであれば使わない手はないというビンボー根性にて今回は外付け32Kを起動してみました。
※32kHzクロックとそのRTCでの歩度調整機能については第15回ご参照ください。(2022/06/07 追記)
Xiaoボードの回路図
Xiaoボードの回路図は以下のサイト(日本語)の下の方にリンクがあり、ダウンロード可能です。
今回使用するXTAL(と思われるデバイス。直接見てません)部分の回路図を引用させていただきます。こんな感じ。
実験に使用中のXiaoボードの周辺
第8回で作成したブレッドボードの回路をそのまま実験に使っております。前回説明しましたとおりMicrochip社ATSAMD21G18のクロックジェネレータ出力は、設定によっては外部出力ができます。今回は発振させたXOSC32Kの出力をクロックジェネレータ5番に接続、そして PA11_A3_D3端子から外部に出力させます。外部には外付けのLEDが取り付けられてますが周波数を測る分には問題ない、と。
実験に使用したGo言語(TinyGo)ソース
実験に使用したソースが以下に。XOSC32を発振させて外部出力するだけでは「寂しい」ので、おとなりの赤色LEDには自主的にLチカしていただき、また、main()関数にも無駄に標準出力に値を垂れ流してもらっています。
※2022/06/03 FIX
package main import ( "fmt" "machine" "time" "runtime/volatile" "unsafe" ) func enableXOSC32() { XOSC32K := (*uint16)(unsafe.Pointer(uintptr(0x40000814))) // NO WRTLOCK, STARTUP 1sec(0x5), AAMPEN, EN32K, XTALEN=1(XTAL), ENABLE=1 volatile.StoreUint16(XOSC32K, 0x052E) time.Sleep(time.Millisecond * 1200) } func setGGEN5out(src uint32) { PMUX8 := (*uint8)(unsafe.Pointer(uintptr(0x41004435))) PCFG8 := (*uint8)(unsafe.Pointer(uintptr(0x4100444B))) PDIR32 := (*uint32)(unsafe.Pointer(uintptr(0x41004408))) GGENSTATUS8 := (*uint8)(unsafe.Pointer(uintptr(0x40000c01))) GENCTRL32 := (*uint32)(unsafe.Pointer(uintptr(0x40000c04))) GENDIV32 := (*uint32)(unsafe.Pointer(uintptr(0x40000c08))) //set PA11 Function H(7) tmp8 := volatile.LoadUint8(PMUX8) volatile.StoreUint8(PMUX8, (tmp8 & 0x0F) | 0x70) //set PMUXEN, clear other bits volatile.StoreUint8(PCFG8, 0x01) //set PA11 OUTPUT tmp32 := volatile.LoadUint32(PDIR32) volatile.StoreUint32(PDIR32, tmp32 | 0x00000800) //set GEN5 DIV=0 volatile.StoreUint32(GENDIV32, 0x00000005) //set GEN4 GENCTRL tmp32 = 0x00090005 | ((src & 0x1F) << 8) volatile.StoreUint32(GENCTRL32, tmp32) for { if (volatile.LoadUint8(GGENSTATUS8) & 0x80) == 0 { break } } } func blinkRedLED() { led := machine.D2 led.Configure(machine.PinConfig{Mode: machine.PinOutput}) for { led.Low() time.Sleep(time.Millisecond * 500) led.High() time.Sleep(time.Millisecond * 500) } } func main() { var counter int = 0 enableXOSC32() setGGEN5out(5) //SRC=0x05 XOSC32K go blinkRedLED() for { counter++ fmt.Println(counter) time.Sleep(5 * time.Second) } }
実験結果
XiaoボードのD3端子(PA11_A3_D3)を観察したものが以下に。測定につかっているDigilent Analog Discovery2の精度もありますが、32.775kHz。微妙な数字ですな。前回の内蔵OSC32Kよりは一桁くらい精度がよくなってますが、本当にこの数字であるとRTC(実時間時計)に使うと結構残念な結果になりそうです。まあね、この頃のIoTデバイスだとNTPで補正するからみたいな運用もありかもしれないけれども。
そんなこんなで外付け発振子、わざわざ動かすこともないってこと?ホントか?