H8,SH,マイコン,ぼやき川柳,ダウンロード

mmcドライバの改修


微調整(とはいえ、元々微調整しかしていませんが)で2GBのSDカードにアクセス出来ましたので、新版をアップします。旧版は拡張メニューにあります 2010.4.22

 詳細は奮闘記に書きますが、3個目のSDカードボードでも動かないので結構落ち込みました。しかしロジアナで信号が少しだけ往復しているのを確認できたので、ボードではなくドライバを疑いました
 正直なところ、この辺の知識は全くありません。試行錯誤しながら適当に触ったら動いちゃったというのが正直なところです(お前は神か!?)
 mmcドライバのソースはmmc.cです。最初、[Disk I/O error.]を出力している箇所を探しましたが見つけられませんでした。どうも、mountコマンドの場合、shell.cの中でエラーは何でも[Disk I/O error.]を出力しているようです
 尚、formatコマンドには対応していません。SDカードはPCでフォーマットしてください

(1)改修その1(sci_mmc_reset)
 mount mmc(0/1)コマンドを入れると最初にこのルーチンが動きます
 SDカードからのレスポンスを受信した後のバージョンのチェック方式を単純にしました。SDカードの規約を確認していないのでちょっと適当です。多少強引に「mmc[minor].ver = 2;」を通しています


static int sci_mmc_reset(minor) {
    int             ret, param, ret0, j;
    volatile int    i;
    IOREG           *csdr;

    ddr_set(mmc[minor].sci_port, CLK + CMD);
    pe_reset(mmc[minor].sci_port, CMD);
    *MMC_DR |= CLK + CMD;
    ddr_set(mmc[minor].port, CS);
    *mmc[minor].scr = 0x00;
    *mmc[minor].ssr = 0;
    *mmc[minor].scmr = 0xfa;
    *mmc[minor].smr = 0x80;
    *mmc[minor].brr = LOW_SPD;
    for(i = 0;i < 1000;i++);
    csdr = get_dr(mmc[minor].port);
    if(mmc[minor].cs_positive == 0) {
        *csdr &= ~CS;
    } else {
        *csdr |= CS;
    }
    INT_DISABLE();
    for(i = 0;i < 20;i++) sci_putch(minor, 0xff);
    sci_putch_sw(minor);
    if(mmc[minor].cs_positive == 0) {
        *csdr |= CS;
    } else {
        *csdr &= ~CS;
    }
    ret = sci_mmc_command(minor, CMD_INITIALIZE, 0, 0);
    if(ret != 1) {
        INT_ENABLE();
        return -1;
    }
    param = be32toh(0x1aa);
    ret = sci_mmc_command(minor, CMD_CHECK, (char*)&param, 4);
    mmc[minor].ver = 1;
    if ( ret >= 0 ) {
//    if((ret &  4) == 0) {        
        mmc[minor].ver = 2;
//        if(ret != 1) {
//            INT_ENABLE();
//            return -1;
//        }
//      for(i = 0;i < 3;i++) sci_getch(minor);
        for( j=0; ; j++ ) {
            ret0  = sci_mmc_command(minor, CMD_APP, 0, 0);
            param = be32toh(HCS);
            ret   = sci_mmc_command(minor, ACMD_COND, (char*)&param, 4);
            if( ( ret0 == 0x00 ) && ( ret == 0x00 ) ) break;

            if( j > 2000) {
               INT_ENABLE();
//write_hex((char*)&ret, 4);
//__write(0,0,"\r",1);
               return -1;
            }
        }
    } else {
        for(;;) {
            ret = sci_mmc_command(minor, CMD_ENABLE, 0, 0);
            if(ret <= 0x01) { mmc[minor].ver = 2;
                              break;                }
            if(ret != 0x01) {
                INT_ENABLE();
                return -1;
            }
        }
    }


//  param = be32toh(512);
//ret = sci_mmc_command(minor, 16, (char*)&param, 4);    // BLKSIZE = 512B
    
    INT_ENABLE();
    return 0;
}


その後、mount出来なかったKINGMAXの2GBのSDカードにもアクセス出来ました。初版からの修正は下記です 2010.4.22

 (ア)2GB SDカード
 KINGMAXの2GB SDカードでCMD_CHECKのリターンコードは1が返っていました。このためさらに過激な修正となりますが、4>=としていたのを0>=と変更しました。一応「FATって何?」で記述されている処理(CMD_CHECKに応答が有った場合はCMD_APPを送信)に準拠しています。送受信ブロックサイズを512Bにする修正を追加しましたが、無くても動作しましたのでコメントアウトしています

 (イ)1GB Micro SDカード
 TOSHIBA 1GB Micro SDカードはACMD_CONDに対してリターンコード −1(レスポンスは5)が返っていました。0になるまで(2000回以内)ループすることでmountできました。

 (ウ)神秘 の空読み
 本当は奮闘記に書いた方が良いのですが(ア)の修正を入れたときに、ついでに空読みを復活させました

   for(i = 0;i < 3;i++) sci_getch(minor);  ・・・・・ SDカードからのレスポンスを空読み

 これは最初にロジアナを入れてMediafoのSDカードをテストした時に、何も読み込んでいなかったので意味がないだろうと思い、何気なくコメントアウトしていましたが2GB SDカードからはレスポンス0001AAが返って来たので復活させました
2GB SDカードが問題なく動作したのでソースをアップしようと思い、念のため他のカードの動作確認を行ったのですがことごとくDisk IO Errorでmount出来ません。
 これが又、原因がなかなか分かりませんでした。ロジアナで調べると本来、次にAPP_CMD(77)16を送信するはずが、(FD)16に化けてしまっています。一度痛い目に遭っていますが、いくら何でも先頭が(F)16はあり得ません。試しに空読みをコメントに戻すと正常に(77)16が観測でき、2GB以外のSDカードも無事mount出来ました。H8のハードマニュアル(特にIOレジスタ)は理解出来ていませんが、空読みで微妙にタイミングを狂わせてしまっているようです。何気なくコメントにした事が実際には重要な効果があったようで神秘です。H8をサポートから外したのはこの辺の不可解な振る舞いに有るのかもしれません

   

(2)改修その2(sci_mmc_command)

 ネゴシエーション後、clockのスピードを上げているのを止めました
この修正は実はロジアナが追随できなくなるのでデバッグ用にスピードを落としただけです。でもそれで動いてしまいました

static int sci_mmc_command(int minor, char command, char *arg, int arglen) {
    int        i, over;
    unsigned char    data, crc;

    switch(command) {
    case CMD_INITIALIZE:
        crc = 0x95;
        *mmc[minor].brr = LOW_SPD;
        break;
    case CMD_CHECK:
        crc = 0x87;
        *mmc[minor].brr = LOW_SPD;
        break;
    default:
        crc = 0x01;
//        *mmc[minor].brr = (mmc[minor].ver < 2) ? MID_SPD : 6;
        *mmc[minor].brr = LOW_SPD;
    }        
    over = MMC_TIME_OVER;
    sci_putch(minor, 0xff);
    sci_putch(minor, 0xff);
    data = MMC_CMD_INIT | (command & 0x3f);
    sci_putch(minor, data);
    for(i = 0;i < 4;i++) {
        data = (i < arglen) ? arg[i] : 0;
        sci_putch(minor, data);
    }
    sci_putch(minor, crc);
    if(mmc[minor].ver < 2) {
        sci_putch(minor, 0xff);
    } else {
        sci_putch_sw(minor);
    }
    sci_putch_sw(minor);
//    while((data = sci_getch(minor)) & 0x80){
    while((data = sci_getch(minor)) == 0xff){
        if(--over == 0) return -1;
    }
    sci_getch_sw(minor);
    return data;
}


mmc.cソース


以下のファイルをコピペしてファイル名mmc.cで保存して(オリジナルは別名にしておきます)CBarでコンパイルしてください
環境設定でコンパイルオプションはDevice_H8.xmlを選択しておいてください

出来上がったmmc.exeはDisktoolで固めて、内蔵ROMに焼きます
(Tabが無視されていたのでスペースに変換してアップしなおしました(2010.4.4))

コンパイルの仕方

誰からもコメントを頂けないので少し解説を追加します(寂しい・・)
CBarの使い方(コンパイルの仕方)やアプリの開発の仕方は「やまねこのマイコン実験室」が大変参考になります。読んで頂いたという前提で手順としては以下です

(1)「大西さんのサイトから」gcc23r18.exeを落としインストール(CBar他がインストールされます)
(2)同じくmodule_modify.zip を落として解凍する
(3)解凍した中からmmc.cを探し別名にしておく
(4)上記の改修したmmc.cをコピペしてmmc.cとして保存
(5)mmc.cbaをWクリック(CBarが立ちあがる)
(6)メニューバーの「設定」「環境設定」をクリック


(7)「Fset」ダイアログの下段から「読込」ボタンをクリック。「ファイルを開く」ダイアログで「Device_H8.xml」を選択


(8)忘れずに「Fset」の「設定」ボタンを押下
(9)「Cbar」に戻り、「実行」から「コンパイル」を選択。コンパイル結果が右のペインに表示される
   「*** Compile completed. ***」が出れば成功です



(10)出来たmmc.exeをDisktoolで固めてH8内蔵ROMに焼きます
   その他の環境は「SDカードボードの動作環境」を参照してください



コンパイル済み実行ファイル

実行ファイルその物はこのサイトでは添付出来ないようです。ご容赦ください
以下はmmc.exeをM-BASE64を使用してbase64エンコードしたものです。デコードするとmmc.exeができるはずです。M-BASE64はVECTORなどから入手してください。


mmcドライバの改修2 奮闘記
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

Menu

管理人/副管理人のみ編集できます