ラベル プログラム の投稿を表示しています。 すべての投稿を表示
ラベル プログラム の投稿を表示しています。 すべての投稿を表示

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であると、次の送信がコントロール・レジスタへの書き込みになってしまうためとされている。

2007年9月8日土曜日

C言語での日本語入力。

今回のインターンシップでのソフトウェア開発はC言語を用いて行いました。
C言語はそもそも2バイト文字が使えないのですが、そこをユーザーのスキルでカバーできてしまうのがC言語の良さ(悪さ?)でしょう。
(俺のようなスキル不足の人間には辛いが・・
(あと適当に書いてるだけなんで、ミスだらけだ。
MS-DOSプロンプト上での実行なので、(幸いにも)S-JISしか考慮してないです。
普段はLinux環境でプログラミングしているので、S-JISのダメ文字によるコンパイルエラーにはビビリました。

引用:wikipedia-Shift JIS
2バイト目に0x5Cを持つ文字のことを、俗にダメ文字と呼び、この中には「ソ」「構」「能」「表」など一般に使用頻度の高い文字も多い
http://ja.wikipedia.org/wiki/Shift_JIS

(ダメ文字の場合はその漢字の直後に\を書いてあげればOK。gccでのコンパイルも同様


C言語が扱う文字は基本的に1バイトです。
コンパイラも処理としては文字コードを認識せずに、ではそれを2バイト文字だと解釈せずに、1バイトの文字列としてメモリ空間に格納するように処理しているようですね。
S-JISならば文字列の取得は標準入力から1文字ずつ読み取り、リターンコードを検出し、その部分をヌル文字に変換してやれば問題ないです。
スペースやタブをどう扱うかはその文字列の使い方次第でしょう。
1バイト文字と2バイト文字の区別は基本的に1バイト目の文字コードの大きさをifで判断します。
基本的にASCII文字ならば1バイト目の最上位ビットが0であり、2バイト文字ならば1となります。
それを利用してい1バイト目の文字コードが0x7Fより小さく、0x21より大きいならば1バイト文字だと判断させるのが簡単です。
入力された文字列にどのようなエスケープシーケンスなどが含まれるかなどは事前に調べる必要があります。
C言語の場合は1バイト毎に処理できるので、かなり細かく操作できます。
今回はS-JISを扱う前提なのでよかったのですが、文字コードの予測ができない場合の処理は複雑すぎますね。