1.13. APA
APA接口包括该模块的初始化,关闭,模拟部分的开关,音量的控制等,相关接口可通过结构体apa_driver进行调用。该系列APA支持16bit精度,单声道。
1.13.1. APA接口
static const struct apa_driver apa_drv_ins = {
.open = __apa_open, //初始化APA
.close = __apa_close, //关闭APA
.analog_open = __apa_analog_open, //打开APA的模拟部分
.analog_close = __apa_analog_close, //关闭APA的模拟部分
.ioctrl = __apa_ioctl, //音量、采样率、中断配置接口
.vol_ctrl = __apa_digital_vol_ctrl, //音量控制接口
};
const struct apa_driver *apa_drv = &apa_drv_ins;
1.13.2. APA初始化
1.13.2.1. 传入参数
#define APA_CLK_320M 1
#define APA_CLK_240M 2 //default
#define APA_CLK_HSB 3
#define APA_PWM_MODE 0 //APA输出音频信号
#define APA_IO_MODE 1 //APA做IO输出高低电平
#define APA_PWM_MODE1 0 //APA_PWM 调制模式1(单端/差分,推荐单端)
#define APA_PWM_MODE2 1 //APA_PWM 调制模式2(差分)
typedef struct _APA_INF {
u8 apa_p_mode; //APA_P端的模式(APA_PWM_MODE/APA_IO_MODE)
u8 apa_n_mode; //APA_P端的模式(APA_PWM_MODE/APA_IO_MODE)
u8 pwm_mode; //APA_PWM调制模式(APA_PWM_MODE1/APA_PWM_MODE2)
u8 pwm_clk; //APA时钟(APA_CLK_320M/APA_CLK_240M/APA_CLK_HSB)
u16 def_sr; //默认采样率(32K/44.1K/48K)
apa_func apa_input; //APA中断回调处理G
u8 dcc_en; //直流滤波器使能
void *priv;
} APA_INF;
1.13.2.2. 使用方法
#include "apa_api.h"
apa_input(void *priv, void *apa_buf, u32 len){
//*apa_buf:可写入的首地址
//len:可写入数据长度(字节数);
}
APA_INF apa_inf;
apa_inf.def_sr = 44100;
apa_inf.pwm_mode = APA_PWM_MODE2;
apa_inf.pwm_clk = APA_CLK_240M;
apa_inf.apa_input = (apa_func)apa_input;
apa_inf.apa_p_mode = APA_PWM_MODE;
apa_inf.apa_n_mode = APA_PWM_MODE;
apa_inf.dcc_en = 1;
/* apa_inf.apa_n_mode = APA_IO_MODE; */
apa_drv->open(&apa_inf);
1.13.3. APA关闭
关闭APA的数字部分和模拟部分
1.13.3.1. 使用方法
apa_drv->close(void);
1.13.4. APA打开模拟部分
该接口只会打开APA的模拟部分,不会对APA的数字部分进行操作。可配合apa_drv->analog_close()使用
1.13.4.1. 使用方法
apa_drv->analog_open(void);
1.13.5. APA关闭模拟部分
该接口只会关闭APA的模拟部分,不会对APA的数字部分进行操作。可配合apa_drv->analog_open()使用,减少不需要播放信号时的功耗。
1.13.5.1. 使用方法
apa_drv->analog_close(void);
1.13.6. APA音量、采样率、中断配置接口
该接口通过传入的命令和参数判断需要执行的功能(音量的初始化、采样率设置/获取、中断的开关)
1.13.6.1. 传入参数
enum { //传入参数 功能解释
APA_REG_VOL_TAB,//u16 * 注册音量表
APA_GET_MAX_VOL,//u8 * 获取最大音量
APA_SET_MAX_VOL,//u8 * 设置最大音量
APA_GET_CUR_VOL,//u8 * 获取当前音量
APA_SET_CUR_VOL,//u8 * 设置当前音量
APA_CLR_DMA_BUF,//NULL 清除DMABUF数据
APA_SET_SR, //u16 * 设置采样率
APA_GET_SR, //u16 * 获取采样率
APA_IE_CTL, //u8 * 控制IE
};
1.13.6.2. 使用方法
#define MAX_SYS_VOL (31) //最大音量等级
#define DEFUAL_SYS_VOL (MAX_SYS_VOL) //系统默认音量
#define APA_DEFAULT_SR (32000) //apa初始化的采样率
const u16 digital_vol_tab[MAX_SYS_VOL + 1] = {
0, 93, 111, 132, 158, 189, 226, 270, 323, 386, //9
462, 552, 660, 789, 943, 1127, 1347, 1610, 1925, 2301, //19
2751, 3288, 3930, 4698, 5616, 6713, 8025, 9592, 11466, 15200, //29
16000, 16384 //31
};
u8 vol = DEFUAL_SYS_VOL;
apa_drv->ioctrl((void *)&vol, APA_SET_MAX_VOL); //设置最大音量
apa_drv->ioctrl((void *)&vol, APA_SET_CUR_VOL); //设置当前音量
apa_drv->ioctrl((void *)digital_vol_tab, APA_REG_VOL_TAB); //注册音量表
u16 def_sr = APA_DEFAULT_SR;
u16 cur_sr = 0;
apa_drv->ioctrl((void *)&def_sr, APA_SET_SR); //设置采样率
apa_drv->ioctrl((void *)&cur_sr, APA_GET_SR); //获取当前音量到cur_sr中
apa_drv->ioctrl((void *)NULL, APA_CLR_DMA_BUF); //清除DMABUF数据
u8 ie_en = 0;
apa_drv->ioctrl((void *)&ie_en, APA_IE_CTL); //通过ie_en控制中断
1.13.7. APA音量控制接口
通过ioctrl完成音量表、最大音量和当前音量的设置后,将需要播放的数据传入该接口,便能实现音量控制。
1.13.7.1. 使用方法
apa_drv->vol_ctrl(apa_buf, buf_len);
1.13.8. APA使用案例
#define MAX_SYS_VOL (31) //最大音量等级
#define DEFUAL_SYS_VOL (MAX_SYS_VOL) //系统默认音量
const u16 digital_vol_tab[MAX_SYS_VOL + 1] = {
0, 93, 111, 132, 158, 189, 226, 270, 323, 386, //9
462, 552, 660, 789, 943, 1127, 1347, 1610, 1925, 2301, //19
2751, 3288, 3930, 4698, 5616, 6713, 8025, 9592, 11466, 15200, //29
16000, 16384 //31
};
u16 apa_cnt;
extern int get_sine_data(u16 *s_cnt, s16 *data, u16 points, u8 ch);//数据替换
static void apa_write(void *priv, void *data, u32 len)
{
get_sine_data(&apa_cnt, data, len / 2, 1);//将数据替换为44.1K采样率的1k正弦波用于测试。
apa_drv->vol_ctrl(data, len);
}
void apa_test_demo()
{
u8 vol = DEFUAL_SYS_VOL;
apa_drv->ioctrl((void *)&vol, APA_SET_MAX_VOL); //设置最大音量
apa_drv->ioctrl((void *)&vol, APA_SET_CUR_VOL); //设置当前音量
apa_drv->ioctrl((void *)digital_vol_tab, APA_REG_VOL_TAB); //注册音量表
APA_INF apa_inf;
apa_inf.def_sr = 44100;
apa_inf.pwm_mode = APA_PWM_MODE2;
apa_inf.pwm_clk = APA_CLK_240M;
apa_inf.apa_input = (apa_func)apa_write;
apa_inf.apa_p_mode = APA_PWM_MODE;
apa_inf.apa_n_mode = APA_PWM_MODE;
apa_inf.dcc_en = 1;
apa_drv->open(&apa_inf);
u8 ie_en = 1;
apa_drv->ioctrl((void*)&ie_en, APA_IE_CTL);//使能APA中断
while(1){
mdelay(5);
}
}
1.13.9. APA特殊用法
APA除了用于播放音频信号,还可以作为普通IO输出高低电平
#define MAX_SYS_VOL (31)
#define DEFUAL_SYS_VOL (MAX_SYS_VOL)
const u16 digital_vol_tab[MAX_SYS_VOL + 1] = {
0, 93, 111, 132, 158, 189, 226, 270, 323, 386,
462, 552, 660, 789, 943, 1127, 1347, 1610, 1925, 2301,
2751, 3288, 3930, 4698, 5616, 6713, 8025, 9592, 11466, 15200,
16000, 16384
};
static void apa_write(void *priv, void *data, u32 len)
{
apa_drv->vol_ctrl(data, len);
}
void apa_test_demo()
{
u8 vol = DEFUAL_SYS_VOL;
apa_drv->ioctrl((void *)&vol, APA_SET_MAX_VOL);
apa_drv->ioctrl((void *)&vol, APA_SET_CUR_VOL);
apa_drv->ioctrl((void *)digital_vol_tab, APA_REG_VOL_TAB);
APA_INF apa_inf;
apa_inf.def_sr = 44100;
apa_inf.pwm_mode = APA_PWM_MODE2;
apa_inf.pwm_clk = APA_CLK_240M;
apa_inf.apa_input = (apa_func)apa_write;
apa_inf.apa_p_mode = APA_IO_MODE; //APA_P端IO模式
apa_inf.apa_n_mode = APA_IO_MODE; //APA_N端IO模式
apa_inf.dcc_en = 0;
apa_drv->open(&apa_inf);
while(1){
set_apap_output_status(1);//P端输出高电平
set_apan_output_status(1);//N端输出高电平
mdelay(5000);
set_apap_output_status(1);//P端输出低电平
set_apan_output_status(1);//N端输出低电平
}
}