Monday, April 29, 2019

Hello World on the Qualcomm QCA4020 developer board

I have recently started working on an IoT project involving the use of a Qualcomm QCA4020 Development Kit prototype board. The board has many useful features for IoT prototyping, but a clear set of "getting started" instructions is not one of them.

Qualcomm's developer network has published a Hello World demo application, but the procedure is for Windows PCs and I want to use Linux for my development platform. Qualcomm's SDK says that Linux and macOS are supported platforms, but any documentation resembling a tutorial is strictly Windows-based.

This blog post is the procedure I worked out for getting their Hello World demo working using a Linux PC to cross-compile the code and flash the Qualcomm developer board

PC Hardware

Any PC running a reasonably recent 64-bit Linux system should work. I am using a pretty old Dell PC:

It is running the latest Debian Stable OS release (9.9)

Materials required

  • Qualcomm QCA4020 development kit
  • Python 2.7
  • GNU ARM Embedded Toolchain
  • OpenOCD
  • Your favorite serial port terminal application
Although the Windows-based procedure uses the Eclipse IDE, I am not using it for my procedure. Integration with Eclipse is left as an exercise for the reader.

Install a serial port terminal emulator

If you plan to see any output from the Qualcomm board's console, you will need a terminal emulator that can connect to a serial port (in this case, a USB-based serial port).

Everybody has their favorite terminal package, so I will make no attempt to convince you to use any particular version. I am using Minicom, primarily because it can automatically reconnect when a serial port device disappears and reappears, which will happen whenever the Qualcomm board's USB cable is unplugged and re-plugged.

When the board is attached (assuming you have no other USB serial port devices), Linux will see it as two serial ports, for example: /dev/ttyUSB0 and /dev/ttyUSB1. The higher numbered port (/dev/ttyUSB1, in my case) is the board's console.

The lower numbered port will be re-configured as a JTAG interface when uploading code into the board's flash memory.

Install Python 2.7

Most Linux distributions, including Debian, pre-install Python version 2.7 by default. If you do not have it installed, install it using your distribution's preferred package manager. For example:
sudo apt install python
The latest Debian Stable (9.9) release installs Python version 2.7.13, which works

Note: Qualcomm's scripts are incompatible with Python version 3. If you have both versions 2 and 3 installed, the default python command should call version 2. If you have reconfigured your Linux distribution to run version 3 by default, you may want to configure it back in order to avoid problems with the build process.

Install OpenOCD

OpenOCD is a tool for interfacing with hardware devices using JTAG. It is used by the Qualcomm scripts for writing compiled code into the board's flash memory.

OpenOCD is available as part of Debian's Linux distribution, but is not installed by default. To install it:

sudo apt install openocd
Debian currently provides version 0.9.0, which works, even though Qualcomm recommends version 0.10.0 (which is provided by other current Linux distributions, including Ubuntu).

Install the GNU-RM Embedded Toolchain

The ARM cross-compiler is not provided by Qualcomm. Instead, you should download it directly from ARM corporation. It is included in the GNU-RM Embedded Toolchain.

Although Qualcomm recommends use of an older version (6-2017-q2-update), I was able to successfully compile the Hello World application using the latest version (8-2018-q4-major), and that is the version presented here. Download the 64-bit Linux tarball (gcc-arm-none-eabi-8-2018-q4-major-linux.tar.bz2) from ARM.

There is no installer for the Linux version of the GNU-RM tools. I chose to use the following procedure, which unpacks all of the files into a public "package" directory (to allow for easy uninstallation), adding symlinks to /usr/local/bin so the binaries will be available on your PATH. Assuming the tarball is located in your home directory:

sudo mkdir -p /usr/local/package/arm_tools
cd /usr/local/package/arm_tools
sudo tar xjf ~/gcc-arm-none-eabi-8-2018-q4-major-linux.tar.bz2
cd /usr/local/bin
sudo ln -s /usr/local/package/arm_tools/gcc-arm-none-eabi-8-2018-q4-major/bin/* .

Download and unpack the SDK

Download the SDK from Qualcomm's developer site. The package you want is named QCA4020.OR.3.0 QCA OEM SDK+CDB and can be downloaded via this link. The SDK will download as a zip file named qca4020.or_.3.0_00011.1.zip.

Note: You will require a Qualcomm login in order to download the SDK. Access is free, but you must request it and wait for approval.

I installed the SDK to a builds directory under my home directory. Assuming you wish to do the same, and have placed the installer in your home directory:

mkdir ~/builds
cd ~/builds
unzip ~/qca4020.or_.3.0_00011.1.zip

Connect the QCA4020 to your PC

This is to identify the names of the serial ports that the QCA4020 board will create.

First, before attaching the QCA4020 board, look in the /dev directory to identify any pre-existing USB serial ports:

ls -l /dev/ttyUSB*
In my case, there were no devices. If you see any, those do NOT correspond to your QCA4020 board.

Make sure the board is jumpered such that it draws power from the same USB port you are using for the console interface (the micro-USB connector labeled J85). Ensure that the following jumpers are set:

  • J36 - pins 1 & 2 (to select USB power)
  • J57 - pins 1 & 2 (to select J85 as the USB port to deliver power)
Note: Pins 1 and 2 are the rightmost pins when the board is held such that the printing on J36 and J57 are readable. This is backward compared to most of the other jumpers on the board.

Plug the QCA4020 board into a USB port on your computer. You should see the power light (next to jumper J20) come on bright and steady. If it does not come on, if it is dim, or if it is flashing, then the board is not getting sufficient power. Some things to check:

  • Make sure the power switch S7 is in the "ON" position
  • Double- and triple-check the jumper settings (J36 and J57). As I wrote, the correct positions are counter-intuitive. Be sure to look closely at where the white dots (indicating pin 1) are for these jumpers
  • It is possible that your USB port isn't providing enough power. If you are attaching the QCA4020 board using a non-powered hub, try swapping it for a powered hub, or connecting it directly to your computer.
  • If the jumpers are correct and it is connected directly to the computer, then your computer may not be supplying sufficient power. If this is the case, move the jumper on J57 to pins 2 & 3 (the leftmost pins) and attach a USB power supply (included with the QCA4020 development kit) to the micro-USB connector labeled J6. Note also that if you do this, you will need to disconnect both USB cables to completely power-off the QCA4020 board.
With the board attached and powered, look in the /dev directory to identify any new USB serial ports. You should see two new devices (in my case, /dev/ttyUSB0 and /dev/ttyUSB1). The higher-numbered device is the console interface. The lower-numbered device is used for the JTAG interface.

Note that, unlike the Windows platform, there is no need to install special drivers for JTAG access. The necessary drivers are built-in to the Linux kernel and will be used by the OpenOCD software without special configuration.

Compile the Hello World application

The following should cross-compile the Hello World demo application:
cd ~/builds/QCA4020.or.3.0_00011.1/target/quartz/demo
cd Helloworld_demo/build/gcc
make BOARD_VARIANT=cdb
The provided Makefile is controlled using the following variables. Three of the four have default values suitable for the developer board, but the fourth does not:
  • RTOS=threadx (default)
  • CHIPSET_VARIANT=qca4020 (default)
  • CHIPSET_REVISION=2p0 (default)
  • BOARD_VARIANT=cdb
You may either set the (non-default) variables in the environment or as parameters to make, as shown above.

Jumper the QCA4020 for JTAG access

In order to get the compiled application loaded into the QCA4020 board, it is necessary to write it to the board's flash memory using the JTAG interface. Several jumpers must be installed on the board in order to enable this capability. See also Appendix A of the QCA4020 development kit user's guide (downloadable from the same site as the SDK) for a detailed description of each jumper.
  • Power off the QCA4020 board (disconnect the USB cable from the PC. If you are using an external power supply as well, unplug it).

    NOTE: Simply flipping the power switch is not sufficient to completly power-off the board. If you flip the switch and leave the USB cable connected, the power light does not turn off, but flickers dimly and the USB serial ports remain visible in Linux. I would not consider it safe to change jumpers while the board is in this state.

  • Install the following jumpers. Look closely at where the white dot representing pin 1 is for each jumper
    • J30 - pins 1 & 2 (to enable JTAG capability)
    • J31 - pins 1 & 2 (to disable auto-boot and enable JTAG debug/flashing)
    • J32 - pins 1 & 2 (to enable JTAG capability)
    • J37 - pins 2 & 3 (to enable JTAG capability)
    • J38 pin 2 to J39 pin 3 (to enable JTAG capability - you will need a jumper wire for this)
    • J38 pin 3 to J39 pin 2 (to enable JTAG capability - you will need a jumper wire for this)
    • J40 - pins 2 & 3 (to enable JTAG capability)
  • Power-on the QCA4020 board (reconnect its USB cable and the external power supply if necessary). Confirm that the power LED is lit, bright and steady.
Note: Most of the jumpers can remain in-place all the time. Only J31 needs to be removed in order to run the application after writing it into the board's flash memory.

Flash the application using JTAG

The following should push the compiled application into the QCA4020 board:
cd ~/builds/QCA4020.or.3.0_00011.1/target/quartz/demo
cd Helloworld_demo/build/gcc
sh flash_openocd.sh
The flash script calls sudo in order to configure the USB port for JTAG. Provide your password when prompted. If your login does not have permission, contact the person responsible for administering your Linux PC to get permission.

Run the Hello World application

First, disable JTAG programming mode and re-enable auto-start mode:
  • Power off the QCA4020 (disconnect all USB cables)
  • Remove jumper J31
  • Power on the QCA4020 (re-connect USB cables)

Launch your terminal emulator application. Configure it for the QCA4020's USB serial console:

  • Device: /dev/ttyUSB1 (or whatever name you identified previously)
  • Bit-rate: 115200
  • Data bits: 8
  • Parity: None
  • Stop bits: 1
  • Flow control: None
If the application is running correctly, you should see a stream of "Hello world" messages appear on the console, one per second.

No comments: