GNSSモジュールを試用する21 -SAM-M10Qが壊れた…!?と思ったら直せた(おまけあり)-

●突然の死
さる4月上旬、ねむいさんは東海自然歩道復路攻略の第一歩を踏まんと
闘志に胸を燃やしておりました。

が、その数日前にublox製のSAM-M10Qを使用した自作のGNSSロガーの
ファームを
差し替えてついでに動作チェックをしていたらなんと一切の
衛星を捕捉しなくなっていたことが発覚!!

いつもなら長くとも1分で捕捉してるはずなのに一晩中放置してもダメ!
次の日副業先(本業は二次裏メイド)近くの川べりの空が開けた土手で
昼休み一杯使って衛星を捕捉しようとしたけど全然ダメ!
その日の昼から帰宅する夕方までこれまた空が開けた会社の屋上に
放置したけど一切衛星が捕捉せずダメ!
結局山行の前日まで粘ったが何やってもダメ!

…というわけで2023年6月で現役を引退したGms-G9さんに急遽前線復帰
してもらって東海自然歩道・復路の第一歩を進むことになりました。
まさか12年前と同じGNSSモジュールで高尾山に向かうことになるとは…



その後、復路第一回も無事済んで時間も余裕ができたので衛星を
捕捉しなくなったSAM-M10Qモジュールを調べてみました。



ねむいさんが実際に使用しているのはublox社製SAM-M10QにLDOや
その他周辺回路を搭載して電源とUART(TTL)を引き出して気軽に
使用できるようにしたMATEK社のモジュールです。


んでもって今回の調査にあたりMATEKSYS社のSAM-M10Qモジュールの
回路を解析して回路図起こしてみました。また、このモジュールで
使用されているV_BCKP用の電池らしきものは電池ではなくSII製の
スーパーキャパシタでした。たいていはリチウム二次電池使って
いるのですが…エフェメリスデータ保持する3~4時間程度くらい持てば
よかろうという設計なのでしょう。

一つ上の写真にもあるように私は基板上に乗った5V->3.3VのLDOを
無視して直接3.3V投入する使い方をして約2年ほど使用しておりました。
結構乱暴ですがSAM-M10QのVDD/VIO/V_BCKPの定格は3.6VMAXなので
まぁ直接の問題はないでしょう。


これはSAM-M10Qに3.3V印可して起動直後のNMEAのログのスクショです。
この中で、
$GNGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99,1*33
$GNGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99,2*30
$GNGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99,3*31
$GNGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99,4*36
$GNGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99,5*37
っていうのが見えると思うんですが本来は衛星を捕捉すると
ここの文字列ががどんどん変わっていくのですが開けた場所に
何時間置いててもずーっとこのまんまでした…。


V_BCKP用のスーパーキャパシタがおかしいのかなぁと思ってたの
ですがテスタで測る分には大本の+3.3V印可5分後くらいには充電も
フルに完了してるようで電圧も3.0Vは保持している感じでしたが…
ちなみにSAM-M10QのV_BCKP保持電圧は1.65V下限となっています。
それ以下になったらどうなるかはデータシートやリファレンス
マニュアルからは(ねむいさんのおつむでは)読み取れませんでした。

ubloxのフォーラムとかもくまなく調べてみたのですが突然衛星を
捕捉しなくなった系の質問はいくつか引っかかったのですが有力な
回答はなし…いくつか指摘されていたのはRF回路部に静電気がかかり
破壊されたのではという見解でした。
まぁ確かにコアは生きてるのはSAM-M10Qから吐き出されえるUARTの
出力から分かりますのでSAM-M10Q内のRF回路が静電気でやられた
のかな…と思っていました。ねむいさん素手でほぼ触ってなくて
しかも使用時は対電防止エアキャップに包んで使用してたのに〜…

話はそれますがフォーラム見てるとublox製のGNSSモジュールでも
中華製ぱちもんが猛威を振るっててM10のひとつ前の世代あたりで
AmazonやAliexpressで異様に安い値段で買えるのは99%ぱちもん
のようです…う〜〜む

で、結局数日にわたり衛星の捕捉を試みたのですが一切衛星を捕捉
しないのは変わらなかったのでAliexpressのMATEKSYS公式ショップから
同じ製品を再購入しました…。

で、動かなくなったほうは静電気で潰しちゃったからもう捨てるしか
ないのですがその前に分解してやろうと画策してまずは基板上の
スーパーキャパシタを取っ払ったのですが、この時に(そういえば
ネット上の記事でもubloxのGNSSモジュールを長期間使ってる人で
バックアップ用二次電池交換してる人多かったな…)と思い返し、
ダメ元でこのまま動かしてみようと電源投入して定位置のベランダに
適当に放置したら…2分もかからず


衛星を補足するようになった


????



ちなみにデータシート/マニュアルの指示ではV_BCKPを使用しない
場合はOpenにすべしと書いてありました。M10ではここOpenとなって
ますが過去のubloxのモジュールだとGNDに落とせって指示もあるので
見落とさないように要注意です。


そんなわけで指示通りV_BCKP関連の回路を全部取っ払ってみました。
V_BCKPの機能を一切使わないようにしました。
そして…


復ッ活ッ!!
ベランダからかつV_BCKP機能殺してるので常にColdStartなので
70秒ほどかかっていますが完全復活です!!!!!

う〜〜む…つまりSAM-M10Qは電気的に破損はしてなくてVbakup用の
スーパーキャパシタが2023年~2025年の春まで使ってきてへたって
きたせいでV_BCKP保持電圧の維持が適切にできなくなってて、
保障値1.65V以下の変な電圧の時にVDD/VIOが投入されたらRF部が
まったく機能しなくなる"地蔵モード"に転んじゃった…
ということなのでしょうか…

スーパーキャパシタ取り除く前にオシロで電源投入時の過渡応答を
せめて記録しとくべきだったか…反省・・・!!

ねむいさんもublox教団に入信してまだ2年弱のひよっこなので
ublox製品を長年ビシバシ使い倒している猛者の方々の意見を広く
拝聴したく思います…!!!




おいおい天下の阪大でもこんな輩が跋扈してるのか…

というわけで復活したっぽいから今度はフィールドで実際に稼働
試験してみました…場所は大阪大学豊中キャンパスです。
ちょっと野暮用があったので阪大に来たのですがその用事済ませ、
ついでにV_BCKP無しの常時コールドスタートのパフォーマンスを
見てみます。


テスト地点は教養学部棟のこの広場にしました。


使う機材はAndroidタブレットAlldocubeとSTM32Primer2を使った
GNSSロガー
です。今回はロガーをUSB-CDCモードでAndroidタブレットと
接続しUSB-Serial変換として使います。

Android側アプリは2023年のときと同じくGPSConnectorを使います。

衛星をFIXするまでの時間はガラホのストップウオッチで測りました。


まずはAndroidタブレット内蔵のGNSSモジュール。
捕捉時間は5回平均で70秒ほどでした。
ていうかなんでか私のAndroidパッドでは運用停止してもう電波が出て
ないはずの初号機(PRN193)が見えてるんですが…


んでもってお次はSAM-M10Qモジュールです…
捕捉時間は平均45秒とコールドスタートながらもかなりの健闘です。

私の使い方、登山/自然歩道攻略で使うならこのV_BCKPをOpen状態
で運用しても必要十分ですね・・・

そんなわけでSAM-M10Qが壊れたと思ったら意外な方法で復活(でいいのか?)
できましたが私の過去の記事をもとにMATEKSYSの同じモジュールを
買った人もタフな使い方してるとスーパーキャパシタがへたってくる
頃合いだとおもいます。
ある日突然衛星が捕捉しなくなった!と気づいた方はモジュールを
捨てる前にスーパーキャパシタを新品と交換するか、V_BCKPの周辺
回路を取り除いてOpenで運用されることをお勧めします!


上記の試験も全部終わって大阪大学から阪急で西院に帰る前に駅前の
インドカレー店で腹ごしらえです…!ぁー食った食った…🍛

●おまけ・十数年越しにSTM32F1のUSBライブラリの致命的バグの原因判明、そして解消
☝で使用しているSTM32Primer2を使ったGNSSロガーのファームウエア
ですが、マスストレージモードでPCに認識する段階で突然プログラムが
デッドロック、ウオッチドッグリセットが発動してしまう"ことがある"
という結構最悪な不具合が10数年存在しておりました…
こちらも今回の検証の折にソースコード見直しで発覚し、対策しました。

不具合の個所はSTM32F1向けの旧USBライブラリのusb_int.c内のCTR_HP()
という関数です。これはUSB_HP_CAN1_TX_IRQHandlerのコールバック
として設定されています。
ねむいさんのGNSSロガーではマスストレージではダブルバッファを
使用していますが、STM32F1ではダブルバッファを使用する際は優先度の
高いUSB割り込みを同時に有効して対応するようリファレンスマニュアル
に記述があります
。この時にUSB_HP_CAN1_TX_IRQHandlerを有効にして
CTR_HP()が呼び出されるようにします。

そのCTR_HP()内でねむいさんは見ちゃいけないものを見てしまった。
なんと割り込みルーチン内でwhileループ、そして存在しない関数
ポインタを選択し実行してしまう可能性があるコード…

このCTR_HP()にはEP0のコントロールパイプの割り込みも普通に
飛び込んできやがるのですが旧USBライブラリではそれが考慮されて
おらず、EP0の割り込みが来てしまった際に実態が存在しない関数
ポインタを実行してしまうためプログラムが暴走してしまうことと
なります。HardFaultになるのではなく暴走です。

やっとからくりが判明したので後はそれを修正するだけです。
CTR_HP()にEP0の割り込み要因が飛び込んできても無視してEP0は優先度の
低い割込みUSB_LP_CAN1_RX0_IRQHandlerで処理してもらうことに
すればOKです。どう修正したかはこちらを参照してください。

何はともあれ10年来の不具合にケリがついたのでだいぶ溜飲が下がり
ました…!

そんでもってダブルバッファが中途半端だったマスストレージモード
でIN/OUTとも両方ともダブルバッファ化することに成功しました!!
STM32のフォーラムいくら探しても見つかりませんでしたがその前身の
STR7のUSBライブラリにそのものずばりの実装が発見されました。

この作例を参考に実装してさらにシングルブロック転送しかでき
なかったのをマルチブロック転送化して実装した結果がこちら↓

相変わらず書き込みがだめだめですが過去のものと比べるとかなり
改善できてきたかと思います。読み込みについては0.8MByte/Secと
フルスピードでできる限界に近づいてきましたのでこれで良しと
します。


なお、SDカードのクロックは24MHz(DefaultSpeedモード)で動かして
てますがHighSpeedモードだともうちょっと速度上がるんじゃないかと
お思いの方がいるでしょうがSTM32F1のHSモードの上限はエラッタの
都合上36MHzまでしか上げることができず、ごらんのとおり屁のつっぱり
にしかなりません。しかも不安定になるので安定性を考えると24MHzの
ままのほうがよいですね。



SDカードじゃなくてeMMCだとちまちま書き込みがかなり改善されます。
F1でも安定してeMMCが動作する。さすが私。


…そんなわけでSTM32Primer2を使い続けて15年以上が経過しましたが
これからもFatFsのSTM32F1の実装例として、GNSSロガーとして末永く
使っていこうと思います!

Go to top of page