ESP8266のSPI通信周りをオシロで確認した

ESP8266に手を出したワケ

今まで作ってきたボードはRaspberry Pi前提で、車両からCANデータを取得するものでした。ちょっと回路の間違いはあったけど一応動いている。でも、ボード単体でCANデータを送信できるようにしたり、ちょっとした解析ができれば、便利ではないかと思った。それには通信機能がついているマイコンが必要だ。

ESP WROOM-02開発ボード

ここ1年くらいで急速に盛り上がってきたESP8266というWiFiチップがある。WiFiチップと言っても、Arduino IDEで開発できる単体マイコンでもあるから、他にマイコンは要らないわけだ。チップ単体だと500円を切っており、ヘタにArduinoボードを買うより安いというのも痺れる。

前回まで作っていたCANボードの搭載チップMCP2515はSPI接続だから、ESP8266のSPI APIを使おうとしたのです。

動かない・・・

ところが動かないんだなこれが。Arduino用のMCP2515ライブラリをESP8266で動くように移植していたのだが、テコでも動かない。レジスタも読めない。

ESP8266にはSPIとHSPIという2種類があるようなのだが・・・世間様の情報を見ても、なぜ2つあるのか全くわからなかったのだ。また、SPIにはArduino SDKでサポートされているArduino互換のSPI APIと、MetalPhreak: ESP8266_SPI_Driverの2種類あるのもなぞだった。
たまらず先人に質問したりしたのだが、接続等も間違っていないようだし。これはソフト的な問題なのか、それともチップ内部で使っているSPI接続(フラッシュメモリ)との競合なのか、などとと謎は増すばかり。

しかし、基板まで作っておいて手元にはテスター以外の計測器がなく・・・「わからないときはモノに聞け!」とばかりに宮仕え先のオシロをひっぱりだしてしまった。

ESP8266のSPI通信周りをオシロで確認した

まず、疑ったのはSPIのモード。SPI通信には4種類のモードがある。mbedのSPIマスターのWikiがまとまっている。Arduino ESP8266 SDKの標準SPIだとMODE0しかサポートしていないそうなので、MetalPhreak: ESP8266_SPI_Driverを使ってテストした。

ヘッダファイルのコメントには、

///////////////////////////////////////////////////////////////////
//
// Function Name: spi_mode
// Description: Configures SPI mode parameters for clock edge and
 clock polarity.
// Parameters: spi_no - SPI (0) or HSPI (1)
// spi_cpha - (0) Data is valid on clock leading edge
// (1) Data is valid on clock trailing edge
// spi_cpol - (0) Clock is low when inactive
// (1) Clock is high when inactive
//
///////////////////////////////////////////////////////////////////
void spi_mode(uint8 spi_no, uint8 spi_cpha,uint8 spi_cpol)

こう書いてあるので自然と、

spi_mode(HSPI, 0, 0);

と書いてしまっていた。この状態でオシロでクロック出力を観察しようとすると・・・

hspi_0_0

信号!出てねえ!!

マジかよ。ちなみに緑がクロック、水色がスレーブ信号出力(MISO)です。SPI通信の場合、クロック供給はホスト側(マイコン)がやるのでクロックが出ていないのは明らかに異常・・・・だと思うのですがどうでしょう?

spi_mode(HSPI, 1, 0);

hspi_1_0

あ、これがArduino一般で言うところのMODE0じゃないのか?

spi_mode(HSPI, 0, 1);

hspi_0_1

んークロックが負論理になっててラッチ先行だからMODE2ですよね。

spi_mode(HSPI, 1, 1);

hspi_1_1

クロックが負論理で、シフト先行だから、MODE3ですよね。

おい!MODE1どこいった!!とにかくspi_mode(HSPI, 0, 0)だと動きそうにないことはわかった。ちなみにこの初期化をしない(デフォルト)で波形を観察すると、デフォルトはspi_mode(HSPI, 1, 0)のようです。なんかモヤモヤするけど、とりあえずの観察結果は以上です。MCP2515はMODE0とMODE3をサポートしているから、デフォルトでOKなのかしら(確認していない)

たぶん、何か勘違いしていると思いますが、現場からは以上です。

SPIとHSPIの違い

もうひとつの疑問。HSPIとSPIの違いは・・・実はよくわかりませんでした。速度差なのかな?と思って速度を調べてみました。

SPIのほうはArduino標準APIに沿っているので最大ホストクロックの2分周(DIV2)のようです。この場合の波形は以下のようになります。

SPI_MODE0_DIV2

1クロック(立ち上がり立下り)でだいたい150nsだから、周波数に直すと約6.6MHzですかね。まあ大半の用途では十分でしょう。

一方でMetalPhreak: ESP8266_SPI_Driverのspi_clock(HSPI, 1, 2);の場合は以下のような波形になりました。

HSPI_CLK_1_2

60nsに2クロック入っているように見えます。だから周波数に直すと33MHzも出ているということになります。この設定では信号がかなり鈍ってしまってますので、実際に基板パターンをひきまわしてペリフェラルと33Mbpsで通信ができるとは限りませんが・・・確かに速いですね。

MCP2515の場合10MbpsまでサポートしていますからHSPIの方がよさそうです。デバイスにもよりますが画像取り込みもできる速度だと思います。意外とポテンシャル高いねESP8266。

コメントは停止中です。