I am testing this on NUCLEO-L476RG. I add the following to mpconfigboard.h:
#define MICROPY_HW_RTC_USE_LSE (0)
Compile, flash and run is fine. Then I remove the X2 crystal (32KHz) physically and USB fails and noting runs. I am no longer able to enter DFU (by pulling BOOT0 high and reset). I put back the X2 crystal and everything is fine again. Am I missing something here? I was under impression that adding the above will eliminate the need for having 32k crystal and there should be a fall back for LSI.
Using LSI instead of LSE
Re: Using LSI instead of LSE
USB needs a 0.25% accurate 48Mhz clock.On the L4 this is normally derived from a PLL multiplier from LSE. LSI is very inaccurate and cannot be used for USB or UART. The MSI is ok for UART at commercial temp, but not for USB. The L4 can derive a clock from USB SOF (1 kHz) but I don't know if MicroPython supports it and I don't think the DFU bootloader does.
-
- Posts: 15
- Joined: Mon Jul 08, 2019 9:15 pm
Re: Using LSI instead of LSE
Hi,
Thanks for the reply but I do not think USB clock is coming from low speed clock, it is sourced from High speed clock (HSE or HSI) and has nothing to do with LSE or LSI.
Thanks for the reply but I do not think USB clock is coming from low speed clock, it is sourced from High speed clock (HSE or HSI) and has nothing to do with LSE or LSI.
Re: Using LSI instead of LSE
From the data sheet:
USB 48Mhz is PLL multiplied from 4Mhz MSI which must be trimmed with LSE. If you don't have LSE you don't get accurate 48Mhz. Even if you have an HSE crystal uPy ignored it because the clock source in mpconfigport is MSI. On NUCLEO L4 boards the 8Mhz STlink clock is not used either for HSE.
Code: Select all
Multispeed internal RC oscillator (MSI), trimmable by software, able to generate
12 frequencies from 100 kHz to 48 MHz. When a 32.768 kHz clock source is
available in the system (LSE), the MSI frequency can be automatically trimmed by
hardware to reach better than ±0.25% accuracy. In this mode the MSI can feed the
USB device, saving the need of an external high-speed crystal (HSE). The MSI
can supply a PLL.
-
- Posts: 15
- Joined: Mon Jul 08, 2019 9:15 pm
Re: Using LSI instead of LSE
Thanks for your input,
I just added a 8MHz HSE to the board (32KHz crystal removed). How do I set mpconfigboard.h and stm32l4xx_hal_conf.h to use HSE and LSI I tried the following for mpconfigboard but it does not work.
// MSI is used and is 4MHz
//#define MICROPY_HW_CLK_PLLM (1)
//#define MICROPY_HW_CLK_PLLN (40)
//#define MICROPY_HW_CLK_PLLP (RCC_PLLP_DIV7)
//#define MICROPY_HW_CLK_PLLQ (RCC_PLLQ_DIV2)
//#define MICROPY_HW_CLK_PLLR (RCC_PLLR_DIV2)
// HSE is used and is 8MHz
#define MICROPY_HW_CLK_PLLM (1)
#define MICROPY_HW_CLK_PLLN (20)
#define MICROPY_HW_CLK_PLLP (RCC_PLLP_DIV7)
#define MICROPY_HW_CLK_PLLQ (RCC_PLLQ_DIV2)
#define MICROPY_HW_CLK_PLLR (RCC_PLLR_DIV2)
I just added a 8MHz HSE to the board (32KHz crystal removed). How do I set mpconfigboard.h and stm32l4xx_hal_conf.h to use HSE and LSI I tried the following for mpconfigboard but it does not work.
// MSI is used and is 4MHz
//#define MICROPY_HW_CLK_PLLM (1)
//#define MICROPY_HW_CLK_PLLN (40)
//#define MICROPY_HW_CLK_PLLP (RCC_PLLP_DIV7)
//#define MICROPY_HW_CLK_PLLQ (RCC_PLLQ_DIV2)
//#define MICROPY_HW_CLK_PLLR (RCC_PLLR_DIV2)
// HSE is used and is 8MHz
#define MICROPY_HW_CLK_PLLM (1)
#define MICROPY_HW_CLK_PLLN (20)
#define MICROPY_HW_CLK_PLLP (RCC_PLLP_DIV7)
#define MICROPY_HW_CLK_PLLQ (RCC_PLLQ_DIV2)
#define MICROPY_HW_CLK_PLLR (RCC_PLLR_DIV2)
-
- Posts: 15
- Joined: Mon Jul 08, 2019 9:15 pm
Re: Using LSI instead of LSE
I have made some changes to system_stm32.c in two locations noted below to resolve this problem for stm32L4. To use the HSE/LSI a preprocessor must be defined in stm32l4xx_hal_conf.h as USE_HSE_LSI (1).
***If something like this is acceptable to the developers of Micropython please consider to make the changes***
***If something like this is acceptable to the developers of Micropython please consider to make the changes***
Code: Select all
….
#elif defined(STM32L4)
#if defined(USE_HSE_LSI) && (USE_HSE_LSI)
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 1;
RCC_OscInitStruct.PLL.PLLN = 20;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
RCC_OscInitStruct.LSEState = RCC_LSE_OFF;
RCC_OscInitStruct.MSIState = RCC_MSI_OFF;
#else
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE|RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
#endif
#endif
….
Code: Select all
….
#if defined(STM32L4)
// Enable MSI-Hardware auto calibration mode with LSE
HAL_RCCEx_EnableMSIPLLMode();
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SAI1|RCC_PERIPHCLK_I2C1
|RCC_PERIPHCLK_USB |RCC_PERIPHCLK_ADC
|RCC_PERIPHCLK_RNG |RCC_PERIPHCLK_RTC;
PeriphClkInitStruct.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1;
/* PLLSAI is used to clock USB, ADC, I2C1 and RNG. The frequency is
MSI(4MHz)/PLLM(1)*PLLSAI1N(24)/PLLSAIQ(2) = 48MHz. See the STM32CubeMx
application or the reference manual. */
PeriphClkInitStruct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLLSAI1;
PeriphClkInitStruct.AdcClockSelection = RCC_ADCCLKSOURCE_PLLSAI1;
PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLLSAI1;
PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI; //RCC_RTCCLKSOURCE_LSE;
PeriphClkInitStruct.RngClockSelection = RCC_RNGCLKSOURCE_PLLSAI1;
PeriphClkInitStruct.PLLSAI1.PLLSAI1Source = RCC_PLLSOURCE_HSE; //RCC_PLLSOURCE_MSI;
PeriphClkInitStruct.PLLSAI1.PLLSAI1M = 1;
PeriphClkInitStruct.PLLSAI1.PLLSAI1N = 12; //24;
PeriphClkInitStruct.PLLSAI1.PLLSAI1P = RCC_PLLP_DIV7;
PeriphClkInitStruct.PLLSAI1.PLLSAI1Q = RCC_PLLQ_DIV2;
PeriphClkInitStruct.PLLSAI1.PLLSAI1R = RCC_PLLR_DIV2;
PeriphClkInitStruct.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_SAI1CLK
|RCC_PLLSAI1_48M2CLK
|RCC_PLLSAI1_ADC1CLK;
#if defined(USE_HSE_LSI) && (USE_HSE_LSI)
//enbale HSE and LSI
PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
PeriphClkInitStruct.PLLSAI1.PLLSAI1Source = RCC_PLLSOURCE_HSE;
PeriphClkInitStruct.PLLSAI1.PLLSAI1N = 12;
#endif
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
__fatal_error("HAL_RCCEx_PeriphCLKConfig");
}
__PWR_CLK_ENABLE();
HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, TICK_INT_PRIORITY, 0));
#endif
Re: Using LSI instead of LSE
Could you please send a pull request for this?seemefirst@gamil.com wrote: ↑Thu Aug 29, 2019 3:42 pm***If something like this is acceptable to the developers of Micropython please consider to make the changes***