仮想I/O (VIO) IPコアを使ったFPGAのデバッグ

今回は、LogiCORE IP Virtual Input/Output (VIO) コアを用いてFPGAの内部信号をPCからコントロールしてみます。

どんなことができるのか

VIOを使うと、Vivadoの画面上でピンや信号線の状態を監視したり、操作したりすることができます。

ILAと同じくデバッグ用のIPコアです。
波形を見たいときはILAを使い、信号線をPCから操作したいときはVIOを使うといった感じでデバッグをしていきます。

下の画像は、LEDが接続されたピンを操作して、ZYBO上のLEDをコントロールしている様子です。

今回はVIOの使い方について書いていこうと思います。

続きを読む

ESP32で複数のシリアルポートを開く

ESP32の中に入っている3つのUARTを使ってみようと思います。
Arduino core for ESP32 WiFi chip release v1.0.1以降ではSerial1とSerial2が定義されました。
それに伴い、記事をの内容を修正しました。(2019/06現在)

やり方 (Arduino core for ESP32 WiFi chip release v1.0.1以降版)

Arduinoのサンプルに「MultiSerial」と言うものがあります。
これを編集して3ポート使えるように修正しました。

void setup() {
  // initialize both serial ports:
  Serial.begin(9600);
  Serial1.begin(9600);
  Serial2.begin(9600);
}

void loop() {
  // read from port 1, send to port 0:
  if (Serial1.available()) {
    int inByte = Serial1.read();
    Serial.write(inByte);
  }

  // read from port 0, send to port 1:
  if (Serial.available()) {
    int inByte = Serial.read();
    Serial1.write(inByte);
  }

    // read from port 0, send to port 2:
  if (Serial2.available()) {
    int inByte = Serial.read();
    Serial2.write(inByte);
  }
}

やり方 (Arduino core for ESP32 WiFi chip release v1.0.0版)

Arduinoのサンプルに「MultiSerial」と言うものがあります。
これを少し編集してシリアルポート0以外のポートを開くことができました。

// ---------- ここを追加
HardwareSerial Serial1(2); // UART2を使う
// ----------

void setup() {
  // initialize both serial ports:
  Serial.begin(115200);
  Serial1.begin(115200);
}

void loop() {
  // read from port 1, send to port 0:
  if (Serial1.available()) {
    int inByte = Serial1.read();
    Serial.write(inByte);
  }

  // read from port 0, send to port 1:
  if (Serial.available()) {
    int inByte = Serial.read();
    Serial1.write(inByte);
  }
}

ESP32のIO16とIO17(UART2のTX,RX)を直接接続することでループバックテストをすることができました。

問題点

今回はUART0と2を使用しました。
UART1は下記のサイトに書いてあるように、デフォルトでSPI Flashに設定されているようです。
ESP32 devkit esp-idf UART1 examle not working - ESP32 Forum

UART1の使い方については分かり次第ブログに書こうと思います。
追記: ver.1.0.1以降を使えばすべてのポートが使用可能です。

追記

Qiitaのこちらの記事で、UART1を使用する方法が書かれた記事についての紹介がありました。
Arduino-ESP32 Serial通信 - Qiita
Secret Serial Port For Arduino/ESP32 | Hackaday
どうやら、ライブラリを直接いじる必要があるみたいです。

Arduino TIANの概要

Arduino TIANというボードを使う機会があったので、このボードについていろいろと紹介して行こうと思います。

Arduino TIANとは

Linuxが動いて、Wi-FiBluetoothEthernetがついてるボード…らしです。
ボード価格は1個1万円程度とArduinoとしてはかなり高価なボードです。

下記ページにて詳しい説明があります。
www.arduino.org

このArduinoボードは普通のArduinoボードとは少し違っていて、Linuxが動くマイクロプロセッサと、ArduinoIDEで開発できるマイクロコントローラが載っていて、それらのチップはシリアルで通信をしているようです。
この仕様についてブロック図で見ていきましょう。

Arduino TIANの回路図(ブロック図)

Arduino TIANのホームページにあるarduino-tian-schematic.pdfを見てみると、1ページ目にこのボードのブロック図が示されています。
f:id:taltalp:20170502164755p:plain
この図を見ると2つのCPUがあるのがわかります。

MIPS 74K CPU
Linuxが動くCPUでAtheros AR9342というMIPSプロセッサです。

・SAMD21G18
ArduinoIDEで開発できるCPUで、アーキテクチャはARM Cortex-M0+です。

この2つのCPUはシリアル通信で相互に通信ができるようです。

続いて各モジュールについて詳しく見ていきましょう。

Wi-Fiモジュール
MIPS 74K CPUに接続されています。
Linux側から使うようです。
ArduinoIDEに入っているWi-Fiサンプルプロジェクトは使うことができなさそうです。

・CP2105(USB-UART)
USB-UART変換チップです。
こちらはMIPS 74K CPUとSAMD21G18Aのどちらにも繋がっています。
実際にPCにUSB接続するとCOMポートが2つ認識されます。
SAMD21G18Aとの接続ではArduino UNOのように、プログラムの書き込み、シリアル通信のコンソールとして動作します。
MIPS 74K CPUとの接続ではLinuxのコンソール画面が出てきました。こちらからOSを操作することができそうです。

・AU6350(USB2.0 HUB)
USBハブチップです。ホストはMIPS 74K CPUとなっています。
USBデバイスとして
・SAMD21G18A
Bluetoothドングル
・基板上のUSBコネクタ
・ピンヘッダのD+、D-ピン
が接続されています。
USB関連(Bluetoothも含め)はLinux側から制御するようです。
ArduinoIDE側ではUSBデバイスの開発が可能なようです。

・ピンヘッダ
Arduino互換のデザインとなっているピンヘッダはSAMD21G18Aに接続されています。
ArduinoIDEから通常の開発と同様に操作することができます。

pythonで印刷するメモ(mac・linux編)

今回はpythonから何かをプリンターで印刷したい時にどうすればいいかについてです。
自分用のメモ書きなので適当な説明です。

テキストを印刷してみる

import subprocess

# ただのテキスト
text = 'print out message'
# ファイルから印刷する場合
text = open('text.txt', 'r').read()

p = subprocess.Popen('lpr', stdin=subprocess.PIPE)
p.communicate(text)
p.stdin.close()

lprコマンドにパイプしてデータを渡すだけで印刷ができました。とても簡単です。

画像を印刷してみる

今回やりたかったのは、画像を生成してそれをファイルとして書き出さずにそのまま印刷する方法です。PILで適当な画像を生成して印刷してみます。

import subprocess
from PIL import Image
from StringIO import StringIO

buf = StringIO()

# create an image
screen = (500, 500)
bgcolor = (0x00, 0x00, 0x00)
img = Image.new('RGB', screen, bgcolor) 

# save this image to memory as a png image
img.save(buf, 'PNG')

# print out
p = subprocess.Popen('lpr', stdin=subprocess.PIPE)
p.communicate(buf.getvalue())

p.stdin.close()
buf.close()

StringIOを使ってメモリ上に画像ファイルを作って、それをlprコマンドに渡してあげることで印刷することができました。

FPGAの差動入力でAD変換

はじめに

XilinxのXcell Journal 94号に掲載されている「1つのザイリンクス FPGA で数百の信号をデジタル化する方法」がとてもおもしろそうだったので実際に実装してみました。
Xcell Journal 日本語版
差動入力1つと抵抗,コンデンサがそれぞれ1つだけでΔ変調器型のADCを作ることができるため1つのFPGAにたくさん搭載することができます。
今回はVivado2015.4で開発してZyboで動かしました。

仕組み

回路図は下のようになります。差動アンプの+側にアナログ信号を入力し,-側にはRCローパスフィルタの出力を接続しています。+側と-側の電位を比較してアンプから0または1の信号が出力され,そのパルスがローパスフィルタを通してフィードバックされます。そうすると+側と-側の電位差がほぼ0となるところで安定します。このとき,デジタル出力から出るパルスはディジタルローパスフィルタを通すことでAD変換をすることができます。
f:id:taltalp:20160619043945p:plain

ソースコード

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
library UNISIM;
use UNISIM.VComponents.all;

entity adc is
    Port ( clk_240m: in STD_LOGIC;
	   sigin_p : in STD_LOGIC;
           sigin_n : in STD_LOGIC;
           sigout : out STD_LOGIC;
           LED : out STD_LOGIC);
end adc;

architecture Behavioral of adc is
    signal sig : std_logic;
begin

    -- 差動入力
    ibufds_1_i : IBUFDS
        generic map(
            DIFF_TERM => FALSE,
            IBUF_LOW_PWR => FALSE,
            IOSTANDARD => "DEFAULT"
        )
        port map(
            O => sig,
            I => sigin_p,
            IB => sigin_n
        );
    
    process (clk_240m) begin
        if (clk_240m'event and clk_240m='1') then
            sigout <= sig;
        end if;
    end process;

    LED <= sig;
end Behavioral;

I/O Planning

ピンアサイン時にいくつか注意点があるため各ピンについて説明をしていきます。
clk_240m : 240MHzのクロックを入れます。zyboの場合PS側からPL側に供給される100MHzまたはPL側に直接供給される125MHzの信号からClocking Wizard等を用いて240MHzを生成します。
sigin_p, sigin_n : 差動入力に対応したピンに割り当てる必要があります。またI/O StdはTMDS_33に設定しました。
sigout : ここから出た信号はRCローパスフィルタに繋がります。LVCMOS33に設定し,Drive Strengthを16に設定しました。 Xcellの内容には24に設定したと書かれていますが,zynq-7010では16が最大なようです。これをオーバーしないように外付けの抵抗の値を決める必要があります。また,Slew TypeはFastにOff-Chip TerminationはNONEに設定しました。
LED : どこでもいいのですが,今回はとりあえずLEDにデジタル信号を入れてみました。

回路

上に示す回路図のRとCは下記のように設定しました。
R = 10kΩ
C = 33pF
3.3Vの電圧をRCに入力するときに16mAの電流値を超えないように設定しています。周波数特性は特に気にせず適当に決めています。

実験

アナログ入力に可変抵抗器で0~3.3Vまでの信号を入力してLEDの光り方をみてみました。
電圧が低いと暗くなり,電圧が高くなると明るくなります。原理はPWM調光と同じような感じです。(PDM信号)

まとめ

FPGAを使ってADCがとても簡単に、しかも大量に実装することができます。FPGAの差動入力にアナログ信号を入れようという考えは非常に面白いですね。

raspberry pi zero の購入方法とかインストール方法とか

先日、はやりの$5パソコンraspberry pi zeroを入手しました.
購入方法やOSのインストール方法などを簡単に紹介します.

1.購入方法

raspberry pi zeroはまだ日本では売っていないようですので海外の通販で買います.

続きを読む

ESP-WROOM-02を赤外線リモコンに(2.解析編)

前回、ESP-WROOM-02で赤外線通信を行うための準備をしました.
taltalp.hatenablog.jp

今回は実際に回路を組んで、赤外線リモコンのコードを解析してみようと思います。
(といってもサンプルプログラムを動かすだけです)

続きを読む