Stephen Smith's Blog

Musings on Machine Learning…

I/O Co-processing on the Raspberry Pi Pico

leave a comment »

Introduction

Last time we looked at how to access the RP2040’s GPIO registers directly from the CPU in Assembly Language. This is a common technique to access and control hardware wired up to a microcontroller’s GPIO pins; however, the RP2040 contains a number of programmable I/O (PIO) coprocessors that can be used to offload this work from the main ARM CPUs. In this article we’ll give a quick overview of the PIO coprocessors and present an example that moves the LED blinking logic from the CPU over to the coprocessors, freeing the CPU to perform other work. There is a PIO blink program in the SDK samples, which blinks three LEDs at different frequencies, we’ll take that program and modify it to blink the LEDs in turn so that it works the same as the examples we’ve been working with.

PIO Overview

There are eight PIO coprocessors divided into two banks for four. Each bank has a single 32 word instruction memory that contains the program(s) that run on the coprocessors. 32 instructions aren’t very many, but you can do quite a bit with these. The SDK contains samples that implement quite a few communication protocols as well as showing how to do video output. 

Each PIO has an input and output FIFO buffer for exchanging data with the main CPUs.

The PIO coprocessors execute their own Assembly Language which the Raspberry folks call a state machine, though they also say they think it is Turing-complete. Below is a diagram showing one of the banks of four. This block is then duplicated twice in the RP2040 package.

Each processor has an X and Y 32-bit general purpose register, input and output shift registers for transferring data to and from the FIFOs, a clock divider register to help control timing, a program counter and then the register to hold the executing instruction as shown in the following diagram.

Each instruction can contain a few bits that specify a delay value, so for many protocols you can control the timing just by adding a timing delay to each instruction. Combine this with the clock divider register to slow down processing and you have a lot of control of timing without using extra instructions.

Sample LED Blinking Program

You write the Assembly Language PIO part of the program into a .pio file which is then compiled by the PIO Assembler into a .h file to include into your program. You can also include C helper functions here and the Pico SDK recommends including an initialization function. The various RP2040 SDK functions to support this are pretty standard and you tend to copy/paste these from the SDK samples.

We are blinking the LEDS using a 200ms delay time which by computer speeds is very slow, but for humans is quite quick. This means we can’t use the clock divider functionality and instruction delays as they don’t go this slow. Instead we have to rely on an old fashioned delay loop. We calculated the delay value in the main function using the frequency of the processor and then doing a loop. We do this delay loop twice because we need to wait for two other LEDs to flash before it’s our turn again. The pull instruction pulls the delay from the read FIFO, then out transfers it to the y register. We move y to x, turn on the pin and then do the delay loop decementing x until its zero. Then we turn the pin off and do the delay loop twice.

.program blink
    pull block
    out y, 32
.wrap_target
    mov x, y
    set pins, 1   ; Turn LED on
lp1:
    jmp x– lp1   ; Delay for (x + 1) cycles, x is a 32 bit number
    mov x, y
    set pins, 0   ; Turn LED off
lp2:
    jmp x– lp2   ; Delay for the same number of cycles again
    mov x, y
lp3:   ; Do it twice since need to wait for 2 other leds to blink
    jmp x– lp3   ; Delay for the same number of cycles again
.wrap             ; Blink forever!

% c-sdk {
// this is a raw helper function for use by the user which sets up the GPIO output, and configures the SM to output on a particular pin

void blink_program_init(PIO pio, uint sm, uint offset, uint pin) {
   pio_gpio_init(pio, pin);
   pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true);
   pio_sm_config c = blink_program_get_default_config(offset);
   sm_config_set_set_pins(&c, pin, 1);
   pio_sm_init(pio, sm, offset, &c);
}
%}

Now the main C program. In this one we configure the pins to use. Note that we will use a coprocessor for each pin, so three coprocessors but each one executing the same program. We start a pin flashing, sleep 200ms and then start the next  one. This way we achieve the same effect as we did in our previous programs.

After we get the LED flashing running on the coprocessors, we have an infinite loop that just prints a counter out to the serial port. This is to demonstrate that the CPU can go on and do anything it wants and the LEDs will keep flashing independently without any of the CPU’s attention.

#include <stdio.h>

#include “pico/stdlib.h”
#include “hardware/pio.h”
#include “hardware/clocks.h”
#include “blink.pio.h”

const uint LED_PIN1 = 18;
const uint LED_PIN2 = 19;
const uint LED_PIN3 = 20;
#define SLEEP_TIME 200

void blink_pin_forever(PIO pio, uint sm, uint offset, uint pin, uint freq);

int main() {
    int i = 0;

    setup_default_uart();

    PIO pio = pio0;
    uint offset = pio_add_program(pio, &blink_program);
    printf(“Loaded program at %d\n”, offset);
    blink_pin_forever(pio, 0, offset, LED_PIN1, 5);
    sleep_ms(SLEEP_TIME);
    blink_pin_forever(pio, 1, offset, LED_PIN2, 5);
    sleep_ms(SLEEP_TIME);
    blink_pin_forever(pio, 2, offset, LED_PIN3, 5);

    while(1)
    {
        i++;
        printf(“Busy counting away i = %d\n”, i);
    }
}

void blink_pin_forever(PIO pio, uint sm, uint offset, uint pin, uint freq) {
    blink_program_init(pio, sm, offset, pin);
    pio_sm_set_enabled(pio, sm, true);
    printf(“Blinking pin %d at %d Hz\n”, pin, freq);
    pio->txf[sm] = clock_get_hz(clk_sys) / freq;
}

Summary

This was a quick introduction to the RP2040’s PIO coprocessors. The goal of any microcontroller is to control other interfaced hardware, whether measurement sensors or communications devices (like Wifi). The PIO coprocessors give the RP21040 programmer a powerful weapon to develop sophisticated integration projects without requiring a lot of specialized hardware to make things easier. It might be nice to have a larger instruction memory, but then in a $4 USD device, you can’t really complain.

For people playing with the Raspberry Pi Pico or another RP2040 based board, you can program in 32-bit ARM Assembly Language and might want to consider my book “Raspberry Pi Assembly Language Programming”.

Written by smist08

April 30, 2021 at 10:02 am

Bit-Banging the Raspberry Pi Pico’s GPIO Registers

with 2 comments

Introduction

Last week, I introduced my first Assembly Language program for the Raspberry Pi Pico. This was a version of my flashing LED program that I implemented in a number of programming languages for the regular Raspberry Pi. In the original article, I required three routines written in C to make things work. Yesterday, I showed how to remove one of these C routines, namely to have the main routine written in Assembly Language. Today, I’ll show how to remove the two remaining C routines, which were wrappers for two SDK routines which are implemented as inline C functions and as a consequence only usable from C code.

In this article, we’ll look at the structure for the GPIO registers on the RP2040 and how to access these. The procedure we are using is called bit-banging because we are using one of the two M0+ ARM CPU cores to loop banging the bits in the GPIO registers to turn them on and off. This isn’t the recommended way to do this on the RP2040. The RP2040 implements eight programmable I/O (PIO) co-processors that you can program to offload this sort of thing from the CPU. We’ll look at how to do that in a future article, but as a first step we are going to explore bit-banging mostly to understand the RP2040 hardware better.

The RP2040 GPIO Hardware Registers

There are 28 programmable GPIO pins on the Pico. There are 40 pins, but the others are ground, power and a couple of specialized pins (see the diagram below).

This means that we can assign each one to a bit in a 32-bit hardware register which is mapped to 32-bits of memory in the RP2040’s address space. The GPIO functions are controlled by writing a 1 bit to the correct position in the GPIO register. There is one register to turn on a GPIO pin and a different register to turn it off, this means you don’t need to read the register, change one bit and then write it back. It’s quite easy to program these since you just place one in a CPU register, shift it over by the pin number and then write it to the correct memory location. These registers start at memory location 0xd0000000 and are defined in sio.h. Note there are two sio.h files, one in hardware_regs which contains the offsets and is better for Assembly Language usage and then one in hardware_structs which contains a C structure to map over the registers. Following are the GPIO registers, note that there are a few other non-GPIO related registers at this location and a few unused gaps in case you are wondering why the addresses aren’t contiguous.

RegisterAddress
gpio_in0xd0000004
gpio_hi_in0xd0000008
gpio_out0xd0000010
gpio_set0xd0000014
gpio_clr0xd0000018
gpio_togl0xd000001c
gpio_oe0xd0000020
gpio_oe_set0xd0000024
gpio_oe_clr0xd0000028
gpio_togl0xd000002c
gpio_hi_out0xd0000030
gpio_hi_set0xd0000034
gpio_hi_clr0xd0000038
gpio_hi_togl0xd000003c
gpio_hi_oe0xd0000040
gpio_hi_oe_set0xd0000044
gpio_hi_oe_clr0xd0000048
gpio_hi_oe_togl0xd000004c

Notice that there are a number of _hi_ registers, perhaps indicating that Raspberry plans to come out with a future version with more than 32 GPIO pins.

In the SDK and my code below we just write one bit at a time, I don’t know if the RP2040’s circuitry can handle writing more bits at once, for instance can we set all three pins to output in one write instruction? Remember hardware registers tend to have minimal functionality to simplify the electronics circuitry behind them so often you can’t get too complicated in what you expect of them.

Bit-Banging the Registers in Assembly

Below is the new updated program that doesn’t require the C file. In our routines to control the GPIO pins, we pass the pin number as parameter 1, which means it is in R0. We place 1 in R3 and then shift it left by the value in R0 (the pin number). This gives the value we need to write. We then load the address of the register we need, which we specified in the .data section and write the value. Note that we need two LDR instructions, once to load the address of the memory address and then the second to load the actual value.

@
@ Assembler program to flash three LEDs connected to the
@ Raspberry Pi GPIO port using the Pico SDK.
@
@

.EQU LED_PIN1, 18
.EQU LED_PIN2, 19
.EQU LED_PIN3, 20
.EQU sleep_time, 200

.thumb_func
.global main             @ Provide program starting address to linker

.align  4 @ necessary alignment

main:

@ Init each of the three pins and set them to output

MOV R0, #LED_PIN1
BL gpio_init
MOV R0, #LED_PIN1
BL gpiosetout
MOV R0, #LED_PIN2
BL gpio_init
MOV R0, #LED_PIN2
BL gpiosetout
MOV R0, #LED_PIN3
BL gpio_init
MOV R0, #LED_PIN3
BL gpiosetout

loop:

@ Turn each pin on, sleep and then turn the pin off

MOV R0, #LED_PIN1
BL gpio_on
LDR R0, =sleep_time
BL sleep_ms
MOV R0, #LED_PIN1
BL gpio_off
MOV R0, #LED_PIN2
BL gpio_on
LDR R0, =sleep_time
BL sleep_ms
MOV R0, #LED_PIN2
BL gpio_off
MOV R0, #LED_PIN3
BL gpio_on
LDR R0, =sleep_time
BL sleep_ms
MOV R0, #LED_PIN3
BL gpio_off

B       loop @ loop forever

gpiosetout:
@ write a 1 bit to the pin position in the output set register
movs r3, #1
lsl r3, r0 @ shift over to pin position
ldr r2, =gpiosetdiroutreg @ address we want
ldr r2, [r2]
str r3, [r2]
bx lr

gpio_on:
movs r3, #1
lsl r3, r0 @ shift over to pin position
ldr r2, =gpiosetonreg @ address we want
ldr r2, [r2]
str r3, [r2]
bx lr

gpio_off:
movs r3, #1
lsl r3, r0 @ shift over to pin position
ldr r2, =gpiosetoffreg @ address we want
ldr r2, [r2]
str r3, [r2]
bx lr

.data
      .align  4 @ necessary alignment
gpiosetdiroutreg: .word   0xd0000024 @ mem address of gpio registers
gpiosetonreg: .word   0xd0000014 @ mem address of gpio registers
gpiosetoffreg: .word   0xd0000018 @ mem address of gpio registers

Having separate functions for gpio_in and gpio_out simplifies our code since we don’t need any conditional logic to load the correct register address.

We loaded the actual address from a shared location. We could have loaded the base address of 0xd000000 and then stored things via an offset, but I did this to be a little clearer. If you look at the disassembly of the SDK routine, it does something rather clever to get the base address. It does:

movs r2, #208 @ 0xd0
lsl r2, r2, #24 @ becomes 0xd0000000

And then uses something like:

str r3, [r2, #40] @ 0x28

To store the value using an index which is the offset to the correct register. I thought this was rather clever on the C compiler’s part and represents the optimizations that the ARM engineers have been adding to the GCC generation of ARM code. This technique takes the same time to execute, but doesn’t require saving any values in memory, saving a few bytes which may be crucial in a larger program.

Summary

Writing to the hardware registers directly on the Raspberry Pi Pico is a bit simpler than the Broadcom implementation in the full Raspberry Pi. With these routines we wrote our entire program in Assembly Language. There is still C code in the SDK which will be linked into our program and we are still calling both gpio_init and sleep_ms in the SDK. We could look at the source code in the SDK and reimplement these in Assembly Language, but I don’t think there is any need. Between the RP2040 documentation and the SDK’s source code it is possible to figure out a lot about how the Raspberry Pi Pico works.

For people playing with the Raspberry Pi Pico or another RP2040 based board, you can program in 32-bit ARM Assembly Language and might want to consider my book “Raspberry Pi Assembly Language Programming”.

Written by smist08

April 24, 2021 at 11:50 am

Calling Main in Assembly Language on the RP2040

with one comment

Introduction

In last week’s article, I presented my first Assembly Language program on the Raspberry Pi Pico. The program worked, but it included some C code that I wasn’t happy with. In this article, I’ll explain why I needed to have the main entry point in C, what I missed and how to correct this problem.

The entry point is a function main() with no parameters or return code called by the RP2040 initialization code after it initializes the RP2040 hardware. In C this worked no problem, but in Assembly Language it resulted in a hardware fault on executing the first instruction in my main() routine. This was a bit of a head scratcher and it took a couple of days before I realized what the problem was. My first thought was that it was alignment, but no it wasn’t that. Perhaps I needed to duplicate the first few instructions in the Assembly Language generated by the C compiler, but no that still caused a hardware fault. Rather mystifying and annoying.

Use the Source

The program you run on the Pico contains pretty much everything in a single executable, that initializes the CPU, peripheral hardware and then runs in an endless loop forever. There is no operating system, just your program. The Raspberry Pi Pico contains a bit of firmware which is activated when you power on with the bootsel button pressed, this allows the Pico to connect as a shareable flash drive to a USB host, and will allow you to copy files into the writable part of the Pico’s flash memory. After that it reboots to let the program run.

One of the good things about the Pico is that the SDK contains the source code for this whole thing, and when you build your program, it actually compiles all this source code alongside your code (there are no libraries in this environment). This means you can build a debug build where everything is debuggable including both your code and the SDK code. This means you can set a breakpoint before your code and single step through the SDK into your code. You can’t start debugging at the very first instruction, you need to let the first bit of the SDK initialize the processor before starting, but you can set a breakpoint fairly early. I found a good place was the platform_entry routine, which is an Assembly Language function in crt0.S. This is the function that initializes the SDK environment and then calls your main() starting point. The code for this routine is fairly innocuous:

platform_entry: // symbol for stack traces
    // Use 32-bit jumps, in case these symbols are moved out of branch range
    // (e.g. if main is in SRAM and crt0 in flash)
    ldr r1, =runtime_init
    blx r1
    ldr r1, =main
    blx r1
    ldr r1, =exit
    blx r1

Nothing special, it just loads the address of our main routine and calls it. Stepping through the C code, it works, stepping through the Assembly Language code, hardware fault.

At some point I thought to look at the documentation for the BLX instruction, why were they calling this rather than BL? This turned out to be the root of the problem.

On a full ARM A-series CPU, like those in a full Raspberry Pi or in your cell phone, it can execute a rich set of instructions, which are the regular ARM 32-bit instruction set, but on the microcontroller M-series CPU like in the Pico it only executes the so called “thumb” instructions. On the A-series CPU you switch back and forth between regular and thumb modes using the BLX instruction. Thumb instructions are 16-bit in length, regular instructions are 32-bit, both have to be aligned, on even bytes the other on 4-byte boundaries. Both of these are even addresses so the true address of any instruction is even, which means the low order bit isn’t really used (it has to be zero). The BLX instruction uses this low order bit to specify whether to switch to thumb mode or not. If it is one, then thumb mode, if even then regular instruction mode. Let’s look at the disassembly for this routine:

1000021a <platform_entry>:
1000021a: 4919      ldr r1, [pc, #100] ; (10000280 <__get_current_exception+0x1a>)
1000021c: 4788      blx r1
1000021e: 4919      ldr r1, [pc, #100] ; (10000284 <__get_current_exception+0x1e>)
10000220: 4788      blx r1
10000222: 4919      ldr r1, [pc, #100] ; (10000288 <__get_current_exception+0x22>)
10000224: 4788      blx r1

10000280: 100012bd .word 0x100012bd   ; runtime_init
10000284: 10000361 .word 0x10000360   ; main
10000288: 100013a9 .word 0x100013a9   ; exit

Notice the address for my main routine is even whereas the other two routines are odd. If I compile with the C routine then main has an odd address as well. I didn’t think of this because the RP2040’s M-series CPU only executes thumb instructions, so why have any functionality to switch between modes? I don’t know but if you do tell it to switch to regular instructions then you get a hardware fault.

The other question is why the author of crt0.S in the SDK calls routines with BLX rather than BL? Afterall the Pico doesn’t support regular instructions, so you are always in thumb mode. If platform_entry used BL instead, then I wouldn’t have had any problem. I wonder if this indicates they developed the SDK on an A-series CPU, perhaps before they obtained real RP2040’s and this indicates how they did early development on the SDK? Or perhaps there is a way to emulate the RP2040 on a full A-series CPU and this is how the developers at the Raspberry Pi foundation operate.

To correct the problem, we just need to indicate our main() routine is a thumb routine. We do this by placing a .thumb_func directive in front of the .global directive.

.thumb_func
.global main             @ Provide program starting address to linker

.align  4 @ necessary alignment

main:

The key point is that this is in front of the .global, since it is really just the linker that needs to process this to set up the correct address when it links in crt0.

Summary

This eliminates the need for the C main() function we had last week. Next time we’ll eliminate the two other C routines we had and explore how the Raspberry Pi Pico’s GPIO control registers work. As with most problems, working through the solution, teaches us a bit more about how the RP2040 works and reminds us that there are consequences of using a subset of the full ARM instruction set.

For people using this SDK, you can program in 32-bit ARM Assembly Language and might want to consider my book “Raspberry Pi Assembly Language Programming”.

Written by smist08

April 23, 2021 at 9:11 am

Assembly Language on the Raspberry Pi Pico

with 3 comments

Introduction

The Raspberry Pi Pico is the Raspberry Foundation’s first entry into the domain of Arduino style microcontrollers. The board contains Raspberry’s own designed SoC (System on a Chip) containing a dual core ARM Cortex-M0+ CPU along with memory and a collection of I/O circuitry. There are no keyboard, mouse or monitor ports on the board, only a micro-USB to connect to a host computer, a number of GPIO pins and three debug pins. This SoC is called the RP2040 and is licensed to other companies to use in their own boards. Raspberry supports programming this board in either C/C++ or MicroPython. The C/C++ SDK also supports Assembly Language programming to some degree and this article is a look at my first attempt to write an Assembly Language program for this board. I ran into a few problems and still have a few things to figure out and we’ll explain those in the article. We’ll write an Assembly Language version of the program we wrote in C last time to flash three connected LEDs.

ARM Cortex-M0+ Assembly Language

I blogged about 32-bit ARM Assembly Language here, and then presented the flashing LED Assembly Language program for the Raspberry Pi here. Further I wrote a whole book on 32-bit ARM Assembly Language Programming: “Raspberry Pi Assembly Language Programming”. These are all oriented to ARM’s full A-series processors which include floating point units (FPU), vector processors, virtual memory support and much more. The ARM M-series processors are a subset of these, designed to be low cost, use little memory and be very power efficient. The ARM M-series processors only contain what are called the ARM “thumb” instructions. Normally, on an A-series processor, each instruction takes 32-bits, but for some applications this uses too much memory, so ARM came up with “thumb” instructions where if the processor is operating in “thumb” mode then each instruction is only 16-bits in length, thus only using half the memory. The original set of “thumb” instructions was too limited, so ARM added a way to run some 32-bit instructions in with the 16-bit instructions and that makes the modern “thumb” instructions set used by the M-series processors. One consequence of using the “thumb” instructions is that registers R8 to R12 are not accessible and hence not implemented on the chip, thus saving circuitry. The registers you do have are all 32-bit and the Raspberry RP2040 has special multiplication and division circuitry to perform these operations quickly.

Code

This program uses the C/C++ SDK to access the GPIO pins, this means this Assembly Language program is quite similar to last week’s C program. To call a routine in Assembly, you put the first parameter in R0, the second in R1 and then call Branch with Link (BL). BL places the address of the next instruction into the LR register, so the called return returns by branching to the address contained in the LR register. When calling functions there is a convention on who has to save which register on the stack, but we don’t use any register over the function calls, so we don’t need to do this. This program is set up as an infinite loop, since there is nothing for the main routine to return to and if it does return the processor halts.

Assembly Language code:

@
@ Assembler program to flash three LEDs connected to the
@ Raspberry Pi Pico GPIO port using the Pico SDK.
@
@

.EQU LED_PIN1, 18
.EQU LED_PIN2, 19
.EQU LED_PIN3, 20
.EQU GPIO_OUT, 1
.EQU sleep_time, 200

.global main_asm             @ Provide program starting address to linker
main_asm:

MOV R0, #LED_PIN1
BL gpio_init
MOV R0, #LED_PIN1
MOV R1, #GPIO_OUT
BL link_gpio_set_dir
MOV R0, #LED_PIN2
BL gpio_init
MOV R0, #LED_PIN2
MOV R1, #GPIO_OUT
BL link_gpio_set_dir
MOV R0, #LED_PIN3
BL gpio_init
MOV R0, #LED_PIN3
MOV R1, #GPIO_OUT
BL link_gpio_set_dir
loop:   MOV R0, #LED_PIN1
MOV R1, #1
BL link_gpio_put
LDR R0, =sleep_time
BL sleep_ms
MOV R0, #LED_PIN1
MOV R1, #0
BL link_gpio_put
MOV R0, #LED_PIN2
MOV R1, #1
BL link_gpio_put
LDR R0, =sleep_time
BL sleep_ms
MOV R0, #LED_PIN2
MOV R1, #0
BL link_gpio_put
MOV R0, #LED_PIN3
MOV R1, #1
BL link_gpio_put
LDR R0, =sleep_time
BL sleep_ms
MOV R0, #LED_PIN3
MOV R1, #0
BL link_gpio_put
B       loop

.data

      .align  4 @ necessary alignment

I didn’t intend to include any C code, but I ran into a couple of problems that require it. One is that a large number of SDK functions are inline C functions which means they can’t be called from outside of C. In our case two functions gpio_set_dir and gpio_put are inline and required wrapping. The other problem is that if the main program is Assembly Language then the code to initialize the board doesn’t seem to be called. I think this is a matter of setting the correct CMake options, but I haven’t had a chance to figure it out yet. For now we have main in the C code and then call the Assembly Language main routine.

C code:

#include “hardware/gpio.h”

void link_gpio_set_dir(int pin, int dir)
{
gpio_set_dir(pin, dir);
}

void link_gpio_put(int pin, int value)
{
gpio_put(pin, value);
}

void main()
{
main_asm();
}

The Raspberry Pi Pico SDK uses the CMake system to manage builds. The SDK provides a large set of build rules. You run CMake and then it creates a makefile that compiles your program.

CMake file:

cmake_minimum_required(VERSION 3.13)

include(pico_sdk_import.cmake)

project(test_project C CXX ASM)

set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

pico_sdk_init()

include_directories(${CMAKE_SOURCE_DIR})

add_executable(flashledsasm
  mainmem.S
  sdklink.c
)

pico_enable_stdio_uart(flashledsasm 1)
pico_add_extra_outputs(flashledsasm)
target_link_libraries(flashledsasm pico_stdlib)

Still To-Do

The program works, but there are a few things I’m not happy about. The Raspberry Pi Pico SDK is pretty new, so there aren’t a lot of answers on StackOverflow yet. The good thing is that it is all open source, so it is just a matter of time to figure out the code. Here is what I’ll be working on:

  1. How to have main be in Assembly Language and have the board properly initialized. Match the C startup sequence.
  2. Figure out the details of the GPIO registers and have Assembly Language versions of the inline C code that accesses these. They are similar to those on the full Raspberry Pi, but different.
  3. How to get constants from the C include file, on first try this didn’t work and gave syntax errors, but the SDK says they should be usable from Assembly Language. They might need a couple of fixes.

Summary

I planned to write a 100% Assembly Language program, but didn’t quite make it. At least the program works, showing you can include Assembly Language in your RP2040 projects. The support to build using the GCC macro assembler is all there and besides some interactions with the SDK all seems to work well. Of course the Raspberry Pi Pico SDK is pretty new so there will be a lot of updates and there are still a number of undocumented holes to investigate.

Written by smist08

April 16, 2021 at 9:43 am

Raspberry Pi Pico First Project

with 3 comments

Introduction

Last week, I blogged about Adafruit’s Feather RP2040 microcontroller. I’ve now received a Raspberry Pi Pico which is also based on the ARM RP2040 processor. The Adafruit version is oriented around programming with CircuitPython and then interfacing to the various companion boards in Adafruit’s Feather lineup. The Raspberry Pi Pico is oriented around programming in C/C++ using the Raspberry Pico SDK and then designing interfaces to other devices yourself. Although you can do either with both boards, I’m going by the direction of the two companies tutorials and volume of documentation. The Raspberry Pi Pico also favours doing your development from a full Raspberry Pi, although you can use a Windows, Linux or Mac, it is quite a bit harder to setup serial communications and debugging.

In this article, I’m going to look at doing a small project with the Raspberry Pi Pico using the C SDK. I’ll look at the elements you use to program, debug and deploy code. I’ll use the same flashing LEDs project that I’ve written about previously.

More Soldering

Like the Adafruit board, if you want to use a breadboard to set up your electronics project, you need to solder pins to the Pico to attach it. Having practiced on the Adafruit Feather, this was no problem. In addition if you want to do proper C debugging using gdb then you need to solder three wires to the debug ports on the end of the board. Note you need wires that can connect to the Raspberry Pi 4’s GPIO pins. All the soldering went fine and when I wired everything up I got serial communications going as well as played a bit with debugging using the SDK’s sample blink program. I was lucky that I could find all the wires, connectors and pins required from previous various Arduino and Raspberry starter kits.

Setting up the LEDs

If you want to use print statements while you are debugging, then you need to use the separate serial communications pins rather than a serial communications channel through the USB port. This is because when you stop the processor in the debugger, it stops it dead and disconnects any USB connections.

The picture below shows the setup. The LEDs are connected each to a GPIO port and then go through a resistor to ground. Remember LEDs have low resistance and you don’t want to short out your device. Also remember that LEDs are directional and you want to connect the plus side to the GPIO pin. The plus side is usually indicated by the longer lead wire.

In the picture above you can also see the 3 wires at the end going off to the Raspberry Pi as well as the three wires by the USB port that lead to serial communications GPIO pins on the Pi. The USB connects to the Pi to provide power, as well as is used to load any program into the flash memory.

A single picture can be hard to see, here is a video showing the LEDs flashing as well as panning around a bit to see all the connections from different angles: https://youtu.be/ogbcMp5Asu4

Code

The C/C++ SDK for the RP2040 provides a set of libraries to help with your device programming along with support for using the GCC toolchain. This means you can write code in C/C++ and Assembly Language and then debug using gdb. If you look at the C code, it is similar to the code we wrote for the regular Raspberry Pi here, though we had to write some of these library type routines against the Linux device driver ourselves.

Here is the C code:

#include <stdio.h>
#include “pico/stdlib.h”
#include “hardware/gpio.h”
#include “pico/binary_info.h”

const uint LED_PIN1 = 18;
const uint LED_PIN2 = 19;
const uint LED_PIN3 = 20;

int main()
{

    bi_decl(bi_program_description(“Copyright (c) 2021 Stephen Smith”));

    stdio_init_all();
    gpio_init(LED_PIN1);
    gpio_init(LED_PIN2);
    gpio_init(LED_PIN3);
    gpio_set_dir(LED_PIN1, GPIO_OUT);
    gpio_set_dir(LED_PIN2, GPIO_OUT);
    gpio_set_dir(LED_PIN3, GPIO_OUT);

    while (1)
    {
        puts(“Flash Loop\n”);
        gpio_put(LED_PIN1, 1);
        sleep_ms(200);
        gpio_put(LED_PIN1, 0);
        sleep_ms(200);
        gpio_put(LED_PIN2, 1);
        sleep_ms(200);
        gpio_put(LED_PIN2, 0);
        sleep_ms(200);
        gpio_put(LED_PIN3, 1);
        sleep_ms(200);
        gpio_put(LED_PIN3, 0);
        sleep_ms(200);
    }

The SDK defines projects using CMake. When you run CMake it will generate a makefile that you use to build your executable using make. Here is the CMake file:

cmake_minimum_required(VERSION 3.13)

include(pico_sdk_import.cmake)

project(test_project C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

pico_sdk_init()

add_executable(flashleds
  flashleds.c
)

pico_enable_stdio_uart(flashleds 1)
pico_add_extra_outputs(flashleds)
target_link_libraries(flashleds pico_stdlib)

Print Statements

In the C code there is a puts() function call to send “Flash Loop” to stdout. You can define what this is in the CMake file, in our case it’s set to the serial port (as opposed to the USB port). We can then read this data by monitoring the serial port on the Raspberry Pi 4 that we’ve connected up. One way to display the output is with the minicom program by calling:

minicom -b 115200 -o -D /dev/serial0

Which then displays:

Debugging

The Pico and the C/++ SDK have support for gdb. You run gdb on the Raspberry Pi 4 and then gdb connects remotely through minicom to the Raspberry Pi Pico. The C tutorial has full instructions on how to do this and when running it works quite well, though it takes several long command lines to get debugging going.

Visual Studio Code

The C/C++ SDK has full support for Visual Studio Code. This is the reason Raspberry added Microsoft repositories to the Raspberry Pi OS to seamlessly install and update this. After all the outcry from users, the calls to the Microsoft repositories have been removed and you need to install this by hand, as documented in the C getting started manual. I’m not really keen on Visual Studio Code, but if you like it and want to use it, go for it.

The best thing about Visual Studio Code is that it automates setting up remote debugging, so you can just say debug and Visual Studio Code does all the setup and connecting behind the scenes.

Summary

Both the Raspberry Pi Pico and Adafruit Feather RP2040 are powerful computers and great value as $5 microcontrollers. The programming environments are rich and powerful. You have lots of choices on how to program these with a lot of good supporting libraries and SDKs. The RP2040 exposes all sorts of GPIO ports and interfacing technology for you to make use of in your projects. It will be interesting to see all the RP2040 based DIY projects being showcased.

For people using this SDK, you can program in 32-bit ARM Assembly Language and might want to consider my book “Raspberry Pi Assembly Language Programming”.

Written by smist08

April 8, 2021 at 3:12 pm

Adafruit Feather RP2040 First Impressions

with 3 comments

Introduction

Last week we talked about the Raspberry Pi’s entry into the microcontroller market with their new RP2040 chip. I had ordered a couple of these, but had yet to receive one. Last Wednesday I received my Adafruit Feather RP2040, this is Adafruit’s entry into this market using Raspberry’s new ARM based RP2040 microcontroller. In this article, I’ll give my first impressions of this Adafruit board, with the caveat that I’ve only had it two days now.

The Adafruit board is similar to the Raspberry Pi Pico, but it is in the form factor for Adafruit’s feather line of peripherals. This means you can stack and intermix the peripherals just like with any other feather microcontrollers. This means the pins correspond to the feather specification rather than those on the Raspberry Pi Pico. This is good since it means you have a large selection of peripherals that are easy to use and pretty much snap together. Further Adafruit has done a good job of providing Python drivers for all their devices. Beyond this, the Adafruit board has a connector for a battery and will manage running off the battery, or charging the battery when connected via USB. The Adafruit board also has an RGB LED that programs can use and a reset button in addition to the boot selection button.

Painful Shipping

The best thing about the Adafruit board was that it was the first RP2040 board that I found that I could actually order, no waiting list, no back order. Kudos, it actually shipped later in the day I ordered it on. The bad news was that the only shipping option was DHL at the exorbitant price of $20USD. I think a lot of companies that sell inexpensive microcontroller parts, usually at around $5 USD each, make all their money by overcharging for shipping. DHL used to be good when they had a big contract to do deliveries for Amazon, then they delivered here reliably every day. Since they lost the Amazon contract, they don’t even deliver to our community and as a result it took an extra four days for the package to get to Gibsons from Vancouver, because they reshipped it with a different courier company and were slow about the process. If Adafruit had an option to use the regular post, it would have been cheaper and would have gotten here quicker. They could have still overcharged for it, but perhaps not as much.

Unboxing

I ordered a few extras along with the Adafruit board, namely a FeatherWing 128×32 OLED display and a lithium ion battery and connector cables. This all arrived in a cardboard box full of bubble wrap with the actual parts safely tucked inside.

I saw that a Raspberry Pi Pico connects to your computer via a micro-USB cable, so I had one of these ready. Picking up the Adafruit RP2040 revealed it uses a USB-C cable, so I had to run upstairs and dig one of these out. This highlights that if there are easy choices in the board design, Adafruit chooses the alternative to what Raspberry chose, I guess to differentiate themselves. Anyway, plugging in the Adafruit to my Raspberry Pi worked, namely it displayed in the Raspberry Pi as a removable disk drive, showing a view to the 8MB flash ROM where you copy your programs to run. Yay, it is working. Next I installed CircuitPython and ran a test program that blinks one of the LEDs on the board. I’ll talk more about CircuitPython after a bit of soldering.

Assembly Requires Soldering

The nice thing about the Arduino Uno and regular Raspberry Pi’s is that they are easy to attach to breadboards for prototyping and experimenting with electronics, everything just snaps together, no soldering required. That isn’t true for either the Adafruit Feather nor the Raspberry Pi Pico. If you want to use a breadboard, you need to solder some pins to them. Both Adafruit and Raspberry have excellent tutorials on how to do this. It was a bit intimidating, since I have a cheap $10 soldering iron from Canadian Tire and the board is very small. Another good thing about the Adafruit RP2040 (and the OLED display board) is that they come with the pins you need for this (you need to order these separately for the Raspberry Pi Pico).

Anyway I went ahead to do this and it turned out to be easier than expected. Heat the pin up with the soldering iron first and then the solder easily flows into position. A bit of a relief since Adafruit recommends buying a $200 soldering iron.

Perhaps down the road, either the various board makers or the companies that assemble kits from these will include an option where these are already soldered in place and perhaps integrated with a breadboard, like the official Arduino Uno starter kit. I see other Adafruit feather boards can be ordered with or without the pins installed, so perhaps they’ll have this available soon.

The reason these pins aren’t automatically built in place, is that this leaves makers a lot of options to package their final products into much smaller packages, since you can solder wires and devices directly to these points.

CircuitPython

The Raspberry Pi tutorial and documentation is all oriented around MicroPython and then the Adafruit documentation and tutorials are all oriented around CircuitPython. CircuitPython is based on Micropython, but taken by Adafruit and made a bit easier to use, especially if you use Adafruit devices. These RP2040 boards basically run one program, so to run Python you need to install the Python runtime to be that one program. To do this you download the CircuitPython UF2 file from Adafruit’s website and copy it to the board’s flash ROM. The board then reboots and the removable drive changes to be a folder inside the CircuitPython environment where you copy your Python program to run. Basically if you copy a file called code.py to this folder then it will be run. You can use the bootsel button to boot into the original view, if you want to later replace the Python runtime with something else.

To actually develop, you need a Python IDE running on a proper computer. Raspberry recommends using Thonny and Adafruit recommends using mu-editor. Thonny comes pre-installed on the Raspberry Pi OS, but adding mu-editor was easy, since it is written in Python, you install it with pip3:

pip3 install mu-editor==1.1.0b3

With this I could cut/paste the blink program from the Adafruit tutorial in and save it as code.py to the device and see the LED on the board flashing. The CircuitPython runtime provides a serial connection back to the IDE via the USB port, so if you click the “Serial” button in the IDE you can see the Python console. At this point you can control Python to some degree through the command line as well as see the output from print statements.

Next up, I connected up the OLED display and wanted to get this to try. Below is a picture of the two devices connected together on a breadboard.

I copy/pasted the Python code for this from another Adafruit tutorial, saved it to the board and nothing happened. Looking at the serial port showed I was getting missing library errors. Of course the next step in the tutorial is to download all  the device specific CircuitPython libraries. Adafruit provides a bundle of all the drivers for their devices, so I downloaded this.

First I tried just copying the libraries I thought I needed, but I didn’t have much luck and kept getting errors. Then I just copied all the libraries and then everything worked as shown in the above photo. The whole library takes 1.9Meg of the 8Meg Flash ROM, so I might try deleting some later.

To give a flavour of CircuitPython programming, below is the sample program to display “Hello World!” in a box on the display:

# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT
“””
This test will initialize the display using displayio and draw a solid white
background, a smaller black rectangle, and some white text.
“””

import board
import displayio
import terminalio
from adafruit_display_text import label
import adafruit_displayio_ssd1306

displayio.release_displays()
i2c = board.I2C()
display_bus = displayio.I2CDisplay(i2c, device_address=0x3C)
display = adafruit_displayio_ssd1306.SSD1306(display_bus, width=128, height=32)

# Make the display context

splash = displayio.Group(max_size=10)
display.show(splash)
color_bitmap = displayio.Bitmap(128, 32, 1)
color_palette = displayio.Palette(1)
color_palette[0] = 0xFFFFFF  # White
bg_sprite = displayio.TileGrid(color_bitmap, pixel_shader=color_palette, x=0, y=0)
splash.append(bg_sprite)

# Draw a smaller inner rectangle

inner_bitmap = displayio.Bitmap(118, 24, 1)
inner_palette = displayio.Palette(1)
inner_palette[0] = 0x000000  # Black
inner_sprite = displayio.TileGrid(inner_bitmap, pixel_shader=inner_palette, x=5, y=4)
splash.append(inner_sprite)

# Draw a label

text = “Hello World!”
text_area = label.Label(terminalio.FONT, text=text, color=0xFFFF00, x=28, y=15)
splash.append(text_area)

while True:
    pass

Summary

The Adafruit Feather RP2040 is a good choice for a more powerful ARM based microcontroller. Its advantage over the Raspberry Pi Pico is the feather hardware ecosystem. Many people will also find the battery connector convenient, since many people will want their final build running off a rechargeable battery. Adafruit has done a good job getting all their CircuitPython support going and there is quite a bit of documentation and tutorials on their website.

I haven’t gotten the RP2040 C/C++ SDK going with the Adafruit board yet, but there is support for this board in the SDK, with a header file of all the pin definitions. For people using this SDK, you can program in 32-bit ARM Assembly Language and might want to consider my book “Raspberry Pi Assembly Language Programming”.

Written by smist08

April 2, 2021 at 11:16 am

Introduction to the RP2040

with 7 comments

Introduction

The Raspberry Pi foundation recently started shipping the Raspberry Pi Pico, a flexible $4 USD microcontroller board. This is Raspberry’s first foray into the world of microcontroller boards, typically Raspberry Pi’s are low cost complete Linux computers and the microcontroller world has been typically dominated by the Arduino line of products, which are typically based on low cost 8-bit processors. One notable part of this announcement is that the processor included on the Pico is a dual core ARM processor with the System on a Chip (SoC) being designed by the Raspberry Pi foundation. In the past all Raspberry Pis have been based on Broadcom SoCs.

This new processor is the RP2040. Not only is this processor being used in the Pi Pico, but the Raspberry Pi foundation is selling this chip to other board manufacturers to use in their own product. Already many companies and foundations that develop Arduino boards are starting to ship products based on the RP2040, but designed to fit into their own eco-system whether it is Arduino or one of its competitors. For instance Arduino, Pimoroni, SparkFun, and Adafruit have all announced either shipping or near shipping products. I haven’t been able to order a Raspberry Pi Pico yet, since they instantly sold out, but I have been able to buy a similar Adafruit board.

All these RP2040 based boards are under $10USD and all of them have lots of GPIO ports to integrate them into your hardware projects. In this article we are going to look into some of the details of the RP2040 chip itself.

RP2040 Overview

The heart of the RP2040 are dual core ARM Cortex-M0+ 32-bit CPUs that operate at 133MHz, along with 264Kb of SRAM. This may not seem like much compared to regular Raspberry Pis or other common inexpensive computers, but in the microcontroller world this is really good. Most microcontrollers are based on slower 8-bit microcontrollers with only a few k of memory, for instance the Arduino Uno operates at 16MHz and has 6kb of memory. There are a sprinkling of 32-bit based microcontrollers based on various ARM or RISC-V models, but the RP2040 is the first to take these mainstream. Keep in mind that the original Apple II operated at 1MHz on an 8-bit CPU and only supported up to 48kb of RAM, yet it was fully capable of word processing, spreadsheets and arcade like video games. The original IBM PC only operated at 4.77MHz, had a 16-bit processor and upto 640Kb of RAM. This $4 microcontroller has far more computing power than any of these early PCs, so it will be pretty amazing to see what people produce.

The ARM Cortex-M0+ core is a low energy 32-bit processor. My book “Raspberry Pi Assembly Language Programming” covers 32-bit Assembly Language programming for a full A series ARM CPU. The M series ARM CPUs for microcontrollers contain a subset of the processing units in the full A series CPUs. For instance, there is no floating point unit (FPU) and no NEON vector processing unit. Further, it doesn’t use the full 32-bit sized instructions, instead it only uses the so called “thumb” instructions which are 16 bit in size. This means there are only eight 32-bit registers for integer arithmetic and other processing (there is only room for three bits to specify a register). With these limitations, the transistor count is greatly reduced for the CPU, reducing power usage and reducing cost. Even with these restrictions, the RP2040 is powerful enough to run Tensorflow Lite.

The RP2040 is manufactured by TSMC using an old 40nm process. This greatly reduces the cost of the chip, since there isn’t much competition for this manufacturing technology. Apple’s latest chips use a 5nm manufacturing process and there is a long waiting list of companies waiting for capacity.

Programming

Typically you program the Raspberry Pi Pico in MicroPython or C/C++ without an operating system. You write your program, compile it and download it to the Pico where it runs as a single program with no operating system. The Raspberry Pi foundation offers full support for MicroPython as well as provides a C/C++ SDK that allows you to compile programs in C, C++ or Assembly Language.

If you are familiar with Arduino and how you program these, then this is exactly how you program the Pico. Which means you need another computer to run the IDE (this could be a regular Raspberry Pi). Then the Pico is connected to this computer via USB.

Of course the Linux folks aren’t sitting still, they take the challenge that Linux should run anywhere quite seriously and have already ported Fuzix, a lightweight Linux to the Pico.

This is more likely to be used for embedded type Linux applications, since connecting monitor, keyboard and mouse are a major challenge that the Pico isn’t designed for.

Will Raspberry Produce Other Chips?

It will be interesting to see if the Raspberry Pi Foundation sticks with Broadcom chips for the regular Raspberry Pis. Will the Raspberry Pi 5 be based on a Pi Foundation designed SoC? If it is, would it allow them to use newer CPU cores? Will it mean they can incorporate an ARM Mali GPU rather than the Broadcom GPU they have been using? Will there be other models of embedded chips beyond the RP2040? Evidently the numbers are significant, the 2 is for the number of cores and the 4 indicates the memory size and then the 0’s are for possible future features. We’ll have to watch Raspberry’s product announcements closely over the next year or two.

Summary

The RP2040 is exciting because it could take the microcontroller market from 8-bit to 32-bit, increasing the programming capabilities of all these DIY electronics projects greatly. Not everyone will move to this, since it will also push the price of 8-bit microcontrollers even lower. But perhaps your next microwave or toaster will contain AI software running on an RP2040.

Written by smist08

March 26, 2021 at 10:38 am

Technology Tips for the Backcountry

with one comment

Introduction

As spring starts and the snow line starts to move back up the mountains, lots of people are planning their hiking and outdoor recreation goals for this new season. With COVID curtailing many of people’s usual indoor activities, we are seeing many new people out on the trails in their brand new hiking boots and other equipment. In this article, I’m going to review some common technologies and techniques to help you stay safe, avoid getting lost, and provide a way to get help if you need it.

This article doesn’t cover other things you need such as sufficient water, food, good hiking boots, warm/waterproof clothes, first aid kit, knife/multitool, bear spray, fire starter, sunscreen, headlamps, and shelter to spend the night.

Technology Breaks

Batteries die, devices can be dropped in a creek and cell phone coverage isn’t good in the Canadian wilderness. Generally it is good to have a backup plan. Knowing how to use a map and compass is a great backup. Even then compasses can fall apart, and a printed map won’t survive getting wet unless plasticized. Here are a few tips to help keep things working:

  • Cell phone battery packs are reasonably inexpensive and light. These provide a great way to recharge your cell phone or other device. Remember to charge the battery pack before a trip and to include the connector cable. Pack the cable and battery together in a ziplock bag to keep them dry. If a device doesn’t have rechargeable batteries, make sure you bring along a spare set of batteries and remember batteries fade even when not in use, so replace these every year. It’s a good idea to carry a separate headlamp or good flashlight, so you don’t need to rely on your phone as a flashlight as this won’t last long and there are more important things to do with your phone.
  • As temperature drops, the internal resistance in batteries increases, reducing their capacity. Typically a battery will only have 50% capacity at -18°C. Keep devices with batteries in your inside pockets so your body heat will keep them warm. Do not keep them in outside pockets on your pack.

  • Have a good shock resistant case for your phone, so if you drop it and it hits a rock, it is ok. Most newer phones are fairly water resistant, but a waterproof case can help. Generally try to keep your device out of the direct rain just in case.

  • Search & Rescue (SAR) statistics show that most lost people are alone. Part of this is that when hiking with a buddy or group, then you have more phones, possibly on different networks, redundancy of equipment and someone there to help if you get stuck or injured.

Let Someone Know Where You Are

If Search & Rescue finds someone within 24 hours of being lost, their chances are very good. Then for each day beyond that the survival statistics fall off rapidly. It is crucial that someone knows where you went and when you are expected back. If no one notices you missing for a week or they don’t know where you went, it can be a life threatening situation. Searching all the trailheads and forest service roads for your car is time consuming and often takes days.

If you hike a lot, just casually telling someone where you are going is probably insufficient. They could easily forget, not really know when you are expected back, confuse the latest hike with a previous hike or not really know which trailhead you went to. A better way is to email or text a message to the person, so they have something to look up. Make sure you include the exact trails you are doing, who you are going with, when you are starting, the trailhead you are parking at and when you are expected back and when to consider you overdue. If your plans change, cancel the hike unless you can update them. It’s a good idea that someone knows what equipment you travel with so SAR knows your capabilities.

There are a couple of apps to help with recording where you are going, that Search & Rescue can also tap into:

AdventureSmart Trip Planner: This is a great app to record the information for your next trip.

Overdue Trip Plan: Another trip planner app, that automates notifying your contacts and includes some offline map and navigation capability.

Prepare to be Offline

If you live in the city, you are used to your mobile phone always working. You can call, text, email or facebook anytime without thinking about it. You don’t have to head very far outside of the city into the backcountry before this stops being so reliable. Even if you can see a large cell phone tower up on the mountain above you, you still may not get coverage. Often when you do a longer hike you will go in and out of coverage as you go up and down and the terrain closes around you or opens up. Here are some tips to deal with being out of coverage. These are both to help you navigate as well as being able to call for help if you need it.

Use 911 to Call for Help

If you need help, call 911 rather than calling a friend. Even if your phone is out of coverage, 911 might still work because it will use any cell network, not just the one you subscribe to. Further the 911 call will include your GPS position, helping SAR get to you directly without having to mount a major search.

Offline Maps

Google and Apple Maps only work when you are online. Besides that they are terrible when you are in the backcountry. They don’t have many trails or landmarks and usually make it look like you are in a green desert. Make sure you use an App with trails, backcountry details and that it downloads the maps to your phone so it can work when out of coverage. Trailforks is a good choice here. More full featured GPS apps like Gaia or ViewRanger are great, but you need to purchase a yearly subscription to download their maps. Another option is to use a standalone GPS such as one of the many Garmin ones.

Satellite Devices

If you really need to stay online, you can purchase a satellite phone. The downside to these is that they are quite expensive and their data plans make regular cell plans look cheap. These are great devices, and will work in many places where cell phones won’t work. But they don’t work everywhere, they need line of sight to their satellite and hence won’t work in gulleys, some valleys and dense vegetation. The good thing is that you usually don’t need to travel far to get reception, on the other hand if you are stuck, you can’t call for help.

 A cheaper alternative are devices like SPOT and InReach. These are satellite devices that can send a selection of messages through the satellite network, but don’t have general communications capability. You can use these to send ok messages, SOS messages as well as let people track your progress on a hike. The subscription fees for these devices is a lot less than full satellite phones and you can often get a discount by calling them.

If you are using one of these devices, they have the capability to track your progress to a website and if you let people know the URL for this map, they can see where you are in real time. If you have one of these devices, make sure you turn on trip tracking at the start of every excursion. This is in case you get in trouble and can’t hit the SOS button, perhaps you fall and hit your head, perhaps you get stuck in a gully. Then SAR can use this map to know your last known position in much greater detail. Chances are you are located at most a ten minutes walk from this last plotted point which allows SAR to find you quicker than starting the search at your car.

Other cell phone apps like Strava and ViewRanger have this capability but can only report when you are in cell coverage. This can still be helpful, as if you are going in and out of coverage it might provide a better last known position than your car helping searchers get to you quicker.

Summary

Whenever you travel into the backcountry you need to be prepared for any eventuality. Weather changes quickly, even a minor fall can hurt your ankle, greatly slowing you down. This article just touches on a few things that can help make your outdoor activities safer and give you peace of mind to enjoy the environment.

Written by smist08

March 19, 2021 at 11:10 am

Some Useful Phone Apps for Search & Rescue

with 2 comments

Introduction

Cell phones have become extremely useful tools for Search & Rescue (SAR) groups providing all-in-one functionality for GPS, maps, camera, communications, reference manuals and even provide an emergency light. This article lists some useful apps to have on your phone to help with SAR activities. Of course, you don’t want to 100% rely on your phone since batteries fail and all equipment can fail in the difficult environments we operate in. That being said, newer phones have longer battery life, are waterproof (to some degree) and in a good case are fairly durable.

Weather and Conditions

WeatherCAN: There are lots of good weather applications as well as the one built into your phone. I like WeatherCAN, but there are lots of good alternatives.

AvalancheCanada: In winter, checking avalanche conditions is crucial to your team’s safety. The Avalanche Canada app is the good one and you should always check the conditions before heading out. Further, be sure to use the app to report conditions as you travel in avalanche terrain.

BC Wildfire: In the summer, there can be wildfires affecting our searches, whether causing us to avoid areas or having our search area obscured by smoke. This app is a good way to keep an eye on what is going on.

First Aid

BCEHS Handbook: This handbook has all our treatment guidelines, so if you have a first aid situation and need to look something up, this is a handy tool to have. Further it saves weight on not needing to have printed books in your pack.

AED: This app lets you locate the nearest AED if you are handling a heart attack. Useful for urban searches as well it is handy outside of SAR.

First Aid: This is the Canadian Red Cross app which contains lots of useful information on common simple first aid procedures.

CPR Tempo: The rate of performing chest compressions is fairly fast and you need to keep it up, even as you get tired. This app is a simple way to get beeps at the correct rate to keep you steady.

Navigation

Avenza Maps: Most SAR management packages can produce maps in PDF format. Typically, they will mark the search areas on the map and then issue it for the teams. They then send out a QR code which you can scan into Avenza Maps, download the map and use it to do your navigation. I’ve used this on several searches and it is a great way to divide up an area for the individual teams.

Gaia GPS: I blogged on Gaia GPS last week. One of the good general GPS programs for phones.

Trailforks: Is a simpler navigation program than the full GPS apps and is really great for having all an area’s trails covered. New trails usually show up in Trailforks before anywhere else. Also many groups use Trailforks for reporting trail conditions, so a good place to check on these. I’ve often used this on searches to see all the mountain bike trails, which were missing from the official map I was following.

TrailMapps Sunshine Coast: Often there is a specialty app for your area, in this case a specialty Sunshine Coast trail app which I’ve found useful.

OsmAnd Maps: This is quite a good navigation tool. It is free and anyone is able to update the maps. I find this is good for things like hydro access roads and other obscure, but not official things that can be used as trails.

ViewRanger: is another full featured GPS program like Gaia. I liked it because the yearly subscription was cheaper, it was easier to use a variety of GPS coordinates and is easy on the phone’s battery when recording a track. It recently merged with outdooractive, so I’m not too sure what its future is now.

Strava: This is an app used by athletes and others to record their physical activities. This is useful for SAR, since if a subject uses Strava then you can get a clue as to where they like to go. Strava also can create a heatmap of where people record, and then search managers can use this when calculating Probability of Area (PoA).

The Strava Heatmap for the Gibsons Area

Utilities & Reference

Inclination: This app lets you use your phone to measure a slope’s inclination. This is useful when judging avalanche risk. It also is important to know when you need to use a safety line on a stretcher when the slope is greater than 20°.

BCSARA Mobile App: This app contains all our BCSARA reference material. It also has utilities to convert between GPS coordinates as well as providing a compass.

RADeMS: Response Assessment and Decision Making Support is our standard tool for evaluating risk. You answer a set of questions on what you are contemplating and get back a risk score to help with your decision making.

YouTube: If you are stuck on something, chances are YouTube has a video to walk you through it.

Phone Builtin Functions

Flashlight: the phone’s builtin flashlight can be useful if your other light sources have failed, but use this as a last resort since your battery is better served for other purposes.

Messenger: Your phone’s texting app is a great way to send in photos and other info to command if you have cell reception.

Camera: Make sure you take a picture of any clues.

EMail: Another low priority communication mechanism.

Compass: a quick way to see your direction and to copy your GPS coordinates to the clipboard (to paste into say messenger).

Maps: Often Apple or Google maps are best for urban searches.

Browser: If you are online, you can look up pretty much anything.

Clock: Set timers and alarms. Perhaps to remember to check in with command.

Phone (and Facetime): often best to phone command. Especially for confidential info when you don’t have a secure radio channel.

Summary

Modern cell phones are amazing devices and if there is some sort of use you can think of, chances are someone has already created an app for that. Most (but not all) of the apps mentioned here are free. I’m sure there are tons more useful apps and would love to hear about them in the comments below. However, you don’t want too many apps, as it’s better to have a smaller set of apps that you regularly use so you are familiar with them and don’t have to figure out something new when you are in the middle of a stressful SAR call.

For SAR make sure you can make do when you are offline. You don’t want to rely on having good cell coverage.

Written by smist08

March 12, 2021 at 11:05 am

Using Gaia for Search & Rescue

with 2 comments

Introduction

Gaia is a navigation program for Apple and Android smartphones. It mimics the functionality of standalone GPS units, but then adds functionality utilizing the extra capabilities most phones include these days. There are lots of articles and youtube videos on how to use Gaia for trip planning and following trails and I won’t cover that here. This article is more about the use cases that Search & Rescue (SAR) teams typically use in a GPS. This article assumes some familiarity with using a standalone GPS and SAR practices, and then very little knowledge of Gaia. I use an Apple iPhone 11, so this article will feature screenshots from the Apple version, but the Android version should be similar.

Installation & Setup

You need to install and set up Gaia first before using. You don’t want to do this part at 3am on a callout. First you need to install Gaia GPS from the Apple App store. Search for “Gaia GPS” and then press the “Get” button to install it.

My screen says Open rather than Get because I already have Gaia installed.

Notice the second item is a subscription for more stuff. The crucial part for SAR is offline access. With the free level, you cannot download maps to use the program when you don’t have a cell data connection. For SAR this is a showstopper. If a SAR group uses Gaia, it probably has a team license and SAR management can provide you with a link that will connect you to the SAR account.

Create Account

After you install Gaia, the first time you run it, you will be prompted to create an account or link to your Facebook account. Use either method to create your Gaia account. This will give you basic access to the program. If your SAR group provided a link to click to connect to their account, you can do that now to connect your Gaia account to the SAR account to get full access. If you don’t have this, then you will need to buy a premium subscription account.

Download Maps for Offline Use

The next thing to do is to download a map of your search region so you can use Gaia offline. The default map is Gaia Topo which is fine for most purposes. If you want to use a different map or set of overlays, you need to select these first before downloading as this process will only process the active map. To download the map, click the ⊕ symbol at the top of the screen.

Select “Download Maps”. This then goes to a map with a resizable rectangle that you can expand to your entire search region. In my case the Sunshine Coast:

You probably also want to do this for any regions you travel to for mutual aid, in my case I’ll download Powell River, Squamish, Whistler, Pemberton and the North Shore. I’m not going to talk about overlays in this article, but if you want these included, they must be selected and active before you choose to download. The file downloaded can be quite large so you need some space on your phone. I would recommend having 1Gig free for maps, which if you have a newer phone, shouldn’t be a big deal. Also perform the download while connected to a good Wifi connection so it is faster and you don’t use up your monthly data cap. If maps overlap, Gaia is reasonably smart and won’t download duplicate data so you don’t need to be careful in how you tile these (ie there is no penalty for overlapping maps).

Configure Units

Next go into “Settings”, the important part is that the units are correct for your purposes.

In SAR, you will probably need to return to this menu repeatedly. Often on a search we need both UTM and lat/long coordinates and have to return here to switch back and forth. If we are working with Marine SAR then we may want to use nautical distance units for that particular search. If we travel to the US for mutual aid, we may even need to use Imperial units.

Power Saving

You should also check the power options. I turn off the option to keep the screen on, as this wastes battery. I need to record tracks, but for the most part my phone lives in my pocket and I’m not looking at the screen.

Security

As you use Gaia, your phone is going to ask security questions, which you generally want to allow. A key one is you want to allow Gaia to always be able to access the GPS, if you choose the option to only access the GPS when using the app, then you are going to have holes in your GPS tracks when you switch to other apps, say to send a message or answer an email.

Basic Usage

Recording a Track

SAR Management always requires a recording of where you traveled so these can all be combined in a master map showing search coverage. The standard for providing these is a GPX file. There is an “Record” button in the upper left of the screen. Remember to hit this before heading out on your search. When recording it changes to a timer showing how long it’s been recording. When you return to command, tap this box again and choose “Finish Track”. It’s a good idea to give this track a meaningful name on the next screen. It will then show you the track. Tap the three dots in the upper right to get a menu:

Select export and then GPX. Next choose eMail and enter the email address of your SAR manager. Much easier than doing this with a standalone GPS.

If you want to include pictures with this file, then you need to save the track and all the pictures in the same folder. To do this create a new folder before starting out and then save everything for the day to this folder. This may or may not be helpful.

Getting my Position

Of course you can get your current position from the phone’s compass app, this is handy to copy to a text and send, but is in lat/long and not very easy to read out over a radio. In SAR we tend to use an abbreviated form of UTM coordinates, so we can give our location over our radio using six digits. You can configure Gaia to show your location by tapping one of the three info boxes at the top and choosing coordinates in one of them.

Then on the radio, I can give my position as 632733. In reality, our radios transmit our location back to command on a regular basis, so I haven’t had to do this on a real callout, but this was frequently requested during training exercises.

Setting a Waypoint

If you hit the ⊕ sign at the top of the screen, you have two ways to create a waypoint.

Scenario one is to enter a marker of where you found a clue or a point you want to make note of for some reason, in this case choose “Add Waypoint (My Location)” and then enter a meaningful title and description.

The other scenario is SAR Management radioing you and asking you to go to some point on the map. The easy way to do this is to hit plus, choose “Add Waypoint”, then the next screen defaults to your current coordinates, that you can edit to the coordinates you’ve been given. Next enter a description, then the waypoint will appear on the map and you can figure out how to get to it.

Once you create a waypoint, if you tap it, you can tap the info icon and open it, from here you can add notes, or even ask Gaia to guide you to the waypoint. You can also edit the waypoint if you need to move it or rename it.

Summary

This was a quick start to Gaia for SAR practitioners. Gaia is a large and sophisticated program, where we only touched on a few aspects of what it can do. The best way to learn a program is to use it and to experiment with it. You don’t want the first time you do something to be during a stressful search in the middle of the night. Gaia isn’t meant to completely replace standalone GPS’s, but a key to SAR success is redundancy so if one piece of equipment fails, you aren’t stuck. Often the cell program is easiest to use, since it has extra functionality like being able to email your track in to command.

Written by smist08

March 5, 2021 at 11:36 am

Posted in Uncategorized