This page is located in archive. Go to the latest version of this course pages. Go the latest version of this page.

Link to descrition of task: Description

Connection to the board

1/ Run GtkTerm on your PC (Applications→Development→Serial Port Terminal)

 GtkMenu: Configuration -> Port:
 Port:   /dev/ttyUSB0;  Baud rate: 115200; Parity: none;  Stopbit: 1

In GtkTerm window, press enter, if you do not see IP address or restart the board.

GtkTerm has also opened the command line window of MZAPO board OS. The login allows you entering commands for the remote system.

  • Login: root
  • Password: mzAPO35

Note: While you are writing password, you will not see any characters, not even *.

Be aware that GtkTerm represents the command line window of the remote Linux running in MZAPO board.

2/ SSH connection allows more possibilities than GtkTerm.

  • Open command line terminal of your PC computer: Applications→Systerm→Xfce Terminal
  • Add the private key of ssh by the command:



ssh-add /opt/zynq/ssh-connect/mzapo-root-key

3/ Mount the complete target file system into the /tmp subdirectory of your PC. Supply IP address of your MZAPO board discovered by GtkTerm.

/opt/zynq/sshfs-mount-target 192.168.202.xxx

4/ Copying files between PC and the board

The 'Makefile' file from MZAPO template uses opened SSH for comfortable work with the board.

But you can also use Midnight commander on PC for copying files, or alternatively, you can connect via SSH, so you can use SCP to transfer files between the target system and the host PC ssh -i /opt/zynq/ssh-connect/mzapo-root-key root@192.168.202.xxx, eventually, you can connect via ssh as user root ssh root@192.168.202.xxx

The part of the board used in the task


Before using knobs and led, you must map them into address space.

unsigned char *mem_base;

mem_base = map_phys_address(SPILED_REG_BASE_PHYS, SPILED_REG_SIZE, 0);

if (mem_base == NULL) exit(1);

Reading knobs values

uint32_t rgb_knobs_value;

rgb_knobs_value = *(volatile uint32_t*)(mem_base + SPILED_REG_KNOBS_8BIT_o);

The knobs data are returned as 4 bytes unsigned | buttons | R-knob | G knob | B knob |, i.e., the bits 7 to 0 are blue knob, bits 15 to 8 are green knob, bits 23 to 16 are red knob, bit 24 is blue knob button, 25 is green knob button, and 26 is red knob button. You can unpack then, e.g. by

int rk, gk, bk, rb, gb, bb;

rk = (rgb_knobs_value>>16) & 0xFF; // red knob position
... similar for green and blue
rb = (rgb_knobs_value>>26) & 1;    // red buttom
... similar for green and blue

32 LEDs are controlled by writing to their port. The next line will light on all LEDs.

*(volatile uint32_t*)(mem_base + SPILED_REG_LED_LINE_o) = 0xFFFFFFFF;

The board contains 2 RGB LEDs with variable colors. The value is 4 bytes | 0-unused | R- | G | B |. The following lines will set the color of the first led to yellow and the second to violet.

*(volatile uint32_t*)(mem_base + SPILED_REG_LED_RGB1_o) = 0x00FFFF00;
*(volatile uint32_t*)(mem_base + SPILED_REG_LED_RGB2_o) = 0x00FF00FF; 


LCD display has 480 columns and 320 rows. The mapping of LCD ports is perfored by:

unsigned char *parlcd_mem_base;

parlcd_mem_base = map_phys_address(PARLCD_REG_BASE_PHYS, PARLCD_REG_SIZE, 0);

if (parlcd_mem_base == NULL)  exit(1);

The initialization of LCD is required before the first usage of LCD. It should be performed only once time by calling:


To begin drawing, move LCD pixel pointer to point 0,0 - top left corner

*(volatile uint16_t*)(parlcd_mem_base + PARLCD_REG_CMD_o) = 0x2c;

Each subsequent write the data port of LCD fills a pointed pixel by color information and then, LCD data pointer is moved to next pixel in the current row. At the end of a row, LCD pixel pointer is moved to the beginning of a next row.

The following command writes black.

*(volatile uint16_t*)(parlcd_mem_base + PARLCD_REG_DATA_o) = 0x0;

A color information for LCD is 16 bit unsigned | 5 bits of Red | 6 bits of Green | 5 bits of Blue |. Thus, BLACK is 0x0, WHITE is 0xFFFF, RED is 0xF800, GREEN is 0x07E0, BLUE is 0x001F

Description of Semester Task 2018/19 - Control of Two Reflectors

Create the program for MZAPO board see the following illustration) that controls two RGB reflectors. The task is intended for groups of 2 students, but it can be solved by a single person as well.

A pair of RGB LEDs, named as LED1 and LED2 on PCB, are shown in the bottom quarter and represent both reflectors. Enter input parameters using the three rotary knobs marked ENCODER1, ENCODER2, and ENCODER3 on the PCB.

Necessary Functions

The color of the reflector light color is always selected in the HSV / HSB color model, see http://colorizer.org/ . Be aware that the RGB-LED cannot distinguish the full range of colors as displays, but depending on its brightness, it displays from 256 (extreme) to 1024 (medium brightness). Select the change steps accordingly. On the web, you will find a number of C programs to convert from HSV to RGB.


  • The assignment will take place on Friday, May of 31th.
  • In case of delayed submission, the rating will be reduced by 10 points for for each subsequent week.
  • Download source code in ZIP to https://cw.felk.cvut.cz/brute/ for plagiarism check.
  • Documentation (user manual and technical report) download to SEMDOC section of brute. One page describing designed function is fully sufficient.

Note: If you work in a team, you need to set up a team before downloading, and it will also apply to individuals. Team creation allows working in pairs.

Scoring conditions

The solution is divided into scored categories whose values are added together.

From 5 to 25 points - Control clarity

  • 5 - The LCD display shows the selected mode and instantaneous adjustment of both reflectors. The option is changed by the knobs.
  • 15 – The LCD display shows not only the mode and settings but also lists a clear text menu where you can select the settings.
  • 25 – The same as in the previous point, but the display can be set not the only normal font, but also double magnified font, so that even people with poor eyesight can read it well.

From 5 to 13 points – light effects

Effects are added to reflector lights and their points are added together. The unit must remember effects, i.e. after setting another effect, you can return to the previous one without having to enter its values again. If the effect is running, its values can be changed without having to interrupt it, so the result is immediately visible.

  • 4 – base points - static light whose color is selected in three modes. Each reflector can be set:
  1. individually - only the selected reflector is set and the other is not changed.
  2. Together - they change simultaneously.
  3. Copy - the reflector takes the setting from the other.
  • +5 – continuous color change - the reflector continuously changes between a pair of colors along a track in the HSV model. Again, this effect can only be selected “individually” for a single spotlight, or “common” for both, or for both in anti-phase. The change time can be set the same as the end colors.
  • +4 – flashing - lighting on with set color can be interrupted with three independently selected times:

(a) the duration of continuous illumination; (b) the extinction time; © the phase shift of one reflector to the other. -

  1. Individually - the flashing is only set for the selected spotlight and the other is not changed.
  2. Together - set at the same time for both reflectors.
  3. Phase Offset - With one spotlight, the phase of the set flashing can be shifted.

12 points – Control of Reflectors over Ethernet

The last point will be very demanding and it is not necessary to solve it for merely obtaining credit. However, brave students who want to achieve A without a test will not miss Ethernet, because without it they will cross the limit of 90 points from the exercise. If someone omits it, he can also get A, but only after writing a good test!:-)

Task: The unit is not only able to control its reflectors, but also to connect to and control another unit. Therefore, it has to find out its IP address and then send commands via network packets.

Design appropriate protocols and how to communicate with the second unit. You should detect the existence of the second unit and then connect to it at any time, and then disconnect and connect again. If you want A mark without a written test, prove to us that you are a C code-expert and the exam would only keep you from learning to other subjects.

Appendix: The initial application creation template

The application template is in the directory


The following files are included in the template

  • Makefile - rules for building and remote running of an application
  • Change_me.c - source code with main function main - template to be renamed
  • Font_prop14x16.c - raster proportional width font 14×16 (width x height points)
  • Font_rom8x16.c - raster fixed width font 8×16
  • Font_types.h - definition of type used for font description
  • Mzapo_parlcd.h - declaration of functions for low level access to the LCD display
  • Mzapo_parlcd.c - implementation of low-level access to the LCD display
  • Mzapo_phys.h - declaration of function for mapping the physical range of addresses into the application process
  • Mzapo_phys.c - implementation of a physical address mapping function into an application process
  • Mzapo_regs.h - definition of base addresses and MZ_APO tutorials

A more detailed description of the design registers can be found in documentation of MZ_APO.

The `Makefile` rules for the build program need to be customized for your own application. The application will consist of one or more source files in the language C (files with the extension `*.c`) or in C ++ (files with the extension `*.cpp`).

An example with the main function

is in the sample file `change_me.c` which should be replaced, renamed as application-specific file.

A list of source files is set in the SOURCES variable, see below Part of the `Makefile` file

SOURCES = change_me.c mzapo_phys.c mzapo_parlcd.c
#SOURCES + = font_prop14x16.c font_rom8x16.c

In the first line, you need to edit the name of your main application file. If fonts are used, you need to uncomment the second line. To add other needed files, it is possible to list them in these two lines or repeating them with += for adding other needed files. Header files (`* .h`) are not listed in make files, they are inserted by C preprocessor.

The name of the desired binary executable is assigned in the variable TARGET_EXE

The translation is done by simply calling the build program

where the first rule found is `all`.

To delete generated files (object files, application binary code and automatically generated dependencies), use `clean` object. Objects can also be combined

make clean all

Any compilation when you change and run an application on a remote drive is done when invoking the object `run`

make TARGET_IP=192.168.202.xxx run

Automatic login, data transfer and application launch on target device with the given IP address requires an already-established private key in the SSH agent for that session


The application is first copied to the subdirectory /tmp created by user's login name and, then, the application is running with the default Both input and output are available on the developer's computer via SSH connections.

Files are also available in GitLab FEL via ssh (required public key):
Alternatively, via https:

Unconnected / Datagram Communications in IP Network (Internet Protocol)

Currently, the IP (Internet Protokol) is the most common standard for communication between computers and devices. The protocol is a higher packet, datagram and link layer protocol. To implement our own frame transfer, a variety of technologies are available on local networks. The most widespread is ETHERNET, which does not, however, address the transmission of frames between multiple networks in its basic formats.

The IP protocol exists in two versions IPv4, which uses to identify the interface. Each computer on the World Wide 32-bit address. Gradually, it passes to a new version of IPv6 that uses 128-bit addresses with better sophisticated assignment and communication rules.

A simpler version of IPv4 is expected to work on a semester task. Above basic a network layer, there is several other protocols specializing in different needs and types of transmission. The best known is the protocol TCP which serves to ensure a secure connection with the complete acknowledgment of receipt mechanism give. The data stream is suspended in the event of packet loss and re-sending is secured undelivered data. Protocol is used, for example, for the most widespread transport application Protocols and HTTP, HTTPS, and SSH services. However, TCP is not suitable for parallel delivery messages with a general destination address to all participants on the local network (Broadcast).

*In order to maintain the list of all the connected units*, the unconnected datagram protocol UDP will be used within your application that allows sending status information to the local network without defining the destination address. Such messages can then receive by all units on the local network.

An example of a simple program in the role of the server and the other in the client can be found, for example in the Beej's Guide to Network Programming manual.

First you need to set up a network socket

   Int sockfd;

   If ((sockfd = socket (AF_INET, SOCK_DGRAM, 0)) == -1) {
        Perror ("socket");
        Exit (1);

The AF_INET option specifies the IPv4 address family, SOCK_DGRAM then selects the UDP unconnected service. More about calling socket in Beej's Guide or in https://www.gnu.org/software/libc/manual/html_node/Creating-a-Socket.html#Creating-a-Socket] GNU C library documentation used on GNU / Linux.

Select a local port, on which the application listens and which is used with the outbound IP address. The computer / drive interface is selected by calling bind (GNU).

Because the datagrams could be sent to all local area network units by mistake, this option must be enabled

    Int broadcast = 1;

    If (setsockopt (sockfd, SOL_SOCKET, SO_BROADCAST, & broadcast,
        Sizeof broadcast) == -1) {
        Perror ("setsockopt (SO_BROADCAST)");
        Exit (1);

It is also possible to use calls sendto and recvfrom to send messages.

Basic example of binding (labeling) IPv4 socket to the service specific port number to be accessible from all network interfaces. The value MY_PORT is 16-bit number in the range 1 to 65535. The network addresses are stored in the network stack data structures in the IP network standard byte order which is big-endian one. The port number has to be converted from the CPU native (h = host) order to the network (n = network) byte order for this reason. The port numbers in the range from 1 to 1000 are reserved for system/privileged services and can be used/requested for the bind only by programs with administrator privilege or delegated privilege for full network stack control.

  struct sockaddr_in bindaddr;

  memset(&bindaddr, 0, sizeof(bindaddr));
  bindaddr.sin_family = AF_INET;
  bindaddr.sin_port = htons(MY_PORT);
  bindaddr.sin_addr.s_addr = INADDR_ANY;

  if (bind(sockfd, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) == -1) {

By default, system blocks reassignment of the same port number for the new instance of the service to new socket for some while after previous user has closed/released the port. That is why it is worthwhile to prevent this temporal blocking before bind() call when service should operate on the predefined port number.

  int yes=1;

  if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes,
                sizeof(yes)) == -1) {
    perror("setsockopt (SO_REUSEADDR)");

Because unintentional sending of broadcast to the network can lead to high load and disturbance of other communications, the broadcast transmission is disable for new socked by default. It can be enabled by set of the socket option

    int broadcast = 1;

    if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &broadcast,
        sizeof broadcast) == -1) {
        perror("setsockopt (SO_BROADCAST)");

The datagrams corresponding UDP services can be send by sendto call and received by recvfrom call.

IPv4 address for broadcast datagram sending to the local network can be setup as

  struct sockaddr_in braddr;

  memset(&braddr, 0, sizeof(braddr));
  braddr.sin_family = AF_INET;
  braddr.sin_port = htons(HELLO_SERVICE_PORT);
  braddr.sin_addr.s_addr = INADDR_BROADCAST;

Simple test of UDP communication from a command line

Server / listener of UDP packed receiving on all network interfaces starting

nc -u -l -p 44444

Starting command to send message

nc -u 44444

courses/b35apo/en/tutorials/10/start.txt · Last modified: 2019/06/27 20:48 by pisa