0
\$\begingroup\$

my experience in programming MCU is only Arduino (also STM32F103 over Arduino) I have now started to use the STM32CUBEIDE and an ST-Link V2 to program my STM32f103.

I have tried the functions:

  • HAL_I2C_IsDeviceReady
  • HAL_I2C_Master_Transmit
  • HAL_I2C_Master_Receive
  • HAL_I2C_Mem_Read

and the 'HAL_StatusTypeDef' return value is always '1' at the first call and '2' at the following calls (of any of the above listed functions).

1 means ERROR and 2 means BUSY. 3 would mean TIMEOUT and 0 would mean OK, as far as I know.

My questions is: even if I change the I2C address the return is still 1 (ERROR) on the first call, and never 3 (TIMEOUT). Why?

According to this: https://os.mbed.com/users/EricLew/code/STM32L4xx_HAL_Driver/docs/tip/stm32l4xx__hal__i2c_8c_source.html#l02221

HAL_I2C_IsDeviceReady shouldn't even return 1, only 0 and 3...

Can somebody tell me what I am doing wrong? I setup the pins correctly in STM32Cube (PB6 and PB7):

void MX_I2C1_Init(void)
{

  hi2c1.Instance = I2C1;
  hi2c1.Init.ClockSpeed = 100000;
  hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
  hi2c1.Init.OwnAddress1 = 0;
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.OwnAddress2 = 0;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  {
    Error_Handler();
  }

}

void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(i2cHandle->Instance==I2C1)
  {
  /* USER CODE BEGIN I2C1_MspInit 0 */

  /* USER CODE END I2C1_MspInit 0 */

    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**I2C1 GPIO Configuration    
    PB6     ------> I2C1_SCL
    PB7     ------> I2C1_SDA 
    */
    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    /* I2C1 clock enable */
    __HAL_RCC_I2C1_CLK_ENABLE();
  /* USER CODE BEGIN I2C1_MspInit 1 */

  /* USER CODE END I2C1_MspInit 1 */
  }
}

And called the initialize function (just like the IDE has prepared for me in the code setup):

/* USER CODE BEGIN 0 */
HAL_StatusTypeDef ret;
unsigned char buf[2];
uint16_t val;
int16_t valt;
float temp_c;
float RoomTemp_Offset = 0;
float Temp_Sensitivity = 321;
/* USER CODE END 0 */

int main(void)
{

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

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */
  DWT_Delay_Init();
  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_I2C1_Init();
  MX_SPI1_Init();
  /* USER CODE BEGIN 2 */

  ret = HAL_I2C_IsDeviceReady(&hi2c1, MPU9250_ADDR, 10, 100);
  printf("Is Ready: %d \n", ret);
  /* USER CODE END 2 */

  /* Infinite loop */

  while (1)
  {
       // Tell MPU9250 that we want to read from the temperature register
      val = read_register(0x41);
      valt = ((int16_t)val << 4) | (val >> 4);
      temp_c = ((valt - RoomTemp_Offset)/Temp_Sensitivity) + 21;
      printf("reading...\n");
      printf("%.6f \n", temp_c);
  }
}

and the read_register function is defined here:

uint16_t read_register(uint16_t register_pointer)
{
    HAL_StatusTypeDef status = HAL_OK;
    uint16_t return_value = 0;
    status = HAL_I2C_Mem_Read(&hi2c1, MPU9250_ADDR, (uint16_t)register_pointer, I2C_MEMADD_SIZE_8BIT, &return_value, 2, 100);
    printf("read HAL_RET: %d \n", status);
    /* Check the communication status */
    if(status != HAL_OK)
    {
        Error_Handler();
    }

    return return_value;
}

and the overall output of the script ower SWO:

Is Ready: 1 
read HAL_RET: 2 
reading...

read HAL_RET: 2 
reading...

read HAL_RET: 2 
reading...

read HAL_RET: 2 
\$\endgroup\$
1
  • \$\begingroup\$ Are you sure your hardware is connected correctly? What pullups are you using? \$\endgroup\$
    – brhans
    Commented Dec 27, 2019 at 18:57

1 Answer 1

0
\$\begingroup\$

okay, thank you brhans for your comment. I thought I had taken care of that but the clock line was pulled high to 3v3, now it works. thank you very much!

I also changed this line

valt = ((int16_t)val << 4) | (val >> 4);

to

valt = ((int16_t)buf[0] << 8) | (buf[1]);
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.