Tips and info on programming a firmware for Ansible

#1

Hey!

Being a programmer by trade (javascript mainly) I was wondering if you guys that have done it already could give me some direction as where to start if I wanted to write a custom firmware for Ansible?

I’ve been looking for a solution to emulate the mlr app with the er-301 and Ansible but doesn’t look like it is entirely possible without modifying the software, so I’m not afraid of coding and willing to learn C but need some guidance as to where to go when you start from scratch.

Cheers!

1 Like

#2

Here is the response I gave someone else privately in regards to the same question…

I’m not sure there is a comprehensive tutorial but there may be a thread or two on lines from last year which talk about it. The readme file in the libavr32 repository provides some details https://github.com/monome/libavr32/blob/master/README.md

All the monome modules are fairly similar hardware wise so you can move code between them w/o too much difficulty. I mention this because your ansible probably already has the UART header and reset switch installed. The older trilogy modules and teletype most likely don’t. If you want to work with one of the older modules you’ll want/need to solder on the UART header at a minimum:

The UART header part details are here:

…once you have that it looks like this installed on an earthsea (it is the 6-pin header on the right):

The serial adaptor I’ve been using is this one: https://www.sparkfun.com/products/9716. I didn’t have to install any drivers for it, it just shows up as a serial device (under macOS).

To connect to the serial adaptor I use the super basic cu command (which should work on linux as well) specifically:

sudo cu -l /dev/tty.usbserial-mod -s 115200

The device name part(tty.usbserial-mod) might differ depending on the adaptor but it will start with tty.usbserial-. You can read the man page for cu for more details if you’d like. Once connected you will at a minimum see the module name printed out when it is power cycled… depending on the build there may be other stuff printed (just look for calles to print_dbg() in the code).

5 Likes

#3

…once you have the development environment up and running and can rebuild the existing firmware from source and re-flash your module then you are good to go - beyond that I recommend just reading the source code and trying to piece together how things work.

One area of the code which may unlock things is noting that at the end of main() there is an infinite loop which processes events. Trace what happens to the events and you are well on your way.

3 Likes

#4

Thanks @ngwese ! So if I understand well the only means of debugging would be to attach a screen to the UART header on the rear via an FTDI cable. Is that right?

0 Likes

#5

Basically yes. I don’t believe the current hardware exposes JTAG headers or equivalent needed to support hardware level debugging (with something like GDB).

To the best of my knowledge the ansible hardware ships with the UART header and reset switch already installed.

0 Likes

#6

Ok and would there be a faster/automated way of uploading the firmware to the module? or do we have to follow the steps: turn module off, turn module on holding preset button etc… because that seems to me to be an awful dev cycle tbh! thanks!

0 Likes

#7

Yes - that is the dev cycle. You can (sort of) skip the power cycle if you have a module with the reset button installed.

  • hold preset button + reset to enter firmware upload mode
  • …do the upload…
  • hit the reset button to restart the module with the USB stack back in the right mode

When I’m working on stuff I move the module (or modules) to a separate rack/case so that I have easy access to the reset button and UART headers. Overall I haven’t found the development cycle to be that bad, if anything it has taught me to slow down and think carefully about what I’m doing because the testing cycle is more involved.

Depending on what you are trying you might consider how you might keep the hardware dependent part of the code separate from the pure library code. Keeping them separate allows for unit testing the code on your development host instead of the hardware (within reason). There are examples of this in libavr32 and teletype

My dev case…

4 Likes