マイコン(Master)とZynq(Slave)をI2C通信する方法 (2)Zynqのハードウェア構成

Vitis
スポンサーリンク

本記事の概要

概要

I2C(Inter-Integrated Circuit)規格でマイコンとZynqをデータを通信する方法を解説。実験に用いるマイコンには、Wio TerminalのATSAMD51P19を選ぶ。まず、マイコンの方をマスター(Manager, Master)として、スレーブ(Subordinary, Slave)であるZynqからデータを要求する。
本記事では、Zynq内部のブロックデザインの構成について解説する。

前回の記事から、センシングデバイスをI2C通信で制御する知見を得るため、I2C通信規格について学ぶとともに、ZynqとWio TerminalのマイコンATSAMD51P19とのI2C通信に挑戦しています。

Wio Terminalを駆使して自宅で使えるIoTデバイスを作りたいなと思う日々を過ごしています…。

前回の記事では、Wio TerminalとZyboの接続方法について構想がまとまったので、実際に本記事から、Zynqとマイコンの中身を作っていきます。
まずは、Zynqの土台となるハードウェア構成、ブロックデザインを解説したいと思います。

本記事の対象読者:以下の状況に直面している方
  • I2C通信の動作原理、構成について知りたい場合
  • ZynqのプロセッサからI2C通信を行うAPIドライバの使用方法を知りたい場合
  • Wio Terminalを使った、外部機器とのI2C通信の方法を知りたい場合

今後の記事では、以下の順に解説をしていきます。

  1. I2C通信の概略とデバイス間の接続方法
  2. Zynqにおけるブロックデザイン(←本記事)
  3. サンプルプログラムxiicps_intr_slave_example.cにおけるドライバAPIの動作原理
  4. Wio Terminalの制御コード(Arduino)

ZynqでI2C通信する方法

ZynqでI2C通信をする方法は、主に次の3つになります。

ZynqでI2C通信をする方法
  1. Zynq PSのI2CペリフェラルのMIOから直接Pmod MIO(JF)で外部と通信
  2. Zynq PSのI2CペリフェラルのEMIOからPLを経由して、Pmod JB-JEで外部と通信
  3. AXI IIC Bus InterfaceというIPを使うなど、I2Cに変換するロジック回路をPL部に生成して、Pmod JB-JEで外部と通信

それぞれの3つについて解説する前に、まずZynqのアーキテクチャ、特にI/Oの構成を見ておくとわかりやすいです。

Zynq PSのEMIOとMIOについて

Zynq-7000アーキテクチャの機能ブロック図を抜粋しました。
左のほうに、MIOとEMIOという表記が見えると思います。

https://japan.xilinx.com/support/documentation/data_sheets/j_ds190-Zynq-7000-Overview.pdfより抜粋

このアーキテクチャの構成とZyboの回路図をもとに、Pmod周りのI/O構成についてポイントを整理してみました。

MIO(Multiplexed I/O)は、ZynqのPS部と直接接続できるI/Oピンです。I2CやUARTなど各種ペリフェラルがすでにPS部内部に搭載されており、そのペリフェラルからZynqの外部と信号を送受信するためのI/Oピンになります。

一方で、EMIO(Extended MIO)は、MIOのように外部と信号をやり取りするための入出力ピンではなく、PL(Programmable Logic)部と信号を送受信するためのI/Oになります。

つまり、MIOとEMIOの違いは、PS部からの出力先が、MIOでは外部入出力ピン、EMIOではPL部になっているという点になります。

ZyboのPmodとの関係

ZynqのI/OピンとZyboのPmodとの接続は、Zyboの回路図に基づくと、上のブロック図のようになっています。

すなわち、

  • Pmod JFはプロセッサ部分(PS部のMIO)と接続されている
  • Pmod JA~JEはFPGA部分(PL部の外部出力ピン)と接続されている
    • さらに、Pmod JAは、FPGAの多目的I/Oピンと接続されていて、XADCという「Zynq内に内蔵されているADC(Analog-Digital Converter)」と接続可能(普通の汎用I/Oとしても使用可能)

ここでは詳細を割愛しますが、XADCはハードウェア・モジュールとして、Zynq内に予め実装されています。これを使えば、アナログ信号を受け取り、AD変換することが可能です。

ZynqでI2C通信をする方法

ブロック図を踏まえ、ZynqでI2C通信するための主な3つの経路を図示しました。

①は、Zynq PSから直接Pmod MIO(JF)で外部と通信という経路です。
PS部にはすでにI2C向けのペリフェラルが用意されているので、それを利用します。ペリフェラルでI2Cのプロトコルに従う信号を作り、MIOを介して直接外部と入出力しています。

②は、Zynq PSからPLを経由して、Pmod JB-JEで外部と通信という経路です。
PS部に用意されているI2C向けのペリフェラルを利用するのは①と同じですが、外部に直接出力せずに一旦EMIOでPL部に信号を送ってから、汎用I/Oなどから外部に出力しています。
本記事の通信では、この②を採用しています。

③は、「インターコネクトからPL部に信号を送り、 PL部でI2C向けの信号を生成してからPmod JB-JEで外部と通信という経路です。
このI2C向けの信号を生成するのに、AXI IIC Bus InterfaceというIP が利用できます。
自作でI2Cのプロトコルに変換するためのロジック回路を作成することも可能です。

ZynqではすでにI2C向けのペリフェラルが実装されているので、③を採用することはあまりないかもしれません。一方で、Microblazeのようにプロセッサをロジックで構築するときなどは有用な方法になります。

以上で、Zynq上でI2C通信する方法が理解できたので、ブロックデザインを実際に作成していきましょう。

ハードウェア設計

Vivadoでのブロックデザインの作成

まずは、Vivadoを立ち上げます。

Hello worldプログラムを構築した時と同様に、Zynqプロセッサのみをまずブロックデザイン上に配置します。
ブロックデザインの構築方法は以下の記事をご覧ください。

下の図のように、PS部を意味するIPコアを用意します。クロックも接続しておきましょう。

では、IPコアをダブルクリックし、I2Cペリフェラルの接続を設定します。

図のように、[MIO Configuration]のタブを選択し、I2C0のチェックボックスにチェックを入れます。すると、I2C0のペリフェラルをどのMIOに接続するかを選べますので、[EMIO]を選択します。

なお、先ほどのZynqの機能ブロック図をご覧いただけばわかるのですが、I2CのペリフェラルはZynq内に2つ実装されています。I2C0とI2C1がその2つです。

ちなみに、EMIO以外に、このウィンドウ上でMIOの各ピンを選択することも可能です。もし、先ほど解説した 「①Zynq PSから直接Pmod MIO(JF)で外部と通信 の経路で、外部と通信したい場合は、適切なMIOピンを選択します。Zyboなら、下の表にあるMIOを選択すればPmod MIO(JF)から送受信できるようになります。

https://digilent.com/reference/programmable-logic/zybo/reference-manualより。

話を戻しますと、EMIOを選択した場合、ブロックデザイン上でIPコアから図のように[IIC_0]というポートが追加されます。

ポートが追加されるということは、PL部に信号が入出力されることを意味します。

この後、ユーザーがPL部でデザインしたロジックに自由に接続することができるようになります。今回は、特にユーザーロジックを作る予定はありませんので、そのまま外部出力しましょう。

上の図では、このポート[IIC_0] を右クリックして、[Make External]を選択して、外部端子を追加しています。このときの外部端子はPL部につながるI/Oピンになり、後で制約ファイル上でピン配置を設定していくこととします。

以上で、ブロックデザインの構築は完了です。

制約ファイルの作成

IIC_0_0がFPGAのどのピンから出力されるか、制約ファイル上で定義します。

制約ファイル[ZYBO_Master.xdc]に、以下の記述を追加しました。

#Pmod JB(Hi-Speed) JB1
set_property PACKAGE_PIN T20 [get_ports IIC_0_0_scl_io] 
set_property IOSTANDARD LVCMOS33 [get_ports IIC_0_0_scl_io]

#Pmod JB(Hi-Speed) JB2
set_property PACKAGE_PIN U20 [get_ports IIC_0_0_sda_io]
set_property IOSTANDARD LVCMOS33 [get_ports IIC_0_0_sda_io]

論理合成、配置配線、bitstreamファイルの作成、XSAファイルの作成

それでは、ブロックデザインの読み込みと制約ファイルの修正が完了したので、論理合成からXSAファイルの作成までを一気に行っていきます。

前回の記事と重複する内容になりますので、改めて確認したい方は[+]マークから詳細をご確認ください。

ブロックデザインからHDL記述への変換

読み込んだブロックデザインをもとにHDL(ハードウェア言語)を作成します。
ブロックデザインのデザイン名を右クリックし、[Create HDL Wrapper …]を選択します。

論理合成、配置配線、bitstreamファイルの作成

[Generate Bitstream]をクリックし、論理合成、配置配線、bitstreamファイルの作成までを行います。

ハードウェアデザインのエクスポート(XSAファイルの作成)

[File]から[Export]>[Export Hardware…]を選択

立ち上がった新しいウィンドウ上で、エクスポートの設定を確認していきます。
まず、[Next]をクリックします。

[Include bitstream]を選択し、[Next]をクリックします。

ファイル名とエクスポート先を指定し、[Next]をクリックします。

最後に、[Finish]をクリックして完了です。

ひがし
ひがし

お疲れさまです。

センサを活用したIoTデバイスづくりをやってみようと思い、手始めにI2C通信の実装が難しそうでしたので、簡単な回路から作成してみました。
次回の記事では、ソフトウェア部分について解説しようと思います。

最後までご覧いただきありがとうございました!

スポンサーリンク


次回の記事のリンク

参考:コードの動作を確認したシステムの構成

開発環境

環境
  • 開発用PC: Windows 10, 64bit
    • Vivado Design Suite – HLx Edition – 2020.2
    • Vitis コア開発キット – 2020.2
  • 開発用基板: Zybo Zynq-7010評価ボード(Board Rev.4)
    • Zynq XC7Z010-1CLG400C
  • 開発用マイコン: Wio Terminal
    • ATSAMD51P19

開発ボード Zybo Zynq-7010評価ボード

コメント