Skip to content

IOIO Developer Getting Started Guide

Ytai Ben-Tsvi edited this page May 31, 2023 · 11 revisions

IOIO Developer Getting Started Guide

Important note: This guide is intended for people who develop IOIO, not people who develop with IOIO. A user guide will soon be published too. However, one important point to stress is that IOIO users are not required to do any sort of embedded programming, nor are they required to set up a development environment for PIC. The mainstream usage of IOIO involves only Android programming and the entire functionality of the board is exposed via a Java API. If you're only interested in that sort of usage, until there's proper documentation, you might want to download the code and have a look at software/IOIOLib as well as at some sample apps (e.g. software/IOIOSimpleApp).

Important note 2: This guide is slightly outdated. It will eventually be fixed, but this is a lower priority than some of the other stuff that's going on. My apologies in advance...

Setting Up Your Environment

Hardware

You'll need:

  • A IOIO (dah!)
  • A programmer that can program PIC24FJxxxDAxxx. The cheapest one is probably a PICKit3 clone, like this one. You'll only need the programmer for flashing the bootloader or for line-by-line debugging. If you have a IOIO with the proper bootloader already installed, you can develop firmware and run it on the device without a programmer.
  • An Android device. You'll need Android 2.* if you want to be able to use the Android device as a programmer.

Software

Update: We recently moved all firmware projects to MPLAB-X, which is currently in Beta, but still much better than MPLAB 8, and most importantly, available for Linux, Mac and Windows.

You'll need the following software installed on your development machine:

What is the Bootloader?

The bootloader is a piece of firmware, running on the PIC24 microcontroller that is on the IOIO board. This firmware is always the first thing that runs when the IOIO is powered on. Roughly speaking, at power-up the bootloader will do the following:

  • Wait for Android device to connect and establish a USB connection (this step will fail if the Android's USB debugging is not enabled).
  • Establish an ADB connection.
  • Using ADB, search for an application called ioio.manager, authenticate it by comparing its cert public key against a known value (currently skipped).
  • Using ADB. figure out the data directory of the ioio.manager app (currently skipped and assumed to be /data/data/ioio.manager/files).
  • Using the ADB file access protocol ("sync:"), read a file called image.ioio in this directory. This file contains an application firmware in a special format discussed below.
  • Flash this image and run it.

Once the application firmware is executing, the bootloader is still responsible for providing it with some services, mostly ADB connections and Flash read/write.

Building the Bootloader

You can skip this step if you have a IOIO with a bootloader or already have the bootloader image. The bootloader project is in firmware/bootloader Depending on whether your using a V0.3/V0.4 board or a V1.0/V1.1/V1.2 board, you need to change the following project settings:

Note: The checked-in version matches the latest V1.2 boards. No need to change anything for those boards.

V0.3/V0.4

  • Under Configure > Select Device menu, choose PIC24FJ256DA206.
  • Make sure the project has a file called boot_p24FJ256DA206.gld in the "Linker Scripts" project folder.

V1.0/V1.1/V1.2 (white)

  • Under Configure > Select Device menu, choose PIC24FJ128DA106.
  • Make sure the project has a file called boot_p24FJ128DA106.gld in the "Linker Scripts" project folder.

Build the project in MPLAB to produce the bootloader image (a .hex file under firmware/bootloader/dist). There's a pre-processor macro called ENABLE_LOGGING which causes the bootloader to output debug messages on a 38400 UART pin. However, the bootloader link stage will fail for memory constraints, so the linker scripts need to be tweaked to allow more RAM for the bootloader.

Flashing the Bootloader

You can skip this step if your IOIO already has a bootloader and you don't care about modifying the bootloader. You can use PICKit3 using the standalone programming software (GUI or command line) or from within MPLAB IDE. Just select it from the "programmer" menu.

If you only have a PICKit2, you can hack it to support PIC24FJ128DA106 by backing up the PK2DeviceFile.dat file found on your PICKit2 installation directory and replacing it with this one. Note that the rest of the MCUs on this file might have gotten corrupt as result of the hack, so only use this device file for PIC24FJ128DA106 / PIC24FJ256DA206.

If you want to flash the bootloader and the application firmware as one hex file, you can build the application firmware as explained below. You can then merge both hex files into one by simply concatenating them (they are text files) after removing the last line ("EOF") from the first one. This is useful for distributing the entire firmware as one standalone image.

Connect the PICKit to the IOIO as follows:

V0.3/V0.4 boards:

Not all boards have a silk-screen, so hold the board with the top side (on with the components) facing you with the USB jack on the right.

  • PICKit3 pin 1> (Vpp) - IOIO pin 28 (one pin above the bottom-left corner).
  • PICKit3 pin 2 (Vdd) - IOIO 3.3V (the 2x3 pin block next to the USB jack)
  • PICKit3 pin 3 (Vss) - IOIO GND (the 4x1 pin block next to the USB jack + one pin above it)
  • PICKit3 pin 4 (PGD) - IOIO pin 35 (bottom row, 7th from the left. Exactly underneath the bottom corner of the PIC chip).
  • PICKit3 pin 5 (PGC) - IOIO pin 34 (bottom row, 6th from the left. One pin to the left of the previous one).
  • 5V to IOIO 5V (all 4 pins on the right edge) OR 7.5V-12V to IOIO Vin (the 3x1 pin block next to the voltage regulators)
  • (optional) 3.3V UART-RX to IOIO pin 2 (top row, 2nd from the right) will give some debug output. Set to 1 stop bit, 38400 baud.

V1.0 board:

  • PICKit3 pin 1> (Vpp) - IOIO pin 30
  • PICKit3 pin 2 (Vdd) - IOIO 3.3V
  • PICKit3 pin 3 (Vss) - IOIO GND
  • PICKit3 pin 4 (PGD) - IOIO pin 37
  • PICKit3 pin 5 (PGC) - IOIO pin 36
  • 5V to IOIO 5V OR 7.5V-12V to IOIO Vin
  • (optional) 3.3V UART-RX to IOIO pin 4 will give some debug output. Set to 1 stop bit, 38400 baud.

V1.1+ board:

  • PICKit3 pin 1> (Vpp) - IOIO mclr pin
  • PICKit3 pin 2 (Vdd) - IOIO 3.3V
  • PICKit3 pin 3 (Vss) - IOIO GND
  • PICKit3 pin 4 (PGD) - IOIO pin 36
  • PICKit3 pin 5 (PGC) - IOIO pin 35
  • 5V to IOIO 5V OR 7.5V-12V to IOIO Vin
  • (optional) 3.3V UART-RX to IOIO pin 32 will give some debug output. Set to 1 stop bit, 115200 baud.

For programming purposes only, you can skip connecting 5V/Vin, and power the PIC from the programmer (3.3V). This is done by enabling Project Properties > PICkit3 > Power > Power target circuit from PICkit3.

Building the App Firmware

The application firmware is in firmware/app_layer_v1. It exposes a protocol to the Android app, which enables controlling many of the PIC's functions in a simple way, over a simple TCP connection. On the Android side, there is a Java library called IOIOLib, which implements the other side of this protocol and provides the client with a very simple and high level API for controlling IOIO. The application layer sits on top of an API provided by the bootloader, called BLAPI. This API is in firmware/blapi. In this directory there's also linker scripts that any IOIO app should be linked with. They enforce the bootloader ABI, i.e. RAM/ROM locations bootloader symbol addresses, etc. Open the firmware/app_layer_v1 project in MPLAB and build it. The resulting hex file (under dist directory) now contains the application executable. There are two ways of getting it to run on the IOIO. The short way (which requires a programmer) is to use a programmer and Flash it normally. It is possible to merge the bootloader hex with the application hex by removing the last line from one of them and concatenating (this is just a simple textual format). The long way, which does not involve a programmer and facilitates the bootloader is detailed below.

Converting a Firmware Hex File to IOIO Format

A simple utility is provided in tools/hex2ioio. It gets two arguments, one is an input hex file (of an application firmware), the other is the result filename (conventionally, with a .ioio suffix). The .ioio file contains the exact same information as the hex file, but it is more compact and much simpler to process by the bootloader.

making *.ioioapp files for flashing

./tools/make-ioio-bundle firmware/latency_tester/dist lat IOIO0023 will create a lat.zip file that if you rename it to lat.ioioapp file then the IOIOManager will know how to use it after pushing it to the sdcard. Note: you may need to build the bootloader with -DBYPASS_SECURITY when using a IOIOManager you built instead of downloading from the Marketplace because the keys will not match.

Bluetooth Programmer

This is a very simple Android app for developers. What it does is listen on a Bluetooth serial socket. When data comes in, it stores it in a file called image.ioio in the exact location the bootloader looks at. Effectively, this allows the Android device to function as a wireless firmware programmer. The app is only available for Android 2.*, since this is when they introduced Bluetooth API. The application code and Eclipse project is under software/IOIOManagerBT. Build it and install it on your Android device. When you run the application, all it does is launch a service that will be indicated by a IOIO+BT notification icon. To stop, expand the notification drawer and click the icon. In order to work with the BT programmer, you first need to pair your Android device to your workstation and map the "IOIO Programmer " Bluetooth service to a serial port. This process is slightly painful on Linux and requires manually messing around with the rfcomm service. If anyone knows how to automate this process, let us know. Then, whenever you want to copy a new firmware to the Android device, just open a connection on this port, send the bytes and close the connection. A pop-up message should appear on the Android device, confirming reception of the new image. On Linux (or Cygwin), this is very conveniently done by issuing a command similar to this one: cp myimage.ioio /dev/ttyS21 Where the actual serial port mapped should replace /dev/ttyS21

Final Check

If all is well, you can now reset the IOIO and connect it to the Android device. Make sure the Android has USB debugging switched on. The LED turns on shortly when the bootloader is connecting. Then, the application starts running.

If this works - congratulations - you've completed the entire cycle and are now ready to develop your own firmware or application!

Developing Android Applications

Under the software directory you will find IOIOLib, which is the library you should work with in order to use IOIO. The public APIs are all documented. There are some sample applications under the software directory that can be used as usage examples.

SW overview