So-net無料ブログ作成
English Version
前の5件 | -

レトロマイコンZ80ボードの構想(その9)CP/M80 BIOS検討 [PIC]

 ebayで注文したブレッドボード用の接続コードがまだ届かず Z80 と PIC24FJ64GA004 のインターフェース部分の実験ができず待ちの状態なのでCP/MのBIOS部分の検討を少しやってみました。

 インテル系のニーモニックはあまり好きじゃないのでザイログ系のニーモニックがフルに使えるMACRO-80(m80.com)をCP/Mエミュ上で使うことに決めました。

 何十年かぶりの m80・・・^^
 avrCPM用のbios.asmを基にしてザイログニーモニックへの変換はすぐにできましたが、ディスクパラメータ生成のためのmac.com用のマクロがそのままでは動かず、自力でm80用に変換しようかとも思ったけどネットで探したら見つかった^^

bios.macの先頭部分抜粋
MSIZE EQU 62 ;size of available RAM in k BIAS EQU (MSIZE-20) * 1024 CCP EQU 3400H+BIAS ;base of cpm ccp BDOS EQU CCP+806H ;base of bdos BIOS EQU CCP+1600H ;base of bios CDISK EQU 0004H ;current disk number (0 ... 15) IOBYTE EQU 0003H ;intel iobyte BUFF EQU 0080H ;default buffer address RETRY EQU 3 ;max retries on disk i/o before error CR EQU 13 LF EQU 10 NSECTS EQU ($-CCP)/128 ;warm start sector count ASEG ORG 100H .PHASE BIOS .Z80 JP BOOT WBOOTE: JP WBOOT JP CONST JP CONIN JP CONOUT JP LIST JP PUNCH JP READER JP HOME JP SELDSK JP SETTRK JP SETSEC JP SETDMA JP READ JP WRITE JP LISTST JP SECTRAN SIGNON: DB CR,LF DB MSIZE/10+'0' DB (MSIZE mod 10) + '0' DB 'k CP/M Version 2.2 COPYRIGHT (C) 1979, DIGITAL RESEARCH' DB CR,LF,0 BOOT: LD SP,BUFF LD HL,SIGNON CALL PRMSG XOR A LD (IOBYTE),A LD (CDISK),A JP GOCPM


 あちこちいじっていますが、アセンブルが通りました。

超久々にm80でザイログニーモニックソースのアセンブル

 ディスクパラメータも想定通りに展開されています。^^

ディスクパラメータ生成
; Name spt bls dks dir cks off dpb dpb_A, 64, 2048, 972, 256, 0, 1 F38B + dpb_A: ddw %64,<;sec per track> F38B 0040 + dw 64 ;sec per track F38D 04 + db 4 ;block shift F38E 0F + db 15 ;block mask F38F 00 + db 0 ;extnt mask F390 03CB + dw 971 ;disk size-1 F392 00FF + dw 255 ;directory max F394 F0 + db 240 ;alloc0 F395 00 + db 0 ;alloc1 F396 0000 + dw 0 ;check size F398 0001 + dw 1 ;offset dpb dpb_B, 64, 2048, 976, 256, 0, 244 F39A + dpb_B: ddw %64,<;sec per track> F39A 0040 + dw 64 ;sec per track F39C 04 + db 4 ;block shift F39D 0F + db 15 ;block mask F39E 00 + db 0 ;extnt mask F39F 03CF + dw 975 ;disk size-1 F3A1 00FF + dw 255 ;directory max F3A3 F0 + db 240 ;alloc0 F3A4 00 + db 0 ;alloc1 F3A5 0000 + dw 0 ;check size F3A7 00F4 + dw 244 ;offset


 Z80とPIC24FJ64GA004とのインターフェースに関してはこれから細かく考えますが、boot時のシステム読込みはSDカードからではなく、PIC内のフラッシュから展開した方が良さそう。

 あと、Z80とPIC間のインターフェースでZ80側のNMIもリセットも使わない方法を実験予定です。うまく行けばI/Oが1bit節約できる ^^


[TOP] [ 前へ ] 連載記事 [ 次へ ]
nice!(0)  コメント(0) 
共通テーマ:趣味・カルチャー

レトロマイコンZ80ボードの構想(その8)パラレルマスターポート機能 [PIC]

 前回の記事「レトロマイコンZ80ボードの構想(その7)SDカード2」でSDカードのアクセス方法が確認できたので外部メモリ制御のためにPIC24FJ64GAのパラレルマスターポート(PMP)機能について実験してみました。

 PICに実装されているPMP機能については「レトロマイコンZ80ボードの構想(その2)」の記事でも少し書いていますがPIC24FJ64GA004では外部メモリ制御のためのアドレス信号はPMA10(アドレス信号合計で11本)までです。
 PICのピンアサインに関しては「レトロマイコンZ80ボードの構想(その5)ピンアサイン」を参照してください。

 今回使用したメモリは HM628128で128KBytesのDIPパッケージの5V動作のスタティックRAMです(アクセスタイム:70ns)。
 今回の評価実験回路については
  • アドレス線
     Z80のメモリ空間は64KBytesなのA16はGNDに固定。またCS2は5Vに接続

  • チップセレクト(CS1/)
     Z80からのバス切替時などにlowになると最悪メモリ内容が破壊される可能性もあるので5Vにプルアップし、PIC側のPMCS1はオープンドレインに設定

  • アドレスの上位ビット
     A14、A15はとりあえず、PIC側のAD13に接続

  • PMWR
     実験的にPIC内でプルアップ設定

としています。

 メモリ書込み時のロジアナ波形が下図です。
 PMPではメモリアクセス時のタイミングをPMMODE(パラレルマスタポート モードレジスタ)で設定でき、今回は
  • WAITB : 0
  • WAITM : 1
  • WAITE : 0

で設定しています(パラメータ名の末尾はそれぞれ Begin,Middle,End の意味だと思う)

 ライトストローブの後にCS1/がdisableになるまでの時間が長め(WAITEで調整)ですが最短設定にしています。

 データ線は読込み時にPIC側が入力状態になりますが、一部5Vトレラントでないポートがあります。時間的には一瞬なのでこのために壊れることはまずないと思いますが抵抗を入れる等、考慮した方がいいかも。
 アドレス線など、他の信号に関してはPIC側からの出力信号であり、3.3V駆動のPIC側の信号でもメモリ側の規格範囲内(Input high voltage Min 2.2V)です。

メモリ書込み波形


 メモリ書込み/読込み時の波形が下図です。
 0x0000アドレスから開始(アドレスは自動インクリメント)して0xa5と0x5aの2つのデータを書込んだだ後、書込んだデータを読み出している波形です。

 読み出し時にデータ線がバタついている部分がありますが、PIC側もメモリ側も入力状態なのでフローティング状態のためです。  バタつくのは良くないのでデータ線に関してはPIC側でプルアップ設定することでバタツキ対処をする予定です
★2018/02/13 修正 {
 3.3V電源が2.9Vの状態でした^^; 3.3Vにするとデータリード時のバタツキは発生しなくなりました(電源電圧が低くスレッショルド付近であったためバタツキ易くなっていたものと思います)。ロジアナのキャプチャも3.3Vのものに差し換えました。
}

メモリ書込み/読込み波形


★2018/02/12 追記
 メモリテスト中のロジアナ波形を追加しておきます。数十分間連続動作させましたがエラーは検出されませんでした。

メモリ試験中の波形



 今回の実験で作ったソースを末尾に貼っておきます。
 PMCS1はPMA14(アドレス線)と兼用なのでネット上で見つかる例はチップセレクトとしてPIC24FJ64GA004には無いPMCS2を使うものが殆どで、今回のようにPMCS1を使っている例は見つかりませんでした(海外等をじっくり探せば例があると思うけど探すより試した方が面白い)。

 メモリライトを2回行った後、メモリリードを2回行っていますが、最初のリードはPMPがメモリリードシーケンスを開始するためのトリガなので読込んだデータは前回のリード動作で読んだ値になっています。(n個のデータを読むためには(n+1)回の、PMDIN1レジスタの読込みが必要)

 また、init()の最後で実験的にPMWRをプルアップ設定してみたところ予想通り、PMPをdisableにした後も信号レベルはhighを保持する(ポート入力機能以外でもPullUp設定は有効)ようになりました。

PMP機能の実験用に作ったソース(picle言語)
:l 1:# PMP test for PIC24FJ64004 2:# ver 0.01 2018/02/10 by skyriver 3: 4:var REG,_REG; 5:var PMCON,PMMODE,PMADDR,PMDAT,PMAEN,PMSTAT; 6:var Pmcon, Pmmode; 7: 8:# print value 9:proc PrnVal( str, val ) { 10: PrnStr_( str ); 11: PrnHex_( val ); 12:} 13: 14: 15:proc ChkBsy() { 16: while ( PMMODE[0] & $8000 ) {} 17:} 18: 19: 20:proc SetAdr( adr ) { 21: ChkBsy(); 22: PMADDR[0] = adr | $4000; 23:} 24: 25: 26:proc MemWr( dat ) { 27: ChkBsy(); 28: PMDAT[0] = dat; 29:} 30: 31: 32:func MemRd() { 33: ChkBsy(); 34: return = PMDAT[0]; 35:} 36: 37: 38:proc init() { 39: var pre,cen,post; 40: PMCON = $0600; # PMMODE[1], PMADDR[2] 41: PMMODE = $0602; 42: PMADDR = $0604; 43: PMDAT = $0608; 44: PMAEN = $060c; 45: PMSTAT = $060e; 46:# PADCFG1 = $02fc; 47: 48: Pmcon = $8380; # 1000 0011 1000 0000 49: PMCON[0] = Pmcon; 50: 51: pre = 0; # 2bit 52: cen = 1; # 4 bit 0:31.25ns 1:62.5ns 2:125ns 53: post = 0; # 2bit 54: Pmmode = $0a00|(pre*64)|(cen*4)|(post); # 00xx x010 xxxx xxxx 55: PMMODE[0] = Pmmode; 56: 57: PMAEN[0] = $47ff; # PMAEN 0100 0111 1111 1111 58:# PADCFG1[0] = $0000; # default 59: 60: asm_( $A8E2CF ); # bset ODCB,#15 61: REG = $02c8; # TRISB 62: REG[2] = 0; # LATB 63: REG[0] = $fff8; # AD11-13 64: 65: REG = $0068; # CNPU1 66: REG[0] = $1000; # pull up CN16 PMWR 67:} 68: 69: 70:proc main() { 71: var dat; 72: init(); 73: 74: SetAdr( 0 ); # set addr 75: MemWr( $a5 ); 76: MemWr( $5A ); 77: 78: SetAdr( 0 ); # set addr 79: dat = MemRd(); 80: dat = MemRd(); 81: 82: PMCON[0] = $0380; # PMP disable 83: PrnVal( "\npmcon : ", Pmcon ); 84: PrnVal( "\npmode : ", Pmmode ); 85:} 86: :run pmcon : 8380 pmode : 0A04 :


[TOP] [ 前へ ] 連載記事 [ 次へ ]
nice!(0)  コメント(0) 
共通テーマ:趣味・カルチャー

レトロマイコンZ80ボードの構想(その7)SDカード2 [PIC]

 前回の記事「レトロマイコンZ80ボードの構想(その6)SDカード」でSDカードとのSPI通信のロジアナ波形を掲載しましたが、ブロック読込み時に読込みデータ間にクロックが停止する隙間がでるのが嫌なのでSPI通信の処理を見直しました。

  • リード時の隙間
     SPI通信でデータリード時にデータ間にクロックの停止する隙間が発生するのはやはりもったいない。SPIモジュール(ハード)自体の制約によるものではないので隙間なく受信するように変更しました。

  • CSをhighに変更後のクロック提供
     web上の情報ではCSをhighにしてから1バイト(0xff)を送信する必要があるという情報を見かけましたが、波形を見てみるとSDカードからの応答の最後のバイトのLSBがlowの場合、その後のクロック提供がないと、DOをlowに引っ張り続けることがあるけどクロック入力によりパラ-シリ変換がシフトされる(ゴミが残った場合吐き出される)とDOがhighに復帰するので供給するクロックは1クロック以上であればいいように思えます。
     今回はわざわざ1バイトの0xffを送らないでSPI受信処理時のクロック提供のための0xff送信でバッファを使うようにしました。
     受信完了後にバッファ内の0xffデータが送信されるのでSDカード側のごみ吐出しはできるものと思います。

 改良版でのSPI波形を参考に貼っておきます。今回はブロックライトとブロックリードの波形も付けました。

★2018/02/10 追記 {
 SDカード初期化時のクロックは333kHzです。初期化後クロック切替えの実験をしたところ、SPI1CON1のプリスケーラの再設定だけではクロックが変わらず、一旦、SPIをdisableにしてからプリスケーラを設定後、SPIをイネーブルにする必要がありました。
 picleソースで書くと

    SPISTAT[0] = $0000;
#   SPISTAT[1] = $7a;    # SPI1CON1 prescale2:1,prescale4:1  = 8:1  2M NG
    SPISTAT[1] = $7d;    # SPI1CON1 prescale1:1,prescale16:1 = 16:1 1M OK
    SPISTAT[0] = $8000;

 こんな感じです。
 コメントに書いたようにブロック書込み/読込み動作が2MHzではNG(DIのデータを取りこぼす)で1MHzではokでした。(PIC24FJのクロックは内蔵の32MHz)
}


CMD0波形

CMD8波形

ACMD41波形(アイドル状態なのでリトライ)

ACMD41波形(0x00のレスポンス(OK))

CMD58波形

CMD24(ブロックライト)波形

CMD24(ブロックライト:データ送信後wait)波形

CMD24(ブロックライト:wait解除され終了)波形

CMD17(ブロックリード)波形

CMD17(ブロックリード:SDカードがパケット送信開始)波形

CMD17(ブロックリード:パケット受信完了)波形


 今回の実験で作成した picleソースは次のとおりです。SRAM上にソースが入りきらなくなってきたのでmain()部分と関数部分を分離し、main()側でフラッシュメモリにセーブした関数ソースをインクルードしています。


実験で使用したソース:関数部分(picle言語)
#LibSpi SPI test to connect SD card for PIC24FJ64GA004 with picle # Ver 0.02 by skyriver 2018/02/08 var SPISTAT,SPIBUF; var _RPINR20,RPOR0; var _REG,AD1PCFG; var TRISA,LATA; var ByteTimer,SdhcFlg; var SpiDat,_Buf; proc init() { SPISTAT = $0240; # SPI1 status SPIBUF = $0248; RPOR0 = $06c0; AD1PCFG = $032c; AD1PCFG[0] = $ffff; # I/O TRISA = $02c0; LATA = TRISA + 4; SPISTAT[1] = $0075; # SPI1CON1 pre 2:3,Post 1:16 = 48:1 333k SPISTAT[2] = 0; # SPI1CON2 SPISTAT[0] = $8000; _RPINR20 = $06a8; _RPINR20[0] = 2; # SDI -> RP2 RPOR0[0] = $0708; # CLK -> RP0, SDO ->RP1 TRISA[0] = TRISA[0] & $fffb; LATA[0] = $0004; _Buf = Array_(0); ByteTimer = 30; } proc SpiCheck() { if ( SPISTAT[0]&1 ) { SpiDat = SPIBUF[0]; } } # wait about 1.8us * n proc TmWait( n ) { for (; n ; n=n-1) { SpiCheck(); } } proc SpiSnd( dat ) { do { SpiCheck(); } while ( SPISTAT[0]&2 ); SPIBUF[0] = dat; } func SpiRcv() { do { if ( (SPISTAT[0]&2) = 0 ) { SPIBUF[0] = $ff; } } while ( (SPISTAT[0]&1) = 0 ); return = SPIBUF[0]; } func SpiRcvAns() { do { return = SpiRcv(); } while ( return = $ff ); } proc SpiRcvN( n ) { var i; for ( i=0; i < n; i=i+1 ) { _Buf[i] = SpiRcv(); } } proc SetCsDisable() { LATA[0] = $0004; TmWait( ByteTimer ); } proc PrnVal( str, val ) { PrnStr_( str ); PrnHex_( val ); } # return 0:NG, 1:OK func BlkRead( sec ) { var ans; LATA[0] = 0; SpiSnd( $51 ); # CMD17 SpiSnd( 0 ); SpiSnd( 0 ); SpiSnd( sec / 256 ); SpiSnd( sec & $ff ); SpiSnd( $ff ); # dummy CRC ans = SpiRcvAns(); if ( ans = 0 ) { ans = SpiRcvAns(); # Data Token if ( ans = $fe ) { var i; for ( i=0; i<128; i=i+1 ) { SpiRcvN( 512 / 128 ); } } SpiRcvN( 2 ); } SetCsDisable(); return = ans = $e5; } # return 0:NG, 1:OK func BlkWrite( sec ) { var i; LATA[0] = 0; SpiSnd( $58 ); # CMD24 SpiSnd( 0 ); SpiSnd( 0 ); SpiSnd( sec / 256 ); SpiSnd( sec & $ff ); SpiSnd( $ff ); # dummy CRC if ( SpiRcvAns() = 0 ) { SpiSnd( $fe ); # send token for ( i = 0; i<512; i=i+1 ) { SpiSnd( i & $ff ); } SpiSnd( $ff ); # dummy CRC SpiSnd( $ff ); return = SpiRcvAns() = $e5; while ( SpiRcv() = 0 ) {} } SetCsDisable(); }


実験で使用したソース:main()部分(picle言語)
# SPI test to connect SD card for PIC24FJ64GA004 with picle # Ver 0.02 by skyriver 2018/02/08 use LibSpi; proc main() { var ans,i; init(); LATA[0] = $0004; for ( i=0; i<10; i=i+1 ) { SpiSnd( $ff ); } TmWait( ByteTimer * 2 ); LATA[0] = 0; SpiSnd( $40 ); # CMD0 SpiSnd( 0 ); SpiSnd( 0 ); SpiSnd( 0 ); SpiSnd( 0 ); SpiSnd( $95 ); ans = SpiRcvAns(); SetCsDisable(); if ( ans <> 1 ) { PrnVal( "Cmd0Res:", ans ); } else { LATA[0] = 0; SpiSnd( $48 ); # CMD8 SpiSnd( 0 ); SpiSnd( 0 ); SpiSnd( 1 ); SpiSnd( $aa ); SpiSnd( $87 ); ans = SpiRcvAns(); SpiRcvN( 4 ); # 16M:00 00 01 aa SetCsDisable(); if ( ans <> 1 ) { PrnVal( "CMD8 err:", ans ); } else { if ( (_Buf[2] <> $01) | (_Buf[3] <> $aa ) ) { PrnStr_("SDC not v2" ); } else { SdhcFlg = 1; do { LATA[0] = 0; SpiSnd( $77 ); # CMD55 SpiSnd( 0 ); SpiSnd( 0 ); SpiSnd( 0 ); SpiSnd( 0 ); SpiSnd( $65 ); ans = SpiRcvAns(); if ( ans = 1 ) { SpiSnd( $69 ); # ACMD41 SpiSnd( $40 ); SpiSnd( $ff ); SpiSnd( $80 ); SpiSnd( $00 ); SpiSnd( $17 ); ans = SpiRcvAns(); } SetCsDisable(); } while ( ans <> 0 ); LATA[0] = 0; SpiSnd( $7a ); # CMD58 SpiSnd( 0 ); SpiSnd( 0 ); SpiSnd( 0 ); SpiSnd( 0 ); SpiSnd( $fd ); ans = SpiRcvAns(); SpiRcvN( 4 ); # 16MB:c0 ff 80 00 SetCsDisable(); if ( ans <> 0 ) { PrnVal( "CMD58 err:", ans ); } if ( BlkWrite( 4 ) ) { if ( BlkRead( 4 ) ) { PrnStr_( "Ok" ); } } } } } LATA[0] = $0004; }


[TOP] [ 前へ ] 連載記事 [ 次へ ]

nice!(0)  コメント(0) 
共通テーマ:趣味・カルチャー

迷惑コメント発生中 [日記]

 やったぁ~。本日のページビューは1千を超えました ^^

 というか、実は数日前から特定のページにアルファベット文字だけの内容でリンクが多数の何かの売込みのコメント書込みが多発しています。

 昨日まではその都度マニュアル操作で消していたんですがそれが気に入らなかった(気に入った?w)のか今朝から頻度が激増しました。

 そうなんです・・・ページビューのほとんどはこのカキコのアクセスが占めてします・・・

 書込み内容を変更しながら自動で書き込んでいるようです。

 このブログは「画像認証」機能があり、コメント書込みの際に画像に書かれた文字を正しく入力する必要があります。
 認証の文字列を読みづらい(と思われる)ものに変更してからは収まっているようですがもう少し様子を見たいと思います。(あまり反応すると増長しそうなのでしばらく放置)

 ん~ 明日のアクセスランキングが楽しみ・・w

nice!(0)  コメント(1) 
共通テーマ:趣味・カルチャー

レトロマイコンZ80ボードの構想(その6)SDカード [PIC]

 前回の記事「レトロマイコンZ80ボードの構想(その5)ピンアサイン」に追記したようにSDカードとのSPI通信の実験をしています。

 picleコンパイラを使ってSDHCタイプのカードの初期化シーケンスが通るようになりました。

 SPIはパラ-シリ変換のICが対向して接続されているような単純なインターフェースでマスター側からクロック提供した場合はデータ有無にかかわらずシフトされるので受信データが発生します(データがない場合は0xff)。

 データ送信の都度、受信データを読みながらやり取りすれば処理的には簡単なのですが、送信バイト間にクロックが停止する隙間ができるのが嫌なので今回は送信データは連続して送信し、受信データは0xff送信(SDカードが送信できるようにクロックを提供)に対応した受信データを確認する(送信バッファにデータを貯めない)方法で処理しました。

 このためには送信データに対する受信データの数(=送信バイト数ー受信バイト数)を管理しておく必要があり、末尾のソース内では SpiCnt でカウントしています。

 また、トランザクション終了後にCSをdisable(high)にしてから1バイトのダミー送信する必要があり、そうしないとSDカード側の送信データのLSBがlowの場合、SPIのデータ線をLowに引っ張り続ける(下図のACMD41のように)ことがあるので、SDカード側のパラ-シリ変換にごみを残さないという意味があるものと思います。

 SDカードとの実際の通信波形はweb上では見当たらなかったので誰かの参考になればと思いロジアナの波形を載せておきます。小さいですがクリックすると拡大表示されます(モバイル環境ではJavaScriptが動かないので大きくなりません^^;)
 使用したSDカードは16MBのものです。

 クロック周波数は333KHzです。(初期化部分は100kHz~400kHzの範囲内であることが必要なようです)

★2018/02/04 23:20 追記 ACMD41波形を追加しました。
★2018/02/10 追記
 改良版の波形を「レトロマイコンZ80ボードの構想(その7)SDカード2に掲載しました。

CMD0波形

CMD8波形

ACMD41波形

CMD58波形


実験に使用したpicleソース
:l 1:# SPI test to connect SD card for PIC24FJ64GA004 with picle 2:# Ver 0.01 by skyriver 2018/02/04 3: 4:var SPISTAT,SPIBUF; 5:var _RPINR20,RPOR0; 6:var _REG,AD1PCFG; 7:var TRISA,LATA; 8: 9:var ByteTimer,SdhcFlg; 10:var SpiCnt,SpiDat,_Buf; 11: 12:proc init() { 13: SPISTAT = $0240; # SPI1 status 14: SPIBUF = $0248; 15: RPOR0 = $06c0; 16: AD1PCFG = $032c; 17: AD1PCFG[0] = $ffff; # I/O 18: TRISA = $02c0; 19: LATA = TRISA + 4; 20: 21:# SPISTAT[1] = $0079; # SPI1CON1 prescale2:2,prescale1:16 = 32:1 500k 22: SPISTAT[1] = $0075; # SPI1CON1 prescale2:3,prescale1:16 = 48:1 333k 23: SPISTAT[2] = 0; # SPI1CON2 24: SPISTAT[0] = $8000; 25: 26: _RPINR20 = $06a8; 27: _RPINR20[0] = 2; # SDI -> RP2 28: RPOR0[0] = $0708; # CLK -> RP0, SDO ->RP1 29: TRISA[0] = TRISA[0] & $fffb; 30: LATA[0] = $0004; 31: 32: _Buf = Array_(0); 33: ByteTimer = 20; 34:} 35: 36: 37:proc SpiCheck() { 38: if ( SPISTAT[0]&1 ) { 39: SpiDat = SPIBUF[0]; 40: SpiCnt = SpiCnt - 1; 41: } 42:} 43: 44: 45:# wait about 2us * n 46:proc TmWait( n ) { 47: var i; 48: for (; n ; n=n-1) { 49:# i = 123 + i; 50: SpiCheck(); 51: } 52:} 53: 54: 55:func SpiRcv() { 56: return = $ff; 57: SPISTAT[0] = $8000; 58: if ( SpiCnt = 0 ) { 59: while ( SPISTAT[0]&2 ) {} 60: SPIBUF[0] = $ff; 61: SpiCnt = 1; 62: } 63: while ( (SPISTAT[0]&1) = 0 ) {} 64: SpiCnt = SpiCnt - 1; 65: return = SPIBUF[0]; 66:} 67: 68: 69:func SpiRcvAns() { 70: do { 71: return = SpiRcv(); 72: } while ( return = $ff ); 73:} 74: 75: 76:proc SpiRcvN( n ) { 77: var i; 78: for ( i=0; i < n; i=i+1 ) { 79: _Buf[i] = SpiRcv(); 80: } 81:} 82: 83: 84:proc SpiSnd( dat ) { 85: do { 86: SpiCheck(); 87: } while ( SPISTAT[0]&2 ); 88: SpiCnt = SpiCnt + 1; 89: SPIBUF[0] = dat; 90:} 91: 92: 93:proc SetCsDisable() { 94: LATA[0] = $0004; 95: SpiSnd( $ff ); 96: TmWait( ByteTimer ); 97:} 98: 99: 100:proc PrnVal( str, val ) { 101: PrnStr_( str ); 102: PrnHex_( val ); 103:} 104: 105: 106:proc main() { 107: var ans,i; 108: 109: init(); 110: 111: LATA[0] = $0004; 112: for ( i=0; i<10; i=i+1 ) { 113: SpiSnd( $ff ); 114: } 115: TmWait( ByteTimer * 2 ); 116: LATA[0] = 0; 117: SpiSnd( $40 ); # CMD0 118: SpiSnd( 0 ); 119: SpiSnd( 0 ); 120: SpiSnd( 0 ); 121: SpiSnd( 0 ); 122: SpiSnd( $95 ); 123: 124: ans = SpiRcvAns(); 125: SetCsDisable(); 126: 127: if ( ans <> 1 ) { 128: PrnVal( "Cmd0Res:", ans ); 129: } else { 130: LATA[0] = 0; 131: SpiSnd( $48 ); # CMD8 132: SpiSnd( 0 ); 133: SpiSnd( 0 ); 134: SpiSnd( 1 ); 135: SpiSnd( $aa ); 136: SpiSnd( $87 ); 137: ans = SpiRcvAns(); 138: if ( ans <> 1 ) { 139: PrnVal( "CMD8 err:", ans ); 140: LATA[0] = $0004; 141: } else { 142: SpiRcvN( 4 ); # 16M:00 00 01 aa 143: SetCsDisable(); 144: if ( (_Buf[2] <> $01) | (_Buf[3] <> $aa ) ) { 145: PrnStr_("SDC not v2" ); 146: } else { 147: do { 148: LATA[0] = 0; 149: SpiSnd( $77 ); # CMD55 150: SpiSnd( 0 ); 151: SpiSnd( 0 ); 152: SpiSnd( 0 ); 153: SpiSnd( 0 ); 154: SpiSnd( $65 ); 155: ans = SpiRcvAns(); 156: if ( ans = 1 ) { 157: SpiSnd( $69 ); # ACMD41 158: SpiSnd( $40 ); 159: SpiSnd( $ff ); 160: SpiSnd( $80 ); 161: SpiSnd( $00 ); 162: SpiSnd( $17 ); 163: ans = SpiRcvAns(); 164: } 165: SetCsDisable(); 166: } while ( ans <> 0 ); 167: LATA[0] = 0; 168: SpiSnd( $7a ); # CMD58 169: SpiSnd( 0 ); 170: SpiSnd( 0 ); 171: SpiSnd( 0 ); 172: SpiSnd( 0 ); 173: SpiSnd( $fd ); 174: ans = SpiRcvAns(); 175: SpiRcvN( 4 ); # 16MB:c0 ff 80 00 176: SetCsDisable(); 177: if ( ans <> 0 ) { 178: PrnVal( "CMD58 err:", ans ); 179: } else { 180: PrnStr_( "SDC V2" ); 181: } 182: } 183: } 184: } 185: LATA[0] = $0004; 186:} :run SDC V2 :


[TOP] [ 前へ ] 連載記事 [ 次へ ]

nice!(0)  コメント(0) 
共通テーマ:趣味・カルチャー
前の5件 | -