SDカードを使ってみよう

by K.I
2005/10/01〜

Index


概要

ふーむ、SPIモードっていうのは、結構単純なのかも。。
[top]

SDカードの仕様

→MMCカードは1〜7だけ使う とにかく、仕様書を読んでみよう。

MMCモード

PIN No. Name Type PIN Description
1 RSV NC Reserved/Allways'L'
2 CMD I/O,PP,ODCommand/Response
3 VSS1 S Ground
4 VDD1 S Power Supply
5 CLK I Clock
6 VSS2 S GND
7 DAT I/O,PP Data
・PP:PushPull, OD:OpenDrain

SPIモード

PIN No. Name Type PIN Description
1 CS I Chip Select(Low active)
2 DI I Data in
3 VSS S Ground
4 VDD S Power Supply
5 SCLK I Clock
6 VSS2 S Ground
7 DO OUT,PP Data out

CRC

CRCは、MMCモードでは必須。

レジスタ

コマンド(SPIモード)

index Argument Resp Abbreviation Command description
CMD0 None R1 GO_IDLE_STATE MMCリセット
CMD1 None R1 SEND_OP_COND カード初期化
CMD9 None R1 SEND_CSD CSD送信要求
CMD10 None R1 SEND_CID CID送信要求
CMD13 None R2 SEND_STATUS STATUS送信要求
CMD16 32bit R1 SEND_BKICKLEN ブロック長(byte数)
CMD17 32bit R1 READ_SINGLE_BLKブロック読出し
CMD24 32bit R1b WRITE_BLOCK ブロック書込み
CMD27 None R1b PROGRAM_CSD CSD programable bit設定
CMD28 32bit R1b SET_WRITE_PROT 書込みプロテクト
CMD29 32bit R1b CLR_WRITE_PROT クリア書込みプロテクト
CMD30 32bit R1 SEND_WRITE_PROTプロテクトSTATUS要求
CMD32 32bit R1 TAG_SECT_START 消去選択最初のブロック
CMD33 32bit R1 TAG_SECT_END 消去選択最後のブロック
CMD34 32bit R1 UNTAG_SECTOR 消去選択前の1セクタ消去
CMD35 32bit R1 TAG_ERASE_G_SEL消去選択最初のグループ
CMD36 32bit R1 TAG_ERASE_G_END消去選択最後のブロック
CMD37 32bit R1 UNTAG_ERASE_GRP消去選択前の1グループ消
CMD38 32bit R1b ERASE 選択されたセクタ消去
CMD42 32bit R1b LOCK/UNLOCK パスワード設定・解除
CMD39 32bit R1 CRC_ON_OFF CRCオプションON/OFF

レスポンス(MMCモード)

レスポンス(SPIモード)

SPIモードでは、R1,R2の2種類のレスポンスがある。
No各ビットの意味
0常に0
1Card is locked
2wp erase skip lock/unlock cmd failed
3error
4CC error
5card ecc failed
6wp violation
7erase param
8out of range
9in idle state
10erase reset
11illegal command
12com crc error
13erase sequence error
14address error
15parameter error

データトークン

MMCはデータの送受信にデータトークンを使う。
[top]

読み書きの手順

スタートアップ

ブロック読出し

← 0XXXXXXX ← 11111110 DDDDDDDD DDDDDDDD ..512byte.. DDDDDDDD DDDDDDDD CCCCCCCC CCCCCCCC

ブロック書込み

← 0XXXXXXX ← 00000000 ...書込み完了までビジートークンを返す。'1'になるまで待つ必要がある ← 0XXXXXXX
1このCRCの値は、自分のCRC7プログラムで求めたんだけど、合ってるのかなぁ?

[top]

PSoCのSPIモジュール

SPIモード

Mode SCLK Edge クロック極性 説明
0 Leading Non-Inverting Leadingエッジでラッチ、
1 Leading Inverted 変化させる
2 Trailing Non-Inverting Trailingエッジでラッチ
3 Trailing Inverted 変化させる

API

SPIM API 意味
SPIM_Start 起動、(モード設定、LSB/MSB first指定)
SPIM_Stop 停止
SPIM_EnableInt 割込み許可
SPIM_DisableInt 割込み禁止
SPIM_SendTxData 1byte送信
SPIM_bReadRxData 1byte受信(受信データはDxBxxDR2?)
SPIM_bReadStatus SPIMステータスを返す

テストプログラム


[top]

とにかく動かしてみよう。

接続

LCDが表示されない?

って、ところか。

PSoCに書き込めない。。

SPIM動作確認

読めるかな?

W%lcome to PSoC MMC program
SPIM initial sdquence
send CMD0 change SPI mode
send CMD1 & wait response is ready

CMD17 00000000

FFF8000000FFFFFFFFFFFF0000001FFF
FFFFFFFF000000FFFFFFFFFFFFFF0000
00FFFFFFFFFF8000001FFFFFFFFFFF0000FFFFFFFFFFFFFF000000FFFFFFFF
FFFC00001FFFFFFFFFFFFF0000007FFF
FFFFFFFF000000FFFFFFFFFFFF800000
07FFFFFFFFFF0000007FFFFFFFFFFFFF
0000FFFFFFFFFFFF80000003FFFFFFFF
FF0000007FFFFFFFFFFFFF000000FFFF
FFFFFF80000000FFFFFFFFFF
F000000
3FFFFFFFFFFF000000FFFFDFFFFFFF80
0000FFFFFFFF0000000FFFFFFFFF
FF000000FFFFFFFFFFFF00000000FFFF
FFFFFF00000007FFFFFFFFFFFE000000
7FFFFFFFFF00000000FFFFFFFFFFFF00
0000FFFFFFFFFFFC0000007FFFFFFFFF
FF000000FFFFFFFFFFFF00000000FFFF
FFFFFC0000003FFFFFFFFFFF00000000
FFFFFFFFFF00000000FFFFFFFFFFF800
0000FFFFFFFFFF000000007FFFFFFFFF
FF0000000007FFFFFBFFFFF00000000
FFFFFFFFF000000003FFFFFFFFFF0000
0003FFFFFFFFFF00000000FFFFFFFFFF
F0000000FFFFFFFFFF000000003FFFFF
FFFF00000000FFFFFFFDFFE000000000
FFFFFFFF000000001FFFFFFFFFFF0000
001FFFFFFFFFF000000000FFFFFFFFFF
00000007FFFFFFFFFF000000007FFFFF
FFFF00000000FFFFFFFFFF0000000003
FFFFFFFF000000007FFFFFFFFFE00000
007FDFFFFFFF0000000000FFFFFFFFFF

CMD17 00000000

00000000FFFFFFFFFF000000000FFFFF
FFFF000000007FFFFFFFFF0000000000
FFFFFFFF0000000003FFFFFFFFF00000
0003FFFFFFFF0000000000FFFFFFFFFF
00000003FFFFFFFFF0000000007FFFFF
FFE000000000FFFFFFFFFF0000000000
FFFFFFC0000000003FFFFFFFFF000000
003FFFFFFFFF0000000000FFFFFFFFF0
0000001FFFFFFFFF00000000007FFFFF
FF0000000000FFFFFFFFC0000000000F
FFFFFF00000000007FFFFFFFFF000000
007FFFFFFFE00000000007FFFFFFFF00
0000007FFFFFFFFF0000000000FFFFFF
FF0000000001FFFFFFFF00000000003F
FFFFFF0000000000FFFFFFFFE0000000
00FFFFFFFF00000000001FFFFFFFFF00
000000FFFFFFFFC00000000000FFFFFF
FF000000000FFFFFFFFF0000000000FF
FFFFE00000000000FFFFFFFF00000000
00FFFFFFFF00000000007FFFFFFFC000
000000FFFFFFFF000000000003FFFFFF
FF000000007FFFFFFFE00000000000FF
FFFF000000000003FFFFFFFF000FFFE00000000000FFFFFFFF0000
000000FFFFFFFF00000000003FFFFFFF
E000000000FFFFFFFF000000000000FF
FFFF00000000003FFFFFFFE000000000
00FFFFFF000000000000FFFFFFFF0000
00000FFFFFFFE0000 000000FFFFFFFF
0000000000FFFFFFFF000000000007FF
FFFF00000000007FFFFFFF0000000000
00FFFFFF000000000003FFFFFFE00000

CMD17 00000020

000000FFFFFFF000000000001FFFFFFF
00000000007FFFFFFF000000000000FF
FFFF00000000000FFFFFFF0000000000
00FFFFFF000000000000FFFFFFF00000
00000FFFFFFF0000000000007FFFFFFF
0000000000FFFFFFF8000000000003FF
FFF000000000007FFFFFFF0000000000
00FFFFF8000000000003FFFFFF000000
00007FFFFFFF000000000000FFFFFFFC
0000000000FFFFFF0000000000003FFF
FF000000000000FFFFFFF80000000000
00FFFF0000000000003FFFFFFF000000
0000FFFFFFFC000000000000FFFFFF00
000000000FFFFFFF0000000000007FFF
FF000000000000FFFFFF000000000000
07FFFF0000000000007FFFFFF8000000
0000FFFFFF00000000000003FFFFFF00
000000007FFFFFF8000000000000FFFF
FF000000000001FFFFFF000000000000
7FFFFC000000000000FFFFFF00000000
0000FFFFFF0000000000003FFFFFFC00
00000000FFFFFF00000000000000FFFF
FF00000000001FFFFFFE000000000000
7FFF00000000000000FFFFFF00000000
0000FFFFFC000000000000FFFFFF0000
00000000FFFFFF0000000000000FFFFF
FE0000000000FFFFFF00000000000000
FFFF00000000000007FFFFFC00000000
0007FFFF00000000000000FFFFFF0000
00000003FFFFFE0000000000007FFFFF
000000000000FFFFFF00000000000001
FFFF0000000000003FFFFF0000000000````````````
0000FFFFFFFFFFF800000007FFFFFFFF

挙動不審

const char CMD0[] = {6,0x40,0x00,0x00,0x00,0x00,0x95};
const char CMD1[] = {6,0x41,0x00,0x00,0x00,0x00,0xf9};
       
char SPIM_IO(data) {
        while(!(SPIM_1_bReadStatus() & SPIM_1_SPIM_TX_BUFFER_EMPTY));
        SPIM_1_SendTxData( data );
        while (!(SPIM_1_bReadStatus() & SPIM_1_SPIM_RX_BUFFER_FULL)); 
        return (SPIM_1_bReadRxData()); 
}

void cmmc_cmd(const char *ccmd)
{
    char *p,*cmd;
    cmd = (char*)ccmd;
    for (p=cmd+1; p<=cmd+*cmd ;p++)
      SPIM_IO(*p);
}

void mmc_init(void)
{
        int     i;
        SPIM_1_EnableInt();
                 
// ---- SPIM initial sequence
        PRT0DR |= 0x02;                 // CS='H'
        SPIM_1_Start(SPIM_1_SPIM_MODE_0 | SPIM_1_SPIM_MSB_FIRST);
        for (i=0; i<10 ;i++)
                SPIM_IO( 0xFF );        // send 80clock
        PRT0DR &= ~0x02;                // CS='L'
        UART_1_CPutString("send SPIM initial clock\r\n");

// ---- send CMD0 change SPI mode
        cmmc_cmd(CMD0);
        i = 0;
        while (SPIM_1_bReadRxData() != 0x01)    // wait response 0x01
                if (i++>100) break;
        if (i<1000) UART_1_CPutString("send CMD0 & response 0x01\r\n");

//---- send CMD1 & wait response is ready
        cmmc_cmd(CMD1);
        i = 0;
        while (SPIM_1_bReadRxData())    // wait response 0x00
                if (i++>100) break;
        if (i<1000) UART_1_CPutString("send CMD1 & response 0x00\r\n");
}


2「はじめてのPSoC」の回路を基にしてる。

[top]

参考

いろいろ参考にさせてもらいました。感謝。
3SDカードは契約しないと資料は見れないらしい。


comments powered by Disqus