最近做的项目遇到的问题,主要输入信号有GT(吉他)、USB audio、BT、WIFI、AUX等,我用一个旋钮来调音量,发现调音量功放输出到喇叭存在跳动的噪音。
在查看datesheet看到了sofeware safeload,如下:
To update parameters in real time while avoiding pop and click noises on the output, a software safeload mechanism has been
implemented by default in the SigmaStudio compiler.
实时更新参数,同时避免弹出和点击对输出噪声,有软件安全加载机制在SigmaStudio编译器中默认实现。这不刚好可以尝试用这个方法去解决。
SigmaStudio automatically sets up the necessary code and parameters for all new projects. The safeload code, together
with other initialization code, fills the beginning section of program RAM. Several datamemory locations are reserved by
the compiler for use with the software safeload feature. The exact parameter addresses are not fixed, so the addresses must
be obtained by reading the log file generated by the compiler. In most cases, the addresses for softwaresafeload parameters
match the defaults shown in Table 58
SigmaStudio自动设置所有必要的代码和参数新项目。安全加载代码,以及其他初始化代码,填充程序内存的开始部分。几个数据方法所使用的内存位置由编译器保留软件安全加载功能。确切的参数地址不是固定,因此必须通过读取日志文件来获取地址由编译器生成。在大多数情况下,地址用于软件安全加载参数匹配表58中所示的默认值。
看到上面这句话我第一时间是去看sigmastudio生成的三个头文件。生成的后缀是PARM.h带有定义safeload的地址。
/* Module SafeLoadModule - SafeLoadModule*/
#define MOD_SAFELOADMODULE_COUNT 6
#define MOD_SAFELOADMODULE_DEVICE "IC1"
#define MOD_SAFELOADMODULE_DATA_SAFELOAD0_ADDR 456
#define MOD_SAFELOADMODULE_DATA_SAFELOAD1_ADDR 457
#define MOD_SAFELOADMODULE_DATA_SAFELOAD2_ADDR 458
#define MOD_SAFELOADMODULE_DATA_SAFELOAD3_ADDR 459
#define MOD_SAFELOADMODULE_DATA_SAFELOAD4_ADDR 460
#define MOD_SAFELOADMODULE_ADDRESS_SAFELOAD_ADDR 461
实现代码思路
1、从data_SafeLoad位0开始,将所需数据写入data_SafeLoad,最多五个参数
2、将所需的起始目标地址写入address_SafeLoad参数
3、将需要传输的字数写入num_SafeLoad参数,最小写入长度为1个字,最大写入长度为5个字
4、等待一个音频帧的时间(做适当的延时)以完成安全加载操作
void adau1452_vol_total(uint8_t vol)
{
if(vol>=SYS_MAX_VOL)
vol = SYS_MAX_VOL-1;
#ifndef ADAU1452_TUNING_ONLINE_ENABLE
//adau1452_spi_write(ADAU1452_VOL_TOTAL_ADDRESS,(uint8_t *)&ADAU1452_VOLUME_TAB[M_Vol_Tab[vol]][0],4);
SafeloadSingleParamWrite(ADAU1452_VOL_TOTAL_ADDRESS,(uint8_t *)&ADAU1452_VOLUME_TAB[M_Vol_Tab[vol]][0],1);
#endif
}
/**
* @brief Write data to ADAU1452 using safeload mode via SPI bus.
* @param address The write register address
* @param param The write register data pointer
* @retval None
*/
void SafeloadSingleParamWrite(uint32_t address, uint8_t *param, uint32_t safeload_num)
{
Write_Safeload_Parameter(SAFELOAD_DATA_0, param);
Write_Safeload_addr(address);
Write_Safeload_number(1); //start the safeload transfer
DelayMs(1); //At a sample rate of 48 kHz, this equates to a delay of >20.83 us
}
1、从data_SafeLoad位0开始,将所需数据写入data_SafeLoad,最多五个参数
/**
* @brief Write data to ADAU1452 using safeload mode via SPI bus.
* @param safe_param The write safeload parameter
* @param param_data The write safeload data pointer
* @retval None
*/
static void Write_Safeload_Parameter(uint16_t safe_param, unsigned char* param_data)
{
uint8_t safe_param_lo;
uint8_t safe_param_hi;
safe_param_hi = (uint8_t)(safe_param>>8);
safe_param_lo = (uint8_t)safe_param;
ADAU1452SPI_CS_Low();
ADAU1452SpiSendByte(ADAU1452_ADDRESS|ADAU1452_WR_CMD);
ADAU1452SpiSendByte(safe_param_hi);
ADAU1452SpiSendByte(safe_param_lo);
ADAU1452SpiSendByte(param_data[0]); //Write parameter byte 4 (MSBs)
ADAU1452SpiSendByte(param_data[1]);
ADAU1452SpiSendByte(param_data[2]);
ADAU1452SpiSendByte(param_data[3]);
//ADAU1452SpiSendByte(param_data[4]); //Write parameter byte 1 (LSBs)
ADAU1452SPI_CS_High();
#ifdef ADAU1452_INTERFACE_DEBUG
DBG_PRINTF("ADAU1452 write safeload parameter:0x%02x 0x%02x",safe_param_hi,safe_param_lo);
DBG_PRINTF(" 0x%02x 0x%02x 0x%02x 0x%02x\n\r",param_data[0],param_data[1],param_data[2],param_data[3]);
#endif
}
2、将所需的起始目标地址写入address_SafeLoad参数
/**
* @brief Write data to ADAU1452 safeload address via SPI bus.
* @param param_addr The write safeload parameter address
* @retval None
*/
static void Write_Safeload_addr(uint32_t param_addr)
{
uint8_t address_lo;
uint8_t address_hi;
address_hi = (uint8_t)((SAFELOAD_ADDRESS)>>8);
address_lo = (uint8_t)(SAFELOAD_ADDRESS);
#ifdef ADAU1452_INTERFACE_DEBUG
DBG_PRINTF("ADAU1452 write safeload addr:0x%02x 0x%02x",address_hi,address_lo);
#endif
ADAU1452SPI_CS_Low();
ADAU1452SpiSendByte(ADAU1452_ADDRESS|ADAU1452_WR_CMD);
ADAU1452SpiSendByte(address_hi);
ADAU1452SpiSendByte(address_lo);
ADAU1452SpiSendByte((uint8_t)param_addr>>24);
ADAU1452SpiSendByte((uint8_t)param_addr>>16);
ADAU1452SpiSendByte((uint8_t)param_addr>>8);
ADAU1452SpiSendByte((uint8_t)param_addr);
ADAU1452SPI_CS_High();
#ifdef ADAU1452_INTERFACE_DEBUG
//DBG_PRINTF(" 0x%02x 0x%02x\n\r",address_hi,address_lo);
DBG_PRINTF(" 0x%08x\n\r",param_addr);
#endif
}
3、将需要传输的字数写入num_SafeLoad参数,最小写入长度为1个字,最大写入长度为5个字
/**
* @brief Write data to ADAU1452 safeload numver register via SPI bus.
* @param param_number The safeload write/read number
* @retval None
*/
#if 1
static void Write_Safeload_number(uint32_t param_number)
{
uint8_t address_lo;
uint8_t address_hi;
address_hi = (uint8_t)((NUM_SAFELOAD+1)>>8);
address_lo = (uint8_t)(NUM_SAFELOAD+1);
#ifdef ADAU1452_INTERFACE_DEBUG
DBG_PRINTF("ADAU1452 write safeload num:0x%02x 0x%02x",address_hi,address_lo);
#endif
ADAU1452SPI_CS_Low();
ADAU1452SpiSendByte(ADAU1452_ADDRESS|ADAU1452_WR_CMD);
ADAU1452SpiSendByte(address_hi);
ADAU1452SpiSendByte(address_lo);
ADAU1452SpiSendByte((uint8_t)param_number>>24);
ADAU1452SpiSendByte((uint8_t)param_number>>16);
ADAU1452SpiSendByte((uint8_t)param_number>>8);
ADAU1452SpiSendByte((uint8_t)param_number);
ADAU1452SPI_CS_High();
#ifdef ADAU1452_INTERFACE_DEBUG
//DBG_PRINTF(" 0x%02x 0x%02x\n\r",address_hi,address_lo);
DBG_PRINTF(" 0x%08x\n\r",param_number);
#endif
}
#endif
4、等待一个音频帧的时间(做适当的延时)以完成安全加载操作
#define DelayMs(x) HAL_Delay(x)