Skip to main content
Explorer
September 10, 2024
Question

STM32-NUCLEO-F411RE using two I2S result in loop in I2S_WaitFlagStateUntilTimeout()

  • September 10, 2024
  • 1 reply
  • 1027 views

Hi, it's my first time using a STM32-NUCLEO-F411RE (actually the STM32 in general) and im trying to get some audio using a i2s MEMS microphone, modifying it using the DSP, and outputting it on another i2s.
The microphone is working, and im turning a led on and off whenever it reads an amount of sounds over a threshold, dps is working fine aswell, however, when i turn the other i2s on (deactivating the SPI on the Cube IDE and activating the other i2s) the microphone is going in a loop as soon as i use HAL_I2S_Receive, going in a loop on :

 

 

 

static HAL_StatusTypeDef I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, FlagStatus State,
 uint32_t Timeout)
{
 uint32_t tickstart;

 /* Get tick */
 tickstart = HAL_GetTick();

 /* Wait until flag is set to status*/
 while (((__HAL_I2S_GET_FLAG(hi2s, Flag)) ? SET : RESET) != State)
 {
 if (Timeout != HAL_MAX_DELAY)
 {
 if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U))
 {
 /* Set the I2S State ready */
 hi2s->State = HAL_I2S_STATE_READY;

 /* Process Unlocked */
 __HAL_UNLOCK(hi2s);

 return HAL_TIMEOUT;
 }
 }
 }
 return HAL_OK;
}

 

 

 

 The i2s clock is set at 96MHz, i tried changing it but nothing worked (and it works when i use only one i2s).

 

My code is:

 

 

 

int main(void)
{

 HAL_Init();

 SystemClock_Config();

 PeriphCommonClock_Config();


 MX_GPIO_Init();
 MX_ADC1_Init();
 MX_I2S3_Init();
 MX_I2S2_Init();

 int above_threshold_count = 30;

 while (1)
 {
	 HAL_I2S_Receive(&hi2s2, (uint16_t *)audio_buffer, FILTER_ORDER, HAL_MAX_DELAY);
	 int noiseType = 0; 
	 float avgAmplitude = 0.0f;
	 if (avgAmplitude > AUDIO_THRESHOLD) {
	 above_threshold_count = DEBOUNCE_COUNT;
	 HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_SET); 

	 generateNoise(masking_output, FILTER_ORDER, MASKING_VOLUME, noiseType);

	 HAL_I2S_Transmit(&hi2s3, (uint16_t *)masking_output, FILTER_ORDER, HAL_MAX_DELAY);
	 } else {
	 above_threshold_count -= 1;
	 if (above_threshold_count <= 0) {
	 HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET); // Turn off LED
	 }

 }
}
}

void SystemClock_Config(void)
{
 RCC_OscInitTypeDef RCC_OscInitStruct = {0};
 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

 /** Configure the main internal regulator output voltage
 */
 __HAL_RCC_PWR_CLK_ENABLE();
 __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);

 /** Initializes the RCC Oscillators according to the specified parameters
 * in the RCC_OscInitTypeDef structure.
 */
 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
 RCC_OscInitStruct.HSIState = RCC_HSI_ON;
 RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
 RCC_OscInitStruct.PLL.PLLM = 16;
 RCC_OscInitStruct.PLL.PLLN = 336;
 RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
 RCC_OscInitStruct.PLL.PLLQ = 7;
 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
 {
 Error_Handler();
 }

 /** Initializes the CPU, AHB and APB buses 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_DIV2;
 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
 {
 Error_Handler();
 }
}

/**
 * @brief Peripherals Common Clock Configuration
 * @retval None
 */
void PeriphCommonClock_Config(void)
{
 RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};

 /** Initializes the peripherals clock
 */
 PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2S;
 PeriphClkInitStruct.PLLI2S.PLLI2SN = 192;
 PeriphClkInitStruct.PLLI2S.PLLI2SR = 2;
 if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
 {
 Error_Handler();
 }
}

/**
 * @brief ADC1 Initialization Function
 * None
 * @retval None
 */
static void MX_ADC1_Init(void)
{

 /* USER CODE BEGIN ADC1_Init 0 */
 /* USER CODE END ADC1_Init 0 */

 ADC_ChannelConfTypeDef sConfig = {0};

 /* USER CODE BEGIN ADC1_Init 1 */
 /* USER CODE END ADC1_Init 1 */

 /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
 */
 hadc1.Instance = ADC1;
 hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
 hadc1.Init.Resolution = ADC_RESOLUTION_12B;
 hadc1.Init.ScanConvMode = DISABLE;
 hadc1.Init.ContinuousConvMode = DISABLE;
 hadc1.Init.DiscontinuousConvMode = DISABLE;
 hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
 hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
 hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
 hadc1.Init.NbrOfConversion = 1;
 hadc1.Init.DMAContinuousRequests = DISABLE;
 hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
 if (HAL_ADC_Init(&hadc1) != HAL_OK)
 {
 Error_Handler();
 }

 /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
 */
 sConfig.Channel = ADC_CHANNEL_0;
 sConfig.Rank = 1;
 sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
 if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN ADC1_Init 2 */
 /* USER CODE END ADC1_Init 2 */

}

/**
 * @brief I2S2 Initialization Function
 * None
 * @retval None
 */
static void MX_I2S2_Init(void)
{

 /* USER CODE BEGIN I2S2_Init 0 */
 /* USER CODE END I2S2_Init 0 */

 /* USER CODE BEGIN I2S2_Init 1 */
 /* USER CODE END I2S2_Init 1 */
 hi2s2.Instance = SPI2;
 hi2s2.Init.Mode = I2S_MODE_MASTER_RX;
 hi2s2.Init.Standard = I2S_STANDARD_PHILIPS;
 hi2s2.Init.DataFormat = I2S_DATAFORMAT_16B;
 hi2s2.Init.MCLKOutput = I2S_MCLKOUTPUT_DISABLE;
 hi2s2.Init.AudioFreq = I2S_AUDIOFREQ_8K;
 hi2s2.Init.CPOL = I2S_CPOL_LOW;
 hi2s2.Init.ClockSource = I2S_CLOCK_PLL;
 hi2s2.Init.FullDuplexMode = I2S_FULLDUPLEXMODE_DISABLE;
 if (HAL_I2S_Init(&hi2s2) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN I2S2_Init 2 */
 /* USER CODE END I2S2_Init 2 */

}

/**
 * @brief I2S3 Initialization Function
 * None
 * @retval None
 */
static void MX_I2S3_Init(void)
{

 /* USER CODE BEGIN I2S3_Init 0 */
 /* USER CODE END I2S3_Init 0 */

 /* USER CODE BEGIN I2S3_Init 1 */
 /* USER CODE END I2S3_Init 1 */
 hi2s3.Instance = SPI3;
 hi2s3.Init.Mode = I2S_MODE_MASTER_TX;
 hi2s3.Init.Standard = I2S_STANDARD_PHILIPS;
 hi2s3.Init.DataFormat = I2S_DATAFORMAT_16B;
 hi2s3.Init.MCLKOutput = I2S_MCLKOUTPUT_DISABLE;
 hi2s3.Init.AudioFreq = I2S_AUDIOFREQ_16K;
 hi2s3.Init.CPOL = I2S_CPOL_LOW;
 hi2s3.Init.ClockSource = I2S_CLOCK_PLL;
 hi2s3.Init.FullDuplexMode = I2S_FULLDUPLEXMODE_DISABLE;
 if (HAL_I2S_Init(&hi2s3) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN I2S3_Init 2 */
 /* USER CODE END I2S3_Init 2 */

}

/**
 * @brief GPIO Initialization Function
 * None
 * @retval None
 */
static void MX_GPIO_Init(void)
{
 GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */

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

 /*Configure GPIO pin Output Level */
 HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET);

 /*Configure GPIO pin : B1_Pin */
 GPIO_InitStruct.Pin = B1_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 HAL_GPIO_Init(B1_GPIO_Port, &GPIO_InitStruct);

 /*Configure GPIO pins : USART_TX_Pin USART_RX_Pin */
 GPIO_InitStruct.Pin = USART_TX_Pin|USART_RX_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

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

/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}

 

 

 

 Any idea of what im doing wrong?

Thanks in advance

    This topic has been closed for replies.

    1 reply

    Technical Moderator
    September 20, 2024

    Hello @GaelicThunder and welcome to the Community;

     

    Could you please check the BSY bit when SPI is disabled?

    Is it  stay high when SPI is disabled?

    Please take a look at this errata precisely section SPI/I2S may help you.

     

    Thank you.

    Kaouthar

    Explorer
    September 20, 2024

    Hello KDJEM.1, thanks for the welcome!

    I ended up being able to use both I2S using DMA, and the results seems ok.
    I didn't check too much why it wasn't working before, since i had to work on another project.

    I will check the errata you sent me and do some test about in on monday, just to be sure.
    Thanks a lot!