Skip to main content
Visitor II
December 9, 2024
Question

PMOD I2S2 spike after frequency change.

  • December 9, 2024
  • 0 replies
  • 413 views

Hello,

I use STM32F407G-DISC1 with Digilent PMOD I2S2. I have FIR filter project and after i enable sound or drasticly change frequency, volume spikes. After few seconds it becomes normal again. Why is that?

Code:

#include "main.h"
I2S_HandleTypeDef hi2s2;
DMA_HandleTypeDef hdma_i2s2_ext_rx;
DMA_HandleTypeDef hdma_spi2_tx;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_I2S2_Init(void);
/*sampling frequency: 48000 Hz
* 0 Hz - 2000 Hz
 gain = 1
 desired ripple = 5 dB
 actual ripple = 3.284632065621469 dB
* 5000 Hz - 24000 Hz
 gain = 0
 desired attenuation = -30 dB
 actual attenuation = -32.02295267957132 dB*/
#define FILTER_TAP_NUM 17
static float filter_taps[FILTER_TAP_NUM] = {
 -0.0021834891907904987,
 0.023133081888390004,
 0.03440125360693663,
 0.054016706019288735,
 0.07610902012650608,
 0.09772535709704201,
 0.11593264129629442,
 0.12810228628568973,
 0.13238343618749146,
 0.12810228628568973,
 0.11593264129629442,
 0.09772535709704201,
 0.07610902012650608,
 0.054016706019288735,
 0.03440125360693663,
 0.023133081888390004,
 -0.0021834891907904987
};
static float firdata [FILTER_TAP_NUM];
static int firptr [FILTER_TAP_NUM];
static int fir_w_ptr = 0;
uint16_t rxBuf[8];
uint16_t txBuf[8];
int main(void)
{
 HAL_Init();
 SystemClock_Config();
 MX_GPIO_Init();
 MX_DMA_Init();
 MX_I2S2_Init();
 HAL_I2SEx_TransmitReceive_DMA (&hi2s2, txBuf, rxBuf, 4);
 while (1)
 {
 }
}
int Calc_FIR (int inSample) {
	float inSampleF = (float)inSample;
	float outdata = 0;

	for (int i=0;i < FILTER_TAP_NUM; i++) {
		outdata += (firdata[i]*filter_taps[firptr[i]]);
		firptr[i]++;
	}
	firdata[fir_w_ptr] = inSampleF;
	firptr[fir_w_ptr] = 0;
	fir_w_ptr++;
	if (fir_w_ptr == FILTER_TAP_NUM) fir_w_ptr=0;

	return (int) outdata;
}

void HAL_I2SEx_TxRxHalfCpltCallback(I2S_HandleTypeDef *hi2s){
	//restore signed 24 bit sample from 16-bit buffers
	int lSample = (int) (rxBuf[0]<<16)|rxBuf[1];
	int rSample = (int) (rxBuf[2]<<16)|rxBuf[3];
	// divide by 2 (rightshift) -> -3dB per sample
	lSample = lSample>>1;
	rSample = rSample>>1;
	//sum to mono
	lSample = rSample + lSample;
	//run HP on left channel and LP on right channel
	lSample = Calc_FIR(lSample);
	//restore to buffer
	txBuf[0] = (lSample>>16)&0xFFFF;
	txBuf[1] = lSample&0xFFFF;
	txBuf[2] = (lSample>>16)&0xFFFF;
	txBuf[3] = lSample&0xFFFF;
}

void HAL_I2SEx_TxRxCpltCallback(I2S_HandleTypeDef *hi2s){
	//restore signed 24 bit sample from 16-bit buffers
	int lSample = (int) (rxBuf[4]<<16)|rxBuf[5];
	int rSample = (int) (rxBuf[6]<<16)|rxBuf[7];
	// divide by 2 (rightshift) -> -3dB per sample
	lSample = lSample>>1;
	rSample = rSample>>1;
	//sum to mono
	lSample = rSample + lSample;
	//run HP on left channel and LP on right channel
	lSample = Calc_FIR(lSample);
	//restore to buffer
	txBuf[4] = (lSample>>16)&0xFFFF;
	txBuf[5] = lSample&0xFFFF;
	txBuf[6] = (lSample>>16)&0xFFFF;
	txBuf[7] = lSample&0xFFFF;
}
void SystemClock_Config(void)
{
 RCC_OscInitTypeDef RCC_OscInitStruct = {0};
 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
 RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};

 /** Configure the main internal regulator output voltage 
 */
 __HAL_RCC_PWR_CLK_ENABLE();
 __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
 /** Initializes the CPU, AHB and APB busses clocks 
 */
 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
 RCC_OscInitStruct.HSEState = RCC_HSE_ON;
 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
 RCC_OscInitStruct.PLL.PLLM = 8;
 RCC_OscInitStruct.PLL.PLLN = 336;
 RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
 RCC_OscInitStruct.PLL.PLLQ = 7;
 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
 {
 Error_Handler();
 }
 /** Initializes the CPU, AHB and APB busses clocks 
 */
 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
 |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
 {
 Error_Handler();
 }
 PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2S;
 PeriphClkInitStruct.PLLI2S.PLLI2SN = 192;
 PeriphClkInitStruct.PLLI2S.PLLI2SR = 2;
 if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
 {
 Error_Handler();
 }
}
static void MX_I2S2_Init(void)
{
 hi2s2.Instance = SPI2;
 hi2s2.Init.Mode = I2S_MODE_MASTER_TX;
 hi2s2.Init.Standard = I2S_STANDARD_PHILIPS;
 hi2s2.Init.DataFormat = I2S_DATAFORMAT_24B;
 hi2s2.Init.MCLKOutput = I2S_MCLKOUTPUT_ENABLE;
 hi2s2.Init.AudioFreq = I2S_AUDIOFREQ_48K;
 hi2s2.Init.CPOL = I2S_CPOL_LOW;
 hi2s2.Init.ClockSource = I2S_CLOCK_PLL;
 hi2s2.Init.FullDuplexMode = I2S_FULLDUPLEXMODE_ENABLE;
 if (HAL_I2S_Init(&hi2s2) != HAL_OK)
 {
 Error_Handler();
 }
}
static void MX_DMA_Init(void) 
{
 /* DMA controller clock enable */
 __HAL_RCC_DMA1_CLK_ENABLE();

 /* DMA interrupt init */
 /* DMA1_Stream3_IRQn interrupt configuration */
 HAL_NVIC_SetPriority(DMA1_Stream3_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(DMA1_Stream3_IRQn);
 /* DMA1_Stream4_IRQn interrupt configuration */
 HAL_NVIC_SetPriority(DMA1_Stream4_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(DMA1_Stream4_IRQn);
}
static void MX_GPIO_Init(void)
{
 GPIO_InitTypeDef GPIO_InitStruct = {0};

 /* GPIO Ports Clock Enable */
 __HAL_RCC_GPIOE_CLK_ENABLE();
 __HAL_RCC_GPIOC_CLK_ENABLE();
 __HAL_RCC_GPIOH_CLK_ENABLE();
 __HAL_RCC_GPIOA_CLK_ENABLE();
 __HAL_RCC_GPIOB_CLK_ENABLE();
 __HAL_RCC_GPIOD_CLK_ENABLE();

 /*Configure GPIO pin Output Level */
 HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_RESET);

 /*Configure GPIO pin Output Level */
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_RESET);

 /*Configure GPIO pin Output Level */
 HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15 
 |GPIO_PIN_4, GPIO_PIN_RESET);

 /*Configure GPIO pin : PE3 */
 GPIO_InitStruct.Pin = GPIO_PIN_3;
 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

 /*Configure GPIO pin : PC0 */
 GPIO_InitStruct.Pin = GPIO_PIN_0;
 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

 /*Configure GPIO pin : PA0 */
 GPIO_InitStruct.Pin = GPIO_PIN_0;
 GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

 /*Configure GPIO pin : PA4 */
 GPIO_InitStruct.Pin = GPIO_PIN_4;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 GPIO_InitStruct.Alternate = GPIO_AF6_SPI3;
 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

 /*Configure GPIO pins : PA5 PA6 PA7 */
 GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
 GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

 /*Configure GPIO pin : PB2 */
 GPIO_InitStruct.Pin = GPIO_PIN_2;
 GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

 /*Configure GPIO pins : PD12 PD13 PD14 PD15 
 PD4 */
 GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15 
 |GPIO_PIN_4;
 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

 /*Configure GPIO pins : PC7 PC10 PC12 */
 GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_10|GPIO_PIN_12;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 GPIO_InitStruct.Alternate = GPIO_AF6_SPI3;
 HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

 /*Configure GPIO pin : PA9 */
 GPIO_InitStruct.Pin = GPIO_PIN_9;
 GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

 /*Configure GPIO pins : PA10 PA11 PA12 */
 GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
 GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;
 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

 /*Configure GPIO pin : PD5 */
 GPIO_InitStruct.Pin = GPIO_PIN_5;
 GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

 /*Configure GPIO pins : PB6 PB9 */
 GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_9;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
 GPIO_InitStruct.Pull = GPIO_PULLUP;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
 GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

 /*Configure GPIO pin : PE1 */
 GPIO_InitStruct.Pin = GPIO_PIN_1;
 GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

}

void Error_Handler(void)
{
 /* USER CODE BEGIN Error_Handler_Debug */
 /* User can add his own implementation to report the HAL error return state */

 /* USER CODE END Error_Handler_Debug */
}

#ifdef USE_FULL_ASSERT

void assert_failed(uint8_t *file, uint32_t line)
{ }
#endif /* USE_FULL_ASSERT */

 

    This topic has been closed for replies.