firmata/arduino — pull request #135 by achingbrain (2014-06-08 09:36:38+00:00)
Title: Added support for the SPI bus

I bought a MFRC522 RFID reader and have managed to get it working with node-firmata. I found a [working sketch](http://www.grantgibson.co.uk/2012/04/how-to-get-started-with-the-mifare-mf522-an-and-arduino/) that talks to the card over the SPI bus which I ported to JavaScript.

I looked at the [SPI proposal on the wiki](http://firmata.org/wiki/Proposals#SPI_Proposal) and cross referenced it with the [Arduino API](http://arduino.cc/en/Reference/SPI) - please accept my apologies if I've got the wrong end of the stick, but I can't see how one applies to the other - the proposal on the Wiki page refers to a scheduler, creating jobs, querying jobs, deleting jobs and so on, but the [SPI class](https://github.com/arduino/Arduino/blob/master/libraries/SPI/SPI.h) is all about reading and writing bytes to devices on the SPI bus.

Anyway the class defined in `SPI.h` look pretty straightforward so I had a go at exposing it's methods. The protocol looks like this:

```
/* SPI transfer request
* -------------------------------
* 0 START_SYSEX (0xF0) (MIDI System Exclusive)
* 1 SPI_REQUEST (0x60)
* 2 SPI_TRANSFER (0x00)
* 3 sequenceId (byte) Used to match requests to responses
* 4 toWrite (byte) How many bytes to write onto the bus
* 5 data 0 (byte)
* 6 data 1 (byte)
* ...
* n END_SYSEX (0xF7)
*/
```

```
/* SPI transfer reply
* -------------------------------
* 0 START_SYSEX (0xF0) (MIDI System Exclusive)
* 1 SPI_REQUEST (0x60)
* 2 SPI_TRANSFER_REPLY (0x01)
* 3 sequenceId (byte) Used to match responses to requests
* 4 SPI_READ (0x02)
* 5 read (byte) How many bytes were read from the bus
* 6 data 0 (byte)
* 7 data 1 (byte)
* ...
* n END_SYSEX (0xF7)
*/
```

```
/* Begin SPI request
* -------------------------------
* 0 START_SYSEX (0xF0) (MIDI System Exclusive)
* 1 SPI_REQUEST (0x6W0)
* 2 SPI_BEGIN (0x02)
* 3 END_SYSEX (0xF7)
*/
```

```
/* End SPI request
* -------------------------------
* 0 START_SYSEX (0xF0) (MIDI System Exclusive)
* 1 SPI_REQUEST (0x60)
* 2 SPI_END (0x03)
* 3 END_SYSEX (0xF7)
*/
```

```
/* Set bit order
* -------------------------------
* 0 START_SYSEX (0xF0) (MIDI System Exclusive)
* 1 SPI_REQUEST (0x60)
* 2 SPI_SET_BIT_ORDER (0x04)
* 3 bitOrder (byte) Sets the order of the bits shifted out of and into the
SPI bus, either LSBFIRST (0 - least-significant bit first) or MSBFIRST
(1 - most-significant bit first).
* 4 END_SYSEX (0xF7)
*/
```

```
/* Set data mode
* -------------------------------
* 0 START_SYSEX (0xF0) (MIDI System Exclusive)
* 1 SPI_REQUEST (0x60)
* 2 SPI_SET_DATA_MODE (0x05)
* 3 dataMode (byte) Sets the SPI data mode: that is, clock polarity and phase.
* 4 END_SYSEX (0xF7)
*/
```

```
/* Set clock divider
* -------------------------------
* 0 START_SYSEX (0xF0) (MIDI System Exclusive)
* 1 SPI_REQUEST (0x60)
* 2 SPI_SET_CLOCK_DIVIDER (0x06)
* 3 clockDivider (byte) Sets the SPI clock divider relative to the system
clock. The dividers available are 2, 4, 8, 16, 32, 64, or 128. The
default setting is SPI_CLOCK_DIV4, which sets the SPI clock to
one-quarter the frequency of the system clock.
* 4 END_SYSEX (0xF7)
*/
```

```
/* Attach interrupt
* -------------------------------
* 0 START_SYSEX (0xF0) (MIDI System Exclusive)
* 1 SPI_REQUEST (0x60)
* 2 SPI_ATTACH_INTERRUPT (0x07)
* 3 END_SYSEX (0xF7)
*/
```

```
/* Detach interrupt
* -------------------------------
* 0 START_SYSEX (0xF0) (MIDI System Exclusive)
* 1 SPI_REQUEST (0x60)
* 2 SPI_DETACH_INTERRUPT (0x08)
* 3 END_SYSEX (0xF7)
*/
```

It'd be great if this could be added to ConfigurableFirmata.

I don't know if all the messages are strictly necessary (setting the clock divider for one seems specific to Arduino), but I'd love to have your input - please let me know what you think.