[IP][Avalon] I2C master controller wrapper

2010/05/19FPGA::IPimport

はじめに

自作部分はAvalon SlaveにWISHBONEモジュールをぶら下げるためのBridgeのみなので、ほかのモジュールにも転用できるかと思います。

【注意】本記事は、16ヶ月ほど前のコードと資料を元に作成しており、i2c_masterもversionがあがっております.WISHBONEおよびI2Cインタフェース部分にも修正が入っているようなので、最新版での動作保障はありません.現状、環境がないので確認できません…

自製部分のみ、_IP_I2C_v000.zipとして置いておきます。tclも入れておきますが、FatFSのときのように動作確認をしていませんので、ご了承いただきたく。実際に使ったサンプルコードも置いておきます(avalon_i2c.zip)。\いまさらですが、writeしか使ってない模様…。WM8731へは書きっぱなしでよかったのかな... 記憶があいまいデスすみません.

概要

I2C MasterとなるIPです.\本IPは,opencores.orgで開示されている,以下のものをベースとしました.

http://www.opencores.org/
  "I2C controller core"
  Category :: Communication controller
  Name: i2c
  Created: 25-Sep-2001 10:15:03
  Updated: 03-Nov-2008 14:55:35

  Category :: Communication controller
  Language :: Verilog
  Language :: VHDL
  Phaze :: ASIC proven
  Phaze :: Design done
  Phaze :: FPGA proven
  Standard :: Wishbone compliant core
  Development status :: Production/Stable



Rev. 0.9  Release data: 03/07/03
i2c_specs.pdf

収録ファイルと個々の概要説明

  • avalonif_i2c.txt

このファイル.IPの簡単な説明等を記載する

  • avalonif_i2c_hw.tcl

SOPC builderが食うファイル. Avalon-MM I/Fの仕様や追加すべきファイル,パラメータ初期値などの情報が入っている.

  • avalonif_i2c.v

Avalon I/Fを含む本モジュールのtopレベルモジュールを記述したファイル. "i2c_master_top.v"と同等の機能を有す.(moduleとSystem BUSの仲介だけ)

以下、i2cオリジナルに含まれるものです。

  • timescale.v
  • i2c_master_defines.v
  • i2c_master_byte_ctrl.v
  • i2c_master_bit_ctrl.v
  • i2c_master_top.v

実装時の注意事項

I2Cバスの信号である,SDA/SCKは外部Pull Upになり,master/slaveはopen drainで駆動します.本IPも,各信号をLowに落とすときだけ,Padのenable信号を出すように作られています.tope level moduleには,以下の信号が出ています.

  sda_padoen_o
  sda_pad_o
  sda_pad_i
  scl_padoen_o
  scl_pad_o
  scl_pad_i

PADの出力値は,sda_pad_o(scl_pad_o)に出てきます.ただし常にLowでGND接続になります.\PADからの入力は,sda_pad_i(scl_pad_i)を通して行います.\最後に,PADの出力制御は,sda_padoen_o(scl_padoen_o)を用い,active lowです.\highのときは,PADはドライブせず,Hi-Z状態としてください.\※詳細はオリジナルのドキュメントを参照していただきたく.

Verilog-HDLでの記述例を示します.\NEEKなど,シングルマスタを想定してプルアップしていない回路では,コメントアウトしたほうを用いてください.ただしデータに関しては双方向と成るため,Pull Upは必須と成ります.\# I2Cとした時点で,CLK/DAT双方ともPullUpすべきだと思うのですが...

module xxx (
  inout HC_I2C_SDAT,
  HC_I2C_SCLK,
  ...
 ) ;


assign sda_pad_i = HC_I2C_SDAT ;
assign HC_I2C_SDAT = (sda_padoen_o==1'b0 ? sda_pad_o : 1'bz) ;
assign scl_pad_i = HC_I2C_SCLK ;
assign HC_I2C_SCLK = (scl_padoen_o==1'b0 ? scl_pad_o : 1'bz) ;
// assign HC_I2C_SCLK = scl_padoen_o ; // if Single Master and No-Pull Up(for NEEK)


slave address = 7'b0011010 @ CSB = Low at NEEK


ハードウェア仕様

モジュールのアドレス空間

offset symbol description
0Status / RxData
1Command Register
2Control / TxData
3preI2C clock prescaler

"Command"

7STASTART condition
6STOSTOP condition
5RDRead Data
4WRWrite Data
3ACKwhen receiver(1:ACK/0:NACK)
2-
1-
0IACK1書き込みで要因クリア

"Control / TxData"

31ENEnable I2C core
30IENinterrupt enable
29-24-reserved
23-8-reserved
7-0txdataTransmit data. slaveアドレス送信時はLSBがdirection(1:R/0:W)を示す

"Status"

31-16-reserved
15RxACKスレーブからのACK受領ステータス.0で受信,1で未受信
14Busy1:STArt detected, 0:STOp detected
13ALArbitration Lost
12-10reserved
9TIP1: 転送中, 0:転送完了
8IF割込みフラグ.転送完了もしくはArbitration Lostでたつ
7-0rxdata

プリスケーラの値は,下記の算出式により得ることができます.

(document 3.2.1参照)
IPの動作クロックを f_clk[Hz],SCLKの周波数を f_sclk[Hz]とします
  value of pre-scaler = f_clk / (5 * f_sclk) - 1

ex.)
  f_clk  = 18.432MHz
  f_sclk = 500kHz

  value of pre-scaler = 18432 / (5 * 500) - 1  = 6.3728 => 7