Notes About Working with Various Arduino & Netduino Microcontroller Boards

Friday, February 1, 2013

Connecting an uM-FPU64 Math Co-Processor to an Arduino Due via I2C

Last November, I made a couple posts about using the Micromega uM-FPU (32-bit) floating point unit with an Arduino. There is also a 64-bit version of the uM-FPU co-processor. I don't really need such mathematical precision for my projects, but the 64-bit version does have some nice additional features. The uM-FPU64 is also  3.3 volt (rather than 5V, but the datasheet indicates that the I2C & SPI interfaces tolerate 5V). The 64-bit chip seems harder to find. I ended up getting mine from Solarbotics in Calgary. 

Both the 32- and 64-bit versions of the chip can be connected to an Arduino using I2C, but the Arduino libraries and examples provided by Micromega are restricted to SPI connectivity. In this post, I show how to use I2C to connect the uM-FPU64 to an Arduino Due. The sample code prints the square roots of the integers from 1 to 127 to the serial console.

Connections:

The pins on the FPU are numbered counterclockwise from the notch (starting with pin 1).

uM-FPU64  --->  Arduino Due
 1 (/MCLR)       3V3
 8 (VSS)         GND
 9 (SEL)         3V3  (3V3 = I2C mode, GND = SPI)
13 (VDD)         3V3  (with 0.1uF capacitor to GND on breadboard)
14 (SERIN)       GND
17 (SCL)         Digital 21 SCL (with 4k7 pull-up resistor to 3V3) 
18 (SDA)         Digital 20 SDA (with 4k7 pull-up resistor to 3V3)
19 (VSS)         GND
20 (VCAP)        GND via 4.7uF capacitor on breadboard
27 (AVSS)        GND 
28 (AVDD)        3V3 (with 0.1uF capacitor between 27 & 28 on breadboard)

Code:

#include <Wire.h>

#define FPU_ADDR   0x64
#define FSETI 0x32 // reg[A] = float(bb)
#define FTOA 0x1F // Convert float to ASCII
#define SELECTA 0x01 // Select register A
#define SQRT 0x41 // reg[A] = sqrt(reg[A])
#define READSTR 0xF2 // Read string from string buffer



#define SYNC 0xF0 // Get synchronization byte
#define SYNC_CHAR 0x5C // sync character

#define RESET_REG  0x01
#define RESET_CMD  0x00
#define DATA_REG   0x00

void setup() {
  Serial.begin(19200);
  while(!Serial) { ; }
  Wire.begin();

  // Reset FPU by writing 0 to I2C register addr. 1
  Wire.beginTransmission(FPU_ADDR);
  Wire.write(RESET_REG);
  Wire.write(RESET_CMD);
  Wire.endTransmission();
  // Recommended delay after reset
  delayMicroseconds(15);

  // Check FPU communication
  Wire.beginTransmission(FPU_ADDR);
  Wire.write(DATA_REG);
  Wire.write(SYNC);
  Wire.endTransmission();
  delay(10);
  Wire.requestFrom(FPU_ADDR, 1);
  while(Wire.available())    
  { 
    char c = Wire.read();    
    if(!c == SYNC_CHAR) {
      Serial.println("uM-FPU64 not responding.");
      while(1); 
    }      
  }
}

void loop() {
  for(int i = 1; i <= 127; i++) {
    String answer = "Sqrt of ";
    (answer += i) += " is ";
    Wire.beginTransmission(FPU_ADDR);
    Wire.write(DATA_REG);
    Wire.write(SELECTA);
    Wire.write(129); // FPU registers 128 & above are 64 bit
    Wire.write(FSETI);
    Wire.write(i);
    Wire.write(SQRT);
    Wire.write(FTOA);
    Wire.write(0x00);
    Wire.write(READSTR);
    Wire.endTransmission();
    Wire.requestFrom(FPU_ADDR, 32);
    while(Wire.available())    
    { 
      char c = Wire.read();    
      answer += c;         
    }
    Serial.println(answer);
  }
  while(1);
}

See the FPU64.h file in the FPU64 library from MicroMega (and include it in your sketch) for the complete list of functions.

2 comments:

  1. 1. What are the advantages connecting throug the I2C rather than the SPI? Better performance? Any disadvantages?

    2. When connecting via the I2C are we still able to use the SPI for connection with other devices? Any special I2C pin changes to the co-process when SPI devices are added?

    Thanks, for such a very nice post.

    ReplyDelete
    Replies
    1. Hi Mark -

      Thanks for your comment. SPI is faster than I2C, but for my projects I haven't come across anything where I2C wasn't fast enough by a comfortable margin, but there probably are applications where the additional speed of SPI would be important. I don't have any numbers on how the speed difference plays out with the FPU. I2C does take one less wire for the connection than SPI, and I have always found I2C very easy to wok with. There shouldn't be any problem using I2C and SPI at the same time.

      Delete