前回はINTRDxを使うことによって、同じ割り込みを共有するペリフェラルの割り込みをさばく方法を説明しました。今回は割り込みの共有が起きないように優先順位をずらす方法を説明しましょう。
2191のデフォルト状態では、PF割り込みAとBは同じ割り込みを共有しています。そのため前回はINTRDxを使いました。しかし二つのペリフェラルに違う割り込みを割り当てればINTRDxを使わずに済みます。
割り込みの割り当ての変更はIPRxで行います。IPRxの内容を書き換えれば好きなデバイスに任意の割り込み順位を与えることが出来ます。
早速例を見ましょう。だいぶ見慣れてきましたね。MASKASとMASKBSの設定までは前回と同じです。今回新しいのはIPR3の設定です。IPR3レジスタは4つのフィールドを持っています
予約 | MDMAIP | FLAGBIP | FLAGAIP |
右側がLSBです。フィールドは4ビットずつで、ここにはペリフェラル割り込み順位を設定します。今回、PF割り込みAにはコア割り込み順位14、PF割り込みBにはコア割り込み順位15を使います。MDMAIPは使わないので適当に順位15を使います。そうすると、それぞれのペリフェラル割り込み順位は10,11,11となります。結局IPR3に書き込む値は0x0BBAとなります。
割りこみに違う順位を割り当てたので、割り込みハンドラの処理は単純なものになりました。
#include <def2191.h> #include <sysreg.h> #include <signal.h> void intHandlerA( int ); void intHandlerB( int ); int main(void) { sysreg_write( sysreg_IOPG, General_Purpose_IO ); io_space_write( DIR, 0x0f ); // set PF0-3 to output io_space_write( FSPR, 0x00 ); // Source polarity is positive. io_space_write( FSSR, 0x30 ); // set PF4,5 to edge sense. io_space_write( FSBER, 0x00 ); // set PF4,5 to one dege. io_space_write( MASKAS, 0x10 ); // set PF4 to PF interrupt A io_space_write( MASKBS, 0x20 ); // set PF5 to PF interrupt B sysreg_write( sysreg_IOPG, Interrupt_Controller_Page ); io_space_write( IPR3, 0x0BBA ); // PFA=>10, PFB=>11 sysreg_write( sysreg_IOPG, General_Purpose_IO ); interrupt( SIG_INT14, &intHandlerA ); interrupt( SIG_INT15, &intHandlerB ); enable_interrupts(); // set GIE while (1) ; } int count = 0; void intHandlerA( int sig ) { count ++; io_space_write( FLAGS, 0x0f & count ); // set singal to LED io_space_write( FLAGC, 0x0f & ~count ); // clear the 0 LED. io_space_write( FLAGC, 0x10 ); // clear interrupt } void intHandlerB( int sig ) { count --; io_space_write( FLAGS, 0x0f & count ); // set singal to LED io_space_write( FLAGC, 0x0f & ~count ); // clear the 0 LED. io_space_write( FLAGC, 0x20 ); // clear interrupt }
動作は前回とまったく同じです。
⇒次はよりよい割り込み処理