« 2013年2月 | トップページ | 2013年4月 »

2013年3月の2件の記事

2013年3月30日 (土)

STM8Sでグラフィック液晶に日本語文字が表示できた

 LPCMプレーヤーでばデバッグの醍醐味を味わって大いに意気が上がったというのに、本来のSTM8Sによるモノクログラフィック液晶(JCG12864A37)への日本語フォント表示の開発の意欲は依然として高まらない。

 進まない理由は前にも書いたように、具体的な目標が決まっていないからである。目的があいまいなので、仕様の選択肢が多くなりすぎ、迷うばかりで先に進まない。何か決めても心配になってまた元へ戻るという堂々巡りになっている。システム開発で良くある失敗プロジェクトのパターンだ。

S_p3265774 こういうときは、少し強引でも、良い加減でもいいから、完成までの作業工程を可能な限り細分し、そのひとつづつを何も考えず、とにかくやってみるという少々乱暴だが効果的な打開策がある。で、今度もこれを応用してみることにした。

手順を分解して沢山の作業項目を作る(3/19/2013)
 ということで、STM8Sの日本語フォント表示計画は、次の5つの手順に分けて、とにかく先に進むこととした。

(1) フォント抽出と、フォント描画の機能の分離
 グラフィック液晶(GLCD)に文字フォントを描く手順は、大きくわけると、フラッシュから、所定の文字のフォントグリフ(フォントのビットマップスキャンデータ)を抽出してくるロジックと、GLCDメモリに、そのデータを移すロジックに分かれる。

 これまでに作った半角のANK文字表示関数と、日本語文字表示関数を分けるか、一緒にするかで悩んでいたが、GLCDの描画部分を共通にして、関数を2つに分けることにした。

(2) 漢字コードの入力
 UARTモニターからは任意の2バイト漢字コードが入力できないといけない。ハードコーディングした漢字コードのテストだけでは不完全である。この開発は、描画とは独立した機能なので、この部分だけでも進める。

(3) フォント構造体の統合とSRAMの構成見直し
 フォントデータを速度の遅いフラッシュに収容しているので、フォント属性だけは、SRAMにあるフォント構造体に収容している。日本語フォントは、FONTXフォーマットを使うとすると、さらに文字データをアドレスするデータブロックがSRAMに必要となり、この量は結構多い(バイナリエディターで調べたところでは蕨フォントで376バイト)。

 このため、ANKとは別の考え方をしないといけない。しかもSRAMは既に限界の2KB近くまで使い込んでいるので、このままではSRAMがオーバーするのは自明である。何とかしなければいけない。

(4) 2バイト日本語フォントデータ抽出関数の開発

 この部分は、ChaNさんのサイトの「FONTXの話」に、幸いソースコード付きで紹介されているので安心である。コードを読んでみると、自分が考えていた手法と殆ど同じで意を強くする。この手順だけで、あのばらばらのブロックに分かれたシフトJISコードがハンドリングできるのか、ちょっと信じられないのだが、彼のコードにぬかりがあるはずはない。

(5) フラッシュメモリの再構成
 フラッシュメモリへの書き込みが、なるべく単純作業で行えるようなメモリの構成とソースコードにしておきたい。そうでないと最初は良くても自分でもメンテナンス不能になる可能性がある。

 しかも今度のフラッシュの初期化の単位がセクター(64KB)ごとなので、今後のことを配慮したメモリ配置をしないといけない。とりあえず、0セクターをワーク用、1セクターをANKフォント、2セクター以降を日本語2バイトコードと割り振って、ソースにハードコーディングしておく。

達成感があるとやる気が出てくるものだ(3/20/2013)
 手順が出来たので、各個撃破のつもりで作業にとりかかった。まず、(1)の手順として、既存のフォント表示関数LcdChr_Ank関数から、フォントデータをLCDメモリに展開するだけの関数LcdPut_Font関数を切り出す。

 やってみると意外に簡単に分離することが出来た。早速、ここだけでテストする。いつもの逐次開発法である。よーし、分離してもこれまでのANK文字は問題なく表示された。これでこれから開発する2バイト漢字コードを表示する関数、LcdChr_Kanji()は、この切り出した関数を呼ぶことでコードの効率化が図れる。

 次に(2)のステップである。16進表示キャラクターから、実際の2バイトバイナリーをデコードするロジックは、AVRなどいくつかのところで実装済みである。このあたりを参考にUARTコマンドのコードを書く。これもそう手間をかけずに完成できた。既存のユーティリティで数値を確認する。

 沢山ある仕事もこうして細かい手順に分けて少しづつ完成させていくと、はずみがつくものだ。ちょっとでも達成感があると次のやる気が出てくる。不思議なものである。しかし、良いことばかりは続かない。(3)の手順で、つまづいた。SRAMのメモリーがなかなか減らないのである。

 フォント構造体の設計は、1バイトのANK系と2バイトの漢字コード系とはヘッダーの部分だけであとは全く別方式でやることにした。そこまでは良かったが、漢字コードのデータブロックに必要な300バイトあまりのSRAMの余剰はどうしても生まれない。

 STM8Sコンパイラーには、変数を、SRAMに置くか(予約語data)、フラッシュに置くか(予約語code)、指定できるようになっている。プログラムの中には、UARTのメッセージのように、固定された定数が多いので、これをcodeでフラッシュに移したつもりなのだが、これが全く効果がない。

 STVD(STマイクロ統合環境)には、出来上がったバイナリーの大きさを表示するsizeコマンドが入っていないので、.mapファイルをエディターで見ている。しかし、これが不思議なことにSRAMのサイズが考えたように減っていかない。変化が連続的でないのである。時々、がくっと減ったり増えたりする。謎である。

 暗礁に乗り上げた。余裕は精々30バイトくらいしかない。このままでは、所望の日本語のフォントデータにたどり着くまでに、何回もフラッシュを読まないといけなくなり速度が落ちてしまう。何とか切り抜ける方法はないがあれこれ考えるが、うまい解決策が思い当たらない。S_p3305790

気を紛らそうとハード工作の道草をする(3/21/2013)
 こういうときは、何か全く別のことで気を紛らわすのが一番だ。そのうち良いアイデアが湧いてくる。ということで前から気になっていたハード工作をすることにした。

 それは、オーディオセットのスピーカーの起動時のポップノイズを避ける遅延装置の作り直しである。LM380革命アンプをテストしていた時、この遅延回路を作って30年以上経っていることに気が付いた。

 この遅延装置の主要な部品は、30年以上前、職場の大型汎用コンピューター(IBM)のハードエンジニアから分けてもらった、大型のリレーとカンパッケージのトランジスターである。それに電源とケースをつけたして自作した。遅延はベースに入ったCR時定数で、電源が入った数秒後トランジスターがリレーをドライブしてスピーカー回路をONする。

S_p3305795  さすがにあの時代の電子計算機の部品である。作ってから全く何の問題なく動いているが、そろそろリレーの寿命が心配になってきた。ウェブなどを見ていると、最近のMOS-FETのオン抵抗は、下手なリレーより低い一桁のミリオーム台なのだそうだ。FETのスイッチングは大電流のところを派手に切るためのものと思っていたが、こういうところにも使われているとは知らなかった。

 ウェブで紹介されている回路を見て驚いた。FETのドライバーのフォトカプラーの2次側に電源線がない。スピーカーの端子を切るだけだからフォトカプラーの絶縁性は余り問題にならないが、2次側に電源が要らないと言うのは回路がとても簡単になる。

 こういうフォトカプラーはフォトボル型といって、1次側のLEDの光だけで、FETのドライブに必要な電圧を出せるのだそうだ。急に欲しくなった。いきつけの千石や、秋月では売っていない。DigiKeyにはさすがにあった(TLP590B、TLP190Bなど)が、これだけ買うわけにも行かない(最近はDigiKeyで欲しいものがない、というよりあらかた買ってしまった)。

 値段は、少々お高い。DigiKeyで¥200ばかりだ。諦めきれずにウェブでさらに探し回ると、例のサトー電気でTLP590Bを売っているのをつきとめた(¥252)。前々から一度は行ってみたいと思っていたサトー電気である。

Photo

川崎のサトー電気でフォトカプラーを手に入れる(3/22/2013)
 相当、古くからある電子部品の専門店である。Webの通販ページが手作り感満載の不調法なリスト一点張りのページだが、品揃えは中々侮りがたい。色々な逸話のあるお店である。ただ、お店が町田や川崎など遠方にあるので行く機会がなかった。

 ちょうと良い機会である。フォトカプラーだけというのもちょっと何だが、気晴らしに久しぶりに車を駆って川崎駅前まで出かけてみた。カーナビで目指すところに辿りつき、車をコインパークに入れて探したのだが、これが見つからない。

 場所は、駅近くの府中街道沿いの家内工場街といった感じのところで、看板が全くない。地図を見直して(印刷してきてよかった)、慎重に調べ直しやっと辿りついた。看板が出ていないのは、トラックに壊されて中に入れたままだったということをあとで聞いた。

 3間ほどの間口の店の中には所狭しと電子部品が積み上げられ、ちょっと壮観である。名物のおばさんは10年近くも前に亡くなったそうだ。親父さんはすこぶる元気らしい。川崎の店の息子さんらしい人は意外に愛想が良かった。

S_p3285787  問題のフォトボル型フォトカプラーTLP590Bを4ヶ、ついでに高速(10Mbit/s)フォトカプラーTL522を2ヶ買った。型番を調べてあったので、あっという間に品物が揃う。足が出ているので導電スポンジにつけて欲しいと言ったら、エアシートで包装してくれた。

 買って帰ると何となく安心して、遅延回路を作る意欲が薄れる。面白いものである。第一、まだオン抵抗の低いFETを入手していない。FETの型番はどういうことになっているのだろう、2SK,2SJ以外に多種多様な型番があって、何がなにやらさっぱりわからない。

 暫くは、FETを何にするかで楽しもう。出来合いのSSR(ソリッドステートリレー)を買ってしまうほうが、安くついて簡単なのだろうけど、こういうところにこだわれるのが自作の醍醐味だ。

SRAMのオーバーはやりたくなかったがUNION(共用体)で回避(3/23/2013)
 STM8Sの日本語フォント表示の開発に戻った。(3)が頓挫しているので、残りの(4)と(5)のステップを進めている。(4)はChaNさんのコードを参考に、LcdChr_Kanji()を少しづつ実装していく。SRAMが残り少ないので、なるべくワークを使わないように気を遣う。

 (5)のフラッシュデータの再構成である。これまでのデータはすべて破棄し、0セクターはテスト用に残し、1セクターをANK文字、2セクターを、日本語文字フォントに割り当てる。書き込みコマンドを書き直し、12ドットと10ドットのANKフォント、日本語フォントは12X12の蕨(わらび)フォントを入れ直す。

 あれえ、データ量が少ないなあ。ダンプリストで確認しようとした。あっ、こいつは32ビット対応になっていない。セクター1以降は、64K以上なのでアドレスはすべて32ビット対応にしておかねばならない。まずダンプリストのソースを修正する。

 ダンプリストが1セクター以降でも動き始めた。データがおかしい。ちゃんとデータが入っていないようだ。どうしたのだろう。ああ、なーんだ。ファイル転送をバイナリーモードにしていなかった。お馬鹿な話である。

 ファイルをもう一度、バイナリーモードで転送し直す。これでANKフォントは入ったようだ。テストし直す。これまでと全く変わりなくGLCDの表示が出来た。さらに日本語ファイルを入れる。時間はかかるが正常終了。サイズもピッタリだ。よーし、これで(5)はクリアした。

(4)の日本語フォント表示関数も、そろそろ完成に近づいた。残りは、懸案の(3)のSRAMのやりくりである。GLCDのVRAMに既に1KB以上取られている上、フラッシュ上にコンスタントを移せていないのでちょっとのことでは空きが出来そうにない。

 これまで構想はあったが、実装をためらっていた方策をやはり実行するしかないようだ。UARTバッファーとフラッシュのデータエリアをUNION(共同体)で流用する方法である。フォントデータをファイル転送するために、UARTはダブルバッファーで100バイト以上をとっている。転送してしまえば、UARTにこんな大きなバッファーはいらない。ここにフォントデータブロックのエリアを割り当てる。

 エリアを共用するので、プログラムの構成を良く考えておかないと、予測不能なバグが出る可能性がある。余りやりたくない方法である。しかし、もう背に腹は代えられない。変数名が長くならないように、共用体(union)の名前をなるべく短くして(uとか、tr)プログラムを書き直す。これでやっと全部のプログラムのSRAMを、2KB(2031バイト)内に納めることが出来た。

嬉しい。フラッシュメモリのエラーが直った(3/25/2013)
 ソフトはおおよそ出来上がったが、実はまだ解決しなければならない大きな問題が残っている。SPIフラッシュM25P40のreadエラーがとれないのである。

 単独では全くエラーが出ないのに、グラフィック液晶(SPIインターフェース)とSPIを共用するとデータエラーが頻発していた。当初は、フラッシュにパスコンを入れたり、接触不良を直したりしてエラーが出なくなっていたのだが、今度の漢字フォントのような大容量データを読み出すと再びエラーが起き始めた。

 漢字ブロックデータはアドレスなので1ビットでも間違いが起きれば、フォントのようにドットが欠けるくらいではすまない。エラーの出方がおかしい。単なるノイズでビットが時々乱れるのではなく、発生するときは、ある時点から連続的におかしくなる。止まっているはずのGLCDが時々動いてエラーを出しているような感じである。

 マスターのSPIから見れば、GLCDへは送信(MOSI)だけであり、フラッシュは殆ど受信(MISO)だけである。お互いに干渉しないはずなのにおかしい。GLCDそのものの結線をはずせば、全くエラーがなくなるので、GLCDによっておかしくなっていることは明白である。

 試しにGLCDの電源ラインを切ってみると、かえってエラーが増える。???である。しかも、液晶面には、電源を切っているのに、画像が出ている!GLCDのコントローラーは動いているのだ。クリアも有効である。謎は深まるばかりである。

 そこで、さらにCLK線をはずしてみた。おお、これでGLCDそのものをはずした時と同じようにエラーが出なくなった。GLCDの方も完全に止まっている。

 どうも、GLCDのクロックラインがフラッシュのSPIのクロックに悪さをしているようだ。両者の間に300Ωばかりのダンプ抵抗を入れてみる。ふむ、GLCDはこれでも動くが、フラッシュのエラーは改善されない。

 えーい、こんどはダイオードだ。小電力用のダイオードを入れる。だめだ。GLCDが動かなくなる。これは0.7V近く電圧降下するからか。では、SBD(ショットキーバリヤーダイオード)ではどうか。やった、やった。SBD(1S4)を入れてGLCDからの信号を遮断すると、GLCDは正常に動き、しかもフラッシュのエラーはきれいになくなった。何十回フォントデータを読み出してもエラーは起きない。

 いやあ、これで2バイトコードのデコード関数開発に心置きなく専念できる。これまでこのエラーが気がかりで中々先に進めなかったのだ。

S_p3265771 遂に日本語フォントの描画に成功(3/27/2013)
 長かったSTM8Sのプロジェクトが大詰めに近づいてきた。当面の目標であるグラフィック液晶への漢字表示である。2バイト日本語フォント表示関数が完成したのでテストに入る。

 漢字コードや、フラッシュのエントリーアドレスなどをUARTに表示するテストステートメントをびっしり入れたお陰で順調にバグがとれ、画面にそれらしい漢字データがあらわれた。あのデータブロックの計算はうまく行っているようだ。この部分は一発で通った。ちゃんと指定どおりの漢字が出る。

S_p3265777  嬉しくて何枚も記念撮影する。まだ、一字づつ16進コードを入れて漢字をひとつ表示するだけだが、表示の度にキーボードの前で何度もガッツポーズを作る。今回は特に感慨深い。とにかく時間がかかっているのだ。

 ブログの記事によれば、STM8Sを触り始めたのが、去年の11月、グラフィック液晶をつないだのが、2ヶ月前の1月、かれこれ5ヶ月近くこれにかかわっている。STM8SがAVRに比べて有利な点を持っているわけではない。情報も少ないし、余りメリットはないのだが、日本語が出るまでと意地になっていた。

 コードを追加して、エンドレスに漢字が表示されるようにする。おやあ、途中で文字が化けてしまう。どうしてだ。ファイル転送は、PCにおけるデータ数と同じ転送バイト数を示しているのでデータエラーは考えられない。ソフトか。うーむ、今までの高揚した気分が一気に落ち込む。

S_p3285780  文字化けし始める漢字コードを探し当てる。8C49「栗」というコードからおかしい。ふーむ、この文字のポインター(ファイルのエントリーからの)と、ひとつ前の8C48「粂」の違いは?あ、あ、あ、わかった。セクター消去を3セクターまでしかやっていない。「栗」からは4セクターに入るんだ。ダンプリストを作っておいて良かった。アドレスの違いが一目でわかった。

 あわてて、フラッシュメモリを7セクターまで消去し、フォントファイルを入れ直す。第二水準の一番最後の文字まで画面に出ることを確認した。これで完全だ。

 遂に、STM8Sの日本語フォント表示プロジェクトは大団円となったようである。次のテーマも良いが、長い間の付き合いでこのSTM8SとGLCDに妙に愛着が出てきた。ブレッドボードのバラックではなくて、ちゃんとした基板に実装してあげようか。

ここに作りかけのソースコードですが、以上の漢字が出力されるプログラムをSTVDプロジェクトの形で固めたものを置きます(フォントは入っています)。以前同様、ライブラリは入っていません。また、容量の関係で、ビルドは最初からやってください。UARTを接続し(38400bps N81)、プロンプトがでたら、kWXYZ でコードWXYZの漢字、kWXYZ- で、連続して漢字が表示されます。中断はスペースキー、終了はリターンキーです。

「JCG12864_330.zip」をダウンロード

| | コメント (5) | トラックバック (0)

2013年3月17日 (日)

リニアPCMプレーヤーのデバッグで電子工作に戻る

 前回の記事以来一ヶ月が経ってしまった。これほど更新が滞ったことはブログ開設以来始めてのことである。電子工作自体のモチベーションが下がってきたこともあるが、この時期、行事が立て続けに続いたことも大きな原因である。

 例年いつも2月から3月にかけては、所属する団体の全体集会の準備と実施、恒例のスキー合宿、確定申告と、毎年必ず決まっている行事で電子工作どころではないのだが、今年は特にそれに輪をかけて別の行事がいくつも重なって多忙を極めた(え、いや現役のときに較べれば、屁のような話ですが)。

 学生時代の友人の新年会が遅れに遅れて、雪見酒を楽しむ会になったことを含めて予定外の飲み会が3つ、さらに義理を欠いていた旧職場の同窓会に久しぶりに出たり、古い友人が突然電話してきて飲むことになったり、さらに長女の縁談で関係者が集まったりして、このあいだ数えたら1ヶ月たらずの間に、10いくつも行事が重なっていた。

 で、電子工作の方は、STM8Sという8ビットプロセッサーにフラッシュメモリをつけて、グラフィック液晶に文字フォントを描いたところで止まったままである。書く事がないとはいえ、備忘録を兼ねているこのブログを放置しておくわけにはいかない。

P3175746

 それに、昔のリニアPCMプレーヤーのトラブルの問い合わせがあり、全体集会(浜松)から帰って、行事が一段落したので久しぶりにこのトラブルシューティングにはまった。原因究明は結構、大変だったが何とか収束することができたので、これを合わせてブログをアップすることにした。(プレーヤーの件は、記事の最後に)。

ダンプリストコマンドは完成したが(2/15/2013)

 これまでのテーマ、STM8Sの話である。STM8S基板(STM8S-Discovery)にフラッシュメモリをつけてモノクログラフィック液晶(Aitendo JCG12864A37)に文字を出す開発は、前回までに1バイトの半角文字を表示するところまできた。フラッシュメモリは2Mバイトの大容量のメモリである。折角だから日本語フォントまで出してみようということになっている。

 日本語フォントデータは、半角に比べれば圧倒的に量が多く、その取り扱いは簡単ではない。今のところ想定している12X12ドットのフォントでも240KBもありコード体系も複雑だ。そのため、デバッグの効率を高めるため、フラッシュメモリ内のデータを16進で表示するユーティリティを作ることにした。

 こういう周到な環境整備が、結局は成功への早道になることが多い。ダンプリストが簡単に出るかでないかでデバッグの効率は全然違う、などと一人で能書きを垂れながら、せっせと、UARTに16進表示を出すコードを書いた。ChaNさんのFatFSのサンプルプログラムにも良い例がある。しかし、これは書式付出力関数を多用されているので余り参考にならない。

Stm8s_hex ほどなく、ダンプリストのユーティリティが完成した。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で送られたデータ転送速度より明らかに描画が遅い。描画の間に待ち時間をはさまないと、残像で画面が見えなくなり、レクタングルはスムーズに移動しなくなる。

S_p2245695  こんどは、円を描画してみた。円を表示するには、本来なら実数で平方根を計算する必要がある。しかし、128X64ドットくらいのGLCDで、浮動小数演算をして座標を求めても表示する場所は整数単位なので意味がない。

 こういうときは、みなさんどうしているのだろう。整数型の平方根算出法をウェブで探してみた。ウェブの力はすごい。あっという間に沢山の解答例が出てきた。だいたいは、ニュートン法である。

 しかし、これでも大げさだ。これくらいの平方根はニュートンの近似式を使うまでもない。平方根の小数1位まで出せるように(四捨五入するため)、元の数を100倍して、それに近い冪を求めれば簡単に、小数一位までの平方根が得られる。

 ロジックは良かったが、なかなか数字が合わない。調べてみたら、このやり方では、26を超える平方根を出すだけでも16ビット(65534)を簡単にオーバーフローしてしまうことがわかった(26X26=676でこれを100倍すると67600)。あわてて32ビットにして事なきを得た。

 画面に円が出た。しかし整数計算した円は、単純に描画すると、急激に値が変わる部分は、空白になってしまう。つまり、円が立ち上がる最初と最後の部分は、値が飛ぶのでその間は描画できない。

Photo  そうか、ちゃんとした円を描くには、最初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のバグだけでもとっておこう。

S_p3165741  スタート時点でのLR逆転はまだ原因は突き止められていない。ここも、LRのトグルはハードで行っているので(V41から)、もしかしたら、ソフトの可能性もありうる。しかし、時間がないので、そこまで調べるゆとりがない。

検証する音源データを作る(3/12/2013)
 全体集会の浜松出張から帰ってきて、やっと仕事が一段落した。早速、ブレッドボードに常備しているLPCMプレーヤーでデバッグを開始した。少なくともpauseの時のバグの修正方法はわかっている。コーディングに入る前にテストデータの作成にとりかかる。

 プログラムは考えたようには動かない。書いたようにしか動かない、というのが鉄則である。どんなに完全だと思っても、本当のテストデータで確認しないと安心できない。テストデータはデバッグの前に必ず作る。このあたりが長年ソフト開発をしてきた経験から生まれたノウハウである。

 数年前、音楽演奏の録音用に買ってあったRolandのデジタルレコーダーR-05を取り出した。最初、自分の声でレコーダーの前を歩きながら、「左です」「右です」などの声を入れたテストデータを作った。

 しかし、再生してみると内蔵マイクがちゃちなせいか、分離が悪くてどっちが左なのか右なのか全然使い物にならない。仕方がないのでPCで適当な音楽を鳴らし、PCのミクサーで左右チャネルを振り、ラインアウトを通してレコーダーに録音した。

S_p3165739  pauseの時の不具合修正は簡単である。割り込みのマスクではなく、単にタイマー(Timer0)をストップさせる(TCCR0B = 0)。ただし、このレジスターはプリスケールを決めるレジスターなので、再開のため、ソースの種類(ステレオ、モノラル、44.1/22.05khzなど)によって決まるプリスケール値を保存しておく必要がある。

 pauseで左右が逆転することは全くなくなった。この部分は解決した。しかし、起動時の左右逆転は、たまにどころか、かなりの頻度で起きていることがわかる。あわてて、再生直前に、トグルピンを初期化するコードを加える。

 これで、電源投入直後の再生は、全くぶれがなくなった。ところが、再生を中止したり、別の曲を再生して(ここが逆転しているかはわからないが)、テスト曲に戻ると、何回かの割合で左右が逆転する。トグルピンを初期化しているのにおかしい。

迷走している(3/13/2013)
 そもそも、V41からは、DACにデータを送る割り込みルーチン、SDカードを読むsystick割り込み、それにLCDに経過時間を表示するバックグラウンドタスクと3段のマルチタスクになっている。構造が複雑な上、曲の再生開始のタイミングも、曲データがバッファーにある程度貯まったところというクリティカルな条件がある。デバッグは容易ではない。

 電源を入れた直後はうまく行くのに、そのあとがうまくいかないというのが気に入らない。片っ端から電源投入直後の初期化コードを、繰り返し処理の中に入れてテストするが、改善されない。これはBU9480Fが悪いのかと疑い始めた時、AVRのリセットでも、うまく行くことがわかって、その疑いは晴れた。

 結局、再生開始直前のトグルピンの初期化がどうも、うまくされていないという仮説が一番有力になってきた。ロジアナを取り出して確認しようと準備し始めた頃、たまたまMega168のデータシートを見ていて、意外な記述を見つける。

「COM0A1~0ビットの1つまたは両方が1を書かれるとOC0A出力はそのI/Oピンの通常ポート機能を無効にし、そのI/Oピンに接続されます。」(p64 14.9.1. タイマ/カウンタ0制御レジスタA )

 うはあ、トグル出力にしているピンは、タイマーにつなぐと、外からはいじれないのだ。それならと、タイマーの定義、TCCR0A=0で、一旦ピンをタイマーからはずし、通常のPORTD=(1<<PD6)などで、ピンの値を固定した後、再度、タイマーのトグルピンとして(bit0=0, bi1=1)、TCCR0Aを設定する。これでトグルピンは初期化されたはずだ。さあ、どうだ。

 いや、やっぱり駄目だ。まだ左右がふらつく。どうもタイマーの方でトグルの情報を残していて、それが復活してしまうようだ。これ以上直すところがなくなった。暗礁に乗り上げる。2日間悩んでいた。前の記事以来もう一ヶ月が経とうとしている。そろそろ記事を上げたいが、この状態のまま経過報告するのもしゃくだ。何とかすっきりする結果にしてしまいたい。

考えれば智恵が出るものだ。やっと正しいチャンネルで再生成功(3/14/2013)
 デバッグに疲れると、他の事をやって気を紛らわす。メモにこれまでの経過を書きとめて、あれこれ仮説をたてる。しかし解決策は生まれてこない。そろそろ、あきらめてブログにこれまでの経過を報告し、完全に直せなかったことを謝ろうと文案を考え始めたころ、ふっと方法を思いついた。

 タイマーのトグルにしたピンを勝手にいじれないのなら、トグルをデコードとは分けて何回かまわし(要するに空振り)、所定の位置に揃えてから再生を始めれば良いのではないか。トグルするピンの状態は、PINを読めばわかるはずだ。

 何か、光が差してきた。コードはそれほど難しくない。DAC割り込み部に空振りするロジックを加え、再生開始の方ではトグルピンを見て左チャネル(最初)になったのを確かめて、空振りをやめて再生に入る。うむ、これはうまくいきそうだぞ。期待に胸が膨らむ。

 あせる手でコンパイルする。何十回とやったテストを始める。おおー、良いようだ。何度やってもチャネルはぶれない。今までなら4~5回で必ず逆になる状態が20回以上やっても同じだ。もう大丈夫だろう。

いやあ、久しぶりの爽快感に体中が満たされていく。気分の良いことこの上ない。難しいパズルを解いたときの達成感である。苦労が大きければ大きいほど、この解決した時の喜びは何ものにも替えがたい。

 単なるデバッグでバージョンを上げるのは少々気が引けるが、混乱をさけるためV43としてプログラムソースを公開することにする。V41以降をお使いの方は、是非、このV43を使っていただきたい(V41以前はトグルを自前でやっているので問題ないと思われる)。また、この微妙な不具合を発見、報告していただいたn_piezoさんに改めて御礼を申し上げる。

ここに例によって、AVRStudioのプロジェクトフォルダーを固めたソースコード一式を置きます。元の記事にも
リンクを貼る予定です。上段が2号機、3号機の小さな液晶をつかったタイプ、下段が1号機のソースコードですなお、双方とも、ソースファイル名は前と変わっていないので注意してください。

「mLPCM328V43.zip」をダウンロード

「SDPCM328V43.zip」をダウンロード


| | コメント (5) | トラックバック (0)

« 2013年2月 | トップページ | 2013年4月 »