2016-07-31 07:04 AM
I've been struggling with this problem for weeks now. Basically I am trying to read out a sensor via I2C. The L3SD I am reading out the sensor in FreeRTOS, but the sensor readout task has the highest priority of all tasks.
Communcation is very unstable. I sometimes had it working for longer periods of time. But now the communication just stops almost instantly. I did a very ugly thing to reinitialize the I2C upon communication failure, and that seems to work to a degree. But then after a few seconds of doing that the communication dies completely. Once I restart the device, I again have these few seconds seconds it is working (reinitalizing probably half of the time steps, so still very ugly).
Unfortunatly I don't have access to a logic analyzer, making debugging more difficult. I am quite new to this board, and did not work a lot with the I2C protocol yet. So am I missing something obvious? Are there specific required settings for initialization of the clock/I2C that I am missing?
Some code snippets can be found here:
Starting the communication
//Enable the accelerometer
uint8_t gyro_data=0b11001111;
uint8_t imu_data=0b01110111;
HAL_I2C_Init(&hi2c1);
while
(HAL_I2C_Mem_Write(&hi2c1,I2C_GYRO_ADDR,0x20,1,&gyro_data,1,I2C_TIMEOUT) != HAL_OK ||
HAL_I2C_Mem_Write(&hi2c1,I2C_IMU_ADDR,0x20,1,&imu_data,1,I2C_TIMEOUT) != HAL_OK)
{
HAL_I2C_DeInit(&hi2c1);
HAL_I2C_Init(&hi2c1);
}
Communcation each 30ms
if
(HAL_I2C_Mem_Read(&hi2c1,I2C_GYRO_ADDR,0x28,1,(uint8_t *)&gyro_data[0],1,I2C_TIMEOUT) != HAL_OK ||
HAL_I2C_Mem_Read(&hi2c1,I2C_GYRO_ADDR,0x29,1,(uint8_t *)&gyro_data[1],1,I2C_TIMEOUT) != HAL_OK ||
HAL_I2C_Mem_Read(&hi2c1,I2C_GYRO_ADDR,0x2A,1,(uint8_t *)&gyro_data[2],1,I2C_TIMEOUT) != HAL_OK ||
HAL_I2C_Mem_Read(&hi2c1,I2C_GYRO_ADDR,0x2B,1,(uint8_t *)&gyro_data[3],1,I2C_TIMEOUT) != HAL_OK ||
HAL_I2C_Mem_Read(&hi2c1,I2C_GYRO_ADDR,0x2C,1,(uint8_t *)&gyro_data[4],1,I2C_TIMEOUT) != HAL_OK ||
HAL_I2C_Mem_Read(&hi2c1,I2C_GYRO_ADDR,0x2D,1,(uint8_t *)&gyro_data[5],1,I2C_TIMEOUT) != HAL_OK)
{
error_counter_sensor++;
HAL_I2C_DeInit(&hi2c1);
HAL_I2C_Init(&hi2c1);
// Error_Handler((uint8_t *)''Error reading out I2C'');
}
My I2C initialization
hi2c1.Instance = I2C1;
hi2c1.Init.Timing = 0x00401959;
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
My HAL_I2C_Mspinit
GPIO_InitStruct.Pin = GPIO_PIN_8|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);
/* Peripheral clock enable */
__HAL_RCC_I2C1_CLK_ENABLE();
My clock initialization
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
HAL_StatusTypeDef ret = HAL_OK;
/* Enable HSE Oscillator and activate PLL with HSE as source */
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 = 25;
RCC_OscInitStruct.PLL.PLLN = 400;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 8;
ret = HAL_RCC_OscConfig(&RCC_OscInitStruct);
if
(ret != HAL_OK)
{
while
(1) { ; }
}
/* Activate the OverDrive to reach the 200 MHz Frequency */
ret = HAL_PWREx_EnableOverDrive();
if
(ret != HAL_OK)
{
while
(1) { ; }
}
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | 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;
ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_6);
if
(ret != HAL_OK)
{
while
(1) { ; }
}
2016-08-01 06:41 AM
Hi johann3s,
''I am quite new to this board, and did not work a lot with the I2C protocol yet. So am I missing something obvious? Are there specific required settings for initialization of the clock/I2C that I am missing?''I suggest you to have a look to I2C examples under the STM32F7 cube firmware package it may be helpful:STM32Cube_FW_F7_V1.4.0\Projects\STM32746G-Discovery\Examples\I2C-Syrine-2016-08-01 06:54 AM
Thank you. I am aware of the examples, in fact I copied several parts of the initialization code specifically from there to prevent myself from making errors.
2016-08-04 11:05 PM
Issue resolved. There was a hardware issue with the I2C slave. Now everything works perfectly