21ic问答首页 - GD32H757XXX 的USB Audio通过I2S传输音频问题
GD32H757XXX 的USB Audio通过I2S传输音频问题
当选择的是"I2S1"后播放音频,对应管脚示波器测量波形正常,但配置为其他几个I2S(I2S0, I2S2, I2S5) 后每个管脚的波形都出不来, 时钟和对应的管脚选择上都核对没问题, 找不到什么原因。
void codec_audio_interface_init(uint32_t audio_freq){
i2s_audiofreq = audio_freq;
/* enable the AD_I2S peripheral clock */
rcu_periph_clock_enable(AD_I2S_CLK);
rcu_spi_clock_config(IDX_SPI1, RCU_SPISRC_PLL0Q);
/* AD_I2S peripheral configuration */
spi_i2s_deinit(AD_I2S);
/* initialize the I2S peripheral with the structure above */
i2s_psc_config(AD_I2S, audio_freq, I2S_FRAMEFORMAT_DT16B_CH16B,
#ifdef IIS_MCLK_ENABLED
I2S_MCKOUT_ENABLE
#elif defined(IIS_MCLK_DISABLED)
I2S_MCKOUT_DISABLE
#endif /* IIS_MCLK_ENABLED */
);
i2s_init(AD_I2S, I2S_MODE_MASTERTX, I2S_STD_MSB, I2S_CKPL_HIGH);
/* enable the I2S DMA TX request */
spi_dma_enable(AD_I2S, SPI_DMA_TRANSMIT);
}
void codec_gpio_init(void)
{
/* enable GPIO clock */
rcu_periph_clock_enable(AD_I2S_WS_CLK);
rcu_periph_clock_enable(AD_I2S_SCK_CLK);
rcu_periph_clock_enable(AD_I2S_SD_CLK);
rcu_periph_clock_enable(RCU_SYSCFG);
/* AD_I2S pins configuration: WS, SCK and SD pins */
gpio_mode_set(AD_I2S_WS_GPIO, GPIO_MODE_AF, GPIO_PUPD_NONE, AD_I2S_WS_PIN);
gpio_output_options_set(AD_I2S_WS_GPIO, GPIO_OTYPE_PP, GPIO_OSPEED_85MHZ, AD_I2S_WS_PIN);
gpio_af_set(AD_I2S_WS_GPIO, GPIO_AF_5, AD_I2S_WS_PIN);
gpio_mode_set(AD_I2S_SCK_GPIO, GPIO_MODE_AF, GPIO_PUPD_NONE, AD_I2S_SCK_PIN);
gpio_output_options_set(AD_I2S_SCK_GPIO, GPIO_OTYPE_PP, GPIO_OSPEED_85MHZ, AD_I2S_SCK_PIN);
gpio_af_set(AD_I2S_SCK_GPIO, GPIO_AF_5, AD_I2S_SCK_PIN);
gpio_mode_set(AD_I2S_SD_GPIO, GPIO_MODE_AF, GPIO_PUPD_NONE, AD_I2S_SD_PIN);
gpio_output_options_set(AD_I2S_SD_GPIO, GPIO_OTYPE_PP, GPIO_OSPEED_85MHZ, AD_I2S_SD_PIN);
gpio_af_set(AD_I2S_SD_GPIO, GPIO_AF_5, AD_I2S_SD_PIN);
#ifdef IIS_MCLK_ENABLED
/* enable GPIO clock */
rcu_periph_clock_enable(AD_I2S_MCK_CLK);
/* codec_i2s pins configuration: MCK pin */
gpio_mode_set(AD_I2S_MCK_GPIO, GPIO_MODE_AF, GPIO_PUPD_NONE, AD_I2S_MCK_PIN);
gpio_output_options_set(AD_I2S_MCK_GPIO, GPIO_OTYPE_PP, GPIO_OSPEED_85MHZ, AD_I2S_MCK_PIN);
gpio_af_set(AD_I2S_MCK_GPIO, GPIO_AF_5, AD_I2S_MCK_PIN);
#endif /* IIS_MCLK_ENABLED */
}
void codec_dma_init(void)
{
/* enable the DMA clock */
rcu_periph_clock_enable(AD_DMA_CLOCK);
rcu_periph_clock_enable(RCU_DMAMUX);
/* configure the DMA Stream */
dma_channel_enable(AD_DMA, AD_DMA_CHANNEL);
dma_deinit(AD_DMA, AD_DMA_CHANNEL);
dma_single_data_para_struct_init(&dma_initstructure);
/* set the parameters to be configured */
dma_initstructure.request = DMA_REQUEST_SPI1_TX;
dma_initstructure.periph_addr = AD_I2S_ADDRESS;
dma_initstructure.memory0_addr = (uint32_t)0; /* this field will be configured in play function */
dma_initstructure.direction = DMA_MEMORY_TO_PERIPH;
dma_initstructure.number = (uint32_t)0xFFFE; /* this field will be configured in play function */
dma_initstructure.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
dma_initstructure.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
dma_initstructure.periph_memory_width = AD_DMA_PERIPH_DATA_SIZE;
dma_initstructure.circular_mode = DMA_CIRCULAR_MODE_DISABLE;
dma_initstructure.priority = DMA_PRIORITY_ULTRA_HIGH;
dma_single_data_mode_init(AD_DMA, AD_DMA_CHANNEL, &dma_initstructure);
/* clear the DMA flags */
dma_flag_clear(AD_DMA, AD_DMA_CHANNEL, DMA_FLAG_FEE);
dma_flag_clear(AD_DMA, AD_DMA_CHANNEL, DMA_FLAG_SDE);
dma_flag_clear(AD_DMA, AD_DMA_CHANNEL, DMA_FLAG_TAE);
dma_flag_clear(AD_DMA, AD_DMA_CHANNEL, DMA_FLAG_HTF);
dma_flag_clear(AD_DMA, AD_DMA_CHANNEL, DMA_FLAG_FTF);
/* enable the selected DMA interrupts */
dma_interrupt_enable(AD_DMA, AD_DMA_CHANNEL, DMA_CHXCTL_FTFIE);
/* enable the I2S DMA request */
spi_dma_enable(AD_I2S, SPI_DMA_TRANSMIT);
/* I2S DMA IRQ channel configuration */
nvic_irq_enable(AD_DMA_IRQ, AD_IRQ_PREPRIO, AD_IRQ_SUBRIO);
}
void audio_play(uint32_t addr, uint32_t size)
{
/* disable the I2S DMA Stream*/
dma_channel_disable(AD_DMA, AD_DMA_CHANNEL);
/* clear the DMA flags */
dma_flag_clear(AD_DMA, AD_DMA_CHANNEL, DMA_FLAG_FEE);
dma_flag_clear(AD_DMA, AD_DMA_CHANNEL, DMA_FLAG_SDE);
dma_flag_clear(AD_DMA, AD_DMA_CHANNEL, DMA_FLAG_TAE);
dma_flag_clear(AD_DMA, AD_DMA_CHANNEL, DMA_FLAG_HTF);
dma_flag_clear(AD_DMA, AD_DMA_CHANNEL, DMA_FLAG_FTF);
/* configure the buffer address and size */
dma_initstructure.memory0_addr = (uint32_t)addr;
dma_initstructure.number = (uint32_t)(size);
/* configure the DMA Stream with the new parameters */
dma_single_data_mode_init(AD_DMA, AD_DMA_CHANNEL, &dma_initstructure);
/* enable the I2S DMA Stream*/
dma_channel_enable(AD_DMA, AD_DMA_CHANNEL);
/* if the i2s peripheral is still not enabled, enable it */
if(0U == (SPI_I2SCTL(AD_I2S) & I2S_ENABLE_MASK)) {
i2s_enable(AD_I2S);
}
/* SPI master start transfer */
spi_master_transfer_start(AD_I2S, SPI_TRANS_START);
}
void codec_audio_interface_init(uint32_t audio_freq){
i2s_audiofreq = audio_freq;
/* enable the AD_I2S peripheral clock */
rcu_periph_clock_enable(AD_I2S_CLK);
rcu_spi_clock_config(IDX_SPI1, RCU_SPISRC_PLL0Q);
/* AD_I2S peripheral configuration */
spi_i2s_deinit(AD_I2S);
/* initialize the I2S peripheral with the structure above */
i2s_psc_config(AD_I2S, audio_freq, I2S_FRAMEFORMAT_DT16B_CH16B,
#ifdef IIS_MCLK_ENABLED
I2S_MCKOUT_ENABLE
#elif defined(IIS_MCLK_DISABLED)
I2S_MCKOUT_DISABLE
#endif /* IIS_MCLK_ENABLED */
);
i2s_init(AD_I2S, I2S_MODE_MASTERTX, I2S_STD_MSB, I2S_CKPL_HIGH);
/* enable the I2S DMA TX request */
spi_dma_enable(AD_I2S, SPI_DMA_TRANSMIT);
}
void codec_gpio_init(void)
{
/* enable GPIO clock */
rcu_periph_clock_enable(AD_I2S_WS_CLK);
rcu_periph_clock_enable(AD_I2S_SCK_CLK);
rcu_periph_clock_enable(AD_I2S_SD_CLK);
rcu_periph_clock_enable(RCU_SYSCFG);
/* AD_I2S pins configuration: WS, SCK and SD pins */
gpio_mode_set(AD_I2S_WS_GPIO, GPIO_MODE_AF, GPIO_PUPD_NONE, AD_I2S_WS_PIN);
gpio_output_options_set(AD_I2S_WS_GPIO, GPIO_OTYPE_PP, GPIO_OSPEED_85MHZ, AD_I2S_WS_PIN);
gpio_af_set(AD_I2S_WS_GPIO, GPIO_AF_5, AD_I2S_WS_PIN);
gpio_mode_set(AD_I2S_SCK_GPIO, GPIO_MODE_AF, GPIO_PUPD_NONE, AD_I2S_SCK_PIN);
gpio_output_options_set(AD_I2S_SCK_GPIO, GPIO_OTYPE_PP, GPIO_OSPEED_85MHZ, AD_I2S_SCK_PIN);
gpio_af_set(AD_I2S_SCK_GPIO, GPIO_AF_5, AD_I2S_SCK_PIN);
gpio_mode_set(AD_I2S_SD_GPIO, GPIO_MODE_AF, GPIO_PUPD_NONE, AD_I2S_SD_PIN);
gpio_output_options_set(AD_I2S_SD_GPIO, GPIO_OTYPE_PP, GPIO_OSPEED_85MHZ, AD_I2S_SD_PIN);
gpio_af_set(AD_I2S_SD_GPIO, GPIO_AF_5, AD_I2S_SD_PIN);
#ifdef IIS_MCLK_ENABLED
/* enable GPIO clock */
rcu_periph_clock_enable(AD_I2S_MCK_CLK);
/* codec_i2s pins configuration: MCK pin */
gpio_mode_set(AD_I2S_MCK_GPIO, GPIO_MODE_AF, GPIO_PUPD_NONE, AD_I2S_MCK_PIN);
gpio_output_options_set(AD_I2S_MCK_GPIO, GPIO_OTYPE_PP, GPIO_OSPEED_85MHZ, AD_I2S_MCK_PIN);
gpio_af_set(AD_I2S_MCK_GPIO, GPIO_AF_5, AD_I2S_MCK_PIN);
#endif /* IIS_MCLK_ENABLED */
}
void codec_dma_init(void)
{
/* enable the DMA clock */
rcu_periph_clock_enable(AD_DMA_CLOCK);
rcu_periph_clock_enable(RCU_DMAMUX);
/* configure the DMA Stream */
dma_channel_enable(AD_DMA, AD_DMA_CHANNEL);
dma_deinit(AD_DMA, AD_DMA_CHANNEL);
dma_single_data_para_struct_init(&dma_initstructure);
/* set the parameters to be configured */
dma_initstructure.request = DMA_REQUEST_SPI1_TX;
dma_initstructure.periph_addr = AD_I2S_ADDRESS;
dma_initstructure.memory0_addr = (uint32_t)0; /* this field will be configured in play function */
dma_initstructure.direction = DMA_MEMORY_TO_PERIPH;
dma_initstructure.number = (uint32_t)0xFFFE; /* this field will be configured in play function */
dma_initstructure.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
dma_initstructure.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
dma_initstructure.periph_memory_width = AD_DMA_PERIPH_DATA_SIZE;
dma_initstructure.circular_mode = DMA_CIRCULAR_MODE_DISABLE;
dma_initstructure.priority = DMA_PRIORITY_ULTRA_HIGH;
dma_single_data_mode_init(AD_DMA, AD_DMA_CHANNEL, &dma_initstructure);
/* clear the DMA flags */
dma_flag_clear(AD_DMA, AD_DMA_CHANNEL, DMA_FLAG_FEE);
dma_flag_clear(AD_DMA, AD_DMA_CHANNEL, DMA_FLAG_SDE);
dma_flag_clear(AD_DMA, AD_DMA_CHANNEL, DMA_FLAG_TAE);
dma_flag_clear(AD_DMA, AD_DMA_CHANNEL, DMA_FLAG_HTF);
dma_flag_clear(AD_DMA, AD_DMA_CHANNEL, DMA_FLAG_FTF);
/* enable the selected DMA interrupts */
dma_interrupt_enable(AD_DMA, AD_DMA_CHANNEL, DMA_CHXCTL_FTFIE);
/* enable the I2S DMA request */
spi_dma_enable(AD_I2S, SPI_DMA_TRANSMIT);
/* I2S DMA IRQ channel configuration */
nvic_irq_enable(AD_DMA_IRQ, AD_IRQ_PREPRIO, AD_IRQ_SUBRIO);
}
void audio_play(uint32_t addr, uint32_t size)
{
/* disable the I2S DMA Stream*/
dma_channel_disable(AD_DMA, AD_DMA_CHANNEL);
/* clear the DMA flags */
dma_flag_clear(AD_DMA, AD_DMA_CHANNEL, DMA_FLAG_FEE);
dma_flag_clear(AD_DMA, AD_DMA_CHANNEL, DMA_FLAG_SDE);
dma_flag_clear(AD_DMA, AD_DMA_CHANNEL, DMA_FLAG_TAE);
dma_flag_clear(AD_DMA, AD_DMA_CHANNEL, DMA_FLAG_HTF);
dma_flag_clear(AD_DMA, AD_DMA_CHANNEL, DMA_FLAG_FTF);
/* configure the buffer address and size */
dma_initstructure.memory0_addr = (uint32_t)addr;
dma_initstructure.number = (uint32_t)(size);
/* configure the DMA Stream with the new parameters */
dma_single_data_mode_init(AD_DMA, AD_DMA_CHANNEL, &dma_initstructure);
/* enable the I2S DMA Stream*/
dma_channel_enable(AD_DMA, AD_DMA_CHANNEL);
/* if the i2s peripheral is still not enabled, enable it */
if(0U == (SPI_I2SCTL(AD_I2S) & I2S_ENABLE_MASK)) {
i2s_enable(AD_I2S);
}
/* SPI master start transfer */
spi_master_transfer_start(AD_I2S, SPI_TRANS_START);
}
您需要登录后才可以回复 登录 | 注册