RP2040 and PI PICO Software Development Tools

The project software will be partially developed using multiple Raspberry PI Pico microcontroller boards. Subcomponents of the design will be breadboarded and tested before the initial prototype PCB is ordered. The Raspberry PI Debug Probe will be used to load and debug code.

The home page for the Raspberry PI RP2040 microcontroller is Raspberry PI RP2040 Microcontroller. Installation of the tools for use with the PI Pico are covered in “Getting started with Raspberry Pi PicoC/C++ development with Raspberry Pi Pico and other RP2040-based microcontroller boards“. Chapter 2 of this guide describes tool installation for Linux. Chapter 9 covers tool installation on Apple macOS and on Microsoft Windows. I installed the tools on Ubuntu 22.04 running under “Windows Subsystem for Linux” (wsl2).

Windows Subsystem for Linux (WSL)

Install WSL (version 2) from the Microsoft store. By default, the latest version of the Ubuntu distribution is installed. You may choose a different Linux distribution. More details of the WSL installation can be found at WSL Install. You must be running Windows 10 version 2004 and higher (Build 19041 and higher) or Windows 11 to install the latest version of WSL.

An advantage of WSL 2 is that allows Linux GUI applications. The procedure for installing and running Linux GUI applications is here. Run Linux GUI apps on the Windows Subsystem for Linux

Install the SDK and Toolchain

Install the SDK as described in section 2.1 of Chapter 2. Install the Toolchain following section 2.2. If installing on Ubuntu or Debian, pay attention to the NOTE at the end of this section. Update the SDK as described in section 2.3.

If you like follow on to Chapters 3 and 4 to verify the the example code builds and runs.

The C/C++ SDK is described in more detail in Raspberry Pi Pico C/C++ SDK – Libraries and tools for C/C++ development on RP2040 microcontrollers. Appendix D discusses board configuration. This information will be necessary to develop code to run on our custom board.

Raspberry PI Debug Probe

The Raspberry PI Debug Probe is a USB device that provides both a UART serial port and a standard Arm Serial Wire Debug (SWD) interface. It will be used both to flash code and to debug code via OpenOCD. This is the documentation for the Raspberry PI Debug Probe.

Install OpenOCD

To support debugging both cores, build OpenOCD from source code. Follow the instructions in the documentation starting after the first command in the Linux (and Raspberry Pi) section of the OpenOCD installation instructions.

When I ran the ./bootstrap command I got the following output on the terminal.

$ ./bootstrap
aclocal --warnings=all
configure.ac:32: error: Macro PKG_PROG_PKG_CONFIG is not available. It is usually defined in file pkg.m4 provided by package pkg-config.
configure.ac:32: the top level
autom4te: error: /usr/bin/m4 failed with exit status: 1
aclocal: error: autom4te failed with exit status: 1

I verified that pkg-config was not installed on my system using

$ dpkg -s pkg-config

Install pkg-config with the following commands.

$ sudo apt-get install -y pkg-config
$ sudo apt-get install -y pkg-config

After the successful installation of pkg-config, rerun the ./bootstrap command from the openocd directory. Continue with the installation as described in the documentation.

Install GDB

$ sudo apt install gdb-multiarch

Uploading Programs to the Pico

The Pico Debug Probes allows binary programs to be uploaded via the SWD port and OpenOCD. There is no need to push and hold the BOOTSEL button. Uploading new code becomes hands free. Change directory to the build directory of one of the pico examples; blink for example. Load the code with the debug probe as shown below. The connection fails. The problem is that the USB port is not connected to WSL2.

$ cd ~/pico/pico-examples/build/blink/
$ sudo openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c "adapter speed 5000" -c "program blink.elf verify reset exit"
Open On-Chip Debugger 0.12.0-g4d87f6d (2023-08-18-11:16)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
Info : Hardware thread awareness created
Info : Hardware thread awareness created
adapter speed: 5000 kHz

Error: unable to find a matching CMSIS-DAP device
** OpenOCD init failed **
shutdown command invoked

$

Open a windows PowerShell as Administrator, list the USB devices and attach the CMSIS-DAP interface device. Attaching the USB device failed.

This image has an empty alt attribute; its file name is attach_usb_fail.jpg

The usbip client must be installed on the Ubuntu distribution. Install using the commands.

sudo apt install linux-tools-virtual hwdata
sudo update-alternatives --install /usr/local/bin/usbip usbip `ls /usr/lib/linux-tools/*/usbip | tail -n1` 20

Attaching the USB port from the Windows PowerShell should now succeed.

sudo openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c "adapter speed 5000" -c "program blink.elf verify reset exit"
Open On-Chip Debugger 0.12.0-g4d87f6d (2023-08-18-11:16)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Info : Hardware thread awareness created
Info : Hardware thread awareness created
adapter speed: 5000 kHz

Info : Using CMSIS-DAPv2 interface with VID:PID=0x2e8a:0x000c, serial=E6614103E73B5D2F
Info : CMSIS-DAP: SWD supported
Info : CMSIS-DAP: Atomic commands supported
Info : CMSIS-DAP: Test domain timer supported
Info : CMSIS-DAP: FW Version = 2.0.0
Info : CMSIS-DAP: Interface Initialised (SWD)
Info : SWCLK/TCK = 0 SWDIO/TMS = 0 TDI = 0 TDO = 0 nTRST = 0 nRESET = 0
Info : CMSIS-DAP: Interface ready
Info : clock speed 5000 kHz
Info : SWD DPIDR 0x0bc12477, DLPIDR 0x00000001
Info : SWD DPIDR 0x0bc12477, DLPIDR 0x10000001
Info : [rp2040.core0] Cortex-M0+ r0p1 processor detected
Info : [rp2040.core0] target has 4 breakpoints, 2 watchpoints
Info : [rp2040.core1] Cortex-M0+ r0p1 processor detected
Info : [rp2040.core1] target has 4 breakpoints, 2 watchpoints
Info : starting gdb server for rp2040.core0 on 3333
Info : Listening on port 3333 for gdb connections
[rp2040.core0] halted due to debug-request, current mode: Thread
xPSR: 0xf1000000 pc: 0x000000ea msp: 0x20041f00
[rp2040.core1] halted due to debug-request, current mode: Thread
xPSR: 0xf1000000 pc: 0x000000ea msp: 0x20041f00
** Programming Started **
Info : Found flash device 'win w25q16jv' (ID 0x001540ef)
Info : RP2040 B0 Flash Probe: 2097152 bytes @0x10000000, in 32 sectors

Warn : Adding extra erase range, 0x10002200 .. 0x1000ffff
** Programming Finished **
** Verify Started **
** Verified OK **
** Resetting Target **
shutdown command invoked
$

Debug a Program with SWD

In the GDB debugger.

$ sudo apt install gdb-multiarch

Rebuild pico-examples with CMAKE_BUILD_TYPE=Debug. If you have already set PICO_SDK_PATH in your ~/.bashrc file skip the “export” command. You can check the value of PICO_SDK_PATH with

$ echo $PICO_SDK_PATH
$ cd ~/pico/pico-examples
$ rm -rf build
$ mkdir build
$ cd build
$ export PICO_SDK_PATH=../../pico-sdk
$ cmake -DCMAKE_BUILD_TYPE=Debug ..
$ cd blink
$ make

Attach OpenOCD via the SWD interface.

$ sudo openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c "adapter speed 5000"

The output should look something like this.

Open On-Chip Debugger 0.12.0-g4d87f6d (2023-08-18-11:16)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Info : Hardware thread awareness created
Info : Hardware thread awareness created
adapter speed: 5000 kHz

Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : Using CMSIS-DAPv2 interface with VID:PID=0x2e8a:0x000c, serial=E6614103E73B5D2F
Info : CMSIS-DAP: SWD supported
Info : CMSIS-DAP: Atomic commands supported
Info : CMSIS-DAP: Test domain timer supported
Info : CMSIS-DAP: FW Version = 2.0.0
Info : CMSIS-DAP: Interface Initialised (SWD)
Info : SWCLK/TCK = 0 SWDIO/TMS = 0 TDI = 0 TDO = 0 nTRST = 0 nRESET = 0
Info : CMSIS-DAP: Interface ready
Info : clock speed 5000 kHz
Info : SWD DPIDR 0x0bc12477, DLPIDR 0x00000001
Info : SWD DPIDR 0x0bc12477, DLPIDR 0x10000001
Info : [rp2040.core0] Cortex-M0+ r0p1 processor detected
Info : [rp2040.core0] target has 4 breakpoints, 2 watchpoints
Info : [rp2040.core1] Cortex-M0+ r0p1 processor detected
Info : [rp2040.core1] target has 4 breakpoints, 2 watchpoints
Info : starting gdb server for rp2040.core0 on 3333
Info : Listening on port 3333 for gdb connections

Open a second terminal window. You can do this with a Shift-click on the WSL2 icon in the taskbar. In the newly opened terminal, change directory containing the built binary. Start GDB.

$ cd ~/pico/pico-examples/build/blink/
$ gdb-multiarch blink.elf
GNU gdb (Ubuntu 12.1-0ubuntu1~22.04) 12.1
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
https://www.gnu.org/software/gdb/bugs/.
Find the GDB manual and other documentation resources online at:
http://www.gnu.org/software/gdb/documentation/.

For help, type "help".
Type "apropos word" to search for commands related to "word"…
Reading symbols from blink.elf…
(gdb)

This starts the GDB command line debugger. You can get a text user interface to GDB using the -tui command line option.

$ gdb-multiarch -tui blin.exe

This gives you something like this.

A Graphical Interface to GDB

Microsoft Visual Studio Code (I couldn’t make this work.)

One potential graphical interface to GDB is Microsoft Visual Studio Code. can be used as a graphical user interface to GDB as well as a coding environment. Chapter 7 of “Getting Started with Raspberry PI PicoC++ development with Raspberry PI Pico and other RP2040-based microcontroller boards“, provides instruction for installing VSCode A guide to installing and using Visual Studio Code on Raspberry Pi OS. I am using Ubuntu as my development OS. This link provides instructions for installing VSCode on Ubuntu 22.04. Note, I was not able to make this install work.

If you follow this procedure begin with the following command to become the root user. This will be required to write to root owned directories.

$ sudo -i

I followed this procedure. When I finished and typed the command to verify the install, I got the following output.

# code --version --user-data-dir
To use Visual Studio Code with the Windows Subsystem for Linux, please install Visual Studio Code in Windows and uninstall the Linux version in WSL. You can then use the code command in a WSL terminal just as you would in a normal command prompt.
Do you want to continue anyway? [y/N] y

Following the se instructions, I uninstalled VSCode as follows.

# apt purge code
# apt autoremove

After installing VSCode in Windows from the Microsoft Store, I ran in from a Uduntu terminal as suggested. Here is the result.

$ code
/mnt/c/Users/glena/AppData/Local/Programs/Microsoft VS Code/bin/code: 61: /mnt/c/Users/glena/AppData/Local/Programs/Microsoft VS Code/Code.exe: Exec format error

One suggestion online to fix this issue was to edit the /etc/wsl.conf file in Ubuntu to disable systemd.

[boot]
systemd=false

This did not fix the problem for me. The error remained.

Install gdbgui

gdbgui is a browser based GUI for GDB. Therefore a browser, if not already present must be installed. I installed Google Chrome using the instructions from Microsoft’s WSL Gui-Apps Tutorial.

The recommended way to install gdbgui is to use pipx. I installed pipx as follows,

$ sudo apt update
$ sudo apt install pipx

and then used pipx to install gdbgui.

$ pipx install gdbgui
installed package gdbgui 0.15.1.0, installed using Python 3.10.12
These apps are now globally available
- gdbgui
⚠️ Note: '/home/glenafield/.local/bin' is not on your PATH environment variable. These apps will not be globally
accessible until your PATH is updated. Run pipx ensurepath to automatically add it, or manually modify your PATH
in your shell's config file (i.e. ~/.bashrc).
done! ✨ 🌟 ✨
$ pipx ensurepath
Success! Added /home/glenafield/.local/bin to the PATH environment variable.

Consider adding shell completions for pipx. Run 'pipx completions' for instructions.

You will need to open a new terminal or re-login for the PATH changes to take effect.

Otherwise pipx is ready to go! ✨ 🌟 ✨

Using gdbgui

Using Windows Powershell as administrator make sure the the Pico Probe USB port is attached is attached to WSL.

Attach OpenOCD via the SWD interface.

$ sudo openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c "adapter speed 5000"

Open a new Ubuntu terminal window. Shift-click on the WSL icon in the taskbar. Start Google Chrome in the background.

$ google-chrome&

Project – US-AFSRM and Drive

This is my first post in a while. Over the past three years haven’t had much spare time to work on this site. I had been working full-time for a company that makes high pole count permanent magnet synchronous motors (PMSM). While there I worked on motor cogging reduction/elimination using active control. This required a deeper dive into motor physics and developed an interest in various motor topologies. One type of motor I find interesting, is the switched reluctance motor (SRM). SRM’s have a simple, low-cost construction which doesn’t require permanent magnets. This allows reliable operation at high speed and high temperature. The challenge with SRMs is, high torque ripple, acoustic noise and vibration. My goal with this project is to build my own SRM, associated drive electronics, firmware and software which will allow experimentation with a variety of control methods.

There are many good references for switched reluctance motor. I find that my go-to reference is;

Switched Reluctance Motor Drives – Fundamentals to Applications, Ed. Berker Bilgen, James Weisheng Jiang &Ali Amadi, CRC Press, Taylor and Frances Group, Boca Raton Fl.

I purchased the Kindle version of the book from Amazon. I found the particular motor topology which I have selected in the Electric Power Applications journal of the Institution of Engineering and Technology (IET).

Hossein Torkaman , Aghil Ghaheri, Ali Keyhani, Axial flux switched reluctance machines: a comprehensive review of design and topologies, IET Electr. Power Appl., 2019, Vol. 13 Iss. 3, pp. 310-321

This paper refers to my selected topology as Single-Phase US-AFSRM. This is short for “UShaped stator”Axial Flex Synchronous Reluctance Machine” Note the use of “machine” rather than “motor”. This is done to reflect that these machines may be run as motors or generators. Also “synchronous” rather than “switched” to indicate the type of switching used. The initial concept is shown below. This is known as an out-runner motor. The motor’s rotor spins around an interior stator. This single puck (I’m Canadian eh!) is only a single phase motor. Multiple phases can be obtained by stacking multiple pucks. Alignment pins placed in the holes of the rotor shaft permit offsets for up to 12 independently aligned phases. A minimum of one puck is required for each phase. Generally more phases permit the generation not just more torque but smoother torque. The cost of this is adding drive electronics for each phase. Torque can be increased for a fixed number of phases by stacking multiple pucks for each phase at the same alignment and wiring their coils in parallel. Make sure that the power electronics are capable of driving the extra current at the lower resistance and inductance presented by parallel connected coils.

The system supports attaching drive electronics to each puck. A preliminary design is shown below. This is the PCB, which connects to the outside world. There is still some room on the board. I hadn’t planned on adding any power electronics to this PCB. My intent is to put the motor drive power components on a separate PCB(s). These could be swapped in and out depending on the type of motor or number of phases. I could add some bus capacitors for the motor power supply. Logic power comes from a separate 8 to 28 Volt DC supply. Another option is to add an AC/DC converter to this PCB to provide logic power from a single phase AC plugin. This is a prototype design. It may make more sense to add interface options in addition to USB and CAN-FD. WiFi, and wired Ethernet are being considered.

The microcontroller used on the board is the RP2040. It is extremely cheap (< $1US) and easy to get considering current supply-chain issues. Thankfully, these seem to be easing somewhat. The microcontroller does not need to be as powerful as some of the microcontrollers typically used in applications like this (for example STF32x) since computations will be spread across multiple microcontrollers; typically one RP2040 per puck. The clocks of the microcontrollers are synchronized and data is passed used multidrop low voltage differential signalling (M-LVDS). The M-LVDS network is connected with coaxial cable using U.FL connectors on the top an d bottom of each PCB. The programmable IO (PIO) of the RP2040 microcontroller allows passing data between PCBs with almost no load on the dual ARM M0+ processors. This PCB communicates with the outside world with a CAN-FD interface.

In coming posts I will describe some of the software development using breadboarded components including multiple Raspberry PI Pico evaluation boards.

Cora Z7: FreeRTOS – Vivado Built-in Example Code

Implementation of a simple TCP/IP server on the Cora Z7 board using FreeRTOS. This implementation is done with Vivado 2019.1, its associated SDK, and the example code included with this distribution. It will likely build and run fine with other distributions.

To start create the hardware system described in this element14 community blog. I followed the example closely except that I named the block design cora_design_1 and I added Cora’s two push buttons and the 2 RGB LEDs through and AXI_GPIO connection by dragging them from the Board tab of the Block Design window. When complete the block design appears as follows.

Block Design

After validating the the design (F6), generate the Bitstream. Launch the SDK from within Vivado; File=>Launch SDK. Alternatively export the hardware; File=>Export=>Export_Hardware and then import the hardware description file after starting the SDK separately. If you don’t already have a Workspace create one. From within the SDK create a new application program. Give it a name and choose freertos as the OS Platform. Select the processor. Choose processor zero on a dual processor system. Create a new BSP. Click “Next>”.

Create a New Application Project

Select the “lwIP TCP Perf Server” template. Click “Finish”.

TCP Perf Server Example

Build the application. The default IP address of the application is 192.168.1.10. Configure your host IP to have a static IP on the same class-C subnet. You may change the default address of the application by editing the value of the #define DEFAULT_IP_ADDRESS in the main.c source file. Connect your host PC to the Cora board with an Ethernet cable. Also connect the Cora board micro USB port to your host PC. You will need a terminal program. You can use the terminal inside the SDK program or an external terminal program. I use TeraTerm which is a free download. Open the terminal. Connect to the terminal through the Cora boards COM port. Configure the settings to the default application values of 115,200 baud, 8N1.

Right click the application project and select Run as=>Run configurations … . Configure as shown

Run Configuration

Click run. If the terminal is connected to the COM port the following startup status information will be displayed.

If using a Windows host you will need to down7load the iperf utility. Download iperf version 2. iperf3 in incompatible with the server running on the Cora board. Open a cmd or terminal window on your host PC. In windows change directory where you have put the iperf executable.

PC Host CMD Window

from the command window run,

iperf -c 192.168.1.10 -i 5 -t 90 -w 2M

The output on the Windows 10 client and the Cora Z7 server are;

iperf Client Output
iperf Server Output

You should achieve a performance of approximately 500 Mbits/sec.

To be continued in the next post.

Cora Z7 4: Pulse Width Modulation (PWM)

One of the components necessary for the end goal of controlling a motor is pulse width modulation (PWM). This component will be used to switch the FETs in the bridge to which the motor is connected. For a brushed DC motor two PWM components will be required; for a three phase brushless motor three.

This post covers the development of a single PWM component. Some of the features that I would like my PWM module to have include;

  1. A single counter is used to drive multiple PWM components.
  2. The resolution of the PWM is up to 14-bits.
  3. Higher PWM carrier frequency (at the cost of lower resolution) can be achieved by using a least significant subset of bits from the counter. High PWM carrier frequencies are useful for driving low inductance motors.
  4. Make the switch points of the PWM symmetric about the midpoint of the PWM carrier wave. The carrier midpoint would be the maximum value if a triangle carrier wave is used. I will be using a sawtooth carrier wave. The allows a simpler counter. I only need to count up and roll over compared to creating an up-down counter.
  5. Generate a carrier wave midpoint signal that can be used to trigger motor current sampling. Sampling the motor currents as far as possible from the PWM switch points reduced noise in the current measurement.

Start Vivado and create a new project.

Click “Next“. Make it an “RTL Project” and check “Do not specify source at this time“. Click “Next“. Select your part. In my case the “Cora Z7-10” board from Digilent. Click “Next“. Review the summary and click “Finish” when satisfied.

Under “PROJECT MANAGER” in the “Flow Navigator” panel click “Settings“. Choose your target language. I will be using VHDL.

Click “OK”. Under “IP INTEGRATOR” in the “Flow Navigator” panel click “Create Block Design“. Give your design a name and click “OK“.

In the “Diagram” panel add IP by clicking on the “+” button. Add a binary counter. Double click the counter block and configure it to an output width of 14 bits. In the control tab check “Clock Enable (CE)” and “Synchronous Clear (SCLR)“.

Click “OK“. The counter needs to be driven by a clock. Click the “+” button and add the “Clocking Wizard” IP. Double click the “Clock Wizard” block to open it. Under the “Board” tab set “CLK_IN1” to “sys_clock“. Check out the “Clocking Options” tab. I just left the default settings. Under the “Output Clocks” tab set the frequency of the “clk_out1” output. I selected 250 MHz. This gives a particular set of possible carrier frequencies depending on the number of bits of the counter that are used. Higher frequency PWM permits lower current ripple in loads (ex. motor coils) with low inductance. A higher clock frequency could probably used. If you select a higher clock frequency, verify that all timing constraints when the hardware builds. The “Output Clocks” tab is also where the optional inputs, outputs and reset are configured. My selections are as shown in the figure below.

Counter BitsPWM Carrier Frequency (KHz)
1415.2588
1330.5176
1261.0352
11122.070

Check out the “MMCM Settings” and “Summary” tabs. Click “OK” when satisfied.

Add ports to connect to “resetn” and “clk_in1“. Right click in the “Diagram” panel and select “Create Port …” from the menu to create each port. For the “resetn” port set the direction to “Input“, the type to “Reset” and the polarity to “Active Low“. For the port which will connect to “clk_in1“, name the port “sys_clock“. Set the direction to “Input“. Set the type to “Clock“. Specify the frequency as “125” MHz. You may need to select “Regenerate Layout“, from the right click menu, to get the diagram elements grouped.

From the “Project Manager” click “Add Sources“. Select “Add or create design sources“. Click “Next>” Click “Create File” and give it the name “PWM“. Click “OK” to add it to the local project. Click “Finish“. You could enter the port definitions in the “Define Module” dialog. Just click “OK“. We will edit the file directly. The file should appear in the hierarchy of the “Sources” tab. Open the file for editing. The source code file can be cloned from this repository.

The PWM module takes as inputs the PWM sawtooth carrier signal in the form of the count from the binary counter and the switch points to the left and right of the centre of the carrier signal. It uses the same clock as the counter. The reset is driven by the “locked” signal from the clocking wizard. The module is held is reset until the generated clock has stabilised. While in reset, the “ce” and “clr” signals are held at a level to keep the binary counter cleared and disabled. Outputs are the PWM signal itself (“pwm_out“) and a signal called “mid” which transitions from low to high at the centre of the carrier signal. This edge transition can be used to trigger current sensor acquisition and synchronise servo loops in motor control.

In the “Diagram” panel, right click and select “Add Module …“. Select the “PWM” module and click “OK“. The module with its input and output ports should appear in the diagram. Again you may need to “Regenerate Layout” to get the blocks to group. Add “mid” and “pwm_out” ports to the diagram. These are both “Output” ports of type “Other“. For now we will drive the left and right switch point signals of the PWM block with constants. Later these signals will be driven by a processor. Use the “+” button to add two “Constant” blocks. Double click to open and set the width to 13. Enter positive values for the switch points. I used 3636 for the left switch point and 4556 for the right switch point. This will give a a symmetric pulse about the centre of the carrier signal. With all signals connected, the block diagram should look something like the following figure.

Write click in the “Diagram” panel and select “Validate Design“. Everything should check out. With block diagram complete, right-click on the board file (.bd) in the sources hierarchy and click “Create HDL Wrapper …“. Let Vivado manage the wrapper and auto-update. Click “OK“.

Constraints need to be specified for the input and output ports in the diagram. Under the “PROJECT MANAGER” click “Add Sources“. Select “Add or create constraints” and click “Next>“. Select “Add Files“. Browse to where the you installed the Digilent Cora Z7 master constraint file. “Cora-Z7-10-Master.xdc” in my case. Select the file. Click “OK“. Make sure that “Copy constrains files into project” is checked. Click “Finish“. The constrains file should now appear under the “Constraints” section of the “Sources” tab hierarchy. Open the file to edit. Uncomment the two lines under the “##PL System Clock” comment. Change the name in braces to “sys_clk”.

## PL System Clock
set_property -dict { PACKAGE_PIN H16   IOSTANDARD LVCMOS33 } [get_ports { sys_clock }]; #IO_L13P_T2_MRCC_35 Sch=sysclk
create_clock -add -name sys_clk_pin -period 8.00 -waveform {0 4} [get_ports { sys_clock }];#set

Select IO pins for the “resetn“, “mid” and “pwm_out” signals. I used the first three IO pins of the JA Pmod header. Uncomment the lines and edit to set the IO names.

## Pmod Header JA
set_property -dict { PACKAGE_PIN Y18   IOSTANDARD LVCMOS33 } [get_ports { resetn }]; #IO_L17P_T2_34 Sch=ja_p[1]
set_property -dict { PACKAGE_PIN Y19   IOSTANDARD LVCMOS33 } [get_ports { mid }]; #IO_L17N_T2_34 Sch=ja_n[1]
set_property -dict { PACKAGE_PIN Y16   IOSTANDARD LVCMOS33 } [get_ports { pwm_out }]; #IO_L7P_T1_34 Sch=ja_p[2]

The complete constraints file is in the repository.

Under the “PROJECT MANAGER” > “PROGRAM AND DEBUG” click “Generate Bitstream“. When the build finishes, open the implementation. Check the “Design Timing Summary” and verify that the timing constraints are satisfied. The “Project Summary” will show the device utilisation.

It remains to check if the design actually works as expected. One way to check the design is to simulate it. The simulator is a very useful tool for debugging. It allows you to inspect both external ports and internal signals. Under the “PROJECT MANAGER” click “Add Sources“. Select “Add or create simulation sources“. Click “Next>“. Specify the simulation set. I used the already created set “sim_1“. This entry can be used to create multiple simulation sets. Click “Create File“. Select the file type; VHDL in my case. Give the file a name. I used “PWM_Test1“. Select the file location local to the project. Click “OK“. Make sure that “Include all design sources for simulation” is checked. Click “Finish“. You can specify the IO ports with the “Define Module” dialog. Just click “OK“. We will edit the file directly.

The “PWM_Test1” file should appear under “Simulation Sources” in the “Sources” hierarchy. Open the file to edit. This file is a wrapper around the “System_1_wrapper” in the “sim_1” set. When done the file should look like this the one in the repository.

Once you save the file it should take its place at the top of the “sim_1” hierarchy.

Under the “PROJECT MANAGER” click “Settings“. Under “Project Settings” click “Simulation“. Review the various tabs. I left the default settings.

Click “OK“.

Under the “PROJECT MANAGER” click “Run Simulation -> Run Behavioral Simulation“. The IO pins appear by default in the simulation “Wave Window“. Add the counter. Select the counter under the “Scope” tab. In the “Objects” panel, right click “Q[13:0]” and add it to the wave window. In the wave window right click on “Q[13:0]” and set “Waveform Style” to “Analog“. Run the simulation for the interval specified in the simulation toolbar by clicking the right arrow button with the “(T)” subscript. Next to the simulation time. I ran for three 100 microsecond intervals for a total of 300 microseconds. The waveforms should show up in the wave window. They didn’t initially on by Ubuntu 16.04 computer. If I toggle from “Default Layout” to ” Simulation Layout” and back, using the upper right selection box, the waveforms magically appear. I need to do this each time I run a simulation segment. I don’t have this problem on Windows. You can verify the sawtooth carrier with a 66.67 microsecond period (15 KHz). The “mid” signal transitions high at the midpoint of the carrier. The “pwm_out” signal has the expected pulse width and is centred about the carrier signal midpoint.

Finally lets program the board and view the outputs on oscilloscope. Under the “PROGRAM MANAGER -> PROGRAM AND DEBUG” click “Open Hardware Manager“. If it doesn’t immediately connect click “auto connect“. Click “Program Device“. Verify that the bit file is correct. Verify that “Enable end of startup check” is checked. Click “Program“.

Connect your scope. I am using a Digilent Analog Discovery2 to monitor the “mid” and the “pwm_out” signals. The Analog Discovery 2 is a compact, inexpensive device; perfect for the job. I highly recommend it.

Here are the output signals from the board.

In useful system the switch points will not be constants. In the next post a processor will be added to set the switch points.

Cora Z7 3: Hello Cora – Software

Launch the Vivado SDK either from a terminal or the launcher. Select the location for your project workspace.

Click OK.

In the “Welcome” tab click on “Create Application Project“.

In the new project dialog click “New” so that you can select the target hardware to be that which you created in the previous post.

This dialog is used to create a new hardware project with hardware description file that was built in the previous post. Browse to the directory where you built the hardware description in the previous post and select the hardware description file. A default project name will appear in the “Project name:” entry. It can be edited. I left the default. The project location can also be changed if the “Use default location” box is unchecked. Again , I left the default. Click “Finish“.

Give the project a name. Select the language and note that a new board support package will be created. Click “Next”.

Select the “Hello World” template and click “Finish“.

In the “Project Explorer” tab you will see the “Hello-Cora” ‘C’ software project. The board support package (bsp) and the hardware platform project. Expand the sub-directories of these project to see there contents. Open the “helloworld.c” file by double-clicking it. Edit the printed message as you like.

Plug the Cora Z7 board into the a USB port on your computer. In Linux you can check which port is assigned to the Cora Z7 board by inspecting the contents of the /dev directory before and after the Cora board is connected. For example the following command in a terminal

ls -al /dev/ttyUSB*

before and after board is connected gives

The Cora board is connected to /dev/ttyUSB2. In the “SDK Terminal ” tab in the bottom centre panel click the “+” button to connect the serial port.

Make the settings 115200 baud, 8 data bits, 1 stop bit an d no parity.

Right click on the “Hello Cora” project in the “Project Explorer“. Select “Run As -> Launch on Hardware (System Debugger)” Progress will be updated in the “SDK Log” panel. The program will load and run. The output is displayed in the “SDK Terminal” tab.

Be patient it can take a while to load the debugger and run the application. If you prefer you can use a terminal program outside the SDK. GtkTerm works fine. Just connect to the same port and use the same port configurations.

Cora Z7 2: Hello Cora – Hardware

Before you can create and run a “Hello Cora” software project, the hardware on which to run the program needs to be built. This post goes through the creation of a simple single processor bare-metal (no OS) system on which the “Hello Cora” application will be executed.

Start Vivado either from a terminal or use the launcher.

Under “Quick Start” click “Create Project >”

Click “Next >”

Enter a project name and location. Check selection box to create a project subdirectory.

Click “Next >”

Select “RTL Project” and “Do not specify sources at this time”.

Click “Next >”

Select “Boards”. Under “Vendor:” choose “digilent.com”. In “Search:” type “Cora”. Select your Cora board.

Click “Next >”

Review the “New Project Summary”.

When satisfied click “Finish”.

The project is initialised and the “Project Manager” window appears.

In the flow navigator bar to the left click “Create Block Design”.

In the “Create Block Design Dialog”, give the design a name. Leave other entries as the default.

Click “OK”.

In the “Diagram” panel, click the “+” button to add IP. You may click the button in the middle of the panel or in the tool bar along its top edge.

In the search window begin typing “zy”. “ZYNQ7 Processing System” will appear.

Make sure that it is highlighted and hit the “Enter” key. A “processing_system_7_0” block will appear in the middle of the panel. You may need to zoom in to make it readable. “Zoom Fit” in the tool bar didn’t work for me. Left click and dragging a “Zoom Area” box around the IP block did. You can also hold “Ctrl” and the mouse wheel to zoom in and out.

Click “Run Block Automation” at the top of the panel.

Accept the defaults and click “OK”.

Zoom in again if necessary.

Right click in the “Diagram” tab and select “Validate Design”.

A clock pin has not been connected. We will fix this. Click “OK”.

On the diagram make a connection between “FCLK_CLK0” and “M_AXI_GP0_ACLK”. As you hover over “FCLK_CLK0” a pencil will appear. Click and hold on “FCLK_CLK0” and drag towards “M_ZXI_GP0_ACLK”. A green check will appear on the “M_ZXI_GP0_ACLK” pin. Drag to this pin and release the mouse button. A connection is established.

Again validate the design. Right click select “Validate Design” or press F6. Two warning messages appear.

These are not a problem. Refer to Hardware errata page of the Cora Z7 Reference Manual. Click “OK”.

Save your project. Click the “Sources” tab design Hierarchy.

Right click on “System (system.bd) (1), click “Create HDL Wrapper …”.

Select “Let Vivado manage wrapper and auto-update”. Click “OK”.

After updating a wrapper file will appear. In the “Flow Navigator” bar click “Generate Bitstream”.

Click “Yes” to launch synthesis and implementation.

Accept the defaults of the “Launch Runs” Dialog and click “OK”.

A progress bar will appear for a short time and then you will see progress updating in the upper right corner of the screen.

When complete the “Bitstream Generation Completed” dialog will appear.

Select “Open Implement Design” and click “OK”.

At this point I was asked to take a survey of Vivado 2018.3 experience. I selected “Remind me Later”. I will take the survey after a bit more experience with this release and bring up the zooming issue. Explore the device and/or the “Project Summary” tab.

At this point our hardware has been generated. Export the hardware description so that is can be imported into the SDK for software development. From the file menu select “File->Export->ExportHardware …”.

Select “Include bitstream” and export “<Local to Project>. Click “OK”.

A “HelloCora.SDK” folder will be created in the project directory. The hardware description file will be imported into the SDK in the next post. If your project needs saving, save it.

If continuing immediately on the the software part of the “Hello Cora” example, you can launch the SDK from the file menu and it will automatically load the hardware description file that you saved in the project. This used to crash in version 2016.4 under Ubuntu but appears to work fine in 2018.3. Nice! Thanks Xilinx.

Cora Z7 1: Cora Z7 and Installing Vivado

I recently purchased a Cora Z7-10 from Digilent.

The Cora Z7-10 features a Xilinx Zynq 7010 System on Chip (SoC) which sports two ARM Cortex-A9 processing cores, a broad array of IO, dual abalog to digitla converters and programmable logic. Details of the board features can be found in the reference manual. Over the next several months I will work on several small projects with a end goal of creating an embedded system to control one or more brushed or brushless DC servomotors . The first step in this process is to install the necessary development tools.

Install Xilinx Vivado

Development on the Cora Z7 boards are supported by the Xilinx Vivado Design Suite. I will be using the latest Webpack version of this suite. At the time this project was started this was Vivado HLX 2018.3. I will be installing Vivado on a Ubuntu 16.04. I have installed Vivado on Windows 10 and got a “Hello Cora” project up and running but I found that the SDK would crash without an error message. Checking the Xilinx forums I found that a work around for the problem was to disable the automatic build setting in the Vivado SDK. To disable just uncheck “Automatic Build” under the “Project” menu of the SDK.

If you haven’t already registered an account with Xilinx you will need to do so before you can download Vivado. Once your account is set up, download the Vivado Design Suite suite from Xilinx.

https://www.xilinx.com/support/download.html

I downloaded

Extract the archive into a working directory. Open up an terminal. Decide where you want Vivado installed. The default for Vivado 2018.3 /tools/Xilinx. I had previously installed Vivado 2016.4 in /opt/Xilinx so will be installing in the /opt/Xilinx directory. If your directory doesn’t already exist create it. In my case

sudo mkdir /opt/Xilinx

Check the file permissions.

ls -al /opt

drwxr-xr-x 5 root root 4096 May 2 21:11 .
drwxr-xr-x 25 root root 4096 Apr 27 07:36 ..
drwxr-xr-x 9 root root 4096 Apr 25 21:44 Xilinx

If your permissions do not allow “other” read and execute permissions use the “chmod” command set the correct permissions.

sudo chmod 755 /opt/Xilinx

Start the installer.

cd Xilinx_Vivado_SDK_2018.3_1207_2324/
sudo ./xsetup

You will get the “Welcome” dialog box.

Note the comment circled in red. I will return to this later. Click “Next >”

Accept the license terms and conditions.

Click “Next >”

Select the edition that you have or for which you can obtain a license. I am using the free WebPACK.

Click “Next >”

These are the default WebPACK selections. I chose these.

Click “Next >” once your selection are made.

Click “Next >”

A summary of the installation choices will be displayed. You may go back and make changes if required.

Click “Install” when ready to proceed.

Installation progress will be updated.

When finished you will be notified.

Once installed, configure the settings file to run by adding the following lines to your .bashrc file in your home directory.

source /opt/Xilinx/Vivado/2018.3/settings64.sh

Make sure to use your install path. After starting up a new terminal Vivado can be run from the command line using

vivado &

The Xilinx SDK can be run from the command line using

xsdk &

I am using the “Unity” desktop environment. To launch Vivado and the SDK from the Unity Launcher create the following two files in ~/.local/share/applications

Vivado_2018.desktop
SDK_2018.desktop

The contents of these file respectively is

[Desktop Entry]
Name=Vivado_2018
Comment=Xilinx Design Suite for HDL design
Exec=/opt/Xilinx/Vivado/2018.3/bin/vivado
Icon=/opt/Xilinx/Vivado/2018.3/doc/images/vivado_logo.ico
Terminal=false
Type=Application

[Desktop Entry]
Name=SDK_2018
Comment=Xilinx Software Development Kit
Exec=env SWT_GTK3=0 /opt/Xilinx/SDK/2018.3/bin/xsdk
Icon=/opt/Xilinx/SDK/2018.3/data/sdk/images/sdk_logo.ico
Terminal=false
Type=Application

Obtain a Vivado License

Start Vivado ether from the command line or the launcher. Start the License Manager under the Help menu.

Help->Manage License…

Click “Obtain License“.

Select the appropriate entry for your install and click “Connect Now“. Login to your Xilinx account. Click “Next” to proceed license entitlement page. Choose your license(s). Click “Generate Node-Locked License”. The “Generate Node License” dialog will come up. Add any comment that you like.

Click “Next“.

Review the license request.

Click “Next“.

The license file will be emailed to the email address set up in your Xilinx account. Close the email notification dialog.

When you receive the email, save the attached license file to a convenient location. From the Vivado License Manager click “Load License”.

Click “Copy License…“. Browse to the location that you save the license file that you received by email. Select it. Click “Open“.

Click “OK”. Select “View License Status” in the License Manager to view the updated License status.

Close the license manager. Exit Vivado.

Additional Library Installation

NOTE: None of this may be necessary.

Remember way back on the “Welcome” dialog for the installation of Vivado there was a comment about “Additional library installation required” for a Ubuntu install.

There is an answer in Xilinx support which addresses this issue.

https://www.xilinx.com/support/answers/66184.html

That being said I have had no problem without following the procedure in this answer; and like they say … “If it ain’t broke don’t fix it. I did go part way through the procedure to try and discover the which libraries that my install missed. If I run into issues in the future I will need to revisit this answer.

A Perl script is provided to check for required libraries and libraries that are missing on a Linux system. Download the Perl script from

https://sourceforge.net/projects/recursive-ldd/

Save the script to a convenient location. Open a terminal and navigate to that directory. Check that Perl is installed on your system. Execute the command on the terminal.

which perl

If it exists and is found you should get a response something like.

/usr/bin/perl

If not found install Perl.

The Vivado environment needs to be set up by sourcing “settings64.sh”. This should already be done if you added the line

source /opt/Xilinx/Vivado/2018.3/settings64.sh

to your .bashrc file as directed above. Run (with your install path substituted)

perl ldd-recursive.pl /opt/Xilinx/Vivado/2018.3/bin/unwrapped/lnx64.o/vivado -uniq

You will get an output something like the following.

librdi_commonmain.so => not found
/lib64/ld-linux-x86-64.so.2
librdi_common.so => not found
libtcmalloc.so.4 => not found
/lib/x86_64-linux-gnu/libc.so.6
linux-vdso.so.1
/lib/x86_64-linux-gnu/libm.so.6
/lib/x86_64-linux-gnu/libgcc_s.so.1
libboost_signals.so => not found

I found all of the libraries that the script reported missing in

/opt/Xilinx/Vivado/2018.3/lib/lnx64.o/

and

/opt/Xilinx/SDK/2018.3/lib/lnx64.o/

Install Cable Drivers

The Linux install of Vivado does not install the JTAG cable drivers. These can be installed by running a script as super-user. Change to the directory containing the script.

cd /opt/Xilinx/Vivado/2018.3/data/xicom/cable_drivers/lin64/install_script/install_drivers/

Run the “install_drivers” script as super-user.

sudo ./install_drivers

Install Digilent Boards Files

Before you can do much useful work with Cora Z7, a board definition file needs to be installed. Download the archive of Digilent Vivado boards repository from

https://github.com/Digilent/vivado-boards/archive/master.zip?_ga=2.189455785.301761015.1557099321-30372036.1524673665

Unpack the archive into a convenient location. Edit the “init.tcl” file in the “utility” subdirectory of the boards repository that you just unpacked. The Vivado_init.tcl file is for Vivado versions before 2016.4. Change the path in the script to the extracted location of the Digilent Vivado board files. My script looks like this. Note that environment variables will not work in this script.

set_param board.repoPaths [list “/home/glenafield/Xilinx/Vivado/vivado-boards-master/new/board_files”]

Save the file and exit the editor. In a terminal, as super-user, copy the edited “init.tcl” file into “$HOME/.Xilinx/Vivado/

sudo cp init.tcl $HOME/.Xilinx/Vivado/

Vivado should now be setup and configured for the Digilent Cora Z7 board. In the next post I will create a simple “Hello Cora” application to run on one of the Cora Z7’s Zynq processors.

Welcome!

Welcome to London Place Systems. I have been fascinated by embedded systems and control since I started pursuing a Master’s of Applied Science (M.A.Sc.) degree in Mechanical Engineering at the University of Waterloo in 1986. The first robot that I worked with was a Reis V15 Industrial Robot. We created our own “embedded” control system with a three Motorola 68030 processor VME bus cards running the VxWorks real-time operating system. The analog motor current and velocity control were left running on the stock Reis hardware. The path planning, kinematics and position control loops were run on the Motorola 68030 processor VME cards. A graphical user interface was created on a Sun workstation running X-windows. Communication with the user interface was with UDP sockets.

Reis V15 Embedded System (circa 1986)

While doing my M.A.Sc. degree in “mechanical” engineering I learned very quickly that I had to expand my class learned skills to include software, electronics and later on, with wide spread availability of programmable logic, firmware. It is the multi-disciplinary systems approach required to build an embedded systems that I find so compelling.

Needless to say, advancements in technology have shrunk size and cost so much that the creation of extremely powerful embedded systems are now accessible to the home hobbyist. It has been my privilege during my career to work in a field which has been so dynamic. It my belief that we are just getting started. The purpose of this blog is to keep track of the small projects that I like to work on in my free time. It is my hope that some who read this blog will find the information interesting or useful. Feedback is always welcome. Questions, insights, comments will help direct my future investigations.