cancel
Showing results for 
Search instead for 
Did you mean: 

MCU Will Not Generate Any SCL Pulses or Drive SDA Low Using CubeMX Generated Code

Elliott99
Associate II

I am attempting to interface an STM32H723 with an ADXL345 accelerometer. I used CubeMX and generated I2C driver code with 400kHZ clock frequency and error/event interrupts enabled. I have attempted both I2C1 and I2C2, but neither peripheral generates any clock pulses or driving of the SDA pin low. I am using 4.7K pull-up resistor between SDA/SCL and 3.3V. I am attempting to  do a 1-byte simple register read of the ADXL345 device from register 0x00, and the ADXL345 device address for read is 0xA7. However, I cannot seem to get I2C1 or I2C2 pins to drive any activity - they just remain pulled high to 3.3V. I am wondering if I am missing something in the initialization code CubMX generated. Cross-referencing with the reference manual, nothing looks out of the ordinary for what I attempted to configure. If anyone could point out anything odd in the init code, I'd greatly appreciate it. 

Init code:

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 = 0x00707CBB;
  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 */

}
void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
  if(i2cHandle->Instance==I2C2)
  {
  /* USER CODE BEGIN I2C2_MspInit 0 */

  /* USER CODE END I2C2_MspInit 0 */

  /** Initializes the peripherals clock
  */
    PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2C2;
    PeriphClkInitStruct.I2c123ClockSelection = RCC_I2C1235CLKSOURCE_D2PCLK1;
    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
    {
      Error_Handler();
    }

    __HAL_RCC_GPIOF_CLK_ENABLE();
    /**I2C2 GPIO Configuration
    PF0     ------> I2C2_SDA
    PF1     ------> I2C2_SCL
    */
    GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF4_I2C2;
    HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);

    /* I2C2 clock enable */
    __HAL_RCC_I2C2_CLK_ENABLE();

    /* I2C2 interrupt Init */
    HAL_NVIC_SetPriority(I2C2_EV_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(I2C2_EV_IRQn);
    HAL_NVIC_SetPriority(I2C2_ER_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(I2C2_ER_IRQn);
  /* USER CODE BEGIN I2C2_MspInit 1 */

  /* USER CODE END I2C2_MspInit 1 */
  }
}

 

int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MPU Configuration--------------------------------------------------------*/
  MPU_Config();

  /* 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();
  /* USER CODE BEGIN 2 */
  
  uint8_t devIdReg = 0x00;
  uint8_t devIdValue = 0x00;
  
  HAL_I2C_Mem_Read_IT(&hi2c2, 0xA7, devIdReg, I2C_MEMADD_SIZE_8BIT, (uint8_t *)&devIdValue, 1);

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}


And before anyone asks: I have tried to use the MasterTransmit_IT() HAL function, but this also generates no activity on the line. I also have attempted to execute the communication attempt with the ADXL345 disconnected and the I2C pins just connected to the breadboard with the pullups - still no clock pulses, so I don't think the accelormeter is in any odd state where it it's holding the lines high. I also have seen that once the HAL Mem_Read() or MasterTransmit() functions are called, the START bit is set although I see no start condition on line. After this, the BUSY flag is stuck set in the ISR register. I also have ensured the PE bit is set in CR1. 

2 REPLIES 2
TDK
Super User

Use HAL_I2C_IsDeviceReady and ensure it returns HAL_OK before doing anything else with I2C. If it doesn't return HAL_OK, check the ErrorCode for the failure reason.

Is BUSY is set, it indicates that the lines are low, likely due to a START condition.

TDK_0-1753722089918.png

 

Get blocking functions working before trying non-blocking.

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

Please show your schematic - see: How to write your question to maximize your chances to find a solution

Some good, clear photos of your setup may also help.

 

If you just set the used pins as GPIO, can you set the SDA and SCL lines high & low?

 

Have you tried this on an ST board; eg, Nucleo ?

Have you tried ST's I2C examples?

 

As @TDK said, get it working using blocking calls before moving on the non-blocking (interrupts, etc); use HAL_I2C_IsDeviceReady to confirm that you can address the slave.

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.