ネームスペース 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 ()
 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::init ( void   ) 

afwの初期化

オーディオ・フレームワークの初期化。初期化関数はこれひとつよべば、残りの関数を まとめて呼んでくれる。ただし、afwstartAudio は呼ばないので、プログラマが明示的に 呼ばなければならない。

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

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

参照元 main().

00173     {
00174         initGPIO();
00175         resetCODEC();
00176         initSPORT();
00177         initDMA();
00178         initInterrupt();
00179         
00180         initProcessData();
00181     }

void afw::initDMA ( void   ) 

SPORT DMAの初期化

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

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

参照先 CH_PER_SAMPLEINTR_PER_BUFFERrxBufferSAMPLE_PER_INTRtxBuffer.

参照元 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::initGPIO ( void   ) 

GPIOの初期化

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

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

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

参照元 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::initInterrupt ( void   ) 

割り込みのイネーブル

SPORT0 受信割込みを有効化する。SPORT0 受信割り込みはIVG9で処理したいので、その割り当ても設定する。 afw::init()が自動的に呼び出すので、プログラマがこの関数を明示的に呼ぶ必要はない。

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

参照先 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::initProcessData ( void   ) 

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

コールバック関数を呼ぶ前に初期化の必要がある場合は、この関数内部で行う。

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

参照元 init().

00018     {
00019     }

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.cpp104 行で定義されています。

参照先 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::processData ( const shortfract  leftIn[],
const shortfract  rightIn[],
shortfract  leftOut[],
shortfract  rightOut[],
int  count 
)

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

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

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

for文の内部では、1サンプルづつ、左右チャンネルコピーを行う。これで 入力データが出力にコピーされる。

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

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

参照元 rxISR().

00051     {    
00052 
00053         for ( int i=0; i<count; i++ ){      // 引数配列のすべてのデータをコピーする。
00054             leftOut[i] = leftIn[i];
00055             rightOut[i] = rightIn[i];
00056         }
00057 
00058     }   // processData

void afw::resetCODEC ( void   ) 

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

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

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

参照先 CODEC_RESET_PULS_WIDTH.

参照元 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::rxISR ( int  signal  ) 

SPORT0受信DMA割り込みハンドラ

引数:
signal ハンドラが呼ばれた割り込み順位が与えられる。値は SIGIVG7 〜 SIGIVG15。
rxISRはSPORT0の受信DMAから割り込みがかかるたびに呼び出され、割り込みのクリアと トリプル・バッファの管理を行う。トリプルバッファの管理は、DMA3_CURR_Y_COUNTの値を もとに行う。

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

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

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

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

参照先 LEFT_CHleftInleftOutprocessData()RIGHT_CHrightInrightOutrxBufferSAMPLE_PER_INTRtxBuffer.

参照元 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::startAudio ( void   ) 

SPORTとDMAのイネーブル

設定が終わったSPORTとDMAの両方をイネーブルする

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

参照元 main().

00188     {
00189                 // DMA開始
00190         *pDMA4_CONFIG   |= DMAEN;   // 送信
00191         *pDMA3_CONFIG   |= DMAEN;   // 受信
00192     
00193                 // SPORT開始
00194         *pSPORT0_TCR1   |= TSPEN;
00195         *pSPORT0_RCR1   |= RSPEN;
00196     }


変数

const int afw::CH_PER_SAMPLE = 2

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

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

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

参照元 initDMA().

const int afw::CODEC_RESET_PULS_WIDTH = 0x10000

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

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

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

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

参照元 resetCODEC().

const int afw::INTR_PER_BUFFER = 3

バッファ数宣言定数

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

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

参照元 initDMA().

const int afw::LEFT_CH = 0

左チャンネル指定定数

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

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

参照元 rxISR().

short afw::leftIn[SAMPLE_PER_INTR] [static]

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

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

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

参照元 rxISR().

short afw::leftOut[SAMPLE_PER_INTR] [static]

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

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

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

参照元 rxISR().

const int afw::RIGHT_CH = 1

右チャンネル指定定数

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

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

参照元 rxISR().

short afw::rightIn[SAMPLE_PER_INTR] [static]

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

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

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

参照元 rxISR().

short afw::rightOut[SAMPLE_PER_INTR] [static]

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

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

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

参照元 rxISR().

volatile int afw::rxBuffer

SPORT0 DMA 受信バッファ

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

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

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

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

参照元 initDMA()rxISR().

const int afw::SAMPLE_PER_INTR = 8

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

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

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

参照元 initDMA()rxISR().

const int afw::SPORT0_SLEN_24 = 0x0017

SPORT0のワード長

SPORT0設定時に使うワード長である。EZ-KIT BF537に搭載されているコーデックは I2S回線のデータを24bit使うので、ここでは24を用意している。

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

参照元 initSPORT().

volatile int afw::txBuffer

SPORT0 DMA 送信バッファ

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

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

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

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

参照元 initDMA()rxISR().


TalkThroughに対してMon Oct 30 17:10:05 2006に生成されました。  doxygen 1.5.0