ここでは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; } }