明日からリフォームのひらりんです.
リフォームで多忙になる前にBlackFin BF706で動作確認を終わらせておきたかったことはほぼ出来ました.
今日はUART Rxを動かして、PCからUSB COMでDSPを制御しました.
今まで、UARTの設定がよくわからず例外が発生していたのですが、以下の設定で動きました.UART0のTxRx両方使いです.全二重と呼びますか?
例外の原因は、赤字のメモリサイズでした.TxまたはRxの場合のメモリサイズは小さくていいが、両方向は大きなメモリサイズが必要です.BIDIRとは両方向のことです.
adi_uart_Open(0, ADI_UART_DIR_BIDIRECTION, driverMemory_uart, ADI_UART_BIDIR_DMA_MEMORY_SIZE, &hDevice);
adi_uart_SetMode(hDevice, ADI_UART_MODE_UART);
adi_uart_SetBaudRate(hDevice, 115200);
adi_uart_SetParity(hDevice, ADI_UART_NO_PARITY);
adi_uart_SetNumStopBits(hDevice, ADI_UART_ONE_STOPBIT);
adi_uart_SetWordLen(hDevice, ADI_UART_WORDLEN_8BITS);
adi_uart_EnableDMAMode(hDevice, true);
adi_uart_RegisterCallback(hDevice, UARTCallback, (void*)0);
adi_uart_SubmitTxBuffer(hDevice, txbuf_uart[0], 1);
adi_uart_EnableTx(hDevice, true);
adi_uart_SubmitRxBuffer(hDevice, rxbuf_uart, 1);
adi_uart_EnableRx(hDevice, true);
Tx側は以前の投稿を読んでもらうとして、今回はRx側です.
Rxはどうも使い心地が悪いかなぁ.現状のRxのやりかたをポエム風に表現するとこうです.
・DMAである
・1BYTE Rxの要求を出す
・1BYTE Rxが完遂されたら割り込みcallbackが生じる
・callbackの内部で、その1文字を自前のバッファに積む
・CRを受信したらコマンド解析などを行う
この「1文字毎にcallback処理する」のってなんかのろくさくて好かないんだけど.
もちろん、50文字Rxという要求を出すのも可能なのですが、それだとコマンド列の末尾で50文字に満たず無反応になってしまうので受諾できません.なので1文字毎にしてます.
または、pollingで「Rxしたぁ?」「何文字?」みたいな関数も用意されてるみたいなのですが、なんのためのDMAなのかなと思ってしまいますが、1文字毎にDMAで受信してるパープリンの言う事じゃねぇや、と思わんでもなく.なんか居心地悪いです.
callback関数の1文字処理のところ.
①ADI_UART_EVENT_RX_BUFFER_PROCESSEDというevent flagが受信完了の意味.
②すぐに受信文字をsaveしといてから、
③次の1文字をRxしろと要求する
④UARTへecho back
⑤CR受信で行末検出
⑥1行受信のflagを立てる
void UARTCallback(){
switch (event) {
case ADI_UART_EVENT_RX_BUFFER_PROCESSED: ①
char x = rxbuf_uart[0]; ②
adi_uart_SubmitRxBuffer(hDevice_uart, rxbuf_uart, 1); ③
h_uart_tx_char(x); ④
switch (x) {
case 0x0d: ⑤
comN = N;
if(N==0 && i==0) break; // no character
N=0; i=0;
bComplete_uart_CR = true; // end of a line ⑥
break;
⑥のフラグをmain()のloopでチェックしていまして、そこでコマンド解析し、DACに発生させる周波数、電圧、波形などを変更します.結果として、BF706をPCから制御していることになります.
制御コマンドはこんな感じです.
f r 600 Rchを600Hzにする
a l 67 Lchの電圧をフルスケールの67%にする
32bitのsin(x)を67%に小さくする演算って固定小数点だとどうやるんだろう???
浮動小数点で表現するとこんなに簡単なわけですが、、、
out = sin(x) * 67 / 100;
固定小数点だと現状はこんなにしています.かったるくない?
long long t64 = mult64_32x32( 0x7fffffff, 67 );
int t32 = t64 / 100;
o = sin_fr32( x );
o = mult_fr1x32x32( o, t32 );
out = polarity==true ? o : (-1)*o; ←前回書いた極性制御
赤字の乗算関数はライブラリが提供するものです.
ーーーー
CrossCoreのproject詰め合わせはこちらです.
BF706のサンプルとしてどんな事を見れるかというと、、、
・BF706評価ボードがtarget
・Timer0でLEDチカチカ(GPIOも)
・Timer1でUARTの周期的送信(10Hzだったかな)
・UART0 Tx 内部状態をPCへ送信
・UART0 Rx PCからBF706を制御する
・SPORTのI2SでDACへ音声データ送信
・sin_fr32(x)で固定小数点でsin波発生→DAC出力
・speed tuneはなにもやってません、だらだらcodeです
免責:被害に遭っても知りません.
明日からDSPのupdateは遅くなりますのでまたね~
かしこ
0 件のコメント:
コメントを投稿