### STM32Cube LL Example Porting Guide Source: https://github.com/stmicroelectronics/stm32cubel4/blob/master/Projects/NUCLEO-L412KB/Templates_LL/readme.txt Instructions for porting a LL example to a targeted board. This involves replacing source files of the LL template with those of the LL example, while preserving board-specific configurations marked by specific comment tags. Updates to 'main.h', 'main.c', 'stm32l4xx_it.h', and 'stm32l4xx_it.c' are detailed. ```c /* ============== BOARD SPECIFIC CONFIGURATION CODE BEGIN ============== */ /* ============== BOARD SPECIFIC CONFIGURATION CODE END ============== */ // In main.h: // Keep LED and user button definition of the LL template under tags // In main.c: // Keep clock configuration: SystemClock_Config() // Replace LEDx_PIN by another LEDx if needed // Replace files: main.h, main.c, stm32l4xx_it.h, stm32l4xx_it.c ``` -------------------------------- ### Install Example Dependencies in Virtual Environment Source: https://github.com/stmicroelectronics/stm32cubel4/blob/master/Drivers/CMSIS/DSP/PythonWrapper/README.md Installs NumPy, SciPy, and Matplotlib within an activated Python virtual environment. These packages are required to run the example scripts provided with the CMSIS-DSP wrapper. ```bash pip install numpy pip install scipy pip install matplotlib ``` -------------------------------- ### Main Header File for STM32L4xx DCMI Preview Source: https://github.com/stmicroelectronics/stm32cubel4/blob/master/Projects/32L496GDISCOVERY/Examples/DCMI/DCMI_Preview/readme.txt This header file provides declarations for the main program functionalities, including system clock configuration, peripheral initializations, and other global definitions specific to the DCMI preview example. It ensures proper setup and control of the STM32L4xx peripherals involved. ```c /** ****************************************************************************** * @file main.h * @author MCD Application Team * @brief This file contains all the functions prototypes corresponding to the * νεςmain functions in main.c ****************************************************************************** * * @attention * * Copyright (c) 2017 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. If no * such notice is provided, the license files are included in the root directory of this package. * ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __MAIN_H #define __MAIN_H /* Includes ------------------------------------------------------------------*/ /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Exported types ------------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/ /* USER CODE BEGIN EC */ /* USER CODE END EC */ /* Exported macro ------------------------------------------------------------*/ /* USER CODE BEGIN EM */ /* USER CODE END EM */ void SystemClock_Config(void); void MX_GPIO_Init(void); void MX_DMA_Init(void); void MX_DCMI_Init(void); void MX_DMA2D_Init(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* USER CODE BEGINUserProg */ /* USER CODE ENDUserProg */ #endif /* __MAIN_H */ /** ****************************************************************************** * @file main.c * @author MCD Application Team * @brief Main program body ****************************************************************************** * * @attention * * Copyright (c) 2017 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. If no * such notice is provided, the license files are included in the root directory of this package. * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "stm32l4xx_hal.h" #include "dcmi_camera.h" #include "stm32l4xx_nucleo_bus.h" #include "stm32l4xx_nucleo_lcd.h" /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ #define FSMC_MEMORY_WIDTH FSMC_ACCESS_MODE_A #define JPEG_IMAGE_SIZE (uint32_t)(320*240*1.5) #define BUFFER_OFFSET (uint32_t)(320*100) /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ static uint8_t *pBmp; /* Pointer to bitmap file */ static uint8_t *pData; /* Pointer to graphic data */ static uint8_t *pRow; /* Pointer to current row of graphic data */ static uint32_t x, y; /* Current X,Y coordinates */ static uint16_t width, height; /* Image width & height */ static uint8_t bytespp; /* Bytes per pixel */ static uint8_t bitmapheader[54]; /* BMP header */ static uint32_t data = 0xFF; /* RGB565 pixel data */ static uint8_t frame_buffer[320*240*2] __attribute__((at(0xC0000000))); /* Frame buffer */ /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ static void MX_NVIC_Init(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* USER CODE BEGIN User Functions */ /** * @brief Handles the reception of the data from the camera * @param None * @retval None */ void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi) { /*##-1- Transfer the DCMI data to the LCD frame buffer #########################*/ /* Change the DMA_DCMI_Data_Buffer pointer to the LCD Frame buffer */ /* HAL_DCMI_IMUMACRO is used to prevent the DMA2D from starting before */ /* the DCMI frame is captured by the DMA */ LCD_SetLayerVisible(0, ENABLE); /* Update the LCD Frame Buffer */ LCD_SetGramScanMode(GRAM_SCAN_POSITIVE); /* Display Picture */ LCD_DisplayPicture(pBmp); /* Turn off the LCD layer */ LCD_SetLayerVisible(0, DISABLE); } /** * @brief System Clock Configuration * @param None * @retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef Osc_Init; RCC_ClkInitTypeDef Clk_Init; RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; /* Enable HSE oscillator */ Osc_Init.OscillatorType = RCC_OSCILLATORTYPE_HSE; Osc_Init.HSEState = RCC_HSE_ON; /* Enable HSE */ Osc_Init.HSEPrediv = RCC_HSE_PREDIV_DIV1; /* No division */ Osc_Init.PLL.PLLState = RCC_PLL_ON; /* Enable PLL */ Osc_Init.PLL.PLLSource = RCC_PLLSOURCE_HSE; Osc_Init.PLL.PLLM = 1; /* Division by 1 */ Osc_Init.PLL.PLLN = 20; /* Multiplication by 20 */ Osc_Init.PLL.PLLR = 2; /* Division by 2 */ HAL_RCC_OscConfig(&Osc_Init); /* Enable MSI PLL mode to activate VOS setting */ HAL_PWREx_EnableMSIPLLMode(); /* Wait for PLL to be ready */ while(Osc_Init.PLL.PLLState != RCC_PLL_ON) { /* Do nothing */ } /* Configure the PLL */ /* PREDIV1: HSE Predivider */ /* PLLCLK: PREDIV1 * PREDIV2 * PLLN / (PLLR * PLLQ) */ /* PLL_VCOInput = HSE / PREDIV1 = 8 MHz */ /* PLL_VCOOutput = PLL_VCOInput * PLLN = 8 * 20 = 160 MHz */ /* SYSCLK = PLL_VCOOutput / PLLR = 160 / 2 = 80 MHz */ /* USB = PLL_VCOOutput / PLLQ = 160 / 4 = 40 MHz */ /* PLLQ = 4 */ /* Select PLL as system clock source */ Clk_Init.ClockType = RCC_CLOCKTYPE_SYSCLK; Clk_Init.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; Clk_Init.SYSCLKDivider = RCC_SYSCLK_DIV1; HAL_RCC_ClockConfig(&Clk_Init, FLASH_LATENCY_4); /* Configure the peripherals clock */ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USART2; PeriphClkInitStruct.Usart2ClockSelection = RCC_USART2CLKSOURCE_SYSCLK; HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); /* Configure the Systick interrupt time */ HAL_SYSTICK_SetClkSource(SYSTICK_CLKSOURCE_HCLK); HAL_SYSTICK_Config(SystemCoreClock / 1000); /* Configure the SysTick_Handler to be the lowest priority */ HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0); } /* USER CODE END User Functions */ ``` -------------------------------- ### HAL WWDG Initialization and Configuration Source: https://github.com/stmicroelectronics/stm32cubel4/blob/master/Projects/STM32L476G-EVAL/Examples/WWDG/WWDG_Example/readme.txt This snippet shows the initialization of the HAL WWDG peripheral and its associated MSP (Microcontroller Specific Peripheral) configuration. It covers clock and NVIC setup, and how to set the WWDG timeout and refresh window. ```c #include "stm32l4xx_hal.h" // ... other initializations ... void WWDG_Init(void) { WWDG_HandleTypeDef hwwdg; // Peripheral clock enable __HAL_RCC_WWDG_CLK_ENABLE(); // WWDG interrupt init HAL_NVIC_SetPriority(WWDG_IRQn, 0, 0); HAL_NVIC_EnableIRQ(WWDG_IRQn); // WWDG configuration hwwdg.Instance = WWDG; hwwdg.Init.Prescaler = WWDG_PRESCALER_8; hwwg.Init.Window = 0x3F; hwwdg.Init.Counter = 256; if (HAL_WWDG_Init(&hwwdg) != HAL_OK) { Error_Handler(); } } void HAL_WWDG_MspInit(WWDG_HandleTypeDef* hwwdg) { // Configure clock and NVIC for WWDG // This function should be updated based on hardware specifics // Example: Enable WWDG clock, configure interrupt controller } void SystemClock_Config(void) { // ... System clock configuration to 80 MHz ... } int main(void) { HAL_Init(); SystemClock_Config(); WWDG_Init(); while (1) { // Refresh WWDG counter periodically if (HAL_WWDG_GetCounter(&hwwdg) > 0x3F) { HAL_WWDG_Refresh(&hwwdg); } HAL_Delay(20); // Refresh every 20 ms // Toggle LED2 } } ``` -------------------------------- ### STM32Cube HAL Driver Examples for STM32L4 Series Source: https://github.com/stmicroelectronics/stm32cubel4/blob/master/Projects/STM32CubeProjectsList.html Provides examples of how to use the STM32Cube HAL (Hardware Abstraction Layer) API to develop firmware applications for the STM32L4 series microcontrollers. These templates serve as a starting point for various projects. ```c /* Reference template based on the STM32Cube HAL API */ /* Can be used to build any firmware application. */ ``` -------------------------------- ### STM32L4 HAL Initialization Source: https://github.com/stmicroelectronics/stm32cubel4/blob/master/Projects/STM32L476G-EVAL/Examples/FLASH/FLASH_DualBoot/readme.txt Initializes all configured peripherals, the Flash interface, and the SysTick timer. This function must be called at the beginning of the main program to ensure proper hardware setup. ```c /** * @brief This function is executed in case of error occurrence. * @retval None */ void Error_Handler(void) { /* User can add his own implementation to report the HAL error return state */ __disable_irq(); while (1) { } } /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* HAL driver initialisation */ if (HAL_Init() != HAL_OK) { Error_Handler(); } /* 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_USART1_UART_Init(); MX_LCD_Init(); MX_FLASHEX_Init(); /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } ``` -------------------------------- ### STM32L4 Interrupt Handler Setup Source: https://github.com/stmicroelectronics/stm32cubel4/blob/master/Projects/NUCLEO-L412RB-P/Templates_LL/readme.txt Contains the C code for setting up interrupt handlers, primarily for the main program and system-specific interrupts. This includes definitions for `main.h` and implementation in `stm32l4xx_it.c`. ```c /** ****************************************************************************** * @file Templates_LL/Inc/stm32l4xx_it.h * @author MCD Application Team * @brief This file contains the headers of the interrupt handlers. ****************************************************************************** * * Copyright (c) 2018 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. If no LICENSE file comes with * this code, it is provided AS-IS. * ****************************************************************************** */ /* Define to prevent recursive inclusion --------------------------------------*/ #ifndef __STM32L4xx_IT_H #define __STM32L4xx_IT_H #ifdef __cplusplus extern "C" { #endif /* Private includes ------------------------------------------------------------ */ /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Exported types ------------------------------------------------------------ */ /* USER CODE BEGIN ET */ /* USER CODE END ET */ /* Exported constants -------------------------------------------------------- */ /* USER CODE BEGIN EC */ /* USER CODE END EC */ /* Exported macro ------------------------------------------------------------ */ /* USER CODE BEGIN EM */ /* USER CODE END EM */ /* Exported functions prototypes --------------------------------------------- */ void NMI_Handler(void); void HardFault_Handler(void); void MemManage_Handler(void); void BusFault_Handler(void); void UsageFault_Handler(void); void SVC_Handler(void); void DebugMon_Handler(void); void PendSV_Handler(void); void SysTick_Handler(void); /* USER CODE BEGIN EFP */ /* USER CODE END EFP */ #ifdef __cplusplus } #endif #endif /* __STM32L4xx_IT_H */ /* USER CODE END Header */ ``` ```c /** ****************************************************************************** * @file Templates_LL/Src/stm32l4xx_it.c * @author MCD Application Team * @brief Interrupt Service Routines. ****************************************************************************** * * Copyright (c) 2018 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. If no LICENSE file comes with * this code, it is provided AS-IS. * ****************************************************************************** */ /* Includes ------------------------------------------------------------------ */ #include "main.h" #include "stm32l4xx_it.h" /* Private includes ------------------------------------------------------------ */ /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Private typedef ------------------------------------------------------------ */ /* USER CODE BEGIN Private */ /* USER CODE END Private */ /* Private define ------------------------------------------------------------- */ /* USER CODE BEGIN Private */ /* USER CODE END Private */ /* Private macro -------------------------------------------------------------- */ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------- */ /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes ----------------------------------------------- */ /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------- */ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /* External variables -------------------------------------------------------- */ /* USER CODE BEGIN EV */ /* USER CODE END EV */ /******************************************************************************* * Cortex-M4 Processor Interruption and Exception Handlers *******************************************************************************/ /** * @brief This function handles Non-Maskable Interrupt and provides * a default handler. * @retval None */ void NMI_Handler(void) { /* USER CODE BEGIN NonMaskableInt_IRQn 0 */ /* USER CODE END NonMaskableInt_IRQn 0 */ /* USER CODE BEGIN NonMaskableInt_IRQn 1 */ while (1) { } /* USER CODE END NonMaskableInt_IRQn 1 */ } /** * @brief This function handles Hard Fault exception and provides a default handler. * @retval None */ void HardFault_Handler(void) { /* USER CODE BEGIN HardFault_IRQn 0 */ /* USER CODE END HardFault_IRQn 0 */ while (1) { /* USER CODE BEGIN W1_HardFault_STRUCTION */ /* Add here your code that wants to be executed once the memory management fault exception has occurred. */ /* USER CODE END W1_HardFault_STRUCTION */ } /* USER CODE END HardFault_IRQn 1 */ } /** * @brief This function handles Memory Management Fault and provides a default handler. * @retval None */ void MemManage_Handler(void) { /* USER CODE BEGIN MemoryManagement_IRQn 0 */ /* USER CODE END MemoryManagement_IRQn 0 */ while (1) { /* USER CODE BEGIN W1_MemoryManagement_STRUCTION */ /* Add here your code that wants to be executed once the memory management fault exception has occurred. */ /* USER CODE END W1_MemoryManagement_STRUCTION */ } /* USER CODE END MemoryManagement_IRQn 1 */ } /** * @brief This function handles Bus Fault exception and provides a default handler. * @retval None */ void BusFault_Handler(void) { /* USER CODE BEGIN BusFault_IRQn 0 */ /* USER CODE END BusFault_IRQn 0 */ while (1) { /* USER CODE BEGIN W1_BusFault_STRUCTION */ /* Add here your code that wants to be executed once the bus fault exception has occurred. */ /* USER CODE END W1_BusFault_STRUCTION */ } /* USER CODE END BusFault_IRQn 1 */ } /** * @brief This function handles Usage Fault exception and provides a default handler. * @retval None */ void UsageFault_Handler(void) { /* USER CODE BEGIN UsageFault_IRQn 0 */ /* USER CODE END UsageFault_IRQn 0 */ while (1) { /* USER CODE BEGIN W1_UsageFault_STRUCTION */ /* Add here your code that wants to be executed once the usage fault exception has occurred. */ /* USER CODE END W1_UsageFault_STRUCTION */ } /* USER CODE END UsageFault_IRQn 1 */ } /** * @brief This function handles System service call via SWI instruction and provides a default handler. * @retval None */ void SVC_Handler(void) { /* USER CODE BEGIN SVC_IRQn 0 */ /* USER CODE END SVC_IRQn 0 */ while (1) { /* USER CODE BEGIN W1_SVC_STRUCTION */ /* Add here your code that wants to be executed once the System Service Call exception has occurred. */ /* USER CODE END W1_SVC_STRUCTION */ } /* USER CODE END SVC_IRQn 1 */ } /** * @brief This function handles Debug Monitor exception and provides a default handler. * @retval None */ void DebugMon_Handler(void) { /* USER CODE BEGIN DebugMonitor_IRQn 0 */ /* USER CODE END DebugMon_IRQn 0 */ while (1) { /* USER CODE BEGIN W1_DebugMonitor_STRUCTION */ /* Add here your code that wants to be executed once the Debug Monitor exception has occurred. */ /* USER CODE END W1_DebugMonitor_STRUCTION */ } /* USER CODE END DebugMonitor_IRQn 1 */ } /** * @brief This function handles Pendable request for system service. * @retval None */ void PendSV_Handler(void) { /* USER CODE BEGIN PendSV_IRQn 0 */ /* USER CODE END PendSV_IRQn 0 */ while (1) { /* USER CODE BEGIN W1_PendSV_STRUCTION */ /* Add here your code that wants to be executed when the PendSV exception has occurred. */ /* USER CODE END W1_PendSV_STRUCTION */ } /* USER CODE END PendSV_IRQn 1 */ } /** * @brief This function handles SysTick interrupt and provides a default handler. * @retval None */ void SysTick_Handler(void) { /* USER CODE BEGIN SysTick_IRQn 0 */ /* USER CODE END SysTick_IRQn 0 */ HAL_IncTick(); /* USER CODE BEGIN SysTick_IRQn 1 */ /* USER CODE END SysTick_IRQn 1 */ } /* USER CODE BEGIN 4 */ /* USER CODE END 4 */ /** * @brief This function handles EXTI line 0 to 15 interrupts. * @param None * @retval None */ /** * @brief This function handles Interrupts generated by the EXTI lines. * @retval None */ void EXTI15_10_IRQHandler(void) { /* USER CODE BEGIN EXTI15_10_IRQn 0 */ /* USER CODE END EXTI15_10_IRQn 0 */ if (LL_EXTI_IsActiveFlag_10()) { LL_EXTI_ClearFlag_10(); /* USER CODE BEGIN DRIVER_UPPERCASE_EXTI10_IRQ */ /* USER CODE END DRIVER_UPPERCASE_EXTI10_IRQ */ } if (LL_EXTI_IsActiveFlag_11()) { LL_EXTI_ClearFlag_11(); /* USER CODE BEGIN DRIVER_UPPERCASE_EXTI11_IRQ */ /* USER CODE END DRIVER_UPPERCASE_EXTI11_IRQ */ } if (LL_EXTI_IsActiveFlag_12()) { LL_EXTI_ClearFlag_12(); /* USER CODE BEGIN DRIVER_UPPERCASE_EXTI12_IRQ */ /* USER CODE END DRIVER_UPPERCASE_EXTI12_IRQ */ } if (LL_EXTI_IsActiveFlag_13()) { LL_EXTI_ClearFlag_13(); /* USER CODE BEGIN DRIVER_UPPERCASE_EXTI13_IRQ */ /* USER CODE END DRIVER_UPPERCASE_EXTI13_IRQ */ } if (LL_EXTI_IsActiveFlag_14()) { LL_EXTI_ClearFlag_14(); /* USER CODE BEGIN DRIVER_UPPERCASE_EXTI14_IRQ */ /* USER CODE END DRIVER_UPPERCASE_EXTI14_IRQ */ } if (LL_EXTI_IsActiveFlag_15()) { LL_EXTI_ClearFlag_15(); /* USER CODE BEGIN DRIVER_UPPERCASE_EXTI15_IRQ */ /* USER CODE END DRIVER_UPPERCASE_EXTI15_IRQ */ } /* USER CODE END EXTI15_10_IRQn 1 */ } ``` -------------------------------- ### STM32L4 Main Program Flow (C) Source: https://github.com/stmicroelectronics/stm32cubel4/blob/master/Projects/NUCLEO-L476RG/Examples_LL/COMP/COMP_CompareGpioVsVrefInt_Window_IT/readme.txt The main program function that initializes the system, configures comparator peripherals, and enables the comparators. It includes essential setup for clocking and peripheral initialization. ```c #include "main.h" #include "stm32l4xx_ll_comp.h" #include "stm32l4xx_ll_exti.h" #include "stm32l4xx_ll_dac.h" #include "stm32l4xx_ll_gpio.h" #include "stm32l4xx_ll_rcc.h" #include "stm32l4xx_ll_pwr.h" #include "stm32l4xx_ll_bus.h" #include "stm32l4xx_ll_system.h" #ifdef CONSTANT_VOLTAGE_GENERATION #include "stm32l4xx_ll_tim.h" #endif /* Private function prototypes ------------------------------------------------*/ void SystemClock_Config(void); void MX_GPIO_Init(void); void MX_COMP2_COMP1_Init(void); #ifdef CONSTANT_VOLTAGE_GENERATION void MX_DAC1_Init(void); #endif /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* 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(); /* Activate merhabalar configuration */ MX_GPIO_Init(); /* USER CODE BEGIN 2 */ #ifdef CONSTANT_VOLTAGE_GENERATION MX_DAC1_Init(); #endif /* USER CODE END 2 */ /* Initialize peripherals */ MX_COMP2_COMP1_Init(); /* USER CODE BEGIN 3 */ #ifdef CONSTANT_VOLTAGE_GENERATION /* Trigger the DAC conversion to generate the intermediate voltage */ LL_DAC_Convert(DAC1, LL_DAC_CHANNEL_1); #endif /* Enable Comparators */ LL_COMP_Enable(COMP1); LL_COMP_Enable(COMP2); /* Infinite loop */ /* USER CODE END 3 */ } /** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) { LL_FLASH_SetLatency(LL_FLASH_LATENCY_4); while(LL_FLASH_GetLatency()!= LL_FLASH_LATENCY_4) { } LL_RCC_HSE_Enable(); /* Wait for HSE to stabilize. */ while(LL_RCC_HSE_IsReady() != 1) { } LL_PWR_EnableBkUpAccess(); LL_RCC_LSE_TurnOnClock(); while (LL_RCC_LSE_IsReady() != 1) { } LL_RCC_SetRTC_Source(LL_RCC_RTCSOURCE_LSE); LL_RCC_PLL_Disable(); while(LL_RCC_PLL_IsEnabled()) { } LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_1, 16, LL_RCC_PLLR_DIV_2); LL_RCC_PLL_Enable(); /* Wait for PLL to stabilize. */ while(LL_RCC_PLL_IsReady() != 1) { } LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL); /* Wait for system clock switch to be complete. */ while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) { } LL_AHB_SetDivider(LL_AHB_DIV_1); LL_APB1_SetDivider(LL_APB1_DIV_2); LL_APB2_SetDivider(LL_APB2_DIV_2); } /** * @brief GPIO Initialization Function * @param None * @retval None */ void MX_GPIO_Init(void) { LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; /* GPIO Ports Clock Enable */ LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOE); LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC); LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); /**/ /* Configure PA0 pin: Digital Input */ GPIO_InitStruct.Pin = LL_GPIO_PIN_0; GPIO_InitStruct.Mode = LL_GPIO_MODE_INPUT; GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; LL_GPIO_Init(GPIOA, &GPIO_InitStruct); /**/ /* Configure PC5 pin: Analog */ GPIO_InitStruct.Pin = LL_GPIO_PIN_5; GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; LL_GPIO_Init(GPIOC, &GPIO_InitStruct); /**/ /* Configure PA4 pin: Analog */ GPIO_InitStruct.Pin = LL_GPIO_PIN_4; GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; LL_GPIO_Init(GPIOA, &GPIO_InitStruct); /*Configure GPIO pin Output Level */ LL_GPIO_SetOutputPin(LD2_GPIO_Port, LD2_Pin); /**/ /* Configure PA5 pin: Output */ GPIO_InitStruct.Pin = LD2_Pin; GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; LL_GPIO_Init(LD2_GPIO_Port, &GPIO_InitStruct); } #ifdef CONSTANT_VOLTAGE_GENERATION /** * @brief DAC1 Initialization Function * @param None * @retval None */ void MX_DAC1_Init(void) { /* USER CODE BEGIN DAC1_Init 0 */ /* USER CODE END DAC1_Init 0 */ LL_DAC_InitTypeDef DAC_InitStruc = {0}; /* Peripheral clock enable */ LL_APBx1ENR1_DAC1EN_Enable(); /* DAC1 Initialization */ /* DAC1 channel1 with alignment none */ DAC_InitStruc.Trigger = LL_DAC_TRIG_SOFTWARE; DAC_InitStruc.WaveAutoEn = DISABLE; DAC_InitStruc.OutputBuffer = LL_DAC_OUTPUT_BUFFER_ENABLE; if (LL_DAC_Init(DAC1, LL_DAC_CHANNEL_1, &DAC_InitStruc) != SUCCESS) { Error_Handler(); } /* USER CODE BEGIN DAC1_Init 1 */ /* Set DAC channel1 voltage to 0.9V (half of Vdda ~ 1.8V) */ /* For Vdda=3.3V, 0.9V is approx 1/3.7 of Vdda. Need to set value = 0.9 * 4095 / 3.3 = 1118 */ LL_DAC_SetDualFrameData(DAC1, LL_DAC_CHANNEL_1, 0, 1118); /* USER CODE END DAC1_Init 1 */ } #endif /** * @brief This function is executed in case of error occurrence. * @retval None */ void Error_Handler(void) { /* USER CODE BEGIN Error_Handler_Debug */ /* User can add his own implementation to report the HAL error return state */ __disable_irq(); while (1) { } /* USER CODE END Error_Handler_Debug */ } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line number * @retval None */ void assert_failed(uint8_t *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ /* Empty comment line */ } #endif /* USE_FULL_ASSERT */ ``` -------------------------------- ### Ethernet Driver Setup and Usage Example Source: https://github.com/stmicroelectronics/stm32cubel4/blob/master/Drivers/CMSIS/docs/Driver/html/group__eth__interface__gr.html Illustrates a typical setup sequence for the Ethernet MAC and PHY drivers and provides example code for their usage. ```APIDOC ## Ethernet Driver Setup and Usage Example ### Description This section demonstrates a typical sequence for initializing and using the Ethernet MAC and PHY drivers. It highlights how these drivers are often used in combination, with the MAC providing a media interface to the PHY. ### Example Code ```c extern ARM_DRIVER_ETH_MAC Driver_ETH_MAC0; extern ARM_DRIVER_ETH_PHY Driver_ETH_PHY0; // Typical setup sequence: // 1. Initialize MAC driver // 2. Initialize PHY driver // 3. Configure MAC and PHY settings as needed // ... subsequent usage of driver functions ... ``` ``` -------------------------------- ### Component Referencing Syntax Examples Source: https://github.com/stmicroelectronics/stm32cubel4/blob/master/Drivers/CMSIS/docs/Pack/html/cp_SWComponents.html Illustrates the syntax for referencing software components and APIs within the STM32CubeL4 pack. This includes examples for CMSIS-RTOS API, CMSIS-DSP Library, and a file system drive. ```text ::CMSIS:RTOS (API) ARM::CMSIS:DSP ::File System:Drive:NOR ``` -------------------------------- ### USART Receiver Example (IT Mode) Description Source: https://github.com/stmicroelectronics/stm32cubel4/blob/master/Projects/NUCLEO-L476RG/Examples_LL/USART/USART_Communication_Rx_IT/readme.txt This section describes the USART Receiver example in Interrupt (IT) mode for STM32L4xx devices. It covers the file structure, hardware and software environment, setup instructions, and how to run the example. The example focuses on asynchronous reception with interrupt handling for character reception and LED control. ```c /** @page USART_Communication_Rx_IT USART Receiver example (IT Mode) @verbatim ****************************************************************************** * @file Examples_LL/USART/USART_Communication_Rx_IT/readme.txt * @author MCD Application Team * @brief Description of the USART_Communication_Rx_IT example. ****************************************************************************** @endverbatim @par Example Description Configuration of GPIO and USART peripherals to receive characters from an HyperTerminal (PC) in Asynchronous mode using an interrupt. The peripheral initialization uses LL unitary service functions for optimization purposes (performance and size). USART Peripheral is configured in asynchronous mode (115200 bauds, 8 data bit, 1 start bit, 1 stop bit, no parity). No HW flow control is used. GPIO associated to User push-button is linked with EXTI. USART RX Not Empty interrupt is enabled. Virtual Com port feature of STLINK could be used for UART communication between board and PC. Example execution: When character is received on USART Rx line, a RXNE interrupt occurs. USART IRQ Handler routine is then checking received character value. On a specific value ('S' or 's'), LED is turned On. Received character is echoed on Tx line. On press on push button, LED is turned Off. In case of errors, LED is blinking. @par Directory contents - USART/USART_Communication_Rx_IT/Inc/stm32l4xx_it.h Interrupt handlers header file - USART/USART_Communication_Rx_IT/Inc/main.h Header for main.c module - USART/USART_Communication_Rx_IT/Inc/stm32_assert.h Template file to include assert_failed function - USART/USART_Communication_Rx_IT/Src/stm32l4xx_it.c Interrupt handlers - USART/USART_Communication_Rx_IT/Src/main.c Main program - USART/USART_Communication_Rx_IT/Src/system_stm32l4xx.c STM32L4xx system source file @par Hardware and Software environment - This example runs on STM32L476xx devices. - This example has been tested with NUCLEO-L476RG Rev C board and can be easily tailored to any other supported device and development board. - NUCLEO-L476RG Rev C Set-up In order to select use of Virtual Com port feature of STLINK for connection between NUCLEO-L476RG Rev C and PC, User has to set USE_VCP_CONNECTION define to 1 in main.h file. If so, please ensure that USART communication between the target MCU and ST-LINK MCU is properly enabled on HW board in order to support Virtual Com Port (Default HW SB configuration allows use of VCP) If VCP is not used (USE_VCP_CONNECTION define set to 0 in main.h file), GPIOs connected to USART1 TX/RX (PA.09 and PA.10) should be wired to respectively RX and TX pins of PC UART (could be done through a USB to UART adapter). Connect GND between STM32 board and PC UART. - Launch serial communication SW on PC (as HyperTerminal or TeraTerm) with proper configuration (115200 bauds, 8 bits data, 1 stop bit, no parity, no HW flow control). Port should be selected according to USE_VCP_CONNECTION value. - Launch the program. Enter characters on PC communication SW side. @par How to use it ? In order to make the program work, you must do the following : - Open your preferred toolchain - Rebuild all files and load your image into target memory - Run the example */ ``` -------------------------------- ### STemWin Hello World Example Source: https://github.com/stmicroelectronics/stm32cubel4/blob/master/Projects/STM32CubeProjectsList.html A simple 'Hello World' example built using the STemWin graphical library. This serves as a basic introduction to STemWin's capabilities for creating graphical user interfaces. ```c // Example code for STemWin Hello World would go here. // This would involve STemWin initialization and basic text rendering. ``` -------------------------------- ### STM32L4 Main Program (C) Source: https://github.com/stmicroelectronics/stm32cubel4/blob/master/Projects/NUCLEO-L4P5ZG/Templates/readme.txt The main program file for the STM32L4 templates example. It initializes the system, configures peripherals, and contains the main loop where application logic resides. This is the entry point for the firmware. ```c /** ****************************************************************************** * @file Templates/Src/main.c * @author MCD Application Team * @brief Main program body ****************************************************************************** * * COPYRIGHT(c) 2019 STMicroelectronics * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of STMicroelectronics nor the names of its contributors may be used * to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "main.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN Private defines */ /* USER CODE END Private defines */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN Variables */ /* USER CODE END Variables */ /* Private function prototypes -----------------------------------------------*/ /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private functions ---------------------------------------------------------*/ /* USER CODE BEGIN Private */ /* USER CODE END Private */ /* Exported functions --------------------------------------------------------*/ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* 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 SysClock_Config_SW */ /** * @brief System Clock Configuration * @retval None */ //void SystemClock_Config(void) //{ // RCC_OscInitTypeDef RCC_OscInitStruct = {0}; // RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; // // /** Configure the main internal regulator output voltage // */ // if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK) // { // Error_Handler(); // } // /** Initializes the RCC Oscillators according to the configuration // * in the RCC_OscInitStruct object. // */ // RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; // RCC_OscInitStruct.HSEState = RCC_HSE_ON; // 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_DIV2; // RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; // if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct) != HAL_OK) // { // Error_Handler(); // } //} /* USER CODE END SysClock_Config_SW */ /* USER CODE BEGIN 2 */ ``` -------------------------------- ### STM32L4 Power RUN SMPS Mode Example Description Source: https://github.com/stmicroelectronics/stm32cubel4/blob/master/Projects/NUCLEO-L452RE-P/Examples/PWR/PWR_RUN_SMPS/readme.txt Provides a detailed description of the Power RUN SMPS Mode example for STM32L4 microcontrollers. It explains the functionalities, hardware setup, and usage instructions. ```text /** @page PWR_RUN_SMPS Power Mode Example @verbatim ****************************************************************************** * @file PWR/PWR_RUN_SMPS/readme.txt * @author MCD Application Team * @brief Description of the Power RUN SMPS Mode example. ****************************************************************************** @endverbatim @par Example Description How to use SMPS in Run mode and access the power consumption gain obtained when the SMPS feature is used. In the associated software, the system clock is set to 80 MHz, an EXTI line is connected to the user button through PC.13 and configured to generate an interrupt on falling edge upon key press. The SysTick is programmed to generate an interrupt each 1 ms. After start-up, the user has five seconds to press the user button. If the user button is pressed, at the end of the 5-second period, the MCU moves to RUN mode @ 80 MHz, SMPS on, power voltage scale 2. If the user button is not pressed during that time, at the end of the 5-second period, the MCU remains in RUN mode @ 80 MHz, SMPS off, power voltage scale 1. The five-secong long period is indicated to the user by LED4 which is blinking during that time. LED4 is used to monitor the system state as follows: - LED4 ON: configuration failed (system will go to an infinite loop) - LED4 toggling: 5-second long period on-going, during which the user can press the user button to activate SMPS - LED4 off: system in RUN mode (with or without SMPS) @note To measure the current consumption, please connect an amperemeter to JP6. @note Care must be taken when using HAL_Delay(), this function provides accurate delay (in milliseconds) based on variable incremented in SysTick ISR. This implies that if HAL_Delay() is called from a peripheral ISR process, then the SysTick interrupt must have higher priority (numerically lower) than the peripheral interrupt. Otherwise the caller ISR process will be blocked. To change the SysTick interrupt priority you have to use HAL_NVIC_SetPriority() function. @note The application needs to ensure that the SysTick time base is always set to 1 millisecond to have correct HAL operation. @par Directory contents - PWR/PWR_RUN_SMPS/Inc/stm32l4xx_conf.h HAL Configuration file - PWR/PWR_RUN_SMPS/Inc/stm32l4xx_it.h Header for stm32l4xx_it.c - PWR/PWR_RUN_SMPS/Inc/main.h Header file for main.c - PWR/PWR_RUN_SMPS/Src/system_stm32l4xx.c STM32L4xx system clock configuration file - PWR/PWR_RUN_SMPS/Src/stm32l4xx_it.c Interrupt handlers - PWR/PWR_RUN_SMPS/Src/main.c Main program @par Hardware and Software environment - This example runs on STM32L452xx devices - his example has been tested with STMicroelectronics NUCLEO-L452RE-P MB1319B (64 pins) board and can be easily tailored to any other supported device and development board. - NUCLEO-L452RE-P MB1319B (64 pins) set-up: - Use LED4 connected to PB.13 pin - User push-button connected to pin PC.13 (External line 13) @par How to use it ? In order to make the program work, you must do the following : - Open your preferred toolchain - Rebuild all files and load your image into target memory - Disconnect toolchain - Unplug the USB cable - Connect Amperemeter between the 2 pins of JP5 (IDD). - Plug the USB (starts the example) - Wait 10 seconds and measure power consumption (A: 80 MHz RUN R1). - Reset board (using reset button) - Press user button within 5 seconds (while led1 is toggling) for SMPS - Wait 10s and start measuring power consumption (B: 80 MHz RUN R1) */ ``` -------------------------------- ### Kernel Startup Initialization and Start CMSIS-RTOS v2 Source: https://github.com/stmicroelectronics/stm32cubel4/blob/master/Drivers/CMSIS/docs/RTOS2/html/os2MigrationGuide.html In CMSIS-RTOS v2, explicit calls to initialize and start the RTOS kernel are required. This contrasts with v1 where the kernel might start implicitly. The `osKernelInitialize()` function initializes the kernel, and `osKernelStart()` begins the scheduler. ```c #include "cmsis_os2.h" int main(void) { // ... other initialization ... // Initialize the RTOS Kernel osKernelInitialize(); // Start the RTOS Kernel scheduler osKernelStart(); // ... rest of your application ... } ```