#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 parse_wide_fm ( unsigned int pri_ch, unsigned int sec_ch, int* idata, int* qdata );
-static void parse_non_wide_fm( unsigned int pri_ch, unsigned int sec_ch, int* idata, int* qdata, int* valid_iq );
+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 );
unsigned int rxif_buffer[2][RXIF_BUFSIZE];
unsigned int af_buffer[2][AF_BUFSIZE];
-} sport_ctl;
+ int index; // パッカーが使う。現在のワードインデックスが0か1か
+} framework;
-static struct {
- int index;
+ struct {
unsigned short flags;
unsigned short smeter;
-} af_ctl;
+ unsigned short comdata[PARAMDATA_NUM];
+} radio;
+
+
/**
* \brief RX_IF受信データの処理タスク
*/
void rx_if_task(VP_INT exinf)
{
+ int i;
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)));
- af_ctl.index = FALSE;
- af_ctl.flags = 0;
- af_ctl.smeter = 0;
+ framework.index = FALSE; // パッカーのインデックスの初期値設定。実のところ、初期値はランダムでも構わない。
+
+ // 受信機パラメタの初期化
+ for ( i=0; i<PARAMDATA_NUM; i++)
+ radio.comdata[i] = 0;
+
+ radio.flags = 0;
+ radio.smeter = 0;
- // SPORT0の送受割り込みを可能にする
+ // SPORT0の送受割り込み受付を可能にする
syscall(ena_int(INTNO_SPORT0_RX));
syscall(ena_int(INTNO_SPORT0_TX));
// 頃合いなので送信DMA割り込みを開始する。
// CPUロックするのは割り込みにより、タイミングがずれるのを嫌って。
loc_cpu();
- sport_ctl.tx_dma_dsc[0].config |= 1 << DI_EN_P;
- sport_ctl.tx_dma_dsc[1].config |= 1 << DI_EN_P;
+ framework.tx_dma_dsc[0].config |= 1 << DI_EN_P;
+ framework.tx_dma_dsc[1].config |= 1 << DI_EN_P;
unl_cpu();
- // RX受信を開始する
+ // RX受信を開始する。転送と同時に割り込みが始まる
*pDMA1_CONFIG |= DMAEN; // RX SPORT DMA Enable
*pSPORT0_RCR1 |= RSPEN; // RX SPORT Enable
ssync();
count = 0;
// FIFOにデータがたまったはずである。
// FIFOデータを読みだして下位2bitのみ表示する
- rx[0] = sport_ctl.rxif_buffer[1][0]; // 下位2bitのみ抽出
- rx[1] = sport_ctl.rxif_buffer[1][1]; // 下位2bitのみ抽出
- rx[2] = sport_ctl.rxif_buffer[1][2]; // 下位2bitのみ抽出
- rx[3] = sport_ctl.rxif_buffer[1][3]; // 下位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] );
} while (1);
- syslog(LOG_NOTICE, "Sample program ends.");
+ syslog(LOG_NOTICE, "rx_if_task ends.");
kernel_exit();
}
left >>= 1; //15bitに変換
- if ( af_ctl.index )
+ if ( framework.index )
{
left |= 0x8000; // MSBを1にする
// indexが0のとき、セカンダリオーディオはDSPからSH2へのデータ回線である
*sec_ch =
- af_ctl.smeter << 16 |
- af_ctl.flags; // flagsのbit15は0なので、indexも0になる
+ radio.smeter << 16 |
+ radio.flags; // flagsのbit15は0なので、indexも0になる
}
// プライマリ・チャンネルの組み立て
*pri_ch = (right << 16) | left;
- af_ctl.index = ! af_ctl.index; // indexの論理反転
+ framework.index = ! framework.index; // indexの論理反転
}
/**
* \param qdata 抽出したQデータ。[-1,1.0)の固定小数点形式
* \detail
*/
-static void parse_wide_fm ( unsigned int pri_ch, unsigned int sec_ch, int* idata, int* qdata )
+static void unpack_wide_fm ( unsigned int pri_ch, unsigned int sec_ch, int* idata, int* qdata )
{
+ // iデータとqデータを抽出する。両者とも16bitで、bit14からbit29に格納されている
+ *idata = ( pri_ch << 2 ) & 0xFFFF0000;
+ *qdata = ( sec_ch << 2 ) & 0xFFFF0000;
+
+ // パラメータ・データを配列に格納する。
+ // 配列インデックスは comaddr、データはcomdataから。comdataはpri/secに分散している。
+ radio.comdata[ ( pri_ch >> 6 ) & 0x0F ] =
+ (( pri_ch << 6 ) & 0xF000) | //
+ (( sec_ch >> 2 ) & 0x0FFF);
}
/**
* \detail
*/
-static void parse_non_wide_fm( unsigned int pri_ch, unsigned int sec_ch, int* idata, int* qdata, int* valid_iq )
+static void unpack_non_wide_fm( unsigned int pri_ch, unsigned int sec_ch, int* idata, int* qdata, int* valid_iq )
{
-
+ // インデックス分け
+ if ( sec_ch & 0x02 ) // bit1が1ならindex = 1
+ {
+ // IQデータはbit[29:2]に格納されている
+ *idata = (pri_ch << 2); // プライマリ・チャンネルの場合はマスク不要
+ *qdata = (sec_ch << 2) & 0xFFFFFFF0;
+ // IQデータが有効であると通知する
+ *valid_iq = TRUE;
+ }
+ else // index = 0
+ {
+ // パラメータ・データをrx_parameter.data配列に格納する。
+ // 配列インデックスは comaddr、データはcomdataから。
+ radio.comdata[ ( pri_ch >> 6 ) & 0x0F ] =
+ ( sec_ch >> 2 ) & 0xFFFF;
+ // IQデータが無効であると通知する
+ *valid_iq = FALSE;
+ }
}
// DMAバッファを明示的にクリアする
for ( i = 0; i < RXIF_BUFSIZE; i++)
{
- sport_ctl.rxif_buffer[0][i] = 0;
- sport_ctl.rxif_buffer[0][i] = 0;
+ framework.rxif_buffer[0][i] = 0;
+ framework.rxif_buffer[0][i] = 0;
}
// 受信SPORTの設定。WORD長は30bitで、アーリー同期信号。外部クロック入力。
// 受信DMAデスクリプタを作る
- sport_ctl.rx_dma_dsc[0].next_descripter = &sport_ctl.rx_dma_dsc[1];
- sport_ctl.rx_dma_dsc[0].start_address = sport_ctl.rxif_buffer[0];
- sport_ctl.rx_dma_dsc[0].x_count = RXIF_BUFSIZE;
- sport_ctl.rx_dma_dsc[0].x_modify = sizeof(sport_ctl.rxif_buffer[0][0]);
- sport_ctl.rx_dma_dsc[0].config =
+ 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
1 << WNR_P | // WNR, 0:Read from memory, 1:Write to Memory
1 << 0 ; // DMA_EN, 0:Disable DMA, 1:Enable DMA
- sport_ctl.rx_dma_dsc[1].next_descripter = &sport_ctl.rx_dma_dsc[0];
- sport_ctl.rx_dma_dsc[1].start_address = sport_ctl.rxif_buffer[1];
- sport_ctl.rx_dma_dsc[1].x_count = RXIF_BUFSIZE;
- sport_ctl.rx_dma_dsc[1].x_modify = sizeof(sport_ctl.rxif_buffer[1][0]);
- sport_ctl.rx_dma_dsc[1].config =
+ 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[1].x_count = RXIF_BUFSIZE;
+ framework.rx_dma_dsc[1].x_modify = sizeof(framework.rxif_buffer[1][0]);
+ 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 << DI_EN_P | // DI_EN, 0:No interrupt at the end, 1:Interrupt at the end
WDSIZE_32 | // WDSIZE, 0:8bit, 1:16bit, 2:32bit,3:reserved
1 << WNR_P | // WNR, 0:Read from memory, 1:Write to Memory
0 << 0 ; // DMA_EN, 0:Disable DMA, 1:Enable DMA
- *pDMA1_NEXT_DESC_PTR = &sport_ctl.rx_dma_dsc[0];
+ *pDMA1_NEXT_DESC_PTR = &framework.rx_dma_dsc[0];
}
// DMAバッファを明示的にクリアする
for ( i = 0; i < AF_BUFSIZE; i++)
{
- sport_ctl.af_buffer[0][i] = 0;
- sport_ctl.af_buffer[0][i] = 0;
+ framework.af_buffer[0][i] = 0;
+ framework.af_buffer[0][i] = 0;
}
// 起きないようにするためである。ラッシュで送信されるのはダミーデータのみ
// である。rx_if_taskの初期化部でSPORT受信部を起動する際に、送信部の割り込みも
// 有効にする。
- sport_ctl.tx_dma_dsc[0].next_descripter = &sport_ctl.tx_dma_dsc[1];
- sport_ctl.tx_dma_dsc[0].start_address = sport_ctl.af_buffer[0];
- sport_ctl.tx_dma_dsc[0].x_count = RXIF_BUFSIZE;
- sport_ctl.tx_dma_dsc[0].x_modify = sizeof(sport_ctl.af_buffer[0][0]);
- sport_ctl.tx_dma_dsc[0].config =
+ 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 << WNR_P | // WNR, 0:Read from memory, 1:Write to Memory
1 << 0 ; // DMA_EN, 0:Disable DMA, 1:Enable DMA
- sport_ctl.tx_dma_dsc[1].next_descripter = &sport_ctl.tx_dma_dsc[0];
- sport_ctl.tx_dma_dsc[1].start_address = sport_ctl.af_buffer[1];
- sport_ctl.tx_dma_dsc[1].x_count = RXIF_BUFSIZE;
- sport_ctl.tx_dma_dsc[1].x_modify = sizeof(sport_ctl.af_buffer[1][0]);
- sport_ctl.tx_dma_dsc[1].config =
+ framework.tx_dma_dsc[1].next_descripter = &framework.tx_dma_dsc[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[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 << DI_EN_P | // DI_EN, 0:No interrupt at the end, 1:Interrupt at the end
WDSIZE_32 | // WDSIZE, 0:8bit, 1:16bit, 2:32bit,3:reserved
0 << WNR_P | // WNR, 0:Read from memory, 1:Write to Memory
0 << 0 ; // DMA_EN, 0:Disable DMA, 1:Enable DMA
- *pDMA2_NEXT_DESC_PTR = &sport_ctl.tx_dma_dsc[0];
+ *pDMA2_NEXT_DESC_PTR = &framework.tx_dma_dsc[0];
}