概要
Tang Nanoに搭載されているFPGA書き込み用のIC CH552T
とFPGAとの間は、書き込みのためのJTAGの信号以外に、UARTの信号が接続されています。
よって、UARTの回路をFPGAに実装すればPCと通信出来ると思われたので、試しにFPGA内でUARTのTXとRXを直結したところ、PCから送信した文字がそのまま返ってくることを確認出来ました。
ただし、PCとFPGAでUART通信を行うにはいくつか作業が必要なので、手順を書いておきます。
プロジェクトの設定
Tang Nanoの回路図より、CH552TのUART信号は、FPGAのRECONFIG_N
およびDONE
ピンに接続されています。
このRECONFIG_N
およびDONE
ピンは、FPGAのコンフィグレーションに用いるピンなので、デフォルトのプロジェクト設定ではユーザー・ロジックから使用することができません。
よって、これらのピンを使用するために、以下のプロジェクトの設定を変更する必要があります。
-
Configurations
ダイアログでDual-Purpose Pin
を選択し、Use DONE as regular IO
とUse RECONFIG_N as regular IO
にチェックを入れてOK
ボタンを押します。
これでUARTの信号が接続されているピンをユーザー・ロジックから使用できるようになります。
GUIを使わずに合成をしている場合は、gw_shでadd_file -cfg
で指定しているdevice.cfg
ファイルにset DONE regular_io = true
とset RECONFIG_N regular_io = true
を設定すると、DONE
ピンと RECONFIG_N
をユーザー・ロジックから使用できるようになります。
set DONE regular_io = true
set RECONFIG_N regular_io = true
CH552Tのファームウェアの更新
上記設定をして、FPGA内部でRECONFIG_NとDONEを接続したデザインを書き込み、PCから送信したデータがそのまま返ってくるかどうか確認しましたが、返ってきませんでした。
という内容をツイートしていたところ、
you may have older firmware. The Source code for the firmware is here.https://t.co/KlbCITVgoD
— Kali Prasad (@kprasadvnsi) April 8, 2020
ということで、ファームウェアが古いということを教えてもらいました。
確かに、Tang Nanoではなく自作GOWIN FPGAボードには上記ファームウェアをビルドして書き込んで使っていましたが、そちらではUARTが使用できていました。
試しにTang NanoのCH552Tのファームウェアを更新してみたところ、PCから送信したデータが返ってくることを確認できました。
ファームウェアのビルド
CH552TのファームウェアのソースコードはGitHubのリポジトリで公開されていますので、以下の手順でビルドします。(筆者の環境はUbuntu 18.04なので、Ubuntu 18.04での手順を示します)
ビルドするのが面倒な人向けにビルド済みバイナリも用意してあります。
-
ビルドに必要なパッケージ (gitとコンパイラとMakeとbinutils)をインストールします
$ sudo apt install git sdcc make binutils
-
ソースコードをcloneします
$ git clone --recursive https://github.com/diodep/ch55x_jtag
-
ファームウェアをビルドします
$ cd ch55x_jtag/src $ make
これで、ch55x_jtag/src/usb_jtag.bin
が生成されます。
ファームウェアの書き込み
CH552TはUSB経由でファームウェアを更新することができます。Windowsであれば、CH552Tの製造元純正の書き込みツールWCHISPTool
で更新できます。Linuxではch552tool
というPythonスクリプトで更新できます。
Windowsでの手順
WindowsではWCHISPToolを使用するので、あらかじめ製造元のページからダウンロード してインストールしておきます。
CH552Tにファームウェアを書き込むには、CH552Tを書き込みモード(ブートローダーモード)にする必要があります。そのための方法は以下の2つがあります。
- CH552Tの14番ピンと20番ピンをショートした状態でUSBケーブルを接続する
- FT_Progを使う
前者の方法の手順は言葉通りの手順です。14番ピンと20番ピンをピンセットなどで挟んでショートしながら、Tang NanoのUSBケーブルを差し込みます。
ほかのピンに触れるなどするとPCのUSBポートやTang Nanoが壊れる可能性がありますので、慎重に行います。
後者の方法は電気的には安全ですが、FTDIが自社のチップ向けに公開しているFT_Progを他社製のチップのために使うことになりますので、ライセンス的にどうかは微妙なところです。 (そもそもWindowsドライバのライセンスがヤバいという話もある)。
このあたりを承知の上で作業する方向けに手順を記載します。
ちなみに、FT_Progを使う方法もtwitterで教えていただきました。
You don't have to do any of this. Download the FTProg tool from FTDI. Click on scan device then program device to put CH552 in Bootloader mode then you can use wchisptoolhttps://t.co/DM4on2sYCx
— Kali Prasad (@kprasadvnsi) April 8, 2020
- FT_Progを起動して
DEVICES->Scan and Parse
メニューを選択する
2. Device Tree
にデバイスが表示されたら、DEVICES->Program
メニューを選択し、Program Devices
ダイアログでProgram
ボタンを押す
3. Programming Failed
とエラーメッセージが表示されるので、OK
を押して閉じる
以上でCH552Tが書き込みモードになりました。
次に、WCHISPToolでファームウェアを書き込みます。インストールしたWCHISPToolを起動します。
-
8 Bit CH55X series
タブを選択し、Chip-option
グループのChip model
リストボックスからCH552
を選びます。 -
BeginDownload
グループのDeviceList
にデバイス名が表示されていることを確認します。表示されない場合はCH552Tが書き込みモードになっていませんので、再度書き込みモードにする作業を行います。 -
User File
の右側のボタンをおして、ビルドしたusb_jtag.bin
を選択します。 -
Download(D)
ボタンを押して書き込み処理を実行します。 - Tang NanoからUSBケーブルを抜いて再度差し込みます。
以上で、ファームウェアのアップデート処理は終わりです。
Linuxでの手順
LinuxでCH552Tのファームウェアの更新を行うには、GitHubで公開されているch552toolを使います。
ch552toolはPythonで記述されており、USBデバイスの操作のためにPyUSB
を使っているため、あらかじめPython及びPyUSBを入れておきます。
参考までにUbuntu 18.04での手順を記載します。
$ sudo apt install python3-pip
$ pip3 install pyusb
ch552toolはWindowsでのWCHISPtool同様に書き込みの処理を行いますが、書き込みモードに切り替える機能はありません。
一方、FT_ProgはWindows用のプログラムですので、Linuxでは使用できません。
対策として、FT_Progが送っているコマンドを送るPythonスクリプトを教えてもらったので、このスクリプトとch552toolを使った方法を以下に記載します。
-
ch552toolをcloneします。
$ git clone https://github.com/MarsTechHAN/ch552tool
-
以下のスクリプトを
to_dfu.py
としてch552toolをcloneしたディレクトリに保存します。to_dfu.pyimport sys import time import usb.core import usb.util dev = usb.core.find(idVendor=0x0403, idProduct=0x6010) if dev is None: dev = usb.core.find(idVendor=0x4348, idProduct=0x55e0) # WCH bootloader if dev is None: print("No devices are found.") sys.exit() else: try: dev.ctrl_transfer(0x40, 0x91, 0, 0, 0) except usb.core.USBError as e: print('Apply magic success.') retryCounter = 20 while retryCounter: print(".", end="") retryCounter = retryCounter - 1 dev = usb.core.find(idVendor=0x4348, idProduct=0x55e0) time.sleep(0.5) if dev is not None: break print("CH552 is now in DFU mode.")
-
to_dfu.py
を実行します。$ cd ch552tool $ python3 ./to_dfu.py Apply magic success. ..CH552 is now in DFU mode.
-
ch552tool.py
を使ってusb_jtag.bin
を書き込みます。(~/ch55x_jtag/src/usb_jtag.bin
はusb_jtag.binのパスに置き換えてください)$ sudo python3 ch55xtool.py -f ~/ch55x_jtag/src/usb_jtag.bin -r Found CH552. BTVER: V2.31. Flash done. Restart and run.
以上でCH552Tのファームウェアの更新作業は完了です。
動作確認
前に作ったLチカプロジェクトにUARTのループバックを追加して動作確認しました。
module blinky_top (
input wire resetn,
output wire [2:0] gpio,
input wire fpga_rx,
output wire fpga_tx
);
logic clk;
OSCH #(
.FREQ_DIV(125) // 250[MHz] / FREQ_DIV = output
) osc_inst (
.OSCOUT(clk)
);
localparam int COUNTER_TOP = 32'd2_000_000 - 32'd1;
assign fpga_tx = fpga_rx;
IO_LOC "resetn" 15;
IO_PORT "resetn" IO_TYPE=LVCMOS33;
IO_LOC "gpio[0]" 18;
IO_PORT "gpio[0]" IO_TYPE=LVCMOS33;
IO_LOC "gpio[1]" 16;
IO_PORT "gpio[1]" IO_TYPE=LVCMOS33;
IO_LOC "gpio[2]" 17;
IO_PORT "gpio[2]" IO_TYPE=LVCMOS33;
IO_LOC "fpga_rx" 9;
IO_PORT "fpga_rx" IO_TYPE=LVCMOS33;
IO_LOC "fpga_tx" 8;
IO_PORT "fpga_tx" IO_TYPE=LVCMOS33;
合成したデザインを描き込んだ後、screenコマンドなどで、CH552Tに対する2個目のデバイスを開きます。(筆者の環境では/dev/ttyUSB1
です)
ちなみに、UARTのボーレートはあまり速すぎない限りいくらでもいいです。今回は115200を指定しています。
$ screen /dev/ttyUSB1 115200
screen起動後文字入力すると、入力した文字が画面に表示されます。screenはローカルエコーをしないので、画面に入力文字が表示されるということは、UARTで送信した文字が返ってきていることを表します。
試しにUSBケーブルを抜き差しして、FPGAのデザインを元に戻してからscreenを実行すると、入力文字が返ってこないことが確認できます。
おわりに
Tang NanoでもPCとのUART通信が手軽に出来るようになりましたので、Tang Nanoの使い道が広がります。
合成後にパラメータをUARTで送ったり、デバッグ用データを送るなどが可能です。