Java Firmware Updater

INFO: This Processing sketch is no longer supported.

This is a cross-platform updater for the uMMC/uMP3/rMP3. You will need put the module into update mode, then use the following Processing sketch to send the firmware file to the module.

Requirements:

  • Download and install Processing for your platform (available for GNU/Linux, Mac OS X, and Windows).
  • Firmware for your module: downloads (you will have to “unzip” it).

Update Steps:

  1. Launch Processing.
  2. Load the following sketch (you can click on the file title to download the file, or you can copy and paste it).
  3. Connect module via USB to TTL converter (such as the SparkFun(tm) FTDI Basic Breakout - 5V [DEV-09115]).
  4. Ensure the module is in Update Mode.
  5. Make sure your serial port index matches where you’ve connected the module.
  6. Run the sketch, and select the firmware from where you downloaded and unzipped it.
  7. Progress should be shown in the Processing console (not in the blank square window).

I wrote this pretty quickly, taking some bits from other examples - so it’s not exactly bug free and it certainly isn’t pretty - but it does the job. If you’d like to improve it, by all means, go ahead, and post the changes here (it’s an open wiki).

If anyone has any suggestions and/or improvements, let me know.

RogueUpdater.pde


/* Rogue Robotics firmware "updater" for Processing           */
/* http://www.roguerobotics.com/                              */
/* Written by Brett Hagman                                    */
/* Version: 0004                                              */
/* Make sure you pick your serial port index number!          */
/* VERSION  DATE        NOTES                                 */
/* 0.0001               Initial coding                        */
/* 0.0002   02/07/2010  Moved serial port before file load    */
/*                      to skip serial port init time         */
/* 0003     02/17/2010  Small changes                         */
/* 0004     02/18/2010  Even speedier! Sending byte[] instead */
/*                      of individual chars                   */

import processing.serial.*;

int portIndex = 1;
Serial myPort;

void setup() {
  size(256, 256);  // Stage size
  fill(255);
  noLoop();
}

byte a2b(byte msn, byte lsn)
{
  String s = "";
  s += char(msn);
  s += char(lsn);
  return byte(unhex(s));
}

void draw()
{
  // Print a list of the serial ports, for debugging purposes:
  println(Serial.list());

  String portName = Serial.list()[portIndex];
  myPort = new Serial(this, portName, 9600);

  String loadPath = selectInput();  // Opens file chooser

  if (loadPath == null) {
    // If a file was not selected
    println("No file was selected...");
  } else {
    // If a file was selected, print path to file
    println(loadPath);
  }

  byte inbytes[] = loadBytes(loadPath);

  // now convert to binary
  byte[] buffer = new byte[inbytes.length/2];

  int j = 0;
  for (int i = 0; i < inbytes.length; i+=2, j++)
  {
    buffer[j] = a2b(inbytes[i], inbytes[i+1]);
  }

  print("File size: ");
  println(buffer.length);

  int index = 0;
  int frameSize = 0;
  byte receivedByte;
  byte retries = 0;
  
  for(index = 0; index < buffer.length; index += frameSize)
  {
    frameSize = (buffer[index] & 0xff) « 8;
    frameSize += (buffer[index + 1] & 0xff) + 2;

    myPort.clear();

    println("Transferring: " + index + "/" + buffer.length + " (" + int(100*index/buffer.length) + "%)");
    
    byte[] bytesToSend = new byte[frameSize];

    for (int i = 0; i < frameSize; i++)
    {
      bytesToSend[i] = buffer[index + i];
    }

    myPort.write(bytesToSend);

    int timeout = 0;
    // now get response
    while (myPort.available() <= 0)
    {
      delay(20);
      if (timeout++ >= 150)
      {
        println("Timeout waiting for response.  Update failed.");
        exit();
      }
    }

    receivedByte = byte(myPort.read());

    switch (receivedByte)
    {
      case 0x11:
        retries = 0;
        break;
      case 0x22:
      default:
        retries++;
        if (retries > 4)
        {
          println("CRC error. File damaged.");
          myPort.stop();
          exit();
        }
        else
        {
          index -= frameSize;
          println("Retry");
        }
        break;
    }
  }
  println("Done!");
  exit();
}