「PIC AVR 工作室」サイトの日記的なブログです。
サイトに挙げなかった他愛ないことを日記的に書き残してます。
PIC AVR 工作室 ブログ



引き続き、arduinoとLM1881でビデオのオーバレイ処理
の実験です。

自作したシリアル版のarduino(MEGA8登載機)でさらに
実験してみました。このボードなら、INT0、INT1の
両ピンは完全にフリーになっているので。

で、早速結果はというと…
c-syncはちゃんと検知できました。でもv-syncは
動作せず。

ラインカウンタはint型で定義しているので、
0クリアされずにずーーとカウントしつづけ、
16ビット数値がオーバーラップする時にちょっとだけ
画面に何か出ます。

実験的に、およそ1画面分のライン数で0クリアする
ようにしてみたら、こんな風な画面が出てきました。


垂直同期が取れないので、市松模様が上下にゆっくり流れて
しまっています(TへT)
なお、スケッチはこれ。
(不等号と&マークは全角に置き換えてます)

// arduino video overlay sketch
// with interrupt 0 (v sync)
// and interrupt 1 (c sync)
// output video signal on digital pin 4

#define video_out 4


volatile int line_no;

volatile boolean bitmap[12] = {LOW,HIGH,
HIGH,LOW,
LOW,HIGH,
HIGH,LOW,
LOW,HIGH,
HIGH,LOW,};


void v_sync()
{
digitalWrite(13, HIGH);
line_no = 0;
}


void c_sync()
{
int disp_line;
int i;
int n;


line_no ++;

if((line_no >= 40) && (line_no <= 135)){

disp_line = (line_no - 40) / 16; //line no now display

for (i=0;i<2;i++){
digitalWrite(video_out,bitmap[disp_line * 2 + i]); //display a bit
}
digitalWrite(video_out,LOW); //black
}

if (line_no == 262+10){
line_no = 0;
}

}



void setup()
{
Serial.begin(9600);
pinMode(video_out, OUTPUT); // set digital pin4 for output video signal
digitalWrite(video_out, LOW);

line_no = 0;
attachInterrupt(1, c_sync, RISING);
attachInterrupt(0, v_sync, RISING);
}

void loop()
{
Serial.println(line_no);
}


配列「bitmap」で定義したイメージがそのまま
画面に市松模様として表示されているのが
お判りいただけるかと思います。


LM1881を繋がずに単体で動作確認をすればv-sync
割り込みも機能してるし、INT1、INT0を差し替えて、
スケッチも逆に書き直してみましたが、やはり
v-syncだけは機能しません。
(つまり、ハードウェアの故障では無いということ)


少なくともc-syncは考えていたとおりに動くことは
判りました。なのでreduino-nanoでc-syncが動作
していなかったのは、やはりデジタル3ピンに繋がった
470Ωの抵抗のせいだろうと思います。

一方、v-syncが上手く機能しない理由はまだあまり
釈然としないのですが、なんとなく想像レベルでは
理由が思い浮かびます。

その理由は…

c-syncでの処理時間が長すぎるということが1点。
そして、割り込みからの復帰処理(arduino言語の
標準機能の内部処理)で、int0、int1どちらから
復帰する際にも両方のトリガーをクリアしてしまう
のでは、ということ。

AVRには32バイトのレジスタファイルが存在する
ので、高級言語の割り込み処理では、これら32個
のレジスタをドッカンとスタックに押し込んで
いるようです。(arduinoについてはまだ未確認ですが)

割り込み開始で32個一気にpush。割り込み終了時に
32個纏めてpopをすることになるわけですが、
これにかなりの時間を使ってしまうだろうという
のが1点。
さらに、高級言語なので元々処理速度が遅いという
のが2点目。

多分そこらへんの理由もあって、1回のc-sync割り込み
に要する時間は結構長いはず。

それは何に影響するのか?

特に垂直同期期間では、シンクロ信号に等価パルス
が入るので、走査線1本の時間は通常の半分しか
ありません。
そうなると、v-syncのトリガがc-sync処理中に発生
するという可能性が高まります。多分、実際c-sync
処理中にv-syncのトリガが引かれているかと
思われます。

その際、
  「v-sync割り込みが発生していたよ」
というトリガの履歴がc-sync割り込みからの復帰時にも
残されていれば、その後あらためてv-sync割り込みが
かかり、ラインカウンタがちゃんと0クリアされる
はずなんですが、c-sync割り込みからの復帰時に
v-sync割り込みがあったことの履歴も一緒にクリア
されてしまっているのではないか?と。

そこまでが想像です。
残念ながら、調べ方が思い浮かびません。

arduinoはシミュレーターが付いていないし、
オンボードデバッグするにしても、使えるのは
シリアル通信機能程度。シリアル通信機能は
あまり割り込み処理とはあまり相性良くないし、
ビデオ信号と比べて遅すぎて有効ではありません。

本当は、シミュレーター使ってc-sync割り込み1回
の処理時間(処理クロック数)を調べたい
のですが…

ひとまず、arduinoの処理速度や割り込み機能を
使う範囲では、このレベルが限界かなぁ…と。

どなたか頑張って、v-syncにきちんとシンクロさせる
ことに挑戦してみてください!


調査方法といえば、arduinoもWIN-AVRも
gccベースなので、上手いことWIN-AVRを
騙してシミュレーターを使えないかなぁと
考えてみたんですが、arduinoのファイル内に
使えそうなファイルは生成されていないみたい。

もう少し調べてみて、上手いことWIN-AVRで
シミュレーションできないか考えてみます。

さすがに組み込みマイコンでは、後付けで
コアダンプを引っ張り出すのは一筋縄で
行かないし、出来たとしても、デバッグ用の
情報をコンパイラが生成しておいてくれないと、
コアダンプも読み様がありませんしね。

本来は、MEGA168にはデバッグ用のワイヤーが
内蔵されているんですけど、arduinoでそれに
対応するくらいなら、最初からWIN-AVR
使いなさいよって話ですよねぇ…

せめてシミュレーター機能は欲しいなぁ…



コメント ( 0 )