« 2009年6月21日 - 2009年6月27日 | トップページ | 2009年7月12日 - 2009年7月18日 »

2009年7月5日 - 2009年7月11日の2件の記事

2009年7月10日 (金)

ストロベリーリナックスのミニLCDのライブラリ公開

(7/10/09)Mlcd
 最近、売り出した低電圧で動くI2Cを使ったストロベリーリナックスの液晶ディスプレイのドライバーがやっと公開できるレベルに達した。このLCD、小さいが2行16文字が表示でき、低電圧(2.7Vまで)で動くのが嬉しい。昇圧用のDC-DCコンバーターなどが要らない。ただインタフェースがI2Cなので知らない人にはとっつきにくいだろう。

 今度公開するライブラリは、標準のTWI(I2CのことをAVRではこう呼ぶ。ライセンスの関係らしい)を持っているAVRチップ(Megaシリーズ)だけでなく、持っていないチップ(Tinyシリーズなど)でも、GPIO(普通のIOピン)を使って、簡単な関数呼び出しだけで文字、アイコンを、このミニLCDに自由に出すことが出来る。I2Cに関する知識は要らない。ライブラリだけならフラッシュサイズは1Kバイトそこそこで入る。

 ソフトウエアで実現するI2Cは当研究所では、ずっと前にTiny26でUSIインターフェースを使ったドライバー(マスター・スレーブとも)を完成させている。当初はこれを組み込んで、TWIとの二本立てと考えていたが、途中で気が変わった。USIインターフェースそのものがTinyシリーズでしか実装しておらず、しかもピンが固定されている。MegaシリーズでもI2Cを2チャンネル使いたい時もある。GPIOを使ったI2Cの方が汎用性が高い。

 それなら、このあいだのChaNさんのFatFSの中にあるAVR用のRTCドライバーである。この前FatFSを使った時、このソースを読み、I2Cインターフェースを実に軽妙にソフトで実現しているのに感動した覚えがある。

 このときはフラッシュサイズを縮めるためこのRTC.cをそのまま使わず、TWIに替えたので、実際にはこのコードは使ったことがない。ちょうど良い機会だ、これを使わせてもらおう。早速FatFSのライブラリのRTC.cから必要なコードを取り出し、#ifでソースを入れ込んでいく。

 気が抜けるくらい余りにも少ないコードでI2Cを実現している。1バイトを送信するだけなら、RTC.c全体の1/3くらいしかない。たいしたもんだ。これで本当に動くのか半信半疑でテストに入る。悪い予想があたってGPIOのI2Cはエラーを大量に吐き出してつながらなかった。

 オシロではそれらしい波形が見えたのに、ロジアナでは全く反応がない。実はこのコードにはもともとよく理解できないところがある。GPIOピンを上下にドライブするのに、DDRという入出力指定レジスターだけを叩いている。これがどうもよくわからない。

(オリジナル)
#define SCL_LOW()    DDRE |=    0x04         /* SCL = LOW */
#define SCL_HIGH()    DDRE &=    0xFB        /* SCL = High-Z */
 (DDREはポートEのDDRレジスター、PE2(0x04)がSCL)

 ChaNさんが書いたコードだ。ぬかりがあるわけはない。どこかに何かを設定するとこれで動くのだろう。しかし、それが何なのか見つけられない。色々いじったが事態は全く好転しない。どうもおかしい。オシロで見えて、ロジアナで見えないというのが何か気になる。臭い。しかしこうなるとハードの問題で、これ以上はちょっと手が出せない。

 悩んだ挙句、強引だがこのDDRレジスター以外に、PORTもドライブするコードを入れてテストしてみた。
(変更したもの)
#define SCL_LOW() {mLCD_DDDR|=(1<<mLCD_SCL); mLCD_DPORT&=~(1<<mLCD_SCL);}while(0)    /* SCL = LOW */
#define SCL_HIGH() mLCD_DDDR &=  ~(1<<mLCD_SCL)    /* SCL = High-Z */
(mLCD_DPORTはSCLのポート番号、mLCD_SCLはSCLピン)

 スイッチを入れる。おおお、ロジアナにそれらしい波形が戻った。ちゃんとスタートコンディションを作っている。立派、立派。しかし、依然としてLCDは動かない。 Gpio_iicでも、ここまで来れば光が見えてきた。

 printfメッセージを沢山出してコードを追う。どうもC言語のBOOL変数はわかりにくい。こちらはアセンブラー育ちなので、等しいとき、正常終了のときはリターンコード0という観念からぬけられない。C言語のTRUE=1 FALSE=0というのがどうにもなじめない。特にif文の中で式なしで使われると大混乱する。やっぱりいくつか勘違いが見つかり修正する。

 #ifを使って分離したTWIのコードとあわせてリターンコードを揃え、祈る気持ちで電源ON。やった。Welcome画面がLCDに出た。これでGPIOのI2CでもLCDが動いた。#defineを設定し直してTWIに戻してみる。動かない!今までの苦労は水の泡か。頭から血が引いていく。はっはっは、ハード接続を替えていなかった。ジャンパーコードを差し込みなおして問題なく稼動。慌ててはいけない。

 アイコンの表示と消去がちょっと難しかったけれど、このあとの開発は順調に進み、だいたいこれでミニLCDのライブラリは完成した。アイコンも関数ひとつで任意の絵柄を表示/消去できる。コントラストもコマンドで調整できる。そろそろ公開できるレベルのようだ。

 これで少しはストロベリーリナックスさんにも顔が立った。前回の記事で営業妨害で訴えられる心配もないだろう。このライブラリでLCDが沢山売れることを願っている。

以下に、AVRstudioのプロジェクトファイルの形でソースコードとヘッダーファイルを置きます。mLCD168はライブラリmLCD.cをテストするためのやっつけのモニターです。10以上を1文字で入力する時は、;、:、などを入れてください。詳しくはフォルダー内の、mLCD_readme.txtを見てください。

7/10に公開したソースコードにはgoposにバグがありました。以下のものは修正されたものです。コメントにあるような変更もしてあります。コードは80バイト近く減っています。前のmLCD.lzhをダウンロードした方はダウンロードしなおし、前のソースは破棄してください。

「mLCD168_712.lzh」をダウンロード

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

2009年7月 7日 (火)

LPCMプレーヤー2号機の開発

アクセス急増の反動でもないが別の工作へ(6/30/09)
 BeagleBoardの記事を載せてからアクセスが急激に増えた。これまでは多くても精々一日に300アクセス程度だったのだが、このところ400を越える日が増えている。ページ単位のアクセスもBeagle関係が多い。みんなの関心が高いようだ。

 前にも書いたようにBeagleBoardはこれまで色々楽しんできた電子工作とは異質の世界である。ARMと言っても最近始めた、Cortex-M3とかLPC2388とは数ランク上のプロセッサーで、ハードは勿論のこと、ソフトもすでに素人がソースレベルで気楽にいじれる規模ではない。日本語表示が出来て次のステップは日本語入力機能なのだが、あまり気が進まない。日本語が入力できたからといって何か次の目的があるわけではない。それにソフトパッケージをダウンロードしてきました。インストールしました。動きました、だけでは何となく面白くない。

 まあ、BeagleBoardに関してはすべてこれしかやっていないので偉そうなことは言えない。しかし何か、こう、どきどきわくわくするところが欲しい。自分の創意、工夫が役に立って、既定の機能と違う動きをしたり、別の働きをするところが見たい。人間とは贅沢なものである。Photo

 そんなこともあって、Beagleはちょっと横に置いて、このあいだのDS-Liteのバッテリーの充電基板を作ってみた。これは基板を作るだけが目的でなく、LPCMプレーヤー2号機を念頭に置いた、電池フォルダー制作の練習を兼ねている。もしプレーヤーを量産するとなったらより簡便な手順で電池フォルダーが作れないと効率が悪い。

 1号機で苦労したのが電池接点を支える天板の固定である。電池は接点にかなり強い力で接している必要がありその強度が問題になる。基板にピンヘッダーの接触ピンをハンダ付けし、それに基板をボンドで固定するという手の込んだ方法で天板の強度を確保しているが、ここはもっと簡単に作れるよう改善しておきたい。
Photo_2
 そこで思い当たったのが、CDケースである。スペースを節約するためCDケースは最近薄いケースを使うようになって、初期の頃の厚いケースがごろごろ余っている。このケースの高さが電池の高さとぴったり合うことを発見した。アクリルのケースを適当にルーターで切り取り、天板付のマザー基板にすることにした。ユニバーサル基板を小さく切ってボンドで接着して接点基板にし、配線用の基板を横に載せる。 Ltc4054

 充電用のIC、LTC4054はこれまでの変換基板では大きすぎるので、サンハヤトの変換シール基板と秋月の8X8のミニ基板(10 ヶ¥100)を活用して実装した。このシール基板はサンハヤトの製品にしては、お買い得で一枚(¥770)に24個のSOTチップ(一ヶあたり¥32、秋月のミニ基板をつけても¥42)をつけることが出来る。このシール基板は結構銅面が多く、データシートによる最小面積50平方mmを満足し、600 mA まで流せそうだ(外気35°C)。基板にジャンパーピンをつけて充電電流の実測が簡単に出来るようにし、充電電流を決める制御抵抗は用心のため半固定の可変抵抗にして調整できるようにする。

 うむ、なかなか具合の良い充電基板が出来た。充電も順調だ。しかしこのCDケースを応用した電池フォルダーは、プレーヤーの方のケースの高さが足らなくて、今度の2号機には使えないことがわかった。残念。充電機能も内蔵しようと当初考えていたが、これもDCアダプターが大きすぎて、とても入りそうにない。充電機能がないとなると、電池交換がすぐ出来るようにしなければならない。

ストロベリーリナックスから小さいLCDが送られてきたので部品あわせをしてみる。いやいや、これは、これまで以上に大変だ。しかし全く不可能と言うわけでもないので悩ましい。何とか納まりそうだが、やっぱり手配線では無理か。そろそろプリント配線に挑戦する時期に来ているのかもしれない。

FatFSのバージョンアップ(7/3/09)2
 LPCMプレーヤー2号機のためのソフトウエアの整備もやり始めた。電源スイッチを入れる場所がないので、スイッチ長押しのソフトパワースイッチを実装する必要がある。ちょうど良い機会なので、これまでの不満なところや、2GB以上のSDカードのサポートをしようと考えた。

 ソフトパワースイッチは、データシートを確かめて驚いた。最も節電できるPowerDownモードだと、Mega88クラス(Mega328など)で1μA、Mega128クラスでも5μAしか流れない。電池の自己放電と言えば、多いほうのニッケル水銀電池では数百μA、少ないリチウム電池でも数μAというからこの消費電流は優秀なものだ。食わず嫌いをしていたようだ。2号機はソフトパワースイッチで決まりだ。

 もうひとつの現在のソフトの不満と言えば、SDカード読み取りの途中でエラーが起きると、そこでスタックしてしまい、電源のOFF/ONをしない限り正常に戻らないという不具合である。まあスイッチを入り切りすれば元へ戻るからそう目くじら立てることもないのだが、設計上はカードを読み直して復帰するはずなのにそれがうまく動いていない。

 これはソースリストをもういちど注意深く読んで不具合があちこちで見つかった。まずマウントは、FatFSではソフト的にしか行っていないので、下位ルーチンのdisk_initializeという関数を呼ぶ必要があった。そのほかのルーチンも初期化をさぼっていて変数がそのままになり元へ戻れないことがわかる(要するにserially reusableでなかった)。これらの修正の結果、プレーヤーはSDカードを途中で差し替えても、電池の瞬断で演奏が止まっても、何かスイッチを押すと最初の状態に戻って正しく動くようになった。

 うむ、大分丈夫になった。これでソフトパワースイッチの実装の環境に不安はない。いよいよ最後のTinyFatFSから、SDHCをサポートするFatFSのバージョンアップにとりかかる。

 ChaNさんのサイトから最新のFatFS(0.07c)をダウンロードさせてもらい移植を開始する。このファイルシステムは着実に進化を続けており、このあいだのバージョンでは遂にWindowsのロングファイルネームをサポートするようになっている。海外のサイトでもFatFSの導入例を時々見る。日本の組み込みOS、TOPPERSにも採用されている。こういうソフトを無償で気前良く提供し、なおかつ改良を怠らない姿勢には頭が下がるばかりである。

 おや、TinyFatFSはどこへ行った? リリースノートを見る。ありゃあ、最新版の最初のバージョン(0.07a)ですでに標準のFatFSに吸収されてしまっている。えー、TinyFatFSは前から、FAT32をサポートしていたんだ。何だSDHCが使えるのか。知らなかった。身の不明を恥じる。それにしてもこのバージョン番号、未だに0.1以下にすることはないんじゃないでしょうか(こんなに進んでいるのに)。もう1以上を名乗って何の問題もないと思いますがね。

 フラッシュサイズはどうだ。うーん、少し大きくなっているようである。R/Oの最小サイズは、TinyFatFSの時の、2524バイトから、3824バイトに上がった。しかしこちらは今、32KBもあるMega328を使っているから全く問題はない。それにTinyFatFSはなくなったけれど、小さいチップ用のプチFatFSが用意されている。さすがやることにぬかりがない。

 I/Oディバイス依存のmmc.cは替えないで良いはずだが、まあ用心のため新しいmmc.cを入れてこちらの環境に合わせる。コンパイルする。いくつかの未定義エラーが出る。あれ、これもバージョンアップしたはずだがとソースを見ると標準のdiskio.hではなく、サンプルプログラムのSDカード用のdiskio.hが必要とわかる。 

 とりあえずコンパイルは通ったので動かしてみる。動かない。Welcome画面から先に進まない。やれやれ2行のLCDの表示だけではどうしようもない。デバッグ用のUARTを入れなおしてすこしづつ確かめていく。本当はテスト環境を作るべきなのだが、不精してプレーヤーにいきなりぶちこんだのが良くなかった。かえって手間がかかっている。

 ディスクの初期化はうまくいっているようだ。エラーは出ていない。しかしファイルの表示が出ない。あちこちにprintfを入れてデバッグする。ファイルサイズがおかしい。おやあ、ちゃんと動くSDカードがあるぞ。演奏も問題ない。これは困った。ハードも影響しているのか。

 あちこち調べまわった結果、やっと原因がわかった。不具合の原因は、ファイル名の小文字だった。LFN(ロングファイル名)をサポートしたので、ファイル名のupper case化がされていないのだ。WAVという拡張子を調べてそれ以外のファイルは再生の対象からはずしていた。正常に動いたSDカードはどういうわけか最初から大文字だった。

 wavという小文字の拡張子も再生リストに入れることにして解決。またしても大山鳴動ネズミ一匹的な騒動だった。フラッシュサイズはこれまでの13KBから1KBほど大きくなっているが、まあ問題ないレベルだ。速さはどうだろう。ロジアナを引っ張り出す。うーむ、速度も少し遅くなった。これまでより12%程度遅くなったか。ま、これも許容範囲だ。

ストロベリーリナックスの低電圧ミニLCDを動かす(7/5/09)

 最近売り出されたばかりの3Vで動く小さなLCDモジュールである。小さいけれど、生意気に2行16文字が表示できる。画面は最上行に携帯電話用らしいアイコンを表示する少し余計な機能があるが、今計画しているLPCMプレーヤー2号機にはぴったりの表示装置である。3Vの低電圧で動くのでDC-DCコンバータも不要だ。3ヶも買ってある。

 インターフェースは、パラレルでなくてI2C(AVRではTWI)である。I2Cは、がた老AVR研究所では発足以来すぐ、秋月のRTC(リアルタイマークロック)とのインターフェースや、Tiny26などI2CのないチップのUSIインターフェースでソフトI2C(マスター・スレーブ)を開発したりして経験を積んでおり実装には問題ない。ショップのページには、液晶コントローラのデータシートも、アプリケーションノートも、サンプルプログラムもダウンロードできるようになっていて、開発に不安はなさそうだ。

 FatFSのバージョンアップが一段落したので、2号機に向けての次のステップとして、早速動作確認をすることにした。さすがに現用のブレッドボードにあるLPCMプレーヤーを使うことは止め、別のブレッドボードに新しくCPUチップ(Mega168)を乗せて専用のテストベンチを作る。配線そのものはCPU周りを準備(ISPまわりとXtal)すればI2Cは2線インターフェースなのでプルアップ抵抗を入れて5分もかからない。

 しかし、ちゃんと動くまでには意外に時間がかかった。日曜日を丸々一日使ってしまった。負け惜しみを言うようだが、沢山あるように見えた資料が問題だった。まず、ショップの提供するデータシートが英語であることはともかく、パラレルとシリアルそれにI2Cの3種類のインタフェース共通のデータシートでとてもわかりづらい。I2Cの項の最初には「I2Cでは書き込みしかできない」と明記してあるのに、後半には、読み込みが出来ないと使えないBusyFlagの説明が出ていたりして混乱する。一般的なI2Cの説明と、このコントローラ特有のビットの説明が混ざっているので余計わかりにくい。

 日本語のアプリケーションノートも、どうも端折って書いてあってこれまた全貌がつかめない。I2Cについてある程度知識があれば類推が効くが、そうでないと理解するのに苦労するだろう。データシートからの引用のチャートは肝心のCOビットの説明文が省略されているので何のことか良くわからない。特にファンクションセットのあたりは省略が激しい。

 結局、データシートと、アプリケーションノート、それにソースコードの3つを同時に見て、それぞれ確認していかないと開発が進まない。各コマンドのあとには必ず30μs程度のwaitが必要なようで、I2Cとしてはシビアな環境ではない。しかもI2Cインターフェースの多いRTCとは違って読み込み処理はなく、一方的に書くだけだ。

 割り切って、スタートコンディション、マスター書き込み宣言、コマンド、データ、ストップコンディションというI2CシーケンスとLCDシーケンスの順番を単純に繰り返す手順を解説するだけで、LCDはとりあえず動くはずなのだが、そういう書き方ではなく色々な方法を紹介したりするものだから余計わかりにくくなっている。

 ソースコードがまた難物であった。余り悪口は言いたくないが、構造化言語であるCの文法を全く無視したアセンブラー的なコーディング(switch文にgotoと、returnが入ると訳がわからなくなる)で、読むのに大苦労である。こういう通信関係のエラーによる中断の多いプログラムは構造化しにくい処理の代表格だが、もうすこし整理の仕方があるだろう。それにこんなに綿密にエラー処理をしたりリトライしてもあまり意味がない。近接した液晶とCPUの間で一旦エラーが起きたら回復する可能性は殆どない。先の見通しがないときエラーで帰ってきても無意味である。

 これまでのI2Cを使ったプロジェクトからソースをとりつくろいUARTからLCDを操作するテストプログラムを作る。久しぶりのAVRの本格的な開発である。用心のため、xprintf(ChaNさんのFatFSについているもの)を沢山仕込み、デバッグに備える。

 動かしてみた。全く動かない。まあこういうのには慣れている。xprintfを初期化から入れて動きを確認していく。あれえ、最初からリセットしている。なんだなんだ。変数を表示するxprintfのところで暴走している。原因はわからないがとにかくxprintfがおかしい。デバッグのために入れたステートメントで暴走するなんて洒落にもならない。

 xprintfをやめ自前のUART出力関数などでデバッグを進める。おやあ、ちゃんと正常終了のフラグを出しているぞ。あっ、ifの中の論理が逆だ。これを正しく直す。おお、画面に何かが出た。なーんだ。I2Cは動いていたのだ。正常なのにエラー終了していた。

 そりゃそうだ。このへんのI2Cの関数はすべて動作確認済みだ。ただ、文字は出たが、表記が目茶目茶である。しかし、ここまでくれば大分近づいた。ソースコードを点検する。コマンドのビットが1ビットずれているのを発見する。Mlcd

 これを修正し、めでたく低電圧ミニLCDは動くようになった。しかし、クリアや、コントラストの変更ができない。これはアプリケーションノートが端折ったところで、ファンクションセットに2種類あり、コマンドを出す前にはそれに応じたファンクションセットをしてからでないと動かないことがわかった。これを修正してUARTから自由にクリアとコントラストが調整できるようになる。

 日曜一日で何とか動くようになった。xprintfが動かなかった原因は次の日、事務所に行く途中で気がついた。xprintfの内部ルーチンのxitoaの行き先を指定するのを忘れていた。これでは暴走するはずである。情けない。

 ストロベリーリナックスさんには相当悪態をついたけれど、今回のソースコードはライブラリ化して近く公開し、少しでもこのディバイスが沢山の人に使われるようにしたいと思っている。こういうお洒落なディバイスをアマチュアに提供してくれるショップは大事にしないといけないし、オープンソースではこれまで沢山の人のお世話になっているのでせめてもの恩返しだ。

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

« 2009年6月21日 - 2009年6月27日 | トップページ | 2009年7月12日 - 2009年7月18日 »