相変わらず、Arduinoでオシロの続きをちょっと。
LCDやOLEDの、SPI通信速度で、表示速度がちょっと
遅いのが気になっているので、最終的に速度アップを
するとしたら、どの程度まで高速化できるのかを
チェックしておくことに。
SPIといっても、LCDもOLEDも4ピンシリアルってやつ
なので、内蔵SPIモジュール使ってるわけじゃなく、
内部ではdigitalWrite()で処理してるので、これが
遅さの元凶だろうと。
んで、直接レジスタを叩いて、信号をオン/オフする
ロジックに。変えるのは、SPI通信用の関数だけ
なので、局所的な修正で済んだ。
で、実行してみた結果を整理してみると、ざっくり、
処理速度が一桁速くなった。
たとえば、
こんな風に、斜めの線で扇形を描いていく処理を
4方向繰り返す処理。修正前は45秒ほど掛かっていた
のが、修正後は約4秒。
10倍くらい速い。この写真の扇表示なら1秒以内。
実際は、描画処理だけじゃなく、線を描く関数内で、
線の傾きの計算とかモロモロしているはずなので、
それを含めると、SPI通信処理周りは、もっと速く
なっているはず。
その他、psetで全画面表示とかも、桁違いに速く
なってる。シメシメ。
やっぱり、digitalWriteの遅さが原因だったんだな。
修正前後の、SPI周りの関数を抜粋。
<<<修正前>>>
void LcdWrite(byte dc, byte data)
{
digitalWrite(PIN_SC1, LOW);
digitalWrite(PIN_DC, dc);
shiftOut(PIN_SDIN, PIN_SCLK, MSBFIRST, data);
digitalWrite(PIN_SC1, HIGH);
}
<<<修正後>>>
void LcdWrite(byte dc, byte data)
{
PORTD &= ~(1<< PIN_SC1); // chip select = LOW
if (dc != LCD_D) {
PORTD &= ~(1<< PIN_DC); // data/command LOW(command)
} else {
PORTD |= 1<< PIN_DC; // data/command HIGH(data)
}
for (int i = 0; i<8; i++) {
PORTD &= ~(1<< PIN_SCLK); // serial clock down
if ((data & 0x80) == 0x80) { // pick up MSB
PORTD |= 1<< PIN_SDIN; // serial data(HIGH)
} else {
PORTD &= ~(1<< PIN_SDIN); // serial data(LOW)
}
PORTD |= 1<< PIN_SCLK; // serial clock up
data <<= 1; // MSB first
}
PORTD |= 1<< PIN_SC1; // chip select HIGH
}
I/Oピン周りの定義は共通で、こんな感じ。
#define PIN_SC1 7 // chip select
#define PIN_SDIN 4 // serial data
#define PIN_SCLK 3 // serial clock
#define PIN_RES 6 // reset
#define PIN_DC 5 // data/command
引き数のdcはデータ/コマンドの選択、dataは
送信するデータ1バイト分。
どちらも、ピン番号はdefineマクロの値を変える
だけで簡単に入れ替えられるんだけど、修正後の
方は、PORTD内だけでしかピンを自由に選択でき
ない。
まぁ、D2~D7の6本から自由に5本を選べるだけ
でも充分かなと。
とりあえず、グラフィック周りの速度は、いざと
なれば充分速い速度に切り替えられるので、必要
になったら…だな。
懸念点は一つ減った。
http://bylines.news.yahoo.co.jp/yamamotoichiro/20140507-00035106/
FreeBSDにも穴か。へぇ。PS4だけじゃなく、
Mac OSのMachも、元を辿ればBSD系だった
ような。
http://www.huistenbosch.co.jp/event/game/
152万平米のゲーセン?