jieli:I2S外设是如何工作的?

1 什么是iis?

  iis 全称 inter-ic sound 集成电路音频总线;为板内通讯的数字音频串行总线;下图为iis的最小系统模式;ttl电平;

  MCLK(可选) Master Clock       >> 一些dac/adc外设自身没有晶振,需要外部sysclk;

  SCK(BLCK)   Serial Continuous Clock  >> 串行总线时钟;也称为bit clock;

  WS(LRCK)   Word Select        >> 传输音频字选择,0->chnLeft,1->chnRight;

                        一个音频点数据 = chnLeft +chnRight = 一个方波,LRCK频率 = Fs音频采样率;

  SD      Serial Data        >> 串行数据线;下降沿改变,上升沿采样;

  

  由图可知,SCK和WS由controller生成;发射器和接收器只针对SD线而不是指设备;

2 iis 计算时钟频率的公式都有哪些?

  MCLK = 256 × Fs , 384 × Fs , 512 × Fs;eg: 512 × 48kHz = 24.576Mhz

  BCLK = Fs × BitDepth × Channels = 48kHz * 16bits * 2ch = 1.536Mhz

  Frame bits = BitDepth × Channels

  Fs音频采样率:每秒内 模拟声音采集的次数,单位Hz;48kHz >> 48000Hz >>48000次;

3 jieli sdk的iis外设(ALNK)是咋工作的?

  ac696x内部包含两个alnk外设,相互独立,ac696x同时支持4chn输入和4chn输出;每条chn可独立配置为input和output;

  典型:ALNK有两种典型工作模式,64SCK和32SCK;

    64SCK:  >> 32bit位深采样,可以兼容16bit 24bit的模拟信号输入输出;

           24bit输入时,jieli会MSB对齐丢弃最低8bit;需要24bits输出时,jieli输出16bits,dac自行MSB对齐后低8bit补0;(这叫兼容)

    32SCK:  >> 16bit位深采样,不能兼容24bit 32bit信号;

  后续把硬件故障排查看下,写的还挺实在;

4 逻辑分析仪测试

  用逻辑分析仪测试SCLK,显示波形为 --160ns __160ns --170ns __160ns 周期性重复;

  逻辑分析仪采样率100Mhz,10ns采样一个点;3.072Mhz的方波为325ns一个,所以逻辑分析仪采样不到具体值;

  由于实际波形具有周期性,所以近似估算5个波形可知刚好是325ns;

  还可以导出csv文件,让AI统计实际波形数据;统计数据点多的话数据就比较准确了;

  

5 代码中是如何实现的呢?

复制代码
/********************************************************************
sdk的音频是如何从蓝牙到dac/iis播放的呢? 
输入的iis音频又是如何回传给通话的呢?
    蓝牙A2DP数据 → A2DP解码器 → 音频流处理链 → Mixer → DAC通道 → DAC硬件 → 模拟音频输出

    如果点击了播放之后,... >>a2dp_dec_start() >> 配置a2dp的音频链,然后输出到mixer;
    另外的mixer一开始就配置好了 ... >> audio_dec_init() >> 设置mixer的混音和dac;

********************************************************************
audio_dec_init() 是咋运行的呢?

    (&decode_task, "audio_dec")创建     >> 其他任务自行加进来的,先放着;
    outputDac 初始化                    >> 给耳机的dac
    硬件滤波初始化                       >> 也不知道啥用,采样率音频转换;

    mixer初始化                         >> 开mixer,回调注册; buff大小,声道数,采样率设置;
                                           mixer单独task输出, 自动mute,频响,等响,人声消除; >> 都没开;

    mixer pipeline设置                  >> 1 entries[entry_cnt++] = &mixer.entry; 
                                             entries[entry_cnt++] = ac反向器, 后续可删;
                                             entries[entry_cnt++] = 自动mute,频响,等响,人声消除; >> 都没开;
                                             entries[entry_cnt++] = 创建dac通道,直接输出到开发板的dac引脚;
                                             先 mixer.stream = audio_stream_open(&mixer, audio_mixer_stream_resume);
                                             再 audio_stream_add_list(mixer.stream, entries, entry_cnt);

                                           2 数字音量hdl初始化iis_digvol_last; 数字音量entry创建iis_digvol_last_entry;
                                             iisOutput外设初始化,              iisOutputEntry创建 iis_last_entry;
                                             entries[0] = 之前entries[]中dac前的一个entry;
                                             entries[entry_cnt++] = iis_digvol_last_entry;
                                             entries[entry_cnt++] = iis_last_entry;
                                             audio_stream_add_entry(entries[i], entries[i + 1]);3个entry串成audioStream;

    所以这个mixer是audioStream下行到iis
********************************************************************
那么音乐音频流是如何从手机 >> mixer 的呢?

1 当手机想要播放音乐的时候, >> appTask发送msg BT_STATUS_A2DP_MEDIA_START;
    //bt_event_func.c
    bt_status_a2dp_media_start() 
        __this->call_flag = 0;          >> &app_bt_hdl,声明在bt.c中, app_bt_opr 结构体在bt.h中;
        __this->a2dp_start_flag = 1;
        //audio_dec_bt.c
        a2dp_dec_open(解码的media_type); >> 给 a2dp_dec_hdl *bt_a2dp_dec(dec) 的结构体指针分配下内存,然后初始化参数;
                                        >> 只能选SCB或AAC dec,设置对应clk;
                                        >> dec->wait.handler = a2dp_wait_res_handler; 
                                        >> &dec->wait 加到 decode_task 中;
                                        >> 执行完毕,decode_task...&dec->wait...   
    a2dp_wait_res_handler(event)        >> 播放音乐->AUDIO_RES_GET, 执行 a2dp_dec_start();

2 a2dp_dec_start();                     >> a2dp_decoder_open(&dec->dec, &decode_task),
                                        >> &dec->xx 设置各解码相关参数,cb,各类音效设置都是在这里设置的;
                                        >> entries[entry_cnt++] = &dec->dec.decoder.entry;
                                                                  &解码结构体 -> a2dp解码句柄 . 解码器(解码通道) . 音频流入口节点
                                        >> entries[entry_cnt++] = dec->sync->entry; 时钟同步节点
                                        >> entries[entry_cnt++] = dec->sync->resample_entry; 动态重采样节点 rl_rr_entry_start
                                        >> ... ... 对应功能要是开了就加上 entries[entry_cnt++]
                                        >> entries[entry_cnt++] = &dec->mix_ch.entry;  最后节点是这个,后续看看是不是基于这里继续的;

                                        >> 先 dec->stream = audio_stream_open(dec, a2dp_dec_out_stream_resume);
                                        >> 再 audio_stream_add_list(dec->stream, entries, entry_cnt);
                                           ...先openStream并注册了a2dpResumeCB,再addEntry,所以不是在这里跑的,那么哪里跑的呢?先放着;
                                        >> a2dp_drop_frame_stop, 置位dec->dec.start, audio_decoder_start, clock_set_cur;

    此时,a2dpStream中的最后节点为 &dec->mix_ch.entry,decoder解码器的开始节点是 &mixer.entry;怎么对应上呢?
    大概是前者写到buff里,后者从buff里取出来把;
        audio_mixer_ch_open_head(&dec->mix_ch, &mixer);
            esco_dec_open(&bt->value, 0);
                bt_status_sco_change();
                    case>>BT_STATUS_SCO_STATUS_CHANGE;
                        正常第一遍应该是这样的,不过第一遍的时候我没看到调用,后续注意下;先放着;

********************************************************************
那么下行通话音频流是如何从 手机 >> mixer 的呢?



********************************************************************
那么上行通话音频流是如何从 iis >> 手机 的呢?



*/
相关推荐
rls_v4 天前
什么是蓝牙的信令测试
bluetooth
rls_v20 天前
AC696X-双模蓝牙功耗与时隙分析
bluetooth
rls_v21 天前
经典蓝牙音量同步机制
bluetooth
你怎么知道我是队长1 个月前
经典蓝牙(Classic Bluetooth / BR/EDR)--- 核心协议层5 --- 经典蓝牙(BR/EDR)服务发现层核心机制详解
bluetooth
你怎么知道我是队长1 个月前
经典蓝牙(Classic Bluetooth / BR/EDR)--- 核心协议层5 --- 经典蓝牙(BR/EDR)电缆替代协议层核心机制详解
bluetooth
你怎么知道我是队长1 个月前
经典蓝牙(Classic Bluetooth / BR/EDR)--- 核心协议层1 --- 经典蓝牙(BR/EDR)物理层核心机制详解
bluetooth
奔跑吧 android2 个月前
【Bluetooth-SIG】【CoreV6.2】【Vol3 Part G】【GATT】【零】【GATT 逐句逐段学习计划 2】
ble·bluetooth·att·gatt·core_v6.2·sig
奔跑吧 android2 个月前
【Bluetooth-SIG】【CoreV6.2】【Vol3 Part F】【十三】【Error Handling——ATT_ERROR_RSP】
ble·bluetooth·att·gatt·蓝牙协议·bt·core_v6.2
一渊之隔4 个月前
uniapp蓝牙搜索连接展示蓝牙设备包含信号显示
前端·网络·uni-app·bluetooth