#include <cdefBF533.h>
-#define PARAMDATA_NUM 16
static void init_sport0_rx(void);
static void init_sport0_tx(void);
-static void pack_af_sample( short left, short right, int * pri_ch, int * sec_ch1);
+static void pack_af_sample( short left, short right, unsigned int * pri_ch, unsigned int * sec_ch);
static void unpack_wide_fm ( unsigned int pri_ch, unsigned int sec_ch, int* idata, int* qdata );
static void unpack_non_wide_fm( unsigned int pri_ch, unsigned int sec_ch, int* idata, int* qdata, int* valid_iq );
+static void set_command_data( unsigned int command, unsigned int data );
unsigned short x_modify;
};
+ // フレームワークの作業用内部変数
static struct {
- struct dma_descripter rx_dma_dsc[2];
- struct dma_descripter tx_dma_dsc[2];
+ struct dma_descripter rx_dma_dsc[2]; // FPGAからのデータDMAデスクリプタ
+ struct dma_descripter tx_dma_dsc[2]; // FPGAへのデータDMAデスクリプタ
- unsigned int rxif_buffer[2][RXIF_BUFSIZE];
- unsigned int af_buffer[2][AF_BUFSIZE];
+ unsigned int rxif_buffer[2][RXIF_BUFSIZE]; // FPGAからのデータDMAバッファ
+ unsigned int af_buffer[2][AF_BUFSIZE]; // FPGAへのデータDMAバッファ
int index; // パッカーが使う。現在のワードインデックスが0か1か
+ short wide_fm_i[WIDE_FM_OVERSAMPE]; // Wide FMを複数サンプルまとめて処理するためのバッファ
+ short wide_fm_q[WIDE_FM_OVERSAMPE]; // Wide FMを複数サンプルまとめて処理するためのバッファ
+ int wide_fm_index; // 次のバッファ格納位置。現在のバッファ長でもある。
} framework;
- struct {
- unsigned short flags;
- unsigned short smeter;
- unsigned short comdata[PARAMDATA_NUM];
-} radio;
+ // ラジオアルゴリズムとのやりとりに使う変数
+ struct RADIO radio;
+ // デバッグ用変数群
+#if defined (DEBUG_QUEUEDEPTH)
+static int debug_queue_level = 0;
+static int debug_queue_max = INT_MIN;
+static int debug_queue_min = INT_MAX;
+#endif
+
/**
* \brief RX_IF受信データの処理タスク
* 書き込む。データキューは \ref af_task との共用である。
*
* また、受信DMA内のRX-IFデータにはコマンドが含まれている。これらの
- * コマンドを内部変数に記録して復調器がりようできるようにしておく。
+ * コマンドを内部変数に記録して復調器が利用できるようにしておく。
*/
void rx_if_task(VP_INT exinf)
{
int i;
+ // オーディオ送信プライマリチャンネルとセカンダリチャンネルデータ
+ unsigned int af_pri_ch, af_sec_ch;
+
vmsk_log(LOG_UPTO(LOG_INFO), LOG_UPTO(LOG_EMERG));
syslog(LOG_NOTICE, "Sample program starts (exinf = %d).", (INT) exinf);
syscall(serial_ctl_por(TASK_PORTID,
(IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV)));
- framework.index = FALSE; // パッカーのインデックスの初期値設定。実のところ、初期値はランダムでも構わない。
+ // データキューのプリフィル。半分まで詰める
+ for ( i=0; i<AF_QUESIZE/2; i+=2)
+ {
+ pack_af_sample(0, 0, &af_pri_ch, &af_sec_ch);
+ syscall(psnd_dtq(DTQ_AF, (VP_INT)af_pri_ch));
+ syscall(psnd_dtq(DTQ_AF, (VP_INT)af_sec_ch));
+#ifdef DEBUG_QUEUEDEPTH
+ debug_queue_level +=2;
+ if ( debug_queue_level > debug_queue_max)
+ debug_queue_max = debug_queue_level;
+#endif // DEBUG_QUEUEDEPTH
+ }
+
+
+ framework.index = FALSE; // パッカーのインデックスの初期値設定。実のところ、初期値はランダムでも構わない。
+
+ framework.wide_fm_index = 0; // 配列内部の有効データ数
// 受信機パラメタの初期化
for ( i=0; i<PARAMDATA_NUM; i++)
// AF送信を開始する。ただし、送信DMA割り込みはまだ発生しない。
*pDMA2_CONFIG |= DMAEN; // TX SPORT DMA Enable
- *pSPORT0_TCR1 |= RSPEN; // TX SPORT Enable
+ *pSPORT0_TCR1 |= TSPEN; // TX SPORT Enable
ssync();
+
+
tslp_tsk(1); // DMAがFIFOを充填するのに十分な時間待つ。
syscall(act_tsk(TASK_AF)); // AFデータ送信タスクをアクティブにする
ssync();
-
-
- int count = 0;
-
-
/*
* メインループ
+ * 受信DMA割り込み待ってから、DMAバッファ内部のデータを解析して然るべき受信処理を行う。
*/
do {
+ // DMA転送が完了した受信バッファ
+ unsigned int* filled_buffer;
+ // next_descriptor
+ struct dma_descripter * next;
+ // ループカウンタ
+ int i;
- long int rx[4];
// SPORT0受信DMAがバッファを埋めるのを待つ。
syscall(wai_sem(SEM_SPORT0_RX));
- count++;
- if ( count > 31500/(RXIF_BUFSIZE/4))
- {
- count = 0;
- // FIFOにデータがたまったはずである。
- // FIFOデータを読みだして下位2bitのみ表示する
- rx[0] = framework.rxif_buffer[1][0]; // 下位2bitのみ抽出
- rx[1] = framework.rxif_buffer[1][1]; // 下位2bitのみ抽出
- rx[2] = framework.rxif_buffer[1][2]; // 下位2bitのみ抽出
- rx[3] = framework.rxif_buffer[1][3]; // 下位2bitのみ抽出
-
- syslog( LOG_NOTICE, "RX word : %08x,%08x,%08x,%08x", rx[0], rx[1], rx[2], rx[3] );
-
- }
+ // SPORT0受信DMAコントローラが次にロードするデスクリプタへのポインタを取得する。
+ // このデスクリプタは、「現在使われていない」DMAデスクリプタであり、逆に言うと
+ // 割り込みが完了したDMAのデスクリプタである
+ next = (struct dma_descriptor *) *pDMA1_NEXT_DESC_PTR;
+ // 取得したデスクリプタから、割り込みを発生したバッファを割り出す。
+ filled_buffer = next->start_address;
+ // RX-IF DMAバッファ内部のデータを処理
+ for ( i= 0; i<RXIF_BUFSIZE; i+=2)
+ {
+ // アンパック済みIQデータ
+ int idata, qdata;
+ // デコード済みオーディオデータ
+ short left, right;
+ // オーディオ送信プライマリチャンネルとセカンダリチャンネルデータ
+ unsigned int af_pri_ch, af_sec_ch;
+
+ // Wide FMモードか否かを確認。
+ // Wide FMモードフラグはプライマリチャンネルでのみ確認可能である。
+ // プライマリ・チャンネルは必ずバッファの偶数番目に位置する。
+ if ( filled_buffer[i] & WIDE_FM_FLAG )
+ { // Wide FMの場合
+ // データはバッファにまとめて WIDE_FM_OVERSAMPE個ごとに処理する
+ // 同時にFPGAから送られてくるデータも紐解いて格納する
+ unpack_wide_fm(filled_buffer[i], filled_buffer[i+1], &idata, &qdata );
+ framework.wide_fm_i[framework.wide_fm_index] = idata;
+ framework.wide_fm_q[framework.wide_fm_index] = qdata;
+ framework.wide_fm_index++;
+
+ // IQデータが揃ったら、デコードする
+ if ( framework.wide_fm_index >= WIDE_FM_OVERSAMPE )
+ {
+
+ // FM受信アルゴリズムを呼び出す
+ radio_demodulate_wide_FM( framework.wide_fm_i, framework.wide_fm_q, &left, &right );
+ // バッファクリア
+ framework.wide_fm_index = 0;
+ // デコード済みオーディオサンプルを、DMAから送信できる形式にパックする
+ pack_af_sample( left, right, &af_pri_ch, &af_sec_ch);
+
+ // パック済みオーディオサンプルをAFキューに送信する
+ // キューに空きがなければ、待たずにエラーをもって帰る
+ syscall(psnd_dtq(DTQ_AF, (VP_INT)af_pri_ch));
+ syscall(psnd_dtq(DTQ_AF, (VP_INT)af_sec_ch));
+#ifdef DEBUG_QUEUEDEPTH
+ debug_queue_level += 2;
+ if ( debug_queue_level > debug_queue_max)
+ debug_queue_max = debug_queue_level;
+#endif // DEBUG_QUEUEDEPTH
+ }
+
+ }
+ else
+ { // 非Wide FMの場合
+ // IQデータが有効か否か
+ int is_valid_iq;
+
+ // 問答無用でWide FMのバッファ済みデータを消す
+ // これで変数の値が変わるのはシステム稼働中多くても1回である。
+ // 必要な場合だけ書き換えるとif文が増えるのでこうしている
+ framework.wide_fm_index = 0;
+ // 非ワイドFMデータをアンパックする
+ // 同時にFPGAから送られてくるデータも紐解いて格納する
+ unpack_non_wide_fm(filled_buffer[i], filled_buffer[i+1], &idata, &qdata, &is_valid_iq );
+ // IQデータが有効の場合だけデコードする
+ if ( is_valid_iq )
+ {
+ // 非ワイドFM受信アルゴリズムを呼び出す
+ radio_demodulate_non_wide_FM( idata, qdata, &left, &right);
+ // デコード済みオーディオサンプルを、DMAから送信できる形式にパックする
+ pack_af_sample( left, right, &af_pri_ch, &af_sec_ch);
+ // パック済みオーディオサンプルをAFキューに送信する
+ // キューに空きがなければ、待たずにエラーをもって帰る
+ syscall(psnd_dtq(DTQ_AF, (VP_INT)af_pri_ch));
+ syscall(psnd_dtq(DTQ_AF, (VP_INT)af_sec_ch));
+#ifdef DEBUG_QUEUEDEPTH
+ debug_queue_level += 2;
+ if ( debug_queue_level > debug_queue_max)
+ debug_queue_max = debug_queue_level;
+#endif // DEBUG_QUEUEDEPTH
+ }
+ } // 非ワイドFMの場合
+
+
+ } // RX-IF DMAバッファ内部のデータを処理
} while (1);
{
syslog( LOG_NOTICE, "TASK_AF activatred!" );
- int i = 0;
-
do{
+ // DMA転送が完了した受信バッファ
+ unsigned int* filled_buffer;
+ // next_descriptor
+ struct dma_descripter * next;
+ // ループカウンタ
+ int i;
+
+
+ // 送信が終わるのを待つ
syscall(wai_sem(SEM_SPORT0_TX));
- // ここに送信処理を書く
- if ( i == 0)
+
+ // SPORT0送信DMAコントローラが次にロードするデスクリプタへのポインタを取得する。
+ // このデスクリプタは、「現在使われていない」DMAデスクリプタであり、逆に言うと
+ // 割り込みが完了したDMAのデスクリプタである
+ next = (struct dma_descriptor *) *pDMA2_NEXT_DESC_PTR;
+
+ // 取得したデスクリプタから、割り込みを発生したバッファを割り出す。
+ filled_buffer = next->start_address;
+
+ // ここに送信処理を書く
+ // AF DMAバッファに送信すべきデータを書く
+ for ( i= 0; i<AF_BUFSIZE; i++)
{
- i=8000;
- syslog( LOG_NOTICE, "AF Interrupt" );
+ unsigned int data;
+
+ // AFキューから送信すべきデータを取り出す
+ // SVCにポーリングを使用しているため、取り出すべきデータがなければ待ちに入らずに
+ // エラーコードを返す
+ syscall(prcv_dtq( DTQ_AF, (VP_INT)&data));
+ // DMAバッファに書き込み
+ filled_buffer[i] = data;
+#ifdef DEBUG_QUEUEDEPTH
+ debug_queue_level --;
+ if ( debug_queue_min > debug_queue_level)
+ debug_queue_min = debug_queue_level;
+#endif // DEBUG_QUEUEDEPTH
}
- i--;
+
}while (1);
}
* なお、セカンダリ・チャンネルはindex = 1の時にサブ・オーディオを伝送するが、
* TRX-305はサブ・オーディオを使わないためこのルーチンは常に値を0としている。
*/
-static void pack_af_sample( short left, short right, int * pri_ch, int * sec_ch)
+static void pack_af_sample( short left, short right, unsigned int * pri_ch, unsigned int * sec_ch)
{
// オーディオデータは15bitしか使わない。Rchの16bit目は0に固定する
right >>= 1; // 15bitに変換
}
// プライマリ・チャンネルの組み立て
- *pri_ch = (right << 16) | left;
+ *pri_ch = ((unsigned int)right << 16) | (unsigned short)left;
framework.index = ! framework.index; // indexの論理反転
*/
static void unpack_wide_fm ( unsigned int pri_ch, unsigned int sec_ch, int* idata, int* qdata )
{
+ int command, data, exp, i, q;
+
// iデータとqデータを抽出する。両者とも16bitで、bit14からbit29に格納されている
- *idata = ( pri_ch << 2 ) & 0xFFFF0000;
- *qdata = ( sec_ch << 2 ) & 0xFFFF0000;
+ i = ( pri_ch << 2 ) & 0xFFFF0000;
+ q = ( sec_ch << 2 ) & 0xFFFF0000;
+ // ブロック浮動小数点処理。expでスケーリングする。
+ exp = ( pri_ch >> 10 ) & 0x0F;
+ *idata = i >> exp;
+ *qdata = q >> exp;
+
+#ifdef DEBUG_BLOCK_FLOAT
+ {
+ static int tested = 0;
+ if ( (i & 0x80000000) && ! tested )
+ {
+ tested = 1;
+ syslog( LOG_NOTICE, "i: %8x, exp: %d, idata:%8x", i, exp, *idata);
+ }
+ }
+#endif
// パラメータ・データを配列に格納する。
- // 配列インデックスは comaddr、データはcomdataから。comdataはpri/secに分散している。
- radio.comdata[ ( pri_ch >> 6 ) & 0x0F ] =
- (( pri_ch << 6 ) & 0xF000) | //
+ // 配列インデックスは comaddr、データはcomdataから。
+ // comdataはpri/secに分散している。
+
+ command = ( pri_ch >> 6 ) & 0x0F;
+ data =
+ (( pri_ch << 10 ) & 0xF000) | //
(( sec_ch >> 2 ) & 0x0FFF);
+ // パラメータ・データをrx_parameter.data配列に格納する。
+ // 配列インデックスは comaddr、データはcomdataから。
+
+ set_command_data( command, data);
+
+ radio.comdata[ command ] = data;
}
/**
* \param sec_ch セカンダリ・チャンネルからのデータ
* \param idata 抽出したIデータ。[-1,1.0)の固定小数点形式。valid_iqが真の時のみ有効
* \param qdata 抽出したQデータ。[-1,1.0)の固定小数点形式。valid_iqが真の時のみ有効
- * \param valid_iq IQデータが有効の時真、向こうの時は偽
+ * \param valid_iq IQデータが有効の時真、無効の時は偽
* \detail
*/
static void unpack_non_wide_fm( unsigned int pri_ch, unsigned int sec_ch, int* idata, int* qdata, int* valid_iq )
{
+ static unsigned int debug_count = 0;
+ static unsigned int debug_izero = 0;
+ static unsigned int debug_qzero = 0;
+
// インデックス分け
if ( sec_ch & 0x02 ) // bit1が1ならindex = 1
{
// IQデータはbit[29:2]に格納されている
- *idata = (pri_ch << 2); // プライマリ・チャンネルの場合はマスク不要
+ *idata = (pri_ch << 2) & 0xFFFFFFF0;
*qdata = (sec_ch << 2) & 0xFFFFFFF0;
// IQデータが有効であると通知する
*valid_iq = TRUE;
+ if ( debug_count < 1000 )
+ {
+ debug_count++;
+ if ( *idata & 1 << 31 )
+ debug_izero++;
+ if ( *qdata & 1 << 31 )
+ debug_qzero++;
+ }
+ else
+ {
+ syslog(LOG_NOTICE, "number of sign bit = %d, %d", debug_izero, debug_qzero);
+ debug_count = 0;
+ debug_izero = 0;
+ debug_qzero = 0;
+ }
}
else // index = 0
{
+ // ラジオパラメータ
+ int command, data;
+
+ command = ( pri_ch >> 6 ) & 0x0F;
+ data = ( sec_ch >> 2 ) & 0xFFFF;
// パラメータ・データをrx_parameter.data配列に格納する。
// 配列インデックスは comaddr、データはcomdataから。
- radio.comdata[ ( pri_ch >> 6 ) & 0x0F ] =
- ( sec_ch >> 2 ) & 0xFFFF;
+
+ set_command_data( command, data);
+
// IQデータが無効であると通知する
*valid_iq = FALSE;
}
}
+/**
+ * \brief SHからのコマンドとパラメタを保存する
+ * \param command コマンド種別
+ * \param data コマンドパラメータ
+ * \details このルーチンはSHからFPGA経由で受け取ったコマンドとそのデータを内部変数に格納する。
+ * 格納されたデータはユーザーが実装した復調アルゴリズムから、API経由で利用される。
+ */
+static void set_command_data( unsigned int command, unsigned int data )
+{
+#ifdef DEBUG_COMMAND
+ if ( radio.comdata[command] != data ){
+ syslog(LOG_NOTICE, "Command : %d, Data : %d", command, data );
+ }
+#endif
+ radio.comdata[ command ] = data;
+
+}
+
/**
* \brief SPORT0 受信割り込みハンドラ
{
// DMA割り込みをクリアする。
*pDMA1_IRQ_STATUS = DMA_DONE;
-
// タスクにSPORT0受信DMAのバッファが埋まったと知らせる。
- syscall(isig_sem(SEM_SPORT0_RX));
-
+ syscall(isig_sem(SEM_SPORT0_RX)); // デバッグとりあえずタスクは殺しておく。
// ペリフェラルへの書き込みを待つ。
ssync();
// タスクにSPORT0送信DMAのバッファが空いたと知らせる。
syscall(isig_sem(SEM_SPORT0_TX));
-
// ペリフェラルへの書き込みを待つ。
ssync();
0 << 9 | // RSFESE, 0:normal frame sync, 1:LR frame clock
1 << 8 | // RXSE, 0:secondary ch disable, 1:secondary ch enable
29 << 0 ; // SLEN 0-1:not allowed,2-31:Serial word length - 1
+
ssync();
// 受信DMAデスクリプタを作る
framework.rx_dma_dsc[0].next_descripter = &framework.rx_dma_dsc[1];
- framework.rx_dma_dsc[0].start_address = framework.rxif_buffer[0];
- framework.rx_dma_dsc[0].x_count = RXIF_BUFSIZE;
- framework.rx_dma_dsc[0].x_modify = sizeof(framework.rxif_buffer[0][0]);
- framework.rx_dma_dsc[0].config =
- FLOW_LARGE | // FLOW, 0:Stop, 1:Auto buffer, 4:Desc array, 6:Desc List small, 7:Desc, List, Large
- NDSIZE_7 | // NDSIZE, the # of element of the next descripter to fetch
- 1 << DI_EN_P | // DI_EN, 0:No interrupt at the end, 1:Interrupt at the end
- 0 << DI_SEL_P | // DI_SEL, 0:Interrupt at the end of outer loop, 1:Interrupt at the end of inter loop
- 0 << RESTART_P | // RESTART, 0:Keep DMA FIFO before start, 1:Purge DMA FIFO before start
- 0 << DMA2D_P | // DMA2D, 0:Linear DMA, 1:2D DMA
- WDSIZE_32 | // WDSIZE, 0:8bit, 1:16bit, 2:32bit,3:reserved
- 1 << WNR_P | // WNR, 0:Read from memory, 1:Write to Memory
- 1 << 0 ; // DMA_EN, 0:Disable DMA, 1:Enable DMA
-
framework.rx_dma_dsc[1].next_descripter = &framework.rx_dma_dsc[0];
+
framework.rx_dma_dsc[1].start_address = framework.rxif_buffer[1];
+ framework.rx_dma_dsc[0].start_address = framework.rxif_buffer[0];
+
+ framework.rx_dma_dsc[0].x_count =
framework.rx_dma_dsc[1].x_count = RXIF_BUFSIZE;
+
+ framework.rx_dma_dsc[0].x_modify =
framework.rx_dma_dsc[1].x_modify = sizeof(framework.rxif_buffer[1][0]);
+
+ framework.rx_dma_dsc[0].config =
framework.rx_dma_dsc[1].config =
FLOW_LARGE | // FLOW, 0:Stop, 1:Auto buffer, 4:Desc array, 6:Desc List small, 7:Desc, List, Large
NDSIZE_7 | // NDSIZE, the # of element of the next descripter to fetch
1 << WNR_P | // WNR, 0:Read from memory, 1:Write to Memory
1 << 0 ; // DMA_EN, 0:Disable DMA, 1:Enable DMA
+
// SPORT0 受信DMAコントローラの初期状態設定
// ここではDMAをイネーブルにしない。また、バッファクリアする
*pDMA1_CONFIG =
0 << 12 | // LTFS, 0:Active high TFS, 1:Active low TFS
0 << 11 | // DITFS, 0:data dependent TFS generation, 1:data independent TFS generation
1 << 10 | // TFSR, 0:TFS is not required every word, 1:TFS is required every word
- 0 << 9 | // ITFS, 0:external TFS, 1:internal TFS
+ 1 << 9 | // ITFS, 0:external TFS, 1:internal TFS
0 << 4 | // TLSBIT, 0:MSB first transmission, 1:LSB first transmission
0 << 2 | // TDTYPE 0:normal, 1:reserved, 2:u-law, 3:a-law
0 << 1 | // ITCLK, 0:external clock generation, 1:internal clock generation
*pSPORT0_TCR2 =
0 << 10 | // TRFST, 0:left streo ch first, 1:right stereo ch first
0 << 9 | // TSFESE, 0:normal frame sync, 1:LR frame clock
- 0 << 8 | // TXSE, 0:secondary ch disable, 1:secondary ch enable
+ 1 << 8 | // TXSE, 0:secondary ch disable, 1:secondary ch enable
30 << 0 ; // SLEN 0-1:not allowed,2-31:Serial word length - 1
+ *pSPORT0_TFSDIV = 255; // TFS period -1 ( The period is 256 )
+
// 送信DMAデスクリプタを作る
// 注意:制御の都合上、最初はDMA割り込みをオフにしておく。これは
// である。rx_if_taskの初期化部でSPORT受信部を起動する際に、送信部の割り込みも
// 有効にする。
framework.tx_dma_dsc[0].next_descripter = &framework.tx_dma_dsc[1];
- framework.tx_dma_dsc[0].start_address = framework.af_buffer[0];
- framework.tx_dma_dsc[0].x_count = RXIF_BUFSIZE;
- framework.tx_dma_dsc[0].x_modify = sizeof(framework.af_buffer[0][0]);
- framework.tx_dma_dsc[0].config =
- FLOW_LARGE | // FLOW, 0:Stop, 1:Auto buffer, 4:Desc array, 6:Desc List small, 7:Desc, List, Large
- NDSIZE_7 | // NDSIZE, the # of element of the next descripter to fetch
- 0 << DI_EN_P | // DI_EN, 0:No interrupt at the end, 1:Interrupt at the end
- 0 << DI_SEL_P | // DI_SEL, 0:Interrupt at the end of outer loop, 1:Interrupt at the end of inter loop
- 0 << RESTART_P | // RESTART, 0:Keep DMA FIFO before start, 1:Purge DMA FIFO before start
- 0 << DMA2D_P | // DMA2D, 0:Linear DMA, 1:2D DMA
- WDSIZE_32 | // WDSIZE, 0:8bit, 1:16bit, 2:32bit,3:reserved
- 0 << WNR_P | // WNR, 0:Read from memory, 1:Write to Memory
- 1 << 0 ; // DMA_EN, 0:Disable DMA, 1:Enable DMA
-
framework.tx_dma_dsc[1].next_descripter = &framework.tx_dma_dsc[0];
+
+ framework.tx_dma_dsc[0].start_address = framework.af_buffer[0];
framework.tx_dma_dsc[1].start_address = framework.af_buffer[1];
- framework.tx_dma_dsc[1].x_count = RXIF_BUFSIZE;
- framework.tx_dma_dsc[1].x_modify = sizeof(framework.af_buffer[1][0]);
+
+ framework.tx_dma_dsc[0].x_count =
+ framework.tx_dma_dsc[1].x_count = AF_BUFSIZE;
+
+ framework.tx_dma_dsc[0].x_modify =
+ framework.tx_dma_dsc[1].x_modify = sizeof(framework.af_buffer[0][0]);
+
+ framework.tx_dma_dsc[0].config =
framework.tx_dma_dsc[1].config =
FLOW_LARGE | // FLOW, 0:Stop, 1:Auto buffer, 4:Desc array, 6:Desc List small, 7:Desc, List, Large
NDSIZE_7 | // NDSIZE, the # of element of the next descripter to fetch
0 << WNR_P | // WNR, 0:Read from memory, 1:Write to Memory
1 << 0 ; // DMA_EN, 0:Disable DMA, 1:Enable DMA
+
// SPORT0 送信DMAコントローラの初期状態設定
// ここではDMAをイネーブルにしない。また、バッファクリアする
*pDMA2_CONFIG =
*pDMA2_NEXT_DESC_PTR = &framework.tx_dma_dsc[0];
}
+
+/**
+ * \brief デバッグ用モニタ・タスク
+ * \param exinf cfgファイルに記述されたパラメタを受け取る引数。使っていない。
+ * \details 一定時間ごとにシステム状態をモニターする。通常は使っていないが、
+ * 開発時に各種システム量を計算、取得するために動かす低順位タスクである。
+ */
+
+void monitor_task(VP_INT exinf)
+{
+
+ while(1)
+ {
+#ifdef DEBUG_DSPLOAD
+ unsigned int cycle_start, cycle_end, total_idle_cycle, total_cycle;
+ {// DSP負荷の計算(前処理)
+
+ idle_cycle = 0;
+ asm volatile ("r0 = cycles;%0 = r0;" : "=d"(cycle_start) : : "R0");
+ }
+#endif // DEBUG_DSPLOAD
+
+ tslp_tsk(1000); // 1秒待つ
+
+#ifdef DEBUG_DSPLOAD
+ {// DSP負荷の計算(後処理)
+ asm volatile ("r0 = cycles;%0 = r0;" : "=d"(cycle_end) : : "R0");
+
+ // ここまでの通算時間を取得する
+ total_cycle = cycle_end - cycle_start;
+ // ここまでの通算アイドル時間を取得する
+ total_idle_cycle = idle_cycle;
+
+
+ // 計算しやすいようにスケーリング
+ total_cycle >>= 16;
+ total_idle_cycle >>=16;
+
+ syslog(LOG_NOTICE, "DSP Load : %d%%", (total_cycle - total_idle_cycle) * 100 / total_cycle);
+ }
+#endif // DEBUG_DSPLOAD
+
+#ifdef DEBUG_QUEUEDEPTH
+ { // AF TASK, RX IF TAXK間のキューの深さを報告する
+
+ syslog( LOG_NOTICE, "Queue depth max : %d, min : %d ", debug_queue_max, debug_queue_min);
+ }
+#endif // DEBUG_QUEUEDEPTH
+
+#ifdef DEBUG_COMMAND_API
+ syslog( LOG_NOTICE, "radio_api_getARM_mode() %d", radio_api_getARM_mode() );
+ syslog( LOG_NOTICE, "radio_api_getAIS_if_shift() %d", radio_api_getAIS_if_shift() );
+ syslog( LOG_NOTICE, "radio_api_getAAT_attack() %d", radio_api_getAAT_attack() );
+ syslog( LOG_NOTICE, "radio_api_getAFA_fade() %d", radio_api_getAFA_fade() );
+ syslog( LOG_NOTICE, "radio_api_getAST_noise_squelch_level() %d", radio_api_getAST_noise_squelch_level() );
+ syslog( LOG_NOTICE, "radio_api_getACP_cw_pitch() %d", radio_api_getACP_cw_pitch() );
+ syslog( LOG_NOTICE, "radio_api_getADN_denoiser() %d", radio_api_getADN_denoiser() );
+ syslog( LOG_NOTICE, "radio_api_getAAN_auto_notch() %d", radio_api_getAAN_auto_notch() );
+ syslog( LOG_NOTICE, "radio_api_getAGL_gain_level() %d", radio_api_getAGL_gain_level() );
+ syslog( LOG_NOTICE, "radio_api_getAIF_filter() %d", radio_api_getAIF_filter() );
+ syslog( LOG_NOTICE, "radio_api_getABN_noise_blanker_on() %d", radio_api_getABN_noise_blanker_on());
+ syslog( LOG_NOTICE, "radio_api_getARG_agc_on() %d", radio_api_getARG_agc_on());
+ syslog( LOG_NOTICE, "radio_api_getANE_noise_squelch_on() %d", radio_api_getANE_noise_squelch_on());
+ syslog( LOG_NOTICE, "radio_api_getAAF_hpf() %d", radio_api_getAAF_hpf() );
+ syslog( LOG_NOTICE, "radio_api_getAAF_lpf() %d", radio_api_getAAF_lpf() );
+ syslog( LOG_NOTICE, "radio_api_getAVP_voice_squelch_level() %d", radio_api_getAVP_voice_squelch_level() );
+ syslog( LOG_NOTICE, "radio_api_getAVS_voice_squelch_on() %d", radio_api_getAVS_voice_squelch_on() );
+#endif // DEBUG_COMMAND_API
+
+ }
+}