「そのうちにやろう。」と思っていたものの、放置状態だった作業をようやく片づけました。その作業とは、I2SのDMA対応。ATMEL SAM7のとっても簡単に使えるPDCに慣れてしまったわたしには、LPC2388のGPDMAの使い方は恐ろしく複雑に感じられ、ずっと敬遠したままになっていたのです。そのため、I2Sの送受信はずっと割り込みでおこなっていました。
44.1KHzのサンプリングレートでは、毎秒44100回のデータ送受が必要になります。これだけの頻度で割り込みが発生すると72MHzのLPC2388でもかなりの負荷になってしまいます。割り込み負荷を軽減するために、LPC2388では8レベルのFIFOを持っており、割り込みをかけるトリガのレベルを指定できるようになっています。この機能を使うことで割り込み回数を半分程度にできるので実用上は問題無いのですが、それでもDMAを使えばさらに大幅にプロセッサの負荷を軽減できます。他の作業もひと段落ついた状態なので、ようやくとこの作業に着手することにしました。
改めてマニュアルを読んでみると、まぁ概要は理解できたのですが、マニュアルでのI2SのDMAに関する記述はとてもわかりにくく感じました。I2S側ではDMA1とDMA2がありますが、これをGPDMA側ではI2SのChannel 0とChannel 1と呼んでいるようです。用語統一するか、ちゃんと関係を説明して欲しいところです。
実際にコードを書いて、いちおう動くようにはなったのですが、それでもまだちゃんと理解できていないのが、DMACCxControlに設定するDWidth, SWidth, DBsize, SBsizeの値。DWidth, SWidthの方はワード単位でいいでしょうから2を選択。DBsize, SBsizeの選択の仕方がわかりません。I2S側からDMA転送要求を出すFIFOレベルの設定を4にしたので、こちらも転送要求数4に対応する1を選択してあるのですが、これが正しい考え方なのか、適切な値なのかがわかりません。試しにちょっと値を変えてみても違いが区別できませんでした。
DMAで用いるLinked List Itemは次↓のようにしてみました。
![](https://blogimg.goo.ne.jp/user_image/22/13/457c958bc8243ac30c1df20c002c76c0.jpg)
USB RAM上に用意したリングバッファに対応するように、LLIも循環リストとしてあります。このままだと、バッファ中のデータを繰り返し送信するだけですが、各LLIの転送が終了すると割り込みをかけることができますので、これを契機にバッファ中のデータを更新してやることで、音楽を連続して再生できるというわけです。つまり、LLIはいったん設定した後は更新しなくてもいいというわけです。
I2SはFMチューナからの受信の際にも入力として利用していますが、そちらについては次回の記事に書くことにします。
44.1KHzのサンプリングレートでは、毎秒44100回のデータ送受が必要になります。これだけの頻度で割り込みが発生すると72MHzのLPC2388でもかなりの負荷になってしまいます。割り込み負荷を軽減するために、LPC2388では8レベルのFIFOを持っており、割り込みをかけるトリガのレベルを指定できるようになっています。この機能を使うことで割り込み回数を半分程度にできるので実用上は問題無いのですが、それでもDMAを使えばさらに大幅にプロセッサの負荷を軽減できます。他の作業もひと段落ついた状態なので、ようやくとこの作業に着手することにしました。
改めてマニュアルを読んでみると、まぁ概要は理解できたのですが、マニュアルでのI2SのDMAに関する記述はとてもわかりにくく感じました。I2S側ではDMA1とDMA2がありますが、これをGPDMA側ではI2SのChannel 0とChannel 1と呼んでいるようです。用語統一するか、ちゃんと関係を説明して欲しいところです。
実際にコードを書いて、いちおう動くようにはなったのですが、それでもまだちゃんと理解できていないのが、DMACCxControlに設定するDWidth, SWidth, DBsize, SBsizeの値。DWidth, SWidthの方はワード単位でいいでしょうから2を選択。DBsize, SBsizeの選択の仕方がわかりません。I2S側からDMA転送要求を出すFIFOレベルの設定を4にしたので、こちらも転送要求数4に対応する1を選択してあるのですが、これが正しい考え方なのか、適切な値なのかがわかりません。試しにちょっと値を変えてみても違いが区別できませんでした。
DMAで用いるLinked List Itemは次↓のようにしてみました。
![](https://blogimg.goo.ne.jp/user_image/22/13/457c958bc8243ac30c1df20c002c76c0.jpg)
USB RAM上に用意したリングバッファに対応するように、LLIも循環リストとしてあります。このままだと、バッファ中のデータを繰り返し送信するだけですが、各LLIの転送が終了すると割り込みをかけることができますので、これを契機にバッファ中のデータを更新してやることで、音楽を連続して再生できるというわけです。つまり、LLIはいったん設定した後は更新しなくてもいいというわけです。
I2SはFMチューナからの受信の際にも入力として利用していますが、そちらについては次回の記事に書くことにします。