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