« AC電流センサーを入手 | トップページ | LCDを待ち時間なしで動かす »

2008年8月31日 (日)

MMC(SDカード)をMega168で

Mega168を2つも失う悲劇(5/2/08)
 LANの電源コントローラが正式運用を始めて実験の中心は、SDカードアクセスの方に移った。chaN氏のFATファイルシステムの話は前から読んでやりたいと思って、Mega128を入手していたのだが、まだまだ先のプロジェクトになると思っていた。ところがこのあいだMega168でSDカードのTinyFSを動かしたという記事を読んで急にやる気になった。組み込みウェブサーバや、計画している電力ロガーの記録媒体に早く使いたいという事情もある。

 そんなこともあって、ソフトはスクラッチをあきらめ、chaN氏のソースを参考にMega168の環境に移し始めた。彼のコードはとても洗練されていて参考になる。しかし、これがなかなかコンパイルが通らないのだ。このプロジェクトのきっかけになったMega168を使った 記事は、ソースが公開されているが、肝腎のコードサイズを小さくする方法が全く書かれていない。このソースを使えば良いようなものだが、それでは前と同じで進歩がない。そこで勉強を兼ねてオリジナルをもとに、コードを解読しながら機能を減らしたり、バッファーサイズを縮めて何とか16Kぎりぎりに収めた。

 RTCとのインタフェースのI2Cはオリジナルでは何故か標準のハードを使わず、スタートコンディションから何から全部ソフトで作っている(これがシンプルで素晴らしい)。これを標準I2Cにして、秋月のエプソンのRTC(リアルタイマー)で動かすようにしたら、コードが200バイト近く減った。

 ここまでは順調だったが、悲劇が襲ったのはテストに入ってからである。UARTが動くところまで行ったが、それ以降はなかなか進まない。カードが入っていないという状態で完全な門前払いである。Mega168の記事ではこのあたりは全部省略され電源は常時ONで動かしているようだが、折角コントロールできる機構なのでつけてやりたい。しかし、ここのしかけが良く分からない。電源が入る前にポートでチェックしている。そんなことできるのか。

 何度かファームに書き込んで動かしているうち、書き込みエラーが起きた。ファーム書き込みのSPIとカードアクセスはピンが共通である。慌ててピンをはずして試みるが同じ。そのうちMCUを全く認識しなくなった。このチップは全くの新品でこんなに早く書き込めなくなることは考えられない。ライターの不具合かと他のボードのMCUを試すが問題ない。

 過電圧をかけたこともないし、熱も全く持っていない。Device Not Foundという冷たいメッセージが出るばかりである。チップの予備はもうない。初期故障なのかと諦め、あわててネットを開き以前Tiny861を買ったショップに注文する。次の日、車で入谷まででかけチップを手に入れた。約束の時間より早かったので、秋葉原の秋月に寄って、H8/3069Fというマイコンボードを買ってし
まった。どうも、何かが動かなくなると不安になって衝動買いしてしまうようだ。

 こいつはフラッシュが512Kもあり、NICチップもRTL8019という本格的なコントローラがついている。これが完成品で、たったの\3450である。実は以前買ったLAN電源コントローラの参考書にこれが詳しく出ていて、このあたりになると10年前に熱中したLinuxが動き本格的な組み込みシステムになる。欲しいセットだったのだ。ついでに千石で安いリードタイプのFET(2SJ325 \100)があったので買う。トランジスタでカードの電源を制御しているが、何となく不安だったからである。

 この不安は的中した。新しいチップをブレッドボードに挿し、実験を続けていたら、また同じ現象が起きたのである! 初期故障でもなんでもない。これは何かが起きている。Gataro研究所始まって以来の大事件である。立て続けに2つも心臓部のチップを失ったのだ。

まず、疑うべきは何故、オリジナルの記事の回路で、トランジスタをつかわずFETを使っていたかである。トランジスタはコレクタにカード電源の負荷がかかりベースがMCUのポートにつながっている。トランジスタがOFF状態でもプルアップ抵抗などを通じてカードを通してMCUに何らかの電流は流れる。しかしMCUの入力ポートは高インピーダンスでMCUを破壊することなど有り得ないはずである。

次に考えられる原因は、カードの電源電圧とMCUの電源電圧の違いである。しかし、これも論理判定で混乱する程度で、壊れるところまで行くとは考えられない。ネット上で色々キーワードを換えて調べてみたが、それらしい情報は見つからない。

 しかし、今の状態では、取り替えても3回目の悲劇が起きる可能性が高い。暫く途方に暮れていたが、結局、オリジナルの回路に忠実に戻すことにした。これなら問題ないはずである。幸いFETが手に入ったので、電源コントロールも組み込める。電源電圧も3.3Vに統一する。0.5Aのレギュレータだが何とかなるだろう。

明け方近くまでブレッドボードの配線を全面的に取り替えて次の朝(といっても昼近くだが)、起き掛けに突然ひらめいた。そうだ電源が入る前にカードが入ったか、ライトプロテクトがかかったかがわかるのは、スイッチが入っているからなのだ。chaN氏の回路図には出ていない。慌ててサンハヤトのソケット基板をテスタで調べる。この基板には記事には出ていない何本かの端子が出ており、シールドかなにかと思っていた端子と、カードインサートなどの端子が導通していた。これだ。

 ここを配線して、プロジェクトは少し前進した。SPIのコマンド送出まで動いた。もう10数回書き込みをやっているが、まだチップはこわれていない。オリジナルと全く同じ配線なのだから、これで壊れたら電波か宇宙線ということになる。それにしても、電源電圧の差で本当にチップはこわれるのだろうか。

何とかセクターまで読めた
(5/3/08)
 SDカードアクセスのプロジェクトは、やっとのことでSDカードの読み出しに成功した。動いてから考えてみれば、何でこんな間違いに気がつかなかったのだろうというケアレスミスの連続である。プログラムのデバッグというのはこういうものだ。動作環境が違うのだから、そこだけ目をつけておれば良いのだが、どうしてもロジックに目を奪われてどうでも良いところばかり疑ってみたりする。

 メインの初期化のところのポートの設定は、目を皿のようにチェックするが、カードの電源を入れるところでもう一回ポートの初期化を行っているのを見落とし、カードのチップセレクトのポートが入力になっているのに気がつかなかった。ロジアナでは、ちゃんとチップセレクトのCSがLow(1)になっていないのに気がついていたが、カードの初期化にはCSをHigh(0)にしたまま70クロック動かしてカードを始動させるという記述に惑わされていた。A5101280

 テストを始めて4日目にして、何とかセクタ単位のデータは吐き出してくれるようになった。FATレベルはまだ動かない。フラッシュサイズが一杯なので必要な関数を小出しに入れている。まだ足らないらしくシステムがリセットしてしまう。それとRTCがまだ動かない。まあ、これはテストステートメントを入れていけば何とかなるだろう。

 やれやれ、人のソースを見るのは疲れる。しかし、chaN氏のソースは非常に洗練されていてとても参考になる。「良い仕事してますねえ」と感心する。しかし、コードサイズは絞っても16K近くになる。Mega128クラスでないと、ちょっと他の応用はきついかもしれない。

 Mega168は順調に動いている。これも寝ながら思いついたのだが、Mega168急死の原因は、やはりトランジスタの電源制御の疑いが濃い。NPNのトランジスタ(2SC1213)なので、SDカード周りのグランドがコレクタにつながって浮いた状態がOFFである。これだと、カードの電源は接続されたままのSPIインタフェースを通して全て流れていく。これはまずい。

 以前、LCDのバックライトをトランジスタで切ったとき、切ったほうが動いているときより電流が多く流れる経験をしている。SDカードは数十mA近く流れると言うことだから、これがMega168のSPIピンに流れれば、壊れる可能性がある。

H8に浮気しそう(5/4/08)
 このあいだのAKI-H8/3069Fを動かしてみた。始め間違えて6VのDCアダプタを直結し、もうちょっとでまた悲劇が起きるところだったが、何とかOSをROMに書き込むことに成功した。これは2MのRAMを持っているので相当本格的なことが出来る。

 このRAMにロードするメディアとそれをドライブするROMのOSがあれば、フラッシュ100回までという制限なしに、自由にプログラムの開発が出来る。もちろんWindowsからもロードが出来るが、コンパイルはともかくプログラムの実行の度に、Windowsからロードするのは美しくない。このあたりが、一番やりたいところなので、SDカードのアクセスは是非実現しておきたいところなのだが、こいつが手強い。

 テニスから帰ってまた地下にこもり、開発に専念する。リアルタイマーは単純なミスが見つかり、クロックの移植は成功したのだが、論理的なファイルの状況表示がうまくいかない。システムがリセットされるのはメモリをオーバーランしているからだろう。その場所をみつけるため、LEDやテストステートメントを挿入するが中々特定できない。

 ファイル構造体の定義の中に512バイトという大きな数字を見つけ、これを減らしても状況は変わらない。このあいだのMega168で動かしたと言う記事のコードを見てみると実際のバッファーサイズが80バイトしかない。構造体が512なのにどうしてバッファーはこんなに小さいのか。ロジックが読みきれていないので試行錯誤でやるしかない。

 現在のこちらのバッファーサイズは256バイト。バッファーは大きければ大きいほど良いはずなのだが、試しに半分の128に減らしてみた。 これが何と、動いたのである。理由はわからない。ちゃんとディレクトリの位置、FATテーブルのセクタ、ファイルの数などが表示された。やれやれお疲れさんでした。 16MのSDカードがうまく出たので、128Mの方を試してみる。セクタ単位は問題ないが、論理ファイルの表示は途中でリセットがかかった。

 まだ完全ではないが、SDカードのプロジェクトもほぼゴールに近づいたようである。あとは、この応用だが、フラッシュ16KのMega168ではテストに精一杯でSDカードを使いこなすのは、やっぱりMega64クラスにならないと難しそうだ。H8なら全く問題がないが。

ほぼ完全にSDカード読み書き成功(5/10/08)
 CPUチップを2つ犠牲にしたが、SDカードアクセスは試作ボードで、想定の機能をほぼ満足し、実用に近づいた。128MのSDカードは最初読めなかったが、いくつかの関数を使わないようにしたら正常に読めるようになった。どうもメモリ管理を自分でやらないとリセットしたりハングするようだ。まだソースが読みきれていないのでこれは後の課題とする。

 ロガーなどの実装のときのためFETを使った電源制御とプルアップ抵抗などSDカードの回路をサンハヤトの変換基板に組み込みブレッドボード上を整理する。昨夜、酔っ払ってピンをひとつ間違えて差込んでVccをショートさせ、あやうくレギュレータを昇天させるところだったが、時間が短かったので何とか助かった。動かないので念のため部品を触っていて、レギュレータがやけどしそうになるほど熱いのを見つけ、あわてて止めた。このあと動かしたが、特に問題はなかった。いや結構丈夫なものだ。A5101274

 余裕が出来たので、ベンチマークをとってみた。8MのCPUクロックで128MのSDカードは、Readでは200KB/秒、Writeでは20KB/秒と、chaN氏のレポートの半分くらいの速さだが、フラッシュ16K、SRAM 1KのMega168でこの数字は立派なものだ。これでAVRマイコンの世界では破格の大容量記録装置を手に入れたことになる。

 ソースはオリジナルは消さずにすべてコメントアウトし、これからMega168クラスでFATシステムを動かす人のための参考になるようにしたが、オリジナルをコメントアウトしたソースを公開するのも気が引けるので、変更点をまとめておく。

  • 元のメインプログラムはすべての機能を試せるようにかなり大きいので、コマンドを半分以下に減らす(main.c)
  • バッファサイズを縮小  ファイルバッファは2048を128 UARTは120から40 (main.c)
  • 電源制御、チップセレクトなどのポートを変更。(mmc.c)
  • 10msのインタバルタイマーのタイマーレジスタ変更。(main.c)
  • RTCを秋月のRTCモジュール(エプソンRTC8564)で動くように変更。ついでにオリジナルのソフトIICをMega標準のIIC機能を利用。

 以上で、TinyFATFsを使いフラッシュサイズ16K以内(fw,frなどの性能テストコマンドを含む)の16,078バイト、SRAMが798バイトに収まっている。コードの内訳は、ttf.cが7キロ、SDカードをアクセスする下位ルーチンmmc.cが2キロ、リアルタイムクロックが1 キロ、その他UARTやXitoaなどの周辺ルーチンが1キロ程度で、残り5キロはメインのコードとコンスタントである。

 従って、電力ロガーなどのアプリは5キロ以内に収めれば、何とかMega168でSDカードに記録するロガーが出来そうである。

|

« AC電流センサーを入手 | トップページ | LCDを待ち時間なしで動かす »

AVR」カテゴリの記事

コメント

コメントを書く



(ウェブ上には掲載しません)


コメントは記事投稿者が公開するまで表示されません。



トラックバック


この記事へのトラックバック一覧です: MMC(SDカード)をMega168で:

« AC電流センサーを入手 | トップページ | LCDを待ち時間なしで動かす »