Teensy4.0でSDXCカード/exFATを使う (SDIO編)

2020年12月13日日曜日

Teensy 4.0

t f B! P L

Teensy4.0ボードに関しては以前記事にて紹介した通り、SDIOインターフェイスのサポートが大きな特徴の一つです。Teensy4系ではTeensy4.1というmicrosdカードスロットを搭載したボードもリリースされているのですがボードのサイズが大きくなってしまいます。Teensy4.0の小型サイズは捨てがたい魅力なのでTeensy4.0ボードにmicrosdカードを接続する方法を試行錯誤を含めてレポートします。またexFATフォーマットの大容量のSDXCカードのアクセステストについても記載します。

SDIOインターフェイス

マイコンボードではSDカードを接続する場合、SPIが一般的ですが、Teensy4.0では4bit SDIOインターフェイスをサポートします。SDIO関連のピンはTeensy4.0の裏面に表面実装ランドとして設けられています。
SDIO関連ピン
もともとは、Teensy4.0のBreakout Board向けのフレキ配線用のコネクタを実装するために設けられたランドのようで、microsdカードのピンの配置と同じ順序で並んでいます。

microsdカードコネクタとの接続

Breakout Boardを使用せずにmicrosdカードスロットを接続しようとする場合、以下の2点をクリアする必要があります。
  • Teensy4.0側のピンピッチは1.0mmであるのに対し、microsdカードのピンピッチは1.1mmである点
  • microsdカードスロットをランド上に直接ピン配置の向きのまま配置しようとするとカード挿入口がTeensy4.0ボードの内向きになる点
このうち前者のピッチの違いについてはあまり良い方法ではありませんが強引に1.0mmピッチを1.1mmピッチに接続する方法で対処することとしました。 microsdカードは8ピンなので、中心に配置した場合1ピンあたり0.1mmのピッチ差が端のピンまで累積して0.35mmずれることになりますが、ランド幅にもよりますがなんとか無理やりはんだ付けすることができます。
後者の向きの問題に対しては、以下の[A], [B] 2つの方法を試しました。

[A] ヒンジ型のmicrosdカードコネクタを使用

通常のロック式のmicrosdカードコネクタではなく、以下のような上面が解放するヒンジ型のmicrosdカードコネクタを使用します。
https://www.marutsu.co.jp/GoodsListNavi.jsp?path=&q=DM3CS
microsdカードのピン以外の部分はポリイミドテープで絶縁してはんだ付けしましたが、それだけではコネクタが浮いてしまうので足の部分をエポキシを使って固定するようにしました。 このコネクタを使用すればmicrosdカードの向きが内向きになってもカードの着脱が可能となります。
ヒンジ型microsdカードコネクタの実装
良い点
  • Teensy4.0ボードのサイズを損なうことなくmicrosdカードを取り付けることができる。
  • Teensy4.0ボードとmicrosdカード端子との配線が最短となる。
悪い点
  • 着脱するにはTeensy4.0ボード裏面の空間を開けておく必要がある。あるいは装着して組み込んだらカードは外さない運用をする。
サイズの点では非常に良いですが、microsdを抜き差しするような普通の使用方法がやりにくい、あるいはできない点がかなり致命的ではあります。

[B] フレキコネクタ・配線を使用

通常のロック式のmicrosdカードコネクタを使用したい場合は一旦フレキ配線でピンを引き出してmicrosdカードコネクタを接続する方法をとります。 Teensy4.0側は1.0mmピッチのフレキコネクタを接続しても良いですし、直接フレキをはんだ付けする方法もあると思います。 1.1mmピッチのmicrosdカードコネクタと1.0mmピッチのフレキを接続する部分でピッチ差ありの接続をする必要があります。今回は8ピンのフレキケーブルとコネクタが手に入らなかったので10ピンを使用しました。
フレキケーブルを利用した接続
良い点
  • 通常のロック式のmicrosdカードスロット等、任意のカードスロットコネクタを使用することができる
  • microsdカードスロットの配置の自由度が上がる
悪い点
  • 部品点数と作業の手間が増える
  • Teensy4.0ボードと別にmicrosdカードコネクタを配置するための空間が必要になる

[C] その他の方法

以下のURLにはmicrosdカードとのその他様々な接続方法が報告されています。
https://forum.pjrc.com/threads/58126-Optimal-microSD-pins-on-the-Teensy-4-0
SDカードの変換アダプタを利用する方法は手っ取り早く手持ちの部材で接続できる方法として良さそうです。

SDXCカード exFATのテスト

64GB以上のSDXCカードを使用する場合はファイルシステムも必然的にexFATを使用することになります。(ツールを使用して無理やりFAT32フォーマットする手があるにはありますが。)exFATをサポートするライブラリとしては、ベータ版ではありますがSdFatライブラリがexFAT対応かつTeensyシリーズのSDIO接続もサポートしています。ここではSdFatベータ版を使用したアクセステストの方法を紹介します。

テストに使用したカード

テストに使用したカードの情報を記載しておきます。
  • SanDisk microSDXC Ultra A1 64GB (UHS-I Speed-class 1)
  • SanDisk microSDXC Ultra A1 512GB (UHS-I Speed-class 1)
  • SanDisk microSDXC Extreme A2 1TB (UHS-I Speed-class 3)
テストに使用したカード
なおmicrosdカードをフォーマットする際には、OS付属のフォーマットツールではなくSD Assosiationから配布されているSD Memory Card Formatterを利用するのが良いようです。

SdFatのベータ版ダウンロード

まず、以下からSdFatのベータ版をダウンロードします。
https://github.com/greiman/SdFat-beta
Arduino環境で使用する場合はフォルダ名をSdFatとして、C:\Users\%username%\Documents\Arduino\libraries\以下に配置します。

テストで使用するプロジェクト

カード認識やアクセススピードの確認に以下のプロジェクトを用います。
  • カード認識用 - examples/SdInfoプロジェクト
  • アクセススピードのベンチマーク用 - examples/benchプロジェクト
benchプロジェクトでは、exFATフォーマットカードを扱うためにbench.inoの冒頭部分でSD_FAT_TYPEを3に設定して使用します。
// SD_FAT_TYPE = 0 for SdFat/File as defined in SdFatConfig.h,
// 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT.
// #define SD_FAT_TYPE 0
#define SD_FAT_TYPE 3
いずれもArduino環境にてコンパイルして、動作確認はシリアルモニタ上で行います。
参考までに64GBカードにてSdInfoプロジェクトを実行した場合のログを記載します。
===================================
SdFat version: 2.0.3-beta.1
Assuming an SDIO interface.

type any character to start
init time: 20 ms

Card type: SDXC

Manufacturer ID: 0X3
OEM ID: SD
Product: SD64G
Version: 8.5
Serial number: **********
Manufacturing date: *****

cardSize: 63864.57 MB (MB = 1,000,000 bytes)
flashEraseSize: 128 blocks
eraseSingleBlock: true

OCR: 0XC0FF8000

SD Partition Table
part,boot,bgnCHS[3],type,endCHS[3],start,length
1,0X0,0XA,0X9,0X2,0X7,0XFE,0XFF,0XFF,32768,124702720
2,0X0,0X0,0X0,0X0,0X0,0X0,0X0,0X0,0,0
3,0X0,0X0,0X0,0X0,0X0,0X0,0X0,0X0,0,0
4,0X0,0X0,0X0,0X0,0X0,0X0,0X0,0X0,0,0

Scanning FAT, please wait.

Volume is exFAT
sectorsPerCluster: 256
clusterCount:      486992
freeClusterCount:  486948
fatStartSector:    49152
dataStartSector:   65536
===================================

エラーが発生する場合の調整箇所

さて、このカード認識やカードアクセステストが上手く動作しない場合、あるいは時々失敗する場合は、私が経験した限りではすべてSDIO関連ピンのドライブ能力の調整で対応ができました。 具体的にはSdFatライブラリのsrc/SdCard/SdioTeensy.cppの以下の部分(300行目付近)を修正します。
  const uint32_t CLOCK_MASK = IOMUXC_SW_PAD_CTL_PAD_PKE |
#if defined(ARDUINO_TEENSY41)
                              IOMUXC_SW_PAD_CTL_PAD_DSE(1) |
#else  // defined(ARDUINO_TEENSY41)
                              IOMUXC_SW_PAD_CTL_PAD_DSE(4) |  ///// WHG (ここの数値を1, 2などにしてみる)
#endif  // defined(ARDUINO_TEENSY41)
                              IOMUXC_SW_PAD_CTL_PAD_SPEED(2);

この部分ではSDIOのクロック線とデータ線4bitのIOのドライブ能力を設定しています。 Teensy4.0ではおそらくBreakout Boardを想定したIOのドライブ能力4が設定されているのですが、今回上記で説明した接続方法(特に[A])ではドライブ能力が強すぎてカードの種類によってはアクセス不良が発生することがあったので、Teensy4.1相当のドライブ能力1または2に設定すると安定して動作させることができました。同容量のSpeed Class違いを試していないので確実なことは言えませんが、SDXCのSpeed Classが上がるとドライブ能力の設定もシビアになるようです。(Speed Class1の512GBカードではDSE値4でも動作するが、Speed Class3の1TBカードではエラーになる。)

benchプロジェクトの実行結果

最後にbenchプロジェクトの実行結果を記載しておきます。microsdの配線方法は[A]と[B]で、ドライブ能力DSE値は[A]: 1, [B]: 2で設定しました。[B]のフレキケーブル長さは約5cmです。 UHS-I Speed Class 1 or 3のフル性能には及びませんが、SPI接続と比べてほぼ5倍のアクセススピードが出ています。
================================
[A] IOMUXC_SW_PAD_CTL_PAD_DSE = 1
(Sandisk SDXC microsd Ultra 64GB)
================================
write speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
21275.23,3384,22,23
20323.90,11178,22,24

read speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
22622.99,23,22,22
22725.82,23,22,22

================================
[A] IOMUXC_SW_PAD_CTL_PAD_DSE = 1
(Sandisk SDXC microsd Ultra 512GB)
================================
write speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
19683.78,11643,22,24
21737.74,1070,22,23

read speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
22622.99,23,22,22
22725.82,23,22,22

================================
[A] IOMUXC_SW_PAD_CTL_PAD_DSE = 1
(Sandisk SDXC microsd Extreme 1TB)
================================
write speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
21095.70,4115,22,23
20574.81,10456,22,24

read speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
22622.99,23,22,22
22725.82,23,22,22

================================
[B] IOMUXC_SW_PAD_CTL_PAD_DSE = 2
(Sandisk SDXC microsd Ultra 64GB)
================================
write speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
21643.64,2109,22,23
21457.85,1912,22,23

read speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
22725.82,23,22,22
22622.99,23,22,22

================================
[B] IOMUXC_SW_PAD_CTL_PAD_DSE = 2
(Sandisk SDXC microsd Ultra 512GB)
================================
write speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
20406.86,10533,22,24
21007.06,9672,22,23

read speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
22622.99,23,22,22
22725.82,23,22,22

================================
[B] IOMUXC_SW_PAD_CTL_PAD_DSE = 2
(Sandisk SDXC microsd Extreme 1TB)
================================
write speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
21007.06,4986,22,24
21275.23,4924,22,23

read speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
22622.99,23,22,22
22725.82,23,22,22
(以上)

自己紹介

自分の写真
電子工作&プログラミング、オーディオ・音楽

注目の投稿

Raspberry Pi Pico Wで電波時計を合わせる (JJY標準電波エミュレータ)

Raspberry Pi Pico Wのアプリケーションとして 最少の周辺部品で電波時計むけJJYエミュレータ(時刻合わせ用)を製作しました。 ※2023年6月6日: ソースコード修正の内容を反映させました。 時刻合わせ風景 概要 電波時計は電波が届くところで使...

QooQ