Загрузка данных
int main(void)
{
const struct device *const i2s_dev_rx = DEVICE_DT_GET(I2S_RX_NODE);
const struct device *const i2s_dev_tx = DEVICE_DT_GET(I2S_TX_NODE);
struct i2s_config config_rx;
struct i2s_config config_tx;
bool streaming = false;
printk("I2S asynchronous Audio: SGTL5000 (RX) & TFA9882 (TX)\n");
const struct device *const rx_dev = DEVICE_DT_GET(DT_NODELABEL(rx_audio_codec));
const struct device *const tx_dev = DEVICE_DT_GET(DT_NODELABEL(tx_audio_codec));
struct audio_codec_cfg audio_cfg;
if (!device_is_ready(rx_dev) || !device_is_ready(tx_dev)) {
printk("Audio codecs are not ready\n");
return 0;
}
/* 1. RX Capture Config */
audio_cfg.dai_route = AUDIO_ROUTE_CAPTURE;
audio_cfg.dai_type = AUDIO_DAI_TYPE_I2S;
audio_cfg.dai_cfg.i2s.word_size = SAMPLE_BIT_WIDTH_RX;
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_BIT_CLK_SLAVE | I2S_OPT_FRAME_CLK_SLAVE;
audio_cfg.dai_cfg.i2s.frame_clk_freq = SAMPLE_FREQ_RX;
audio_cfg.dai_cfg.i2s.mem_slab = &mem_slab_rx;
audio_cfg.dai_cfg.i2s.block_size = BLOCK_SIZE_RX;
audio_cfg.mclk_freq = AUDIO_MCLK_FREQ;
audio_codec_configure(rx_dev, &audio_cfg);
/* 2. TX Playback Config */
audio_cfg.dai_route = AUDIO_ROUTE_PLAYBACK;
audio_cfg.dai_cfg.i2s.word_size = SAMPLE_BIT_WIDTH_TX;
audio_cfg.dai_cfg.i2s.frame_clk_freq = SAMPLE_FREQ_TX;
audio_cfg.dai_cfg.i2s.mem_slab = &mem_slab_tx;
audio_cfg.dai_cfg.i2s.block_size = BLOCK_SIZE_TX;
audio_codec_configure(tx_dev, &audio_cfg);
k_msleep(500);
if (!init_buttons()) return 0;
if (!device_is_ready(i2s_dev_rx) || !device_is_ready(i2s_dev_tx)) {
printk("SAI2 Devices are not ready\n");
return 0;
}
/* 3. Setings for I2S/SAI */
config_rx.word_size = SAMPLE_BIT_WIDTH_RX;
config_rx.channels = NUMBER_OF_CHANNELS;
config_rx.format = I2S_FMT_DATA_FORMAT_I2S;
config_rx.options = I2S_OPT_BIT_CLK_MASTER | I2S_OPT_FRAME_CLK_MASTER;
config_rx.timeout = TIMEOUT;
/* RX I2S config */
config_rx.frame_clk_freq = SAMPLE_FREQ_RX;
config_rx.mem_slab = &mem_slab_rx;
config_rx.block_size = BLOCK_SIZE_RX;
i2s_configure(i2s_dev_rx, I2S_DIR_RX, &config_rx);
/* TX I2S config */
config_tx = config_rx;
config_tx.word_size = SAMPLE_BIT_WIDTH_TX;
config_tx.frame_clk_freq = SAMPLE_FREQ_TX;
config_tx.mem_slab = &mem_slab_tx;
config_tx.block_size = BLOCK_SIZE_TX;
i2s_configure(i2s_dev_tx, I2S_DIR_TX, &config_tx);
#ifndef MY_CODE
/* 1. Set explicit volume to safe maximum level (100%) */
audio_property_value_t vol_val = { .vol = 100 };
audio_codec_set_property(tx_dev, AUDIO_PROPERTY_OUTPUT_VOLUME, AUDIO_CHANNEL_ALL, vol_val);
audio_codec_set_property(rx_dev, AUDIO_PROPERTY_INPUT_VOLUME, AUDIO_CHANNEL_ALL, vol_val);
/* 2. Explicitly disable output channel mutes */
audio_property_value_t mute_val = { .mute = false };
audio_codec_set_property(tx_dev, AUDIO_PROPERTY_OUTPUT_MUTE, AUDIO_CHANNEL_ALL, mute_val);
audio_codec_set_property(rx_dev, AUDIO_PROPERTY_INPUT_MUTE, AUDIO_CHANNEL_ALL, mute_val);
audio_codec_start_output(rx_dev);
#endif
if (!streaming) {
if (!prepare_transfer(i2s_dev_rx, i2s_dev_tx)) {
printk("Failed to prepare TX buffers\n");
}
if (!trigger_command(i2s_dev_rx, i2s_dev_tx, I2S_TRIGGER_START)) {
}
streaming = true;
printk("Stream started\n");
} else {
if (!trigger_command(i2s_dev_rx, i2s_dev_tx, I2S_TRIGGER_DROP)) {
}
streaming = false;
printk("Stream stopped\n");
}
/* 4. Main cycle */
while (streaming) {
void *rx_block = NULL;
void *tx_block = NULL;
size_t rx_size;
int ret;
/* Read RX (16 kHz) */
ret = i2s_read(i2s_dev_rx, &rx_block, &rx_size);
if (ret < 0) {
printk("i2s_read failed: %d\n", ret);
break;
}
/* Proccess rx data */
process_block_data(rx_block, SAMPLES_PER_BLOCK_RX);
#if 0
/* Allocate TX block(32 kHz) */
ret = k_mem_slab_alloc(&mem_slab_tx, &tx_block, K_NO_WAIT);
if (ret < 0) {
printk("Failed to allocate TX block: %d\n", ret);
k_mem_slab_free(&mem_slab_rx, rx_block);
break;
}
/* Upsample to 32kHz */
audio_upsample_to_32k((const int16_t *)rx_block, (int32_t *)tx_block,
NUMBER_OF_CHANNELS, SAMPLE_FREQ_RX);
k_mem_slab_free(&mem_slab_rx, rx_block);
/* Send to TX (32 kHz) */
ret = i2s_write(i2s_dev_tx, tx_block, BLOCK_SIZE_TX);
if (ret < 0) {
printk("i2s_write failed: %d\n", ret);
k_mem_slab_free(&mem_slab_tx, tx_block);
break;
}
#else
#if 0//ndef MY_CODE
int16_t *mas = rx_block;
for(int i=0; i<rx_size; i++)
{
if(mas[i] != 0)
printk("data[%d]=0x%X\n",i,mas[i]);
}
#endif
#if 0
ret = i2s_write(i2s_dev_tx, rx_block, rx_size);
if (ret < 0) {
printk("i2s_write failed: %d\n", ret);
//k_mem_slab_free(&mem_slab_tx, tx_block);
break;
}
#else
void *mem_block;
uint32_t block_size = 0;
/* If not using DMIC, play a sine wave 440Hz */
mem_block = (void *)&__16kHz16bit_stereo_sine_pcm;
block_size = __16kHz16bit_stereo_sine_pcm_len;
ret = i2s_buf_write(i2s_dev_tx, mem_block, block_size);
#endif
#endif
}
return 0;
}