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の表示が変わります。
⇒次はレベルメーター