×

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をブートモードで起動するためのプログラムはこのような感じで実現しました。

[cpp]
#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;
}
[/cpp]

実際にそれらを行っているのは、以下の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します。

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

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

[bash][/bash]

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

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