📄 ba1924.c
字号:
#ifdef SUPPORT_BA1924
#include "global.h"
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include <avr/delay.h>
#include "carcav.h"
#include "ba1924.h"
#include "rds.h"
/*26x10 matrix*/
UINT16 rds_decoding_matrix[26] ={ //H 图F3
0x0200,0x0100,0x0080,0x0040,
0x0020,0x0010,0x0008,0x0004,
0x0002,0x0001,0x02dc,0x016e,
0x00b7,0x0287,0x039f,0x0313,
0x0355,0x0376,0x01bb,0x0201,
0x03dc,0x01ee,0x00f7,0x02a7,
0x038f,0x031b,
};
#ifdef RDS_ENCODER
/*16*26*/
UINT32 rds_encoding_matrix[16] = { //G,图F1
0x02000077,0x010002e7,0x008003af,0x0040030b,
0x00200359,0x00100370,0x000801b8,0x000400dc,
0x0002006e,0x00010037,0x000082c7,0x000043bf,
0x00002303,0x0000135d,0x00000b72,0x000005b9,
};
/*A B C C' D*/
UINT16 rds_offset_word[5] ={0x00fc,0x0198,0x0168,0x0350,0x01b4};//表F1,偏置码
#endif
/*10bits A B C C' D*/
UINT16 rds_syndrome[5]={0x03d8,0x03d4,0x025c,0x03cc,0x0258};//表F1,同步码
typedef struct {
UINT32 rds_buffer; //32bit 的数据,实际为26bit
BYTE rds_bit_cnt; //结构?
BYTE rds_sync_state; //同步状态
BYTE rds_block_id; //快地址
BYTE rds_crc_ok; //校验成功
UINT16 rds_block_data[4]; //块数据
}rds_var;
rds_var rds_var1;
//volatile BYTE rdsDataReady=0;
extern void rds_process_group(UINT16 a, UINT16 b, UINT16 c, UINT16 d);
unsigned char new_bit_received=0;
#ifdef RDS_ENCODER
void rds_encode(UINT16 data,BYTE block_id)
{
BYTE i;
UINT16 check_word = 0;
UINT32 sent_word = 0;
for(i=0;i<16;i++)
{
if(data & (0x01<<i))
{
check_word ^= (rds_encoding_matrix[15-i]&0x03ff);
}
}
sent_word = ((data<<10)|(check_word^rds_offset_word[block_id]));
rds_var1.rds_buffer = sent_word;
//printf("che %x sent %x\n",check_word,sent_word);
}
#endif
void rds_calculate_crc(void)
{//crc 校验,校验结果通过rds_var1.rds_crc_ok返回
//同时完成对rds_var1.rds_block_id的判定
BYTE i=0;
BYTE j=0;
UINT16 rds_check_word=0;
//UINT16 rds_data_word;
//UINT16 rds_compare = 0;
UINT32 k=1;
rds_var1.rds_crc_ok = 0;
for(i=0;i<26;i++)
{
if(rds_var1.rds_buffer & (k<<i))
{
rds_check_word^=(rds_decoding_matrix[25-i]);
}
}
for(j=0;j<5;j++)
{
if(rds_check_word==rds_syndrome[j])
{
rds_var1.rds_crc_ok = 1;
rds_var1.rds_block_id = j;
break;
}
}
}
/*
state shift:
state0-(1)->state1-(2)->state2-(3)->state3-(4)->state4
| | |
|------<<(5)|
|-----<<---(6)-------|
1--in state 0,init rd_-bit_cnt to 0,and state shift to 1;
2--in state 1,wait the shift buffer to be full;once the buffer is full(>26 bit),
calculate the syndrome and check it up from the syndrome table.if
we get the rds_sync_ok flag,shift state to 2,and store the block data to
the buffer.
3--in state 1,if we didn't get rds_sync_ok flag(it often happen),we just break,
and wait for the next bit come in.Then do the same as title 2.
4--in state 2,it is quite similar with state1,we wait for the shift buffer to be full
and check it up fot rds_sync_ok;if we get the rds_sync_ok flag,store data
and shift to the next state.if we don't get the rds_sync_ok flag,just wait for
the next bit until sync ok.
5--in state 3,also similar with the previous state.The different is
*/
void rds_get_data(void)
{
//ASSERT((rds_var1.rds_sync_state<=4), "rds_get_data");
switch(rds_var1.rds_sync_state)
{
case 0: //reset cnt
rds_var1.rds_bit_cnt = 0;
rds_var1.rds_sync_state = 1;
break;
case 1: //cnt ==26
if(rds_var1.rds_bit_cnt>=26)
{
rds_calculate_crc();
if(rds_var1.rds_crc_ok)
{
if(rds_var1.rds_block_id == 0)
{
rds_var1.rds_sync_state = 2;
rds_var1.rds_bit_cnt = 0;
rds_var1.rds_block_data[0] = (UINT16)(rds_var1.rds_buffer>>10)&0xffff;
//printf("sync 0\n");
}
}
}
break;
case 2: //next block
if(rds_var1.rds_bit_cnt >= 26)
{
rds_calculate_crc();
if(rds_var1.rds_crc_ok)
{
if(rds_var1.rds_block_id == 1)
{
rds_var1.rds_bit_cnt = 0;
rds_var1.rds_sync_state = 3;
rds_var1.rds_block_data[1] = (UINT16)(rds_var1.rds_buffer>>10)&0xffff;
}
}
}
break;
case 3:
if(rds_var1.rds_bit_cnt == 26)
{
rds_var1.rds_bit_cnt = 0;
rds_calculate_crc();
if(rds_var1.rds_crc_ok)
{
if((rds_var1.rds_block_id ==2)||(rds_var1.rds_block_id ==3)) //block C or C'
{
rds_var1.rds_sync_state = 4;
rds_var1.rds_block_data[2] = (UINT16)(rds_var1.rds_buffer>>10)&0xffff;
}
else
{
rds_var1.rds_sync_state = 2;
}
}
else
{
rds_var1.rds_sync_state = 2;
}
}
break;
case 4:
if(rds_var1.rds_bit_cnt == 26)
{
rds_var1.rds_bit_cnt = 0;
rds_calculate_crc();
if(rds_var1.rds_crc_ok)
{
if(rds_var1.rds_block_id ==4) //block D
{
//printf("sync 3 id %d\n",rds_var1.rds_block_id);
rds_var1.rds_block_data[3] = (UINT16)(rds_var1.rds_buffer>>10)&0xffff;
rds_process_group(rds_var1.rds_block_data[0],rds_var1.rds_block_data[1],rds_var1.rds_block_data[2],rds_var1.rds_block_data[3]);
}
else
{
rds_var1.rds_sync_state = 2;
}
}
else
{
rds_var1.rds_sync_state = 2;
}
}
break;
default:
rds_var1.rds_sync_state = 0;
break;
}
}
/*
MSB first
return 0:no new bit is get
1:new bit in
*/
/*
BYTE rds_collect_one_bit(void)
{
static BYTE prev_state= 0;
BYTE ret = 0;
if(PIN_RDS_CLK)
{
prev_state = 1;
}
else
{
if(prev_state == 1)
{
if(RDS_DATA_SET)
{
//TUNER_CLK_SET(1);
rds_var1.rds_buffer<<=1;
rds_var1.rds_buffer |= 0x00000001;
}
else
{
//TUNER_CLK_SET(0);
rds_var1.rds_buffer<<=1;
rds_var1.rds_buffer &= 0xfffffffe;
}
rds_var1.rds_bit_cnt ++;
ret = 1;
}
prev_state = 0;
}
return ret;
}
*/
/*
void rds_collect_data(void)
{
_delay_us(10);
if(rds_collect_one_bit()) //调用一次rds_collect_one_bit,判断是否有新的数据收到
{ //如果收到新的数据,则执行rds_get_data
rds_get_data();
}
}
*/
//INTERRUPT(SIG_INTERRUPT1)
SIGNAL(SIG_INTERRUPT1)
{
#ifdef _DIFFER_ENCODE_
static BYTE prev_state= 0;
//sei();
if(prev_state == 1){
if (RDS_DATA_SET) { //差分编码,之前为高现在为高则收到0
rds_var1.rds_buffer<<=1;
rds_var1.rds_buffer &= 0xfffffffe;
}else{ //差分编码,之前为高现在为低则收到1
rds_var1.rds_buffer<<=1;
rds_var1.rds_buffer |= 0x00000001;
prev_state = 0;
}
}else{
if (RDS_DATA_SET) { //差分编码,之前为低现在为高则收到1
rds_var1.rds_buffer<<=1;
rds_var1.rds_buffer |= 0x00000001;
}else{ //差分编码,之前为低现在为低则收到0
rds_var1.rds_buffer<<=1;
rds_var1.rds_buffer &= 0xfffffffe;
prev_state = 0;
}
}
#else
//sei();
if (RDS_DATA_SET) {
rds_var1.rds_buffer<<=1;
rds_var1.rds_buffer |= 0x00000001;
}else{
rds_var1.rds_buffer<<=1;
rds_var1.rds_buffer &= 0xfffffffe;
}
#endif
rds_var1.rds_bit_cnt++;
rds_get_data(); //CRC
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -