ELM Home Page

Translate this page with Microsoft Translator
更新: 2014. 4. 29

NXPの小ピンARMの試食


ARMマイコン・メーカの一つ、NXP Semiconductorsが小ピンCortex-M0マイコンをDIPパッケージで相次いで発売しています。PIC/AVRに代表される小規模8ビット・マイコンを置き換えようと鳴り物入りで登場したのはいいのですが、期待に反してそのなかなか逝けてる仕様から落胆の声も聞かれるようです。

私もいくつか試食してみたので、そのリポートを載せておきます。これらのリポートは、当初、32ビットへの誘いのオマケとして追加してきたものですが、元の趣旨から外れてきたので独立したページに分離しました。

  1. DIPなARMマイコンLPC1114を食す
  2. 8ピンDIPのLPC810を食す
  3. LPC811(DIP化済み)を食す
  4. LPC810再び
  5. FM音源の実験
  6. NXPのSTAPマイコン

DIPなARMマイコンLPC1114を食す

NXP LPC1114
さぁ、ボクと契約して電子工作を始めるんだ

去年(4Q/2011)発表されたLPC1114のDIP版が今(3Q/2012)になってなぜか流行っているようなので調べてみたところ、トラ技の付録になっているらしい。同時に秋月でも販売開始されているとのことで、帰りに秋葉に寄ってみました。ほんとに28ピンで600milだ(笑)。確かに存在感はありますが、これではNXPのDIPマイコンに対する姿勢が問われますね。MicrochipやAtmelを見習ってもらいたいものです。まぁ、国産に多いSDIPだったらもっと嫌ですけど。ちなみに、電源ピンは点対称になっているので、逆挿ししても即死することはないと思います。フールプルーフかリバーシブルを狙っているのでしょう。

このマイコンは、MARY基板に使われているのと(RAMやピン数を除き)同じで、特に興味を引かれる点はありません。とはいっても、通電もせずにいきなりジャンク箱では可哀想なので、とりあえずLチカだけしてみました。はんだ付けなしで実験できるのがDIPマイコンのいいところですね。プログラムは単純なので、main()をリセットエントリにして、main.c一本にまとめてあります。LEDは14番ピンとしています。

2012. 9. 7

8ピンDIPのLPC810を食す

NXP LPC810
待望の8ピンARM。しかし…

発表後もなかなか量産出荷の始まらなかったLPC810(8ピンARM)ですが、突然供給が開始(4Q/2013)されパーツ・ショップに並び話題になりました。もちろん、私も早速買ってきて試食してみることにしました。しかし、書き込みツール(lpcsp)がまだ対応していなかったので、まずそれを対応させることから始めなければなりません。パラメータの追加だけで簡単にいくと思ったら、なんとデータ転送がuuencodeからbyte-streamに変更されていて、処理を分ける必要がありました。その他、デリミタの処理も違うなどいろいろハマりました。

スタートでずっこけましたが、気を取り直してLチカと簡単なUART通信を試してみます。LPC810の電源ピンの位置は少し変わっていて、6番がVdd、7番がVssになります。また、ISPモードでは2番がTXD、8番がRXDになります。そして、5番ピンをLに落として電源投入またはリセット(1番)を解除するとISPモードで起動します。このように、多くのピンを使ってしまうので、実際のシステムではISPやSWDは困難になるでしょうし、JTAGだと全ピン使ってしまいます。もっとも、このクラスのマイコンにデバッガなんて必要ないですけどね。

さて、これが80円で出てしまったものだから、このクラスのPIC/AVRは駆逐されてしまうのでは? との懸念があったようです。しかし、そう簡単にはいきそうもありません。なぜなら、LPC81xは黒歴史になりそうなほど糞だということが分かったからです。具体的に上げてみると…

このように、私がいままで8ピンAVRで作ったプロジェクトがほとんど置き換えできないことが分かり、唖然としてしまいました。本気でPIC/AVRに切り込むつもりなら、NXPは味噌汁で顔を洗って出直すべきでしょう(笑)。しかし、これほど規模が小さいと32ビットの効率は悪く逆に8ビットは良くなるので、苦戦を強いられるかも知れません。

ダメモトで8pin SDプレーヤの移植を試みたけど…コード・サイズが全く及ばず轟沈。つづく。

2013. 12. 1

LPC811(DIP化済み)を食す

NXP LPC811
LPC811でリベンジ!

前回8ピンARMで負けたので、16ピンで再挑戦。ということで、今回は同じシリーズでLPC810の一つ上のランクになるLPC811を試食してみました。ROM/RAMはそれぞれ8K/2KとLPC810の2倍乗っているので、何とかプログラム・コードは収まりそうです。しかし、そこにはまだハードルが...。

LPC81xの内蔵ペリフェラルの中で最も難解なのがSCT(State Configurable Timer)です。SCTは各種イベントの発生と動作を細かく制御することができ、内部・外部要因に応じた複雑なタイミングの生成などが可能な多機能タイマ・モジュールといえます。しかし、それゆえ単にPWM出力やキャプチャなどの機能を使いたいというだけでも数多くのレジスタを設定しなければなりません。この辺の設定をうまくやってくれるライブラリが欲しくなるところですが、これの機能を網羅するような柔軟性を持ったライブラリとなると、ただでさえ小さなROMに対してそのサイズがバカになりません。コンフィグレータで目的別のソース・コード生成、というのがうまい落としどころでしょうか。まぁ、慣れればレジスタ直打ちの方が自由で良いと思いますけどね。

マニュアルを読み進めてSCTの機能が明らかになると、その設計に少し抜けているところも見えてきます。たとえば、0~31のステートに対してイベント条件をステート0~1にしか設定できないとか(残りのステートは?)。もっとも、ステートを活用できる使い所がなかなか想像できませんし、そもそもSCTの特徴がハマるようなアプリケーションなんて滅多にないのかも知れません(ぉ。一体何を夢見て設計したのでしょうね。

結局、SCTは「複雑な割りには大して使えないモジュール」というのが率直な感想です。やっぱりこのクラスのマイコンには、AVRの16bitタイマくらいが使い勝手の点でバランスがとれていると思うのですが、どうなんでしょう。あ、LPC111xのPWMに比べて良いところが一つだけありました。比較値が同期更新になっているので、グリッチ・フリーなクリアなサウンド出力が得られます。まぁ、そんなの当たり前のことなんですけど。

SCTをマスタしたところで、次はSPIをマスタで動かしてみましょう。LPC81xのSPIモジュールは、1~16ビットの任意のフレーム長、SPIモード0~3、最高速度はPCLK/1まで設定可能で、これが1個または2個(LPC812の一部)内蔵されています。これもオリジナルな設計らしく、他のLPCシリーズのSPIモジュールとは異なったものになっています。一抹の不安を覚えたものの、単なるSPIなので難しいところはないはず。

さっそく、マニュアルを見ながらチマチマと初期化コードを書いてコンパイル、プログラム・コードを書き込みます。ところが、普通ならそれで一発で動作するはずなのに、何か変です。SDカードの初期化まではパスしているのですが、セクタの読み出しでコケているようなのです。おもむろにオシロスコープを出してきて動作を確認しようとしたところ、驚愕の事実が。どうもSPIの信号が意図しない動作をしているようです(810,811とも。たぶん812も。)(※1)。いろいろ試してはみたものの埒が明かないので、思い切ってSPIモジュールの使用は諦めて最後の手段のBit-banging SPI(GPIOをソフトウェアで操作してSPIデバイスを制御すること)で行くことにしました。ハードウェアSPIに比べて速度で大きく劣るのが難点ですが、それでもCCLK/6程度のビット・レートは出ていて、今回の用途には使える程度の速度になりました。GPIOの入出力レイテンシが予想より大きかったのは意外でしたが(OUT→INの間に4命令挟まないとエコー・バックを読めない(AVRなら1命令))。

ということで、何とか移植に成功しましたので、結果をここに置いておきます。機能的にはAVR版(スレテオ構成)を忠実に再現しています。コード・サイズもAVRとほぼ同じとなり、このような小規模な制御用途ではARMのコード効率のアドバンテージは減殺されることが裏付けられました。

で、結局LPC81xって一体何だったんだろう。使えるかどうか分からないけどぉ、なんか作っちゃったー、みたいな何か。LPC81xについてはこれで〆とします。あぁ、なんか疲れた...。でも楽しかった!

2014. 1. 14


※1: BBSでの指摘により、理由が判明しました。LPC81xのSPIモジュールでは、モード0/2(クロック後縁でシフト)において、フレームの転送が終わるときに送信バッファが空の場合は、トランスミッタは最終クロックの後縁直前でストール(転送が終わらない糞詰まり状態)します。最終クロック後縁で出力されるデータは次のフレームの先頭ビットであるべきで、それが存在しないから出せない、ということらしいです。そして、次の送信データが書き込まれると、「前回の途中」からデータ転送が再開することになります。なるほど、モード0が3になってしまうわけです。しかし、この動作はSPIの規格としては無意味...というよりモード設定が無意味になってしまいむしろ有害といえます。SPIではシフト・エッジ→データ出力→サンプリング・エッジにおいて、データ出力からサンプリングまで0.5クロック時間あれば良く、そもそも先頭ビットの出力はシフト・エッジ同期である必要はありません。なぜわざわざこのような設計になっているのか理解に苦しみます。まぁ、それはそれでかまいませんけど、こんな重要なことはEOTビットの項目ではっきりと解説されるべきなんですけどねぇ。マニュアルにない使い方は想定すらしていないのかも知れません。このため、モード0/2で使用する場合は、次のうちいずれかの配慮が必要になります。

2014. 1. 16

LPC810再び

死屍累々
死屍累々...(なんかグロい)

え、「LPC81xはもう止めたんじゃなかったか」って? いやぁ、ダメなマイコンほど何とかして使い倒してやろうと、逆に燃えるって言うじゃないですか。ということで、唯一の8ピンARMであるLPC810を使って何か実験してみようと思います。さて、何をしよう...って、既にLPC810の攻略が目的になっていますけど、気にしない気にしない:-)

小ピン・マイコンの応用で簡単そうなモノとしては、タッチ・センサがあります。現在主流になっている静電式タッチ・センサについては既にAVRマイコンでやっているように、大抵のマイコンで十分に実現可能です。今回はLPC810を使ってこれをもう少し掘り下げてみることにします。

静電式タッチ・センサでは、タッチ動作(検出電極に対する指などの接近)を静電容量の変化として検出しますが、よく使われている検出方式としては、「単純積分方式」と「チャージ-トランスファ(C-T)方式」の2通りがあります。これ以外にも発振回路の特性変化を検出するタイプなど目的に応じていくつかありますが、ここでは説明しません。次にこれらの2つの方式について説明します。

単純積分方式

図1. 単純積分方式
Simple Integration Method

単純積分方式の動作を図1に示します。まず、検出電極の静電容量をCdとし、これを測定の対象とします。Cdは回路上に存在する浮遊容量(Cs)と指などの接近による増加分(Co)を足したもの(Cd = Cs + Co)となります。単純積分方式では、RiCdにより構成されるCR回路の時定数によって決まる積分時間を測ることによりCdの値を得ます。

  1. リセット。Cdの電荷を抜く。
  2. 積分開始。Riを通してCdが充電されていく。
  3. VCdが基準値に達したら終了。

結果は積分時間(Cdに比例)として得られます。この方式の利点は、使用するGPIOポートが1本で済むことで、使用可能なピン数に制限があるときに有効です。その反面、回路のインピーダンスが高く(Cdが小さくRiも相応に高く設定される)EMIによる影響を受けやすいため、安定動作のためには複数回計って平均化するなどの工夫が必要になります。また、ソフトウェア・ループによる実装の場合、割り込みなどによる処理中断があると大きなエラーとなってしまうため、時間計測中は割り込みを止める必要があります。

チャージ-トランスファ方式

図2. チャージ-トランスファ方式
Charge-Transfer Method

図2にC-T方式の動作を示します。積分コンデンサ(Ci)の容量はCdより十分に大きな値(数百倍程度)に選びます。そして、2つのポートを適当なシーケンスで駆動することにより、Cdを通してCiを充電していきます。

  1. リセット。両側のポートをLレベルに駆動してCiの電荷を抜く。
  2. チャージ。下側ポートをHi-Zにし、上側ポートをHレベルに駆動。CdVccまで充電される。Ciには影響はない。
  3. トランスファ。上側ポートをHi-Zにし、下側ポートをLレベルに駆動。Cdの電荷がCiに転送される。
  4. VCiが基準値未満ならチャージに戻る。このサイクルを繰り返すと徐々にVCiが上昇していき、基準値に達したところで終了。

結果はC-Tサイクル数(Cdに反比例)として得られます。これを例えるなら、「コップ(Cd)のサイズを知るために、単純積分方式では蛇口を開けてからコップが一杯になるまでの時間を計り、C-T方式ではコップ何杯でバケツ(Ci)が一杯になるかを計る。」とすると、その動作を理解しやすいと思います。なお、Cdはシンク側に接続されていても全く同じ事です。この方式の利点は、低インピーダンス動作とCiによる平均化のためEMIの影響を受けにくいことと、時間ではなく回数を計っているため割り込みの影響を受けないことです。

LPC810に実装してみる

さっそく、タッチ・センサ機能を以上の二つの検出方式でLPC810に実装してみます。単純積分方式では充電開始から基準電圧に達するまでの時間を計るため、入力キャプチャ付きタイマが欲しいところ。LPC81xでこの用途に使えるのはSCTだけです。SCTが他の目的に使われているときは、ソフトウェア・カウンタで計るしかありません。基準電圧は適当で良いので、デジタル入力のスレッショルド電圧(Vcc/2程度)そのままとすれば十分でしょう。

単純積分方式は既にAVRで実験済みですが、C-T方式の実装は今回が初めてとなります。C-T制御は単純なものなので、SCTの片側でC-Tサイクル発生、もう片側で計数、条件付き入力イベントで終了、とすれば自動化できるかも...と思いましたけど、出力ポートの設定にP-ch OD出力が存在しないため無理でした。う~む、惜しい。このため、C-T方式は全てソフトウェアによる制御が必要になります。

検出電極は□10mm程度のサイズとし、誘電体でカバーしたものを想定しています。0.5~1mm程度のプラ板の裏側に銅箔電極を貼り付けた構造が簡単で良いと思います。C-T方式でCiに直列に入っている抵抗は、Ciをリセットする際のサージ電流や負電圧による故障(エレクトロ・マイグレーションやラッチアップ)の発生を防ぐためのものなので、無くて問題ないようなら省略してしまってもかまいません。ソフトウェアはメイン・ループで毎秒100回測定してその測定値をUARTに出力(生データおよびメディアン・フィルタ処理後の値)します。検出電極を指で押さえると数値が変動するのが分かるでしょう。

ところで、秋月でLPC810の価格が75円に値下がりしていました。コレを仕事に使おうなんて誰も考えないでしょうし、物好きなホビーストに一通り行き渡って売れなくなったのだろうか?

2014. 2. 4

FM音源の実験


1個で1音♪

80年代のロック・ポップ音楽を印象づけた楽器といえば、なんと言ってもヤマハDX7に代表されるFM音源のシンセでしょう。FM音源はフル・デジタル演算により実現され、僅かなパラメータだけを元にアナログ方式にない複雑な音色を合成することを可能にしました。そして、その特徴的な音色とパソコンより安い価格設定もあり、プロはもちろんアマチュアに至るまでの音楽シーンを一気に席巻することになります。FM音源はまた、ホビー向けパソコンやアミューズメント機器にも組み込まれ、広く利用されるようになります。秋葉原でも各種FM音源チップセットが出回り、私も亜土電子でYM2203を買ってきてPC拡張ボードやZ80ボードに組み込んでいろいろ遊んでいました。

FM音源の原理

オペレータの構成とアルゴリズム

FM音源ではオペレータという発振・変調器のブロックを最小単位とし、これを複数組み合わせることでひとつの音を合成します。右の図にオペレータのブロック図を示します。オペレータは、出力の元となる正弦波を発生する発振器WGとそれの振幅に経時変化を与えるエンベロープ発生器EGで構成されます。WGはDDSによって実現され、任意の周波数を出力できます。EGはキーを押さえてから放すまでの振幅変化のパターンをいくつかの区間で区切ってある程度自由に設定できます。図に示したEGのパラメータは、ADSRと呼ばれる4区間を制御する基本的なもので、これにキーやベロシティによるバリエーションが加えられるほか、シンセによってはさらに複雑なエンベロープを生成できるものもあります。それでも出力波形は正弦波(一部のシンセでは非正弦波も選択可)であることには変わりなく、単独のオペレータが合成する音は単なる正弦波音「ポー」またはそれにエンベロープを適用した時報音「ポーン」だけで、味もそっけもないものです。

そこで、FM音源ではオペレータの出力で別のオペレータの周波数を変調できるようにしました。これにより、単なる加算・乗算・フィルタ処理では難しい複雑な倍音を含んだ豊かな音色を合成することが可能になっています。これらのオペレータのうち、別のオペレータの変調入力に接続されるものを「モジュレータ」、音源の出力となるものを「キャリア」といいます。オペレータの接続のしかたには何通りかあり、たとえば4オペレータ構成では8通りとなります。また、このオペレータの接続パターンをアルゴリズムといい、音色の特徴を決める重要なパラメータとなっています。

LPC810に実装してみる

それでは早速LPC810にFM音源を実装してみます。上に示した原理図だけ見れば難なく実装できる程度のものなので、特に難しい点はないと思います。ただ、ひとつだけハマった点は、FM音源は正確にはFM(周波数変調)ではなくPM(位相変調)だったということ。ブロック図を見ても分かると思いますが、生成された位相θに変調信号を加算しています。最初、FMという言葉を鵜呑みにして周波数ωのところに変調入力を加算したところ、フィードバックを増やすと周波数がズレたり発振が止まったりする現象に悩まされました。で、よく調べてみたらそういうことだったというわけで orz。


負荷率58%! FM音源は重い。

実装に当たってはトリッキーな最適化は避け、原理に基づいた素直な実装とし、ほかのプロジェクトへの使い回しを狙った汎用モジュールとしています。オペレータ数は、2,3,4,6を選べるようにしました。FM音源は、各種音源の中でも演算負荷の重い部類に入るので、8ピンとして速さだけが取り柄のLPC810にはうってつけのイジメ材料になりそうです。試しに4オペレータで作成して負荷率を測ってみたところ、1音で58%に達してしまいました。さすがにFM音源は重いですね。その内訳は、オペレータ(fmop)が10%×4、その上位のアルゴリズム(fmsynth)が12%、その上位の出力処理が残りとなっています。さらに6オペレータで試してみると、なんと80%超! うーむ、イジメ甲斐があるなぁ(笑)。

このように、FM音源は当時のマイコンで実現できるような代物ではなく、当然のことながら専用ICによって実現されていました。これは現在でも変わりなく、本格的なマルチ・ティンバー音源をやるとなると、マイコンに収まるようなモノではないと思います。たとえば、6op×32chなら192個のオペレータが並列動作するということになり、趣味のFM音源プロジェクトにおいてはまさにFPGAの出番といえます。

実験環境を整える

さて、とりあえず手っ取り早く適当なメロディを出してみたくなったのですが、それにはMIDI等でコントロールするのがいちばん手軽でしょう。ただ、MIDI関係はSC-88(これに対応したゲームが多かった)を手放して以来縁がなかったので、まずはMIDIボードを探すことから始めなければなりません。ジャンク箱のかなり下層にMIDI付きサウンド・ボードがあったはずだけど...あった。でも残念、GUSとSBP2(ISAボード)でした orz。あ、もう一個あった。これは...PC88用(自作)だッ orz。確か、PCIのがあったはずなのに出てこない。かといって、これだけのためにUSB MIDIを買うのもアレですし。仕方ないので、COMポート接続で簡単に音階を出せる程度のテスト・アプリをでっち上げて、ついでに音色作成に必要になるパラメータ・エディタも組み込んでおきました。

結局負ける

DX7ネタで始めてみたのはいいのですけど、オチがハク・ネルになったあたり典型的な負けパターンでした。でも、音源としては完成したので、実験に終わらせず何とか形にしたいものです。つづく(のか?)。

2014. 4. 20

NXPのSTAPマイコン

LPC81x DIP

この手のマイコンのユーザはブレッドボーダーが殆どでしょう。あれば欲しがる人の多いLPC81xシリーズ全品のDIP版ですが、ようやく出回り始めたようです。昨日の帰りにマルツパーツ館さいたま店に寄ってみたところ200個以上在庫があったので、試しに買ってみました(画像は見やすいように加工してあります。あ、石投げないでください:-)


LPC1500

まぁ、冗談はこれくらいにしておいて、最近発売されたLPC1500シリーズ(M3コア)がなかなか良さげなので、新しいプロジェクトにといくつか購入してみました。そしていくつか気付いた点を書いてみます。

2014. 4. 29

Sign