//--------------------------------------------------------------------------
//  NUCLEO-F446RE で，アナログ信号の入出力の際に，出力の標本化周波数を，
//  入力の標本化周波数の４倍にするクラス MultirateLiPh の使用例
//
//  MultirateLiPh クラスは出力の補間フィルタに直線位相 FIR フィルタを使用
//
//  処理の内容：AD 変換器からの入力をそのまま DA 変換器に出力する
//
//  2023/01/15, Copyright (c) 2023 MIKAMI, Naoki
//--------------------------------------------------------------------------

#include "MultirateLiPh.hpp"    // マルチレート処理用
#pragma diag_suppress 870   // マルチバイト文字使用の警告抑制のため
using namespace Mikami;

#define FIR_INTERPOLATOR_DEFAULT
// 補間フィルタの係数として，デフォルト以外の係数を使う場合の例：
//      16 行目の #define 文を無効にし，以下の #define 文のいずれかを有効にする
//#define FIR_INTERPOLATOR_ORDER94    // 94 次のフィルタで補間を行う場合
//#define FIR_INTERPOLATOR_ORDER4     // 補間を行わない場合

const float FS_ = 10;       // 入力の標本化周波数： 10 kHz

#ifdef FIR_INTERPOLATOR_DEFAULT
// 出力標本化周波数を４倍にするオブジェクト（デフォルトの補間フィルタ係数を使う場合）
MultirateLiPh myAdDa_(FS_);
#else
// 次の行はデフォルト以外の補間用フィルタ係数を使う場合
#include "coefficients.hpp"     // デフォルトの補間用フィルタの係数を使う場合は不要
MultirateLiPh myAdDa_(FS_, ORDER_, HK1_, HK2_, HK3_);
#endif  // FIR_INTERPOLATOR_DEFAULT

// 信号処理に割り当てられる処理時間を見積るために使用
// 標本化周波数が 10 kHz の場合
//int us_ = 50;   // OK
int us_ = 90;   // 70 次: OK, 94 次: OK
//int us_ = 91;   // 70 次: OK, 94 次: NG
//int us_ = 92;   // 70 次: NG, 94 次: NG

// ソフトウェア割込みに対する割込みサービス･ルーチン
void SwiIsr()
{
    float xn = myAdDa_.Input(); // 入力
    //-----------------------------------------------------------------
    // 実際には，ここにディジタルフィルタなどの処理を記述する
    wait_us(us_);   // 信号処理に許される実行時間を見積るため
    // ここの処理時間が長すぎる場合はおかしな出力波形になる
    // 実際の信号処理では，この関数は不要
    //-----------------------------------------------------------------
    myAdDa_.Output(xn);         // 出力
}

int main()
{
    printf("\r\nAD 変換の結果をそのまま DA 変換します\r\n");
    printf("DA 変換の際はアップサンプリングを行います\r\n");
    printf("wait: %d [μs]\r\n", us_);

    myAdDa_.Start(&SwiIsr); // 標本化を開始する

    while (true) {}
}
