LoRa E5 Dev Board example code in STM32 Cube IDE: LED Blink

ASHUTOSH SONI
11 min readJul 3, 2021

--

Photo by Vishnu Mohanan on Unsplash

Hi everyone, recently I came across a task where I was required to work on the new LoRa-E5 Dev Board and write some code for my specific use case. I was new to STM32 devices and the STM32CubeIDE provided by ST Microelectronics. I will walk you through my experiences in short and provide some basic but useful example codes in layman terms aimed for any beginner. If you are looking for a fully technical description on the topic, you might want to wait for my future blogs. LET’S GET STARTED THEN!!! 🔥

Introduction

The realm of coding in C/C++/Python etc., is completely different from programming a MCU (micro controller unit) in a lot of ways which we will discuss along the blog. People who have worked on the former will appreciate the new challenges involved in the later. Since the LoRa E5 dev-board was recently launched in the market, I really had a tough time to first of all find relevant resources in terms of blogs, YouTube videos, or anything for that matter and secondly, actual interpretation of those bits and pieces to write a working code myself. The first part is the driving factor for writing the blog, since there are a lot of rather complex and detailed knowledge of the various peripherals on the MCU required to be gained from the long datasheets or descriptive documents. For a beginner, this can be a bit overwhelming and frustrating at times. So lets break down the process.

Challenges in MCU programming which you should have knowledge about:

  1. Architecture of the processor (arm cortex model version etc.).
  2. Peripherals and their driver function codes. Eg. Hardware Abstraction Layer (HAL) and Low Layer (LL) for STM32.
  3. Pin-out of the board. (sketch of the board with detailed connections of the various peripherals onboard).
  4. Development environment for the board. Eg. STM32 Cube IDE for STM32 MCUs.

Most of the datasheets and description documents for a particular board are one Google (or DuckDuckGo 😜) away, but if just having the correct literature did your entire work, librarians would be the most literate species on Earth 😆. Jokes apart, let’s now focus on how to start the development of a simple LED blink program on the LoRa E5 Dev-board, but before we start let me give you some brief idea of the board and the STM32CubeIDE.

LoRa E5 Dev Board

The LoRa E5 Dev Board is part of the LoRa-E5 Development Kit manufactured by the Seeed Studios, which contains an antenna(EU868/US915), a USB type C cable, and a 2*AA 3V Battery Holder with the board itself. The board has a embedded LoRa-E5 STM32WLE5JC module which has the both the LoRa RF and the MCU on a single small chip. It is has an ARM Cortex-M4 core processor and Semtech SX126X LoRa chip which supports LoRaWAN and LoRa protocol worldwide (for more info follow wiki link).

STM32 Cube IDE

You can follow the link given just above to the official page to find all the relevant information of how to download for Linux/MacOS/Windows, how to use etc. In a nutshell, STM32CubeIDE is a development environment based on Eclipse IDE framework which helps users in software development for STM32 devices with detailed support for each MCU or dev-board made by ST Microelectronics. This means unlike other MCU software development environments, you won’t have compatibility issues since it will provide all the configurations completed tailored for the MCU that you select. You can choose the development board or the MCU/MPU from the Target Selector (we will see how to). The IDE also has a software named CubeMX which is used to setup the configurations of various peripherals such as UART, USART, I2C, SPI etc., on board before we write the user code. Frankly, there are thousands of lines of code 😢 in the form of .c and .h files which have to be present to drive the corresponding peripheral and these lines of code cannot and need not be written by the user 😌. Here comes the best part of using Cube IDE 😏. It auto generates the required peripheral initialization and other related files in a structured format in the project folder. The version details of the STM32CubeIDE installed on my machine is following (it is a good practice to mention the versions to avoid issues which may arise for users using a separate older versions):

Version: 1.6.1
Build: 9958_20210326_1446 (UTC)

Lets get started with a basic example code where we want to blink a Red LED present on the board at regular intervals of time (like blink sketch in Arduino).

LED Blink example code

Setting up the project

Download and install the STM32CubeIDE on the computer, select the workspace directory as per wish and open STM32CubeIDE. The workspace will contain all the project folders which you create.

For a new project, click File->New->STM32 Project. It will open a Target Selector window (Figure 1) where you can select the MCU/MPU or Dev board as per requirement. The LoRa E5 Dev-board was not available in the Board selector section, hence we will have to searchwith the STM32WLE5JC MCU present onboard. Enter “STM32WLE5JC” in the Part Number field and select the MCU from the results. Follow the onscreen instructions and leave rest as default (for basics). If setting up for the first time, it will download the necessary files for the particular chip. In my case the STM32Cube FW_WL V1.0.0 firmware package had to be installed (https://www.st.com/en/embedded-software/stm32cubewl.html for more info).

Figure 1: Target Selector

The project folder will be created with the name specified by you, say Blink. The toolbar shown in Figure 2 contains all the tools required to build, release, debug, run, etc., the project files. The file structure is quite simple and you can get used to it by simply exploring the same but for the basics you need to remember that the header (.h) files are present in Core->Inc while the corresponding program files (.c) files are present in the Core->Src folder.

Figure 2: Toolbar

Configuring .ioc file

The device configuration files in STMCubeIDE are saved with extension .ioc and these files contain all the initial setup code which will help auto generate the initialization codes and include the related files. We can easily find that the red LED is connected to the pin PB5 by referring the datasheet. Open the Blink.ioc file of the project, click on the Pinout & Configuration tab and select Pinout view in CubeMX. Find the pin PB5 (you can use the search bar given in the bottom too). Click on PB5 and select it as GPIO_Output (GPIO: General Purpose Input Output). You can select from the dropdown for each pin in the pinout view as per the requirement. You can add User Label to the pins, for easy reference to it while writing code, using the GPIO peripheral settings or simply right clicking on the pin. Let’s set the label for PB5 pin as LED. We are done with the configuration setup. Now click on the save button (2nd button from the left on the toolbar) or the Device Configuration Tool Code Generation (8th button from the left on toolbar) to generate the code from the Blink.ioc file.

Writing code

The main file or the starting file for the project is the main.c file (rhymes haa.. 😆). This will contain the main() function which will be the starting point of the entire project code execution, you can add function calls and/or user code in the same function and include the different files in the main.c file which you want to use in the project.

Before writing the user code for LED blinking, we need to know where to write the user code such that it does not get erased if we regenerate the code from the .ioc file which would obviously be a terrible experience if you loose a lot of important code due to this mistake. Each time you generate the code after altering anything in the .ioc file, all the changes made in the code created during auto generation are erased except the ones written in the designated user code comments. Lets see an example:

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

If you write some piece of code between the USER CODE BEGIN and END comments then the code will not get erased, which is a very useful feature. There are a lot of such comments created automatically for the user code by the IDE but a lot of times they won’t be present at the place you need them and you cannot create the comment on your own to fool the auto generation process 😜.

To write the code we need to have the HAL (Hardware Abstraction Layer) function documentation open to refer to (follow this link below for HAL description for this board).

We will need the HAL_GPIO_TogglePin() and the HAL_Delay() functions to make the led blink at regular intervals. The HAL_GPIO_TogglePin() toggles (alternates) the state (ON/OFF) for the GPIO pin given to the function as input on the given GPIO port. The HAL_Delay() adds the specified amount of delay to the code in millisecond (ms). The code which has to be executed repeatedly on the MCU is put inside the while(1) loop inside void main(void) function. The LED PB5 pin will be referred by user label LED and the following code should be pasted in the while(1) loop:

// code to blink the led every 1sHAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin); // toggles led pin
HAL_Delay(1000); // adds 1000ms i.e. 1s of delay

You will appreciate the use of user labels while dealing with a code without one. The pins are then referred to by numbers and you will not have an intuitive sense of the code when building larger projects.

Build, Upload and Debug

Build

After the code is written, the project has to be build in order to create the lower levels files required to be uploaded on the board. You can build the project by clicking on the Hammer button (5th button from the left) while an active file from the project is open in the editor (else the button won’t activate). You will need a .hex file to upload it using any stm32 programmer utility. By default, building the project won’t generate the .hex file. To enable it you need to right click the project in the Project Explorer and click on Properties, then refer to Figure 3 to enable .hex file generation.

Figure 3: Hex file generation enable

Upload

Once the .hex file is created, we need a utility to upload the file on the MCU. There are different ways to upload/flash the code files on the board but we will be using a ST-Link V2 clone (link) to upload the files using STM32CubeProgrammer software provided by ST Microelectronics (link given in the beginning of the section). It provides a large number of features to read and write data on the board. Pin connections are given in the following table from the ST-Link to the dev-board.

+-------------+---------------------------------------------+
| ST-Link Pin | LoRa E5 Dev Board Pin (in SWD/SWIM section) |
+-------------+---------------------------------------------+
| SWCLK | CLK |
| SWDIO | DIO |
| GND | GND |
| 3.3 V | VCC |
+-------------+---------------------------------------------+
  1. Plug in the ST-Link in one of the USB slots on the computer and open the STM32CubeProgrammer. From the dropdown on the top right corner, select ST-Link as the upload method. Click on Connect button.
  2. If it does not connect to the board and gives Target not found error, press the reset button on the board and then press Connect, release the reset, it should be connected after this.
  3. Select the .hex file from the Open file tab in Memory and File edition window. For the first time upload on the board, the board will be locked and you won’t be able to read or write anything on it.
  4. To enable the read/write option, go to Options Byte (OB) window and set the RDP in the Read Out Protection option to AA (Figure 4).
  5. Click on the Download button in the Memory and File edition view. The popup and the log will show the success or failure of the code upload.
Figure 4: STM32CubeProgrammer RDP setting

Debug

The STMCubeIDE also provides the option to debug the code where you can walk through the code and look for possible errors keeping watch at the various variables, setting up breakpoints and a ton of other features. To start debugging, click on the Bug button (13th button from the left) on the toolbar and it will ask you to setup the debug configurations. Select the ST-Link option and the it will detect the ST-Link ID once you click on scan (Figure 5 for more reference). The code will be uploaded on the board and the debug session will activate, you can explore the new tools in the debug perspective (CubeIDE terminology for view or window for a particular type of operation).

Figure 5: Debug configuration window

Congratulations!!! 😃, you have made it till the end 👏. I hope I was able to make smallest of details clear to you in a language which a beginner can understand. I have tried to focus on points which can make a beginner stuck for days if not awake of what to do and I want people not to waste time and learn from my experiences. This was just a basic LED blink code, but I will make more informative blogs with how to use OLED, I2C, UART/USART etc. So stay tuned!!! 👋

References

My GitHub: https://github.com/ashutosh952

--

--

ASHUTOSH SONI

BTech Honours Student in the Electrical Engineering Discipline at IIT Bhilai. Interested in topics such as Wireless Communications, LTE, 5G/6G, Drones, Embedded