[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 

2009/02/12(木)[SOPC][IP] MMC/SPI FatFs

[SOPC][IP] MMC/SPI FatFs

MMC/SDカードのアクセスを行うためのIPです.\ オリジナルは長船さん作成のVHDLで記述されたものでした.\ Verilogに移植して,ソフトウェア部分もFatFs(R0.06, Apr 01, 2008)に 差し替え,BBSにあったLFN対応パッチもマージしました*1.\ それぞれNEEK向けに修正*2してあります.


*1 : ただし,7bit文字のみ対応.2バイト文字はUNICODEになるので,このままではうまく認識されません.

*2 : WP/CS信号を常時Lowに変更.tclを編集\ set_interface_property avalon_slave_0 addressSpan 1024

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

  • avalonif_mmcdma.txt\ このファイル.IPの簡単な説明等を記載する
  • avalonif_mmcdma_hw.tcl\ SOPC builderが食うファイル. Avalon-MM I/Fの仕様や追加すべきファイル,パラメータ初期値などの情報が入っている.
  • avalonif_mmcdma.v\ Avalon I/Fを含む本モジュールのtopレベルモジュールを記述したファイル.
  • SDIF.v\ SPIモードのビット転送モジュール.
  • SDIF_MEM.v\ Mega Wizardで生成したSRAMモジュール.\ 8bit write, 32bit readの512bytesメモリ.\ 出力にはバッファを設けず,readaddressにしたがってq出力が出てくるようにしてある.

ダウンロード


ハードウェア仕様

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

offset symbol description
0statusSPIステータス,送受信データ(8bit)
1divideSPI clockに用いるmodule入力クロックの分周比(FofSCK = 入力周波数/divide/2)
2timerタイムアウト検出用ダウンカウンタ(module input clockで動作).0で止まる
3reserved0(予約/現実装ではstatusが見える)
4dmastatusDMAステータス
5~reserved[123](予約)
128~readbuff[128]DMA転送バッファ(現状読み出しのみ)

※offsetは,32bit word指定.CPUからのアドレスは x4して見える.※使用メモリ256Word = 1024Byte = 10bit

ビットフィールド

status(MMC IF status) レジスタ
bit description mmc_spi.hシンボル
31-16const zero-
15割込み許可フラグ1:mmc_irq_enable
14-13const zero-
12MMC I/F FRCゼロフラグ1:mmc_zf_bitmask
11MMC-Write Protect1:mmc_wp_bitmask
10MMC-Card Detection1:mmc_cd_bitmask
9MMC I/F転送フラグ(0書き込みで転送開始要求)1:mmc_commexit / 0:mmc_commstart
8MMC Chip Select(Active Low)1:mmc_selnegete / 0:mmc_selassert
7-0MMC I/F受信データ8bitデータ.読み出し=RxData,書き込み=TxData(txdataのリードバック不可)

dmastatus レジスタ
bit description mmc_spi.hシンボル
31-16const zero-
15DMA function IRQ enable bit(1:enable, 0:disable)mmc_dmairq_enable
14assert(0->1) when transfer-endsmmc_dmadone_bitmask
131:受信データエラー@SPImmc_dmade_bitmask
121:受信タイムアウト@SPImmc_dmato_bitmask
11const zero-
10w1:転送開始,r1:転送中/r0:転送終了mmc_dmastart
9const zero-
8-0転送バイト数-


ハードウェアの動作イメージ

MMC/SDからのデータ読み出し

読み出し時,DMA機能を用いることで,本モジュールのアドレス空間に配置されているバッファメモリにSDからのデータを転送することができます.
MMC/SDからの転送は,byte単位で行われるため,CPUで転送するよりは高速な読み出しが可能でしょう.\ただし,転送できるメモリは本モジュール内の先頭からのみという制約もあります.

※ポートを読み出してのPIO転送も勿論可能です.

Avalon-MM Master portを増設し,Avalon-DMAを内包すれば,任意の空間への転送も可能となるでしょう.


MMC/SDへのデータ書き出し

書き込みについては,バッファからの転送は未サポートであり,PIO転送する必要があります.



注意事項

DMA転送を要求した際には,SDIF module(SDIF.v)のアクセスを本IPのtop level moduleが行うため,ユーザがCPU等からアクセスしてはいけません.\dmastatusの読み出し動作のみ許容します.(DMA転送の終了をポーリングで知るため)\SDIFのほかのレジスタへのアクセスを試みても,本IPのステートマシンがSDIFへのアクセスを占有し,statusレジスタの値しか参照できない状態となります.