ZED-F9PのSPIインターフェース

ZED-F9Pをマイコンで制御する場合、インターフェースとして、UART, I2C, SPIから選ぶ事になります。

UARTはボーレートの設定が正しければ確実に動作し、送信と受信が独立しているので使いやすいインターフェースです。転送速度は230,400bps程度までは安定していますが、460,800bpsになるとマイコンとのクロック差が問題となり、エラーが起きやすくなります。

I2Cはクロックが400kHzでも安定して通信が可能ですが、アドレスチェックや送受信が同時に行えないなどにより、転送レートが少し下がります。

ZED-F9Pの性能をフルに発揮させようとすると、400kHz以上の安定したインターフェースが必要で、SPIが最も適していると考えられます。
データシートによるとSPIを使った時のZED-F9Pの転送レートは最大125KB/s、クロックは5.5MHzとなっています。今回、この上限を確認してみました。

使用した回路図は次のとおりで、ESP32とZED-F9Pを接続しています。
CLK,MISO,MOSI,CSの4本のSPI用の信号ラインのほかにTX_READYのラインも接続しました。
また、D_SEL(47番ピン)はグランドに接続してあります。

ArduinoのIDEで作成したソースコードは次のとおりです。
TX_READYピンがHighになるとデータが用意できているので、ZED-F9Pからデータを読み出し、表示するという単純なテストプログラムです。

#include <SPI.h>  
SPIClass SPI2(HSPI);
int mTxReadyPin = 36;

#define SAVE_BUFF_MAX 1024
char saveBuff[ SAVE_BUFF_MAX ];
void setup() {
	// serial
	Serial.begin(115200);
	Serial.printf("spi test start\r\n");    

	// SPI
	SPI2.begin( 14, 12, 13, 15 );
	SPI2.setFrequency(5000 * 1000);	
	SPI2.setHwCs( true );
	pinMode( mTxReadyPin, INPUT);
}

void loop() {
	if ( ! digitalRead( mTxReadyPin ) ) return;
	int nret = spiReceive( saveBuff, 999 );
	if ( nret > 0 ){
		saveBuff[nret]='\0';
		Serial.printf("spi=%s\r\n",saveBuff);
	}
}
int spiReceive( char* buff, int numBytes )
{
	int n = 0;
	for( int i=0; i < numBytes; i++ ){
		int c = SPI2.transfer( 0xff );
		if ( c == 0xff ) break;
		buff[n++] = c;
	}
	return n;
}

最初のテストとして、22行目をコメントアウトし、TX_READYピンを使わないで読み出しました。

問題なく読み出せるだろうと思いましたがシリアルモニタにはZED-F9PからのNMEAセンテンスが表示されません。
ロジアナでSPIの信号を確認しても、クロックやCSは正常に出力されています。
色々試して分かったのは、ZED-F9Pが工場出荷時の状態でない場合、SPIが正常に動作しない事でした。
u-centerを使って、工場出荷時の状態に戻したところ、シリアルモニタにはNMEAセンテンスが正常に表示されるようになりました。
このテストに使ったZED-F9Pは別のテストで使っていたもので、工場出荷時の状態と違う設定がしてあり、SPIが動作しませんでした。通常は起きませんが、SPIが正常に動作しない場合は工場出荷時の状態に戻してみるといいかもしれません。

正常にSPIとして動作するようになったので、クロックの周波数を上げていきました。
500kHzまでは問題なかったのですが、1MHzにしたところ、ZED-F9Pからはエラーメッセージが出力され、リブートを繰り返すようになりました。
エラーメッセージは
$GNTXT,01,01,01,exception 0x00130405 has occurred*2D
という例外処理で、この意味は検索しても出てきませんでした。

原因としてはSPIの1MHzのクロックが休みなくZED-F9Pに供給されるので、ZED-F9P内部のマイコンの処理が間に合わず、例外処理になってしまうのだと考えられます。

そこで、TX_READYピンを見て、必要な時だけクロックを供給し読み出すようにしました。
TX_READYピンはデフォルトでは信号を出力しませんので、「ZED-F9PのTX_READYピン」で述べた設定を行いました。そしてソースコードの22行目のコメントアウトを外しました。

そうしたところ、クロックは1MHzでも問題なく動作し、段階的に上げていったところ、10MHzまで正常に動作しました。データシートでは5.5MHzが上限となっていますので、10MHzで動作すれば十分です。

次の波形はロジアナで観測したもので、クロックは10MHzです。

測位レートは10Hzの設定ですが、実際は何故か12Hz程度になっています。

以上、高速で読み出すにはTX_READYピン+SPIインターフェースが良いという事が確認できました。