예제 #1
0
///////////////////////////////////////////////////////////////////////////////
////! Starts DMA driven I2S transfers
////! \param[in] *buffer pointer to sample buffer (contains L/R halfword)
////! \param[in] len size of audio buffer
///////////////////////////////////////////////////////////////////////////////
void CS43L22_Start(u32 *buffer, u16 len)
{
	// start I2S DMA transfers

	RCC_PLLI2SCmd(DISABLE);
#ifndef OVERCLOCK
	RCC_PLLI2SConfig((uint32_t)214,(uint32_t)2); //I2S PLL dividers for 38009 calculated from stm32f407 datasheet!!!
#else
	// RCC_PLLI2SConfig((uint32_t)198,(uint32_t)2); //I2S PLL dividers for 43010 calculated from stm32f407 datasheet!!!
	RCC_PLLI2SConfig((uint32_t)258,(uint32_t)3); //I2S PLL dividers for 48000 from stm32f407 datasheet!!!
#endif
	CS43L22_Config();

	// reload DMA source address and counter
	DMA_Cmd(DMA1_Stream5, DISABLE);

	// ensure that IRQ flag is cleared (so that DMA IRQ isn't invoked by accident while this function is called)
	DMA_ClearFlag(DMA1_Stream5, DMA_FLAG_TCIF5 | DMA_FLAG_TEIF5 | DMA_FLAG_HTIF5 | DMA_FLAG_FEIF5);

	// take over new buffer pointer/length
	DMA1_Stream5->M0AR = (u32)buffer;
	DMA1_Stream5->NDTR = 2*len;

	DMA_Cmd(DMA1_Stream5, ENABLE);
}
예제 #2
0
    void initClocks() {
        // enable HSI and set it as the system clock source
        RCC_HSICmd(ENABLE);
        while(!(RCC->CR & RCC_CR_HSIRDY)); // wait for it to be ready
        RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);

        // disable PLL and PLLI2S
        RCC_PLLCmd(DISABLE);
        RCC_PLLI2SCmd(DISABLE);

        // disable HSE and CSS (disabling the HSE also disables CSS)
        RCC_HSEConfig(RCC_HSE_OFF);

        // Configure PLL values and set source to HSE
        RCC_PLLConfig(
                RCC_PLLSource_HSE,
                DESIRED_PLL_M,
                DESIRED_PLL_N,
                DESIRED_PLL_P,
                DESIRED_PLL_Q
        );

        // set PLL I2S to our new values
        RCC_PLLI2SConfig(
                DESIRED_PLL_I2S_N,
                DESIRED_PLL_I2S_R
        );

        // set I2S clock source to PLLI2S
        RCC_I2SCLKConfig(RCC_I2S2CLKSource_PLLI2S);

        // set AHB, APB1, APB2 prescalers
        RCC_HCLKConfig(DESIRED_HCLK_DIV);
        RCC_PCLK1Config(DESIRED_PCLK1_DIV);
        RCC_PCLK2Config(DESIRED_PCKL2_DIV);

        // enable HSE
        RCC_HSEConfig(RCC_HSE_ON);
        if(RCC_WaitForHSEStartUp() == ERROR) RCC_DeInit(); // SHUT DOWN, EVERYTHING!

        // enable CSS
        RCC_ClockSecuritySystemCmd(ENABLE);

        // enable PLL
        RCC_PLLCmd(ENABLE);
        while(!(RCC->CR & RCC_CR_PLLRDY)); // wait for ready

        // enable PLL I2S
        RCC_PLLI2SCmd(ENABLE);

        // set system clock source to PLL
        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

        if(!checkClocks()){
            // No actual error reporting done here because we don't want to depend on GPIO etc
            while(1);
        }

    }
예제 #3
0
/**
  * @brief  Configure PLLSAI.
  * @param  None
  * @retval None
  */
void PLLSAI_Config(void)
{ 
  /* Configure PLLSAI prescalers */
  /* PLLSAI_VCO : VCO_429M */
  /* SAI_CLK(first level) = PLLSAI_VCO/PLLSAIQ = 429/2 = 214.5 Mhz */
  RCC_PLLSAIConfig(429, 2, 4);
  
  /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ = 214.5/19 = 11.289 Mhz */  
  RCC_SAIPLLSAIClkDivConfig(19);
  
  /* Configure PLLI2S prescalers */
  /* PLLI2S_VCO : VCO_344M */
  /* SAI_CLK(first level) = PLLI2S_VCO/PLLI2SQ = 344/7 = 49.142 Mhz */
  RCC_PLLI2SConfig(344, 7, 4);
  
  /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ = 49.142/1 = 49.142 Mhz */  
  RCC_SAIPLLI2SClkDivConfig(1);
  
  /* Configure Clock source for SAI Block A */
  RCC_SAIBlockACLKConfig(RCC_SAIACLKSource_PLLSAI);
  
  /* Configure Clock source for SAI Block B */
  RCC_SAIBlockBCLKConfig(RCC_SAIBCLKSource_PLLI2S);
  
  /* Enable PLLSAI Clock */
  RCC_PLLSAICmd(ENABLE);
  
  /* Wait till PLLSAI is ready */
  while(RCC_GetFlagStatus(RCC_FLAG_PLLSAIRDY) == RESET) 
  {
  }
  
  /* Enable PLLI2S Clock */
  RCC_PLLI2SCmd(ENABLE);
  
  /* Wait till PLLI2S is ready */
  while(RCC_GetFlagStatus(RCC_FLAG_PLLI2SRDY) == RESET) 
  {
  }
}
예제 #4
0
void audioInit()
{
    I2S_InitTypeDef I2S_InitStructure;

    Audio_GPIO_Init();

    /*CONFIG the I2S_RCC ,MUST before enabling the I2S APB clock*/
    //PLLI2SN 302,PLLI2SR 2,I2SDIV 53,I2SODD 1,FS 44.1KHZ,16bit,Error 0.0011%
    RCC_PLLI2SConfig(302,2);
    RCC_PLLI2SCmd(ENABLE);
    RCC_I2SCLKConfig(RCC_I2S2CLKSource_PLLI2S);

    /* Enable the CODEC_I2S peripheral clock */
    RCC_APB1PeriphClockCmd(CODEC_I2S_CLK, ENABLE);
    /* CODEC_I2S peripheral configuration */
    SPI_I2S_DeInit(CODEC_I2S);
    I2S_InitStructure.I2S_AudioFreq = AudioFreq;
    I2S_InitStructure.I2S_Standard = I2S_Standard_Phillips;
    I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16b;
    I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low;//clk 0 when idle state
    I2S_InitStructure.I2S_Mode = I2S_Mode_MasterTx;
#ifdef CODEC_MCLK_ENABLED
    I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Enable;
#elif defined(CODEC_MCLK_DISABLED)
    I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Disable;
#else
    #error "No selection for the MCLK output has been defined !"
#endif /* CODEC_MCLK_ENABLED */

    /* Initialize the I2S peripheral with the structure above */
    I2S_Init(CODEC_I2S, &I2S_InitStructure);
    I2S_Cmd(CODEC_I2S, ENABLE);
    //interrupt
#ifdef CODEC_USE_INT
    SPI_I2S_ITConfig(CODEC_I2S,SPI_I2S_IT_TXE,ENABLE);
#elif defined(CODEC_USE_DMA)
#error "DMA is not initialized"
#endif
}
예제 #5
0
//设置IIS的采样率(@MCKEN)
//samplerate:采样率,单位:Hz
//返回值:0,设置成功;1,无法设置.
u8 I2S2_SampleRate_Set(u32 samplerate)
{ 
	u8 i=0; 
	u32 tempreg=0;
	samplerate/=10;//缩小10倍   
	
	for(i=0;i<(sizeof(I2S_PSC_TBL)/10);i++)//看看改采样率是否可以支持
	{
		if(samplerate==I2S_PSC_TBL[i][0])break;
	}
 
	RCC_PLLI2SCmd(DISABLE);//先关闭PLLI2S
	if(i==(sizeof(I2S_PSC_TBL)/10))return 1;//搜遍了也找不到
	RCC_PLLI2SConfig((u32)I2S_PSC_TBL[i][1],(u32)I2S_PSC_TBL[i][2]);//设置I2SxCLK的频率(x=2)  设置PLLI2SN PLLI2SR
 
	RCC->CR|=1<<26;					//开启I2S时钟
	while((RCC->CR&1<<27)==0);		//等待I2S时钟开启成功. 
	tempreg=I2S_PSC_TBL[i][3]<<0;	//设置I2SDIV
	tempreg|=I2S_PSC_TBL[i][3]<<8;	//设置ODD位
	tempreg|=1<<9;					//使能MCKOE位,输出MCK
	SPI2->I2SPR=tempreg;			//设置I2SPR寄存器 
	return 0;
}