何?コード行を入力せずに3線式SPIドライバーを構築しますか?

[ガイド]最近、ZYNQを使用して高速データ取得を行うには、3線式システムを使用して読み取りおよび書き込み機能を実現するADIの高速アナログ-デジタルサンプリングチップにアクセスする必要があります。おそらく誰もがこのように書き込み通信を実現するために3線式システムを使用しています。読み取り/書き込みを実現するための3線式システムは、一部の友人によって使用されていない可能性があります。今日は、既製のIPを使用してコードを記述せずに3線式SPIを実装する方法を共有します。

バックグラウンド

多くのADIチップは、3線式SPIによって制御されます。例としてAD9467を取り上げます。AD9467は、最大250MSPSのサンプリングレートを持つパイプラインアーキテクチャの16ビット高速ADCチップです。一部の複雑なシステムでは、そのアプリケーション分野は非常に広範囲です。

  • マルチキャリア、マルチモードセルラーレシーバー

  • アンテナアレイの位置決め

  • パワーアンプの線形化

  • ワイヤレスブロードバンド通信システム

  • レーダーシステム

  • 赤外線イメージングシステム

  • 通信システム等

チップブロック図から、チップは主に以下の部品で構成されていることが大まかにわかります。

  • 3線式SPI通信インターフェースは、チップのレジスタ読み取りおよび書き込み制御を実現します。主にチップモード構成に使用されます。

  • LVDSインターフェース:データの外部送信を担当し、ANSI-644標準に従います。

  • CLK + / CLK-:は入力クロックです。クロックはデジタルチップにあり、心臓は人間にあります。すべてのアクションはクロックによって駆動されます。

  • VIN + / VIN-:差動入力、アナログ信号入力チャネル。

チップの他の部分については、この記事の焦点では​​ありません。SPIの通信タイミング図を次に示します。

SPIモードのタイミング図と組み合わせる:

  • 立ち上がりエッジのサンプル

  • データの次のビットは、CLKロー期間中に変化します

したがって、CPOL = 0、CPHA = 0です。

さらに、最初のビットは、このメッセージで読み取り操作と書き込み操作のどちらを開始したかを識別するために使用されます。この設計は、I2C標準の読み取りビットと書き込みビットに多少似ていますか?

次に問題が発生します。実行する必要のあるSPI通信では、読み取りと書き込みに3線式SPIを実装する必要があります。

  • シングルチップマイクロメータを使用してIOポートをプログラムする方が簡単ですが、高速ADデータ送信を実現するために、従来のシングルチップマイクロコンピュータは拡張されています。LVDSインターフェースのデータスループットレートを達成することは困難です。

  • また、ZYNQの内蔵SPIペリフェラルも使いやすく、3線式モードに簡単に設定できます。残念ながら、周辺ピンは基本的に使い果たされています。ただし、EMIOを使用して、対応するピンをPL側から引き出すことを検討できます。

  • ZYNQのPS側でGPIOを使用する場合は、それを行うこともできますが、残念ながら、ボードのPS側には多くのGPIOがありません。

  • ザイリンクスのAXIQuad SPI IPを使用して、PL側に実装します。しばらく投げた後、このIPは3線式SPIをサポートしていないようです。

  • verilog HDLを使用してIPを作成し、それをAXIバスに掛けて、Linuxデバイスドライバーを実装します。このソリューションは問題ありません。残念ながら、私は怠惰で、車輪を作り直したくありません!

  • .....。

いくつか投げた後、宝物がADI職員に見つかりました:

https://wiki.analog.com/resources/fpga/peripherals/spi_engine

SPIエンジンIPフレームワークの公式実装:

  • 実行モジュール:メインモジュール。SPIエンジンコマンドストリームを処理し、SPIバスインターフェイスロジックを実装するために使用されます

  • AXIインターフェイスモジュール:メモリマッピングソフトウェアは、SPIエンジンコマンドストリームにアクセスしたり、コアインターフェイスをアンロードしたりできます

  • オフロードモジュール:実行する外部イベントによってトリガーされるSPIエンジンコマンドストリームを保存します

  • 相互接続モジュール:複数のSPIエンジンコマンドストリームをSPIエンジン実行モジュールに接続します

verilogHDLコードベースは次の場所にあります。

https://github.com/analogdevicesinc/hdl.git

PS / PL設計

hdlライブラリをダウンロードし、ウィザードに従ってライブラリを作成し、対応するtclスクリプトを実行して、hdlライブラリに必要なファイルを生成します。次に、必要に応じて次のブロックデザインを設計します。

  • PS側のDDRとPLに必要なクロックFCLK_CLK0を設定し、ここで100MHzを出力します。

  • ipライブラリからaxi_spi_engine_v1_0とspi_engine_execution_v1_0を引き出し、上の図に従って接続します。

  • AXIインターフェイス、および対応するリセット、クロック信号などを接続します。

  • 設定には複数のチップ選択信号が必要です。複数のスレーブチップのニーズに応じて複数のチップ選択信号を設定できます。たとえば、2つのデバイスをLinuxデバイスツリーにマウントするように2つ設定します。

次に、最上位の設計ファイルをインスタンス化します。問題が発生します。spi_1にはまだ4つのピンがあります。PL側のピンに引き出された場合でも、4線式システムですが、どのように変更しますか?

ウィキの写真と説明を見て、それを好転させる必要があることがわかります。

  • 3線式モードの場合、three_wireは1になり、これはAXIバスコマンドを介して渡されます。

  • sdo_tは、sdoの内部信号を出力するかどうかを制御できます。ゲート制御をオフにすると、mosiピンが高インピーダンスになり、外部信号をサンプリングして、入力信号を双方向セレクターを介して読み取り信号に転送できます。

したがって、次のコードを一番上のファイルに追加します。

assign phy_sclk = spi_sclk;
assign phy_cs = spi_cs;
assign phy_mosi = spi_sdo_t ? 1'bz : spi_sdo;
assign spi_sdi = spi_three_wire ? phy_mosi : phy_miso;

たとえば、私はこれを書きました:

`timescale 1ns / 100ps
//顶层设计文件
module system_top (
//DDR信号
inout   [14:0]  ddr_addr,
inout   [ 2:0]  ddr_ba,
inout           ddr_cas_n,
inout           ddr_ck_n,
inout           ddr_ck_p,
inout           ddr_cke,
inout           ddr_cs_n,
inout   [ 3:0]  ddr_dm,
inout   [31:0]  ddr_dq,
inout   [ 3:0]  ddr_dqs_n,
inout   [ 3:0]  ddr_dqs_p,
inout           ddr_odt,
inout           ddr_ras_n,
inout           ddr_reset_n,
inout           ddr_we_n,
//必须的一些PS信号
inout           fixed_io_ddr_vrn,
inout           fixed_io_ddr_vrp,
//54个PS MIO引脚
inout   [53:0]  fixed_io_mio,
//PS时钟引脚
inout           fixed_io_ps_clk,
//PS上电复位信号
inout           fixed_io_ps_porb,
//PS SRSTB信号
inout           fixed_io_ps_srstb,
output [1:0]       spi_0_cs,
output             spi_0_sclk,
input              spi_0_sdi,
output             spi_0_sdo,
);
  
wire ip_spi_0_cs;
wire ip_spi_0_sclk;
wire ip_spi_0_sdi;
wire ip_spi_0_sdo;
wire ip_spi_0_three_wire;   
wire ip_spi_0_sdo_t;

assign spi_0_cs = ip_spi_0_cs;
assign spi_0_sclk = ip_spi_0_sclk;
//如此处理,这样引出的SPI可以兼容3线制以及4线制SPI
assign spi_0_sdo = ip_spi_0_sdo_t ? 1'bz : ip_spi_0_sdo;
assign ip_spi_0_sdi = ip_spi_0_three_wire ? spi_0_sdo : spi_0_sdi;

//例化block设计
ip_block_wrapper i_system_wrapper (
    //DDR以及常规MIO、时钟、复位等信号
    .DDR_addr(ddr_addr),
    .DDR_ba(ddr_ba),
    .DDR_cas_n(ddr_cas_n),
    .DDR_ck_n(ddr_ck_n),
    .DDR_ck_p(ddr_ck_p),
    .DDR_cke(ddr_cke),
    .DDR_cs_n(ddr_cs_n),
    .DDR_dm(ddr_dm),
    .DDR_dq(ddr_dq),
    .DDR_dqs_n(ddr_dqs_n),
    .DDR_dqs_p(ddr_dqs_p),
    .DDR_odt(ddr_odt),
    .DDR_ras_n(ddr_ras_n),
    .DDR_reset_n(ddr_reset_n),
    .DDR_we_n(ddr_we_n),
    .FIXED_IO_ddr_vrn(fixed_io_ddr_vrn),
    .FIXED_IO_ddr_vrp(fixed_io_ddr_vrp),
    .FIXED_IO_mio(fixed_io_mio),
    .FIXED_IO_ps_clk(fixed_io_ps_clk),
    .FIXED_IO_ps_porb(fixed_io_ps_porb),
    .FIXED_IO_ps_srstb(fixed_io_ps_srstb),       

      //连至顶层
    .spi_0_cs(ip_spi_0_cs),
    .spi_0_sclk(ip_spi_0_sclk),
    .spi_0_sdi(ip_spi_0_sdi),
    .spi_0_sdo(ip_spi_0_sdo),
    .spi_0_sdo_t(ip_spi_0_sdo_t),
    .spi_0_three_wire(ip_spi_0_three_wire)     
  );    
endmodule

Linux構成

まず、デバイスツリーを構成する必要があります。

&axi_spi_engine_0 {
    status = "okay";
    //配置SPI控制器匹配字段,这样会自动编译ADI 提供的SPI 控制器驱动
    compatible = "adi,axi-spi-engine-1.00.a";
    spi-rx-bus-width = <1>;
    spi-tx-bus-width = <1>; 
    bits-per-word = <8>;
    interrupt-parent = <&intc>;
    interrupts = <0 30 4>;      
    num-cs = <4>;

    #address-cells = <0x1>;
    #size-cells = <0x0>;    
    ad9467_0: ad9467@0 {
        compatible = "adi,ad9467";
        reg = <0>;
        spi-max-frequency = <500000>;
        #address-cells = <1>;
        #size-cells = <1>;

        spi-rx-bus-width = <1>; 
        spi-tx-bus-width = <1>;
        bits-per-word = <8>;
        spi-3wire;        
    };

    ad9467_1: ad9467@1 {
        compatible = "spidev";
        reg = <1>;
        spi-max-frequency = <500000>;
        #address-cells = <1>;
        #size-cells = <1>;        
 
        spi-rx-bus-width = <1>; 
        spi-tx-bus-width = <1>;
        bits-per-word = <8>;
        //这个字段需要使能,表示该设备是三线制
        spi-3wire;           
    };      
};

LinuxコードベースはADIに基づいて改善されました:

https://github.com/analogdevicesinc/Linux

対応するSPIコントローラードライバーを構成してから、コンパイルしてデプロイします。デモにはプロジェクトの他の技術的な詳細が含まれているため、ここでは説明しません。有効性を見てみましょう。

この波形を見ると、友人から「データ送信が終わった理由、SDO / SDI多重化ピンの波形が立ち上がり、徐々に過渡するプロセス」があります。これは、この時点でスレーブチップが出力状態から高インピーダンス状態に変化し、マスターがこのとき、エンドチップも高抵抗状態にあり、ライン容量効果によりこのような変化が起こります。

結論として

ADIの改良されたIPライブラリを使用すると、コードを1行も入力しなくても、3線式SPIを簡単に実現できます。このソリューションは、3線式/ 4線式SPIと同時に互換性があり、成熟した安定したソリューションです。これは、SOCチップやLinuxなどのZYNQチップが人々に好まれている理由を示しています。成熟したホイールが多数あるため、自分でホイールを作成する必要はありません。製品の研究開発の進捗を加速し、ユーザーが解決する必要のあるアプリケーションの問題に集中できるようにします。これを取り除くためのヒントは次のとおりです。

アプリケーション開発を行うときは、最初に要件を整理します。何をしたいですか?どこに行くの?しかし、コードを急がないでください。最初に既製のホイールがあるかどうかを検索し、ホイールの再発明を拒否してください。それは間違いなく開発プロセスをスピードアップします。ただし、オープンソースリソースを無料で使用できるかどうかにも注意する必要があります。知的財産のIPの問題にも注意してください。


1.ヤン・フユのコラム|新車用のCAN FDでは、まだだまされているかもしれません!

2. SMICの深夜のメロン:Jiang Shangyiが戻ってきて、Liang Mengsongが去りたいですか?

3.米国がエンティティのリストを再発行し、Beili、China Southern Airlines、Southern Institute of Technologyがリストに含まれ、「7人の国防息子」がついに登場しました。

4.分析:世界的なチップ不足は想像を超えています

5. WindowsはAndroidを採用していますが、Microsoftはどのような動きをしていますか?

6.バルクとホールセールのどちらが効率的ですか?可変アクセスは、ARMアーキテクチャによって明確に調整されています

免責事項:この記事はオンラインで複製されており、著作権は元の作者に帰属します。作品の著作権にかかわる場合は、お問い合わせください。ご提供いただいた著作権証明書に基づいて著作権を確認し、作者の報酬を支払うか、内容を削除いたします。

おすすめ

転載: blog.csdn.net/DP29syM41zyGndVF/article/details/111502875