ネームスペース afw


説明

オーディオ・フレームワーク

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 (void)
 afwの初期化
void start (void)
 SPORTとDMAのイネーブル
bool ISR (void)
 SPORT0受信DMA割り込みサービス・ルーチン
void initProcessData (int count)
 コールバック関数の処理化
void processData (const shortfract leftIn[], const shortfract rightIn[], shortfract leftOut[], shortfract rightOut[], int count)
 オーディオ・コールバック関数

変数

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_32 = 31
 SPORT0のワード長
volatile int txBuffer [INTR_PER_BUFFER][SAMPLE_PER_INTR][CH_PER_SAMPLE]
 SPORT0 DMA 送信バッファ
volatile int rxBuffer [INTR_PER_BUFFER][SAMPLE_PER_INTR][CH_PER_SAMPLE]
 SPORT0 DMA 受信バッファ
short lchIn [SAMPLE_PER_INTR]
 左チャンネル入力バッファ
short lchOut [SAMPLE_PER_INTR]
 左チャンネル出力バッファ
short rchIn [SAMPLE_PER_INTR]
 右チャンネル入力バッファ
short rchOut [SAMPLE_PER_INTR]
 右チャンネル出力バッファ


関数

void afw::init ( void   ) 

afwの初期化

オーディオ・フレームワークの初期化。初期化関数はこれひとつよべば、残りの関数を まとめて呼んでくれる。ただし、 afw::start は呼ばないので、プログラマが明示的に 呼ばなければならない。また、afwISR()を割込みハンドラとして登録するのも プログラマの責任で行う

afw.cpp220 行で定義されています。

参照先 initDMA()initGPIO()initInterrupt()initProcessData()initSPORT()resetCODEC()SAMPLE_PER_INTR.

参照元 main().

00221     {
00222         initGPIO();
00223         resetCODEC();
00224         initSPORT();
00225         initDMA();
00226         initInterrupt();
00227         
00228         initProcessData(SAMPLE_PER_INTR);
00229     }

void afw::initDMA ( void   ) 

SPORT DMAの初期化

SPORT0に接続されているDMAを設定する。DMA3が受信、DMA4が送信である。 オーディオ信号は16ビット以上の長さがあるのでワードサイズは32bit, 連続送受信のためにオートバッファ、モードを使う。また、トリプル・バッファを 実装するために、DMA転送は2次元で行い、3ライン分のバッファを確保して各ラインの 転送を終えるたびに割り込みを発生させる。 afw::init()が自動的に呼び出すので、プログラマがこの関数を明示的に呼ぶ必要はない。

afw.cpp185 行で定義されています。

参照先 CH_PER_SAMPLEINTR_PER_BUFFERrxBufferSAMPLE_PER_INTRtxBuffer.

参照元 init().

00186     {
00187     
00188                 // DMA3の設定
00189         *pDMA3_CONFIG = WNR | WDSIZE_32 | DI_EN | DI_SEL | FLOW_AUTO | DMA2D ; // 32bit, 2DDMA, 各ライン割り込み、オートバッファ
00190         *pDMA3_START_ADDR = (void *) rxBuffer;                  // 受信DMAバッファへのポインタ
00191         *pDMA3_X_COUNT = CH_PER_SAMPLE * SAMPLE_PER_INTR;       // 2次元DMAの桁数
00192         *pDMA3_X_MODIFY = sizeof(int);                          // 転送ごとのインクリメント量
00193         *pDMA3_Y_COUNT = INTR_PER_BUFFER;                       // 2次元DMAの行数
00194         *pDMA3_Y_MODIFY = sizeof(int);                          // 1行転送後のインクリメント量
00195     
00196                 // DMA4の設定
00197         *pDMA4_CONFIG = WDSIZE_32 | FLOW_AUTO | DMA2D;          // 32bit, 2DDMA, オートバッファ
00198         *pDMA4_START_ADDR = (void *)txBuffer;                   // 受信DMAバッファへのポインタ
00199         *pDMA4_X_COUNT = CH_PER_SAMPLE * SAMPLE_PER_INTR;       // 2次元DMAの桁数
00200         *pDMA4_X_MODIFY = sizeof(int);                          // 転送ごとのインクリメント量
00201         *pDMA4_Y_COUNT = INTR_PER_BUFFER;                       // 2次元DMAの行数
00202         *pDMA4_Y_MODIFY = sizeof(int);                          // 1行転送後のインクリメント量
00203 
00204     }

void afw::initGPIO ( void   ) 

GPIOの初期化

PORT Fに割り当てられているGPIO(フラグピン)の初期化を行う。 PORT Fのピン割り当ては以下のとおり(カッコ内はマスク)

afw::init()が自動的に呼び出すので、プログラマがこの関数を明示的に呼ぶ必要はない。

afw.cpp114 行で定義されています。

参照元 init().

00115     {
00116         *pPORTF_FER   &= ~PF12;         // ポート Fのプログラマブル・フラグを利用できるようにする。
00117         *pPORTFIO_DIR |=  PF12;         // ポートFの方向設定。LEDとコーデックのRESET制御を出力に
00118     }

void afw::initInterrupt ( void   ) 

割り込みのイネーブル

SPORT0 受信割込みを有効化する。SPORT0 受信割り込みはデフォルトでは DMA3に割り当てられているので、DMA3割込みを有効にする。

afw.cpp211 行で定義されています。

参照元 init().

00212     {
00213 
00214                 // SPORT0 RX 割込みを有効に。デフォルトはDMA3
00215         *pSIC_IMASK |= IRQ_DMA3;
00216     }

void afw::initProcessData ( int  count  ) 

コールバック関数の処理化

引数:
count afw::processDataが呼ばれる際、各バッファに格納されているオーディオデータの数
afw::processData()関数を呼ぶ前に初期化の必要がある場合は、この関数内部で行う。

processdata.cpp15 行で定義されています。

参照元 init().

00016     {
00017         // ここでprocessData用の初期化を必要に応じて行う
00018     }

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のクロックおよびフレーム同期 信号を自分で生成する設定に変更しなければならない。

afw.cpp163 行で定義されています。

参照先 SPORT0_SLEN_32.

参照元 init().

00164     {
00165                 // Sport0 受信設定
00166         *pSPORT0_RCR1 = RFSR | RCKFE;
00167         *pSPORT0_RCR2 = SPORT0_SLEN_32 | RSFSE;
00168     
00169                 // Sport0 送信設定
00170         *pSPORT0_TCR1 = TFSR | TCKFE;
00171         *pSPORT0_TCR2 = SPORT0_SLEN_32 | TSFSE;
00172 
00173     
00174     }

bool afw::ISR ( void   ) 

SPORT0受信DMA割り込みサービス・ルーチン

戻り値:
デバイスの割り込み処理を行ったときには真を返す。行わなければ偽。
afw::ISRはSPORT0の受信DMAから割り込みがかかるたびに呼び出され、割り込みのクリアと トリプル・バッファの管理を行う。トリプルバッファの管理は、DMA3_CURR_Y_COUNTレジスタの値を もとに行う。 なお、割り込みがSPORT0 受信DMA割込みではない場合、afwISRは何もせずに戻る。

DMA3_CURR_Y_COUNTレジスタは、転送の最初に当たってDMA3_CURR_Y_COUNTレジスタの値に設定され、 ラインの転送が終わるごとにデクリメントされる。しかし、最後のラインの 転送後は、デクリメントされずに1のままに留まる。その結果、各ラインの転送終了 では、割込み発生ごとに以下のようにDMA3_CURR_Y_COUNTレジスタの値が変化する

このことから、ソフトウェアとの同期に使ってよいのはDMAx_CURR_Y_COUNTレジスタが2の場合 のみであり、あとは決めうちでバッファの添え字をインクリメントしなければならない事がわかる。 プログラム中では、この添え字としてbufferIdxをあてている。

トリプルバッファの管理が終わったら、受信DMAバッファからデータを取り出し、並べ なおしてから afw::processData を呼ぶ。

afw.cpp271 行で定義されています。

参照先 lchInlchOutLEFT_CHprocessData()rchInrchOutRIGHT_CHrxBufferSAMPLE_PER_INTRtxBuffer.

参照元 cec::ivg9().

00272     {
00273         if ( *pSIC_ISR & IRQ_DMA3 ){        // SPORT0_RX割込みか?
00274             static unsigned int bufferIdx = 0;       // トリプル・バッファ操作用インデックス
00275     
00276             *pDMA3_IRQ_STATUS = 0x0001;         // 割込みクリア
00277     
00278                     // トリプルバッファのどのバッファを使うか決める
00279             if ( *pDMA3_CURR_Y_COUNT == 2 )     // 2次元DMAの最初の行の転送が終了した場合
00280                 bufferIdx = 0;
00281             else if ( bufferIdx < 2 )           // それ以外の場合
00282                 bufferIdx ++;
00283             else
00284                 bufferIdx = 0;                  // 値が異常な場合の処理
00285 
00286                     // DMAが格納した受信データを入力バッファにコピーする
00287                     // 受信データバッファは24bit データを左詰めで32bit 変数に格納しているので
00288                     // 16bit右シフトして入力バッファにコピーする
00289             for( int i =0; i< SAMPLE_PER_INTR; i++ ){
00290                 lchIn[i] = rxBuffer[bufferIdx][i][LEFT_CH]  >>16;
00291                 rchIn[i] = rxBuffer[bufferIdx][i][RIGHT_CH] >>16;
00292             }
00293         
00294                     // ユーザー・コールバック関数の呼び出し
00295             processData( 
00296                             (shortfract *)lchIn,       // short型とshortfract型は
00297                             (shortfract *)rchIn,      // 同じ大きさなので、
00298                             (shortfract *)lchOut,      // キャストによって強制変換していい
00299                             (shortfract *)rchOut, 
00300                             SAMPLE_PER_INTR 
00301                         );
00302 
00303                     // 出力バッファのデータを送信データバッファにコピーする
00304                     // 送信データバッファは24bit データを左詰めで32bit 変数に格納しているので
00305                     // 出力バッファから16bit左シフトして送信バッファにコピーする    
00306             for( int i =0; i< SAMPLE_PER_INTR; i++ ){
00307                 txBuffer[bufferIdx][i][LEFT_CH] = lchOut[i] <<16;
00308                 txBuffer[bufferIdx][i][RIGHT_CH]= rchOut[i] <<16;
00309             }
00310             return (true);         // 割込み処理を行った
00311         }
00312         else
00313             return(false);          // 割込み処理を行わなかった
00314 
00315     }

void afw::processData ( const shortfract  leftIn[],
const shortfract  rightIn[],
shortfract  leftOut[],
shortfract  rightOut[],
int  count 
)

オーディオ・コールバック関数

引数:
leftIn 左チャンネルの入力データバッファ
rightIn 右チャンネルの入力データバッファ
leftOut 左チャンネルの出力データバッファ
rightOut 右チャンネルの出力データバッファ
count 各バッファに格納されているオーディオデータの数
この関数はDMAが受信バッファをいっぱいにするたびに割り込み経由で呼ばれる。 引数として渡されるのは受信データを含む入力バッファのほか、送信データを 格納するために使う出力バッファとデータ個数である。 ユーザーは関数内部で入力バッファのデータを加工して、出力バッファに送信すべき データをおく。呼び出しに先立って初期化が必要な場合は、 afw::initProcessData() 関数で行う。

配列はshortfract型である。この16bit固定小数点型はshortと同じ大きさを 持つが、四則は固定小数点領域で定義されている。

for文は常に必要なので、改造する場合はfor文の内側だけを書き換える。引数 である配列の各要素は、オーディオのサンプルデータが順番に格納されたもの である。したがって、これらを順番に処理することで、オーディオ処理を実装 できる。

割り込みソースのクリアなどは、この関数の呼び出し側で行うので、関数内で 処理する必要はない。

processdata.cpp47 行で定義されています。

参照元 ISR().

00054     {    
00055 
00056         for ( int i=0; i<count; i++ ){      // 引数配列のすべてのデータを処理する。
00057             // ここで信号処理を行う。
00058             leftOut[i] = leftIn[i];
00059             rightOut[i]= rightIn[i];
00060         }
00061 
00062     }   // processData

void afw::resetCODEC ( void   ) 

オーディオ・コーデックのリセット

PORT Fに割り当てられているコーデック・リセット信号(PF12)をトグルする。 afw::init()が自動的に呼び出すので、プログラマがこの関数を明示的に呼ぶ必要はない。

afw.cpp126 行で定義されています。

参照先 CODEC_RESET_PULS_WIDTH.

参照元 init().

00127     {
00128         *pPORTFIO_CLEAR = PF12;             // リセット・ピンをアサートする。
00129     
00130         for( int i = 0; i< CODEC_RESET_PULS_WIDTH;i++)          // アサート状態を一定時間保持
00131             asm volatile( "nop;" );
00132     
00133         *pPORTFIO_SET = PF12;               // リセット・ピンをデアサートする。
00134 
00135 
00136     }

void afw::start ( void   ) 

SPORTとDMAのイネーブル

設定が終わったSPORTとDMAの両方をイネーブルし、オーディオ処理を開始する。 必ず afw::init()の後に呼ぶ。

afw.cpp232 行で定義されています。

参照元 main().

00233     {
00234                 // DMA開始
00235         *pDMA4_CONFIG   |= DMAEN;   // 送信
00236         *pDMA3_CONFIG   |= DMAEN;   // 受信
00237     
00238                 // SPORT開始
00239         *pSPORT0_TCR1   |= TSPEN;
00240         *pSPORT0_RCR1   |= RSPEN;
00241     }


変数

const int afw::CH_PER_SAMPLE = 2

サンプルあたりチャンネル数の宣言

サンプルあたり何チャンネルのデータを伝送するか宣言する。I2Sはステレオなので、この値は2である。 この値はユーザーが変更してはならない。

afw.cpp46 行で定義されています。

参照元 initDMA().

const int afw::CODEC_RESET_PULS_WIDTH = 0x10000

オーディオ・コーデックのリセット時間

EZ-KIT Lite BF537では、オーディオ・コーデックのリセット信号がADSP-BF537のPF12に 接続されている。コーデックの使用に先立って、この信号をアサートしなければならない。

このマクロは、リセット信号をアサートする時間を与える。時間はループの繰り返し 回数なので、あまり精度は高くない。注意深い値が必要である。

afw.cpp64 行で定義されています。

参照元 resetCODEC().

const int afw::INTR_PER_BUFFER = 3

バッファ数宣言定数

DMA用のバッファ領域を afw::txBufferおよび afw::rxBufferとして 確保する際に、割り込みいくつ分のバッファを用意するかを宣言する。 具体的にいえば、トリプルバッファなので3を宣言する。過去3回の割り込み分のデータをバッファに 格納できるということである。

afw.cpp38 行で定義されています。

参照元 initDMA().

short afw::lchIn[SAMPLE_PER_INTR]

左チャンネル入力バッファ

afw::processDataに引数として渡すための一時バッファ。 afw::rxBufferのデータは L,R,L,Rになっているので、左チャンネルだけ取り出してこのバッファに格納する。

afw.cpp249 行で定義されています。

参照元 ISR().

short afw::lchOut[SAMPLE_PER_INTR]

左チャンネル出力バッファ

afw::processDataに引数として渡すための一時バッファ。 afw::txBufferのデータは L,R,L,Rになっているので、 afw::processDataが返してきた値の左チャンネルデータを このバッファから読み出して afw::txBufferに格納する。

afw.cpp256 行で定義されています。

参照元 ISR().

const int afw::LEFT_CH = 0

左チャンネル指定定数

afw::rxBufferおよび、 afw::txBufferにアクセスする際、最下位の添え字を指定 するときに使う。

afw.cpp21 行で定義されています。

参照元 ISR().

short afw::rchIn[SAMPLE_PER_INTR]

右チャンネル入力バッファ

afw::processDataに引数として渡すための一時バッファ。 afw::rxBufferのデータは L,R,L,Rになっているので、右チャンネルだけ取り出してこのバッファに格納する。

afw.cpp262 行で定義されています。

参照元 ISR().

short afw::rchOut[SAMPLE_PER_INTR]

右チャンネル出力バッファ

afw::processDataに引数として渡すための一時バッファ。 afw::txBufferのデータは L,R,L,Rになっているので、 afw::processDataが返してきた値の右チャンネルデータを このバッファから読み出して afw::txBufferに格納する。

afw.cpp269 行で定義されています。

参照元 ISR().

const int afw::RIGHT_CH = 1

右チャンネル指定定数

afw::rxBufferおよび、 afw::txBufferにアクセスする際、最下位の添え字を指定 するときに使う。

afw.cpp28 行で定義されています。

参照元 ISR().

volatile int afw::rxBuffer[INTR_PER_BUFFER][SAMPLE_PER_INTR][CH_PER_SAMPLE]

SPORT0 DMA 受信バッファ

受信DMAがアクセスし、SPORT RXチャンネルからデータを受け取るのバッファ

最下位の次元はL, Rチャンネル用に2つの要素を格納する。下から2番目の次元は、 割込み1回ごとに送信されるサンプル数を指定する。1回の割り込みの間にDMA転送 されるデータの量は、 afw::SAMPLE_PER_INTR * afw::CH_PER_SAMPLE で決まる。

afw::INTR_PER_BUFFER だけ用意される次元は、このバッファが割込み何回分のデータを 格納するかを表す。

afw.cpp102 行で定義されています。

参照元 initDMA()ISR().

const int afw::SAMPLE_PER_INTR = 8

割り込みあたりのサンプル数

何サンプルのデータを受信したら割り込みをかけるかを指定する。この値を大きくするほど 効率がよくなるが、遅延も増大し、また、必要なメモリ量も増える。したがって、これらの バランスを考えながらユーザーが値を決めることになる。

afw.cpp54 行で定義されています。

参照元 init()initDMA()ISR().

const int afw::SPORT0_SLEN_32 = 31

SPORT0のワード長

SPORT0設定時に使うワード長である。EZ-KIT BF537に搭載されているコーデックは 32bit長のI2S回線を使うので、ワード長が32になるよう指定する。 32bit長にする場合は、31と設定することに注意。

afw.cpp72 行で定義されています。

参照元 initSPORT().

volatile int afw::txBuffer[INTR_PER_BUFFER][SAMPLE_PER_INTR][CH_PER_SAMPLE]

SPORT0 DMA 送信バッファ

送信DMAがアクセスし、SPORT TXチャンネルにデータを送り込むためのバッファ

最下位の次元はL, Rチャンネル用に2つの要素を格納する。下から2番目の次元は、 割込み1回ごとに送信されるサンプル数を指定する。1回の割り込みの間にDMA転送 されるデータの量は、 afw::SAMPLE_PER_INTR * afw::CH_PER_SAMPLE で決まる。

最上位の次元は、このバッファが割込み何回分のデータを 格納するかを表す。

afw.cpp90 行で定義されています。

参照元 initDMA()ISR().


AudioFrameWorkに対してMon Apr 9 15:44:05 2007に生成されました。  doxygen 1.5.1-p1