2025/04/23 (2025年04月 のアーカイブ)
Seeed Studio XIAO RA4M1 でDAC出力(レジスタアクセスとDMA)
この間から触っている XIAO RA4M1 ですが、DAC を叩いてサイン波を出すサンプルを GitHub に置きました。
https://github.com/g200kg/arduino-r4-ra4m1-dac12-example

その1
RA4M1_DAC12_RegisterWrite
analogWrite() は内部で何か余計な処理をしているみたいなので、レジスタを直接叩いて波形を出力します。
サンプリングレート 44100Hz で 440Hz サイン波を出すサンプルです。

DAC は 12bit で 0~4095 のデータを右詰めで使用しています。タイマーは FspTimer の AGT1 を使用して割り込み処理内で DAC を叩きます。ついでに割り込み処理にどれくらいの時間がかかっているか D1 ピンに信号を出して確認しました。
HI = main loop
LO = interrupt
割り込み処理内の負荷は全体の10%くらいなので、これでもまあそこそこの波形生成処理はできそうではあります。
その2
RA4M1_DAC12_DMA
せっかくなのでペリフェラルにもう少し仕事をしてもらって DMA で出力バッファから直接 DAC を叩きます。
DMA はレジスタが多くて設定が面倒ですが、これで CPU の割り込み処理無しで出力バッファから勝手に DAC 出力されます。
DMA はノーマルモードのフリーラン状態にしておきタイマーイベントでキックする度に 16bit データを一つずつ DAC に送る形です。ポイントは出力バッファを「拡張リピート領域」と呼ばれる設定にする事で、転送元アドレスの下位ビットだけが更新されるようにしてリングバッファとして機能しています。なおこのため、出力バッファは 512byte 境界に配置する必要があるので下の宣言になっています。
uint16_t DACOut::buff[DACOut::buffSize] __attribute__((aligned(512)));
タイマーは RegisterWrite と同じく AGT1 を使用していますが ICU_DELSR0 レジスタにイベント AGT1_AGTI を設定する事で DMA へのトリガーとなります。
ライセンスは制限無しで好きなように使って良い Unlicense ライセンスにしていますので興味があればどうぞ。
Posted by g200kg : 2025/04/23 09:55:01