Maple-Arduino Compatibility

Overview

The biggest difference between the Maple and most Arduino boards is that the Maple uses a 32-bit ARM Cortex-M3 architecture chip, while the Arduinos have 8-bit Atmel AVR chips. The different instruction set means that machine code (which makes up executable binary program) is incompatible between the two, and a different compiler (actually just a different version of gcc) is required.

The compiler for the regular Arduino IDE is the popular avr-gcc package; the compiler for the Maple version of the IDE is CodeSourcery’s edition of gcc for the ARM EABI target (arm-non-eabi-gcc). A (preliminary) reference on using arm-none-eabi-gcc is available.

The bitwidth of the processor means that the Maple can process 32-bit operations (like adding two 32-bit integers) in a single instruction, while an Arduino processor would have to split up large operations into several smaller ones. In a lot of cases 8-bit operations are plenty (integers 0-255, single characters of text, etc.), but if you’re dealing with higher resolution data, the speed up could be significant.

A trade-off is that code could be larger as well; program instructions and memory locations can be up to 32 bits each. However, removal of extra instructions and fancy packing together of simple instructions means that programs aren’t much larger (or are even smaller).

Header Numbering and Incompatibilities

The numbering of headers is different; on the Maple each GPIO has a unique number: D0, D1, D2, all the way up to D37 (actually, there are a few more...). On the Arduino, the analog pins are numbered separately (A0-A5) from the digital pins (D0-D13).

The incompatible hardware differences are:

  • I2C port: on most Arduinos, the I2C port is Analog Input 4 (SDA) and Analog Input 5 (SCL); on the Maple, I2C port 1 is D5 (SCL) and D9 (SDA), and I2C port 2 is D29 (SCL) and D30 (SDA).

    It should be possible to skywire, sacrificing signal quality (due to increased capacitance). Alternatively, I2C can be bit-banged reasonably well in software. This peripheral could potentially be rerouted internally, but we haven’t looked into it.

  • PWM on D10: all the other standard Arduino PWM headers have PWM functionality on the Maple (D2,D3,D6,D9,D11), but not D10. We did our best! It may be possible to reroute this peripheral internally using low level configuration, but we haven’t looked in to it.

  • No External Voltage Reference: The Arduino has an AREF pin which allows the use of an external ADC voltage reference; the Maple has an extra GPIO pin (D14) with PWM capability in this spot, and does not allow an external voltage reference to be configured.

  • EEPROM: the Maple does not have any internal EEPROM. This functionality can be emulated with regular persistent flash memory, or with an external EEPROM chip.

  • ISP Programming: the Maple does not use an ISP/ICSP bus for debugging; it uses JTAG.

Software Language/Library Changes

With a few exceptions, the entire Wiring/Arduino language is supported. However, there are some subtle differences, most of which are improvements:

  • 32-bit integers: many standard functions either expect or return full 32-bit (4 byte) integer values instead of the regular 16-bit (2 byte) Arduino values.
  • 64-bit doubles: The double type is a full double-precision floating point type on the Maple; it is a single-precision floating point value on the Arduino.
  • pinMode() types: any GPIO (including analog pins) can be configured into one of the following modes with a single call to pinMode(): OUTPUT, OUTPUT_OPEN_DRAIN, INPUT_FLOATING, INPUT_PULLUP, INPUT_PULLDOWN. Additionally, the PWM pins (labeled “PWM” on the Maple’s silkscreen) can be configured in PWM and PWM_OPEN_DRAIN modes, and the analog input pins (labeled “AIN”) can be configured in INPUT_ANALOG mode. See the GPIO documentation for more information.
  • Serial port syntax: like the Arduino Mega, the Maple has multiple USART ports. By default, Serial is not mapped to any of them, use Serial1 through Serial3 instead.
  • 16-bit PWM: Arduino boards support 8-bit PWM, which means that calls to analogWrite() take values between 0 (always off) and 255 (always on). The Maple supports 16-bit PWM, so the corresponding values should be between 0 (always off) and 65535 (always on).
  • 12-bit ADC: Arduino boards support 10-bit ADC, which means that calls to analogRead() will return values between 0 and 1023. The Maple supports 12-bit ADC, so the same call will instead return values between 0 and 4095.

Shield and Device Compatibility

Shield/Device Compatible? Notes
Ethernet shield Yes! Tested; no library yet
WiFi Shield Yes! Tested; preliminary library support
MIDI shield Yes! Tested; no library yet
XBee shield Unknown  
Bluetooth shield Unknown Some Bluetooth <-> UART boards have been tested and are known to work.
Cellular shield Unknown  

Library Porting Status

The state of currently ported Arduino libraries is the Maple Library Reference.

Library Ported? Notes
Wire Preliminary In progress; see library reference.
LiquidCrystal Yes Included since IDE 0.0.7
Ethernet Not yet Planned
EEPROM (Unsupported) third-party emulation The Maple doesn’t have EEPROM; it uses flash instead. There is an EEPROM emulation library by x893, but we haven’t tested it.
Firmata Not yet Planned
Matrix Not yet Planned
Servo Yes Included since IDE 0.0.9
SoftwareSerial Not yet Planned
Sprite Not yet Planned
Stepper Not yet Planned

Sketch and Library Porting HOWTO

In addition to the suggestions in this section, you may find many of the individual language reference pages useful. As appropriate, these have “Arduino Compatibility” sections; one good example is the analogWrite() function.

  • Check the hardware and header differences above, and see if your project or shield needs to be modified (eg, add 3.3V level converters or reroute PWM to header D10).
  • Check for ported library functionality. We intend to port all of the core and popular libraries (like Wire, Ethernet, and the LCD screen driver), but this task is not yet finished. (Patches are welcome!)
  • Check for peripheral conflicts; changing the configuration of timers and bus speeds for a feature on one header may impact all the features on that hardware “port”. For example, changing the timer prescaler to do long PWM pulses could impact I2C communications on nearby headers.
  • Rewrite any low-level code. This could potentially be very difficult, but hopefully you’ve used the Arduino libraries to abstract away the registers and other hardware-specific details. Your sketch probably doesn’t have any low-level code; a library which wraps a particular peripheral very well may. Some help is available in the GCC for Maple reference.
  • Redeclare variable sizes if necessary: generics like int will probably work unless you depend on side-effects like rollover.
  • Check every pinMode(): the Maple has more modes for GPIO pins. For example, make sure to set analog pins to INPUT_ANALOG before reading and PWM pins to PWM before writing. The full set of pin modes is documented in the pinMode() reference.
  • Modify PWM writes: pinMode() must be set to PWM, the frequency of the PWM pulse configured, and the duty cycle written with up to 16-bit resolution.
  • Modify ADC reads: analogRead() takes the full pin number (not 0-5) and returns a full 12-bit reading. The ADC pin must have its pinMode() set to INPUT_ANALOG.
  • Possibly convert all Serial-over-USB communications to use SerialUSB instead of a USART serial port. The Maple has a dedicated USB port which is not connected to the USART TX/RX pins in any way.
  • Check timing: Maple clock cycles are just 13.9 nanoseconds, though the peripheral bus speeds (which limit GPIO output) are clocked slower.