ここではJavaでBitBangを制御してRM-922をリセットするためのプログラムについて述べています.FT232RLに備わるBitBangを使えば,ちょっとした端子を制御を行えるため,RM-922をFT232RL経由でリセットすることができます.ハードウェア構成についてはこちらをご覧ください.
以前,BitBangを用いるにはFTDIが提供しているライブラリを利用してC++でアプリケーションを作っていました.しかしJavaでBitBangを利用するとしたらC++で作成したアプリケーションをJavaのプログラム中で呼び出さねばならず,ちょっと面倒でした.そこでJNA(Java Native Access)を使ってDLLにある関数を呼び出すことにしました.参考にしたサイトはこちらです.参考にしたサイトの情報はおそらくちょっと古いのか,DLLの名称が異なっていたためにそれを変えるとともに,FT_OpenEX関数を使用していたところをFT_Open関数に変更しました.加えてFT_SetBitMode関数を使うことで端子のモードを変えられるようにしました.これにより,Bit Bangを使ったのち,通常のUSB-シリアル変換の機能を使えるようにしました.ついでに今後の拡張を考えて端子や状態をEnumで定義しておきました.下にプログラムを示します.
FT232Controller.java
package jp.ac.nagano_nct.ashida_lab.ft232_bitbang_controller;
import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.PointerByReference;
/** FT232のBit Bang機能をコントロールするクラス
* @author ashida
*/
public class FT232Controller {
/** オープンする
* @param device_number デバイス番号
* @param handle ハンドル
* @return デバイスの状態
*/
static native int FT_Open(int device_number, PointerByReference handle);
/** クローズする
* @param handle ハンドル
* @return デバイスの状態
*/
static native int FT_Close(Pointer handle);
/** 書き込む
* @param handle ハンドル
* @param write_data 書き込むデータ
* @param write_data_length 書き込むデータの長さ
* @param written_data_length 書き込んだデータの長さ
* @return
*/
static native int FT_Write(Pointer handle, Pointer write_data, int write_data_length, IntByReference written_data_length);
/** 読み込む
* @param handle ハンドル
* @param read_data 読み込むデータ
* @param read_data_length 読み込むデータの長さ
* @param get_data_length 読み込んだデータの長さ
* @return
*/
static native int FT_Read(Pointer handle, Pointer read_data,int read_data_length, IntByReference get_data_length);
/** ビットモードを設定する
* @param handle ハンドル
* @param pin 端子
* @param mode モード
* @return
*/
static native int FT_SetBitMode(Pointer handle, int pin, int mode);
static {
/* FT232を操作するDLLの名称 */
Native.register("ftd2xx");
}
/** ハンドル */
Pointer _handle = null;
/** コンストラクタ
* @param device_number デバイス番号
*/
public FT232Controller(int device_number){
/* ハンドラの参照返し */
PointerByReference handle = new PointerByReference();
if (FT_Open(device_number, handle) != DeviceStatus.FT_OK.getValue()) {
throw new RuntimeException("FT_Open failed.");
}
_handle = handle.getValue();
}
/** クローズする */
public void close() {
FT_Close(_handle);
}
/** 書き込む
* @param data 書き込むデータ
*/
public void write(short... data){
Memory memory = new Memory(data.length);
IntByReference ref = new IntByReference();
memory.write(0, data, 0, data.length);
FT_Write(_handle, memory, data.length << 1, ref);
}
/** 読み込む
* @return 読み込んだデータ
*/
public byte read() {
Memory memory = new Memory(1);
IntByReference ref = new IntByReference();
FT_Read(_handle, memory, 1, ref);
return memory.getByte(0);
}
/** ビットモードを設定する
* @param bit_mode ビットモード
* @param pins 操作する端子
*/
public void setBitMode(BitMode bit_mode,Ft232Pin...pins){
int pins_value=0;
for(Ft232Pin pin: pins){
pins_value += pin.getValue();
}
FT_SetBitMode(_handle, pins_value, bit_mode.getValue());
}
public static void main(String []args){
/* オープンする */
FT232Controller controller = new FT232Controller(0);
/* D7を非同期Bit Bangモードにする */
controller.setBitMode(BitMode.FT_BITMODE_ASYNC_BITBANG, Ft232Pin.D7);
/* D7をLow(=リセット)にする */
controller.write((short)0x00);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
/* D7をHigh(=リセットでない)にする */
controller.write((short)0x80);
/* D7を通常の端子状態にする */
controller.setBitMode(BitMode.FT_BITMODE_RESET, Ft232Pin.D7);
/* クローズする */
controller.close();
}
}
BitMode.java
package jp.ac.nagano_nct.ashida_lab.ft232_bitbang_controller;
/** ビットモード
* @author ashida
*/
public enum BitMode {
/** Bit Bangモードをやめる */
FT_BITMODE_RESET(0x00),
/** 非同期式のBit Bangモード */
FT_BITMODE_ASYNC_BITBANG(0x01),
/** MPSSEモード */
FT_BITMODE_MPSSE(0x02),
/** 同期式のBit Bangモード */
FT_BITMODE_SYNC_BITBANG(0x04),
/** MCU ホストバスのエミュレーションモード */
FT_BITMODE_MCU_HOST(0x08),
/** 高速シリアル通信モード */
FT_BITMODE_FAST_SERIAL(0x10),
/** CBUS Bit Bangモード */
FT_BITMODE_CBUS_BITBANG(0x20),
/** 同期式FIFO Bit Bangモード */
FT_BITMODE_SYNC_FIFO(0x40);
/** 値 */
private int _value;
/** コンストラクタ
* @param value 値
*/
private BitMode(int value){
_value = value;
}
/** 値を得る
* @return 値
*/
public int getValue(){
return _value;
}
}
DeviceStatus.java
package jp.ac.nagano_nct.ashida_lab.ft232_bitbang_controller;
/** デバイスの状態
* @author ashida
*/
public enum DeviceStatus {
/** OK */
FT_OK(0),
/** 不当なハンドル */
FT_INVALID_HANDLE(1),
/** デバイスが見つからない */
FT_DEVICE_NOT_FOUND(2),
/** デバイスが開かれていない */
FT_DEVICE_NOT_OPENED(3),
/** IOエラー */
FT_IO_ERROR(4),
/** 操作をするためのリソースが不足している */
FT_INSUFFICIENT_RESOURCES(5),
/** ある操作のときに提供されたパラメータが不当であった */
FT_INVALID_PARAMETER(6),
/** 不当なボーレート */
FT_INVALID_BAUD_RATE(7),
/** 開かれていないデバイスを消そうとしてできなかった */
FT_DEVICE_NOT_OPENED_FOR_ERASE(8),
/** 開かれていないデバイスに書き込もうとしたができなかった */
FT_DEVICE_NOT_OPENED_FOR_WRITE(9),
/** デバイスへの書き込みに失敗した */
FT_FAILED_TO_WRITE_DEVICE(10),
/** EEPROMの読み込みに失敗した */
FT_EEPROM_READ_FAILED(11),
/** EEPROMの書き込みに失敗した */
FT_EEPROM_WRITE_FAILED(12),
/** EEPROMの消去に失敗した */
FT_EEPROM_ERASE_FAILED(13),
/** EEPROMがこのデバイスでは提供されていない */
FT_EEPROM_NOT_PRESENT(14),
/** EEPROMをプログラムされていない */
FT_EEPROM_NOT_PROGRAMMED(15),
/** 不当な引数であった */
FT_INVALID_ARGS(16),
/** サポートされていない */
FT_NOT_SUPPORTED(17),
/** その他のエラー */
FT_OTHER_ERROR(18),
/** デバイスリストが用意されていない */
FT_DEVICE_LIST_NOT_READY(19);
/** 値 */
private int _value;
/** コンストラクタ
* @param value 値
*/
private DeviceStatus(int value){
_value = value;
}
/** 値を得る
* @return 値
*/
public int getValue(){
return _value;
}
}
FT232Pin.java
package jp.ac.nagano_nct.ashida_lab.ft232_bitbang_controller;
/** FT232の端子
* @author ashida
*/
public enum FT232Pin {
/* すべての端子 */
ALL(0xFF),
/** D7 */
D7(0x80),
/** D6 */
D6(0x40),
/** D5 */
D5(0x20),
/** D4 */
D4(0x10),
/** D3 */
D3(0x08),
/** D2 */
D2(0x04),
/** D1 */
D1(0x02),
/** D0 */
D0(0x01);
/** 値 */
private int _value;
/** コンストラクタ
* @param value 値
*/
private Ft232Pin(int value){
_value = value;
}
/** 値を得る
* @return 値
*/
public int getValue(){
return _value;
}
}
