0
\$\begingroup\$

I have a problem with my i2c connection. After a few seconds of reading the i2c readings stopped and i can't see any SDA signals with an osilloscope. I use CUBEMX5.0.1 and in the function I2C_WaitOnFlagUntilTimeout the __HAL_I2C_GET_FLAG(hi2c, Flag) seems to be always SET. I communicate with my MPU6050 sensor.

main.cpp:

#include "main.h"
#include "i2c.h"
#include "tim.h"
#include "usart.h"
#include "usb_otg.h"
#include "gpio.h"
#include "MPU6050.h"


volatile uint32_t adc;
char read[5];
int a;
uint8_t g[3];
uint8_t RxData[6], Temp[2],TxData[6];
Sensors::MPU6050 mpu(0x68,false);
float gyro_X,gyro_Y,gyro_Z,temp;

/
int main(void)
{

  HAL_Init();


  SystemClock_Config();


  MX_GPIO_Init();
  MX_USART2_UART_Init();
  MX_USB_OTG_FS_PCD_Init();
  MX_TIM1_Init();
  MX_TIM3_Init();
  MX_TIM2_Init();
  MX_I2C1_Init();


  HAL_TIM_Base_Start(&htim2);



  for(uint8_t i=0 ; i <255;i++)
    {
        if(HAL_I2C_IsDeviceReady(&hi2c1,i,1 ,10) == HAL_OK )
        {
           HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin); // @suppress("Invalid arguments")// @suppress("Symbol is not resolved")
           g[2] = i;
           break;
        }
     }

    Sensors::MPU6050::Init();

  while (1)
  {
     HAL_GPIO_TogglePin(CLKCYCLE_GPIO_Port,CLKCYCLE_Pin); // @suppress("Invalid arguments") // @suppress("Symbol is not resolved")
     if(Sensors::MPU6050::dateRDY == true){
         Sensors::MPU6050::readGyroRAW();
         Sensors::MPU6050::readAcclRAW();
         Sensors::MPU6050::dateRDY = false;
     }

     char txt[32];
     HAL_UART_Transmit(&huart2,(uint8_t*)txt,sprintf(txt, "GYROX: %lu \t", Sensors::MPU6050::rawGYRO[0]),1000);
     HAL_UART_Transmit(&huart2,(uint8_t*)txt,sprintf(txt, "GYROY: %lu \t", Sensors::MPU6050::rawGYRO[1]),1000);
     HAL_UART_Transmit(&huart2,(uint8_t*)txt,sprintf(txt, "GYROZ: %lu \n\r", Sensors::MPU6050::rawGYRO[2]),1000);

     HAL_Delay(100);

  }

}


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

  HAL_PWR_EnableBkUpAccess();

  __HAL_RCC_PWR_CLK_ENABLE(); // @suppress("Statement has no effect")
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); // @suppress("Statement has no effect")

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; // @suppress("Symbol is not resolved")
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; // @suppress("Symbol is not resolved")
  RCC_OscInitStruct.PLL.PLLM = 25;
  RCC_OscInitStruct.PLL.PLLN = 432;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  if (HAL_PWREx_EnableOverDrive() != 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; // @suppress("Symbol is not resolved")
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; // @suppress("Symbol is not resolved")
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; // @suppress("Symbol is not resolved")
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; // @suppress("Symbol is not resolved")

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7) != HAL_OK) // @suppress("Symbol is not resolved") // @suppress("Invalid arguments")
  {
    Error_Handler();
  }
  PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USART3|RCC_PERIPHCLK_I2C1
                              |RCC_PERIPHCLK_SDMMC1|RCC_PERIPHCLK_CLK48;
  PeriphClkInitStruct.Usart3ClockSelection = RCC_USART3CLKSOURCE_PCLK1;
  PeriphClkInitStruct.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1;
  PeriphClkInitStruct.Clk48ClockSelection = RCC_CLK48SOURCE_PLL;
  PeriphClkInitStruct.Sdmmc1ClockSelection = RCC_SDMMC1CLKSOURCE_CLK48;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
}


void Error_Handler(void)
{

}


void assert_failed(uint8_t *file, uint32_t line)
{ 

}

MPU6050.h:

#ifndef MPU6050_H_
#define MPU6050_H_

#define SELF_TEST_X     0x0D
#define SELF_TEST_Y     0x0E
#define SELF_TEST_Z     0x0F
#define SELF_TEST_A     0x10
#define SMPLRT_DIV      0x19
#define CONFIG          0x1A
#define GYRO_CONFIG     0x1B
#define ACCEL_CONFIG    0x1C
#define FIFO_EN         0x23
#define INT_PIN_CFG     0x37
#define INT_ENABLE      0x38
#define INT_STATUS      0x3A
#define ACCEL_XOUT_H    0x3B
#define ACCEL_XOUT_L    0x3C
#define ACCEL_YOUT_H    0x3D
#define ACCEL_YOUT_L    0x3E
#define ACCEL_ZOUT_H    0x3F
#define ACCEL_ZOUT_L    0x40
#define TEMP_OUT_H      0x41
#define TEMP_OUT_L      0x42
#define GYRO_XOUT_H     0x43
#define GYRO_XOUT_L     0x44
#define GYRO_YOUT_H     0x45
#define GYRO_YOUT_L     0x46
#define GYRO_ZOUT_H     0x47
#define GYRO_ZOUT_L     0x48
#define USER_CTRL       0x6A
#define PWR_MGMT_1      0x6B
#define PWR_MGMT_2      0x6C
#define FIFO_COUNTH     0x72
#define FIFO_COUNTL     0x73
#define FIFO_R_W        0x74
#define WHO_AM_I        0x75

#define DLPF_CFG_260    0x00
#define DLPF_CFG_184    0x01
#define DLPF_CFG_94     0x02
#define DLPF_CFG_44     0x03
#define DLPF_CFG_21     0x04
#define DLPF_CFG_10     0x05
#define DLPF_CFG_5      0x06

#define FS_SEL_250      0x00
#define FS_SEL_500      0x01
#define FS_SEL_1000     0x02
#define FS_SEL_2000     0x03

#define AFS_SEL_2       0x00
#define AFS_SEL_4       0x01
#define AFS_SEL_8       0x02
#define AFS_SEL_16      0x03

#define DATA_RDY_EN     0x01

#include "main.h"
#include "i2c.h"

namespace Sensors {

class MPU6050 {
public:
    MPU6050(uint16_t address, bool IntEnable);

    virtual ~MPU6050();

    static void Selftest();
    static void Config();
    static void Init();
    static void SetGyroResolution();
    static void SetACCLResolution();

    static void readGyroRAW();
    static void readAcclRAW();

    static uint16_t rawGYRO[3] ,rawACCL[3];
    static uint8_t TxData[6];

    static bool dateRDY;



private:
    static uint16_t address;
    static bool IntEnable;

};

} /* namespace Sensors */

#endif /* MPU6050_H_ */

MPU6050.cpp:

#include "MPU6050.h"

namespace Sensors {

uint16_t MPU6050::address;
bool MPU6050::IntEnable;

bool MPU6050::dateRDY = false;

uint16_t MPU6050::rawGYRO[3] ,MPU6050::rawACCL[3];
uint8_t MPU6050::TxData[6];

MPU6050::MPU6050(uint16_t address, bool IntEnable) {
    this->address = address << 0x01;
    this->IntEnable = IntEnable;


}

MPU6050::~MPU6050() {
    // TODO Auto-generated destructor stub
}


void MPU6050::Init(){
    //reset Sensor
    uint8_t buffer[3] = {0x80,0x07,0x00};
    HAL_I2C_Mem_Write(&hi2c1,address,PWR_MGMT_1, I2C_MEMADD_SIZE_8BIT, (uint8_t*)&buffer[0], 1,100);
    HAL_Delay(50);
    HAL_I2C_Mem_Write(&hi2c1,address,SMPLRT_DIV, I2C_MEMADD_SIZE_8BIT, (uint8_t*)&buffer[1], 1,100);
    HAL_Delay(50);
    HAL_I2C_Mem_Write(&hi2c1,address,PWR_MGMT_1, I2C_MEMADD_SIZE_8BIT, (uint8_t*)&buffer[2], 1,100);
    HAL_Delay(50);
    //config
    Config();
    HAL_Delay(50);
    //set res to 500°/s
    SetGyroResolution();
    HAL_Delay(50);
    //set res to 4g/s
    SetACCLResolution();
    HAL_Delay(50);
}

void MPU6050::Config(){
    //Set DigitalLowPassFilter
    uint8_t buffer[2] ={ DLPF_CFG_260, DATA_RDY_EN };
    HAL_I2C_Mem_Write(&hi2c1,address,CONFIG, I2C_MEMADD_SIZE_8BIT, (uint8_t*)&buffer[0], 1,100);
    HAL_I2C_Mem_Write(&hi2c1,address,INT_ENABLE, I2C_MEMADD_SIZE_8BIT, (uint8_t*)&buffer[1], 1,100);

}

void MPU6050::SetGyroResolution(){
    uint8_t buffer = FS_SEL_500<<3;
    HAL_I2C_Mem_Write(&hi2c1,address,GYRO_CONFIG, I2C_MEMADD_SIZE_8BIT, (uint8_t*)&buffer, 1,100);
}

void MPU6050::SetACCLResolution(){
    uint8_t buffer = AFS_SEL_4<<3;
    HAL_I2C_Mem_Write(&hi2c1,address,ACCEL_CONFIG, I2C_MEMADD_SIZE_8BIT, (uint8_t*)&buffer, 1,100);
}

void MPU6050::readGyroRAW(){
    uint8_t buffer[6];

    HAL_I2C_Mem_Read(&hi2c1,address,GYRO_XOUT_L,I2C_MEMADD_SIZE_8BIT,buffer,6,100);

    rawGYRO[0] = buffer[1] << 8|buffer[0];
    rawGYRO[1] = buffer[3] << 8|buffer[2];
    rawGYRO[2] = buffer[5] << 8|buffer[4];
}

void MPU6050::readAcclRAW(){
    uint8_t buffer[6];

    HAL_I2C_Mem_Read(&hi2c1,address,ACCEL_XOUT_L,I2C_MEMADD_SIZE_8BIT,buffer,6,100);



    rawACCL[0] = buffer[1] << 8|buffer[0];
    rawACCL[1] = buffer[3] << 8|buffer[2];
    rawACCL[2] = buffer[5] << 8|buffer[4];
}

} /* namespace Sensors */

stm32f7xx_it.cpp:

#include "main.h"
#include "stm32f7xx_it.h"
#include "MPU6050.h"
#include "stm32f7xx_hal.h"

extern DMA_HandleTypeDef hdma_i2c1_rx;
extern DMA_HandleTypeDef hdma_i2c1_tx;

void NMI_Handler(void)
{

}


void HardFault_Handler(void)
{

  while (1)
  {

  }
}

void MemManage_Handler(void)
{

  while (1)
  {

  }
}


void BusFault_Handler(void)
{

  while (1)
  {

  }
}


void UsageFault_Handler(void)
{

  while (1)
  {

  }
}


void SVC_Handler(void)
{

}

void DebugMon_Handler(void)
{

}


void PendSV_Handler(void)
{

}


void SysTick_Handler(void)
{

  HAL_IncTick();

}


void EXTI9_5_IRQHandler(void)
{

  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_6);
  if(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_6)){ // @suppress("Invalid arguments") // @suppress("Symbol is not resolved")
      Sensors::MPU6050::dateRDY = true;
  }

}
void EXTI15_10_IRQHandler(void)
{

  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);

  if(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_13)){ // @suppress("Invalid arguments") // @suppress("Symbol is not resolved")
      __HAL_RCC_I2C1_FORCE_RESET(); // @suppress("Symbol is not resolved") // @suppress("Field cannot be resolved")
      HAL_Delay(2);
      __HAL_RCC_I2C1_RELEASE_RESET(); // @suppress("Symbol is not resolved") // @suppress("Field cannot be resolved")*/
    }

}

My board is a STM32-Nucleo-144 F722ZE and I use CubeMXF7 1.14.0

\$\endgroup\$
  • \$\begingroup\$ I'm guessing "datafoow" is probably a typo? \$\endgroup\$ – Hearth Feb 2 at 20:11
  • \$\begingroup\$ yes it's a typo \$\endgroup\$ – Pluscrafter Feb 2 at 20:29
  • \$\begingroup\$ Which CubeF7 firmware library version? Which flag is it waiting on, and in which function? As a hint, many times if there are things happening in the background such as realtime OS or long interrupts, the I2C library does not handle that properly (at least on F2). \$\endgroup\$ – Justme Feb 2 at 21:57
  • \$\begingroup\$ There is no Interrupts or realtimeOS yet. but coud it help when I add 10k pullup resistors to sda scl ? The problem occurs after seconds or minutes. \$\endgroup\$ – Pluscrafter Feb 2 at 22:41
  • 1
    \$\begingroup\$ Your resistors are still a bit weak for the high speed mode, try 2.2K. Also design your firmware to recover, ie, start over with a new transaction. At an extreme, you can reset the I2C peripheral. \$\endgroup\$ – Chris Stratton Feb 3 at 17:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.