2007年10月26日金曜日

CCSのプログラムサンプル。




#include
#include
#include "c6711dsk.h"
#include "codec_intr.h"

#define BUFFER_SIZE 2048
const int bufferlength = BUFFER_SIZE;
static int buffercount = 0;
static int buffer[BUFFER_SIZE];

void addto_buffer(int value)
{
//配列bufferのbuffercount番目にA/Dの内容を保存
buffer[buffercount] = value;

//buffercountをインクリメント
buffercount++;

//バッファがいっぱいになったら、buffercountを0に戻す
if (buffercount == bufferlength) buffercount = 0;
}

int get_delayedVoice(void)
{
return(buffer[buffercount]);
//buffercount番目のbufferの内容を返す
}


int main() {

int temp;

CSR=0x100; // disable all interrupts
//コントロール・ステータス・レジスタ 全ての割り込みを禁止

*(unsigned int *)EMIF_GCR =0x3300; // EMIF global control
*(unsigned int *)EMIF_CE0 =0x30; // EMIF CE0control
*(unsigned int *)EMIF_CE1 =0xffffff03; // EMIF CE1 control, 8bit async
*(unsigned int *)EMIF_SDCTRL=0x07117000; // EMIF SDRAM control
*(unsigned int *)EMIF_SDRP =0x61a; // EMIF SDRM refresh period
*(unsigned int *)EMIF_SDEXT =0x54519; // EMIF SDRAM extension

mcbsp0_init();

//EMIF External Memory Interface 外部メモリ・インターフェース
temp=*(unsigned int *)IML&0xfc1fffff; // read interrupt multipexer (IML) 割り込みマルチプレクサ下位レジスタ
temp=temp|0x01a00000; // INTSEL8 value
*(unsigned int*)IML=temp; // set interrupt multiplexer (IML) ICR=0xffff; // clear all pending interrupt
IER=IER|0x102; // enable NMI & INT8 割り込みイネーブル・レジスタ

CSR=CSR|1; // enable interrupt (global) コントロール・ステータス・レジスタ

// forever loop

while(1) {
;
}

}

//================================================================

void mcbsp0_init(void) {
// mcbsp0 initialize
// マルチチャンネル・バッファード・シリアル・ポート0

*(unsigned int *)McBSP0_SPCR=0; // reset serial port
*(unsigned int *)McBSP0_PCR =0; // set pin control reg.;
*(unsigned int *)McBSP0_RCR =0x10040; // set rx control reg. one 16 bit data/frame
*(unsigned int *)McBSP0_XCR =0x10040; // set tx control reg. one 16 bit data/frame
*(unsigned int *)McBSP0_DXR =0; // clear DXR
*(unsigned int *)McBSP0_SPCR=0x12001; // setup SP control reg.;
// codec initialize
mcbsp0_write(1);
mcbsp0_write(0x0380);
mcbsp0_write(1);
mcbsp0_write(0x0306);
mcbsp0_write(1);
mcbsp0_write(0x0400); // mic preamp gain=0dB (line input level)
mcbsp0_write(1);
mcbsp0_write(0x0586); // DAC gain=12dB
mcbsp0_read(); mcbsp0_read(); mcbsp0_read(); mcbsp0_read(); // waiting....
}

//================================================================

void mcbsp0_write(int out_data) {

while ((*(unsigned int *)McBSP0_SPCR&0x20000)==0) {
;
};
*(unsigned int *)McBSP0_DXR = out_data;
}

//================================================================

int mcbsp0_read(void) {
while ((*(unsigned int *)McBSP0_SPCR&0x2)==0) {
;
};
return *(unsigned int *)McBSP0_DRR;
}

//================================================================

//interrupt 割り込み処理の記述
interrupt void mcbsp0_rx_intr(void) {
int temp;
int out;

temp=*(unsigned int *)McBSP0_DRR; // read A/D
//c6711dsk.hに定義されている #define McBSP0_DRR 0x18c0000
0x18c0000の内容(A/D変換された値)をtempに代入。

addto_buffer(temp); /* Add voice sample to buffer for graphing and
delay/echo effects */
//addto_bufferにA/D変換された値を渡す。


out = temp + get_delayedVoice();
//配列bufferのbuffercount番目の値を受け取り、A/Dの値を足してoutに代入する

*(unsigned int *)McBSP0_DXR=out & 0xfffe; // write D/A
//c6711dsk.hに定義されている #define McBSP0_DXR 0x18c0004
outと0xfffeとを、各ビット毎にANDを取り、そこに代入する




ざざっと解析してみました。
main関数は各パラメータを設定し、無限ループを行う。
mcbsp0_rx_intrが割り込みで実行される。
int型の配列bufferがBUFFER_SIZE分確保されており、そのbufferの0番目にaddto_buffer()によりA/D変換された値を格納し、buffercountをインクリメントする。
その直後、get_delayedVoice()が呼び出され、前の処理でインクリメントされたbuffercount番目のbufferの値(BUFFER_SIZE回前にA/D変換された値)を読む。
そのBUFFER_SIZE回前にA/D変換された値に現在のA/D変換された値を足し、0xfffe(1111 1111 1111 1110)と各ビット毎のANDを取り、D/Aに渡す。
上記の処理により、データのLSB(Least Significant Bit:最下位ビット)を強制的に0にしている。
これはデータのLSBが1であると、次の送信がコントロール・レジスタへの書き込みになってしまうためとされている。

0 件のコメント: