今まで、気にしていなかったけど、ふと気づいて確認してみたことがあるのでメモしておきます。
受話器を上げた時に聞こえるダイアルトーン(400Hz)は、DACを使って生成しています。現在は400Hzの波形データを16KHzサンプリングで160サンプル分作っておき、これをDMAでDACに送信することで、トーンを生成しています。DACのDMAトリガとしてはTIM7を設定し、TIM7で16KHz周期でトリガを生成することでDMA要求を生成してやります。
DACのDMA設定では上図に示すようにCircularモードを使用しています。STM32ではDMA転送サイズの半分が完了した時点と、全てが完了した時点で割り込みを発生させることができますので、この割り込みを使って新たな波形データを用意してやれば連続的にトーンや音声を再生することができます。通話音声を再生する際には、DMAトリガをTIM7からI2SのFSYNC信号に切り替えることでWT32から送られてくる音声データとの同期を取っています。
現在のプロジェクトでは上述のように160サンプルの半分である80サンプルを送信する度に割り込みがかかって新たなトーンデータを生成していますが、ダイアルトーンの生成中にデバッガを使ってCPUコアの実行を止めてもダイアルトーンが流れ続けます。なぜならば、CPUコアの実行を止めてもTIM7を止めない限りDMA要求が継続して発生し続けるため、Circularモードではバッファーの内容がDACに対し繰り返し連続して送られることになり、その結果トーン再生が続くからです。16KHz、160サンプルは10ms分のデータ量になります。10msは400Hzの波形データではちょうど4周期分に相当しますので、実は5ms間隔で発生する割り込みによるデータ更新があってもなくてもバッファ内の波形データには変化が生じず、400Hzのトーンを綺麗に連続して再生することができます。
このようにDMAのCircularモードを使用すると、周期の倍数となる長さのデータを用意しておき一度その送信を開始すれば、その後はCPUの介在無しで周期的なトーンを連続して再生することができます。トーン生成以外にも応用できるテクニックだと思うので、何かの機会に使ってみようかと思います。
受話器を上げた時に聞こえるダイアルトーン(400Hz)は、DACを使って生成しています。現在は400Hzの波形データを16KHzサンプリングで160サンプル分作っておき、これをDMAでDACに送信することで、トーンを生成しています。DACのDMAトリガとしてはTIM7を設定し、TIM7で16KHz周期でトリガを生成することでDMA要求を生成してやります。
DACのDMA設定では上図に示すようにCircularモードを使用しています。STM32ではDMA転送サイズの半分が完了した時点と、全てが完了した時点で割り込みを発生させることができますので、この割り込みを使って新たな波形データを用意してやれば連続的にトーンや音声を再生することができます。通話音声を再生する際には、DMAトリガをTIM7からI2SのFSYNC信号に切り替えることでWT32から送られてくる音声データとの同期を取っています。
現在のプロジェクトでは上述のように160サンプルの半分である80サンプルを送信する度に割り込みがかかって新たなトーンデータを生成していますが、ダイアルトーンの生成中にデバッガを使ってCPUコアの実行を止めてもダイアルトーンが流れ続けます。なぜならば、CPUコアの実行を止めてもTIM7を止めない限りDMA要求が継続して発生し続けるため、Circularモードではバッファーの内容がDACに対し繰り返し連続して送られることになり、その結果トーン再生が続くからです。16KHz、160サンプルは10ms分のデータ量になります。10msは400Hzの波形データではちょうど4周期分に相当しますので、実は5ms間隔で発生する割り込みによるデータ更新があってもなくてもバッファ内の波形データには変化が生じず、400Hzのトーンを綺麗に連続して再生することができます。
このようにDMAのCircularモードを使用すると、周期の倍数となる長さのデータを用意しておき一度その送信を開始すれば、その後はCPUの介在無しで周期的なトーンを連続して再生することができます。トーン生成以外にも応用できるテクニックだと思うので、何かの機会に使ってみようかと思います。