Code generation for MIC32 (Hello, Engee!)¶
This demo presents the development of a Engee model for transmitting a Morse code message on a flashing LED, followed by code generation and execution on the MIK32 NUKE V0.3 debug board.
Introduction¶
In this example, a MIK32 NUKE V0.3 debug board based on the K1948VC018 MIK32 Amur microcontroller is used as the target device. Engee developed a model of forming and issuing pulses of Morse code encoded message. Since the embedded-programming program "Blink" is analogous to the first program "Hello, World!", in this example we will combine both programs, and the debug board LED will flash us the message "Hello, Engee!". We use GPIO 9 as the digital output to send the message, with the VD3 LED built into the debug board connected to it. Compilation and loading of the code into the microcontroller is done from VS Code with PlatformIO extension.
Model Description¶
The model of this example is mik32_blink.engee
. Blocks C Function
- "systemClockConfig" and "HAL_GPIO_WritePin_9" are used to configure the clocking system and work with peripherals (digital output) respectively. Block Repeating Sequence Stair
"Sequence" generates an encoded message - a binary code sequence specified by the variable Код_Морзе
.
Also, a data type conversion block is used to convert the signal at the output of the "Sequence" block, in this case from Float64
to UInt8
.
Connecting peripherals¶
The block C Function
"systemClockConfig" contains meaningful code only on the tab <\> StartCode
, which is used to configure the clocking subsystem of the microcontroller frequency monitor. The function generated from this block is only called during initialisation. The seq
ports of the C Function
blocks are used only to establish a clear sequence of blocks during code generation. To call functions from the standard library of hardware abstractions of the microcontroller MIK32 (mik32_hal
), used in the code of peripheral connection blocks, header files mik32_hal_pcc.h
and mik32_hal_gpio.h
are connected in the settings of block C Function
"systemClockConfig". These files are contained in the subfolder include
of the project.
It is not necessary to download these files and connect them to the project in the VS Code environment, as they are already contained in the corresponding PlatformIO packages when the environment is set up correctly.
A detailed description of the principles of operation of the code embedded in C Function
is given in the comments to the code blocks.
Sequence formation¶
We will simplify the message "Hello, Engee!" set for encoding in Morse code - the common abbreviation for the greeting is the message "ZDR". And since it will be continuously cyclically repeated, we will add a space at the end of it. Thus, our entire message will now look like this: "ZDR, ENGEE! ".
Morse code is encoded according to the following rules:
- the element with the shortest duration is a dot,
- a dash is equal in duration to three dots,
- the space between elements in one letter is equal in duration to a dot,
- the space between letters (signs) in one word is equal in duration to three dots,
- the space between words is equal to 7 points,
- at an average transmission speed of ~60-140 letters (characters) per minute, the duration of a point is approximately 100 ms.
Formation of spaces between letters is carried out at the end of the letter. It also follows that a space of 4 dots is used to separate words. The characters used in the message are encoded by the following sequences of elements:
Symbol | Morse Code | Binary code |
D or D | $-\cdot\cdot$ | 111 0 1 0 1 000 |
E or E | $\cdot$ | 1,000 |
G or G | $--\cdot$ | 111 0 111 0 1 000 |
N or H | $-\cdot$ | 111 0 1 000 |
R or P | $\cdot-\cdot$ | 1 0 111 0 1 000 |
Z or Z | $--\cdot\cdot$ | 111 0 111 0 1 0 1 000 |
, | $\cdot-\cdot-\cdot-$ | 1 0 111 0 1 0 111 0 1 0 111 0 1 0 111 000 |
! | $--\cdot\cdot--$ | 111 0 111 0 111 0 1 0 1 0 1 0 111 0 111 0 111 000 |
space | 0000 |
To write the encoded message in the block Repeating Sequence Stair
we will convert dots and dashes into units with the duration of 1 and 3 respectively. Gaps will be converted to zeros: between elements - 1 zero, between letters - 3 zeros, between words - 3 zeros at the end of the letter and 4 zeros of space.
Knowing all the codes for the characters in the message we can encode the whole message:
Символы = collect("ЗДР, ENGEE! ")
Код_Морзе_скрипт = (Int64)[];
for Итерация in 1:size(Символы, 1)
if (Символы[Итерация] == 'D')||(Символы[Итерация] == 'Д')
Код_символа = [1,1,1,0,1,0,1,0,0,0];
elseif (Символы[Итерация] == 'E')||(Символы[Итерация] == 'Е')
Код_символа = [1,0,0,0];
elseif (Символы[Итерация] == 'G')||(Символы[Итерация] == 'Г')
Код_символа = [1,1,1,0,1,1,1,0,1,0,0,0];
elseif (Символы[Итерация] == 'N')||(Символы[Итерация] == 'Н')
Код_символа = [1,1,1,0,1,0,0,0];
elseif (Символы[Итерация] == 'R')||(Символы[Итерация] == 'Р')
Код_символа = [1,0,1,1,1,0,1,0,0,0];
elseif (Символы[Итерация] == 'Z')||(Символы[Итерация] == 'З')
Код_символа = [1,1,1,0,1,1,1,0,1,0,1,0,0,0];
elseif Символы[Итерация] == ' '
Код_символа = [0,0,0,0];
elseif Символы[Итерация] == ','
Код_символа = [1,0,1,1,1,0,1,0,1,1,1,0,1,0,1,1,1,0,0,0];
elseif Символы[Итерация] == '!'
Код_символа = [1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,1,1,0,0,0];
end
Код_Морзе_скрипт = vcat(Код_Морзе_скрипт, Код_символа);
end
Now the variable Код_Морзе_скрипт
from the Engee workspace with our encoded message can be passed to the model.
Modelling results¶
To simulate a flashing LED with a coded message, let's download and run the model mik32_blink.engee
:
if "mik32_blink" in [m.name for m in engee.get_all_models()]
m = engee.open( "mik32_blink" );
else
m = engee.load( "$(@__DIR__)/mik32_blink.engee" );
end
# передаём для моделирования закодированное в скрипте сообщение -
# таким образом мы заменяем переменную `Код_Морзе`, загружаемую в обратных вызовах
Код_Морзе = Код_Морзе_скрипт
данные = engee.run(m);
From the obtained simulation data plot the signal Sequence.1
- the output of the sequence shaper:
using Plots
gr()
plot(данные["Sequence.1"].time, данные["Sequence.1"].value;
label = :none, st = :step, lw = 2, size = (800, 150),
title = "ЗДР, ENGEE! ")
As can be seen from the modelled graph, the formation of the coded message is successful and according to the specified rules. Now we can proceed to code generation and execution of the model code on the target device.
Code generation¶
Let's generate code from the model to load the control algorithm into the microcontroller:
engee.generate_code( "$(@__DIR__)/mik32_blink.engee",
"$(@__DIR__)/mik32_blink_code")
The files created in the folder mik32_blink_code
- header mik32_blink.h
and source mik32_blink.c
will be used further on in the project assembly. The generated file of the main program main.c
will not be used in the project, for code execution in the development environment prepared by main.c
, located in the root folder mik32_blink
of the example.
Preparing the project in the development environment¶
The development environment through which the project is built and loaded into the target device is VS Code with the PlatformIO add-on. The environment configurations and connections are not considered in this example, as they are described in detail at resources) of the controller developer.
From the example directory let's transfer the generated files, main.c
and the configuration file platformio.ini
to the PlatformIO project.
After that you can proceed to build the project and load the programme.
Code execution on MIK32¶
Let's connect the debug board MIK32 NUKE V0.3 to the USB-port of the computer, then in PlatformIO we can observe the connected device. To correctly identify the connection of this board requires a USB driver. The driver used in the example is libusbK
.
After successful connection, let's proceed to building the project:
"PLATFORMIO -> PROJECT TASKS -> mik32v2 -> General -> Build ".
If there are no build errors, load the compiled code into the microcontroller:
"PLATFORMIO -> PROJECT TASKS -> mik32v2 -> General -> Upload ".
As a result of executing the code generated from the Engee model, you can observe the formation of a Morse code encoded message by a blinking LED.
Conclusion¶
In this example we have considered the development of the Engee model for the control programme of the built-in LED to issue a coded message on the K1948VK018 MIK32 Amur microcontroller as part of the MIK32 NUKE V0.3 debug board. The developed model is embedded by generated files into the PlatformIO environment project for VS Code with further assembly, loading and execution on the target device.