DIV5142用のイコライザーソフトを考えてみましょう! 2020.10.8

夜にパソコンを点けて考え事をしていると、いきなりパソコンの電源が落ちた。
ん?何が起こった?
とりあえず再度起動させようと電源スイッチを押すが、なにも反応しない・・・・
ACコンセントを抜き差ししても同じ。パソコン背面の電源のテストスイッチを押しても反応しない。

電源が壊れた????

中古のPCなので、寿命だったかもしれません。とりあえず電源が原因との目星をつけて交換修理(雑記帳43)です。
一時はどうなるかとあせっりましたが、なんとか復旧しました。

で、何を考えていたかといえば、最近800×480ドットの液晶を買った(TeaTime参照)のですが、
どうつかおうかと思案していました。考える中で、この液晶にはタッチペン機能もあるので、まずはそれも動かしてみました。
タッチパネルは4線式の抵抗膜方式ですが、LCDに駆動用のICも乗っているので外付けにAD変換器が要りません。
座標値ではありませんが、ペン位置が0〜4095の12ビットの値で得られます。


最近買った800×480ドットのLCDです。簡単にタッチパネルも動かしてみました。

タッチパネルのソフトについてはこのサイトにサンプルプログラムがあるので、それを改造して使います。
しかし、よくわからないのがデモプログラムのコメントです。多分中国語なんでしょうが、文字化けしてしまって
なにがなんだかわかりません。まあ、コメントなくてもプログラムで何をしているかは見当はつきますが・・・・



タッチパネルのプログラムの一部ですが、何のコメントなのかさっぱりです。


そうだ!イコライザーソフトを考えよう!

タッチパネルで簡単なお絵かきソフトを書いてみましたが、それだけでは面白くありません。
800×480の画素数もあるので、色々とできそうです。そこで、DIV5142用のイコライザーソフトを
考えてみることにしました。FESP5142-Doではグラフィックイコライザーを作りましたが、24素子です。
DIV5142なら4個のPCM5142をつなげることができるので、最大100素子弱のイコライザーもできそうです。
また100素子となると表示量も増えるので480×320では少々厳しいところもありますが、800画素もあれば十分
いけるでしょう。なんせ800×480なら480×320の2.5倍の画素数がありますから。


FESP5142-Doでのグラフィックイコライザーです。24素子なので480*320のLCDでも十分です。

制御CPUは大容量が必要

FESP5142-DoではPIC18F26K20を使いました。これはプログラム容量が64kBと比較的大きいものですが、
それでも最終的にはプログラムエリアは86%まで消費しました。イコライザーを100画素近くまで対応させたものを作ろうとすると、
さらにプログラム容量は増える可能性が高いです。そのため、現状で86%だと、追加するような形でプログラムを組めば
高い確率で100%をオーバしそうです。精神的には、もう一段容量の大きい128kBのPICをつかったほうがいいでしょう。
でないと、途中でにっちもさっちもいかなくなってしまうかもしれません。

選択できるPICがない?

そこで、いつもの秋月電子のサイトをみて、つかえそうなPICを探しはじめました。
必要な条件としては、下記のようなものなります。
 @容量が大きい(128kB以上)
 A高速動作のもの(64MHzで動くもの)
 B入手できるもの(できれば秋月だと簡単)
 CCコンパイラに対応しているもの(CCS-CのPCHが使えるもの)
 Dライタソフトが対応しているもの(PICKIT-2のデバイスファイルに記載されているもの)。
 EDIPタイプのもの(QFPだと変換基板が必要だし、ICSPでしか書き込めなくなる)。

とくに@容量A速度は必須でしょうか。B入手性については秋月でなくても、RSコンポやDIGIKEYがあるのであまり制約はないかもです。
問題の1つはCコンパイラ対応です。今もっているコンパイラは保守費用なんか払っていませんから、バージョンアップもしていません。
そのため、新しいPICはあまり対応できていません。 またDライタ対応については、デバイスファイルの編集ソフトも公開されていますので、
その使い方さえ習得すればなんとかなるでしょうが、それでも面倒は避けたいです。EパッケージもDIPタイプなら試作も簡単です。
 で、まずは秋月で売っているもので使えそうなものをピックアップしてみました。
悲しいことに、すべてを満足するものがありません。PIC18F47Q10あたりが使えればいいのですが、重要なCコンパイラ対応が×になっています。

秋月電子で入手できるものからピックアンプしてみました。
PICの種類 @容量 A最大速度 CCCSコンパイラ
対応
DPICライター
対応(PICKIT2)
Eパッケージ 備考
(参考)
PIC18F26K20
64kB 64MHz 28P(DIP) FESP5142-Doで使用
PIC18F8723 128kB 32MHz 80QFP
PIC18F46K22 64kB 64MHz 40P(DIP) FESP5142で使用
PIC18F47K22 128kB 64MHz × × 40P(DIP)
PIC18F47Q10 128kB 64MHz × × 40P(DIP)
PIC18F67J60 128kB 41.667MHz 64QFP


何を使おうか?

さて、使えるPICがなかなか見つからないので、その他の構成も考えてみましょう。

案1)RasPiをつかうのはどうか?
 これなら容量、速度jは完全にクリアーです。RasPi-ZEROあたりでも十分でしょう。もう何も気にする必要はありません。
 RasPIを使う最大の問題は、その起動の遅さです。スイッチONしてから1分ほどかかりそうです。とくにスペックの低いRasPiでは
 CPUが遅いせいか、起動に時間がかかります。オーディオ装置として、適切かなあ〜という気もあります。
 それに、RasPi-zeroでも2000円程度しますし、それにSDカードも必要と、結構高くつきます。
 

案2)H8マイコンなどは?

 以前に電子ボリュームにH8/3052をつかったこともあるので、また使っているうちに思い出せそうではあるのですが、
開発環境(コンパイラーやライター)を揃えるのが面倒です。それに、いまさらH8とつかうのも〜という感じです。
それとH8のマイコンボードはSDカードは不要ではありますが、RasPi-ZEROとおなじくらいの値段です。

案3)PIC18F46K22で我慢する。
 やっぱり、普通に使えるPIC16F46K22あたりに落ち着きそうです。プログラムはなんとか納まるように空き領域を増やすために、
 数kBあるるディジタルフィルターのデータ領域は外付けのEEPROMに納めればいいでしょう。EEPROMはI2Cインターフェイスなので、
 読み込みに時間がかかりますが、起動時の1〜2秒の我慢で済むはずです。それでもプログラム容量が逼迫するなら、文字フォントも
 EEPROMに書き込めばいいかもしれません。頻繁に使用する数字はPIC内に持たせて、それ以外はEEPROMに押し付けます。
 ちょうど、DIV5142にはEEPROMを搭載できるパターンもあるので、それが使えそうです。
  さらにそれでも逼迫するならシリアルSRAMも接続しておいて、フォントデータはすべてそちらに退避しておくのも一つの手です。

 
 DIV5142にはEEPROM用のパターンを設けています。


PICに必要なI/Oピン数は?
 必要なI/Oピン数が少なければ、28PinタイプのPIC18F26K20がつかえるかもしれないので、必要なピン数を一応確認です。

普通に組んだ場合は下記になります。

 ・LCDデータ    ・・・8あるいは16  (DB0〜DB7、DB8〜15)
 ・LCD制御線    ・・・4   (RST、RS、CS、WR 。 RDは使わない)
 ・タッチパネル   ・・・4   (CS、CLK、SI、SO)
 ・I2C        ・・・・2   (SDA,SCL)
 ・ICSP       ・・・・2    
−−−−−−−−−−−−−−−
           合計 20本 あるいは 28本

合計は20あるいは28です。28PinのPICで使えるI/Oは最大で24なので、LCDのデータバスを8ビットにすれば28PinのPICでも余裕で入ります。
16ビット幅になると無理ですが、もうちょと使うピン数を共通化すれば入るかもです。

ということで、節約版は
 ・LCDデータ    ・・・16  (DB0〜15)
 ・LCD制御線    ・・・3  (RS、CS、WR 。 RST,RDはH固定)
 ・タッチパネル   ・・・2  (CS、SI。 CLKはLCDのWRと兼用。SOはDB0と兼用)
 ・I2C        ・・・・2   (SDA,SCL)
 ・ICSP       ・・・・0  (プログラム書き込み後は面倒だけと外す)
---------------------------
           合計 23本

必要I/O数は23になったので、16Bitバスにしても、28PinのPICでも入りそうです。でも、プログラム書き込み後に、いちいちICSPケーブルを外すのも
面倒だなあ〜。まあ、プログラムの開発は40PinのPICで行っておいて、完成時には28PinのPICに移せばいいでしょう。

そもそもデータバスに16ビットも必要?

LCDの出データバスは8ビットでもつかえますが、わざわざ16ビットにする効果はあるだろうか?
確かに、書き込むパルスの回数が半分以下になりますから効果はあるでしょうが、LCDの書き込み
がCPUの実行時間に占める割合が低ければ、あまり効果はありません。このあたりは、実際に
やってみないとわからないところです。まあ、一度組んでみましょう。

評価基板を作りましょう!
ブレッドボードに組んでも良かったのですが、しばらくのお付き合いになる可能性もあるので
小型の基板にとりつけました。ついでにEEPROMとSerialRAMも搭載しています。


まずは部品配置を決めましょう。


完成です。


裏面はいつものポリウレタン線です。φ0.29mmの太めのものをつかっていますが、
これが案外使いやすいです。


こんな感じで接続してつかいます。

あとは、夜な夜なプログラムを書いていきましょう。
今日は二日酔い気味で、調子がちょっと悪いです。早く寝よ・・・・・


ちょっと脇道・・・・コンパイラって賢い!? 2020.10.9

今回のソフト作成ではプログラム容量と速度にかなり気をつかわなくてはいけません{←いつも気をつけろよ!
I/Oを扱うときには16ビット整数の上位8bitだけを必要とするときが頻繁にあります。
そこで通常ならビットシフトが使われると思います。
たとえば

   b = a >> 8  ;

とすれば、b変数にはa変数を8ビット分を右にシフトした値が代入されます。しかし、8回もビットシフトを行うのは
プログラムとしては効率的ではありません(と思っていた・・・。
そのため、いつもは共用体(UNION)をつかっていました。すなわち

  union { int16 x; char y[2]; } z;

  z.x = a;
  b  = z.b[1];


としていたわけです。そこで、今回は本当にコードがどのくらい短くなっているかを調べてみることにしました。
I/OのAポートに1バイトを出力するプログラムで検討です。コードが短くなっていれば、ほぼ自動的に実行速度もあがるはずです。

で、得られたのが予想外の結果でした。

プログラム 内容 命令バイト数
基本形 output_a( a ); 単純にaの下位8ビットを出力 −(基準)
共用体を使用   z.x = a;
  output_a(z.b[1]);
一旦共用体の変数に代入して、その上位バイトを出力。 +8
(まあこのくらいは増えるでしょう
ビットシフトを使用 output_a(a >> 8); aを8回ビットシフトして、上位8ビットを出力 +0 
(増えていない!)

なんと、ビットシフト8回繰り返してもコードが増えていません。不思議に思って、アセンブラリストを見て納得です。8ビット分シフトする
ということは、1バイト分ずれるということですから、コンパイラが自動的に変数の領域をずらして代入しています。なるほど、賢いな〜。
ということは、いままで共用体をつかっていたのは、容量も時間も無意味だった〜ということが判明です。あ〜あ・・・・・

ちなみに、ビットシフト量を16とか24にしても同様に、メモリーの位置をずらすことで対応するようです。

では、シフト量を8ではなく7にしたらどうなるか?上記の結果から予想できますが、まじめにビットシフトを行なうようなので、
36バイトと大幅にコードが増えました。コンパイラが8BitCPU用なので、16bit整数で1ビットシフトしようとすれば8ビットづつ
2回にわけて実行する必要があります。1回のビットシフトをメモリー上の変数領域でやると2バイトのコードが
必要になるので、それが都合7回で7ビット分×2回×2命令バイト数=28命令バイト数は最低必要になるということですね。
ですから、8ビットシフトは最低でも32命令サイクル必要と思って、つかっていなかったのですよね〜。

プログラム 内容 命令バイト数
基本形 output_a( a ); 単純にaの下位8ビットを出力 −(基準80)
8回ビットシフト output_a(a >> 8); aを8回ビットシフトして、上位8ビットを出力 +0 
7回ビットシフト output_a(a >> 7); aを7回ビットシフトして出力 +36
(大幅に増大)

それにしても8回のビットシフトはコードが増えないことがわかったのは大きな収穫です。
コンパイラってよくできてますね。


イコライザは何素子にしよう?

DIV5142を応用するとして、192kHz動作で最大96素子までカバーできますが、そこまで多くしても
あまり意味がない気がしてきました。実際に、市販器をみると多くても30素子程度のものが多いようです。
ということで、PCM5142を2連結にするとして48素子でのイコライザを考えましょう。

画面はシンプルに
 まずはグライコとしてシンプルにいきましょう。
 機能としては
  ・調整する周波数範囲は20Hz〜20kHzで48素子。
  ・LR個別あるいは両方のゲイン調整可能。ゲイン調整ステップは0.2dB程度。
  ・セッティングのロード・セーブは4個


そういえば、初期ゲインの設定もいるな〜。あとで追加しましょう。


画面レイアウトはこんな感じ?初期ゲインの調整も追加しなくっちゃ!

 この画面レイアウトのイメージで、グライコ調整に使う領域はおよそ730×320です。1素子あたりに使えるのは15×300になります。
さてさて、どんなデザインにすれば見やすいだろう?といっても、あまり凝るとメモリーを喰うので、まずはシンプルに単純な四角形に
なるんだろうな〜。

(つづく)