{"id":2509,"date":"2024-05-04T15:04:17","date_gmt":"2024-05-04T15:04:17","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=2509"},"modified":"2024-05-04T15:04:19","modified_gmt":"2024-05-04T15:04:19","slug":"getting-started-with-lvgl-v9-with-stm32f429-disco-part1-environment-setup","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=2509","title":{"rendered":"Getting Started with LvGL V9 with STM32F429-disco Part1: Environment setup"},"content":{"rendered":"\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"300\" height=\"95\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/logo_lvgl.png\" alt=\"\" class=\"wp-image-2510\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/logo_lvgl.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/logo_lvgl-250x79.png 250w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/figure><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>In this guide, we shall take a look at what is LvGL and setup the environment to run LvGL on STM32F429-disco.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>In this guide, we shall cover the following:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>What is LvGL.<\/li><li>Environment Setup.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. What is LvGL:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>LVGL<\/strong>&nbsp;(Light and Versatile Graphics Library) is an&nbsp;<strong>open-source graphics library<\/strong>&nbsp;designed for creating&nbsp;<strong>embedded graphical user interfaces (GUIs)<\/strong>. It provides a comprehensive set of tools and features to build beautiful UIs with ease. Here are some key points about LVGL:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li><strong>Versatility<\/strong>: LVGL is suitable for a wide range of devices, including&nbsp;<strong>microcontrollers (MCUs)<\/strong>,&nbsp;<strong>microprocessors (MPUs)<\/strong>, and various display types. Whether you\u2019re working on a smartwatch, smartphone-like interface, or any other embedded system, LVGL can be a great choice.<\/li><li><strong>Widgets and Layouts<\/strong>: LVGL offers&nbsp;<strong>30+ built-in widgets<\/strong>, which are pre-designed UI elements like buttons, labels, sliders, and more. Additionally, it provides&nbsp;<strong>web-inspired layout managers<\/strong>&nbsp;to arrange these widgets efficiently.<\/li><li><strong>Typography and Fonts<\/strong>: LVGL supports a&nbsp;<strong>typography system<\/strong>&nbsp;that can handle many languages. You can easily render text with different fonts and styles.<\/li><li><strong>Low Memory Footprint<\/strong>: Despite its rich features, LVGL maintains a&nbsp;<strong>small memory footprint<\/strong>. For example, the LVGL library itself requires only around 50KB of RAM and 100KB of flash memory.<\/li><li><strong>No External Dependencies<\/strong>: LVGL is&nbsp;<strong>fully open-source<\/strong>&nbsp;and doesn\u2019t rely on any external libraries. This makes it easy to port to different platforms and integrate with various operating systems (OS) or bare-metal setups.<\/li><li><strong>Commercial Use<\/strong>: LVGL is&nbsp;<strong>free even for commercial projects<\/strong>, making it an attractive choice for both hobbyists and professional developers.<\/li><\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Collaborations and Support<\/h3>\n\n\n\n<p>Several companies and communities collaborate with LVGL:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>NXP<\/strong>: NXP tightly integrates LVGL into their ecosystem, allowing easy integration into MCUXpresso projects. They are also working on first-class support for VG-Lite and PXP accelerators on i.MX RT devices.<\/li><li><strong>Espressif<\/strong>: LVGL seamlessly integrates with Espressif\u2019s package manager, making it straightforward to get started. Espressif\u2019s display drivers work well with LVGL for IoT development.<\/li><li><strong>Xiaomi<\/strong>: Xiaomi has used LVGL in numerous devices and appreciates its performance and lightweight nature. They actively collaborate with LVGL\u2019s open-source community.<\/li><li><strong>Nuvoton<\/strong>: Nuvoton\u2019s customers use LVGL for developing smart devices related to the Industrial Internet of Things (IIoT).<\/li><li><strong>Renesas<\/strong>: Renesas pairs its advanced microcontrollers with LVGL, providing ready-to-use projects for their boards.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Environment Setup:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>Before we start, we need to setup STM32CubeIDE to work in register level programming, please following <a href=\"https:\/\/blog.embeddedexpert.io\/?p=1255\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=1255\" target=\"_blank\" rel=\"noreferrer noopener\">this guide<\/a> to set STM32CubeIDE.<\/p>\n\n\n\n<p>Just change STM32F411xE to the following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">STM32F429xx<\/pre><\/div>\n\n\n\n<p>This will tell the compiler to use STM32F429 as main header file<\/p>\n\n\n\n<p>We start off by creating new source file with name of <strong><em>sys_init.c<\/em><\/strong>. This source file shall contain the core setup to run STM32F429 at maximum speed of 180MHz.<\/p>\n\n\n\n<p>Within the source file:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;stm32f4xx.h&quot;\n\nvoid SystemInit (void)\n{\n\n\t#define PLL_M      4\n\t#define PLL_N      180\n\t#define PLL_P      2\n\t#define PLL_Q      9\n\n\t__IO uint32_t StartUpCounter = 0, HSEStatus = 0;\n\n\n\t  RCC-&gt;CR |= ((uint32_t)RCC_CR_HSEON);\n\n\n\t  do\n\t  {\n\t\tHSEStatus = RCC-&gt;CR &amp; RCC_CR_HSERDY;\n\t\tStartUpCounter++;\n\t  } while((HSEStatus == 0) &amp;&amp; (StartUpCounter != 3000));\n\n\t  if ((RCC-&gt;CR &amp; RCC_CR_HSERDY) != RESET)\n\t  {\n\t\tHSEStatus = (uint32_t)0x01;\n\t  }\n\t  else\n\t  {\n\t\tHSEStatus = (uint32_t)0x00;\n\t  }\n\n\t  if (HSEStatus == (uint32_t)0x01)\n\t  {\n\n\t\tRCC-&gt;APB1ENR |= RCC_APB1ENR_PWREN;\n\t\tPWR-&gt;CR &amp;= (uint32_t)~(PWR_CR_VOS);\n\n\n\t\tRCC-&gt;CFGR |= RCC_CFGR_HPRE_DIV1;\n\n\n\t\tRCC-&gt;CFGR |= RCC_CFGR_PPRE2_DIV1;\n\n\n\t\tRCC-&gt;CFGR |= RCC_CFGR_PPRE1_DIV2;\n\n\n\t\tRCC-&gt;PLLCFGR = PLL_M | (PLL_N &lt;&lt; 6) | (((PLL_P &gt;&gt; 1) -1) &lt;&lt; 16) |\n\t\t\t\t\t   (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q &lt;&lt; 24);\n\n\n\t\tRCC-&gt;CR |= RCC_CR_PLLON;\n\n\n\t\twhile((RCC-&gt;CR &amp; RCC_CR_PLLRDY) == 0)\n\t\t{\n\t\t}\n\n\t\t\/* Configure Flash prefetch, Instruction cache, Data cache and wait state *\/\n\t\tFLASH-&gt;ACR = FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;\n\n\t\t\/* Select the main PLL as system clock source *\/\n\t\tRCC-&gt;CFGR &amp;= (uint32_t)((uint32_t)~(RCC_CFGR_SW));\n\t\tRCC-&gt;CFGR |= RCC_CFGR_SW_PLL;\n\n\t\t\/* Wait till the main PLL is used as system clock source *\/\n\t\twhile ((RCC-&gt;CFGR &amp; (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL)\n\t\t{;}\n\t  }\n\t  else\n\t  { \/* If HSE fails to start-up, the application will have wrong clock\n\t\t\t configuration. User can add here some code to deal with this error *\/\n\t  }\n\n\t  \/*Enable FPU*\/\n\t  SCB-&gt;CPACR |= ((3UL &lt;&lt; 10*2)|(3UL &lt;&lt; 11*2));\n\n\t  \/*Enable cell compensation*\/\n\t  RCC-&gt;APB2ENR|=RCC_APB2ENR_SYSCFGEN ;\n\t  SYSCFG-&gt;CMPCR|=(1&lt;&lt;0);\n\t  while(!((SYSCFG-&gt;CMPCR)&amp;(1&lt;&lt;8))){;}\n}\n\n<\/pre><\/div>\n\n\n\n<p>For more information about how to configure the core, please refer to <a href=\"https:\/\/blog.embeddedexpert.io\/?p=454\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=454\" target=\"_blank\" rel=\"noreferrer noopener\">this guide<\/a>.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Now, create new source and header file with name of delay.c and delay.h respectively.<\/p>\n\n\n\n<p>Within delay.h header file:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#ifndef DELAY_H_\n#define DELAY_H_\n\n#include &quot;stdint.h&quot;\nvoid delay_init(uint32_t freq);\nuint64_t millis();\nvoid delay(uint32_t time);\n\n\n\n\n#endif \/* DELAY_H_ *\/<\/pre><\/div>\n\n\n\n<p>Within delay.c source file:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;delay.h&quot;\n#include &quot;stm32f4xx.h&quot;\n\n\n\n#define\tCTRL_ENABLE\t\t\t\t\t(1U&lt;&lt;0)\n#define CTRL_CLKSRC\t\t\t\t\t(1U&lt;&lt;2)\n#define CTRL_COUNTFLAG\t\t\t\t(1U&lt;&lt;16)\n#define CTRL_TICKINT\t\t\t\t(1U&lt;&lt;1)\n\n\nvolatile uint64_t mil;\n\nvoid delay_init(uint32_t freq)\n{\n\n\tSysTick-&gt;LOAD  = (freq\/1000) - 1;\n\n\t\/*Clear systick current value register *\/\n\tSysTick-&gt;VAL = 0;\n\n\t\/*Enable systick and select internal clk src*\/\n\tSysTick-&gt;CTRL = CTRL_ENABLE | CTRL_CLKSRC ;\n\n\t\/*Enable systick interrupt*\/\n\tSysTick-&gt;CTRL  |= CTRL_TICKINT;\n\n}\n\n\n\nuint64_t millis()\n\t{\n\t__disable_irq();\n\tuint64_t ml=mil;\n\t__enable_irq();\n\treturn ml;\n\t}\n\n\n\nvoid delay(uint32_t time)\n{\n\n\tuint64_t start=millis();\n\twhile((millis() - start) &lt; (time+1));\n}\n\nvoid SysTick_Handler(void)\n{\n\tmil++;\n}\n<\/pre><\/div>\n\n\n\n<p>In part 2, we shall cover the initialization of LCD and touch driver.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Stay tuned.<\/p>\n\n\n\n<p>Happy coding \ud83d\ude09 <\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this guide, we shall take a look at what is LvGL and setup the environment to run LvGL on STM32F429-disco. In this guide, we shall cover the following: What is LvGL. Environment Setup. 1. What is LvGL: LVGL&nbsp;(Light and Versatile Graphics Library) is an&nbsp;open-source graphics library&nbsp;designed for creating&nbsp;embedded graphical user interfaces (GUIs). It provides [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,19,11,12],"tags":[],"class_list":["post-2509","post","type-post","status-publish","format-standard","hentry","category-embedded-systems","category-lcd","category-peripheral-drivers","category-stm32"],"_links":{"self":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/2509"}],"collection":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2509"}],"version-history":[{"count":1,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/2509\/revisions"}],"predecessor-version":[{"id":2511,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/2509\/revisions\/2511"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2509"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2509"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2509"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}