QNX下音频解码器SGTL5000驱动的调试

QNX系统下sgtl5000音频解码器的调试
调试环境:QNX7.0    BSP版本:SabreARD  CODEC:SGTL5000
本板所使用的arm芯片是imx6q,原bsp开发包所使用的音频芯片是CS42448,并且使用接口是EASI,与我们开发板是完全不同。我的开发板的CODEC硬件原理图:

sgtl5000 通过I2S接口与IMX6的SSI总线完成音频数据的交换;cpu通过I2C或者SPI完成对CODEC的控制,由于
硬件设计是I2C的接口,所以我们通过I2C来完成对CODEC的控制。
在调试过程中,我们从mx6q-sabrelite版本中将sgtl5000的驱动拷贝了过来进行调试。需要注意的是I2S的协议,
I2S协议类似于I2C协议,需要指定主备模式,主设备将会为备设备提供I2S的Bit时钟和声道选择时钟。在startup初
始化过程中,需要调试ssi模块的初始化。
SSI、AUDIO与CODEC之间的关系以及数据的流向?
对于IMX6Q来讲:AUDIO模块分为internal port和external port 两种端口类型。internal port是硬连接于ssi的,
不可以更改,其对应关系是:inter_port1<-->SSI1, inter_port2<--->SSI2,inter_port7<--->SSI3;而external port
对应的 是3-6,对应的外部管脚AUDIO3-AUDIO6。 内外部端口结构图如下:
我们可以通过配置audio1-7的寄存器完成内外部端口之间的映射,比如可以配置port3的数据源以及TXFS和TXC
的方向和源。需要特别注意的是,这个配置需要和I2S两端配置的主备模式要协调一致。在调试过程中最早出现的问题
就是由于该内外部端口的主备模式相反,导致一直没有声音。例如若CODEC配置为MASTER模式,则I2S协议中用到
的TXC和TXFS时钟信号都是由COEC提供 的,则 AUDIO模块内的external port应该配置为output模式,也就是
master模式,否则相反。
与internal port硬连接的SSI模块需要配置为I2S模式,该模式的配置是在CODEC中的ssi的初始化接口中完成,
移植过来的代码可以直接使用,无需更改。需要特备注意的是,我们需要在startup中完成ssi模块正常工作的时钟配置。
代码如下:
//#define CODEC_SLAVE 1
	#if defined (CODEC_SLAVE) //imx6q:master, codec:slave
	{
		/*
		 * Note that bits [20:19] are defined differently by the i.MX6 Quad/Dual compared to the i.MX6 DualLite/Solo
		 * The i.MX6 Solo/DualLite use bits 20:19 to control a PLL post-divider, whereas the Quad/Dual use bits 20:19
		 * for testing purposes.
		 */
		#define PLL_AUDIO_CTRL_POST_DIV_1			(0x3 << 19)
		#define PLL_AUDIO_CTRL_BYPASS				(1 << 16)
		#define PLL_AUDIO_CTRL_ENABLE				(1 << 13)
		#define PLL_AUDIO_CTRL_POWERDOWN			(1 << 12)
		#define PLL_AUDIO_CTRL_MFI_MASK				(0x7F << 0)	/* In the docs these bits are labeled DIV_SELECT */

		#define CCM_ANALOG_PLL_AUDIO_CTRL				0x70
		#define CCM_ANALOG_PLL_AUDIO_CTRL_SET			0x74
		#define CCM_ANALOG_PLL_AUDIO_CTRL_CLR			0x78
		#define CCM_ANALOG_PLL_AUDIO_NUM				0x80
		#define CCM_ANALOG_PLL_AUDIO_DENOM				0x90

		//This register contains the numerator (A) of Audio PLL fractional loop divider.
		out32(MX6X_ANATOP_BASE + CCM_ANALOG_PLL_AUDIO_NUM, 0x2a0);
		//This register contains the Denominator (B) of Audio PLL fractional loop divider
		out32(MX6X_ANATOP_BASE + CCM_ANALOG_PLL_AUDIO_DENOM, 0x3e8);
		//The control register provides control for the audio PLL.
		//This field controls the pll loop divider. Valid range for DIV_SELECT divider value: 27~54.
		out32(MX6X_ANATOP_BASE + CCM_ANALOG_PLL_AUDIO_CTRL_CLR, PLL_AUDIO_CTRL_MFI_MASK);
		//DIV_SELECT = 28 POST_DIV_SELECT = 0x3
		out32(MX6X_ANATOP_BASE + CCM_ANALOG_PLL_AUDIO_CTRL_SET, (0x1c & PLL_AUDIO_CTRL_MFI_MASK) | PLL_AUDIO_CTRL_POST_DIV_1);

		/* Power up and enable Audio PLL (PLL4) */
		out32(MX6X_ANATOP_BASE + CCM_ANALOG_PLL_AUDIO_CTRL_CLR, PLL_AUDIO_CTRL_BYPASS | PLL_AUDIO_CTRL_POWERDOWN);
		out32(MX6X_ANATOP_BASE + CCM_ANALOG_PLL_AUDIO_CTRL_SET, PLL_AUDIO_CTRL_ENABLE);

		/* the clock frequence of ssi2 is 12.288MHz*/
		init_ssi2_clk();
		init_audiomux(2, 3);
	}
	#else //imx6q:slave, codec:master
	{
		init_audiomux(3, 2);
	}
	#endif
该代码配置了SSI模块需要的工作时钟,但是配置完此之后,ssi仍然不能正常工作,主要是由于IMX6存在有门时钟
,该门时钟主要是控制芯片内部各个模块的时钟使能标记。主要是为了降低功耗。如下:

我们在上文配置的ssi时钟其实配置的是SSI_CLK_ROOT,该时钟的主要作用是为了产生SSI作为I2S模式下作为
MASTER 时所需要用的TXC和TXFS时钟,而SSI模块正常工作的时钟是由ipg_clk_root所提供的, 而该时时钟是由AHB时钟2分频得到的。 具体应用如下:
所以上图中的World Clock和Serial Bit Clock都是由SSI's sys clock产生的。而SSI's sys clock对应的就是
SSI_CLK_ROOT时钟源。因此我们除配置完ssi模块工作在I2S模式下的协议时钟外,还需要配置SSI模块
正常工作的时钟,即配置CCM模块 的CGR5寄存器时钟SSI_CLK_ENABLE。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值