マイコン工作実験日記

Microcontroller を用いての工作、実験記録

NucleoのST-LinkをJ-Link化してみる

2016-04-29 17:35:33 | Weblog
これまでにもFreedomのOpenSDALPCXpresso, そして最近ではAtmelのEDBGというように、各社のARMマイコン評価ボードに対して、そのJTAGインタフェース部分をJ-Link化してしまうファームを無償で提供してきたSEGGERですが、ついに残された最後の大物(?)であったSTのST-Linkを書き換える日がやってきました。なんと、NucleoだけでなくDISCOVERYもJ-Link化してしまいます。

できれば現在使用中のNucleo-L476で使ってみたいところなんですが、これまでST-Linkは用無し扱いしていたこともあって、すでに首切り済みです。そこで、まだ首のつながっているNucleo-F103RBを引っ張り出してきて、J-Link化を確認してみることにしました。手順はこちらのページに書かれているように、必要なドライバとJ-Linkソフトを用意した状態で、STLinkReflesh,exeをダウンロードして実行します。



ライセンス説明にAで答えたら、1のUpgradeをするだけ。EXEなんで、この作業だけはWindowsでやらないといけません。無事に終了したので、今度はMac上で確認作業。


はい、JLinkEXEを実行すると、ちゃんとJ-Linkとして認識され、ターゲットのSTM32F103RBにもConnectすることができました。ST-LinkはJTAGドライバがWindows用にしかないために、わたしにとっては無用の長物でした。これからはJ-Linkとして有効に使うことができるんで、これは大変にありがたい!!


パワーダウンを使ってみる

2016-04-26 06:36:52 | SLIC
これまでAg1171のPD端子はオープンで使っていましたが、オンフック時の消費電流を削減するためにSTM32につなげてやりました。

PD端子をLレベルにすることでパワーダウンすることができますが、この端子はHレベルにしてはならないことになっているので、上図のようにダイオードを入れて使います。

オンフックを検出したならば、PD信号をLレベルにすることでAg1171はパワーダウン状態に入ります。しかし、パワーダウン状態ではオフフックの検出ができません。そこで時折パワーダウンを解除して、フッキング状態が変化していないか確認してやる必要があります。しかも、パワーダウンを解除してから信号の状態が安定するまでには50msを要します。オフフックされたことを速やかに検出するためには、頻繁にパワーダウン状態から抜け出さねばならなくなります。

今回はパワーダウン期間を350msにしてみました。その後50msのウエイトを置くのので、オンフック時には400ms間隔で状態確認を行うことになります。実際に試してみると受話器を耳に当てて、ちょっとしてからダイアルトーンが聞こえる感じですが、まぁいいことにしよう。



電流を測ってみると、当然のことながら数値が変化します。テスターでは少ない時で63mA程度。70mAほど減ったようです。

消費電流を確認する

2016-04-23 11:46:12 | Weblog
これまで基本的なSLICやSTM32L476の動作を理解、確認することを目的として作業を進めてきましたが、ある程度全体の格好が整ってきたので少しずつ細部の見直し作業を進めていきたいと思います。その中心作業として考えているのが消費電流の削減です。もともとオフフック時におけるSLICの消費電流が大きいことはわかっているので、マイコンがある程度電流を消費してもそれほど気にすることはないのですが、オンフック状態での待機電流は小さく抑えたいものです。現状ではマイコンも72MHzで動かしており、APBクロックも72MHz。こんなに高速でなくても充分に処理はできるはずなので、このあたりも順次調べていきたいと思います。

そんなわけで、まずは現状の把握から始めます。3.3Vのレギュレータの出力にテスタを入れて全体の消費電流を調べてみました。まずはオンフックの状態です。BluetoothでのHFP接続は確立されており、発信あるいは着信を待機している状態です。LCD表示もつけていますが、バックライトは未接続のため点灯させていません。



137mA. 思っていたよりも飯食ってるなぁ。Ag1171のデータシートによれば、3.3V動作時の平均的消費電流は70mAで、最大105mAとなっていますので、SLIC以外でも30mAから70mA程度流れていることになります。



オフフックすると電流値は跳ね上って400mA近くに。SLICデータシートでは平均360mAなので、 まぁ予想通りの数字ではあります。

消費電流を削減するための手段としては次の方法を考えています。
  1. SLICのPD端子によるパワーダウン制御Ag1171ではPD端子をLレベルにすることでオンフック時の消費電流を5mA程度に削減できます。
  2. ペリフェラルの動作クロック制御現状ではADC/DACが常時動いてしまっているので、オンフック時にはこれを止めることにする。また、動作時クロック速度も下げられるはず。
  3. アイドル時にコアを止めるFreeRTOSが提供するTickless idle modeを使ってみる。

なんと言ってもSLICの消費電流が大きいので、まずはPD端子によるパワーダウンから試してみることにします。

RTCを使ってみる

2016-04-22 12:31:31 | Weblog


オンフック状態での画面表示が寂しいので、RTCを使っての時刻表示を追加してみました。が、やはりこんな小さなフォントではやはり画面が寂しい。本当はもっと大きなフォントを使いたかったのですが、使っているglcdライブラリに含まれているサイズの大きな数字フォントを調べてみると、フォントには数字のグリフしか含まれておらず、コロンやスラッシュが含まれていませんでした。やっぱり、自分で用意しなきゃダメかなぁ。

もうひとつ残念なことは、わたしの使っているAndroidスマホでは、HFP接続をしても時刻の設定ができないこと。AT+CCLKコマンドがエラーになってしまいます。カミさんのiPhoneならちゃんと時刻設定できるのですが。。。

時刻表示のためにはRTCで毎秒割り込みを発生させて、その度にRTCの日付/時刻を読みだして表示させています。最初、読みだしの順序を間違えていて、表示がちっとも更新されないという問題にあって、戸惑っていました。読み出しのためには、

HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BCD);
HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BCD);

というように時刻読み出しに続いて日付を読み出さないといけないという制限があるんですね。

CircularモードDMA

2016-04-16 12:22:56 | Weblog
今まで、気にしていなかったけど、ふと気づいて確認してみたことがあるのでメモしておきます。

受話器を上げた時に聞こえるダイアルトーン(400Hz)は、DACを使って生成しています。現在は400Hzの波形データを16KHzサンプリングで160サンプル分作っておき、これをDMAでDACに送信することで、トーンを生成しています。DACのDMAトリガとしてはTIM7を設定し、TIM7で16KHz周期でトリガを生成することでDMA要求を生成してやります。

DACのDMA設定では上図に示すようにCircularモードを使用しています。STM32ではDMA転送サイズの半分が完了した時点と、全てが完了した時点で割り込みを発生させることができますので、この割り込みを使って新たな波形データを用意してやれば連続的にトーンや音声を再生することができます。通話音声を再生する際には、DMAトリガをTIM7からI2SのFSYNC信号に切り替えることでWT32から送られてくる音声データとの同期を取っています。

現在のプロジェクトでは上述のように160サンプルの半分である80サンプルを送信する度に割り込みがかかって新たなトーンデータを生成していますが、ダイアルトーンの生成中にデバッガを使ってCPUコアの実行を止めてもダイアルトーンが流れ続けます。なぜならば、CPUコアの実行を止めてもTIM7を止めない限りDMA要求が継続して発生し続けるため、Circularモードではバッファーの内容がDACに対し繰り返し連続して送られることになり、その結果トーン再生が続くからです。16KHz、160サンプルは10ms分のデータ量になります。10msは400Hzの波形データではちょうど4周期分に相当しますので、実は5ms間隔で発生する割り込みによるデータ更新があってもなくてもバッファ内の波形データには変化が生じず、400Hzのトーンを綺麗に連続して再生することができます。

このようにDMAのCircularモードを使用すると、周期の倍数となる長さのデータを用意しておき一度その送信を開始すれば、その後はCPUの介在無しで周期的なトーンを連続して再生することができます。トーン生成以外にも応用できるテクニックだと思うので、何かの機会に使ってみようかと思います。


ダイアリングから通話、切断まで

2016-04-10 12:45:54 | Weblog
先週の続きで、ダイアリングから発信、通話、そして切断までの一連の流れを処理できるように作業しています。ついでにLCDのアイコン表示もちょっと変更、追加。

まずは初期状態。HFP接続が無い状態では、通話できないことを示すために、受話器アイコンを使ってみることにしました。



HFP接続が確立するとこの表示を消して、アンテナと電池残量アイコんを表示。



受話器をオフフック/オンフックする度に、受話器アイコンを点灯/消灯することとしました。



ダイアル後、発信中と通話中はダイアルした番号を表示します。今のところ、発信中と通話中の表示が同一なので、この点は今後改善したいところ。



一連の処理の流れの様子は次のとおり。
  • ダイアル桁間タイマーにより入力されたダイアル信号の間隔を監視し、このタイマーが満了したことを検出したならばATDコマンドをWT32に送り、発信。
  • 呼び出し信号並びに通話音声用のSCOリンクが張られたことを示すRING ... SCOを検出したならば、SAIからのFSYNC信号に同期してADC/DACを動作させることで音声パスをつなげる。
  • オンフックで通話を切断するHANGUPコマンドをWT32に送信。
  • SCOリンクが切られたNO CARRIERイベントによりADC/DACの動作トリガをタイマーの設定し直す。


パルス数を数える

2016-04-04 23:20:53 | SLIC
すでにDTMF検出はVinTask内で実装していましたが、パルスダイアルのためのパルス検出機能は未実装でした。そこでSlicTaskにパルス検出機能を追加してみました。

パルスダイアリングのパルス信号は下図に示したようにAg1171のSHK信号を解析することで検出します。SHK信号の立ち上がりでパルス数をインクリメントしてゆき、一定時間(T1)オフフック状態が続いたならばひとつのパルス列が終了したとみなします。

SHK信号の立ち下がりでは、T2タイマを起動して一定時間Lの状態が続いた時点でパルス信号ではないと判断し、オンフックされたことを確定することにしました。



実験に使っている電話機は10pps対応のものです。受話器に備わっている設定スイッチをP側にすることでパルスダイアル信号を生成しますが、途中で ’*’キーを押すとトーン信号に切り替えることができます。実際に動作確認してみた結果は次のとおりです。



パルスでもDTMFでも、どちらでも正しい数字を検出できることが確認できました。次は、ダイアルした番号で発呼できるようにするかな。