Using LSI instead of LSE

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
seemefirst@gamil.com
Posts: 15
Joined: Mon Jul 08, 2019 9:15 pm

Using LSI instead of LSE

Post by seemefirst@gamil.com » Mon Aug 26, 2019 9:47 pm

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.

chrismas9
Posts: 152
Joined: Wed Jun 25, 2014 10:07 am

Re: Using LSI instead of LSE

Post by chrismas9 » Tue Aug 27, 2019 3:38 pm

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.

seemefirst@gamil.com
Posts: 15
Joined: Mon Jul 08, 2019 9:15 pm

Re: Using LSI instead of LSE

Post by seemefirst@gamil.com » Tue Aug 27, 2019 3:51 pm

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.

chrismas9
Posts: 152
Joined: Wed Jun 25, 2014 10:07 am

Re: Using LSI instead of LSE

Post by chrismas9 » Wed Aug 28, 2019 2:31 pm

From the data sheet:

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. 
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.

seemefirst@gamil.com
Posts: 15
Joined: Mon Jul 08, 2019 9:15 pm

Re: Using LSI instead of LSE

Post by seemefirst@gamil.com » Wed Aug 28, 2019 4:21 pm

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)

seemefirst@gamil.com
Posts: 15
Joined: Mon Jul 08, 2019 9:15 pm

Re: Using LSI instead of LSE

Post by seemefirst@gamil.com » Thu Aug 29, 2019 3:42 pm

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***

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   


User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: Using LSI instead of LSE

Post by jimmo » Fri Aug 30, 2019 10:53 am

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***
Could you please send a pull request for this?

Post Reply