BC-11AH-M2 USB ドングルの使用手順

Posted by: otsuka

BC-11AH-M2 を USB ドングルにする拡張基板 802.11ah USB を使って BC-11AH-M2 を USB 接続し、
11ah Wifi interface として使用するための手順を紹介します。

BC-11AH-USB USB ドングルとして認識させ操作するためには、
nrc7292_sw_pkg の中の package/src/ft232h-usb-spi/ にある
FT232H USB-SPI bridge driver を使います。

NRC7292 Application Note (FT232H_USB_SPI)
で FT232H USB-SPI bridge driver のビルド方法や insmod 時の設定などが説明されていますが、
この driver の制限から 5.x 系以降の linux kernel では使用できないので、
使用できる最新の環境は
linux kernel 4.19.118 が使われている Debian 10 (buster) ベースの Raspberry Pi OS 2020-05-27 版
2020-05-27-raspios-buster-armhf.zip
になります。

また、4.x 系の最新 kernel でもこの driver のままでは二重に load される不具合があるのと、
使用 chip の ID に変更があるため、driver をビルドする前に以下の差分のような修正を加える必要があります。

diff -urN ft232h-usb-spi.orig/drivers/spi/spi-ft232h/ft232h-usb.c ft232h-usb-spi.mod/drivers/spi/spi-ft232h/ft232h-usb.c
--- ft232h-usb-spi.orig/drivers/spi/spi-ft232h/ft232h-usb.c	2024-05-11 07:14:09.000000000 +0900
+++ ft232h-usb-spi.mod/drivers/spi/spi-ft232h/ft232h-usb.c	2024-10-15 16:23:49.000000000 +0900
@@ -17,8 +17,13 @@
 
 
 #define VID_FTDI	0x0403
-#define PID_FT232H	0x6014
+//#define PID_FT232H	0x6014
+// BC: 2024/10/08
+// for bc-11ah-m2usb_spi 
+#define PID_FT232H	0x6010
 
+static bool ft232h_probed = false;
+static int ft232h_diconnected = 0;
 
 extern int ft232h_intf_probe(struct usb_interface *intf, const struct usb_device_id *id);
 extern void ft232h_intf_disconnect(struct usb_interface *intf);
@@ -37,23 +42,35 @@
 static int ft232h_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
 {
 	int ret;
-
+dev_info(&intf->dev, "[%s]:\n", __func__);
+	if (ft232h_probed) {
+		dev_info(&intf->dev, "[%s] already probed...\n", __func__);
+		return 0;
+	}
 	ret = ft232h_intf_probe(intf, id);
 	if (ret == 0) {
 		struct ft232h_intf_priv *priv = usb_get_intfdata(intf);
 
 		ret = ft232h_spi_probe(priv->spi_pdev);
 	}
-
+	
+	if (ret == 0) {
+		ft232h_probed = true;
+	}
+dev_info(&intf->dev, "[%s]: done... %d\n", __func__, ret);
 	return ret;
 }
 
 static void ft232h_usb_disconnect(struct usb_interface *intf)
 {
 	struct ft232h_intf_priv *priv = usb_get_intfdata(intf);
-
-	ft232h_spi_remove(priv->spi_pdev);
-	ft232h_intf_disconnect(priv->intf);
+	dev_info(&intf->dev, "[%s]: p:%p %d\n", __func__, priv, ft232h_diconnected);
+	if (priv) {
+		ft232h_spi_remove(priv->spi_pdev);
+		ft232h_intf_disconnect(priv->intf);
+	}
+	dev_info(&intf->dev, "[%s]: done...\n", __func__);
+	ft232h_diconnected++;
 }
 
 static struct usb_driver ft232h_usb_driver = {

Raspberry Pi 3、Raspberry Pi 4 で動作を確認しています。

1. Raspberry Pi OS 2020-05-27 版で Raspberry Pi を起動する。

上記の 2020-05-27-raspios-buster-armhf.zip をダウンロードして microSD カードに書き込み、
Raspberry Pi を起動します。

2. driver をビルドできる環境を整える。

driver のビルドに必要な kernel header をインストールします。
pi@raspberrypi:~ $ sudo apt install raspberrypi-kernel-headers
kernel header がインストールできたら、5.x 系 kernel に更新されてしまわないよう
kernel 関連の一連のパッケージをホールドします。
pi@raspberrypi:~ $ sudo apt-mark hold libraspberypi-bin libraspberrypi-dev libraspberrypi-doc \ 
libraspbererypi0 raspberrypi-bootloader rasapberrypi-kernel raspberrypi-kernel-headers

3. ft232h-usb-spi をビルドして USB ドングルを接続し driver を insmod する。

上記の修正を適用済みの nrc7292_sw_pkg を
https://github.com/BeatCraft/nrc7292_sw_pkg/
からダウンロードしビルドします。
pi@raspberrypi:~ $ git clone https://github.com/BeatCraft/nrc7292_sw_pkg.git
pi@raspberrypi:~ $ cd nrc7292_sw_pkg/package/src/ft232h-usb-spi/
pi@raspberrypi:~/nrc7292_sw_pkg/package/src/ft232h-usb-spi $ make
エラーなくビルドが完了したら、ft-232h-usb-spi ディレクトリ内の
drivers/spi/spi-ft232h/
に spi-ft232h.ko ができています。

この kernel module が正常に load できるか確認します。
Raspberry Pi に BC-11AH-M2 USB を接続してから、
$ ./Insmod.sh を実行します。
default では Raspbery Pi 3 向けに spi_bus_num=3、gpio_bus_num=500 という設定が書かれています。
Raspberry Pi 3 で実行すると、
pi@raspberrypi:~/nrc7292_sw_pkg/package/src/ft232h-usb-spi$ ./Insmod.sh
sudo insmod ./drivers/spi/spi-ft232h/spi-ft232h.ko latency=1 spi_bus_num=3 gpio_bus_num=500
export gpiochip0 gpiochip100 gpiochip128 gpiochip500 unexport
spio spi3
Raspberry Pi 4 ではこの bus number のままだとエラーになるので
Insmod.sh 内を gpio_bus_num=492 に書き換えてから実行します。
pi@raspberrypi:~/nrc7292_sw_pkg/package/src/ft232h-usb-spi$ ./Insmod.sh
sudo insmod ./drivers/spi/spi-ft232h/spi-ft232h.ko latency=1 spi_bus_num=3 gpio_bus_num=492
export gpiochip0 gpiochip492 gpiochip504 unexport
spio spi3

正常に load でき、spi_master、 gpio デバイスができることを確認したら、
11ah インタフェースとして使用するための設定を行います。

4. nrc7292_sw_pkg をセットアップする。

Raspberry Pi HAT 形式の BC-11AH-M2 を使用するときと同様、
UG-7292-018-Raspberry_Pi_setup.pdf
に従って nrc7292_sw_pkg のインストールと設定を行います。

5. nrc_pkg/script/start.py の設定を USB 接続向けに変更する。

4 の手順で /home/pi にインストールされた nrc_pkg 内の script/start.py の以下の設定項目を USB 接続向けに変更します。
ft232h_usb_spi を default の 0 から 1 に変更。
# FT232H USB-SPI Conf. (FT232H CSPI Conf)
ft232h_usb_spi = 1            # FTDI FT232H USB-SPI bridge
                              # 0 : Unused
                              # 1 : NRC-CSPI_EIRQ Input Polling
                              # 2 : NRC-CSPI Registers Polling

Raspberry Pi 4 で動作させる場合は 関数 ft232h_usb 内の spi_gpio_irq を 492 に変更。
Raspberry Pi 3 で動作させる場合は 500 のままで大丈夫です。
def ft232h_usb():
    # Re-define SPI parameters for ft232h_usb_spi
    # ft232h_usb_spi
    global spi_clock, spi_bus_num, spi_gpio_irq, spi_cs_num, spi_polling_interval
    print("[*] use ft232h_usb_spi")
    spi_bus_num = 3
    spi_gpio_irq = 492
    if int(spi_clock) > 15000000:
        spi_clock = 15000000
    if int(spi_cs_num) != 0:
        spi_cs_num = 0
    if int(spi_polling_interval) <= 0:
        spi_polling_interval = 50
    if int(ft232h_usb_spi) != 1:
        spi_gpio_irq = -1

6. start.py で 11ah interface を動作させ、STA としてまたは AP として正しく動作させる。

BC-11AH-M2 USB が接続され、./Insmod.sh で spi-ft232h.ko が正常に load された状態で
5 の設定が正しく変更されていたら、start.py の実行により BC-11AH-M2 USB が wlan0 として設定され
pi@raspberrypi:~/nrc_pkg/script $ ./start.py 0 3 JP
で STA として、
pi@raspberrypi:~/nrc_pkg/script $ ./start.py 1 3 JP
で AP として動作します。


起動時に自動で USB 11ah が使用可能になるようにしたい場合には、
ビルドした spi-ft232h.ko を
/lib/modules/4.19.118-v7l+/kernel/drivers/spi/
にコピーして depmod -a を行い、
/etc/modprobe.d/spi-ftd232h.conf
を以下の内容で作成しておきます。
options spi-ft232h latency=1 spi_bus_num=3 gpio_bus_num=492
この設定を行った上で BC-11AH-M2 USB を接続して起動すると
起動時にデバイスの用意までが完了するので
起動完了後すぐに start.py を実行することができます。