DSP

Linux内核中的FM RDS浅析

2019-07-13 20:54发布

    RDS(Radio Data System)即无线数据广播系统,它是在调频广播发射信号中利用副载波把电台名称,节目类型,节目内容以及其它信息以数字形式发送出去。      在该项目中,我们采用的平台是IMX53+Linux,FM/AM芯片采用的是NXP公司的TEF663*系列,TEF6638芯片具备音频codec和FM/AM两个功能,因此该芯片有两个core,分别是Radio DSP和Audio DSP。TEF6638是音频系统中的核心,所有发声的通道都要通过TEF6638,该芯片的外围硬件连接比较简单,通过I2C总线和CPU相连,并通过I2C总线来控制TEF6638.RDS是FM中的一个子功能,为了调试好RDS功能,必须先将FM功能调好,这样才能在收听FM的时候,在屏幕上能看到FM频率,节目类别以及节目等信息。当我们收到一个FM频点时,例如102MHZ,想看看该频点是否有RDS信息?我们就可以读TEF6638的寄存器0X0和0X7,寄存器0X0的第四位和寄存器0X7的第七位是状态标志位,如果该位置1,表明有RDS信息到来,我们应该先读寄存器0X0的第四位,再读寄存器0X7的第七位,因为是寄存器0X0的第四位传送给寄存器0X7的第七位,因此我们在写程序的时候,可以判断这两位是否一致?如果不一致,就说明有错误。当状态标志位置1的时候,表明有RDS信息到来,同时我们还要读一下寄存器0X7的第五位和第六位,第五位是判断RDS数据是否一个完整的数据?若该位置0,表示接下来的数据是一串完整的数据,即A B C D四个数据块,若该位置1,表明只有A块数据PI是正确的,第六位的意思是寄存器的数据是否被新数据所覆盖?若置0表示没有被覆盖,置1表示数据没有及时的出来,新数据覆盖了旧数据,这就要求我们在65毫秒之类将寄存器的数据读出来。同时我们还要读一下寄存器0X7的第4位,该位表示RDS数据是A块还是B块,该位有助于我们判断读出来的RDS数据是否正确?接下来我们就是读寄存器0X8~0XF寄存器,寄存器0X8和0X9是A块数据,0XA和0XB是B块数据,0XC和0XD是C块数据,0XE和0XF是D块数据,在这里需要指出的是,我们使用的TEF6638芯片具有硬件解码的功能,换句话说就是将接受到的原始数据解码成符合RDS标准的数据,也就是我们所说的A B C D数据块,当然我们也可以设置寄存器0X9的第0位是否需要硬件解码?如果不需要硬件解码,那我们接受到的就是最原始的数据,这样还需我们用软件来解码.软件解码也很简单,只需要弄懂RDS标准就OK。我们的项目中是硬件解码,接受到的数据都是符合RDS标注的A B C D块,A块数据对应寄存器0X8和0X9,这两个字节加起来是16位,需要注意的是寄存器0X8的最高位对应的A块数据的第15位,寄存器0X9的最低位对应的是A块数据的第0位,B C D块也如此。将A B C D数据都读完后,我们还需要读一下错误标志寄存器0X10,该寄存器的8个位标明了A B C D数据块是否正确,若位0,表明接受的数据全部正确,若位0XFF,表明数据不可修复的错误。接下来就是如何用软件将这些数据往上层传?我们FM/AM在linux内核中采用的是V4L2架构,该结构很好的支持了RADIO,我们可以在结构体v4l2_file_operations中添加read底层调用接口,在read函数中添加相应的信息,就可完成对RDS信息的读取。最后我们还要写测试程序,相对底层来说简单许多,先open一下/dev/radio0,然后再read一下该设备描述符,在此不用多讲。最后要说明一点的是,在国内还没有RDS的频点,听说在广州那边有几个台,没有实地考察过,我们采用的信号发生器是罗尔茨提供的设备,可以发射带RDS信息的FM。
crstal-520@163.com