バスマスタ転送機能を用いて、サンプリング(入力)/ジェネレーティング(出力)する場合の設定手順を説明します。
初期化とモード設定が完了したら、サンプリング/ジェネレーティング条件を設定します。
サンプリング/ジェネレーティング条件には、入出力を開始するための条件(ソフトスタート、外部スタート等)を設定するスタート条件設定(DioDmSetStartTrigger
)、
入出力を行なうタイミング(内部クロック、外部クロック等)を設定するクロック条件設定(DioDmSetClockTrigger
)、
入出力を完了するための条件(ソフトストップ、指定個数停止など)を設定するストップ条件設定(DioDmSetStopTrigger
)
の3種類があります。
また、各設定に対して、それを補足する条件設定関数(例:個数指定停止時の個数設定など)があります。
これらのサンプリング/ジェネレーティング条件設定は、常に同じ条件でデータを入出力する場合には、初期化後に一度行なっておけば、それ以降は同じ条件で動作が行なわれます。
データ転送毎に異なる動作条件で転送を行なう場合には、変更すべき設定のみを、転送開始する前に設定してください。
リセット関数によって、前回の転送時のFIFO内容をリセットする必要があります(DioDmFifoReset )。
■サンプリング:入力
バスマスタ転送は、ボードに転送先のメモリアドレスを設定しておき、転送をスタートするとボードからそのメモリアドレスへデータの転送を行ないます。
従って、転送開始前に入力値を受け取るバッファ領域を、ボードに設定しておかなければなりません(DioDmSetBuffer)。
設定したバッファ領域は、物理的に他のアドレスに移動しないようにロックされます。ロックされた領域は、転送完了によってアンロックされます。
アンロックされた領域に対する転送は危険ですので、バッファの設定は転送を行なう毎にかならず行なわなければなりません。
バッファ領域をヒープやスタックなどに取った場合、この領域は転送が完了するまで、開放されないようにしなければなりません。
転送完了までにバッファ領域が開放されてしまった場合、その領域は他の処理に使用されます。
他の処理に使用されている領域にデータ転送が行なわれると、プログラムが例外を発生してしまう可能性があります。
プログラムの安全性を重視するのであれば、バスマスタ転送に使用する領域は、グローバルな領域を使用することをお勧めします。
また、転送時の動作として、バッファ内にデータを全部転送した時点で転送を完了する1回転送と、
同じバッファ領域に対して無限回数繰り返してデータを転送する無限転送を用意しています。
■ジェネレーティング:出力
バスマスタ転送は、ハードウェアに転送元のメモリアドレスを設定しておき、ジェネレーティングを実行する前に、そのメモリアドレスからボード内のFIFOにデータの転送を行なっておきます。
出力を行なう場合は、出力データを格納したバッファ領域を、ハードウェアに設定しておかなければなりません(DioDmSetBuffer)。
設定したバッファ領域は、物理的に他のアドレスに移動しないようにロックされます。ロックされた領域は、転送完了によってアンロックされます。
バッファの設定は転送を行なう毎にかならず行なわなければなりません。
バッファ領域をヒープやスタックなどに取った場合、この領域は転送が完了するまで、開放されないようにしなければなりません。
転送完了までにバッファ領域が開放されてしまった場合、その領域は他の処理に使用され、出力したいデータ以外のデータが書き込まれます。
そのままの状態で転送が行なわれると、予期せぬデータを出力してしまう可能性があります。
プログラムの安全性を重視するのであれば、バスマスタ転送に使用する領域は、グローバルな領域を使用することをお勧めします。
また、転送時の動作として、バッファ内のデータを全部転送した時点で転送を完了する1回転送と、同じバッファ領域から無限回数繰り返してデータを転送する無限転送を用意しています。
同一データを指定回数だけ繰返して転送したい場合、その回数分のサイズのバッファを用意して、1回転送を使用してください。
サンプリング/ジェネレーティング条件を設定し、バッファを設定したら、動作をスタートします(DioDmTransferStart
)。
動作をスタートすると、スタート条件が満たされた時点でサンプリング/ジェネレーティングが開始され、ストップ条件が満たされた時点でサンプリング/ジェネレーティングが終了します。
ソフトウェアスタートにした場合、DioDmTransferStart関数を呼び出したタイミングで、サンプリング/ジェネレーティングが開始されます。
入力データは、一旦ボード内のFIFOに蓄えられ、バスが空いたタイミングを利用して、アプリケーション中のメモリに転送されます。
出力データは、直ちにボード内のFIFOに送られ、クロック条件が成立した時点で外部に出力されます。
DioDmSetStopTrigger関数で設定したストップ条件が満たされると、サンプリング/ジェネレーティングが終了します。
もしくは、DioDmSetBuffer関数で指定したLengthのデータ個数の1回転送が完了した時も、サンプリング/ジェネレーティングが終了します。
その他、DioDmTransferStop関数を呼び出し強制停止したり、バスマスタ転送中にエラーが発生したときも、サンプリング/ジェネレーティングは終了します。
アプリケーションから動作の終了を捕らえるには、以下の3つの方法が用意されています。
・メッセージによって終了を確認する方法(DioDmSetStopEvent
)
・コールバックによって終了を確認する方法(DioDmSetStopCallBackProc)
・ステータスを監視する方法(DioDmGetStatus
)
基本は、メッセージもしくは、コールバックによる通知を使用します。
ステータス監視を行う場合には、DIODM_STATUS_BMSTOP と DIODM_STATUS_PIOSTOP の両方のステータスを監視します。
ただし、この方法は、ステータス確認のためにデバイスにI/Oすることになるためバスマスタの転送レートが落ちる可能性があります。
サンプリングデータの処理や次の転送準備に入る前に、必ず、いずれかの方法で転送が完了していることを確認してから、次の処理を開始するようにしてください。(DioDmTransferStop
を使用した場合も同様です)
動作途中で、転送数を確認して(DioDmSetCountEvent
)処理を行なうこともできます。
転送完了後には、(DioDmGetStatus)を使用して正常にバスマスタ転送が完了したことを確認するようにしてください。
なお、バスマスタ転送中にデバイスにアクセスするとバスマスタ転送が妨げられます。
そのため 頻繁に(DioDmGetStatus
)を呼び出したり、(DioDmSetCountEvent
)による通知を行うと、転送レートに悪影響が出る可能性があります。
スレッド内で(DioDmSetBuffer)を使用してバスマスタ用のバッファをセットした場合、スレッド終了時にメモリのロックが解除され、バスマスタ転送を強制停止するため、バスマスタ転送が完了するまでスレッドを終了しないでください。
バスマスタ転送機能を使用している場合、通常のデジタル入出力機能を使用することはできません。