OSDN Git Service

テストプログラムの問題を修正することで、amの包絡線検波ができるようになった。
[trx-305dsp/dsp.git] / trx305 / framework.c
index 689c835..3a244d4 100644 (file)
@@ -7,13 +7,13 @@
 #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, 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 );
 
 
 
@@ -39,19 +39,15 @@ static struct {
 } framework;
 
     // ラジオアルゴリズムとのやりとりに使う変数
- struct {
-    unsigned short flags;
-    unsigned short smeter;
-    unsigned short comdata[PARAMDATA_NUM];
-} radio;
+ struct RADIO radio;
 
 
-static  int debug_counter = 0;
-static  int debug_level = 0;
-static  int debug_tx_counter = 0;
-static  int debug_rx_counter = 0;
-
-#define DEBUGLOOP (31700)
+    // デバッグ用変数群
+#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
 
 
 /**
@@ -82,7 +78,11 @@ void rx_if_task(VP_INT exinf)
         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));
-        debug_level ++;
+#ifdef DEBUG_QUEUEDEPTH
+        debug_queue_level +=2;
+        if ( debug_queue_level > debug_queue_max)
+            debug_queue_max = debug_queue_level;
+#endif // DEBUG_QUEUEDEPTH
     }
 
 
@@ -107,9 +107,11 @@ void rx_if_task(VP_INT exinf)
 
         // 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データ送信タスクをアクティブにする
 
@@ -126,9 +128,6 @@ void rx_if_task(VP_INT exinf)
     ssync();
 
 
-
-
-
     /*
      *  メインループ
      *  受信DMA割り込み待ってから、DMAバッファ内部のデータを解析して然るべき受信処理を行う。
@@ -189,11 +188,13 @@ void rx_if_task(VP_INT exinf)
 
                         // パック済みオーディオサンプルをAFキューに送信する
                         // キューに空きがなければ、待たずにエラーをもって帰る
-#if 0
                     syscall(psnd_dtq(DTQ_AF, (VP_INT)af_pri_ch));
                     syscall(psnd_dtq(DTQ_AF, (VP_INT)af_sec_ch));
-#endif
-                    debug_level += 2;
+#ifdef DEBUG_QUEUEDEPTH
+                    debug_queue_level += 2;
+                    if ( debug_queue_level > debug_queue_max)
+                        debug_queue_max = debug_queue_level;
+#endif // DEBUG_QUEUEDEPTH
                 }
 
             }
@@ -218,11 +219,13 @@ void rx_if_task(VP_INT exinf)
                     pack_af_sample( left, right, &af_pri_ch, &af_sec_ch);
                         // パック済みオーディオサンプルをAFキューに送信する
                         // キューに空きがなければ、待たずにエラーをもって帰る
-#if 0
                     syscall(psnd_dtq(DTQ_AF, (VP_INT)af_pri_ch));
                     syscall(psnd_dtq(DTQ_AF, (VP_INT)af_sec_ch));
-#endif
-                      debug_level += 2;
+#ifdef DEBUG_QUEUEDEPTH
+                    debug_queue_level += 2;
+                    if ( debug_queue_level > debug_queue_max)
+                        debug_queue_max = debug_queue_level;
+#endif // DEBUG_QUEUEDEPTH
                 }
             }   // 非ワイドFMの場合
 
@@ -282,21 +285,15 @@ void af_task(VP_INT exinf)
                 // AFキューから送信すべきデータを取り出す
                 // SVCにポーリングを使用しているため、取り出すべきデータがなければ待ちに入らずに
                 // エラーコードを返す
-#if 0
             syscall(prcv_dtq( DTQ_AF, (VP_INT)&data));
-#endif
                 // DMAバッファに書き込み
             filled_buffer[i] = data;
-
-            debug_level --;
-        }
-#if 0
-        debug_counter ++;
-        if ( debug_counter > DEBUGLOOP ){
-            syslog( LOG_NOTICE, "AF LENGTH %d", debug_level);
-            debug_counter =0;
+#ifdef DEBUG_QUEUEDEPTH
+            debug_queue_level --;
+            if ( debug_queue_min >  debug_queue_level)
+                debug_queue_min = debug_queue_level;
+#endif // DEBUG_QUEUEDEPTH
         }
-#endif
 
     }while (1);
 }
@@ -346,7 +343,7 @@ static void pack_af_sample( short left, short right, unsigned int * pri_ch, unsi
     }
 
         // プライマリ・チャンネルの組み立て
-    *pri_ch = (right << 16) | left;
+    *pri_ch = ((unsigned int)right << 16) | (unsigned short)left;
 
 
     framework.index = ! framework.index;  // indexの論理反転
@@ -362,16 +359,42 @@ static void pack_af_sample( short left, short right, unsigned int * pri_ch, unsi
  */
 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;
 }
 
 /**
@@ -380,7 +403,7 @@ static void unpack_wide_fm ( unsigned int pri_ch, unsigned int sec_ch, int* idat
  * \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
  */
 
@@ -390,22 +413,46 @@ static void unpack_non_wide_fm(  unsigned int pri_ch, unsigned int sec_ch, int*
     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;
     }
     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 受信割り込みハンドラ
@@ -417,15 +464,11 @@ void sport0_rx_int_handler(void)
 {
         // DMA割り込みをクリアする。
     *pDMA1_IRQ_STATUS = DMA_DONE;
-
         // タスクにSPORT0受信DMAのバッファが埋まったと知らせる。
-    syscall(isig_sem(SEM_SPORT0_RX));
-
+    syscall(isig_sem(SEM_SPORT0_RX)); // デバッグとりあえずタスクは殺しておく。
         // ペリフェラルへの書き込みを待つ。
     ssync();
 
-    debug_rx_counter++;
-
 }
 
 /**
@@ -441,16 +484,9 @@ void sport0_tx_int_handler(void)
 
         // タスクにSPORT0送信DMAのバッファが空いたと知らせる。
      syscall(isig_sem(SEM_SPORT0_TX));
-
          // ペリフェラルへの書き込みを待つ。
      ssync();
 
-     debug_tx_counter++;
-     if ( debug_tx_counter > 31000)
-     {
-         syslog( LOG_INFO, "TX, SIC_ISR:x08", *pSIC_ISR );
-         debug_tx_counter = 0;
-     }
 }
 
 /**
@@ -506,6 +542,7 @@ static void init_sport0_rx(void)
             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();
 
 
@@ -577,7 +614,7 @@ static void init_sport0_tx(void)
             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
@@ -586,9 +623,11 @@ static void init_sport0_tx(void)
     *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割り込みをオフにしておく。これは
@@ -636,3 +675,74 @@ static void init_sport0_tx(void)
     *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
+
+    }
+}