ポートの動作もさせましたので、次は割り込みです。とリあえず、これだけできれば一通りのことができるようになります。
さて、まずは割り込みといえばデバッグモニター用にシリアルを書くものと相場が決まってるのでw、これを作ってみることにします。NGWのシリアルポートはUSART1のRXDとTXDのみがRS-232Cのレベル変換ICに繋がっています。RTSとCTSのハードウェアフロー制御信号線は繋がっていないので使えません。これらの信号線は、NGWの端子側でループバックで接続されているだけです。そんなわけで、ハードウェアフロー制御はできないので、フロー制御処理は入れません。
AVR32のgccでは割り込み処理は以下のように記述します。
#include <sys/interrupts.h>
// 割り込みハンドラ
__int_handler *usart_int_handler()
{
// 割り込み処理
return (void *) 0;
}
// 割り込みハンドラの登録
set_interrupts_base( (void *) AVR32_INTC_ADDRESS );
register_interrupt( (__int_handler) (usart_int_handler), // 割り込みハンドラ
AVR32_USART1_IRQ/32, // 割り込みグループ
AVR32_USART1_IRQ % 32, // 割り込みライン
INT0); // 優先度
AVR32の割り込み処理では、割り込み入力を1つのグループの中でorゲートで接続されています。そのグループごとに優先度を設定できます。上記の処理を割り込みマスクを解除する前に実行することで、ハンドラが登録されます。
AVR32のUSARTでは、普通の非同期シリアルの他にいろいろな機能がついています。例えばマンチェスター符号のエンコード/デコードができたりするので、ASKやFSKの変調/復調回路と組み合わせるだけで、ちょっとした無線データモデムを作れます。
まぁ、それをやってみるのもいいのですが、それにはNGWが2台必要なので今回はパスということでw
ポート、通信設定初期化
さて非同期シリアルの話に戻りますが、PIOAのPA17,18がRXD,TXDなので、これらをポートとして使わない設定にし、USARTのあるペリフェラルA(Bを選択するとタイマー0の端子)を選択しておきます。また、RXD,TXDの接続先は232Cのトランシーバーなので、プルアップはオフにします(トランシーバー内でプルダウンされているため)。
ボーレイトの設定
非同期シリアル通信では、通常はデータをスタートビットから特定のクロックでサンプリングして、多数決でビットの値を決定します。サンプリングクロック用のボーレイトジェネレイターの分周カウンタの設定をしなければなりません。
USART1の動作クロックはPBAから供給されます。PBAはPLLの再設定で30MHzにしましたが、USART1にはこれを8分周したクロックが供給されるようになっています。
今回はサンプリングを16倍で行うことにしますので、ボーレイトジェネレータの分周設定は115200bpsの場合以下のような計算式となります。
CD=2: (30*10^6(Hz)/8) / (16 * CD) = 117187.5
誤差 117187.5/115200 = 1.72%
取り合えず数%以内に収まっていれば、十分使えますので2で設定します。
割り込み処理
今回のシリアルドライバは、受信だけでなく送信も割り込みを使っています。といってもたいしたことなくて、単に送信バッファにデータを入れたときに割り込みを許可して、割り込み内でバッファが空になったら送信割り込みを禁止します。送信割り込みを使う場合に注意しなければいけないのが、送信割り込み許可マスクの解除タイミングと、割り込み処理部分です。誤った設計をすると、送信割り込みが停止したり、不要なところで許可してしまう場合がありますので注意が必要です。が、そういうのはフロー制御を実装するときに大問題になるので、今回は特にあまり気を払う必要はありませんw 実際の処理はサンプルフローを参照下さい。
取りあえず、一区切りつきましたので、SDRAMメモリ検査、LED点灯、シリアルループバックのみを行う、スタンドアロンのサンプルをアップロードしておきます。次はRTOSのポーティングをしますが、取りあえずμITRON v4.0互換のHOS-V4をAVR32対応にしてみることにします。TOPPERSは、なんかいろいろと公開するのが面倒くさそうなのでw たぶん時間がちょっとかかるので、このカテゴリの記事は当分おあずけ、かもしれません。
主にドールや電子工作関連を中心にしたブログです。