SAMD21マイコンで作るDRSSTC用インタラプタ設計チュートリアル
Arduino MKR ZEROとSeeed XIAO SAMD21で採用されている「ATSAMD21G18」を使用したインタラプタを考えてみます。
特に、Seeed XIAO SAMD21に関しては秋月電子通商で850円と非常に安価です。
(Seeed XIAO SAMD21について発売時はSeeeduino XIAOという名前でしたが変更がありました)
Arduino IDE 2系にて開発する前提で話を進めていくので環境(ボード定義の追加)を整えておいてください。
ATSAMD21G18のデータシートを確認してみよう
マイコン製造元のMicrochip Technology - ATSAMD21G18のページを確認してみましょう。
ページ下部の「Documentation」セクションにデータシートが存在しています。
このPDFの情報が1次情報となります。
名前の通り、データシートとなっていて、マイコンを扱う上でのすべての情報が載っています。
エラッタというのは不具合の一覧のことです。うまく動かない際に確認するとエラッタを踏んでいる場合があります。
マイコンのデータシートは日本語版もある場合もありますが、翻訳が間違っているなどの場合があるのでできるだけ英語版を見るようにしましょう。
(稀にデータシート自体が間違っていることもあるにはあるのですが…)
ATSAMD21G18のペリフェラル機能は?
データシートPDFの14ページの表(Table 2-1)を参考にしましょう。
このデータシートはSAMD21ファミリのデータシートですので、型番によって実際に載っているペリフェラルなどに差があります。
今回使用するのは「ATSAMD21G18」ですので、表の項目を見てみましょう。
USB | SERCOM | TC | TCC | I2S | DMA | ADC |
---|---|---|---|---|---|---|
あり | 6 | 3 | 3 | あり | 12 | 14 |
抜粋したのがこの表になります。
何がなんだかよくわかりませんよね?
ペリフェラル - USBとは(データシート:691ページ)
その名の通りUSBの通信機能を搭載しているかどうかです。
Seeed XIAO SAMD21等ではコンピューターとの通信(プログラムの書き込み)にも使用するようになっています。
もちろんプログラム次第で様々な通信も可能で、USB-MIDIの代わりをさせることも出来ます。
ペリフェラル - SERCOMとは(データシート:408ページ)
これはSAMDマイコンに搭載されている「Serial Communication Interface」ペリフェラルのことで、様々な通信方式を切り替えて使用できるものです。
設定次第でUSART(シリアル通信)、SPI、I2Cを切り替えて使用出来ます。
MIDIを受けて発音するにはシリアル通信が必要になるので、SERCOMを1つは使用する形になると思われます。
また、外部にADCやDAC、各種センサーを始めとするIC類を使用する場合、SPIやI2C通信を使用することが多いです。
ペリフェラル - TCとは(データシート:555ページ)
「Timer/Counter」ペリフェラルのことで、タイマーやカウンターとして動作することができるものです。
基本的には16bitのタイマー・カウンターとなっていて、2つのTCを使用して32bitのタイマー・カウンターとして使用することができるようです。
その名の通り、カウンターが入っているものですが、どのような動作をするのでしょうか?
データシートの556ページにブロックダイアグラムが載っています。
上部のBASE COUNTER(カウンター)は数を数える部分です。
設定したクロックで駆動され、順にカウントアップやカウントダウンを行えるものです。
そして、下部にはCompare/Capture(コンペア・キャプチャ)があります。
図中に書かれたCC0というのが値を入れるレジスタ(変数のようなもの)で、CC0に設定した値とカウント値を一致するかを確認できるのです。
また、そこからWAVE FORM GENERATION(波形生成)という部分を介して外のWOx Outに繋がっています。これは外部のピンです。
つまり、カウントアップして指定値になったとき等に信号を出力するなどという動作ができるのです。
例えば、クロックを1us単位に設定して1usごとにカウントアップされるように設定したとしましょう。
CC0に100を指定すれば、カウントアップして100になるまで、つまり100us秒経過するまで外部のピンをONにし信号を出力する、などといったことが実現できるのです。
ペリフェラル - TCCとは(データシート:616ページ)
「Timer/Counter for Control Applications」ペリフェラルで、TCペリフェラルを拡張させたものになります。
動作自体はTCと同じでタイマーとカウンターが搭載されたペリフェラルですが、Compare/Capture(コンペア・キャプチャ)が増やされ、波形生成機能が高機能になっています。
Hブリッジを駆動させたい場合など、複数の出力が必要になるときに活用できる高機能なペリフェラルという認識で大丈夫かと思われます。
もちろん、普通にタイマーとして使用することもできます。
TCペリフェラルでは2つ使用することで32bitにすることが出来ましたが、TCCの場合は1つでも24bitに設定可能で、カウンター部分も高機能になっています。
ペリフェラル - I2Sとは(データシート:525ページ)
「Inter-IC Sound Controller」ペリフェラルで、オーディオのやり取りをするための通信を担うものです。
I2Sとは、I2Cとまた別で、デジタル音声データをやり取りするための規格です。
デジタルの音声と聞くと、S/PDIFを思い浮かべる方も居るでしょう。
I2Sでは主に基板上でのIC間のデジタル音声データ接続を念頭に設計されている規格です。
I2Sデジタルマイクを繋いで音声入力をしたり、I2S DAC・アンプを接続してスピーカーから音を出すというようなことが出来ます。
今回のことには関係ないのでは?と思うかもしれません。
I2Sではオーディオデータをシリアルで出力します。
オーディオにとらわれず見方を変えてみましょう。すると単純にシリアライザーとして動作しているペリフェラルに見えます。
シリアライザーなのでパラレルでビット列を渡すと勝手にビット単位で順次ピンから出力することができるということです。
これは波形データを一定周期ずつ内部で生成できれば使えそうなペリフェラルだと思いませんか?
出力のクロックが柔軟に設定できれば使える可能性もあるでしょう。
こういうことを念頭に置いてペリフェラルを調べるということに挑戦してみてください。
ペリフェラル - DMAとは(データシート:268ページ)
「Direct Memory Access Controller」ペリフェラルでDMAを担当します。
DMAとは何か?それはCPUを使わずにバスを通じてデータを転送することです。
人間の作業で例えてみましょう。
大量の荷物を運びたい場合に、自分で運ぶと、運んでいる間は他の作業ができませんよね?
しかし、運送屋さんが来てくれたとしましょう。
自分は運送屋さんに「この荷物をここまで運んで」と指示すれば勝手に運んでくれる上に、自分は他の作業をすることが出来ます。
DMAとはそういう仕組みのことです。
CPUが自分でデータを転送せずに、勝手にデータを運ばせる、なのでCPUの負荷を下げることが出来るというものです。
DMAの設定自体、難しい部類に入るので最初のうちは気にせず「こういうのもあるんだな」ぐらいで認識しておくといいと思います。
ペリフェラル - ADCとは(データシート:780ページ)
「Analog-to-Digital Converter」のことです。
アナログをデジタルに変換します。
ピンに入力されている電圧を測定して、数値に変換(デジタル化)するというものです。
タイマーIC555では抵抗値の変化で値を入力していたと思います。
マイコンの場合も同様に可変抵抗からの値を入力することが出来ますが、可変抵抗からは電圧のアナログ値の出力になるので、ADCペリフェラルを使用し、電圧を測定する必要があります。
全体像を見てみよう
データシート18ページにあるマイコン全体のブロックダイアグラムを見てみましょう。
図の上部にある「CORTEX-M0+ PROCESSOR」がCPUです。
右上にはRAMが存在しています。
例えると作業する人間と、作業机のような関係です。
これらが「HIGH-SPEED BUS MATRIX」で接続されています。
AHBという高速なバスのことで、幹線道路のようなものです。
バスマトリックスは交差点として考えるのがわかりやすいかもしれません。
各種ペリフェラルはAPBという低速なバスに繋がっています。
そのため、バスマトリックス直下に「AHB-APB BRIDGE」が存在して間の橋渡しをしています。
ペリフェラルはよく見るとDMAという表記も見当たり、別の線で繋がれているのがわかると思います。
これはDMA転送用のバスで、DMAコントローラーに繋がっています。
そのためCPUからデータのやり取りをする以外にもDMA経由でデータのやり取りをすることも可能になっています。
ちなみに「ARMマイコンで電子工作 SAMファミリ活用ガイドブック」という本でペリフェラル機能がざっと解説されているため、参考にしても良いと思います。
※この書籍ではMPLAB XとPICkit 4を使った開発方法を解説していて、プログラム記述の方法も若干違うため留意してください。
同様にMPLABでのサンプルコードですが、この辺も参考になるかもしれません。
単音のインタラプタを作ってみよう
タイマーIC555でよく作られているインタラプタをマイコンで再現してみましょう。
どのように制御パルスを作り出すか?
ArduinoでLEDを光らせた経験のある方は以下のようなコードが思い浮かぶのではないでしょうか。
void setup() {
pinMode(1, OUTPUT);
}
void loop() {
digitalWrite(1, HIGH);
delayMicroseconds(100);
digitalWrite(1, LOW);
delayMicroseconds(900);
}
上記コードだと、1番のピンをHIGHにして100us待機、ピンをLOWにして900us待機、この繰り返し動作です。
つまり、1kHzでの音程で100usのON時間での放電となる。
簡単な構造のDRSSTCの場合は、この程度の周波数が上限になってくると思われます。
圧電スピーカーを1番ピンとGNDに接続してみると音がなっていることも確認できるでしょう。
波形をオシロスコープで確認してみましょう。
安定していないのがわかりますか?
理論的には上記のコードで1kHzの周波数の信号が出る予定ですが、計測を行ってみると983Hzとなっています。
また、周波数や時間のズレがそこそこあります。
その上、複数の出力を得たい場合にはどのようなコードになるでしょうか?
複雑なスパゲッティコードになってしまうと思います。
波形を出力する以外にMIDIを受信する、LEDやLCDで現在の状態を表示する、ADCから値を読み込むなどといった処理を間に入れると、時間が変化してしまってなおさら使い物にならないインタラプタになってしまうでしょう。
ではどのようにしたら良いのでしょうか?
タイマーの使用を前提にピン配置を考えてみよう
タイマーペリフェラルを使用して波形を生成することを考えてみましょう。
SAMD21に搭載されているのは、TCとTCCペリフェラルです。
24bitモードにも出来る高機能なTCCペリフェラルを使用する前提で話を進めましょう。
データシートの624ページを見るとTCCで波形生成するためのモードがいくつかあることがわかります。
NFRQ、MFRQ、NPWMなどです。
- https://forum.arduino.cc/t/changing-arduino-zero-pwm-frequency/334231
- https://forum.arduino.cc/t/arduino-zero-m0-timer-capture-and-compare/898075