2015年3月1日日曜日

LPC810のState Configurable Timer(SCT)を使ってPWMを構成する

概要

A tiny MML parserのアプリケーションを考える過程で、LPC810が手元で眠っている事に気付きました。8ピンのARM Cortex-M0+でA tiny MML parserなんて素敵です。

さっそく調べてみたところ、先日のArduinoと同様に動作させる事を考えた場合には、State Configurable Timer(SCT)を使ってPWMを構成すれば良い事がわかりました。

あちこちで大不評のSCTですが、実は簡単に使えるのではないかと思っていました。
が、実際にやってみてやっぱり大撃沈。レジスタマップと機能説明を読んでも、どんな風に設定すれば自分が欲しい動作になるのか、全然意味がわかりません。

そんな中、LEDをステートマシンで点滅させるエクセサイズを見つけたので、頭からやってみる事にしました。これを応用すれば出力をトグルさせるだけのPWMにも適用できるというわけです。

リソース

エクセサイズのリソースhttp://www.nxp-lpc.com/updated_materials/sct/lpc81x/LPC81x_SCT_code_examples.zip

エクセサイズのプレゼンhttps://onedrive.live.com/view.aspx?resid=7AE40E5A5F1EC907!24470&ithint=file%2cpptx&app=PowerPoint&authkey=!ACDxmgRtdAZZdXE (スライド30ページから)

エクセサイズのリソース

ダウンロードしたエクセサイズのリソースは、説明に従って実際にプロジェクトを仕上げるために、作業開始時点の内容になっています。プロジェクトをセットアップし、スライド30ページを開きます。



Red State Machine file generator

Red State Machine file generatorとは、ステート・マシンを構成し、その構成に従ったソースコードを生成するまでを支援するツールです。

プロジェクトエクスプローラで右クリックを押して「New」から「Other...」を選択します。


「Red State」から「Red State Machine file generator」を選択します。


ファイル名を入れます。


「Choose Target」ボタンを押してターゲットを選択します。


上記で準備は完了。
エクセサイズのスタートです。

ステップ1

  • U_ALWAYS状態を削除する
  • State Tableタブで状態を構成する

U_ALWAYS状態を削除するために、ステート・マシン編集画面にあるU_ALWAYSを右クリックして「Delete」を選択します。



次に状態を管理するState Tableタブに二つの状態を入力します。
このState Tableに状態名や次の状態名を入力すると、画面中央にある状態編集用GUIにも自動的に反映されます。


上記編集直後の画面は以下。


ちょっと配置が汚いので状態を示すボックスをマウスでドラッグして移動させて下さい。
矢印が双方向に見えるかもしれませんが、そんな事はありません。
きちんと二本に見えるように配置して下さい。


ステップ2

次にステート・マシンに対する入力、delayとmatch0を定義します。


ステップ3

動作の定義を追加します。

EVENT 0

始めにAction Listタブの右上にあるプラスボタンを押して新しい動作を追加し、名前をEVENT 0に変更します。


EVENT 0に対する動作を定義します。
追加は、Operationと書かれたテーブルの上にカーソルを移動させて右クリックして行ないます。

Setオペレーションに対して「Output pin 0」を選択します。


Callオペレーションに対して「Limit unified counter」を選択します。



EVENT 1

同様にEVENT 1を定義します。


名前をEVENT 1に変更して、以下の動作を追加します。
EVENT 1は、EVENT 0に対して逆の動作Clear Output pin 0を選択します。


EVENT 0の時と同様にCall Limit unified counterも追加します。


ステップ4

動作を定義したら、状態に関連づけます。
State Tableタブに戻ってActionカラムをクリックすると、先ほど定義したイベントを選択できます。


出来上がると以下のようになります。


念のため、ここでSignalsタブの内容も確認しておきましょう。
この値は、最初にState TableにSignal名を入れた時点で自動的に追加されています。


マッチを入力として扱うように設定します。



この時点で、画面中央のステートマシン編集画面は以下のようになっています。


ステップ5

Outputs for State Machineタブを開いてプリロード値を設定します。

Generate Codeボタンを押してコードを生成します。



ステップ6

ワークスペースを切り替え、SCT初期化コードを有効にする。


エクセサイズのコードで予め実装されたコメントアウト済みの箇所のコメントアウトを外します。


次に、sct_user.hを開いて下さい。

吐き出されたコードは「#include "board.h"」なる定義が実装されています。
ここを「#include "LPC8xx.h"」に書き換えます。このエクセサイズに内包されたCMSISの中にこの定義ファイルがあります。


何故このような作業が必要になるかというと、ツールが自動生成したsct_fsm.cからsct_fsm.hが参照されており、このsct_fsmの内部実装でLPC_SCTという定義を使っているからです。



上記のファイル名は、State Machine SettingsのHeader in sct_user.hに対して予め設定可能です。


ステップ7

最終調整です。
まず、SCTに制御させるピンを決定します。
今回はLPC800 MiniボードのLEDを点滅させる事にしましょう。
このボードは、PIO0_2にLEDが接続されています。


SWMのピン割当レジスタを設定します。
SWM PINASSIGN6レジスタのビット31:24がCTOUT_0の選択レジスタになっています。


PIO0_0が0x00、PIO0_17が0x11と順に値を加える事で出力を選択します。
今回はPIO0_2ですから、0x02を設定すれば良いことになります。


これで準備完了です。

その他の注意点

CMSISのクロック選択

CMSISのクロック選択は、system_LPC8xx.cの実装側に含まれます。
動作させるボードに応じて設定する必要があります。


この選択を間違えると「何で動かないんだ?」と混乱します。


対象プロセッサ

対象プロセッサを正しく選択して下さい。
この設定は、プロジェクトのプロパティに含まれます。


この選択によって、ツールチェインに与えられるリンカスクリプトが変わります。


実行結果

今回はLPC800 mini boardを使って動作確認しました。1.6秒周期でGPOをトグル動作させており、この動作がCPUの介在無しで行なわれています。この動作周期では、何が嬉しいのか意味不明ですが、後はレジスタを一つ書き換えるだけでPWMの動作周波数が変更されるという仕掛けです。

まとめ

LPC800シリーズに搭載されている新しいSCTは、レジスタマップや機能説明を読んだだけでは使いこなすのが相当難しいものです。というのも、設計の背景や前提にある上位のモデルをそこから読み取る事は困難で、何を前提に設計されたレジスタなのか理解していなければどんな値を設定してよいのかもわかりません。特に複数の状態を、複数の条件に従って遷移する事を考えると、レジスタの相互関係の理解も必要です。


NXPの設計者が何を思ったのかわかりませんが、「こんなツールを用意すれば今までにないマイコンが生まれる」と息巻いたのかもしれません。日本国内で最初に広まった時点で、このRed State Machineよりも先にレジスタの話が先行した結果、「意味不明な機能」というイメージが先行してしまったのかもしれません。(確かにレジスタマップと機能説明だけ読んだら意味不明でした)


LPC800シリーズのSCTは、色んな人を色んな混乱に陥れているという意味で、決して優れた設計とは言えないかもしれませんが、何か新しい領域に挑戦しようという設計者の意気込みを感じました。本当は、ユーザにそんな意気込みを感じさせてはいけない気もしますが、こういう試行が次の新しいモノに繋がって行くのでしょう。

XilinxのVivadoなんかを見ていても思いますが、ツールに任せるべきところは任せ、手で書くところは手で書く、そんな時代に変わりつつあるのかもしれません。

2015年2月26日木曜日

Arduinoでも扱いやすくするために'A tiny MML parser'をアップデートしました (ついでにスーパーマリオも演奏してみました)

Arduinoでも扱いやすくするために'A tiny MML parser'をアップデートしました。このアップデートにより、以下の動画で示すような長い曲でも難なく再生させる事ができるようになりました。お約束感が満載ですが、Super Marioのテーマ曲を演奏しています。



'A tiny MML parser'の公開直後、「A Day in The BAKA's Lifeさん」の「ARDUINOからA TINY MML PARSERを使ってみた」の記事によって、Arduinoを使った活用の御紹介を頂きました。

最初にライブラリを公開した段階では、Blackfin以外に具体的なターゲット・プラットフォームのイメージを持っていなかったのですが、この記事のおかげでお手軽なArduinoで動作するのは面白いなぁと興味を持ちました。

で、実際に自分でもやってみた結果、FLASH上にもMMLを配置できた方がアプリケーションの幅が広がるだろうとの結論に達しました。

というのも、avr-gccではconstとPROGMEMというディレクティブを使って、コンパイラにテキストの配置を指示する形を取ります。AVRの場合、ハーバード・アーキテクチャですから、一口にポインタと言ってもSRAMを指すポインタなのかFLASHを指すポインタなのか区別して扱う必要があるわけです。


最初のバージョンでは、FLASH上に配置する事を考慮していなかったので、必然的にSRAMにMMLを配置せざるを得ず、長大な曲を再生させる事は困難でした。

今回公開した新しいバージョンでは、mml.hにMML_USE_AVR_PROGMEMという定義を追加しました。この値を(1)に設定する事でFLASH上に配置した文字列を処理対象にする事が可能です。もちろん、従来通りSRAM上に配置する事も可能。アプリケーションの設計に応じて切り替えて御利用頂けます。

サンプルのスケッチは https://www.cubeatsystems.com/tinymml/download.html からダウンロードできます。

2015年1月5日月曜日

小規模組み込みシステム向けコマンド・インターフェース・ライブラリNT-Shellのフォローアップ


小規模組み込みシステムデバッグ用シェル - Natural Tiny Shell (NT-Shell)で紹介した小規模組み込みシステムデバッグ用シェルですが、現在は以下のように公開先の変更やフォローアップ記事の掲載などが行なわれています。特に、NT-Shellを使ったモニタ・プログラムNT-Monitorは実践的な活用事例として有効ですので是非ご覧下さい。

2017/4/1追記。

公開サイトを変更しています。以下から最新版をダウンロードできます。
https://www.cubeatsystems.com/ntshell/

CQ出版社の月刊誌インターフェース2013年1月号に記事を書きました。
http://www.kumikomi.net/interface/sample/201301/if01_174.pdf

インターフェース2013年1月号のソースコードは、CQ出版社のダウンロードサービスで入手できます。
http://www.cqpub.co.jp/interface/download/contents.htm

TOPPERS活用アイデア・アプリケーション開発コンテストでの資料はこちら。
https://www.toppers.jp/docs/contest/presen2011_NaturalTinyShellTask.pdf


C言語で記述されたマイコンでも使えるMMLパーサー 'A tiny MML parser'

MML (Music Macro Language)

MMLは、音楽記法をテキストで簡易的に扱うための記述言語です。
例えば、「ド・レ・ミ」と四分音符で歌う場合には「C4 D4 E4」と書く事で表現できます。

経緯

先日、大晦日ハッカソン2014なるものを見つけ、mrubyをBlackfinボード(UCB-BF512-B)で動かすおひとりハッカソンを企画し実行したわけですが、実は色々な小道具を整備しないとmrubyに辿りつけないとわかり何故か寄り道。Windows、Mac OS、Linuxで動作可能なChaNさんのFM音源モジュールの簡易シミュレーターの流れもあって、MMLパーサーがあれば自由に自動演奏させられるなぁという考えから実装したい衝動に負けてしまいました。

'A tiny MML parser'

'A tiny MML parser'は、Cで記述されたMMLパーサーです。


特徴をざっと挙げると
  • シンプルなAPI
  • 可搬性に優れたソースコード (C89準拠)
  • 外部ライブラリに非依存 (libcも不要)
  • 小さなフットプリント
  • シャープ、フラット、ダブル・シャープ、ダブル・フラットなどにも正しく対応可能
  • 複数の符点音符にも正しく対応可能
  • 三連符に対応
など、マイコンで使う事も考慮した設計と実装になっています。

特に、シャープやフラットが複数付く場合、符点が複数付く場合、三連符に対応可能な点は、実際の曲を簡易的に表現可能という意味で重宝する仕様になっています。三連符を疑似的に入力するのとか辛いじゃないですか・・・。


どういう風に使えるの?

'A tiny MML parser'を使うには、要求されている唯一のコールバック関数を実装するだけです。
このコールバック関数は、「typedef void (*MML_CALLBACK)(MML_INFO *p, void *extobj);」と宣言されており、mml_fetch関数を呼ぶ度に一つのMMLコマンドが解釈されてコールバックが呼ばれる仕組みです。


ライブラリのインターフェースは以下に示すようにたったの三つです。


まず、初期化関数mml_initでコールバック関数を渡して初期化します。
この時、extobjに外部オブジェクトへのポインタを渡してやると、コールバック関数で受け取れます。

次に設定関数mml_setupで演奏時に必要となるオプションとMMLを渡します。
「オプションなんてわけわからん!」という人は「(MML_OPTION *)0」を渡して下さい。

最後に呼び出し関数mml_fetchでMMLのパースを実行します。
このmml_fetchを呼び出す度に、一つのMMLコマンドが解釈されます。

ちなみに、このライブラリは「何が書いてあるのか?」について解釈する機能を提供します。
「それをどうするのか?」については一切関知しません。
実際のシステムに導入する場合、これを意識して使う事が結構ポイントになってきます。

デモ

Blackfin上でFM音源を構成し、そのFM音源をMMLで操作している様子をデモ映像にしました。


このデモでは、ChaNさんのFM音源のコードを若干改造したものをミドルウェアとして使用しています。MMLパーサーも軽量ミドルウェアとして導入できたので、上位の実装は非常にシンプルな形で済ます事ができました。

ボードには、金子システム社製BlackfinボードACB-BF592-AUMB-SGTL5000-Aを搭載したBlueTankを使用しています。

ライセンス

ライセンスはMITです。
趣味でも業務でも、ライセンスの範囲で自由にお使い頂けます。

ダウンロード

'A tiny MML parser'のダウンロードは以下のページからどうぞ。


2014年12月31日水曜日

mrubyをBlackfinボード(UCB-BF512-B)で動かすおひとりハッカソン

大晦日ハッカソン2014

大晦日ハッカソン2014なるものを見つけてひっそり参加する事にしました。


テーマは「mrubyをBlackfinボード(UCB-BF512-B)で動かす」という事に決定。


mrubyはVersion 1.1.0を使用します。


今回のハッカソンの作業は https://github.com/shintamainjp/MISO-DEV-2014 で公開します。