EZ-KIT LiteのSW2, SW3を使ってボリュームのアップダウンをしてみました。PF割り込みを使っています。ボリュームの変更はAC97のヘッドホン出力ゲインの変更で行っています。ゲインは31ステップなので、中間の15を初期値としています。
このプログラムの中で一番注意しなければならないのは、PFHandler()の中で呼んでいるfwEzZKit2191のiAC97Writeメンバー関数です。これはAC97にコマンドを送る関数ですが、同様の関数がmain()の中では"t"で始まる関数であるのに対して、こちらは"i"で始まっています。t, iはそれぞれtask、interruptコンテキストで使用されることを意味しています。MCMはこの点を厳しく区別しますので注意してください。
なお、割り込みの取り扱いについては割り込みを使おうとPF割り込みを使おうを参照してください。また、下のサンプルはプログラムの前半を省略しています。トークスルーを参考に前半を作ってみてください。答えがわからない人向けにプロジェクトをダウンロードできるようにしておきます。
//************************************************************************** // // メイン関数 // // メイン関数では次のことを行う // // 1. 割り込みハンドラ登録 // 2. フレームワークのインスタンス生成 // 3. フレームワークの実行 // 4. コーデックの初期化が終わるのを待つ // 5. コーデックのミュート解除 // 6. 無限ループ // // 以上の処理はほとんどのプログラムで共通である // //************************************************************************** int main (void) { interrupt( SIG_INT5 ,&sportHandler); // SPORT割り込みハンドラ登録 interrupt( SIG_INT15, &PFHandler ); // PF割り込みハンドラ登録 enable_interrupts(); // グローバル割り込みイネーブル setupPF(); myVol = new CVolume( ); // インスタンス生成 myVol->run(); // AC97制御開始 // 入出力のミュートを解除 myVol->tAC97Write( ac97::HEAD_VOLUME, ac97::gain( false, volume, volume ) ); myVol->tAC97Write( ac97::RECORD_GAIN, ac97::gain( false, 8, 8 ) ); // メインルーチンではあとは割り込み待ち while( 1 ) asm( "idle;" ); } //************************************************************************** // // SPORT割り込みハンドラ // 単にインスタンスに制御を渡すだけ // //************************************************************************** void sportHandler( int intr ) { myVol->handleInterrupt(); } //************************************************************************** // // PFの設定 // 0-3はLED出力, 4-5は押しボタン入力 // //************************************************************************** void setupPF(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 edge. io_space_write( MASKAS, 0x30 ); // set PF4,5 to PF interrupt A io_space_write( FLAGS, 0xf & ~volume ); // set singal to LED io_space_write( FLAGC, 0xf & volume ); // clear the 0 LED. } //************************************************************************** // // PF割り込みハンドラ // ボリュームのアップダウンとLED点灯 // //************************************************************************** #define MAX( a, b ) ( a > b ? a : b ) #define MIN( a, b ) ( a < b ? a : b ) void PFHandler( int sig ) { sysreg_write( sysreg_IOPG, General_Purpose_IO ); if ( io_space_read( FLAGS ) & 0x10 ) // PF4 を押したとき { io_space_write( FLAGC, 0x10 ); // 割り込みクリア volume = MAX( volume-1, 0 ); // ボリュームダウン } if ( io_space_read( FLAGS ) & 0x20 ) // PF5 を押したとき { io_space_write( FLAGC, 0x20 ); // 割り込みクリア volume = MIN( volume+1, 31 ); // ボリュームアップ } // ここでヘッドホン出力を設定 // メンバー関数の名前に注意 myVol->iAC97Write( ac97::HEAD_VOLUME, ac97::gain( false, volume, volume ) ); // LED設定 io_space_write( FLAGS, 0xf & ~volume ); // set singal to LED io_space_write( FLAGC, 0xf & volume ); // clear the 0 LED. }
プログラムを走らせてSW2, SW3を押すと、ボリュームのアップダウンにあわせてLEDの表示が変わります。
⇒次はレベルメーター