マイクロビット(c_08)SDカード初期化 用モジュール
SDカードモジュール(SPI) SDC_INIT_c.py
2GB以下(MMC)とSDHC(2GB超~32GB)SDカードの初期化で使う自作の’SDC_INIT_c.py’を作成しました。使い方だけを記載します。(※記事e_022を元にクラスにしました。)
‘SDC_INIT_c.py’は末尾にあります。
使い方
ファイル転送
micro:bitへ’SDC_INIT_c.py’を送った後でimportして使います。micro:bitに直接ファイルをアップロード出来ない場合(Thonny 3.1.12など)は、microfsなどを使ってアップロードします。
※microfsについては、当サイト内のこちらを参照ください。
※ファイルシステムへ送って使わないとメモリーエラーになると思います。(micro:bit V1)
メソッド
‘SDC_INIT_c’をimportすると「SDC_init, SDC_cmd00, SDC_cmd01, SDC_cmd08, SDC_acmd41, SDC_end」のメソッドが使えるようになります。
SDC_INIT()で初期化します。CS(chip select)と接続するmicro:bitのpinを指定して初期化します。defaltはpin8です。
(01)SDC_init()
ダミークロックを’0xff’を80個送りspi通信にします。CSをLowにしてデバイスを選択します。
(02)SDC_cmd00()
cmd0(GO_IDLE_STATE)コマンドを送ります。
(03)SDC_cmd08()
cmd8(SEND_IF_COND)コマンドを送ります。
(04)SDC_acmd41()
cmd55(APP_CMD)に続けてacmd41(SD_APP_OP_COND)コマンドを送ります。
SDHCの初期化に使うコマンドのようです。
(05)SDC_cmd01()
cmd1(SEND_OP_CND)コマンドを送ります。2GB以下のSDカードの初期化に使うようです。
(06)SDC_end()
CSをHighにしてデバイスを非選択にします。
使用例
2GB以下(MMC)とSDHC(2GB超~32GB)の初期化をしてみました。
SDC_INIT_ex.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from microbit import *
#SDC_INIT_c.py
from SDC_INIT_c import *
import sys
## example ------------------
# SPI init bps=100kHz
spi.init(baudrate=100000, bits=8, mode=0, sclk=pin13, mosi=pin15, miso=pin14)
sleep(10)
a=SDC_INIT()
## SDHC or MMC INIT START
a.SDC_init()
##CS(0)
a.SDC_cmd00()
a.SDC_cmd08()
a.SDC_end()
実行結果
standard SD 1GBの初期化
>>> %Run SDC_INIT_ex.py
START CLK>80
cmd0 OK resp=0x01
CMD8 R7-5bytes >> b'\xff\xff\xff\xff\xfe'
CARD ERROR >> MMC(Standard)
cmd0 OK resp=0x01
cmd1 OK resp=0x00
MMC_INIT
>>>
SDHC16GBの初期化
>>> %Run SDC_INIT_ex.py
START CLK>80
cmd0 OK resp=0x01
CMD8 R7-5bytes >> b'\x01\x00\x00\x01\xaa'
CMD8 0x01 or 0x00 >>> 1
CMD55 Pass 0x01 >>>
ACMD41 0x01 RETRY b'\x01'
CMD55 Pass 0x01 >>>
ACMD41 Pass 0x00 b'\x00'
SDHC_INIT
>>>
モジュール
SDカードの初期化用モジュール
SDC_INIT_c.py
from microbit import *
import sys
# ------------------------INIT (SDC 2GB<)---- CMD0>>CMD8>>CMD55>>ACMD41
# ------------------------INIT (SD MMC <=2GB) CMD0>>CMD1
# command
# cmd0=0x40 GO_IDLE_STATE
# cmd1=0x41 SEND_OP_CND
# cmd8=0x48 SEND_IF_COND
# cmd55=0x77 APP_CMD
# acmd41=0x69 SD_APP_OP_COND
class SDC_INIT:
def __init__(self,pins=pin8):
# micro:bit pin8 for CS active(0)
self.CS_pin=pins
# card send data
def spi_cmd(self,cmd,da1,da2,da3,da4,crc):
buf=bytearray(6)
buf[0]=0x40+cmd
buf[1]=da1
buf[2]=da2
buf[3]=da3
buf[4]=da4
buf[5]=crc
spi.write(buf)
return buf
# dummy 8clk
def spi_ff(self):
spi.write(b'\xff')
# chip select active(0)
def CS(self,dat):
self.CS_pin.write_digital(dat)
# SDCの初期化 Initialization sequence
def SDC_init(self):
print('START CLK>80')
self.CS(1) #CS=Hでダミークロックを80個送信(74個<)
for i in range(10):
self.spi_ff()
self.CS(0)
# ---------------------------------------------------------- CMD00
def SDC_cmd00(self):
#print('CMD0')
#cmd0=0x40 #GO_IDLE_STATE
self.spi_ff()
self.spi_cmd(0,0x00,0x00,0x00,0x00,0x95)
while True:
self.spi_ff()
res=spi.read(1) # response
#print('response=',res)
if res== b'\x01':
print('cmd0 OK resp=0x01')
break
# ---------------------------------------------------------- CMD08
def SDC_cmd08(self):
#print('CMD8')
# cmd8=0x48(SEND_IF_COND)
self.spi_ff()
self.spi_cmd(8,0x00,0x00,0x01,0xAA,0x87)
self.spi_ff()
# R7(5bytes)=R1+4bytes
res=spi.read(5) #response
print('CMD8 R7-5bytes >>',res)
if (res[0]== 0x01) or (res[0]== 0x00):
print('CMD8 0x01 or 0x00 >>>',res[0])
self.SDC_acmd41()
else:
print('CARD ERROR >> MMC(Standard) ')
#sys.exit()
self.SDC_cmd00()
self.SDC_cmd01()
print('MMC_INIT')
def SDC_acmd41(self):
while True:
# ---------------------------------------------------------- CMD55 APP_CMD
#print('CMD55')
# cmd55=0x77(APP_CMD)
self.spi_ff()
self.spi_cmd(55,0x00,0x00,0x00,0x00,0x01)
self.spi_ff()
res=spi.read(1) #response
if res == b'\x01':
print('CMD55 Pass 0x01 >>>')
else:
print('CMD55 ERROR EXIT')
sys.exit()
# ---------------------------------------------------------- acmd41
#print('ACMD41')
# acmd41=0x69(SD_APP_OP_COND)
self.spi_ff()
self.spi_cmd(41,0x40,0x00,0x00,0x00,0x01)
self.spi_ff()
res=spi.read(1) #response
if res == b'\x01':
print('ACMD41 0x01 RETRY', res)
if res == b'\x00':
print('ACMD41 Pass 0x00', res)
print('SDHC_INIT')
break
#CS(1)
#spi_ff()
# ---------------------------------------------------- CMD01 SEND_OP_CND
def SDC_cmd01(self):
#print('CMD01')
while True:
#cmd1=0x41(SEND_OP_CND)
self.spi_ff()
self.spi_cmd(1,0x00,0x00,0x00,0x00,0x01) # CMD>>0xFF out>>read response
self.spi_ff()
res=spi.read(1) # response
#print('response=',res)
if res== b'\x00':
print('cmd1 OK resp=0x00')
break
#END
def SDC_end(self):
self.spi_ff()
self.CS(1)
self.spi_ff()