×

1号の足跡(4) Lazuriteにプログラムを転送する(その1)

2016-07-04

Raspberry PiでLazuriteのテスターを作るシリーズの続きです。
本日からRaspberry PiからLazuriteにプログラムを転送する仕組みを開発しながら、プログラムを開発していきたいとおもいます。
まず初日の本日はLazuriteがプログラムを受信するモードで起動するまでを行っていきます。

1. Lazuriteをブートモードで起動する

image

Lazuriteに搭載しているマイコン ML620Q504Hは何もしなければプログラムROMの0番地から動作していきます。プログラム書き込みをするためには、ML620Q504Hに搭載されているハードウエアリマップ機能を使用して動作するプログラムを変更することで実現しています。

TEST1N端子 = リセット端子と同じ
TEST端子 –>
Lのとき:   通常動作 0番地からプログラムが動作します
Hのとき:    0xFC00番地からプログラムが動作します。

ハードウエアリマップ機能の詳細は、ML620Q504Hのユーザーズマニュアル 「27.3.5 ハードウェアによるリマップ機能」を参照してください。

さて、ML620Q504Hの0xFC00番地からプログラムが起動すると、ソフトウエアリマップ機能によりプログラムのアドレスが再び0xF000番地にジャンプし、その領域にXMODEMのプロトコルで受信したデータを0番地から書き込むプログラムがあらかじめ書き込まれています。このプログラムを使用してLazuriteIDEからプログラムの書き込みを行っているのです。
Lazurite SubGHzの回路図を見てみると、FTDIのFT232RのCBUS0端子はTEST1N端子に、CBUS1端子がTEST端子に、それぞれ接続されています。通常はTEST端子はLになっているのですが、プログラムを書き込むモード(以降、ブートモード)にするためにはTEST端子をHにしてリセットを解除すればよいので、CBUS0とCBUS1端子をFTDIのD2XXライブラリを使用して動かして、そのような状態になるようにすればよいのです。

 

回路図抽出

FTDIのD2XXライブラリを使用してLazuriteIDEをブートモードで起動するためのプログラムはこのような感じで実現しました。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../../lib/release/ftd2xx.h"

#define SUCCEEDED			0
#define	ERR_ARGC			1
#define	ERR_LIST_DEVICE	2
#define	ERR_NO_DEVICE		3
#define	ERR_CBUS_BITBANG	4

// memory for storing parameters
char Manufacturer[32];
char ManufacturerId[64];
char Description[64];
char SerialNumber[16];

int main(int argc, char* argv[])
{
	FT_STATUS ftStatus;
	FT_HANDLE hFt;
	static FT_PROGRAM_DATA Data;
	DWORD numDevs = 0;
	DWORD testDev;
	int ret=SUCCEEDED;

	// check number of args
	if(argc != 2)
	{
		ret = ERR_ARGC;
		//printf("%d\n",ret);
		return ret;
	}
	// get number of devices
	ftStatus = FT_ListDevices(&numDevs,NULL,FT_LIST_NUMBER_ONLY);
	if(ftStatus != FT_OK) {
		//printf("%d\n",ERR_LIST_DEVICE);
		return ret;
	}
	// connect memory
	Data.Manufacturer = Manufacturer;
	Data.ManufacturerId = ManufacturerId;
	Data.Description = Description;
	Data.SerialNumber = SerialNumber;

	// get Manufacture and description
	for (testDev = 0;testDev < numDevs; testDev++) {  		ftStatus = FT_Open(testDev, &hFt);  		if(ftStatus != FT_OK) {  			continue;  		}  		Data.Signature1 = 0x00000000;  		Data.Signature2 = 0xffffffff;  		ftStatus = FT_EE_Read(hFt,&Data);  		if(ftStatus != FT_OK) {  			FT_Close(hFt);  			continue;  		}  		// check Description  		if(strncmp(Data.Description,argv[1],sizeof(Description)) == 0) break;  		FT_Close(hFt);  	} 	 // error check  	if(testDev>= numDevs)
	{
		ret = ERR_NO_DEVICE;
		//printf("%d\n",ERR_NO_DEVICE);
		return ret;
	}

	// change to CBUS_BITBANG and reset LSI
	ftStatus = FT_SetBitMode(hFt, 0xF0 , FT_BITMODE_CBUS_BITBANG);
	if(ftStatus != FT_OK) {
		//printf("%d\n",ERR_CBUS_BITBANG);
		goto error;
	} 

	// set test pin of ML620Q504H to high
	ftStatus = FT_SetBitMode(hFt, 0xF1 , FT_BITMODE_CBUS_BITBANG);
	if(ftStatus != FT_OK) {
		ret = ERR_CBUS_BITBANG;
		goto error;
	} 

	// start ML620Q504H as boot mode
	ftStatus = FT_SetBitMode(hFt, 0xD3 , FT_BITMODE_CBUS_BITBANG);
	if(ftStatus != FT_OK) {
		ret = ERR_CBUS_BITBANG;
		goto error;
	}

error:
	FT_Close(hFt);
	//printf("%d\n",ret);
	return ret;
}

実際にそれらを行っているのは、以下の3行になります。
0xF0 = CBUS0(TEST端子)=L,   CBUS1(TEST1N端子)=L
0xF1 = CBUS0(TEST端子)=H,   CBUS1(TEST1N端子) = L
0xD3 = CBUS0(TEST端子)=H,   CBUS1(TEST1N端子) = 入力端子にして、ML620Q504Hに内蔵しているpullup抵抗でHにしています。

続いて、このファイルを”bootmode.cpp”として保存し、次のコマンドでbuildします。

g++ bootmode.cpp -o bootmode -Wall -Wextra -L. -lftd2xx -lpthread -ldl -lrt -Wl,-rpath /usr/local/lib

最後に、Lazurite SubGHzをブートモードで起動してみたいと思います。

pi@raspberrypi ~/develop/miniTester/ftdi_test/src/bootmode $ sudo rmmod ftdi_sio
pi@raspberrypi ~/develop/miniTester/ftdi_test/src/bootmode $ sudo rmmod usbserial
pi@raspberrypi ~/develop/miniTester/ftdi_test/src/bootmode $ sudo ./bootmode “LAZURITE Sub-GHz Rev2″
[\bash]

実行した結果、下の写真のようにブートモードで起動したことを示すオレンジ色のLEDが点灯しました。(最初の写真はブートモードで起動したことを示すLEDが点灯していたのでした)

image

明日は引き続き、プログラムの書き込みを行っていきたいと思います。