[C] 纯文本查看 复制代码
void i2s_gpio_config(void)
{
/* configure I2S1 and I2S1_ADD pins: I2S2_WS(PA15), I2S2_CK(PC10), I2S2_SD(PD6), I2S2_ADD_SD(PC11) */
gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_6);//CLK
gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ, GPIO_PIN_6);
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_15);//WS
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ, GPIO_PIN_15);
gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_10 | GPIO_PIN_11);
gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ, GPIO_PIN_10 | GPIO_PIN_11);
gpio_af_set(GPIOA, GPIO_AF_6, GPIO_PIN_15);
gpio_af_set(GPIOC, GPIO_AF_6, GPIO_PIN_10);
gpio_af_set(GPIOC, GPIO_AF_5, GPIO_PIN_11);
gpio_af_set(GPIOD, GPIO_AF_5, GPIO_PIN_6);
}
/*!
\brief configure different peripheral clocks
\param[in] none
\param[out] none
\retval none
*/
void i2s_rcu_config(void)
{
/* enable GPIOA clock */
rcu_periph_clock_enable(RCU_GPIOA);
/* enable GPIOB clock */
rcu_periph_clock_enable(RCU_GPIOC);
/* enable GPIOI clock */
rcu_periph_clock_enable(RCU_GPIOD);
/* enable SPI2/I2S2 clock */
rcu_periph_clock_enable(RCU_SPI2);
/* enable DMA0 clock */
rcu_periph_clock_enable(RCU_DMA0);
}
/*!
\brief configure the SPI peripheral
\param[in] none
\param[out] none
\retval none
*/
void i2s_spi_config(void)
{
spi_i2s_deinit(SPI2);
/* configure I2S2 and I2S2_ADD */
i2s_init(SPI2, I2S_MODE_MASTERTX, I2S_STD_PHILLIPS, I2S_CKPL_LOW);
i2s_psc_config(SPI2, I2S_AUDIOSAMPLE_48K, I2S_FRAMEFORMAT_DT16B_CH16B, I2S_MCKOUT_DISABLE);
i2s_full_duplex_mode_config(I2S2_ADD, I2S_MODE_MASTERTX, I2S_STD_PHILLIPS, I2S_CKPL_LOW, I2S_FRAMEFORMAT_DT16B_CH16B);
}
void i2s_dma_config(void)
{
dma_single_data_parameter_struct dma_init_struct;
dma_single_data_para_struct_init(&dma_init_struct);
dma_deinit(DMA0, DMA_CH5);
dma_init_struct.periph_addr = (uint32_t)&SPI_DATA(SPI2);
dma_init_struct.memory0_addr = (uint32_t)i2s2_Audiobuffer1;
dma_init_struct.direction = DMA_MEMORY_TO_PERIPH;
dma_init_struct.periph_memory_width = DMA_PERIPH_WIDTH_16BIT;
dma_init_struct.priority = DMA_PRIORITY_LOW;
dma_init_struct.number = I2S_AUDIO_SIZE;
dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
dma_init_struct.circular_mode = DMA_CIRCULAR_MODE_DISABLE;
dma_single_data_mode_init(DMA0, DMA_CH5, &dma_init_struct);
dma_channel_subperipheral_select(DMA0, DMA_CH5, DMA_SUBPERI0);
dma_circulation_disable(DMA0, DMA_CH5);
dma_interrupt_enable(DMA0, DMA_CH5, DMA_INT_FTF);
nvic_irq_enable(DMA0_Channel5_IRQn, 0, 0); // 使能DMA中断
//dma_interrupt_enable(DMA0, DMA_CH5, DMA_INT_FTF);
// /* configure I2S2_ADD transmit DMA */
// dma_deinit(DMA0, DMA_CH5);
// dma_init_struct.periph_addr = (uint32_t)&SPI_DATA(I2S2_ADD);
// dma_init_struct.memory0_addr = (uint32_t)i2s2_txbuffer;
// dma_init_struct.direction = DMA_MEMORY_TO_PERIPH;
// dma_init_struct.priority = DMA_PRIORITY_LOW;
// dma_single_data_mode_init(DMA0, DMA_CH5, &dma_init_struct);
// dma_channel_subperipheral_select(DMA0, DMA_CH5, DMA_SUBPERI2);
//
/* configure SPI2 receive DMA */
// dma_deinit(DMA0, DMA_CH0);
// dma_init_struct.periph_addr = (uint32_t)&SPI_DATA(SPI2);
// dma_init_struct.memory0_addr = (uint32_t)i2s2_rxbuffer;
// dma_init_struct.direction = DMA_PERIPH_TO_MEMORY;
// dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
// dma_single_data_mode_init(DMA0, DMA_CH0, &dma_init_struct);
// dma_channel_subperipheral_select(DMA0, DMA_CH0, DMA_SUBPERI0);
}
void DMA0_Channel5_IRQHandler(void) {
// 检查传输完成标志
if(dma_interrupt_flag_get(DMA0, DMA_CH5, DMA_INT_FLAG_FTF)) {
dma_interrupt_flag_clear(DMA0, DMA_CH5, DMA_INT_FLAG_FTF);
// 停止当前DMA通道
dma_channel_disable(DMA0, DMA_CH5);
// 切换缓冲区
if(I2S_Buffer_Index == 0)
{
I2S_Buffer1_playdone = 1;
// Buffer1传输完成,切换到Buffer2
dma_memory_address_config(DMA0, DMA_CH5,DMA_MEMORY_0, (uint32_t)i2s2_Audiobuffer2);
I2S_Buffer_Index = 1;
}
else
{
I2S_Buffer2_playdone = 1;
// Buffer2传输完成,切换到Buffer1
dma_memory_address_config(DMA0, DMA_CH5, DMA_MEMORY_0,(uint32_t)i2s2_Audiobuffer1);
I2S_Buffer_Index = 0;
}
// 重新设置传输数量并启动DMA
dma_transfer_number_config(DMA0, DMA_CH5, I2S_AUDIO_SIZE);
dma_channel_enable(DMA0, DMA_CH5);
}
}
void I2S2_Init(void)
{
/* enable peripheral clock */
i2s_rcu_config();
/* configure GPIO */
i2s_gpio_config();
/* configure DMA */
i2s_dma_config();
/* configure I2S */
i2s_spi_config();
/* enable I2S and I2S_ADD*/
i2s_enable(SPI2);
i2s_enable(I2S2_ADD);
/* enable DMA channel */
//spi_dma_enable(SPI2, SPI_DMA_TRANSMIT);
//dma_channel_enable(DMA0, DMA_CH5);
}
void I2S_DMA_Start(void)
{
//i2s_enable(SPI2);
//i2s_enable(I2S2_ADD);
//dma_memory_address_config(DMA0, DMA_CH5, DMA_MEMORY_0,(uint32_t)i2s2_txbuffer);
//dma_transfer_number_config(DMA0, DMA_CH5, 96);
//nvic_irq_enable(DMA0_Channel5_IRQn, 0, 0); // 使能DMA中断
spi_dma_enable(SPI2, SPI_DMA_TRANSMIT);
dma_channel_enable(DMA0, DMA_CH5);
//delay_1ms(1);
Play_Config();
}
void I2S_DMA_Stop(void)
{
//Exit_Play_Mode();
//delay_1ms(1);
spi_dma_disable(SPI2, SPI_DMA_TRANSMIT);
dma_channel_disable(DMA0, DMA_CH5);
//nvic_irq_disable(DMA0_Channel5_IRQn); // 使能DMA中断
dma_interrupt_flag_clear(DMA0, DMA_CH5, DMA_INT_FTF);
dma_interrupt_flag_clear(DMA0, DMA_CH5, DMA_INT_HTF);
//delay_1ms(10);
//Enter_Sleep_Mode();
//I2S2_Init();
//CLD8684_Init();
//Play_Config();
// 等待DMA完全停止
//while(dma_flag_get(DMA1, DMA_CH4, DMA_FLAG_CHEN));
//while((DMA_CHCTL(DMA0,DMA_CH5) & DMA_CHXCTL_CHEN) != 0);
// 强制保持I2S2使能(防止意外关闭)
if((SPI_CTL1(SPI2) & SPI_I2SCTL_I2SEN) == 0) {
i2s_enable(SPI2);
}
}