忍者ブログ
 30年ぶりに復活した隊長の電子工作指令本部

【メイン側】
Application Library の TCP/IP Stack を利用する場合、処理を細かく分割してこまめに
制御を譲り合い、全体を回すような処理にする必要があります。
(USBのフレームワークと同様です)
本作のアプリは、この仕組みにのっとったものとなっています。

static void Run(void)
{
    for(;;)
    {
        TaskSTK();
        TaskSDC();
        TaskLCD();
        TaskAPP();
    }
}
TCP/IP通信処理や、画像のデコード処理は、基本的にApplication Library を利用している
だけです。Pingに応答するICMPServerや、SNTPクライアント等も、殆どライブラリがやって
くれます。
例えば、サーバーへの接続は次のように記述します。
// ソケットオープン(接続)
s_Socket = TCPOpen((DWORD)s_PopServer, TCP_OPEN_RAM_HOST,
    POP3_SERVER_PORT, TCP_PURPOSE_GENERIC_TCP_CLIENT);
下記は、独自に記述してある主な機能です。

SDC(microSD)ドライバ

前作のフォトフレームのコードを、ほぼそのまま使用しました。
SPIクロックは、20MHzに設定しています。(これ以上上げるとエラー)
後、SectorRead() は、DMAをやめて、代わりに一部をインラインアセンブラで書き直しました。

天気予報の取得

tenki.jp から取得した、各地のピンポイント天気のHTMLを解析しています。
解析とはいっても大した事はありません。文字列検索が主です。
今後、ページがリニューアルする度に改修する必要が多々あると思われます。

POP3クライアント

POPプロトコル自体は単純明快です。なので、これも大した事は行っていません。
添付ファイルは、Base64デコードする必要がありますが、これも特に難しい技術でも何でもない
ですね。ピンポイントでアセンブラ化すると、少し早くなるかもしれません。
普通のメーラーや、いくつかのWebメーラー、携帯でテストしていますが、変なメーラーから
送信したものだと受信出来ないかも知れません。

画像転送

SRAMへアクセスして、表示データを読み書き込む処理です。
水平・垂直ブランク期間は、SRAMのアドレス・データバスが開放されている状態なので、この間
にアクセスします。
ブランク期間は、INT3/4(66Pin/67Pin)に接続されている同期信号により知る事が出来ます。
両方の信号のうち、水平同期信号を割り込みトリガーとして利用し、垂直ブランクかどうかは、
67Pin(RA15)を調べて判断します。
水平と垂直の処理上の違いは、単に処理する時間(量)が短いか長いかだけの違いです。

割込み優先度は、オーバーヘッドが少なくなるよう最高の7を指定しました。しかし、これでも
20サイクル程度プロローグコードが挿入されるようです。(7以外はもっと多い)
割込みハンドラ内では、次の三種類の何れかを実行します。

1) 塗りつぶし:  単色カラー値18BitをSRAMに書き込みます。
2) ビットマップの書き込み:  ビットマップデータをSRAMに書き込みます。
3) ビットマップの読み込み:  ビットマップデータをSRAMから読み込みます。

ビットマップの読み込みは、転送先と転送元をブレンドして転送するために用意しました。
本作では、カレンダーの文字表示で使用しています。
背景の上に、文字だけを描画する処理です。アンチエイリアスされるので文字のギザギザも
低減します。
現状は単色だけですが、BItmapのα値を使うようにすれば、AlphaBlend化も可能でしょう。

節電

休止条件(周囲が暗い or 設定が"0"の時間帯)が成立すると、メイン側PICは周辺電源をOFFし
スリープモードへ入ります。
そしてWDTにより、8秒おきにウェイクアップし、今度は逆に稼動条件が成立していないかどうか
をチェックし、なければ即スリープに戻ります。
また、メイン側PICは、稼働中であっても何もする事がない間は、パワーセーブ状態
(32.768KHz駆動)になって節電します。

なので、消費電流の大きい80MHzで動作しているのは、画像を切り替えたりメールチェック等の
定期通信を行っている間だけです。

【サブ側】

基本的な初期化後、水平・垂直スキャンを繰り返すだけです。

水平・垂直ブランク期間は暇なので、この間に次のスキャンに備えて必要な演算や、nop で
時間待ちを行います。

本作では、垂直スキャンは下から上へと行うので、1ライン終わる毎にアドレス値を1ライン分づつ
小さくしていきます。一番上のラインを完了したら、一番下のラインへ戻ります。

水平スキャンは、普通に左から右へ行います。
PICは、1ドット毎にSRAMのリードアドレスをインクリメントします。
すると、SRAMの各アドレスに記録されているデータが、バスに次々と出力されます。
LCDは、出力されたデータをフェッチし、各ドットを表示していきます。
PICとSRAMとLCDは、同じ30MHzクロックで同期して動作しているので、一糸乱れず1ドットづつ
表示させていく事が出来ます。

ここで、PICとLCDが同じクロックということは、アドレスのインクリメント処理を1サイクル毎に行う
必要がある事にお気付きでしょうか。
さすがのPIC32MXでも、これは不可能です。1足してIO出力で、最低2サイクル必要になります。
そこで、SRAMのバーストリードを利用します。
SRAMのADV/LDピンの制御と、4足してIO出力の処理でバーストリード可能となり、4サイクル
で4アドレス分の処理を完了させる事が出来ます。
つまり、1サイクル=1アドレス=1ドットの処理が実現します。

実は当初は、PICは60MHzで駆動し、1/2に分周した30MHzをLCDのドットクロックにする予定
で設計していました。ところが、回路のチェック中に、PICの外部クロックはMax.50MHzとデータ
シートに記載されている事に気がつき、バーストリードでなんとかならないか再考した結果、
現状案が生まれました。

この他、1ラインのピッチを800ではなく、1024にしてあるのも大きなポイントです。
これは、水平スキャン中に16ビットを超えるビットの書き込みを行わなくても済むようにするため
です。
PIC32MXは、レジスタは32Bitでも、ポートは16Bitですから、17Bit以上のデータは一度では
IO出力出来ず、二度に分けて出力する必要があります。
もし1ラインを800にすると、水平中どこかで桁上がりが発生するので、二度IO出力しなければ
なりません。1024アライメントにする事により、水平中の桁上がりを避けることが出来ますので
一度のIO出力(16ビット分)だけで済ませる事が出来ます。
後は、暇な期間である水平ブランク期間にアドレスを1024減算し、その値については二度に
分けてIO出力すればOKですね。 

 

拍手[1回]

PR
この記事へのトラックバック
この記事にトラックバックする:
隊長

ブログ内検索

Copyright © [ The 電子工作 ] All rights reserved.
Special Template : 忍者ブログ de テンプレート and ブログアクセスアップ
Special Thanks : 忍者ブログ
Commercial message : [PR]