« ArduinoでXMLを解析する | トップページ | Arduino RSSリーダー »

SPIデバイスの混在とSS信号の初期状態

自作のGLCDシールドにて突然一部の漢字が表示できなくなる事象に何回か遭遇しました。漢字フォントを格納したSPI Flash memory(AT45DB161D)の内容をダンプするとページ単位でall-FFに初期化されています(データーが残っているページもあります)。なにやら、ページ・セクター単位で消去が動いたような状態です。この問題の原因と対策について考えてみました。

問題の発生トリガー

時間の関係で事象を再現させる試験はできていませんが、以下の状況で消去が発生しているように見えます:

  • Ethernet shield互換のWIZ812MJとSPI Flash memory双方を基板に搭載して通電している(以下、ここではWIZ812MJをEthernet shieldと記載)
  • Ethernet shieldのライブラリのみ使用して、Ethernet関連の試験を行った(SPI Flashは初期化を行っていない)
  • SPI Flash memoryのSS(CS)信号入力は、以下の回路図に示す通り、汎用I/OのPL0(PORTL bit0)を使用している

Glcd_shield2

すなわち、MCUに対してPL0の制御レジスタ設定を行っていない(リセット時の初期状態のままにしている)ため、SPI Flashから見るとSS(CS)信号が有効に見えてしまうことを疑っています。想定される問題の発生メカニズムは以下です:

  • Ethernet shieldへのデーター書き込みを行うと、SCK/MOSIが駆動される
  • このとき、SPI FlashのSS(CS)がLowレベルに見えてしまう
  • Ethernet shieldとSPI Flashの両方が選択されてしまい、Ethernet shieldへのコマンドがSPI Flashへのページ・セクタ消去コマンドと誤認識された(こんな偶然の一致があるのだろうかと思いますが)

上記の仮定が成り立つかは、SS信号ピンの初期状態に依存します。

AVRにおけるSS信号ピンの初期状態

データーシートには以下の記載があります:

  1. SPIを有効にすると、SS/MOSI/MISO/SCKの入出力方向をSPIモード用に設定する
  2. MCUをMasterに設定すると、SS信号の入出力方向はユーザーのDDRBレジスタ設定に従う

1項の「SPIを有効にする」とは、SPCRレジスタのSPE(bit6)を1にすることだと思います。リセット時の初期状態ではSPEは0(SPI無効)となります。この場合のSS信号ピンの方向性や出力レベルはどうなるのでしょうか。SS信号を収容するPORTBは汎用I/Oとして機能すると考えられます。汎用I/Oの初期状態は入力ポートでハイインピーダンス状態になります。

以下の試験スケッチを使って、リセット時のSS信号ピン(PB2)電圧を測りました(測定器はテスターを使用)。MCUはATmega328(Arduino nano)を使用。

1) SPCRを設定しない(SPI無効): SS = 0.4V
 → PORTBは入力ポート(Hi-z)として動作

2) SPE=1, MSTR=1(マスター): SS = 0.4V
 → PB2のDDRを設定していない→ 入力として動いていると思われる

3) SPE=1, MSTR=1, DDRB=4, PORTB=4:SS = 4.7V(HIGH)
 → PB2を明示的に、出力・HIGHに設定

上記の1)はSPIライブラリの初期化ルーチンを実行していない状態に相当し、この場合MCUのSSピンに接続されたSPIデバイスはLOW入力(選択状態)と等価になると思われます。冒頭の回路図に示したSPI FlashのSS(CS)入力は汎用I/Oで制御しているため、リセット直後は入力ポート状態となり上記1)と同様になります。このためライブラリの初期化ルーチンを実行していない状態では問題の発生条件が成立すると言えます。

対策

Ethernet shieldに加えてSPI Flash memoryもライブラリ経由で初期化を行えば、SS信号ピンにHighを出力するため問題が発生することはありません。Ethernetのみを使用する場合でも必ずSPI Flash memory(AT45DB161D)の初期化を行うようにすればよのですが、忘れてしまいそうです。

そのため、SS信号を5Vにプルアップしました。Ethernet shiedのみを動作させる試験を少し行った範囲では、Flash memoryの誤消去は発生しておらずうまく動いているようです。ハード・ソフトのどちらの責任で初期設定を行うかを設計仕様として決める必要があることを意味し、なかなか奥が深いです。大規模開発では重要なポイントになります。このプロジェクトは個人レベルの日曜大工なので、行き当たりばったりでやっていますが、、、

« ArduinoでXMLを解析する | トップページ | Arduino RSSリーダー »

Arduino」カテゴリの記事

コメント

基本的にSPIデバイスのSS入力にはプルアップを入れておいた方が良いかと思われます。
デバイスによってはSSが不定だと省電力モードに入れなかったりしますし。

いつもありがとうございます。
なるほど、省電力モード移行のトラブルもあるのですね。SPIやI2CといったシリアルインタフェースはArduinoで初めて触ったのですが、結構楽しめました。

この記事へのコメントは終了しました。

« ArduinoでXMLを解析する | トップページ | Arduino RSSリーダー »

2018年10月
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
無料ブログはココログ