(日々の記録)デジタルオシロを買った。(日)リニアPCMプレーヤーのデバッグで電子工作に戻る前回の記事以来一ヶ月が経ってしまった。これほど更新が滞ったことはブログ開設以来始めてのことである。電子工作自体のモチベーションが下がってきたこともあるが、この時期、行事が立て続けに続いたことも大きな原因である。例年いつも2月から3月にかけては、所属する団体の全体集会の準備と実施、恒例のスキー合宿、確定申告と、毎年必ず決まっている行事で電子工作どころではないのだが、今年は特にそれに輪をかけて別の行事がいくつも重なって多忙を極めた(え、いや現役のときに較べれば、屁のような話ですが)。学生時代の友人の新年会が遅れに遅れて、雪見酒を楽しむ会になったことを含めて予定外の飲み会が3つ、さらに義理を欠いていた旧職場の同窓会に久しぶりに出たり、古い友人が突然電話してきて飲むことになったり、さらに長女の縁談で関係者が集まったりして、このあいだ数えたら1ヶ月たらずの間に、10いくつも行事が重なっていた。電子工作の方は、STM8Sという8ビットプロセッサーにフラッシュメモリをつけて、グラフィック液晶に文字フォントを描いたところで止まったままである。書く事がないとはいえ、備忘録を兼ねているこのブログを放置しておくわけにはいかない。それに、昔のリニアPCMプレーヤーのトラブルの問い合わせがあり、全体集会(浜松)から帰って、行事が一段落したので久しぶりにこのトラブルシューティングにはまった。原因究明は結構、大変だったが何とか収束することができたので、これを合わせてブログをアップすることにした。(プレーヤーの件は、記事の最後に)。ダンプリストコマンドは完成したが(2/15/2013)これまでのテーマ、STM8Sの話である。JCG12864A37)に文字を出す開発は、前回までに1バイトの半角文字を表示するところまできた。フラッシュメモリは2Mバイトの大容量のメモリである。日本語フォントまで出してみようということになっている。日本語フォントデータは、半角に比べれば圧倒的に量が多く、その取り扱いは簡単ではない。今のところ想定している12X12ドットのフォントでも240KBもありコード体系も複雑だ。そのため、デバッグの効率を高めるため、フラッシュメモリ内のデータを16進で表示するユーティリティを作ることにした。いう周到な環境整備が、結局は成功への早道になることが多い。ダンプリストが簡単に出るかでないかでデバッグの効率は全然違う、などと一人で能書きを垂れながら、せっせと、UARTに16進表示を出すコードを書いた。ChaNさんのFatFSのサンプルプログラムにも良い例がある。これは書式付出力関数を多用されているので余り参考にならない。ほどなく、ダンプリストのユーティリティが完成した。UARTのコマンドに入れて、半角のフォントのエリアをキーボードのキーで表示を止めたり、再開させたりして遊ぶ。左側に16進、右側にANKコードが出る本格的なダンプリストである。環境整備は出来たが、肝腎の日本語2バイトコードの表示関数の開発は、まだ手が出ない。このSTM8Sでは、やり残していることがまだいくつかある。その一つがスクロールである。AVRでは動かしたが、STM8Sには移植していない。画面が小さくスクロールの見栄えが良くないので気が進まないのだ。128X64ドットの画面だと、小さな文字(5X10ドット)でも、たかだか5行、20文字程度しか表示できない。これでは、スクロールすると、あっと言う間に文字が見えなくなってしまう。苦労の割には効果が薄い。STM8Sでは先送りすることにした。それでも、日本語フォント実装に向けて、少しづつ作業を進めている。フォントは2つまで入れ、複数フォントの動作を確認した。日本語フォントは、12X12の蕨(わらび)フォントをダウンロードした。フラッシュメモリ上のこれまでの1バイト系と整合性のある仕様が決められないのでフラッシュに書き込むところまでは行っていない。STM8SのUART立ち上がりハングは直ってしまった(2/18/2013)もうひとつのSTM8Sの問題は、UARTがハングすることである。STVD(STマイクロの統合開発環境)でコンパイルしテストする分には全く問題がないが、そこを経由せず、単に電源を入れて動かすと、PCコンソールとのUARTがハングアップする。実用的に使おうというときには大問題になる。始め、STVDに何かオプションがあって、単独で使うときのバイナリーは、統合環境のときと違うものを作るのではないかと一生懸命探したが何もない。他の方々の使用例を調べてみても、こういうことは全く書いておらず、問題なく単独で動いているようだ。そのうちいつのまにか動いたり、また動かなくなったり、わけのわからない状態になった。ダンプリスト開発が一段落したので、少し、本腰を入れて調べ始めた。ときどき動くと言うのが曲者である。ソフトではなくハードを疑う。GLCDの表示はうまく動いているし、UARTも何か送受信をしているが字化けだけが原因のようだ。UARTの初期化が疑われる。試しにボーレートを下げて設定してみたが変わらない。こんなことで変るわけはないとは思いながら、今度は、UARTの初期化ルーチンをプログラムのメインループの直前まで遅らせてみた。ところが、なんと、これで直ったのである。今までのトラブルがうそのように快調にUARTが動く。要するに、電源投入後、すぐにUARTを初期化すると、ハングすることがわかった。STVDでは最初デバッガーが動くので、十分な時間の余裕が生まれていたのだ。STM8SのUARTを動かす時は、スタートのあと100μsくらいの待ち時間をUARTの初期化の前に入れる。クロックがまだ安定していないのだろう。円を描くのが結構難しい(2/22/2013)行事が重なってきて、まとまった時間を電子工作に割けなくなってきた。懸案の次のテーマ、日本語フォント表示に踏み込む時間の余裕がない。言って全く時間がないわけでもない。こまぎれの時間ならいくらでもある。いうときは、TVの前で時間をつぶさず(下らない番組を見ていると自分がどんどん馬鹿になる気がする)、なるべくPCでSTM8Sの開発画面に向かうようにした。まとまったコードは書けないので、気の付いた細かな、とりとめもない開発を少しづつやっては楽しむ。グラフィックディスプレイ(GLCD)の描画速度が気になっていたので、調べてみることにした。どれくらいの早さで画像が出せるのだろう。さんから頂いたソースコードには、点と線の表示関数はあるが、それ以上の関数の用意はない。そこで、まず、直線を組み合わせて四角枠(レクタングル)を描画する関数を作って表示してみた。感心にも、RaisonanceのCコンパイラーは、GNUのRand()を実装していた。フォトフレームで使ったSTM32の乱数関数を参考に、ランダムなレクタングルを画面に出してみる。描画速度は余り早くない。SPIで送られたデータ転送速度より明らかに描画が遅い。描画の間に待ち時間をはさまないと、残像で画面が見えなくなり、レクタングルはスムーズに移動しなくなる。こんどは、円を描画してみた。円を表示するには、本来なら実数で平方根を計算する必要がある。128X64ドットくらいのGLCDで、浮動小数演算をして座標を求めても表示する場所は整数単位なので意味がない。いうときは、みなさんどうしているのだろう。整数型の平方根算出法をウェブで探してみた。あっという間に沢山の解答例が出てきた。だいたいは、ニュートン法である。これくらいの平方根はニュートンの近似式を使うまでもない。平方根の小数1位まで出せるように(四捨五入するため)、元の数を100倍して、それに近い冪を求めれば簡単に、小数一位までの平方根が得られる。ロジックは良かったが、なかなか数字が合わない。調べてみたら、このやり方では、26を超える平方根を出すだけでも16ビット(65534)を簡単にオーバーフローしてしまうことがわかった(26X26=676でこれを100倍すると67600)。あわてて32ビットにして事なきを得た。整数計算した円は、単純に描画すると、急激に値が変わる部分は、空白になってしまう。円が立ち上がる最初と最後の部分は、値が飛ぶのでその間は描画できない。した円を描くには、最初Y軸から描きはじめて、45°まで行ったら、今度は、X軸を増やしていって描画していく必要があるのだ(図参照)。何度か試行錯誤のあと、やっと、円らしい画像が描けた。このLCDの表示は遅い。動画らしく動かしてみたが、全体が白っぽくなるだけでまるで動画にならない。FSTNで動画は厳しいようだ。ここに、以上のダンプリスト、円などの描画が出来るSTM8SのソースリストをSTVDのプロジェクトの形で置きます。この前と同様、必要なライブラリは同梱されていませんので各自サイトから落としてリンクさせてください。試作プログラムなので当記事と違う描画をしているところがあります。「JCG12864_317.zip」をダウンロード日本語フォント表示関数の検討に入る(2/26/2013)グラフィック画像の表示にもあきたので、いよいよ、日本語2バイトコードのデコードロジックを検討し始めた。検討だけならメモ用紙と筆記具さえあれば、どこでも出来る。スキーに行く時も一式を持っていったが、結局今回は、その時間がなかった。電子工作に熱中していた時は、行き帰りのバスの中でロジックを考え、良いアイデアが生まれた時もあったのだが。言い訳になってしまうが、STM8Sの開発の進捗が遅いのは、実はモチベーションが下がっているからではない。このSTM8Sの使用用途が決まっていないというのが一番の原因である。仕様を決めるときに「何に使うか」が明確でないので、色々迷ってなかなか決められないからである。今度の日本語フォント表示開発も同じことだ。JJYの標準時計にするなら、大げさな表示ルーチンは必要ない。大容量フラッシュメモリも必要ない。必要な日本語のビットマップデータを用意するだけで出来てしまうはずだ。日本語ファイル名や、テキストデータの表示という目的なら、本格的な日本語フォント表示関数を開発する意義があるのだが、あいにく、そういう用途は考えていない。固いことを言っても始まらない。好きなように作れば良いというのが結論だが、つい昔の「問題解決」の癖が出て、「効率」を考えてしまう。それはともかく、日本語フォント表示関数の仕様である。シフトJISは、第1バイトで、このデータがシフトJISの1バイト目であることを識別できるので、フォント表示関数は、ANKの1バイトと共用にすることができる。こちらは、フォントグリフを縦から横に変換する処理(大抵のグラフィック液晶はこの処理が必要なようだ)が、かなりコードを喰うので、ANK(半角)も2バイト(日本語)コードも一緒の関数にしたいのだが、大抵のこのあたりのプログラムは、1バイトコードと2バイトコードのフォント出力関数は別のものを作っている。その理由がどうもわからない。入力を値参照にするかアドレス参照にするかも頭を悩ませる問題だ。1バイト関数でアドレス参照にしている例は殆どない。開発に手間がかかるだけに、このあたりの仕様は良く考えてから決めたい。そんなことで、中々検討が先に進まない。それと関数が出来上がって、GLCD上に日本語(漢字)データをどうやって画面上に見せていくかというのも何が良いか迷っている。スクロールを生かして、画面上を移動させていくのが一番見栄えがするような気もする。うーむ、悩むだけで決まらないなあ。LPCMプレーヤーの不具合を調べる(3/6/2013)そうこうする内に、3年前に作ったリニアPCMプレーヤーの不具合報告がコメントにあがった。いう問い合わせは大抵、忙しい時に限ってくるものである。ステレオの音の左右のチャネルがばらけるのだという。最初、メディアによって違うと言うのでI/Oエラーか、リッピングのエラーだと答えておいたが、その後、詳しい調査報告があり、pause(一時停止)でも起きると言う。ソフトの不具合の可能性が高い。いくらオープンソースとはいえ、発表したソフトに不具合があるのを放置しておくわけには行かない。久しぶりに3年前のリニアPCMプレーヤーのソースコードを開いて調べてみた。pauseは、DAC割り込みルーチンの割り込みをマスクすることによって、再生を止めている。ありゃあ、こりゃいかん。タイマーはpauseをかけても動きっぱなしで、LRのトグルはレジスターがコンペアマッチする度に動き続けている。V41、V42以前のバージョンのときはLRのトグルは割り込みルーチンの中の命令でやっていたので、割り込みを停止すればLRのトグルは止まるが、V41,V42ではハードでトグルをするようになっている。ジッターはなくなったのは良いが、pauseで再生を止めると、延々とトグルを続ける。このままでは、pauseのあとの次の再開が前の状態を保持して動く保証はない。50%の確率で左右が逆転する。生録(SL機関車の録音など)や、オペラなど、音の場所に敏感な音源を聞かない人にとって左右のチャネルの逆転は気づきにくい。それにしても、よくここまでわからなかったものだ。今は電子工作以外の事で忙しく、とてもこれに関わる余裕がない。調査してくださった、n_piezoさんにお断りのコメントを返すのが精一杯だった。折り返し、修正のお願いのコメントが返ってきた。半年も1年も放置する積もりはない。出来るだけ早く、pauseのバグだけでもとっておこう。スタート時点でのLR逆転はまだ原因は突き止められていない。ここも、LRのトグルはハードで行っているので(V41から)、もしかしたら、ソフトの可能性もありうる。時間がないので、そこまで調べるゆとりがない。検証する音源データを作る(3/12/2013)全体集会の浜松出張から帰ってきて、やっと仕事が一段落した。ブレッドボードに常備しているLPCMプレーヤーでデバッグを開始した。少なくともpauseの時のバグの修正方法はわかっている。コーディングに入る前にテストデータの作成にとりかかる。プログラムは考えたようには動かない。書いたようにしか動かない、というのが鉄則である。どんなに完全だと思っても、本当のテストデータで確認しないと安心できない。テストデータはデバッグの前に必ず作る。録音用に買ってあったRolandのデジタルレコーダーR-05を取り出した。最初、自分の声でレコーダーの前を歩きながら、「左です」「右です」などの声を入れたテストデータを作った。再生してみると内蔵マイクがちゃちなせいか、分離が悪くてどっちが左なのか右なのか全然使い物にならない。仕方がないのでPCで適当な音楽を鳴らし、PCのミクサーで左右チャネルを振り、ラインアウトを通してレコーダーに録音した。pauseの時の不具合修正は簡単である。このレジスターはプリスケールを決めるレジスターなので、再開のため、ソースの種類(ステレオ、モノラル、44.1/22.05khzなど)によって決まるプリスケール値を保存しておく必要がある。pauseで左右が逆転することは全くなくなった。起動時の左右逆転は、たまにどころか、かなりの頻度で起きていることがわかる。あわてて、再生直前に、トグルピンを初期化するコードを加える。これで、電源投入直後の再生は、全くぶれがなくなった。ところが、再生を中止したり、別の曲を再生して(ここが逆転しているかはわからないが)、テスト曲に戻ると、何回かの割合で左右が逆転する。トグルピンを初期化しているのにおかしい。迷走している(3/13/2013)そもそも、V41からは、DACにデータを送る割り込みルーチン、SDカードを読むsystick割り込み、それにLCDに経過時間を表示するバックグラウンドタスクと3段のマルチタスクになっている。構造が複雑な上、曲の再生開始のタイミングも、曲データがバッファーにある程度貯まったところというクリティカルな条件がある。デバッグは容易ではない。電源を入れた直後はうまく行くのに、そのあとがうまくいかないというのが気に入らない。片っ端から電源投入直後の初期化コードを、繰り返し処理の中に入れてテストするが、改善されない。トグルピンの初期化がどうも、うまくされていないという仮説が一番有力になってきた。ロジアナを取り出して確認しようと準備し始めた頃、たまたまMega168のデータシートを見ていて、意外な記述を見つける。「COM0A1~0ビットの1つまたは両方が1を書かれるとOC0A出力はそのI/Oピンの通常ポート機能を無効にし、そのI/Oピンに接続されます。)うはあ、トグル出力にしているピンは、タイマーにつなぐと、外からはいじれないのだ。bi1=1)、TCCR0Aを設定する。これでトグルピンは初期化されたはずだ。いや、やっぱり駄目だ。タイマーの方でトグルの情報を残していて、それが復活してしまうようだ。これ以上直すところがなくなった。