Kaynağa Gözat

Fixed sample rate not set correctly under slave I2S mode.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@530 bbd45198-f89e-11dd-88c7-29a3b14d5316
wuyangyong 15 yıl önce
ebeveyn
işleme
3a72099612
1 değiştirilmiş dosya ile 385 ekleme ve 383 silme
  1. 385 383
      bsp/stm32_radio/codec.c

+ 385 - 383
bsp/stm32_radio/codec.c

@@ -97,49 +97,49 @@ static void GPIO_Configuration(void)
 {
     GPIO_InitTypeDef GPIO_InitStructure;
 
-	/* Disable the JTAG interface and enable the SWJ interface */
-	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
-
-	/* PC5 CODEC CS */
-	GPIO_InitStructure.GPIO_Pin = CODEC_CSB_PIN;
-	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
-	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
-	GPIO_Init(CODEC_CSB_PORT, &GPIO_InitStructure);
-
-	// WS
-	GPIO_InitStructure.GPIO_Pin = CODEC_I2S_WS_PIN;
-	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
+    /* Disable the JTAG interface and enable the SWJ interface */
+    GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
+
+    /* PC5 CODEC CS */
+    GPIO_InitStructure.GPIO_Pin = CODEC_CSB_PIN;
+    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
+    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
+    GPIO_Init(CODEC_CSB_PORT, &GPIO_InitStructure);
+
+    // WS
+    GPIO_InitStructure.GPIO_Pin = CODEC_I2S_WS_PIN;
+    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
 #if CODEC_MASTER_MODE
-	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
+    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
 #else
-	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
 #endif
-	GPIO_Init(CODEC_I2S_WS_PORT, &GPIO_InitStructure);
+    GPIO_Init(CODEC_I2S_WS_PORT, &GPIO_InitStructure);
 
-	// CK
-	GPIO_InitStructure.GPIO_Pin = CODEC_I2S_CK_PIN;
-	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
+    // CK
+    GPIO_InitStructure.GPIO_Pin = CODEC_I2S_CK_PIN;
+    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
 #if CODEC_MASTER_MODE
-	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
+    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
 #else
-	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
 #endif
-	GPIO_Init(CODEC_I2S_CK_PORT, &GPIO_InitStructure);
+    GPIO_Init(CODEC_I2S_CK_PORT, &GPIO_InitStructure);
 
-	// SD
-	GPIO_InitStructure.GPIO_Pin = CODEC_I2S_SD_PIN;
-	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
-	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-	GPIO_Init(CODEC_I2S_SD_PORT, &GPIO_InitStructure);
+    // SD
+    GPIO_InitStructure.GPIO_Pin = CODEC_I2S_SD_PIN;
+    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
+    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+    GPIO_Init(CODEC_I2S_SD_PORT, &GPIO_InitStructure);
 
 #ifdef CODEC_USE_MCO
-	/*    MCO    configure */
-	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
-	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-	GPIO_Init(GPIOA,&GPIO_InitStructure);
+    /*    MCO    configure */
+    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
+    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+    GPIO_Init(GPIOA,&GPIO_InitStructure);
 
-	RCC_MCOConfig(RCC_MCO_HSE);
+    RCC_MCOConfig(RCC_MCO_HSE);
 #endif
 }
 
@@ -147,132 +147,132 @@ static void DMA_Configuration(rt_uint32_t addr, rt_size_t size)
 {
     DMA_InitTypeDef DMA_InitStructure;
 
-	/* DMA Channel configuration ----------------------------------------------*/
-	DMA_Cmd(CODEC_I2S_DMA, DISABLE);
-	DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&(CODEC_I2S_PORT->DR));
-	DMA_InitStructure.DMA_MemoryBaseAddr = (u32) addr;
-	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
-	DMA_InitStructure.DMA_BufferSize = size;
-	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
-	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
-	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
-	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
-	DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
-	DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
-	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
-	DMA_Init(CODEC_I2S_DMA, &DMA_InitStructure);
-
-	/* Enable SPI DMA Tx request */
-	SPI_I2S_DMACmd(CODEC_I2S_PORT, SPI_I2S_DMAReq_Tx, ENABLE);
-
-	DMA_ITConfig(CODEC_I2S_DMA, DMA_IT_TC, ENABLE);
-	DMA_Cmd(CODEC_I2S_DMA, ENABLE);
+    /* DMA Channel configuration ----------------------------------------------*/
+    DMA_Cmd(CODEC_I2S_DMA, DISABLE);
+    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&(CODEC_I2S_PORT->DR));
+    DMA_InitStructure.DMA_MemoryBaseAddr = (u32) addr;
+    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
+    DMA_InitStructure.DMA_BufferSize = size;
+    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
+    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
+    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
+    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
+    DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
+    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
+    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
+    DMA_Init(CODEC_I2S_DMA, &DMA_InitStructure);
+
+    /* Enable SPI DMA Tx request */
+    SPI_I2S_DMACmd(CODEC_I2S_PORT, SPI_I2S_DMAReq_Tx, ENABLE);
+
+    DMA_ITConfig(CODEC_I2S_DMA, DMA_IT_TC, ENABLE);
+    DMA_Cmd(CODEC_I2S_DMA, ENABLE);
 }
 
 static void I2S_Configuration(uint32_t I2S_AudioFreq)
 {
-	I2S_InitTypeDef I2S_InitStructure;
+    I2S_InitTypeDef I2S_InitStructure;
 
-	/* I2S peripheral configuration */
-	I2S_InitStructure.I2S_Standard = I2S_Standard_Phillips;
-	I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16b;
-	I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Disable;
-	I2S_InitStructure.I2S_AudioFreq = I2S_AudioFreq;
-	I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low;
+    /* I2S peripheral configuration */
+    I2S_InitStructure.I2S_Standard = I2S_Standard_Phillips;
+    I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16b;
+    I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Disable;
+    I2S_InitStructure.I2S_AudioFreq = I2S_AudioFreq;
+    I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low;
 
-	/* I2S2 configuration */
+    /* I2S2 configuration */
 #if CODEC_MASTER_MODE
-	I2S_InitStructure.I2S_Mode = I2S_Mode_SlaveTx;
+    I2S_InitStructure.I2S_Mode = I2S_Mode_SlaveTx;
 #else
-	I2S_InitStructure.I2S_Mode = I2S_Mode_MasterTx;
+    I2S_InitStructure.I2S_Mode = I2S_Mode_MasterTx;
 #endif
-	I2S_Init(CODEC_I2S_PORT, &I2S_InitStructure);
+    I2S_Init(CODEC_I2S_PORT, &I2S_InitStructure);
 }
 
 uint8_t SPI_WriteByte(unsigned char data)
 {
-	//Wait until the transmit buffer is empty
-	while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
-	// Send the byte
-	SPI_I2S_SendData(SPI1, data);
-
-	//Wait until a data is received
-	while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
-	// Get the received data
-	data = SPI_I2S_ReceiveData(SPI1);
-
-	// Return the shifted data
-	return data;
+    //Wait until the transmit buffer is empty
+    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
+    // Send the byte
+    SPI_I2S_SendData(SPI1, data);
+
+    //Wait until a data is received
+    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
+    // Get the received data
+    data = SPI_I2S_ReceiveData(SPI1);
+
+    // Return the shifted data
+    return data;
 }
 
 static void codec_send(rt_uint16_t s_data)
 {
-	codec_reset_csb();
-	SPI_WriteByte((s_data >> 8) & 0xFF);
-	SPI_WriteByte(s_data & 0xFF);
-	codec_set_csb();
+    codec_reset_csb();
+    SPI_WriteByte((s_data >> 8) & 0xFF);
+    SPI_WriteByte(s_data & 0xFF);
+    codec_set_csb();
 }
 
 static rt_err_t codec_init(rt_device_t dev)
 {
-	codec_send(REG_SOFTWARE_RESET);
-
-	// 1.5x boost power up sequence.
-	// Mute all outputs.
-	codec_send(REG_LOUT1_VOL | LOUT1MUTE);
-	codec_send(REG_ROUT1_VOL | ROUT1MUTE);
-	codec_send(REG_LOUT2_VOL | LOUT2MUTE);
-	codec_send(REG_ROUT2_VOL | ROUT2MUTE);
-	// Enable unused output chosen from L/ROUT2, OUT3 or OUT4.
-	codec_send(REG_POWER_MANAGEMENT3 | OUT4EN);
-	// Set BUFDCOPEN=1 and BUFIOEN=1 in register R1
-	codec_send(REG_POWER_MANAGEMENT1 | BUFDCOPEN | BUFIOEN);
-	// Set SPKBOOST=1 in register R49.
-	codec_send(REG_OUTPUT | SPKBOOST);
-	// Set VMIDSEL[1:0] to required value in register R1.
-	codec_send(REG_POWER_MANAGEMENT1 | BUFDCOPEN | BUFIOEN | VMIDSEL_75K);
-	// Set L/RMIXEN=1 and DACENL/R=1 in register R3.
-	codec_send(REG_POWER_MANAGEMENT3 | LMIXEN | RMIXEN | DACENL | DACENR);
-	// Set BIASEN=1 in register R1.
-	codec_send(REG_POWER_MANAGEMENT1 | BUFDCOPEN | BUFIOEN | VMIDSEL_75K | BIASEN);
-	// Set L/ROUT2EN=1 in register R3.
-	codec_send(REG_POWER_MANAGEMENT3 | LMIXEN | RMIXEN | DACENL | DACENR | LOUT2EN | ROUT2EN);
-	// Enable other mixers as required.
-	// Enable other outputs as required.
-	codec_send(REG_POWER_MANAGEMENT2 | LOUT1EN | ROUT1EN | BOOSTENL | BOOSTENR | INPPGAENL | INPPGAENR);
-
-	// Digital inferface setup.
-	codec_send(REG_AUDIO_INTERFACE | BCP_NORMAL | LRP_NORMAL | WL_16BITS | FMT_I2S);
-
-	// PLL setup.
-	// fs = 44.1KHz * 256fs = 11.2896MHz
-	// F_PLL = 11.2896MHz * 4 * 2 = 90.3168MHz
-	// R = 90.3168MHz / 12.288MHz = 7.35
-	// PLL_N = 7
-	// PLL_K = 0x59999A (0x5A5A5A for STM32's 44.117KHz fs generated from 72MHz clock)
-	codec_send(REG_PLL_N | 7);
+    codec_send(REG_SOFTWARE_RESET);
+
+    // 1.5x boost power up sequence.
+    // Mute all outputs.
+    codec_send(REG_LOUT1_VOL | LOUT1MUTE);
+    codec_send(REG_ROUT1_VOL | ROUT1MUTE);
+    codec_send(REG_LOUT2_VOL | LOUT2MUTE);
+    codec_send(REG_ROUT2_VOL | ROUT2MUTE);
+    // Enable unused output chosen from L/ROUT2, OUT3 or OUT4.
+    codec_send(REG_POWER_MANAGEMENT3 | OUT4EN);
+    // Set BUFDCOPEN=1 and BUFIOEN=1 in register R1
+    codec_send(REG_POWER_MANAGEMENT1 | BUFDCOPEN | BUFIOEN);
+    // Set SPKBOOST=1 in register R49.
+    codec_send(REG_OUTPUT | SPKBOOST);
+    // Set VMIDSEL[1:0] to required value in register R1.
+    codec_send(REG_POWER_MANAGEMENT1 | BUFDCOPEN | BUFIOEN | VMIDSEL_75K);
+    // Set L/RMIXEN=1 and DACENL/R=1 in register R3.
+    codec_send(REG_POWER_MANAGEMENT3 | LMIXEN | RMIXEN | DACENL | DACENR);
+    // Set BIASEN=1 in register R1.
+    codec_send(REG_POWER_MANAGEMENT1 | BUFDCOPEN | BUFIOEN | VMIDSEL_75K | BIASEN);
+    // Set L/ROUT2EN=1 in register R3.
+    codec_send(REG_POWER_MANAGEMENT3 | LMIXEN | RMIXEN | DACENL | DACENR | LOUT2EN | ROUT2EN);
+    // Enable other mixers as required.
+    // Enable other outputs as required.
+    codec_send(REG_POWER_MANAGEMENT2 | LOUT1EN | ROUT1EN | BOOSTENL | BOOSTENR | INPPGAENL | INPPGAENR);
+
+    // Digital inferface setup.
+    codec_send(REG_AUDIO_INTERFACE | BCP_NORMAL | LRP_NORMAL | WL_16BITS | FMT_I2S);
+
+    // PLL setup.
+    // fs = 44.1KHz * 256fs = 11.2896MHz
+    // F_PLL = 11.2896MHz * 4 * 2 = 90.3168MHz
+    // R = 90.3168MHz / 12.288MHz = 7.35
+    // PLL_N = 7
+    // PLL_K = 0x59999A (0x5A5A5A for STM32's 44.117KHz fs generated from 72MHz clock)
+    codec_send(REG_PLL_N | 7);
 #if CODEC_MASTER_MODE
-	codec_send(REG_PLL_K1 | 0x16);
-	codec_send(REG_PLL_K2 | 0xCC);
-	codec_send(REG_PLL_K3 | 0x19A);
+    codec_send(REG_PLL_K1 | 0x16);
+    codec_send(REG_PLL_K2 | 0xCC);
+    codec_send(REG_PLL_K3 | 0x19A);
 #else
-	codec_send(REG_PLL_K1 | 0x16);
-	codec_send(REG_PLL_K2 | 0x12D);
-	codec_send(REG_PLL_K3 | 0x5A);
+    codec_send(REG_PLL_K1 | 0x16);
+    codec_send(REG_PLL_K2 | 0x12D);
+    codec_send(REG_PLL_K3 | 0x5A);
 #endif
-	codec_send(REG_POWER_MANAGEMENT1 | BUFDCOPEN | BUFIOEN | VMIDSEL_75K | BIASEN | PLLEN);
-	codec_send(r06);
+    codec_send(REG_POWER_MANAGEMENT1 | BUFDCOPEN | BUFIOEN | VMIDSEL_75K | BIASEN | PLLEN);
+    codec_send(r06);
 
-	// Enable DAC 128x oversampling.
-	codec_send(REG_DAC | DACOSR128);
+    // Enable DAC 128x oversampling.
+    codec_send(REG_DAC | DACOSR128);
 
-	// Set LOUT2/ROUT2 in BTL operation.
-	codec_send(REG_BEEP | INVROUT2);
+    // Set LOUT2/ROUT2 in BTL operation.
+    codec_send(REG_BEEP | INVROUT2);
 
-	// Set output volume.
-	vol(25);
+    // Set output volume.
+    vol(25);
 
-	return RT_EOK;
+    return RT_EOK;
 }
 
 // Exported functions
@@ -280,136 +280,136 @@ static rt_err_t codec_init(rt_device_t dev)
 
 void vol(uint16_t v)
 {
-	v = (v & VOL_MASK) << VOL_POS;
-	codec_send(REG_LOUT1_VOL | v);
-	codec_send(REG_ROUT1_VOL | HPVU | v);
-	codec_send(REG_LOUT2_VOL | v);
-	codec_send(REG_ROUT2_VOL | SPKVU | v);
+    v = (v & VOL_MASK) << VOL_POS;
+    codec_send(REG_LOUT1_VOL | v);
+    codec_send(REG_ROUT1_VOL | HPVU | v);
+    codec_send(REG_LOUT2_VOL | v);
+    codec_send(REG_ROUT2_VOL | SPKVU | v);
 }
 
 void eq(codec_eq_args_t args)
 {
-	switch (args->channel)
-	{
-	case 1:
-		codec_send(REG_EQ1 | ((args->frequency & EQC_MASK) << EQC_POS) | ((args->gain & EQG_MASK) << EQG_POS) | (args->mode_bandwidth ? EQ3DMODE_DAC : EQ3DMODE_ADC));
-		break;
-
-	case 2:
-		codec_send(REG_EQ2 | ((args->frequency & EQC_MASK) << EQC_POS) | ((args->gain & EQG_MASK) << EQG_POS) | (args->mode_bandwidth ? EQ2BW_WIDE : EQ2BW_NARROW));
-		break;
-
-	case 3:
-		codec_send(REG_EQ3 | ((args->frequency & EQC_MASK) << EQC_POS) | ((args->gain & EQG_MASK) << EQG_POS) | (args->mode_bandwidth ? EQ3BW_WIDE : EQ3BW_NARROW));
-		break;
-
-	case 4:
-		codec_send(REG_EQ4 | ((args->frequency & EQC_MASK) << EQC_POS) | ((args->gain & EQG_MASK) << EQG_POS) | (args->mode_bandwidth ? EQ4BW_WIDE : EQ4BW_NARROW));
-		break;
-
-	case 5:
-		codec_send(REG_EQ5 | ((args->frequency & EQC_MASK) << EQC_POS) | ((args->gain & EQG_MASK) << EQG_POS));
-		break;
-	}
+    switch (args->channel)
+    {
+    case 1:
+        codec_send(REG_EQ1 | ((args->frequency & EQC_MASK) << EQC_POS) | ((args->gain & EQG_MASK) << EQG_POS) | (args->mode_bandwidth ? EQ3DMODE_DAC : EQ3DMODE_ADC));
+        break;
+
+    case 2:
+        codec_send(REG_EQ2 | ((args->frequency & EQC_MASK) << EQC_POS) | ((args->gain & EQG_MASK) << EQG_POS) | (args->mode_bandwidth ? EQ2BW_WIDE : EQ2BW_NARROW));
+        break;
+
+    case 3:
+        codec_send(REG_EQ3 | ((args->frequency & EQC_MASK) << EQC_POS) | ((args->gain & EQG_MASK) << EQG_POS) | (args->mode_bandwidth ? EQ3BW_WIDE : EQ3BW_NARROW));
+        break;
+
+    case 4:
+        codec_send(REG_EQ4 | ((args->frequency & EQC_MASK) << EQC_POS) | ((args->gain & EQG_MASK) << EQG_POS) | (args->mode_bandwidth ? EQ4BW_WIDE : EQ4BW_NARROW));
+        break;
+
+    case 5:
+        codec_send(REG_EQ5 | ((args->frequency & EQC_MASK) << EQC_POS) | ((args->gain & EQG_MASK) << EQG_POS));
+        break;
+    }
 }
 
 // TODO eq1() ~ eq5() are just for testing. To be removed.
 void eq1(uint8_t freq, uint8_t gain, uint8_t mode)
 {
-	codec_send(REG_EQ1 | ((freq & EQC_MASK) << EQC_POS) | ((gain & EQG_MASK) << EQG_POS) | (mode ? EQ3DMODE_DAC : EQ3DMODE_ADC));
+    codec_send(REG_EQ1 | ((freq & EQC_MASK) << EQC_POS) | ((gain & EQG_MASK) << EQG_POS) | (mode ? EQ3DMODE_DAC : EQ3DMODE_ADC));
 }
 
 void eq2(uint8_t freq, uint8_t gain, uint8_t bw)
 {
-	codec_send(REG_EQ2 | ((freq & EQC_MASK) << EQC_POS) | ((gain & EQG_MASK) << EQG_POS) | (bw ? EQ2BW_WIDE : EQ2BW_NARROW));
+    codec_send(REG_EQ2 | ((freq & EQC_MASK) << EQC_POS) | ((gain & EQG_MASK) << EQG_POS) | (bw ? EQ2BW_WIDE : EQ2BW_NARROW));
 }
 
 void eq3(uint8_t freq, uint8_t gain, uint8_t bw)
 {
-	codec_send(REG_EQ3 | ((freq & EQC_MASK) << EQC_POS) | ((gain & EQG_MASK) << EQG_POS) | (bw ? EQ3BW_WIDE : EQ3BW_NARROW));
+    codec_send(REG_EQ3 | ((freq & EQC_MASK) << EQC_POS) | ((gain & EQG_MASK) << EQG_POS) | (bw ? EQ3BW_WIDE : EQ3BW_NARROW));
 }
 
 void eq4(uint8_t freq, uint8_t gain, uint8_t bw)
 {
-	codec_send(REG_EQ4 | ((freq & EQC_MASK) << EQC_POS) | ((gain & EQG_MASK) << EQG_POS) | (bw ? EQ4BW_WIDE : EQ4BW_NARROW));
+    codec_send(REG_EQ4 | ((freq & EQC_MASK) << EQC_POS) | ((gain & EQG_MASK) << EQG_POS) | (bw ? EQ4BW_WIDE : EQ4BW_NARROW));
 }
 
 void eq5(uint8_t freq, uint8_t gain)
 {
-	codec_send(REG_EQ2 | ((freq & EQC_MASK) << EQC_POS) | ((gain & EQG_MASK) << EQG_POS));
+    codec_send(REG_EQ2 | ((freq & EQC_MASK) << EQC_POS) | ((gain & EQG_MASK) << EQG_POS));
 }
 
 void eq3d(uint8_t depth)
 {
-	codec_send(REG_3D | ((depth & DEPTH3D_MASK) << DEPTH3D_POS));
+    codec_send(REG_3D | ((depth & DEPTH3D_MASK) << DEPTH3D_POS));
 }
 
 rt_err_t sample_rate(int sr)
 {
-	uint16_t r07 = REG_ADDITIONAL;
+    uint16_t r07 = REG_ADDITIONAL;
 
-	switch (sr)
-	{
-	case 8000:
-		r06 = REG_CLOCK_GEN | CLKSEL_MCLK | MCLK_DIV6 | BCLK_DIV8 | (r06 & MS);
-		r07 |= SR_8KHZ;
-		break;
+    switch (sr)
+    {
+    case 8000:
+        r06 = REG_CLOCK_GEN | CLKSEL_MCLK | MCLK_DIV6 | BCLK_DIV8 | (r06 & MS);
+        r07 |= SR_8KHZ;
+        break;
 
-	case 11025:
-		r06 = REG_CLOCK_GEN | CLKSEL_PLL | MCLK_DIV8 | BCLK_DIV8 | (r06 & MS);
-		r07 |= SR_12KHZ;
-		break;
+    case 11025:
+        r06 = REG_CLOCK_GEN | CLKSEL_PLL | MCLK_DIV8 | BCLK_DIV8 | (r06 & MS);
+        r07 |= SR_12KHZ;
+        break;
 
 #if CODEC_MASTER_MODE
-	case 12000:
-		r06 = REG_CLOCK_GEN | CLKSEL_MCLK | MCLK_DIV4 | BCLK_DIV8 | (r06 & MS);
-		r07 |= SR_12KHZ;
-		break;
+    case 12000:
+        r06 = REG_CLOCK_GEN | CLKSEL_MCLK | MCLK_DIV4 | BCLK_DIV8 | (r06 & MS);
+        r07 |= SR_12KHZ;
+        break;
 #endif
 
-	case 16000:
-		r06 = REG_CLOCK_GEN | CLKSEL_MCLK | MCLK_DIV3 | BCLK_DIV8 | (r06 & MS);
-		r07 |= SR_16KHZ;
-		break;
+    case 16000:
+        r06 = REG_CLOCK_GEN | CLKSEL_MCLK | MCLK_DIV3 | BCLK_DIV8 | (r06 & MS);
+        r07 |= SR_16KHZ;
+        break;
 
-	case 22050:
-		r06 = REG_CLOCK_GEN | CLKSEL_PLL | MCLK_DIV4 | BCLK_DIV8 | (r06 & MS);
-		r07 |= SR_24KHZ;
-		break;
+    case 22050:
+        r06 = REG_CLOCK_GEN | CLKSEL_PLL | MCLK_DIV4 | BCLK_DIV8 | (r06 & MS);
+        r07 |= SR_24KHZ;
+        break;
 
 #if CODEC_MASTER_MODE
-	case 24000:
-		r06 = REG_CLOCK_GEN | CLKSEL_MCLK | MCLK_DIV2 | BCLK_DIV8 | (r06 & MS);
-		r07 |= SR_24KHZ;
-		break;
+    case 24000:
+        r06 = REG_CLOCK_GEN | CLKSEL_MCLK | MCLK_DIV2 | BCLK_DIV8 | (r06 & MS);
+        r07 |= SR_24KHZ;
+        break;
 #endif
 
-	case 32000:
-		r06 = REG_CLOCK_GEN | CLKSEL_MCLK | MCLK_DIV1_5 | BCLK_DIV8 | (r06 & MS);
-		r07 |= SR_32KHZ;
-		break;
+    case 32000:
+        r06 = REG_CLOCK_GEN | CLKSEL_MCLK | MCLK_DIV1_5 | BCLK_DIV8 | (r06 & MS);
+        r07 |= SR_32KHZ;
+        break;
 
-	case 44100:
-		r06 = REG_CLOCK_GEN | CLKSEL_PLL | MCLK_DIV2 | BCLK_DIV8 | (r06 & MS);
-		r07 |= SR_48KHZ;
-		break;
+    case 44100:
+        r06 = REG_CLOCK_GEN | CLKSEL_PLL | MCLK_DIV2 | BCLK_DIV8 | (r06 & MS);
+        r07 |= SR_48KHZ;
+        break;
 
-	case 48000:
-		r06 = REG_CLOCK_GEN | CLKSEL_MCLK | MCLK_DIV1 | BCLK_DIV8 | (r06 & MS);
-		r07 |= SR_48KHZ;
-		break;
+    case 48000:
+        r06 = REG_CLOCK_GEN | CLKSEL_MCLK | MCLK_DIV1 | BCLK_DIV8 | (r06 & MS);
+        r07 |= SR_48KHZ;
+        break;
 
-	default:
-		return RT_ERROR;
-	}
-	codec_send(r06);
-	codec_send(r07);
+    default:
+        return RT_ERROR;
+    }
+    codec_send(r06);
+    codec_send(r07);
 
 #if !CODEC_MASTER_MODE
-	I2S_Configuration((uint32_t) sr);
+    I2S_Configuration((uint32_t) sr);
 #endif
 
-	return RT_EOK;
+    return RT_EOK;
 }
 
 FINSH_FUNCTION_EXPORT(vol, Set volume);
@@ -424,217 +424,219 @@ FINSH_FUNCTION_EXPORT(sample_rate, Set sample rate);
 static rt_err_t codec_open(rt_device_t dev, rt_uint16_t oflag)
 {
 #if !CODEC_MASTER_MODE
-	/* enable I2S */
-	I2S_Cmd(CODEC_I2S_PORT, ENABLE);
+    /* enable I2S */
+    I2S_Cmd(CODEC_I2S_PORT, ENABLE);
 #endif
 
-	return RT_EOK;
+    return RT_EOK;
 }
 
 static rt_err_t codec_close(rt_device_t dev)
 {
 #if CODEC_MASTER_MODE
-	if (r06 & MS)
-	{
-		CODEC_I2S_DMA->CCR &= ~DMA_CCR1_EN;
-		while ((CODEC_I2S_PORT->SR & SPI_I2S_FLAG_TXE) == 0);
-		while ((CODEC_I2S_PORT->SR & SPI_I2S_FLAG_BSY) != 0);
-		CODEC_I2S_PORT->I2SCFGR &= ~SPI_I2SCFGR_I2SE;
-
-		r06 &= ~MS;
-		codec_send(r06);
-
-		/* remove all data node */
-		if (codec.parent.tx_complete != RT_NULL)
-		{
-			rt_base_t level = rt_hw_interrupt_disable();
-
-			do
-			{
-				codec.parent.tx_complete(&codec.parent, codec.data_list[codec.read_index].data_ptr);
-				codec.read_index++;
-				if (codec.read_index >= DATA_NODE_MAX)
-				{
-					codec.read_index = 0;
-				}
-			}
-			while (codec.read_index != codec.put_index);
-
-			rt_hw_interrupt_enable(level);
-		}
-	}
+    if (r06 & MS)
+    {
+        CODEC_I2S_DMA->CCR &= ~DMA_CCR1_EN;
+        while ((CODEC_I2S_PORT->SR & SPI_I2S_FLAG_TXE) == 0);
+        while ((CODEC_I2S_PORT->SR & SPI_I2S_FLAG_BSY) != 0);
+        CODEC_I2S_PORT->I2SCFGR &= ~SPI_I2SCFGR_I2SE;
+
+        r06 &= ~MS;
+        codec_send(r06);
+
+        /* remove all data node */
+        if (codec.parent.tx_complete != RT_NULL)
+        {
+            rt_base_t level = rt_hw_interrupt_disable();
+
+            do
+            {
+                codec.parent.tx_complete(&codec.parent, codec.data_list[codec.read_index].data_ptr);
+                codec.read_index++;
+                if (codec.read_index >= DATA_NODE_MAX)
+                {
+                    codec.read_index = 0;
+                }
+            }
+            while (codec.read_index != codec.put_index);
+
+            rt_hw_interrupt_enable(level);
+        }
+    }
 #endif
 
-	return RT_EOK;
+    return RT_EOK;
 }
 
 static rt_err_t codec_control(rt_device_t dev, rt_uint8_t cmd, void *args)
 {
-	switch (cmd)
-	{
-	case CODEC_CMD_RESET:
-		codec_init(dev);
-		break;
-
-	case CODEC_CMD_VOLUME:
-		vol(*((uint16_t*) args));
-		break;
-
-	case CODEC_CMD_SAMPLERATE:
-		sample_rate(*((int*) args));
-		break;
-
-	case CODEC_CMD_EQ:
-		eq((codec_eq_args_t) args);
-		break;
-
-	case CODEC_CMD_3D:
-		eq3d(*((uint8_t*) args));
-		break;
-
-	default:
-		return RT_ERROR;
-	}
-	return RT_EOK;
+    switch (cmd)
+    {
+    case CODEC_CMD_RESET:
+        codec_init(dev);
+        break;
+
+    case CODEC_CMD_VOLUME:
+        vol(*((uint16_t*) args));
+        break;
+
+    case CODEC_CMD_SAMPLERATE:
+        dev->close(dev);
+        sample_rate(*((int*) args));
+        dev->open(dev,0);
+        break;
+
+    case CODEC_CMD_EQ:
+        eq((codec_eq_args_t) args);
+        break;
+
+    case CODEC_CMD_3D:
+        eq3d(*((uint8_t*) args));
+        break;
+
+    default:
+        return RT_ERROR;
+    }
+    return RT_EOK;
 }
 
 static rt_size_t codec_write(rt_device_t dev, rt_off_t pos,
-		const void* buffer, rt_size_t size)
+                             const void* buffer, rt_size_t size)
 {
-	struct codec_device* device;
-	struct codec_data_node* node;
-	rt_uint32_t level;
-	rt_uint16_t next_index;
-
-	device = (struct codec_device*) dev;
-	RT_ASSERT(device != RT_NULL);
-
-	next_index = device->put_index + 1;
-	if (next_index >= DATA_NODE_MAX)
-		next_index = 0;
-
-	/* check data_list full */
-	if (next_index == device->read_index)
-	{
-		rt_set_errno(-RT_EFULL);
-		return 0;
-	}
-
-	level = rt_hw_interrupt_disable();
-	node = &device->data_list[device->put_index];
-	device->put_index = next_index;
-
-	/* set node attribute */
-	node->data_ptr = (rt_uint16_t*) buffer;
-	node->data_size = size >> 1; /* size is byte unit, convert to half word unit */
-
-	next_index = device->read_index + 1;
-	if (next_index >= DATA_NODE_MAX)
-		next_index = 0;
-
-	/* check data list whether is empty */
-	if (next_index == device->put_index)
-	{
-		DMA_Configuration((rt_uint32_t) node->data_ptr, node->data_size);
+    struct codec_device* device;
+    struct codec_data_node* node;
+    rt_uint32_t level;
+    rt_uint16_t next_index;
+
+    device = (struct codec_device*) dev;
+    RT_ASSERT(device != RT_NULL);
+
+    next_index = device->put_index + 1;
+    if (next_index >= DATA_NODE_MAX)
+        next_index = 0;
+
+    /* check data_list full */
+    if (next_index == device->read_index)
+    {
+        rt_set_errno(-RT_EFULL);
+        return 0;
+    }
+
+    level = rt_hw_interrupt_disable();
+    node = &device->data_list[device->put_index];
+    device->put_index = next_index;
+
+    /* set node attribute */
+    node->data_ptr = (rt_uint16_t*) buffer;
+    node->data_size = size >> 1; /* size is byte unit, convert to half word unit */
+
+    next_index = device->read_index + 1;
+    if (next_index >= DATA_NODE_MAX)
+        next_index = 0;
+
+    /* check data list whether is empty */
+    if (next_index == device->put_index)
+    {
+        DMA_Configuration((rt_uint32_t) node->data_ptr, node->data_size);
 
 #if CODEC_MASTER_MODE
-		if ((r06 & MS) == 0)
-		{
-			CODEC_I2S_PORT->I2SCFGR |= SPI_I2SCFGR_I2SE;
-			r06 |= MS;
-			codec_send(r06);
-		}
+        if ((r06 & MS) == 0)
+        {
+            CODEC_I2S_PORT->I2SCFGR |= SPI_I2SCFGR_I2SE;
+            r06 |= MS;
+            codec_send(r06);
+        }
 #endif
-	}
-	rt_hw_interrupt_enable(level);
+    }
+    rt_hw_interrupt_enable(level);
 
-	return size;
+    return size;
 }
 
 rt_err_t codec_hw_init(void)
 {
-	rt_device_t dev;
-
-	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE);
-	RCC_APB1PeriphClockCmd(CODEC_I2S_RCC_APB1, ENABLE);
-	RCC_AHBPeriphClockCmd(CODEC_I2S_RCC_AHB, ENABLE);
-
-	NVIC_Configuration();
-	GPIO_Configuration();
-	I2S_Configuration(I2S_AudioFreq_44k);
-
-	dev = (rt_device_t) &codec;
-	dev->type = RT_Device_Class_Sound;
-	dev->rx_indicate = RT_NULL;
-	dev->tx_complete = RT_NULL;
-	dev->init = codec_init;
-	dev->open = codec_open;
-	dev->close = codec_close;
-	dev->read = RT_NULL;
-	dev->write = codec_write;
-	dev->control = codec_control;
-	dev->private = RT_NULL;
-
-	/* set read_index and put index to 0 */
-	codec.read_index = 0;
-	codec.put_index = 0;
-
-	/* unselect */
-	codec_set_csb();
-
-	/* register the device */
-	return rt_device_register(&codec.parent, "snd", RT_DEVICE_FLAG_WRONLY | RT_DEVICE_FLAG_DMA_TX);
+    rt_device_t dev;
+
+    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE);
+    RCC_APB1PeriphClockCmd(CODEC_I2S_RCC_APB1, ENABLE);
+    RCC_AHBPeriphClockCmd(CODEC_I2S_RCC_AHB, ENABLE);
+
+    NVIC_Configuration();
+    GPIO_Configuration();
+    I2S_Configuration(I2S_AudioFreq_44k);
+
+    dev = (rt_device_t) &codec;
+    dev->type = RT_Device_Class_Sound;
+    dev->rx_indicate = RT_NULL;
+    dev->tx_complete = RT_NULL;
+    dev->init = codec_init;
+    dev->open = codec_open;
+    dev->close = codec_close;
+    dev->read = RT_NULL;
+    dev->write = codec_write;
+    dev->control = codec_control;
+    dev->private = RT_NULL;
+
+    /* set read_index and put index to 0 */
+    codec.read_index = 0;
+    codec.put_index = 0;
+
+    /* unselect */
+    codec_set_csb();
+
+    /* register the device */
+    return rt_device_register(&codec.parent, "snd", RT_DEVICE_FLAG_WRONLY | RT_DEVICE_FLAG_DMA_TX);
 }
 
 void codec_dma_isr(void)
 {
-	/* switch to next buffer */
-	rt_uint16_t next_index;
-	void* data_ptr;
+    /* switch to next buffer */
+    rt_uint16_t next_index;
+    void* data_ptr;
 
-	next_index = codec.read_index + 1;
-	if (next_index >= DATA_NODE_MAX)
-		next_index = 0;
+    next_index = codec.read_index + 1;
+    if (next_index >= DATA_NODE_MAX)
+        next_index = 0;
 
-	/* save current data pointer */
-	data_ptr = codec.data_list[codec.read_index].data_ptr;
+    /* save current data pointer */
+    data_ptr = codec.data_list[codec.read_index].data_ptr;
 
-	codec.read_index = next_index;
-	if (next_index != codec.put_index)
-	{
-		/* enable next dma request */
-		DMA_Configuration((rt_uint32_t) codec.data_list[codec.read_index].data_ptr, codec.data_list[codec.read_index].data_size);
+    codec.read_index = next_index;
+    if (next_index != codec.put_index)
+    {
+        /* enable next dma request */
+        DMA_Configuration((rt_uint32_t) codec.data_list[codec.read_index].data_ptr, codec.data_list[codec.read_index].data_size);
 
 #if CODEC_MASTER_MODE
-		if ((r06 & MS) == 0)
-		{
-			CODEC_I2S_PORT->I2SCFGR |= SPI_I2SCFGR_I2SE;
-			r06 |= MS;
-			codec_send(r06);
-		}
+        if ((r06 & MS) == 0)
+        {
+            CODEC_I2S_PORT->I2SCFGR |= SPI_I2SCFGR_I2SE;
+            r06 |= MS;
+            codec_send(r06);
+        }
 #endif
-	}
-	else
-	{
+    }
+    else
+    {
 #if CODEC_MASTER_MODE
-		if (r06 & MS)
-		{
-			CODEC_I2S_DMA->CCR &= ~DMA_CCR1_EN;
-			while ((CODEC_I2S_PORT->SR & SPI_I2S_FLAG_TXE) == 0);
-			while ((CODEC_I2S_PORT->SR & SPI_I2S_FLAG_BSY) != 0);
-			CODEC_I2S_PORT->I2SCFGR &= ~SPI_I2SCFGR_I2SE;
-
-			r06 &= ~MS;
-			codec_send(r06);
-		}
+        if (r06 & MS)
+        {
+            CODEC_I2S_DMA->CCR &= ~DMA_CCR1_EN;
+            while ((CODEC_I2S_PORT->SR & SPI_I2S_FLAG_TXE) == 0);
+            while ((CODEC_I2S_PORT->SR & SPI_I2S_FLAG_BSY) != 0);
+            CODEC_I2S_PORT->I2SCFGR &= ~SPI_I2SCFGR_I2SE;
+
+            r06 &= ~MS;
+            codec_send(r06);
+        }
 #endif
 
-		rt_kprintf("*\n");
-	}
+        rt_kprintf("*\n");
+    }
 
-	/* notify transmitted complete. */
-	if (codec.parent.tx_complete != RT_NULL)
-	{
-		codec.parent.tx_complete(&codec.parent, data_ptr);
-	}
+    /* notify transmitted complete. */
+    if (codec.parent.tx_complete != RT_NULL)
+    {
+        codec.parent.tx_complete(&codec.parent, data_ptr);
+    }
 }