stm32duino/Arduino_Core_STM32

STM32L562RE I2C2 Clock Not Being Set

Closed this issue · 0 comments

This is on a custom board with STM32L562. Here's how my STM32 pins are configured, PB10, BP11 as I2C2.

Image

Here is my SystemClock_Config which sets the I2C2 Clock

WEAK void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {};

  /** Configure the main internal regulator output voltage
  */
  if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE2) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure LSE Drive Capability
  */
  HAL_PWR_EnableBkUpAccess();
  __HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW);

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_HSE
                              |RCC_OSCILLATORTYPE_LSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.LSEState = RCC_LSE_ON;
  RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 1;
  RCC_OscInitStruct.PLL.PLLN = 12;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV4;
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV4;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSE;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    Error_Handler();
  }

  /** Enable MSI Auto calibration
  */
  HAL_RCCEx_EnableMSIPLLMode();

  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC | RCC_PERIPHCLK_SDMMC1
                                      | RCC_PERIPHCLK_UART4 | RCC_PERIPHCLK_USB
                                      | RCC_PERIPHCLK_I2C2;
  PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
  PeriphClkInit.Sdmmc1ClockSelection = RCC_SDMMC1CLKSOURCE_PLLP;
  PeriphClkInit.Uart4ClockSelection = RCC_UART4CLKSOURCE_PCLK1;
  PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSI48;
  PeriphClkInit.I2c2ClockSelection = RCC_I2C2CLKSOURCE_HSI;

  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }

}

And here's my PeripheralPins section for I2C2

//*** I2C ***
#ifdef HAL_I2C_MODULE_ENABLED
WEAK const PinMap PinMap_I2C_SDA[] = {
  // {PB_4,       I2C3, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C3)},
  // {PB_7,       I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)},
  // {PB_7_ALT1,  I2C4, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF5_I2C4)},
  // {PB_9,       I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)},
  {PB_11,      I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)},
  // {PB_11_ALT1, I2C4, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF3_I2C4)},
  // {PB_14,      I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)},
  // {PC_1,       I2C3, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C3)},
  // {PC_1_ALT1,  I2C4, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF2_I2C4)},
  // {PC_9,       I2C3, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF6_I2C3)},
  {NC,         NP,   0}
};
#endif

#ifdef HAL_I2C_MODULE_ENABLED
WEAK const PinMap PinMap_I2C_SCL[] = {
  // {PA_7,       I2C3, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C3)},
  // {PB_6,       I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)},
  // {PB_6_ALT1,  I2C4, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF5_I2C4)},
  // {PB_8,       I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)},
  {PB_10,      I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)},
  // {PB_10_ALT1, I2C4, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF3_I2C4)},
  // {PB_13,      I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)},
  // {PC_0,       I2C3, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C3)},
  // {PC_0_ALT1,  I2C4, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF2_I2C4)},
  {NC,         NP,   0}
};

Yet, when I compile an .ino file with this code:

// Define register addresses from the reference manual
#define I2C2_BASE           0x40005800U
#define I2C2_CR1            (*(volatile uint32_t*)(I2C2_BASE + 0x00))
#define I2C2_ISR            (*(volatile uint32_t*)(I2C2_BASE + 0x18))
#define I2C2_TIMINGR        (*(volatile uint32_t*)(I2C2_BASE + 0x10))

#define RCC_BASE            0x40021000U // For L5, adjust if needed for L4
#define RCC_APB1ENR1        (*(volatile uint32_t*)(RCC_BASE + 0x58))
#define RCC_CCIPR1          (*(volatile uint32_t*)(RCC_BASE + 0x88)) // L5 specific, L4 is RCC_CCIPR

#define GPIOB_BASE          0x42020400U // For L5, adjust if needed for L4
#define GPIOB_MODER         (*(volatile uint32_t*)(GPIOB_BASE + 0x00))
#define GPIOB_OTYPER        (*(volatile uint32_t*)(GPIOB_BASE + 0x04))
#define GPIOB_PUPDR         (*(volatile uint32_t*)(GPIOB_BASE + 0x0C))
#define GPIOB_AFRH          (*(volatile uint32_t*)(GPIOB_BASE + 0x24))
#define GPIOB_IDR           (*(volatile uint32_t*)(GPIOB_BASE + 0x10))

log_printf(DEBUG_INFO, "----- I2C Pre-Scan Debug -----");

// 1. Check if I2C2 clock is enabled in the RCC
log_printf(DEBUG_INFO, "RCC APB1ENR1: 0x%08X (I2C2EN is bit 22)", RCC_APB1ENR1);
if (!(RCC_APB1ENR1 & (1 << 22))) {
    log_printf(DEBUG_ERR, "ERROR: I2C2 peripheral clock is NOT enabled!");
}

It seems like the clock source isn't being set

(8029) RCC APB1ENR1: 0x10400420 (I2C2EN is bit 22)

(8031) I2C2 Clock Source (RCC_CCIPR1): 0 (0=PCLK, 1=SYSCLK, 2=HSI16)

(8033) System Clock Freq: 8000000 Hz

(8035) PCLK1 Freq: 8000000 Hz

(8037) GPIOB MODER: 0xFFFFDEBF (should be Alternate Function '10')

(8038) GPIOB OTYPER: 0x00000000 (should be Open-Drain '1')

(8041) GPIOB AFRH: 0x00000000 (should be AF4 for I2C2)

I'm on 2.10.1

Used platform            Version Path
atmosphericiq:stm32      1.0.6   /home/tom/.arduino15/packages/atmosphericiq/hardware/stm32/1.0.6
STMicroelectronics:stm32 2.10.1  /home/tom/.arduino15/packages/STMicroelectronics/hardware/stm32/2.10.1

I don't see any errors, etc in the build logs. Anything else I should check?