MAX10でADC(アナログ/デジタル変換)を試してみる

はじめに

Intel社(旧アルテラ)のFPGAのMAX10のADC()の使い方を紹介します。使用するボードでDE10-lite(Terasic社)です。ADCの詳細はIntel社の資料:MAX10アナログ-デジタルのコンバータ ー・ユーザーガイドを参照してください。

 セミナー情報<広告>

 手ぶらでOK!実習・ゼロから始めるZynq SoC開発「超」入門

初心者大歓迎!ハード,ソフトのいいとこどり開発に挑戦

2024年5月11日(土) CQ出版社セミナルーム 

詳しくはこちらへ


1.ADCの追加

1-1.元になる設計データの準備
ADCを利用する回路は"Quartus PRIMEでniosⅡ 導入編"の回路に追加するので
予め"Quartus PRIMEでniosⅡ 導入編"に従て設計プロジェクト(max10_nios2e_sys)とNiosⅡプロセッサ用プログラムを作成してください。

1-2.Platform Designerの起動
Quartus Primeで設計プロジェクト(max10_nios2e_sys.qpf)を読み込み、Project Navigatorのmax10_niso2e:u0上で
マウス右ボタンを押してPlatform Designerを選択する

1-3.PLLの追加
ADCを使うには特定の周波数のクロックが必要でALTPLLを使用してクロックを生成します。
Platform DesignerのIP Catlogで"ALTPLL Intel FPGA IP"をクリックしてAddをクリックするとmax10_niso2eにALTPLLが追加される。

1-4.ALTPLLの設定/入力クロック周波数設定
DE10-liteのクロック周波数に合わせて
"What PLL is frequency of the inclk0.0 input?"を50MHzに設定、"Next"をクリック

1-5.ALTPLLの設定/ロック信号の生成
ADCはPLLが安定したかを知るためにlock信号が必要です。
Create an 'areset' input asynchronously reset the PLL"のチェックを外します。
"Lock Output"の"Create"locked oyroyr"にチェックが入っていること確認する。

1-6.ALTPLLの設定/入力クロック周波数設定
ALTPLL設定ウィンドで"Output"タブの"clk c1"をクリック
"Use this clock"にチェックを入れる
"Enter output clock frequency"をマークして2Mhzに設定、"Finish"をクリック

1-7.ALTPLLの設定終了
Finishをクリック

1-8.ALTPLLの接続
Platform Designerの"System Contents"でaltpll_0のクロック、リセット、バスを接続する。
altpll_0のinclk_interfaceとclk_0のclkの接点をクリックして接続
altpll_0のinclk_interface_resetとclk_0のresetの設定をクリックして接続
altpll_0のpll_slaveとnios2_gen2_0のdata_masterの設定をクリックして接続

1-9.ALTPLLのアドレス設定
Platform Designerの"Address Map"でaltpll_0_slaveのnios2_gen2_0_data_masterを
0x0002_0200に設定

1-10.ADCの追加
追加するIPは"Modular ADC"です。ADCとADCコントロール回路がセットになっているIPです。
Platform DesignerのIP Catlogで"Modular ADC Intel FPGA IP"をクリックしてAddをクリックするとmax10_niso2eに"Modular ADC"が追加される。

1-11.ADCの設定/クロック、基準電圧、使用チェンネル
"Clocks"の"ADC Sample Rate"を25Khz、"ADC Input Clock"を2Mhzに設定
"Refarence Valtage"の"Refarence Valtage Source"を"Internal"に設定
"Channels"タブの"CH1"タブで"Use Channel 1"にチェックを入れる。

1-12.ADCの設定/シーケンサー
CHを読み取る順番をシーケンサーに設定します。
"Seguencer"タブの"Number of slot used"を1に設定
"Slot1"を"CH1"に設定
この設定で1回のシーケンスでCH1を1回だけ読み込みます。
右下の"Finish"をクリックする。

1-13."Modular ADC"の接続
Platform Designerの"System Contents"でmodular_adc_0のクロック、リセット、PLLクロック、PLLロック、シーケンサーのバスIF、サンプルデータのバスIF、割込みを接続する。
modular_adc_0のclockとclk_0のclkの接点をクリックして接続
modular_adc_0のreset_sinkとclk_0のresetの設定をクリックして接続
modular_adc_0のadc_pll_clockとaltpll_0のc1の接点をクリックして接続
modular_adc_0のadc_pll_lockedとaltpll_0のlocked_conduitの接点をクリックして接続
modular_adc_0のseguencer_csrとnios2_gen2_0のdata_masterの設定をクリックして接続
modular_adc_0のsample_store_csrとnios2_gen2_0のdata_masterの設定をクリックして接続
modular_adc_0のsample_store_irqとnios2_gen2_0のirqの設定をクリックして接続
ADCの測定端子は予めCH毎に固定されいるので接続の設定はありません。CH1はPIN_F5に接続されています。

1-14."Modular ADC"のアドレス設定
Platform Designerの"Address Map"で
modular_adc_0_sequencer_csrとnios2_gen2_0_data_masterを0x0002_0300に設定
modular_adc_0_sample_store_csrとnios2_gen2_0_data_masterを0x0002_0400に設定

1-15.max10_niso2eのHDL生成
Platform Designerの右下の"Gnerate HDL"をクリック

"Gnerate"をクリック

"Save System Conmpleted"で"Close"をクリック

暫くして"Generate Completed"が表示されたら"Close"をクリック

"Finish"をクリックしてPlatform Designerを終了

1-16.コンパイル
ADCの測定端子は予めCH毎に固定されいるのトップ回路のVerilog-HDL記述とピン配置指定は必要がありません。"Quartus Prime"でコンパイルを実施します。

1-17.電圧生成回路の作成
DE10-liteのJP1のpin29(3.3V)とpin30(GND)を可変抵抗の両端に接続、抵抗可変端子は10KΩの抵抗を介してADC_IN0端子(ADCのCH1の測定端子,PIN_F5)に接続します。


実際の接続の様子

1-18.MAX10へ書き込み
DE10-liteとPCを接続する。
コンパイルが完了したら、"Quartus Prime"の"Programer"でmax10_nios2e_sys.sofを書き込みます。

2.測定用プログラムの作成

2-1.Nios Software Build Tools for Eclipseの起動
"Quartus Prime"で"Tools"→"NiosⅡ Software Build Tools for Eclipse"を選択

ワークスペースの設定
Quartusの作業フォルダ\workspaceに設定

2-2.新規ソフトウェアプロジェクトの作成
"Nios Software Build Tools for Eclipse"(以降SBT)で"File""New""NiosⅡ Application and BSP from Template"を選択

2-3.ひな形プロジェクトの作成
"NiosⅡ Software Examples"の
"SOCP Infomaition File name"にQuartusの作業フォルダ/max10_nios2e.sopcinfoを設定
"Project name"にadc_prog01を入力
"Project template"で"Hello World Small"を選択
"Finish"をクリック

2-4.Cソースコードの作成
adc_prog01のsrcの下のhello_world_small.cを開く
元のソースコードは削除して以下を張り付けてセーブする。

//ADC読み取りプログラム
#include "sys/alt_stdio.h"
#include "alt_types.h"
#include "system.h"
#include "altera_modular_adc.h"
#include "altera_modular_adc_sample_store_regs.h"
#include "altera_modular_adc_sequencer_regs.h"
alt_u8 adc_callback_occurred;
alt_u32 adc_data[MODULAR_ADC_0_SAMPLE_STORE_CSR_CSD_LENGTH];
void adc_callback(void *context) //コールバック関数
{
adc_callback_occurred = 1;
alt_adc_word_read(MODULAR_ADC_0_SAMPLE_STORE_CSR_BASE,adc_data,MODULAR_ADC_0_SAMPLE_STORE_CSR_CSD_LENGTH);
}
int main()
{
  volatile int lp;
  int i;
  int sample_data;
  alt_modular_adc_dev *p_adc;
  alt_u32 *adc_data;
  adc_data = (alt_u32 *) MODULAR_ADC_0_SAMPLE_STORE_CSR_BASE;//サンプリングデータのアドレスをセット
  p_adc = altera_modular_adc_open(MODULAR_ADC_0_SEQUENCER_CSR_NAME); //modular_adcのオープン
  adc_interrupt_disable(MODULAR_ADC_0_SEQUENCER_CSR_BASE); //割込み禁止
  alt_adc_register_callback(p_adc,adc_callback,NULL,MODULAR_ADC_0_SAMPLE_STORE_CSR_BASE);//コールバック関数の登録
  adc_set_mode_run_continuously(MODULAR_ADC_0_SEQUENCER_CSR_BASE); // 連続動作
  alt_printf("Hello from Max10 Nios II!!adc\n");
  adc_start(MODULAR_ADC_0_SEQUENCER_CSR_BASE);//ADCのスタート
  i=0; //select CH1
  while (1){
   for(lp=0;lp<1000000;lp++) ;
   alt_printf("SLOT%x  ",(i+1));
   sample_data=(int)(adc_data[i]&0x0FFF);//サンプルデータ読み出し
   printf("%x ",sample_data);//読み出し値の表示
   sample_data =sample_data>>8;//サンプルデータの上位4bitを取り出し
   while(sample_data>0){//上位4bitの値だけ"*"を表示する
     alt_printf("*");
     sample_data--;
   }
   alt_printf("\n");
  }
  return 0;
}

2-4.ビルド
adc_prog_01の上でマウスの右ボタンを押して"Build Project"を選択


2-5.プログラムの実行
adc_prog01の上でマウス右ボタンを押して"Run As"→"3 Nios Hardware"を選択

 

2-6.プログラムの実行結果
プログラムの実行が開始したら

可変抵抗を動かして電圧を変動させる。その測定結果が"NiosⅡ console"に表示されます。
測定値は12ビットで16進数で表示され、Vで0、3.3Vでfffになります。

以上になります。
Cソースの記述はIntel社のサンプルプロジェクトが参考になります。