概要
LPC810をPSG互換チップとして動作させるファームウェアを作ってみました。オリジナルのPSGとは異なりI2Cで制御できるようにしたので気軽に電子工作に組み込むことができます。ArduinoやRaspberry Piのお供に、またLチカからのステップアップにぜひご利用ください。
SoundCortex
LPC810について
秋月電子にて80円で入手できます。YMZ294はちょっと高くてなー、とか足が多くて制御できないなー、なんて人。YMZ285を買って騙された!って人にお勧め。ぜひこのチップを爆買いしてSoundCortexを焼いてPSGとして使いましょう。
ちなみにファームウェアの書き込みはシリアルで出来ます。電子工作やってたらUSB-USART変換器の1つくらいは持ってると思うので、特に追加設備なしで書き込みできるかと思います。あるいは本棚漁れば古いトラ技と付属のライターが出てくるのではないでしょうか。
ファームウェア
LPC向けにSoundCortexというファームウェアを作ってGitHubにて公開しています。このファームを搭載したチップの事はSoundCortexChip、通称SCCと呼ぶのが良いのではないでしょうか。
回路図はこんな感じになります。簡単ですね。
この図では680Ωの抵抗と0.01uFのコンデンサでLPFを挟んでますが、面倒ならPIO0_4とGNDを直接圧電ブザーなんかに繋いでも大丈夫。出力的には8-bit/46.875kHzのPWMで再生されますので、ノイズの大半はよほど耳が良い人じゃないと聴こえないかと思います。図のLPFは23.4kHzがカットオフ周波数になってます。
(2016/4/14追記:ヘッドフォン出力のインピーダンスは〜100Ω程度に抑えた方が良いようなので、RとCは一桁ずつずらした方が良いかもしれません。2回目の制作では手持ちの部品の関係で75Ωと0.1uFの組み合わせでカットオフ21.2kHzのLPFを構成する方法をとりました。)
I2CバスはSDA/SCLともにpull upが必要ですのでmaster側でやってなければ経路で適宜pull upして下さい。Raspberry Pi Model B+で試したところ、外側でのpull upは不要でした。
PSG互換モード
SoundCortex自体は色々なチップのエミュレーションを追加しようと思っているのですが、現状ではPSG互換のファームウェアのみ提供しています。
I2Cはslave address 0x50でアクセスできます。書き込みは2 bytes単位で行って下さい。最初の1 byteがPSGの内部レジスタ番号、続く1 byteが書き込む値です。例えば[0x00, 0xFF]を書き込めばPSGレジスタ0に0xFFが書き込まれます。速度はあまり検証していないのですが、一般的な100kHzはもちろん通りますし、運が良ければ3MHzで書けると思います。
拡張機能としてレジスタ0xFFに0を書き込むと3.579545MHz(デフォルト)、0以外を書き込むと4MHzのオシレータを繋げたPSGとして動作します。また0xFFを読みだすとメジャーバージョン1、0xFEを読みだすとマイナーバージョン0が読み出されるはずです。
あと、いつもの事ですがエンベロープはエミュレートしてません。あんまり使われることがないのでモチベーションがわかなかったり、テストする(データ探す)のが面倒だったりとか。
使ってみよう
Raspberry Pi編
Raspberry Piとの接続は電源合わせてもたった4本の線で繋ぐだけ。
オーディオは別途2本配線しつつ、間にお遊びでLED刺してます。
Raspberry Piについてはこの辺でピンアウトを調べて下さい。1: 3v3、3: SDA、5: SCL、9: GNDとなっています。
I2Cはraspi-configやGUIから簡単に有効化できます。有効化したらi2c-toolsをインストールしておくと簡単なテストができて便利です。
pi@raspberrypi:~ $ sudo apt-get install i2c-tools
pi@raspberrypi:~ $ sudo i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: 50 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
pi@raspberrypi:~ $
こんな感じで0x50の場所に何か繋がっていることが確認できます。
pi@raspberrypi:~ $ sudo i2cget -y 1 0x50 0xff
0x01
pi@raspberrypi:~ $ sudo i2cget -y 1 0x50 0xfe
0x00
バージョン番号もちゃんと読み出せてますね。
実際にC言語などからアクセスしようとするとこんな感じになります。
#include <fcntl.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <unistd.h>
static int fd = -1;
void SoundCortexOpen() {
fd = open("/dev/i2c-1", O_RDWR);
if (fd < 0) {
perror("file open error");
exit(EXIT_FAILURE);
}
if (ioctl(fd, I2C_SLAVE, 0x50)) {
perror("can not set address");
exit(EXIT_FAILURE);
}
}
void SoundCortexWrite
(unsigned char reg, unsigned char data) {
if (fd < 0)
SoundCortexOpen();
unsigned char cmd[2];
cmd[0] = reg;
cmd[1] = data;
write(fd, cmd, 2);
}
で、例えばfMSXなんかに手を加えてみましょう。AY8910.cのWrite8910からSoundCortexWrite(R, V)みたいな感じで呼んであげれば、あら不思議。MSXエミュレータの出力がLPC810から出てきます。
というデモをYouTubeに上げてみましたよ。ちなみにこのデモはLPF通さずにミキサー直で録音してます。
Arduino編
Arduino UNOに繋げて試してみました。写真ではpullup入れてますが、標準のWire.hを使う限りではpullup不要みたいですね。入れといて実害はないので、そのままにしてます。電源は3.3Vを使うようにしてください。LPC810の定格の問題です。digispark使って面倒だから5Vで繋げてみたけど、やっぱり動きませんでした。
#include <Wire.h>
void SoundCortexWrite(uint8_t reg, uint8_t value) {
Wire.beginTransmission(0x50);
Wire.write(reg);
Wire.write(value);
Wire.endTransmission();
}
void setup() {
Wire.begin();
SoundCortexWrite(0x00, 0xfd);
SoundCortexWrite(0x01, 0x01);
SoundCortexWrite(0x07, 0xfe);
SoundCortexWrite(0x08, 0x0f);
}
void loop() {
}
これでラの音が鳴ります。最初の2回の書き込みでCh.1のTPを0x01fdに設定して出力周波数をラの高さに合わせています。で、続くレジスタ7への0xfeの書き込みでCh.1の出力を有効化、レジスタ8で音量を最大に設定しています。
PC編
I2CBridgeってのをやはりLPC810で作りました。こいつをUSBシリアル変換器とSoundCortexの間に刺してあげれば、PCからシリアルを叩く事でI2Cバスにコマンドを送り出すことができます。ファームウェアの開発中はこっちの方がテストが楽なので、基本こちらでテストしてたんですが、やはりシリアルの速度がI2Cと比べると遅いですね。230400bpsで安定して通信出来ていたんですが、それでもPSGだけの演奏でもちょっともたります。ましてやSCCと一緒に演奏させた日にはボロボロ……。
こんな事に使うと良いと思う
MIDI楽器
USBやBLE、あるいはオリジナルのDINのMIDI。インタフェースまでは簡単にできるんだけど、シンセのエミュレーションは素人にはなかなか手がでないもの。そこでMIDIを受けてPSG音源を使って演奏する……となれば敷居はだいぶ下がるはず。
改造目覚まし時計
ちょっと凝ったブザーや演奏がマイコンから簡単にできますよ。
ChipTuneプレイヤー
世の中に存在するChipTune向けのサウンドフォーマットをマイコンから再生するとかどうですか。わりと多くのフォーマットがCPUエミュレーションが必要だったりして大変ですけど。
その他もろもろの電子工作
もっと音出しましょう。
Comments
気づいたら秋月は80円→300円というぼったくり価格に。他のお店はまだ75円とかで売っているので、他のお店を探すのがお勧めです。
NXPがQualcommに買収されたのと関係ありますかね?
他のお店で値段が変わっていないので何とも……僕が買って騙されたと書いたYMZ285が300円である事とは関係あるかもしれません:P
@toyoshimさん、
ネット検索したら、2016年8月くらいには、値上がってたようなことを言っている方がいたので、買収とは関係なさそうですね。よく調べないですいません。
...ということは、この記事がトリガーになって、秋月での需要と供給のバランスがくずれて...
買収は関係ないですね。DIP部品だからだと思います。LPC1114も爆上げされました。
この辺の値段は仕入れ時の値段と在庫状況で変わるので単にそういう話だと思います。
DIP系、スルーホール用部品はどんどん選択肢が減っていっているのが現状です。
http://akizukidenshi.com/catalog/faq/goodsfaq.aspx?goods=I-06071
1114に対するQ&Aを見つけましたが、プロモーション価格ってのがあるんですね。
だとすると810も同様で、各店舗の在庫が切れたら一様に値上がりする可能性がありますね。
大昔100円だったTINY2313とかも同様でしょうか。
初期にばらまく事はよくありますね〜。少し意味合いは違いますがビジネス向けでもサンプル無料で貰えますし。
LPC810なんかは謎スペックの多い旧NXPのマイコンの中でも微妙な仕様で、当時は何に使えるのか皆目見当がつかなかった石ですが、SCT無かったら誰も見向きもしなかったのではないかとも思います。そういう意味でも生産量は多くないのではないかなぁ。
AVRもMicrochipになってから扱いが微妙になってる印象があるので、ラインを整理して終息されて枯渇する可能性は十分にあるかなと思います。Arduino系の人気はまだまだ根強いですが、あくまでも僕の周りの話ですがPICの採用例はあれどAVRって見たこと無いんですよね・・・。
現場での採用事情は興味深いです。PICは久しく使ってないのですが、USB使えるラインも安くなってきてるしMIPS採用の32系のエントリモデルでもOTGまで対応してるので、この辺りに戻るのも悪くないかな、とか思いました。この値段ならAVRで無理してV-USBとか動かす意味すら無くなってきてますね。
MIPSなら昔PS2用に書いたFM音源コアがそのまま動きそう。仕事で書いたので勝手に公開とかは出来ないのが玉に瑕ですが。
あとは各社のラインが整理される頃にはFPGAがもっと低価格帯に降りてこないかなー、と期待してます。
Let's comment your feelings that are more than good