1. Blog>
  2. Build and Flash Rust+Mynewt Firmware for PineTime Smart Watch

Build and Flash Rust+Mynewt Firmware for PineTime Smart Watch

by: Oct 20,2020 4845 Views 0 Comments Posted in Technology

raspberry pi Internet of Things Rust Nrf52 Pinetime

All you need is a Raspberry Pi and a Windows or macOS computer!

UPDATE: This code in this article has been archived in the pre-lvgl branch of pinetime-rust-mynewt. The pinetime-rust-mynewt firmware has been revamped to support Rust Watch Faces on LVGL. Check out the updates

Welcome to the World of Modern IoT Gadgets! If you’re used to old-school IoT gadgets like Arduino Uno that are underpowered and have no networking and display… PineTime Smart Watch will surprise you! (Check out the Pine64 Store)

Raspberry Pi connected to PineTime

PineTime is powered by a Nordic nRF52 Microcontroller with an Arm Cortex-M4F CPU… The same microcontroller found in a high-end gaming mouse!

With built-in colour touchscreen and Bluetooth networking, embedded programming on PineTime becomes really fun and exciting.

Raspberry Pi used for flashing the PineTime firmware

PineTime is a prime example of a real-world, off-the-shelf gadget that’s powerful and yet affordable, because it’s manufactured in huge quantities. But they can be intimidating to newbies who have not programmed such commercial devices.

Today I’ll show you that programming a PineTime is not that hard… All you need is a Raspberry Pi, some wires and a little creativity!

Another view of the improvised Raspberry Pi connection to PineTime

Connect PineTime to Raspberry Pi

Note: This section is obsolete. Please refer to the updated instructions here: “Connect PineTime to Raspberry Pi

lupyuen/ visual-embedded-rust

…Then proceed to the next section

Carefully pry open the PineTime casing. Use tweezers to pivot the shiny battery gently to the side. Be careful not to break the red and black wires that connect the battery to the watch!

Be careful not to break the red and black wires (lower left) that connect the battery to the watch

Just above the battery we see 4 shiny rings. This is the Serial Wire Debug (SWD) Port for PineTime. We’ll use this port to flash our firmware to PineTime. The 4 pins (from left to right) are SWDIO (Data I/O), SWDCLK (Clock), 3.3V, GND.

What is “flash memory” / “flashing” / “firmware”? Read this

SWD Port at top left: SWDIO, SWDCLK, 3.3V and GND. 5V battery charging pad at lower right. Bent antenna wire is at top centre.

In the above photo, the pins from left to right are…

1.SWDIO (Yellow)

2.SWDCLK (Blue)

3.3.3V (Red)

4.GND (Black)

The exposed copper wire at the top centre of the photo is the Bluetooth antenna. Bend it upwards so that it doesn’t come into contact with anything.

Bending the Bluetooth Antenna so that it doesn’t touch anything

At lower right we see a pad marked 5V. We’ll connect this pad to Raspberry Pi to charge the battery. If charging of the battery is not needed during development, we may leave5V disconnected.

Connect the SWD Port and the 5V Pad (optional) to the Raspberry Pi with Solid-Core Wire (22 AWG) and Female-To-Female Jumper Cables

Some have reported that the SIM Ejector Tool from our phones will also fit perfectly into PineTime’s SWD holes. (Or file the pin down until it fits)

We may use Raspberry Pi Zero, 1, 2, 3 or 4 . The pins on Raspberry Pi to be connected are…

Connecting Raspberry Pi’s SPI port to PineTime. Based on https://pinout.xyz/

Raspberry Pi’s SPI port connected to PineTime. 5V may be disconnected if battery charging is not needed.

 The PineTime touchscreen needs to be accessible during development, so I mounted PineTime on a $2 clear box cover from Daiso with Blu Tack and sticky tape.

PineTime and Raspberry Pi mounted on a clear box cover

Be Creative! And send me photos of your PineTime setup…

UPDATE: Check this Reddit Thread for a super-cool Raspberry Pi Zero setup!

Here’s a tip: Colour the Raspberry Pi pins with a marker (one side only) so that we remember which pin to use

Why didn’t I use the SWD cable that was shipped with PineTime? Because the wires were too thin and may lose contact with the SWD connector. Compare that with the Solid Core 22 AWG wire (green), which fits nicely. Also note that the SWD cable is shipped with random colours.

Remove PineTime Flash Protection

Note: This section is obsolete. Please refer to the updated instructions here: “Remove PineTime Flash Protection

lupyuen/ visual-embedded-rust

…Then proceed to the next section

PineTime is shipped with preloaded demo firmware. We need to erase the demo firmware and unprotect PineTime’s flash memory so that we may flash our own firmware.

What is “flash protection”? Read this

Power on the Raspberry Pi. Open a command prompt and enter the following…

sudo raspi-config

Select Interfacing Options → SPI → Yes

Select Finish

At the command prompt, enter the following…

# Remove folders ~/pinetime-rust-mynewt and ~/openocd-spi (if they exist)
rm -rf ~/pinetime-rust-mynewt
rm -rf ~/openocd-spi

# Download and extract "pinetime-rust-mynewt" folder containing our prebuilt firmware, source files and flashing scripts
sudo apt install -y wget p7zip-full
cd ~
wget https://github.com/lupyuen/pinetime-rust-mynewt/releases/download/v2.0.5/pinetime-rust-mynewt.7z
7z x pinetime-rust-mynewt.7z
rm pinetime-rust-mynewt.7z

# Install build tools for PineTime: VSCode, Rust, gcc, gdb, openocd-spi, newt
cd ~/pinetime-rust-mynewt
scripts/install-pi.sh

# Latest nightly-2020-04-20 fails with asm error, so we use nightly-2020-02-16
source $HOME/.cargo/env
rustup default nightly-2020-02-16
rustup update
rustup target add thumbv7em-none-eabihf

At the Welcome to Rust! prompt, press Enter to select the default option:

1) Proceed with installation (default)

If you see this error…

Cloning into 'openocd-spi/jimtcl'...
fatal: unable to access 'http://repo.or.cz/r/jimtcl.git/': Recv failure: Connection reset by peer
fatal: clone of 'http://repo.or.cz/r/jimtcl.git' into submodule path '/private/tmp/aa/openocd-spi/jimtcl' failed

It means that the sub-repository for one of the dependencies jimtcl is temporarily down. You may download the pre-built openocd-spi binaries from this link. Then copy the executable openocd-spi/src/openocd to pinetime-rust-mynewt/openocd/bin/openocd

When the installation has completed, enter the following at the command prompt…

# Remove flash protection from PineTime and erase demo firmware
cd ~/pinetime-rust-mynewt
scripts/nrf52-pi/flash-unprotect.sh

We should see Shut Down And Power Off Your Raspberry Pi

If we see Clock Speed and nothing else after that…

Info : BCM2835 SPI SWD driver

Info : SWD only mode enabled

Info : clock speed 31200 kHz

Info : SWD DPIDR 0x2ba01477

Then the connection to the SWD Port is probably loose, please check the pins.

If we don’t see this DPIDR number, or if we see a different DPIDR number...

SWD DPIDR 0x2ba01477

Then the connection to the SWD Port is most likely loose, please check the pins.

Also enter sudo raspi-config and confirm that the SPI port has been enabled.

If we see this instead…

openocd/bin/openocd: cannot execute binary file: Exec format error

Then install-pi.sh probably didn’t run correctly. To fix this, copy the openocd executable like this…

cp $HOME/openocd-spi/src/openocd $HOME/pinetime-rust-mynewt/openocd/bin/openocd

Shut down and power off your Raspberry Pi. Wait 30 seconds for the red and green LEDs on your Pi to turn off. Power on your Pi. Enter the same commands at a command prompt…

# Remove flash protection from PineTime and erase demo firmware
cd ~/pinetime-rust-mynewt
scripts/nrf52-pi/flash-unprotect.sh

We should see Flash Is Already Unprotected

PineTime’s demo firmware has been erased and the flash protection has been removed.

What is OpenOCD? Why Raspberry Pi and not ROCK64 or Nvidia Jetson Nano? Read this


Flash Bootloader and Application to PineTime

We’re now ready to flash our own firmware to PineTime! We’ll be flashing the PineTime firmware that’s based on open-source Apache Mynewt embedded operating system. Mynewt OS contains two components that we shall flash to PineTime…

Mynewt Bootloader: This is the C code that’s run whenever we power on PineTime. The Bootloader executes the Mynewt Application upon startup.

Mynewt Application: Contains a Rust application that controls the PineTime functions, and low-level system functions written in C.

The Bootloader and Application firmware image files may be found at these locations…

lupyuen/ pinetime-rust-mynewt

What is a Bootloader? Read this

To flash Mynewt Bootloader to PineTime, enter the following at the command prompt…

# Flash Mynewt Bootloader to PineTime
cd ~/pinetime-rust-mynewt
scripts/nrf52-pi/flash-boot.sh

Commands to flash Mynewt Bootloader to PineTime

We should see Done

pi@raspberrypi:~/pinetime-rust-mynewt $ scripts/nrf52-pi/flash-boot.sh 
+ openocd/bin/openocd -f scripts/nrf52-pi/swd-pi.ocd -f scripts/nrf52/flash-boot.ocd
Open On-Chip Debugger 0.10.0+dev-01126-g307e591f (2020-01-20-21:33)
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
Info : only one transport option; autoselect 'swd'
force hard breakpoints
Info : BCM2835 SPI SWD driver
Info : SWD only mode enabled
Info : clock speed 31200 kHz
Info : SWD DPIDR 0x2ba01477
Info : nrf52.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : Listening on port 3333 for gdb connections
Stopping...
target halted due to debug-request, current mode: Thread 
xPSR: 0x61000000 pc: 0x000001ca msp: 0x2000ffe8

Flashing Bootloader...
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x000000d8 msp: 0x20010000
Enabled ARM Semihosting to show debug output
** Programming Started **
Info : nRF52832-QFAA(build code: E1) 512kB Flash, 64kB RAM
Warn : Adding extra erase range, 0x00000b78 .. 0x00000fff
** Programming Finished **
** Verify Started **
** Verified OK **

Restarting...
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x000000d8 msp: 0x20010000, semihosting

**** Done!

Log of Mynewt Bootloader flashing. From https://github.com/lupyuen/pinetime-rust-mynewt/blob/master/logs/load-bootloader-pi.log

To flash Mynewt Application to PineTime, enter the following at the command prompt…

# Flash Rust+Mynewt Application to PineTime
cd ~/pinetime-rust-mynewt
scripts/nrf52-pi/flash-app.sh

Commands to flash Mynewt Application to PineTime

We should see Done! Press Ctrl-C To Exit

pi@raspberrypi:~/pinetime-rust-mynewt $ scripts/nrf52-pi/flash-app.sh 
+ openocd/bin/openocd -f scripts/nrf52-pi/swd-pi.ocd -f scripts/nrf52/flash-app.ocd
Open On-Chip Debugger 0.10.0+dev-01126-g307e591f (2020-01-20-21:33)
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
Info : only one transport option; autoselect 'swd'
force hard breakpoints
Info : BCM2835 SPI SWD driver
Info : SWD only mode enabled
Info : clock speed 31200 kHz
Info : SWD DPIDR 0x2ba01477
Info : nrf52.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : Listening on port 3333 for gdb connections
Stopping...
target halted due to debug-request, current mode: Thread 
xPSR: 0x61000000 pc: 0x000081ee msp: 0x2000ffd8

Flashing Application...
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x000000d8 msp: 0x20010000
Enabled ARM Semihosting to show debug output
** Programming Started **
Info : nRF52832-QFAA(build code: E1) 512kB Flash, 64kB RAM
Warn : Adding extra erase range, 0x0003e820 .. 0x0003efff
** Programming Finished **
** Verify Started **
** Verified OK **

Restarting...
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x000000d8 msp: 0x20010000, semihosting
Enabled ARM Semihosting to show debug output

**** Done! Press Ctrl-C to exit...

Log of Mynewt Application flashing. From https://github.com/lupyuen/pinetime-rust-mynewt/blob/master/logs/load-application-pi.log

The new PineTime firmware runs after the flashing has been completed. Here are the debugging messages produced by our Rust application…

Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
TMP create temp_stub_0
NET hwid 4a f8 cf 95 6a be c1 f6 89 ba 12 1a 
NET standalone node 
Rust test display

Log of Mynewt Application executing. From https://github.com/lupyuen/pinetime-rust-mynewt/blob/master/logs/load-application-pi.log

And we should see on the PineTime screen…

Our Rust Application rendering graphics and text to the PineTime display

Press Ctrl-C to stop the display of debugging messages.

We have flashed a simple Rust application located at pinetime-rust-mynewt/rust/app/src/display.rs that renders some graphics and text to the PineTime display…

/// Render some graphics and text to the PineTime display. `start_display()` must have been called earlier.
pub fn test_display() -> MynewtResult<()> {
  console::print("Rust test display\n"); console::flush();
   
  // Create black background
  let background = Rectangle::<Rgb565>
    ::new( Coord::new( 0, 0 ), Coord::new( 239, 239 ) )  // Rectangle coordinates
    .fill( Some( Rgb565::from(( 0x00, 0x00, 0x00 )) ) ); // Black

  // Create circle
  let circle = Circle::<Rgb565>
    ::new( Coord::new( 40, 40 ), 40 )           // Circle centre and radius
    .fill( Some( Rgb565::from(( 0xff, 0x00, 0xff )) ) ); // Magenta

  // Create square
  let square = Rectangle::<Rgb565>
    ::new( Coord::new( 60, 60 ), Coord::new( 150, 150 ) ) // Square coordinates
    .fill( Some( Rgb565::from(( 0x00, 0x00, 0xff )) ) ); // Blue

  // Create text
  let text = fonts::Font12x16::<Rgb565>
    ::render_str("I AM PINETIME")             // Text to be rendered
    .stroke( Some( Rgb565::from(( 0x00, 0x00, 0x00 )) ) ) // Black text
    .fill(  Some( Rgb565::from(( 0xff, 0xff, 0x00 )) ) ) // Yellow background
    .translate( Coord::new( 20, 16 ));           // Shift the text

  // Render background, circle, square and text to display
  druid::draw_to_display(background);
  druid::draw_to_display(circle);
  druid::draw_to_display(square);
  druid::draw_to_display(text);   

  // Return success to the caller
  Ok(())
}

Our Rust application that renders graphics and text. From https://github.com/lupyuen/pinetime-rust-mynewt/blob/master/rust/app/src/display.rs

Here’s a good introduction to Rust programming and here’s a good overview of Rust

The Rust application references the Rust library (crate) named [embedded_graphics]. That’s where Rectangle, Circle, fonts, … are defined.

How do we modify this Rust application and rebuild the firmware? We have 3 options:

[Option 1] Build the firmware on a Windows computer, and copy to Pi for flashing

[Option 2] Build the firmware on a macOS computer, and copy to Pi for flashing

[Option 3] Build the firmware on a (powerful) Raspberry Pi (or PineBook Pro) and flash directly


[Option 1] Install PineTime Build Tools on Windows

(If you’re building firmware on macOS, skip to the next section. If you’re building firmware on Raspberry Pi, skip to the section “[Option 3] Install Build Tools on Raspberry Pi”)

To build your own firmware on a Windows computer, follow these instructions to install the build tools for Rust and Mynewt OS on Windows…

1.Download the pinetime-rust-mynewt.7z file attached below…github.com/lupyuen/pinetime-rust-mynewt/releases/tag/v2.0.4

Expand the .7z file with 7zip…

www.7-zip.org/download.html

2.Click here to install Build Tools For Visual Studio 2019:

visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2019

Build Tools For Visual Studio 2019

Click the Individual Components tab

Select the following components:

1.Windows 10 SDK (10.0.18362.0)

2.C++ CMake Tools for Windows

(This should be automatically selected) MSVC v142 — VS 2019 C++ x64/x86 Build Tools

Install rustup according to the instructions here:

rustup.rs

Click the link provided to download rustup?init.exe

Launch the downloaded file rustup?init.exe

If you see the message “Windows Defender SmartScreen prevented an unrecognised app from starting”…

Click More Info

Click Run Anyway

At the Welcome to Rust! prompt, press Enter to select the default option:

1) Proceed with installation (default)

Open the Command Prompt and enter…

# Install Rust build tools for Arm Cortex

rustup default nightly

rustup update

rustup target add thumbv7em-none-eabihf

Install GNU Arm Embedded Toolchain for Windows from Arm Developer Website…

gcc-arm-none-eabi-8-2019-q3-update-win32-sha1.exe

Select this option at the last install step:

"Add path to environment variable"

Install VSCode…

code.visualstudio.com

What is VSCode? Is it related to Visual Studio? How is Microsoft involved? Read this


[Option 2] Install PineTime Build Tools on macOS

(If you’re building firmware on Windows, skip to the section “Build PineTime Firmware”)

To build your own firmware on a macOS computer, follow these instructions to install the build tools for Rust and Mynewt OS on macOS…

Download the pinetime-rust-mynewt.7z file attached below…github.com/lupyuen/pinetime-rust-mynewt/releases/tag/v2.0.5

Expand the .7z file with Keka…

www.keka.io/en/

Install rustup according to the instructions here:

rustup.rs

At the Welcome to Rust! prompt, press Enter to select the default option:

1) Proceed with installation (default)

Open the Command Prompt and enter…

# Install Rust build tools for Arm Cortex
source $HOME/.cargo/env
rustup default nightly
rustup update
rustup target add thumbv7em-none-eabihf
# Install Go and newt (build tool for Mynewt OS)
cd pinetime-rust-mynewt
scripts/install-mac.sh

In case of problems, compare with this installation log

Install GNU Arm Embedded Toolchain for macOS from Arm Developer Website…

gcc-arm-none-eabi-8-2019-q3-update-mac.tar.bz2

Expand the .tar.bz2 compressed file with Keka.

Add the uncompressed bin folder to your PATH environment variable in your ~/.profile and ~/.bashrc files, like this:

export PATH=”/Users/MYUSERNAME/gcc-arm-none-eabi-8–2019-q3-update/bin:$PATH”

Install VSCode…

code.visualstudio.com

What is VSCode? Is it related to Visual Studio? How is Microsoft involved? Read this


[Option 3] Install PineTime Build Tools on Raspberry Pi

(If you’re building firmware on Windows or macOS, skip this section)

The PineTime Build Tools are already installed on our Raspberry Pi when we executed install-pi.sh earlier.

Launching VSCode on Raspberry Pi

Launch VSCode by clicking the Raspberry Pi Menu (top left corner) → Programming → Code OSS Headmelted

What is VSCode? Is it related to Visual Studio? How is Microsoft involved? Read this


Building PineTime Firmware on Raspberry Pi 4 with VSCode. Displayed on Xiaomi 65-inch 4K TV.

If you’re building firmware on PineBook Pro…

To install the build tools on PineBook Pro, check these instructions


Build PineTime Firmware on Windows, macOS and Raspberry Pi

We’re all set to build our own PineTime Firmware with VSCode!

Launch VSCode. Click File → Open Folder

Select the downloaded folder pinetime-rust-mynewt

When prompted to open the workspace, click Open Workspace

When prompted to install Extension Recommendations, click Install All

Edit the Rust demo application located at pinetime-rust-mynewt/rust/app/src/display.rs

Change I AM PINETIME to your own message.

Editing the Rust demo application with VSCode

Click Terminal → Run Task → [2] Build Application

This builds the Mynewt Application, which includes our Rust application.

Build Mynewt Application Log

If you see the message Undefined reference to main, rebuild the application by clicking Terminal → Run Task → [2] Build Application

In case of problems, compare with this build log

Click Terminal → Run Task → [3] Image Application

This creates the Firmware Image File for our Mynewt Application. The file is located at pinetime-rust-mynewt/bin/targets/nrf52_my_sensor/app/apps/my_sensor_app/my_sensor_app.img

Image Mynewt Application Log

In case of problems, compare with this image log

Building PineTime Firmware on Windows with VSCode


Flash New PineTime Firmware

Finally let’s flash our new firmware to PineTime!

If you used a Windows or macOS computer to build the firmware…

Copy the application firmware image my_sensor_app.img from

pinetime-rust-mynewt/bin/targets/nrf52_my_sensor/app/apps/my_sensor_app

on your Windows/macOS computer to the same folder on your Raspberry Pi.

I used Cyberduck to copy the file to Raspberry Pi. This step is not needed if you used a Pi to build the firmware.

Location of the Mynewt Application Firmware Image my_sensor_app.img

On our Raspberry Pi, enter the following at the command prompt…

# Flash Rust+Mynewt Application to PineTime
cd ~/pinetime-rust-mynewt
scripts/nrf52-pi/flash-app.sh

Commands to flash Mynewt Application to PineTime

We should see…

pi@raspberrypi:~/pinetime-rust-mynewt $ scripts/nrf52-pi/flash-app.sh 
+ openocd/bin/openocd -f scripts/nrf52-pi/swd-pi.ocd -f scripts/nrf52/flash-app.ocd
Open On-Chip Debugger 0.10.0+dev-01126-g307e591f (2020-01-20-21:33)
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
Info : only one transport option; autoselect 'swd'
force hard breakpoints
Info : BCM2835 SPI SWD driver
Info : SWD only mode enabled
Info : clock speed 31200 kHz
Info : SWD DPIDR 0x2ba01477
Info : nrf52.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : Listening on port 3333 for gdb connections
Stopping...
target halted due to debug-request, current mode: Thread 
xPSR: 0x61000000 pc: 0x000081ee msp: 0x2000ffd8

Flashing Application...
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x000000d8 msp: 0x20010000
Enabled ARM Semihosting to show debug output
** Programming Started **
Info : nRF52832-QFAA(build code: E1) 512kB Flash, 64kB RAM
Warn : Adding extra erase range, 0x0003e820 .. 0x0003efff
** Programming Finished **
** Verify Started **
** Verified OK **

Restarting...
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x000000d8 msp: 0x20010000, semihosting
Enabled ARM Semihosting to show debug output

**** Done! Press Ctrl-C to exit...

Log of Mynewt Application flashing. From https://github.com/lupyuen/pinetime-rust-mynewt/blob/master/logs/load-application-pi.log

Our modified firmware is now running on PineTime! Press Ctrl-C to exit.

Explore the Rust code here to understand how the features were implemented in PineTime

If you prefer to build PineTime firmware and create the firmware image via the command line, here are the commands…

For Windows…

:: Build Rust+Mynewt Application and create Application Firmware Image for PineTime
cd pinetime-rust-mynewt
scripts\build-app.cmd
scripts\nrf52\image-app.cmd

Build firmware and create firmware image on Windows

For macOS and Raspberry Pi…

# Build Rust+Mynewt Application and create Application Firmware Image for PineTime
cd ~/pinetime-rust-mynewt
scripts/build-app.sh
scripts/nrf52/image-app.sh

Build firmware and create firmware image on macOS and Raspberry Pi

If you see the error message Undefined reference to main, run build-app.cmd or build-app.sh again and it should be fixed.


Debug PineTime Firmware with Raspberry Pi

With only a Raspberry Pi, we may debug the firmware on PineTime: Step into the program line by line, set a breakpoint to pause execution, inspect variables at runtime, …

Check the article “Debug Rust+Mynewt Firmware for PineTime on Raspberry Pi” for details

Debugging PineTime Firmware with Raspberry Pi


Advanced Topic: Build druid UI Firmware for PineTime

Our demo application can render graphics but it’s not interactive like a real watch app… Watch apps should respond to our touch! Like this…

This Rust demo application that responds to touch was programmed with the druid UI framework like this…

pub fn launch() {
  console::print("Rust launch\n"); console::flush();
  // Build a new window
  let main_window = WindowDesc::new(ui_builder);
  // Application state is initially 0
  let data = 0_u32;
  // Launch the window with the initial application state
  AppLauncher::with_window(main_window)
    .use_simple_logger()
    .launch(data)
    .expect("launch failed");
}

/// Build the UI for the window. The application state consists of 1 value: `count` of type `u32`.
fn ui_builder() -> impl Widget<u32> { // `u32` is the application state
  console::print("Rust UI builder\n"); console::flush();
  // Create a line of text based on a counter value
  let text =
    LocalizedString::new("hello-counter")
    .with_arg(
      "count", 
      // Closure that will fetch the counter value...
      | data: &u32, _env | // Closure will receive the application state and environment
        (*data).into()  // We return the counter value in the application state
    );
  // Create a label widget to display the text
  let label = Label::new(text);
  // Create a button widget to increment the counter
  let button = Button::new(
    "increment"// Text to be shown
    // Closure that will be called when button is tapped...
    | _ctx, data, _env | // Closure will receive the context, application state and environment
      *data += 1    // We increment the counter
  );

  // Create a column for the UI
  let mut col = Column::new();
  // Add the label widget to the column, centered with padding
  col.add_child(
    Align::centered(
      Padding::new(5.0, label)
    ),
    1.0
  );
  // Add the button widget to the column, with padding
  col.add_child(
    Padding::new(5.0, button), 
    1.0
  );
  // Return the column containing the label and button widgets
  col
}

druid UI application. From https://github.com/lupyuen/pinetime-rust-mynewt/blob/master/rust/app/src/ui.rs

There’s a lot happening in this short piece of code… Check this article for the details.

To build this druid UI app instead of the previous graphics display app, open VSCode on your Windows or macOS computer. Edit the Rust application configuration file pinetime-rust-mynewt/rust/app/Cargo.toml

Edit the file such that display_app is commented out, and ui_app is uncommented…

# Optional features
[features]
default = [     # Select the conditional compiled features
  # "display_app"# Disable graphics display app
  "ui_app",     # Enable druid UI app
  # "use_float",  # Disable floating-point support e.g. GPS geolocation
]

From https://github.com/lupyuen/pinetime-rust-mynewt/blob/master/rust/app/Cargo.toml

Repeat the instructions above to build the PineTime firmware on your computer, then flash the firmware from Raspberry Pi to PineTime. And now you’ll have an interactive watch app on your PineTime!

If you wish to flash the druid UI firmware without rebuilding…

Download to your Raspberry Pi the pinetime-rust-mynewt.7z file attached below…

github.com/lupyuen/pinetime-rust-mynewt/releases/tag/v1.0.1

Then flash the application firmware image my_sensor_app.img located at

pinetime-rust-mynewt/bin/targets/nrf52_my_sensor/app/apps/my_sensor_app

In the video above, some touches don’t seem to update the counter. If you have any ideas why, lemme know! Here’s the touchscreen driver in Rust. This article explains how it works.

Rust druid app with touchable button running on PineTime

Here’s a video of PineTime connected to a Raspberry Pi 4 that’s building the druid app with VSCode…

Building druid app for PineTime with VSCode on RaspberryPi 4. Uses the “Task Runner” extension: https://marketplace.visualstudio.com/items?itemName=SanaAjani.taskrunnercode&ssr=false


Advanced Topic: Flash and Debug PineTime with ST-Link

If we’re doing serious development with PineTime, I recommend getting an ST-Link v2 USB dongle ($2) that connects PineTime directly to our Windows, macOS or Linux computer.

ST-Link allows us to flash PineTime directly from our computer, and it even supports firmware debugging (setting breakpoints, checking values of variables at runtime, …)

Here’s how we connect PineTime to ST-Link…

PineTime connected to ST-Link

Connecting PineTime to ST-Link

Instructions for flashing and debugging may be found in the article “Install Apache Mynewt and Embedded Rust for nRF52 and Visual Studio Code on Windows and macOS” under the sections “Flash The Firmware” and “Run The Program”.

Also check this article that explains the VSCode Debugger configuration files: “Debug RIOT-OS on PineTime with VSCode

Proposed plan to unbundle Watch Apps from PineTime firmware

Read the Original Article


Note: The content and the pictures in this article are contributed by the author. The opinions expressed by contributors are their own and not those of PCBWay. If there is any infringement of content or pictures, please contact our editor (zoey@pcbway.com) for deleting.


Written by

Join us
Wanna be a dedicated PCBWay writer? We definately look forward to having you with us.
  • Comments(0)
Upload photo
You can only upload 5 files in total. Each file cannot exceed 2MB. Supports JPG, JPEG, GIF, PNG, BMP
0 / 10000
    Back to top