QCC3008项目实战:BlueVest体感背心

为了方便大家学习,现与我爱蓝牙网联合推出【QCC300x/CSR867x/QCC30xx/QCC51xx开发板】。

技术交流QQ群号:743434463
开发板会员QQ群号:725398389(凭订单号入群,赠独家学习资料)
——————————正文分割线———————————–

1. 引言

BlueVest体感背心是虚拟现实增强设备的一种,可以让用户真实感受到枪击或被怪物攻击的振动。
QCC3008项目实战:BlueVest体感背心_第1张图片
体感背心一般由背心主体、振动装置、驱动装置、音频处理单元组成。常见的体感背心的工作原理是,当有音频信号输入音频处理单元后,增强与振动相关的音频信号频率分量,由驱动装置使振动装置起振,穿戴者即可感受到击打、枪击的振动效果。此类型产品的优点是泛用性较好,可无缝接入各家VR平台,整体方案成本较低;缺点是振动位置数量较少,不能产生手臂、头部、背部位置的振动,沉浸感较低。

2. 主要功能

  • 3.5mm接口输入/USB输入/蓝牙输入
  • 线控耳机接入免提通话
  • 音乐音量/振动强度调节

体感背心系统框图如下:
QCC3008项目实战:BlueVest体感背心_第2张图片
硬件平台的核心器件是CSR8670、LM4811、TAS5731。CSR8670负责蓝牙连接、电源管理、音频处理、外设驱动;LM4811负责驱动有线耳机;TAS5731负责增强与振动相关的频率分量,驱动振动马达产生振动。

3. 项目难点

3.1. 配置QCC3008同时输出I2S和AUX OUT

QCC3008支持multi-channel output,需分别配置configure tool和UFE:
QCC3008项目实战:BlueVest体感背心_第3张图片
QCC3008项目实战:BlueVest体感背心_第4张图片
QCC3008项目实战:BlueVest体感背心_第5张图片

3.2. LM4811的驱动

驱动部分包含使能LM4811和通过PIO进行音量控制:

#define LM4811_CLOCK_PIO		8
#define LM4811_UPDN_PIO			1

static void lm4811_init(void)
{
	PioSetPio(LM4811_UPDN_PIO,pio_drive,FALSE);
	PioSetPio(LM4811_CLOCK_PIO,pio_drive,FALSE);
}

static void lm4811_vol_up(void)
{
	PioSetPio(LM4811_UPDN_PIO,pio_drive,TRUE);
	PioSetPio(LM4811_CLOCK_PIO,pio_drive,TRUE);
	PioSetPio(LM4811_CLOCK_PIO,pio_drive,FALSE);
	PioSetPio(LM4811_UPDN_PIO,pio_drive,FALSE);
}

static void lm4811_vol_down(void)
{
	PioSetPio(LM4811_UPDN_PIO,pio_drive,FALSE);
	PioSetPio(LM4811_CLOCK_PIO,pio_drive,TRUE);
	PioSetPio(LM4811_CLOCK_PIO,pio_drive,FALSE);
	PioSetPio(LM4811_UPDN_PIO,pio_drive,FALSE);
}

3.3. TAS5731的驱动

驱动部分包含初始化,音量控制,错误检查:

#define TAS5731_VOL_DEFAULT		0x30	/* 0dB */
#define TAS5731_VOL_MAX			0x00	/* 24dB*/
#define TAS5731_VOL_MIN			0x90	/* -48dB */
#define TAS5731_VOL_STEP_SIZE	6		/* 3dB */

static uint8_t vol = TAS5731_VOL_DEFAULT;

static void tas5731_vol_up(void)
{
	if (vol >= (TAS5731_VOL_MAX+TAS5731_VOL_STEP_SIZE))
	{
		vol -= TAS5731_VOL_STEP_SIZE;
	}
	tas5731_i2c_write_one_byte(TAS5731_I2C_ADDR,0x07,vol);	
}

static void tas5731_vol_down(void)
{
	if (vol < TAS5731_VOL_MIN)
	{
		vol += TAS5731_VOL_STEP_SIZE;
	}
	tas5731_i2c_write_one_byte(TAS5731_I2C_ADDR,0x07,vol);	
}

const uint8_t tas5731_reg20_val[] = {0x20,0x00,0x01,0x77,0x72};

static void tas5731_init(void)
{
	/*tas5731_i2c_read_one_byte(TAS5731_I2C_ADDR,0x00,&val);*/
	
	tas5731_i2c_write_one_byte(TAS5731_I2C_ADDR,0x1B,0x00);
	
	......
	
	tas5731_i2c_bulkwrite(TAS5731_I2C_ADDR,(uint8_t *)tas5731_reg20_val,sizeof(tas5731_reg20_val));
	
	tas5731_i2c_write_one_byte(TAS5731_I2C_ADDR,0x05,0x00);
	tas5731_i2c_write_one_byte(TAS5731_I2C_ADDR,0x07,vol);
	
	MessageSendLater(&theSink.task, EventUsrUnused40CD, 0, 1000);
}

static void tas5731_check_error(void)
{
	uint8_t val;

	tas5731_i2c_write_one_byte(TAS5731_I2C_ADDR,0x02,0x00);
	
	tas5731_i2c_read_one_byte(TAS5731_I2C_ADDR,0x02,&val);

	if (val)
	{
		tas5731_init();
	}
	MessageSendLater(&theSink.task, EventUsrUnused40CD, 0, 1000);
}

void tas5731_soft_mute(void)
{
	tas5731_i2c_write_one_byte(TAS5731_I2C_ADDR,0x07,0xff);	
}

void tas5731_soft_unmute(void)
{
	tas5731_i2c_write_one_byte(TAS5731_I2C_ADDR,0x07,vol);	
}

static void tas5731_deinit(void)
{
	MessageCancelAll(&theSink.task,EventUsrUnused40CD);
}

3.4. 播放提示音时只能听到单声道

需载入sbc编码格式的提示音文件,码率需要128000,否则会破音。

4. 总结

项目本身难度不是很大,产品形态较新颖。侧面看出QCC3008的潜能还是可以挖掘的,在不需要修改DSP的方案中,QCC3008的性价比较CSR8670更高。后续可以探索将source的AGHFP功能移植到QCC300X系列,可尝试低成本的语音对讲方案。

你可能感兴趣的:(蓝牙方案,CSR8670蓝牙芯片软件开发)