cancel
Showing results for 
Search instead for 
Did you mean: 

I2S CLK Outputs on STM32F303 HAL

epalaima
Associate II
Posted on November 16, 2016 at 08:45

Hi, I am working with the STM32F303 (using the STM32F3Discovery) and I have been trying to set up I2S communication with an external audio codec. 

I generated code to set up the peripherals with STCubeMX. It generated code that setups up I2S2 as full duplex master with I2S MCLK out on PC6. The code generated correctly and I succeeded in building and running it.

However, when I tried checking the code with an oscilloscope there was no clock signal (LR clock, Word Clock or MCLK ) on any of the Pins (PB12-13 and PC6 for the STM32F303.

Is there something else I need to enable to use I2S?

I am using Atollic TrueStudio with a Segger J-Link debugger. 

#!i2s #hal #discovery #i2s #stm32f303
2 REPLIES 2
slimen
Senior
Posted on November 16, 2016 at 17:08

Hello,

You can test/compare with a working I2S example within STM32CubeF3 firmware package to identify what is going wrong in your case and confirm if the problem here seems related to the hardware or software environment.

The example will help you to have more idea on how implementation is done.

Make sure that you've configured the right pins in the right mode. You can refer to the product datasheet and reference manual for more clarification about pin and clock configuration. 

Regards

epalaima
Associate II
Posted on November 16, 2016 at 19:21

I set up I2S via CubeMX and the code it generated compiles properly. I check to make sure that the GPIO were set up, and they are. I use a X16 PLLMUL to get the clock speed necessary for I2S MCLK output. It seems strange that neither CubeMX and TrueStudio would return any errors. I have everything I need for I2S set up, before I configured the clock properly CubeMX would show an error. 

I looked up the example project you mentioned. It is not available for the STM32F303 discovery board which I am using. Is the problem that I am working with a discovery board? I have access to all the necessary pins and am trying to interface with an external codec so I don't see why this would be the case.

Also is there a place in the datasheet where it describes the actual bit registers on the chip that are used for I2S? I could not find that, or maybe it is handled differently than that. 

Here is my complete main.c. Compiles perfectly but no clock outputs:

STM32303E_EV/* Includes ------------------------------------------------------------------*/

#include ''stm32f3xx_hal.h''

/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private variables ---------------------------------------------------------*/

I2S_HandleTypeDef hi2s2;

/* USER CODE BEGIN PV */

/* Private variables ---------------------------------------------------------*/

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/

void SystemClock_Config(void);

void Error_Handler(void);

static void MX_GPIO_Init(void);

static void MX_I2S2_Init(void);

/* USER CODE BEGIN PFP */

/* Private function prototypes -----------------------------------------------*/

/* USER CODE END PFP */

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

int main(void)

{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration----------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */

  HAL_Init();

  /* Configure the system clock */

  SystemClock_Config();

  /* Initialize all configured peripherals */

  MX_GPIO_Init();

  MX_I2S2_Init();

  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */

  /* USER CODE BEGIN WHILE */

  while (1)

  {

  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */

  }

  /* USER CODE END 3 */

}

/** System Clock Configuration

*/

void SystemClock_Config(void)

{

  RCC_OscInitTypeDef RCC_OscInitStruct;

  RCC_ClkInitTypeDef RCC_ClkInitStruct;

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;

  RCC_OscInitStruct.HSIState = RCC_HSI_ON;

  RCC_OscInitStruct.HSICalibrationValue = 16;

  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;

  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL16;

  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

  {

    Error_Handler();

  }

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

  }

  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

  /* SysTick_IRQn interrupt configuration */

  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);

}

/* I2S2 init function */

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_16B;

  hi2s2.Init.MCLKOutput = I2S_MCLKOUTPUT_ENABLE;

  hi2s2.Init.AudioFreq = I2S_AUDIOFREQ_8K;

  hi2s2.Init.CPOL = I2S_CPOL_LOW;

  hi2s2.Init.ClockSource = I2S_CLOCK_SYSCLK;

  hi2s2.Init.FullDuplexMode = I2S_FULLDUPLEXMODE_ENABLE;

  if (HAL_I2S_Init(&hi2s2) != HAL_OK)

  {

    Error_Handler();

  }

}

/** Pinout Configuration

*/

static void MX_GPIO_Init(void)

{

  /* GPIO Ports Clock Enable */

  __HAL_RCC_GPIOB_CLK_ENABLE();

  __HAL_RCC_GPIOC_CLK_ENABLE();

}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**

  * @brief  This function is executed in case of error occurrence.

  * @param  None

  * @retval None

  */

void Error_Handler(void)

{

  /* USER CODE BEGIN Error_Handler */

  /* User can add his own implementation to report the HAL error return state */

  while(1) 

  {

  }

  /* USER CODE END Error_Handler */ 

}

#ifdef USE_FULL_ASSERT

/**

   * @brief Reports the name of the source file and the source line number

   * where the assert_param error has occurred.

   * @param file: pointer to the source file name

   * @param line: assert_param error line source number

   * @retval None

   */

void assert_failed(uint8_t* file, uint32_t line)

{

  /* USER CODE BEGIN 6 */

  /* User can add his own implementation to report the file name and line number,

    ex: printf(''Wrong parameters value: file %s on line %d\r\n'', file, line) */

  /* USER CODE END 6 */

}

#endifAL