i2s1_rx: &sai2 {
nxp,rx-sync-mode;
status = "okay";
};
i2s1_tx: &sai2 {
status = "okay";
mclk-output;
};
i2s0_rx: &sai3 {
nxp,rx-sync-mode;
status = "okay";
};
i2s0_tx: &sai3 {
status = "okay";
mclk-output;
};
/* Configure Data Path via SAI2 */
&sai2 {
status = "okay";
pinctrl-0 = <&pinmux_sai2>;
pinctrl-names = "default";
mclk-output;
nxp,tx-channel = <1>;
};
&sai3 {
status = "okay";
pinctrl-0 = <&pinmux_sai3>;
pinctrl-names = "default";
mclk-output;
nxp,tx-channel = <1>;
};
&lpi2c1 {
status = "okay";
pinctrl-0 = <&pinmux_lpi2c1>;
pinctrl-names = "default";
/* Instantiate the SGTL5000 codec driver */
rx_audio_codec: sgtl5000@a {
compatible = "nxp,sgtl5000";
reg = <0x0a>;
pinctrl-0 = <&pinmux_sgtl5000_mclk>;
pinctrl-names = "default";
bus_sai = <&sai2>;
clocks = <&ccm IMX_CCM_SAI2_CLK 0x7C 20>;
clock-names = "mclk";
status = "okay";
};
audio_codec: wm8960@1a {
compatible = "wolfson,wm8960";
reg = <0x1a>;
clocks = <&ccm IMX_CCM_SAI3_CLK 0x7C 18>;
clock-names = "mclk";
};
};
zephyr_i2s_dev.c:
#define I2S_RX_NODE DT_NODELABEL(i2s0_rx)
#define I2S_TX_NODE DT_NODELABEL(i2s0_tx)
static const struct device *const i2s_dev_rx = DEVICE_DT_GET(I2S_RX_NODE);
static const struct device *const i2s_dev_tx = DEVICE_DT_GET(I2S_TX_NODE);
static const struct device *const codec_dev = DEVICE_DT_GET(DT_NODELABEL(audio_codec));
int zephyr_i2s_open_stream(I2S_Stream **stream, uint8_t *buf, uint8_t audio_in)
{
struct i2s_strm *i2s_stream;
struct i2s_config config;
int ret = 0;
uint32_t dynamic_block_size = ((current_sample_rate / ZEPHYR_AUDIO_DIV_SIZE) * NUMBER_OF_CHANNELS * BYTES_PER_SAMPLE);
current_audio_block_size = dynamic_block_size;
struct audio_codec_cfg audio_cfg;
audio_cfg.dai_route = AUDIO_ROUTE_PLAYBACK_CAPTURE;
audio_cfg.dai_type = AUDIO_DAI_TYPE_I2S;
audio_cfg.dai_cfg.i2s.word_size = SAMPLE_BIT_WIDTH;
audio_cfg.dai_cfg.i2s.channels = NUMBER_OF_CHANNELS;
audio_cfg.dai_cfg.i2s.format = I2S_FMT_DATA_FORMAT_I2S;
audio_cfg.dai_cfg.i2s.options = I2S_OPT_FRAME_CLK_MASTER;
audio_cfg.dai_cfg.i2s.frame_clk_freq = current_sample_rate;
audio_cfg.dai_cfg.i2s.mem_slab = &mem_slab_tx;
audio_cfg.dai_cfg.i2s.block_size = dynamic_block_size;
audio_cfg.mclk_freq = AUDIO_MCLK_FREQ;
audio_codec_configure(codec_dev, &audio_cfg);
config.word_size = SAMPLE_BIT_WIDTH;
config.channels = NUMBER_OF_CHANNELS;
config.format = I2S_FMT_DATA_FORMAT_I2S;
config.options = I2S_OPT_BIT_CLK_MASTER | I2S_OPT_FRAME_CLK_MASTER;
config.frame_clk_freq = current_sample_rate;
config.block_size = dynamic_block_size;
config.timeout = TIMEOUT;
if (!configure_streams(i2s_dev_rx, i2s_dev_tx, &config)) {
printf("Failed to reconfigure streams for %u Hz\n", current_sample_rate);
return -1;
}
Надо сделать динамическое переключение аудио устройств:
1) i2s0_rx,i2s0_tx,audio_codec
2) i2s1_rx,i2s1_tx,rx_audio_codec
Через какие-то extern настройки например, которые можно менять