ADSP-BF537 EZ-KIT Lite上で動作するオーディオフレームワーク関連の関数および変数を含む名前空間。 プログラマは以下の関数を呼んでオーディオ処理を開始する。
関数 | |
| void | initGPIO (void) |
| GPIOの初期化 | |
| void | resetCODEC (void) |
| オーディオ・コーデックのリセット | |
| void | initSPORT (void) |
| SPORT0の初期化 | |
| void | initDMA (void) |
| SPORT DMAの初期化 | |
| void | initInterrupt (void) |
| 割り込みのイネーブル | |
| void | init () |
| afwの初期化 | |
| void | startAudio (void) |
| SPORTとDMAのイネーブル | |
| void | rxISR (int signal) |
| SPORT0受信DMA割り込みハンドラ | |
| void | initProcessData (void) |
| コールバック関数の処理化 | |
| void | processData (const shortfract leftIn[], const shortfract rightIn[], shortfract leftOut[], shortfract rightOut[], int count) |
| オーディオ・コールバック関数 | |
変数 | |
| int volatile | txBuffer [INTR_PER_BUFFER][SAMPLE_PER_INTR][CH_PER_SAMPLE] |
| SPORT0 DMA 送信バッファ | |
| int volatile | rxBuffer [INTR_PER_BUFFER][SAMPLE_PER_INTR][CH_PER_SAMPLE] |
| SPORT0 DMA 受信バッファ | |
| static short | leftIn [SAMPLE_PER_INTR] |
| 左チャンネル入力バッファ | |
| static short | leftOut [SAMPLE_PER_INTR] |
| 左チャンネル出力バッファ | |
| static short | rightIn [SAMPLE_PER_INTR] |
| 右チャンネル入力バッファ | |
| static short | rightOut [SAMPLE_PER_INTR] |
| 右チャンネル出力バッファ | |
| const int | LEFT_CH = 0 |
| 左チャンネル指定定数 | |
| const int | RIGHT_CH = 1 |
| 右チャンネル指定定数 | |
| const int | INTR_PER_BUFFER = 3 |
| バッファ数宣言定数 | |
| const int | CH_PER_SAMPLE = 2 |
| サンプルあたりチャンネル数の宣言 | |
| const int | SAMPLE_PER_INTR = 8 |
| 割り込みあたりのサンプル数 | |
| const int | CODEC_RESET_PULS_WIDTH = 0x10000 |
| オーディオ・コーデックのリセット時間 | |
| const int | SPORT0_SLEN_24 = 0x0017 |
| SPORT0のワード長 | |
| void afw::initGPIO | ( | void | ) |
GPIOの初期化
PORT Fに割り当てられているGPIO(フラグピン)の初期化を行う。 PORT Fのピン割り当ては以下のとおり(カッコ内はマスク)
afw::init()が自動的に呼び出すので、プログラマがこの関数を明示的に呼ぶ必要はない。
参照元 init().
00054 { 00055 *pPORTF_FER = 0x0000; // ポート Fのプログラマブル・フラグを利用できるようにする。 00056 *pPORTFIO_DIR = 0x1FC0; // ポートFの方向設定。LEDとコーデックのRESET制御を出力に 00057 *pPORTFIO_INEN = 0x003C; // プッシュボタン用のピンを入力可能にする 00058 *pPORTFIO_CLEAR = 0x0FC0; // LEDを消灯 00059 }
| void afw::resetCODEC | ( | void | ) |
オーディオ・コーデックのリセット
PORT Fに割り当てられているコーデック・リセット信号(PF12)をトグルする。 afw::init()が自動的に呼び出すので、プログラマがこの関数を明示的に呼ぶ必要はない。
参照元 init().
00068 { 00069 *pPORTFIO_CLEAR = PF12; // リセット・ピンをアサートする。 00070 00071 for( int i = 0; i< CODEC_RESET_PULS_WIDTH;i++) // アサート状態を一定時間保持 00072 asm volatile( "nop;" ); 00073 00074 *pPORTFIO_SET = PF12; // リセット・ピンをデアサートする。 00075 00076 00077 }
| void afw::initSPORT | ( | void | ) |
SPORT0の初期化
オーディオコーデックに接続されているSPORT0を初期化する。シリアル回線の フォーマットはI2Sで、クロックおよびLR信号は外部生成。この関数を読んだ段階 では、ポートはディセーブルのままにしておく。
設定は送受信とも以下のとおり
詳細はADSP-BF537 Hardware Referenceの "Stereo Serial Operation" を参照のこと。 afw::init()が自動的に呼び出すので、プログラマがこの関数を明示的に呼ぶ必要はない。
注意:EZ-KIT Lite BF537 Rev 1.0のユーザーはSPORTのクロックおよびフレーム同期 信号を自分で生成する設定に変更しなければならない。
参照先 SPORT0_SLEN_24.
参照元 init().
00105 { 00106 // Sport0 受信設定 00107 *pSPORT0_RCR1 = RFSR | RCKFE; 00108 *pSPORT0_RCR2 = SPORT0_SLEN_24 | RSFSE; 00109 00110 // Sport0 送信設定 00111 *pSPORT0_TCR1 = TFSR | TCKFE; 00112 *pSPORT0_TCR2 = SPORT0_SLEN_24 | TSFSE; 00113 00114 00115 }
| void afw::initDMA | ( | void | ) |
SPORT DMAの初期化
SPORT0に接続されているDMAを設定する。DMA3が受信、DMA4が送信である。 オーディオ信号は16ビット以上の長さがあるのでワードサイズは32bit, 連続送受信のためにオートバッファ、モードを使う。また、トリプル・バッファを 実装するために、DMA転送は2次元で行い、3ライン分のバッファを確保して各ラインの 転送を終えるたびに割り込みを発生させる。 afw::init()が自動的に呼び出すので、プログラマがこの関数を明示的に呼ぶ必要はない。
参照先 CH_PER_SAMPLE・INTR_PER_BUFFER・rxBuffer・SAMPLE_PER_INTR・txBuffer.
参照元 init().
00127 { 00128 00129 // DMA3の設定 00130 *pDMA3_CONFIG = WNR | WDSIZE_32 | DI_EN | DI_SEL | FLOW_AUTO | DMA2D ; // 32bit, 2DDMA, 各ライン割り込み、オートバッファ 00131 *pDMA3_START_ADDR = (void *) rxBuffer; // 受信DMAバッファへのポインタ 00132 *pDMA3_X_COUNT = CH_PER_SAMPLE * SAMPLE_PER_INTR; // 2次元DMAの桁数 00133 *pDMA3_X_MODIFY = sizeof(int); // 転送ごとのインクリメント量 00134 *pDMA3_Y_COUNT = INTR_PER_BUFFER; // 2次元DMAの行数 00135 *pDMA3_Y_MODIFY = sizeof(int); // 1行転送後のインクリメント量 00136 00137 // DMA4の設定 00138 *pDMA4_CONFIG = WDSIZE_32 | FLOW_AUTO | DMA2D; // 32bit, 2DDMA, オートバッファ 00139 *pDMA4_START_ADDR = (void *)txBuffer; // 受信DMAバッファへのポインタ 00140 *pDMA4_X_COUNT = CH_PER_SAMPLE * SAMPLE_PER_INTR; // 2次元DMAの桁数 00141 *pDMA4_X_MODIFY = sizeof(int); // 転送ごとのインクリメント量 00142 *pDMA4_Y_COUNT = INTR_PER_BUFFER; // 2次元DMAの行数 00143 *pDMA4_Y_MODIFY = sizeof(int); // 1行転送後のインクリメント量 00144 00145 }
| void afw::initInterrupt | ( | void | ) |
割り込みのイネーブル
SPORT0 受信割込みを有効化する。SPORT0 受信割り込みはIVG9で処理したいので、その割り当ても設定する。 afw::init()が自動的に呼び出すので、プログラマがこの関数を明示的に呼ぶ必要はない。
参照先 rxISR().
参照元 init().
00153 { 00154 // SPORT0受信DMA終了割り込み(DMA3)の優先度を設定する 00155 *pSIC_IAR0 &= 0xff0fffff; // DMA3の割り込み割りあてを解除 00156 *pSIC_IAR0 |= 0x00200000; // DMA3を優先度2 (IVG9)に割り当てる 00157 00158 // 割込みハンドラを登録する 00159 interrupt( SIGIVG9, rxISR ); 00160 00161 // SPORT0 RX 割込みを有効に 00162 *pSIC_IMASK |= 0x00000020; 00163 }
| void afw::init | ( | void | ) |
afwの初期化
オーディオ・フレームワークの初期化。初期化関数はこれひとつよべば、残りの関数を まとめて呼んでくれる。ただし、afwstartAudio は呼ばないので、プログラマが明示的に 呼ばなければならない。
参照先 initDMA()・initGPIO()・initInterrupt()・initProcessData()・initSPORT()・resetCODEC().
参照元 main().
00173 { 00174 initGPIO(); 00175 resetCODEC(); 00176 initSPORT(); 00177 initDMA(); 00178 initInterrupt(); 00179 00180 initProcessData(); 00181 }
| void afw::startAudio | ( | void | ) |
| void afw::rxISR | ( | int | signal | ) |
SPORT0受信DMA割り込みハンドラ
| signal | ハンドラが呼ばれた割り込み順位が与えられる。値は SIGIVG7 〜 SIGIVG15。 |
DMA3_CURR_Y_COUNTは、転送の最初に当たってDMA3_CURR_Y_COUNTの値に設定され、 ラインの転送が終わるごとにデクリメントされる。しかし、最後のラインの 転送後は、デクリメントされずに1のままに留まる。その結果、各ラインの転送終了 では、割込み発生ごとに以下のようにDMA3_CURR_Y_COUNTの値が変化する
このことから、ソフトウェアとの同期に使ってよいのはDMAx_CURR_Y_COUNTが2の場合 のみであり、あとは決めうちでバッファの添え字をインクリメントしなければならない事がわかる。 プログラム中では、この添え字としてbufferIdxをあてている。
トリプルバッファの管理が終わったら、受信DMAバッファからデータを取り出し、並べ なおしてから afw::processData を呼ぶ。
参照先 LEFT_CH・leftIn・leftOut・processData()・RIGHT_CH・rightIn・rightOut・rxBuffer・SAMPLE_PER_INTR・txBuffer.
参照元 initInterrupt().
00252 { 00253 static int bufferIdx = 0; // トリプル・バッファ操作用インデックス 00254 00255 *pDMA3_IRQ_STATUS = 0x0001; // 割込みクリア 00256 00257 // トリプルバッファのどのバッファを使うか決める 00258 if ( *pDMA3_CURR_Y_COUNT == 2 ) // 2次元DMAの最初の行の転送が終了した場合 00259 bufferIdx = 0; 00260 else // それ以外の場合 00261 bufferIdx ++; 00262 00263 // DMAが格納した受信データを入力バッファにコピーする 00264 // 受信データバッファは24bit データを右詰で32bit 変数に格納しているので 00265 // 8bit右シフトして入力バッファにコピーする 00266 for( int i =0; i< SAMPLE_PER_INTR; i++ ){ 00267 leftIn[i] = rxBuffer[bufferIdx][i][LEFT_CH] >>8; 00268 rightIn[i] = rxBuffer[bufferIdx][i][RIGHT_CH] >>8; 00269 } 00270 00271 // ユーザー・コールバック関数の呼び出し 00272 processData( 00273 (shortfract *)leftIn, // short型とshortfract型は 00274 (shortfract *)rightIn, // 同じ大きさなので、 00275 (shortfract *)leftOut, // キャストによって強制変換していい 00276 (shortfract *)rightOut, 00277 SAMPLE_PER_INTR 00278 ); 00279 00280 // 出力バッファのデータを送信データバッファにコピーする 00281 // 送信データバッファは24bit データを右詰で32bit 変数に格納しているので 00282 // 出力バッファから8bit左シフトして送信バッファにコピーする 00283 for( int i =0; i< SAMPLE_PER_INTR; i++ ){ 00284 txBuffer[bufferIdx][i][LEFT_CH] = leftOut[i] <<8; 00285 txBuffer[bufferIdx][i][RIGHT_CH]= rightOut[i] <<8; 00286 } 00287 00288 }
| void afw::initProcessData | ( | void | ) |
| void afw::processData | ( | const shortfract | leftIn[], | |
| const shortfract | rightIn[], | |||
| shortfract | leftOut[], | |||
| shortfract | rightOut[], | |||
| int | count | |||
| ) |
オーディオ・コールバック関数
| leftIn | 左チャンネルの入力データバッファ | |
| rightIn | 右チャンネルの入力データバッファ | |
| leftOut | 左チャンネルの出力データバッファ | |
| rightOut | 右チャンネルの出力データバッファ | |
| count | 各バッファに格納されているオーディオデータの数 |
for文の内部では、1サンプルづつ、左右チャンネルコピーを行う。これで 入力データが出力にコピーされる。コピーする際、 param::gainの値を データに乗ずる。
割り込みソースのクリアなどは、この関数の呼び出し側で行うので、関数内で 処理する必要はない。
processdata.cpp の 41 行で定義されています。
参照先 param::gain.
参照元 rxISR().
00048 { 00049 00050 for ( int i=0; i<count; i++ ){ // 引数配列のすべてのデータをコピーする。 00051 leftOut[i] = leftIn[i] * param::gain; 00052 rightOut[i] = rightIn[i] * param::gain; 00053 } 00054 00055 } // processData
| volatile int afw::txBuffer |
| volatile int afw::rxBuffer |
short afw::leftIn[SAMPLE_PER_INTR] [static] |
左チャンネル入力バッファ
afw::processDataに引数として渡すための一時バッファ。afwrxBufferのデータは L,R,L,Rになっているので、左チャンネルだけ取り出してこのバッファに格納する。
参照元 rxISR().
short afw::leftOut[SAMPLE_PER_INTR] [static] |
左チャンネル出力バッファ
afw::processDataに引数として渡すための一時バッファ。afwtxBufferのデータは L,R,L,Rになっているので、afwprocessDataが返してきた値の左チャンネルデータを このバッファから読み出してafwtxBufferに格納する。
参照元 rxISR().
short afw::rightIn[SAMPLE_PER_INTR] [static] |
右チャンネル入力バッファ
afw::processDataに引数として渡すための一時バッファ。afwrxBufferのデータは L,R,L,Rになっているので、右チャンネルだけ取り出してこのバッファに格納する。
参照元 rxISR().
short afw::rightOut[SAMPLE_PER_INTR] [static] |
右チャンネル出力バッファ
afw::processDataに引数として渡すための一時バッファ。afwtxBufferのデータは L,R,L,Rになっているので、afwprocessDataが返してきた値の右チャンネルデータを このバッファから読み出してafwtxBufferに格納する。
参照元 rxISR().
| const int afw::LEFT_CH = 0 |
| const int afw::RIGHT_CH = 1 |
| const int afw::INTR_PER_BUFFER = 3 |
| const int afw::CH_PER_SAMPLE = 2 |
| const int afw::SAMPLE_PER_INTR = 8 |
| const int afw::CODEC_RESET_PULS_WIDTH = 0x10000 |
オーディオ・コーデックのリセット時間
EZ-KIT Lite BF537では、オーディオ・コーデックのリセット信号がADSP-BF537のPF12に 接続されている。コーデックの使用に先立って、この信号をアサートしなければならない。
このマクロは、リセット信号をアサートする時間を与える。時間はループの繰り返し 回数なので、あまり精度は高くない。注意深い値が必要である。
参照元 resetCODEC().
| const int afw::SPORT0_SLEN_24 = 0x0017 |
SPORT0のワード長
SPORT0設定時に使うワード長である。EZ-KIT BF537に搭載されているコーデックは I2S回線のデータを24bit使うので、ここでは24を用意している。
参照元 initSPORT().
1.4.7