2025-07-28 9:55 AM
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.
2025-07-28 10:01 AM - edited 2025-07-28 10:02 AM
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.
Get blocking functions working before trying non-blocking.
2025-07-28 11:01 AM
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.