- 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);
- }
- }