|
予定どおり風邪をひきまして、現在も絶賛水洟中! どうもプログラムに集中できません。というわけで、5V→3.3Vの電源アダプターを作ってみました。三端子レギュレータとコンデンサでチョチョイのチョイ、のはず。
ところで、三端子レギュレータってこんなイメージですよね(下の写真)。
名前のとおり足が三本あって、刻印面から見ると左から IN、GND、OUTの順。
でも何を思ったのか今回ぼくが使ったのは、左側がNJM2845DL1-33、右側がAMS1117-3.3。端子にクセのある連中です。
NJMのはラーメン屋の岡持ちの持つところみたいなのがGNDです。足の間にちょろっと出ていますが(男の子なのねw)、GNDとも他の端子とも繋がってないようでした。AMSのGNDは左端で、上のベロは放熱用なのでしょう。
78シリーズの端子イメージが定着しているのはぼくだけじゃないようで、WEBを眺めていると配列の違いに起因する失敗談を見かけました。
作ってみたのが下の写真。サンハヤトの電源付きブレッドボードの上に並べてみました。
左端はサンハヤトの電源。5Vの入力はACアダプターとUSBの両対応で、出力は5Vと3.3Vをジャンパで選択できます。上の電源ラインは5V、下の電源ラインは3.3Vと使い分けもできて、さすがに使いやすいです。 中央がNJMで作ったアダプター。ちゃんと表面実装しているのがお分かりでしょうか。コンデンサもチップを使っています。矢印は5V→3.3Vの方向を示します。ピンのふちが黒いのはGNDのシルシで、ぼくの習慣みたいなものです。GNDがセンターなのでINとOUTを上下に真っ直ぐ引き出すと、端子の位置がズレます。
右端がAMSで作ったアダプター。熱対策するほどのこたぁないだろうと密集してみました。チップ・コンデンサは裏側に貼り付けています。電解コンデンサも使ってみました。GNDが端だと配線がやりにくいなあと思いながらよく見ると、サンハヤトの製品もAMS1117-3.3でした。こりゃまた失礼「(・∀・)w
ブレッドボードぐせ?がついたせいか、入出力端子に丸ピンソケットを使ってしまいました。これではうっかりすると挿し込み時にショートしますね。どこかのブログで拝読した「両端がオスプラグの100V延長コード」を連想しました。
「端子」についてアレコレ考えることになった今回のプチ工作でした。 【蛇足】
ところで、5VACアダプタなんて、そのへんにゴロゴロしてそうなモンですが、4.5Vや9V、11Vなども混じっていて、意外とみつからなかったりします(ぼくだけか?)。
そんなとき、百均で買ったUSB充電コードのプラグを改造しておけば便利かもしれません。1チップMSXのUSB端子も使い道ができるかもね(・∀・)b |
全体表示
-
詳細
コメント(2)
|
やはり、こういう画面で見ないと雰囲気でませんな。
相変わらず、コマンドの発行とレスポンスの受け取りに難航しています。作業的には、ほとんどそれで全部なんですけどね。
付け加えて言えば、読み込みのデータ受け取りと書き込みのデータ渡しぐらいかな?
エラー処理ってのもバカにならないもんですなあ(他人事モード)。
まあ、ちゃんとやってまっせのアリバイづくりばかりですわ。
メインルーチンは極力簡単にするのが好みなんです。
読み込みの場合、コマンド・レスポンス1Bに続いてバッファが512B、ダミーのCRCが2B。合計515B一気に読み込んでラクをしようというのが、ミエミエ中尾ミエですな。PSG0と1は、初期値と作業中の値。作業が終われば初期値に戻します。HLPTRは、BASICから2バイト整数を渡すときのポインタです。
コマンドは、前回の構想から後退してます。リセット用のSDカード専用コマンド、ACMD41ではなくCMD1を使っているのは「退化」と言っていいでしょう。これでダメなら、もっかいSDカード用に書き換えます。
プログラムは全体の半分ほどを示しました。この先の下半身はほぼできておるのですが、本当に読み込んだり、書き込んだりする「RDSD」「WTSD」の部分なんか、ヒドイものですなあ。はっはっは。
浅草ギ研さんは、わざわざスーパーで買ってきた1GBのSDで実験されていて、ちゃんとMMC用のコマンドで動いているそうです。写真まで載せてます。
ぼくがターゲットにしているのは、SanDiskの1GBです。ちゃんとしたメーカー品のほうが仕様にうるさいかもしれませんね。しようがないな。
とらぬタヌキの八畳敷きでしたっけ? まだプログラムも完成していないのですが、マイクロSDでうまくいけば、通常のSDにも応用したいですね。ミニSDって中途半端なモノ使っている人いるのですかね?
なにぶんBASICベースを前提としていますので、どうもFAT対応はメモリ容量的にむずかしいようです。当初にちらっと書いたように、S○NYのHBI-55のような固定長ストレージとしての使い方を念頭に置いています。
とりあえず、中間報告まで。
|
|
今日調べてまとめたものを掲載。実際の端子操作を念頭になるべく分かりやすく書いたつもりですが、誤解・勘違い・誤りがあろうかと思います。誤字脱字、遺漏脱肛など、みつけたら、やさしく教えてね。
────────────────────────────────────
■一般注意事項(今回の仕様の一部を含む)
●SDカードシリーズ、SD・SDHC・SDXCなどの規格のうち、2GB以下のSDのみ対応。なお、この条件を満たすSDへの対応を保証するものではない。
●基本的にアイドル時は、/CS、CLK、DINともH。なお、SD側のDOもアイドル時はH。
つじかわさんが「動作不安定のため」、/CSだけ74HC14で反転させ、CLK、DINは2回反転させて「整形」したとされている。当初のプログラムにおいて、プログラム側で/CSを負論理で書いていたなら他の信号と同様に2回反転させて「整形」すれば済むはずである。 ところで、MSX起動時、汎用ポートの8ピンはL、7・6ピンはHである。MSXにSDを装着したまま起動したとすると、SDに通電した時点で/CS=L、つまり選択状態となる。つじかわさんはこれを嫌って、当初から8ピンだけは74HC14で反転するつもりだったのではないか? /CSは、起動時からHの7又は6ピンに割り当てればいいようなものであるが、頻繁に書き換えるCLKとDINをビットが隣りどうしのセットで扱いたかったのかも知れない。CLKの立下りでDIがSDに読み込まれるので、7・6ピンを同時に変化させたのだろう。 この結果、余禄として、本来同時に変化すべきトリガAとトリガBに、実はタイムラグが生じる予想外の"発見"に至ったのではないか。 なお、書籍「フラ研」には「CLK」にバッファを入れたら、すんなり正常動作した旨の記述がある(109頁)。つじかわさんが動作不安定に悩まされたのも、CLKが原因だったかもしれない。 ●随所にダミークロックが8クロック挿入されるが、この間、/CSはH・Lどっちでもいいとされる(「フラ研」95頁。ホンマかいな?)。今回はダミークロックの間は一般に/CS=Lで統一する。
●CLKはホスト側で発生する。DIN(DATA IN)やDO(DATA OUT)の端子名はSD側から見た名称であるが、以下で「出力する」と言った場合は、一般にホスト側からの出力を意味する。DOのみカード側の出力となる。混乱しないように>自分。
●ホスト側からDINに出力するときは、CLKの立下りでSDに取り込まれる。SDが取り込んだタイミングを見計らってCLK=Hにする。
●ホスト側に読み込むときは、CLKの立上がりでSDはDOに出力するのでタイミングを見て読み込み後、CLK=Lにする。
──────────────────────────────────── ■初期化シーケンス(初期化中は400kHz以下のクロック。)
1 /CS=H
2 CLKから80クロック出力
CLK=Hの初期状態から、L・Hを80回送信し、CLK=Lとする。 資料によっては「74クロック」と記載しているものもあるが、SanDiskやALTERAの資料等では「80クロック」となっている。ダミーデータを10バイト送信すると考えれば「80クロック」に根拠があると思われる。 浅草ギ研さんは「クロックを10バイト送る」と表現されている。8bit×10バイト=80クロックだが、CLKの動きだからクロックで表現するほうが分かりやすい。 3 /CS=L
/CS=Lの状態でSDがCMD0を認識すると「SPIモード」に移行する。SPIモード以外に、SDカード本来の「ネイティブモード」があるのは知っているよね。SandDiskがSPI対応を提案して取り入れられたそうです。SandDisk、エライ! 4 CMD0発行
SDに対するリセット開始の命令である。 データ並びは、40H,00H,00H,00H,00H,95H。 一般に、コマンドは先頭1バイトがコマンド本体、続く4バイトが引数、最後の1バイトがCRCとなる。 先頭2ビットは「01」で始まり残る6ビットが実質的なコマンドを示す。CMD0の場合、2進数で書くと「01000000B」なので、これを16進数にすると「40H」となる。 引数は持つものと持たないものがある。CMD0は引数を持たないので全部「00H」で埋める。CRCのビット0はエンドビットとして「0」に決まっているので、実質7ビットがCRCである。SDでは、ホストとカード間の通信におけるエラー検出にCRCが使われるが、SPIモードではCMD0のみ意味を持ち、他のコマンドでは基本的に無視される。CRCの計算は面倒なのでかなり助かる。CMD0のCRCだけはチェックされるので、エンドビットの「0」を含めて「95H」となる。 DINに値をセットしながら、H・Lを繰返しCLKの立下がりでコマンドを送出する。 コマンド送出後、CLKの立上がりでDOをポーリングし続ける。SDが「BUSY」状態の間はDOはHのままである。これがL(つまり「0」)になると「コマンド・レスポンス」の始まりである。
浅草ギ研さんはレスポンス待ちについて、「1バイトずつポーリングする。値がFFHのときはBUSY、FEHになるとBUSY終了」旨の書き方をされているが、ちょっと誤解を招きそうな気がする。BUSYの期間は不定である。「ポーリング結果をレジスタのビット0に入れ、左にシフトしながら次のポーリング結果を待つ」と書くのがより動作を理解しやすいだろう。「0」がきたときは、結果的にレジスタの値は「FEH」になるけどね。 5 コマンド・レスポンスの受信
DOから「0」を先頭に8ビット(=1バイト)のコマンド・レスポンスを受信する。「00000001B」(初期化プロセス実行中)であればOK。違っていたら何らかのエラーが起きている。 エラーがあった場合、今回のプログラムの仕様ではBASICに渡すバッファの先頭にエラー・レスポンスを残すしてRETするので、作業を中止してエラーの原因究明に当たろう。 他のコマンドでは、コマンド・レスポンスは「00H」であるが、CMD0だけ「01H」の点に注意が必要である。 ちなみに、コマンド・レスポンスには、1バイトの「R1」のほか「R1b」「R2」「R3」があるが。SPIモードでは「R1」のみ気にしておけばいい。 6 CMD1のための間奏曲(インターメッツォ)
ポーリング終了直後のCLKはHとなっているのでLにする。 CLKのH・Lを8回繰り返す。 CLK=Hにする。 /CS=Hにする。 この、CMD0とCMD1との間の操作は書籍によっては書いていない。ダミークロック送出と/CS=Hのタイミングが逆になってる例もあった。浅草ギ研さんもずいぶん悩んだらしい。この動作全体をしなくても動くこともあるらしい。 一応、安全のための「おまじない」として入れておく。 7 CMD1発行
SDの初期化作業が終わったかどうかの問い合わせ。 データ並びは、41H,00H,00H,00H,00H,F9H。ただしCRCはどうでもいいよ。
発行手順はCMD0と同様。SDが初期化作業中であれば、DOはHのまま。再びCMD1を発行し続けてポーリングする。 大容量化によってBUSY期間は長くなるらしく、100ms以上のタイムアウト期間を見込むべきらしい。 コマンド送出後、CLKの立ち上がりでDOをポーリングし続ける。ポーリングについてはCMD0と同じ。 8 コマンド・レスポンスの受信
DOから「0」を先頭に8ビット(=1バイト)のコマンド・レスポンスを受信する。「00000000B」ならOK。違っていたら何らかのエラーが起きている。 9 次のCMDのための間奏曲(インターメッツォ)
ここは 6 と同じ。 くたびれたところへ、ちょうどガメラが来た(・∀・)わ〜い♪ 怪獣見よっとw |
|
予想通り難航中なう。SDカードの初期化の部分でつまずいています。
CMD0でリセットかけると、カードは初期化作業に入ります。それが終わったかどうか問い合わせるのが、MMCではCMD1、SDカードではACMD41のようです。
でも、「ACMD」の「A」は「2バイトコマンド」を意味するそうで、先行してACMD5?を送信してACMD41を送信するようです。初期化作業が終わるまでコマンドを発行し続けて待ちます。
このへんのフローチャートについて、SUN DISKの資料を入手しましたが、上から下へ一部ループという見慣れたフローチャートじゃなくて、あっち行ったり、こっち行ったりするのです。挙句の果てに「対応カードじゃない!」と放り出されたり。ま、それが正しいフローですが。
今日は一日、200頁ほどの英語の資料に取り組んでくたびれました。
一行もプログラムは書けていません。だんだんと「なんだかみなさん、CMD1でうまくいってるみたいじゃん?」と、低きに流れる気持ちになっています。
あ、それと「2G超え非対応、HC非対応」と仕様書にかかなくっちゃ。
SDカードもバージョンがいろいろできてややこしいです(*´Д`*)
プログラム書く前に、処理のシーケンスを書き直します・・・>┼○ バタッ
明日か明後日、『平成ガメラ3部作』が届くので、ブログ更新は暫く滞りますw
『ゴジラ対ヘドラ』と『三大怪獣 地球最大の決戦』と『パシフィック・リム』も一緒に届く予定です。週末は怪獣三昧 ヽ( ´¬`)ノ〜♪
|
|
昼寝しながらも、コツコツと作業を進めております。
「MSX テクニカル・ハンドブック」や「MSX-DOS スーパーハンドブック」を初め、「BASIC説明書」「Z80マシン語ランド」「フラッシュ・メモリー・カードの徹底研究(以下「フラ研」という)」などなど、書籍たくさん、
MMC/SDCの使いかた
浅草ギ研 A33FでMicroSDカードにアクセスしてみる
などなどWEBもたくさん、参照させていただいてます。
「フラ研」には、SDカードでは初期化コマンドにACMD41を用いないと、MMC用のCMD1ではレスポンスが返ってこないと書いてありますが(149頁)、浅草ギ研さんとこではCMD1を使っておられて、相変わらず困惑している今日この頃です。「フラ研」の別のページでは「MMC用のソフト・ハードでSDにもアクセスできた」と書いてあり(112頁)、本当のところどうなんでしょう?
とりあえず、対応予定のCMDを並べてみました。
CMD0: DEFB 40H,00H,00H,00H,00H,95H
ACMD41: DEFB 69H,00H,00H,00H,00H,95H ↑このふたつは、SDカードのリセットに使います。いまだACMD41を使うべきかCMD1にするか迷い中。実験してから決めます。 CMD16: DEFB 50H,00H,00H,02H,00H,95H
↑このコマンドで、ブロック・サイズを512Bに設定します。2G以上のSDカードでは1024Bのこともあるようです(「フラ研」151頁)。「フラ研」の筆者のひとりは「これまで512B以外は見たことがない」と書いていますが(126頁)、2006年に発行された本なので2G以上のカードがあまり普及していなかったのでしょう。スマートメディアが「最も普及しているメモリ・カード」(11頁)とされる時代でした。 CMD17: DEFB 51H,00H
CMD17H: DEFB 00H CMD17L: DEFB 00H,95H ↑このコマンドは、読み込み時、アクセスするセクタを指定します。「H」と「L」の部分には、USR関数で渡される数値が代入されます。 CMD24: DEFB 58H,00H
CMD24H: DEFB 00H CMD24L: DEFB 00H,95H ↑このコマンドは、書き込み時、アクセスするセクタを指定します。この「H」と「L」の部分も読み込み時と同様です。 CMD59: DEFB 7BH,00H,00H,00H,00H,95H
↑このコマンドは、CRCを明示的に無効にします。SPIモードでは最初のCMD0以外、CRCは無視されるはずですが、「ごくまれにCRCを無視しないカードがある」と「フラ研」に書いてありました(106頁)。CMD0以外のコマンドのCRCが全部「95H」となっていますが意味ありません。
まあ、これぐらいのコマンドに対応しておけば大丈夫でしょう、たぶんw。
で、肝心のSDカードのアクセス部分ですが、
SDINI:;---------
CALL CSH CALL CLK80 CALL CSL RET RDSD:;----------
RET WTSD:;---------- RET まだこれだけしか書けてません。というか、全然書いてないじゃんw
ときどきダミークロックを挟まないといけない(「フラ研」95頁)とか、「CMD0とCMD1の2つのコマンドを発行するあいだはCSはずっとLOWのままのように書いてありますし、SDカードの仕様が書いたドキュメント類を読むとそのようになっているようですが、実際に実験してみた結果、CMD1後にCSをHIGHにして1バイトダミーバイトを送信しないと同期が狂うことがわかりました。よって実際のプログラムではCMD1を何回も発行する前にCS=HIGHにして1バイト送信し、CS=LOWにしてからCMD1を発行しています。(この部分でかなりの時間を消費してしまった。SDカードのドキュメントわかりづらいです。) 」(浅草ギ研さん)とか、いろんな情報が錯綜して現在調査中であります。
つじかわさんの「mmc_test.com」も理解しきれてないし。
以下、現時点でのアセンブラリストとBASICのリストを掲げておきます。現時点では何事も起きず、無事「OK」となります。SDにアクセスしてないもんな。
ここのブログ、別ファイルにて掲載する機能がないし、TABコードを半角スペースに変換するし、なので少し困っています。完成時の公開をどうしようかな? 画像では困るでしょうね。
─────────────────────
■アセンブラリスト(適宜、半角スペースをTABに変換してね。)
;===================
; SDTEST.ASM XCD /B ; KIKI 2014 ;=================== JPORT EQU 6 ;Use JPORT B
CS EQU 5 ;CS =PIN8 CLK EQU 3 ;CLK=PIN7 DIN EQU 2 ;DI =PIN6 DO EQU 0 ;DO =PIN1(#14) ORG 0C000H
MAIN:;----------
CALL SDR ;USR0=0C000H CALL PSGRST RET CALL SDW ;USR1=0C007H CALL PSGRST RET BUFF: DEFS 512 ;BUFF=0C00EH
PSG0: DEFS 1 PSG1: DEFS 1 CMD0: DEFB 40H,00H,00H,00H,00H,95H ACMD41: DEFB 69H,00H,00H,00H,00H,95H CMD16: DEFB 50H,00H,00H,02H,00H,95H CMD17: DEFB 51H,00H CMD17H: DEFB 00H CMD17L: DEFB 00H,95H CMD24: DEFB 58H,00H CMD24H: DEFB 00H CMD24L: DEFB 00H,95H CMD59: DEFB 7BH,00H,00H,00H,00H,95H SDR:;-----------
DI PUSH HL CALL PSGINI CALL SDINI LD A,(BUFF) OR A RET NZ POP HL INC HL INC HL LD A,(HL) LD (CMD17L),A INC HL LD A,(HL) LD (CMD17H),A CALL RDSD EI RET SDW:;-----------
DI PUSH HL CALL PSGINI CALL SDINI LD A,(BUFF) OR A RET NZ POP HL INC HL INC HL LD A,(HL) LD (CMD24L),A INC HL LD A,(HL) LD (CMD24H),A CALL WTSD EI RET PSGINI:;---------
LD A,15 OUT (0A0H),A IN A,(0A2H) LD (PSG0),A PUSH AF LD A,15 OUT (0A0H),A POP AF SET 6,A SET CS,A SET CLK,A SET DIN,A OUT (0A1H),A LD (PSG1),A RET SDINI:;---------
CALL CSH CALL CLK80 CALL CSL RET RDSD:;----------
RET WTSD:;----------
RET ;CS H/L --------
CSH: LD A,15 OUT (0A0H),A LD A,(PSG1) SET CS,A OUT (0A1H),A LD (PSG1),A RET CSL: LD A,15
OUT (0A0H),A LD A,(PSG1) RES CS,A OUT (0A1H),A LD (PSG1),A RET ;CLK H/L --------
CLKH: LD A,15 OUT (0A0H),A LD A,(PSG1) SET CLK,A OUT (0A1H),A LD (PSG1),A RET CLKL: LD A,15
OUT (0A0H),A LD A,(PSG1) RES CLK,A OUT (0A1H),A LD (PSG1),A RET ;DIN H/L --------
DINH: LD A,15 OUT (0A0H),A LD A,(PSG1) SET DIN,A OUT (0A1H),A LD (PSG1),A RET DINL: LD A,15
OUT (0A0H),A LD A,(PSG1) RES DIN,A OUT (0A1H),A LD (PSG1),A RET ;CLOK 80 -------
CLK80: CALL CLKL LD B,80 CLK80L: CALL CLKH CALL CLKL DJNZ CLK80L CALL CLKH RET ;DUMY CLOK 8 -------
DCLK: CALL CLKL LD B,8 DCLK8L: CALL CLKH CALL CLKL DJNZ DCLK8L CALL CLKH RET PSGRST:;--------
LD A,15 OUT (0A0H),A LD A,(PSG0) OUT (0A1H),A RET END
─────────────────────
■BASICリスト(何もなくてごめんね。)
1000 '===============
1010 ' SDTEST.BAS 1020 ' KIKI 2014 1030 '=============== 1040 SAVE "SDTEST.BAS" 1050 CLEAR 100,&HC000 1060 DEFINT A-Z 1070 BLOAD "SDTEST.OBJ" 1080 DEFUSR0=&HC000 1090 DEFUSR1=&HC007 1100 A=USR0(0) 1110 END |


