2019-03-18 01:17 AM
I am using STM32F407 on STM32F4 Discovery Board and the IDE i am using to program is Keil_v5. I am trying to transmit data using I2S communication protocol on I2S port 2. I used the System Clock Configuration tool provided by ST. The desired configuration is shown in the image below:
So, i made the configuration as it seen in the image and this piece of code is below:
void systemClockConfig(void){
/** Struct definitions for clock settings **/
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_Clk_InitStruct;
RCC_PeriphCLKInitTypeDef PeriphCLKInitStruct;
/** Configure the main internal regulator output voltage **/
__HAL_RCC_SYSCFG_CLK_ENABLE();
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/** Initializes the clock settings OSC_IN to SYSCLK **/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLN = 192;
RCC_OscInitStruct.PLL.PLLM = 8;
RCC_OscInitStruct.PLL.PLLQ = 8;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV6;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
/** Initializes the clock settings SYSCLK to periph **/
RCC_Clk_InitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
RCC_Clk_InitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_Clk_InitStruct.AHBCLKDivider = RCC_SYSCLK_DIV4;
RCC_Clk_InitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_Clk_InitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
HAL_RCC_ClockConfig(&RCC_Clk_InitStruct, FLASH_LATENCY_0);
/** Initializes the clock settings for I2S peripheral **/
PeriphCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2S;
PeriphCLKInitStruct.PLLI2S.PLLI2SN = 215;
PeriphCLKInitStruct.PLLI2S.PLLI2SR = 5;
HAL_RCCEx_PeriphCLKConfig(&PeriphCLKInitStruct);
}
The register settings of I2S and GPIO register setting are made as it can be seen in the code below:
void i2sInit(void){
I2S_HandleStruct.Instance = SPI2;
I2S_HandleStruct.Init.Mode = I2S_MODE_MASTER_TX;
I2S_HandleStruct.Init.Standard = I2S_STANDARD_PHILIPS;
I2S_HandleStruct.Init.DataFormat = I2S_DATAFORMAT_16B;
I2S_HandleStruct.Init.MCLKOutput = I2S_MCLKOUTPUT_DISABLE;
I2S_HandleStruct.Init.AudioFreq = I2S_AUDIOFREQ_48K;
I2S_HandleStruct.Init.FullDuplexMode = I2S_FULLDUPLEXMODE_DISABLE;
I2S_HandleStruct.Init.CPOL = I2S_CPOL_HIGH;
I2S_HandleStruct.Init.ClockSource = I2S_CLOCK_PLL;
HAL_I2S_Init(&I2S_HandleStruct);
}
// GPIOB_PIN_10 -> CK, GPIOB_PIN_12 -> WS, GPIOC_PIN_3 -> SD
void gpioInit(void){
GPIO_InitTypeDef i2s_InitStruct;
/* Peripheral clock enable */
__HAL_RCC_SPI2_CLK_ENABLE();
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
i2s_InitStruct.Pin = GPIO_PIN_12 | GPIO_PIN_13;
i2s_InitStruct.Mode = GPIO_MODE_AF_PP;
i2s_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
i2s_InitStruct.Pull = GPIO_NOPULL;
i2s_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(GPIOB, &i2s_InitStruct);
i2s_InitStruct.Pin = GPIO_PIN_3;
i2s_InitStruct.Mode = GPIO_MODE_AF_PP;
i2s_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
i2s_InitStruct.Pull = GPIO_NOPULL;
i2s_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(GPIOC, &i2s_InitStruct);
}
The problem is that i cant get any signal on the output of I2S port. The function i use to send data is that :
HAL_I2S_Transmit(&I2S_HandleStruct, i2sReadData, i2sReadSize, i2sTimeout);
I am a newbie on STM32 mcu. Can you please enlighten me about the problem?
Best Regards
2019-03-18 02:28 AM
On the DISCO-F4 board, PC3 is connected to the MEMS microphone output, see UM1472.
JW
2019-03-18 03:56 AM
Thank you for your response.
I changed the intitialization of i2s and set the PB15 as the sd line. But still it stuck on the function belows and gives the timeout error. This function is from "stm32f4xx_hal_i2s.c" file.
static HAL_StatusTypeDef I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, uint32_t State,
uint32_t Timeout)
{
uint32_t 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((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
{
/* Set the I2S State ready */
hi2s->State = HAL_I2S_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(hi2s);
return HAL_TIMEOUT;
}
}
}
return HAL_OK;
}
As i understand, the i2s's SR register gives the error. But, i looked the register value via system analyzer and here is the values in image below. Actually there is only one active value.
Best regards.
2019-03-18 05:09 AM
I see that SPI_I2SCFGR.I2SMOD=0, which means SPI mode. That's definitively wrong.
I don't use Cube/CubeMX so can't help with the code above. You might want to have a look at the examples.
JW
2019-03-18 06:57 AM
Actually i am not using the Cube/CubeMX software. But, thanks anyway. You showed me the way i should consider more.
Best regards