-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
This simple sketch reveals a bug in the Cygnet:
#include <Wire.h>
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
for (int i = 0; i < 5; i++) {
digitalWrite(LED_BUILTIN, HIGH);
delay(500);
digitalWrite(LED_BUILTIN, LOW);
delay(500);
}
Wire.begin();
}
void loop() {
digitalWrite(LED_BUILTIN, HIGH);
delay(1000);
digitalWrite(LED_BUILTIN, LOW);
delay(1000);
}Describe the bug
The sketch will indefinitely hang at Wire.begin(); until the USB is plugged in. If the USB is plugged in at the beginning of the sketch, the whole sketch will run without interruption.
To Reproduce
Flash the sketch above using SWD when the device is powered by battery, and the Cygnet will blink 5 times quickly, but never transition to the slower blinks.
Plug in the USB and it will continue to the slower blinks.
Expected behavior
Continuous Blinking
Desktop (please complete the following information):
- OS: Linux
- Arduino IDE version: 2.3.8
- STM32 core version: 2.12.0
- Tools menu settings if not the default: n/a
- Upload method: SWD
Board (please complete the following information):
- Name: Blues Cygnet
- Hardware Revision: 1.2
- Extra hardware used if any: n/a
Additional context
I've tested several modifications to the initialization routines, and I was able to narrow it down to the following change in the WEAK void SystemClock_Config(void) function:
From (reproducing):
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_USB;
PeriphClkInit.AdcClockSelection = RCC_ADCCLKSOURCE_SYSCLK;
PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_MSI;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
Error_Handler();
}To (no repro):
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
PeriphClkInit.AdcClockSelection = RCC_ADCCLKSOURCE_SYSCLK;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
Error_Handler();
}When I stepped through the debugger, this is the exact place it hangs in the code:
twi.c:
#if defined(I2C3_BASE)
if (i2c == I2C3) {
#if defined(RCC_PERIPHCLK_I2C3) || defined(RCC_PERIPHCLK_I2C35)
#ifdef RCC_PERIPHCLK_I2C3
clkSrcFreq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_I2C3);
#else
clkSrcFreq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_I2C35);
#endif
if (clkSrcFreq == 0)
#endif
{
#if defined(__HAL_RCC_GET_I2C3_SOURCE)
switch (__HAL_RCC_GET_I2C3_SOURCE()) {
#ifdef RCC_I2C3CLKSOURCE_HSI
case RCC_I2C3CLKSOURCE_HSI:
clkSrcFreq = HSI_VALUE;
break;
#endif
#ifdef RCC_I2C3CLKSOURCE_SYSCLK
case RCC_I2C3CLKSOURCE_SYSCLK:
clkSrcFreq = SystemCoreClock;
break;
#endif
#if defined(RCC_I2C3CLKSOURCE_PCLK1) || defined(RCC_I2C3CLKSOURCE_D2PCLK1)
#ifdef RCC_I2C3CLKSOURCE_PCLK1
case RCC_I2C3CLKSOURCE_PCLK1:
#endif
#ifdef RCC_I2C3CLKSOURCE_D2PCLK1
case RCC_I2C3CLKSOURCE_D2PCLK1:
#endif
clkSrcFreq = HAL_RCC_GetPCLK1Freq();
break;
#endif
#ifdef RCC_I2C3CLKSOURCE_CSI
case RCC_I2C3CLKSOURCE_CSI:
clkSrcFreq = CSI_VALUE;
break;
#endif
#ifdef RCC_I2C3CLKSOURCE_PLL3
case RCC_I2C3CLKSOURCE_PLL3:
HAL_RCCEx_GetPLL3ClockFreq(&PLL3_Clocks);
clkSrcFreq = PLL3_Clocks.PLL3_R_Frequency;
break;
#endif
default:
Error_Handler();
}
#else
/* STM32 G0 I2C3 has no independent clock */
clkSrcFreq = HAL_RCC_GetPCLK1Freq();
#endif
}
}
#endif // I2C3_BASEI don't understand the relationship between the USB and the I2C peripherals.