cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_I2S_Receive gives 0s although codec transmits data

PPats.1
Associate III

Hello!

For a week i've been trying to configure my stm32f302cbt6 and the tlv320aic3254 codec to trasmit data to the mcu through i2s_ext_sd but HAL_I2S_Receive returns 0s to the buffer although i see data coming out of the codec. I have configured i2s2 peripheral, master clock in the pinout config, i configured the codec analog input and clocks to generate sample rate and all clocks and bit depths i've checked with the osciloscope seem to be within spec. i ve also called HAL_I2S_MspInit(&hi2s2); in the MX_I2S2_Init(void) function to set the default pins and played around wth the different setting but no luck.

Is there something obvious i am missing?

Any ideas would be enlightening!

Best Regards

Patsaoglou P.

Project resources: https://github.com/patsaoglou/AudioWayDSP

1 ACCEPTED SOLUTION

Accepted Solutions
AScha.3
Chief II

dont ask me WHY ...

  • i just can say "try" - if i tried it and it was working, so good chance, it will work for you also.
  • any chip designed for special function will do probably best in its "standard" mode
  • the standard for a I2S connection is continuous running with constant clock
  • the standard for a codec is in and out stream running continuous
  • expect from HAL lib, basic "standard" is tested and working - special modes create more suspense...or surprise

If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

7 REPLIES 7
PPats.1
Associate III
I2C_HandleTypeDef hi2c2;
 
I2S_HandleTypeDef hi2s2;
 
/* USER CODE BEGIN PV */
 
/* USER CODE END PV */
 
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_I2C2_Init(void);
static void MX_I2S2_Init(void);
/* USER CODE BEGIN PFP */
void tlv320_Init(I2C_HandleTypeDef *hi2c2);
/* USER CODE END PFP */
 
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint16_t buf[4];
/* USER CODE END 0 */
 
/**
  * @brief  The application entry point.
  * @retval int
  */
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();
 
  /* USER CODE BEGIN Init */
 
  /* USER CODE END Init */
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* USER CODE BEGIN SysInit */
 
  /* USER CODE END SysInit */
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_I2C2_Init();
  MX_I2S2_Init();
  /* USER CODE BEGIN 2 */
  HAL_Delay(1000);
  tlv320_Init(&hi2c2);
  HAL_GPIO_TogglePin(GPIOA, TEST_LED_Pin);
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
	  HAL_I2S_Receive(&hi2s2, buf, 2, 1000);
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
 
/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
 
  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV5;
  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_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL14;
  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();
  }
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_I2C2;
  PeriphClkInit.I2c2ClockSelection = RCC_I2C2CLKSOURCE_HSI;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }
}
 
/**
  * @brief I2C2 Initialization Function
  * @param None
  * @retval None
  */
static void MX_I2C2_Init(void)
{
 
  /* USER CODE BEGIN I2C2_Init 0 */
 
  /* USER CODE END I2C2_Init 0 */
 
  /* USER CODE BEGIN I2C2_Init 1 */
 
  /* USER CODE END I2C2_Init 1 */
  hi2c2.Instance = I2C2;
  hi2c2.Init.Timing = 0x2000090E;
  hi2c2.Init.OwnAddress1 = 0;
  hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c2.Init.OwnAddress2 = 0;
  hi2c2.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
  hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c2) != HAL_OK)
  {
    Error_Handler();
  }
 
  /** Configure Analogue filter
  */
  if (HAL_I2CEx_ConfigAnalogFilter(&hi2c2, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
  {
    Error_Handler();
  }
 
  /** Configure Digital filter
  */
  if (HAL_I2CEx_ConfigDigitalFilter(&hi2c2, 0) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN I2C2_Init 2 */
 
  /* USER CODE END I2C2_Init 2 */
 
}
 
/**
  * @brief I2S2 Initialization Function
  * @param 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_ENABLE;
  hi2s2.Init.AudioFreq = I2S_AUDIOFREQ_48K;
  hi2s2.Init.CPOL = I2S_CPOL_HIGH;
  hi2s2.Init.ClockSource = I2S_CLOCK_SYSCLK;
  hi2s2.Init.FullDuplexMode = I2S_FULLDUPLEXMODE_ENABLE;
  if (HAL_I2S_Init(&hi2s2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN I2S2_Init 2 */
  HAL_I2S_MspInit(&hi2s2);
  /* USER CODE END I2S2_Init 2 */
 
}
 
/**
  * @brief GPIO Initialization Function
  * @param 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_GPIOF_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
 
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(TEST_LED_GPIO_Port, TEST_LED_Pin, GPIO_PIN_RESET);
 
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(CODEC_RESET_GPIO_Port, CODEC_RESET_Pin, GPIO_PIN_RESET);
 
  /*Configure GPIO pin : TEST_LED_Pin */
  GPIO_InitStruct.Pin = TEST_LED_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(TEST_LED_GPIO_Port, &GPIO_InitStruct);
 
  /*Configure GPIO pin : CODEC_RESET_Pin */
  GPIO_InitStruct.Pin = CODEC_RESET_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(CODEC_RESET_GPIO_Port, &GPIO_InitStruct);
 
/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}
void tlv320_Init(I2C_HandleTypeDef *hi2c2){...}

0693W00000bhJpqQAE.png0693W00000bhJoYQAU.jpg

16bit wclk and left and right codec data going into mcu

AScha.3
Chief II

HM203 🙂 i still have my HM605 🙂

shure, you didnt exchange data in/out ? miso-x-mosi (i would just try it)

+

you use a codec , data in+out same time; so some HAL_I2SEx_TransmitReceive() would ensure "normal" data flow for a codec. (in+out)

i used I2S to send data to dac, with dma , circular buffers and using callbacks:

HAL_I2S_Transmit_DMA() ; working fine with 16bit data, with 32bits all mixed up (wrong data order).

If you feel a post has answered your question, please click "Accept as Solution".

Thanks for the immediate reply!

Note : HM203 beautiful for doing analog, I have it for one year and just better instead of buying a cheap crappy digital one!! Anyway.

miso-x-mosi you mean trying on spi. I feel like I did something wrong with the mcu pins and the pin sending data from codec is configured as output instead of input?? I called HAL_I2S_MspInit(&hi2s2) but I feel I miss something on the pins.

I ll test​ HAL_I2SEx_TransmitReceive().

Thank you.

PP​

AScha.3
Chief II

>miso-x-mosi you mean trying on spi.

no. just swap the two lines . (because i made this mistake, get zero data, because master IN connected to slave IN .)

and when set I2S in Cube, you can see, which pins are used, and the mode.

0693W00000bhKkNQAU.png

If you feel a post has answered your question, please click "Accept as Solution".
PPats.1
Associate III

Well AScha.3 thanks for the response! Btw for a reason i cant change the send/receive pins from the .ioc

configurator for a reason! i used HAL_I2SEx_TransmitReceive and now i have real time data filling the buffer but i i also had to change hi2s2.Init.Mode from I2S_MODE_MASTER_RX to I2S_MODE_MASTER_TX.

A few things i ve noticed:

--When i use I2S_MODE_MASTER_RX, HAL_I2SEx_TransmitReceive returns 0 data

--When i use I2S_MODE_MASTER_TX and HAL_I2S_Receive returns 0 data and and i have no clock outputs from the mcu (master, word, bit clocks)

-- I have to use HAL_I2SEx_TransmitReceive in I2S_MODE_MASTER_RX that receives but also trasmits for the clocks to work and i found no way to only transmit

Is there a reason for all that or these trasmit/receive codecs you have to do both in order for them to work?

Thanks again for your time

Best regards

PP0693W00000bhKpwQAE.png 

AScha.3
Chief II

dont ask me WHY ...

  • i just can say "try" - if i tried it and it was working, so good chance, it will work for you also.
  • any chip designed for special function will do probably best in its "standard" mode
  • the standard for a I2S connection is continuous running with constant clock
  • the standard for a codec is in and out stream running continuous
  • expect from HAL lib, basic "standard" is tested and working - special modes create more suspense...or surprise

If you feel a post has answered your question, please click "Accept as Solution".