SPI Communication using ONLY arduino libraries- no AVR code!

I am trying to suss out how to get SPI communication going between two UNOs using only the Arduino libraries, so that my program will work the same on my chipKit UNO32 and my Leaflabs Maple board. I have a super simple master test program here;

#include <SPI.h>

char x = 'A';
void setup()
{
 SPI.begin();

pinMode(SS, OUTPUT);
digitalWrite(SS, HIGH);
}

void loop()
{
SPI.transfer(x); 
delay(500);
 }

but I’m having trouble writing the slave side, mainly because I don’t fully understand the SPI.transfer(); function. Does this function control both sending AND recieving data on the SPI bus? if anyone could show me some slave code (Arduino libraries only!) that would work with the master code above that would be awesome!

You have to take SS low for the duration of the sending/receiving.

void loop() {
    digitalWrite(SS, LOW);
    SPI.transfer(x);
    digitalWrite(SS, HIGH);
    delay(500);
}

All should be revealed here:

http://gammon.com.au/spi

Nick, that's a very helpful page indeed but I'm wondering is it possible to make an equivalent slave program without directly addressing the AVR registers? for example when you turn on SPI in slave mode;

SPCR |= _BV(SPE);

because this won't work on my chipKit UNO32 board.

eriknyquist: I'm wondering is it possible to make an equivalent slave program without directly addressing the AVR registers? for example when you turn on SPI in slave mode;

SPCR |= _BV(SPE);

because this won't work on my chipKit UNO32 board.

I don't think the Arduino SPI library covers slave mode so you are out of luck. You'll have to figure out how to do it on the PIC processor.

Turn that line into a function. Find an equivalent on the PIC. You will probably need some "glue" routines anyway unless both libraries work in exactly the same way and have the same names.

dammit you're right, Arduino API doesn't cover slave mode.....why arduino?? why?? Anyway thanks for your help guys, Nick I'm sure I'll find a way around it, maybe I'll just bite the bullet and write a SPI slave lib. If i do then I'll make sure to share it up here!

eriknyquist: dammit you're right, Arduino API doesn't cover slave mode.....why arduino?? why?? Anyway thanks for your help guys, Nick I'm sure I'll find a way around it, maybe I'll just bite the bullet and write a SPI slave lib. If i do then I'll make sure to share it up here!

Are you sure?:

http://arduino.cc/forum/index.php/topic,22187.0.html

Lefty

retrolefty:

eriknyquist:
dammit you’re right, Arduino API doesn’t cover slave mode…why arduino?? why??
Anyway thanks for your help guys, Nick I’m sure I’ll find a way around it, maybe I’ll just bite the bullet and write a SPI slave lib. If i do then I’ll make sure to share it up here!

Are you sure?:

http://arduino.cc/forum/index.php/topic,22187.0.html

Lefty

Looks like that example uses direct register manipulation on the Slave side:

void SlaveInit(void) {
  // Set MISO output, all others input
  pinMode(SCK_PIN, INPUT);
  pinMode(MOSI_PIN, INPUT);
  pinMode(MISO_PIN, OUTPUT);
  pinMode(SS_PIN, INPUT);

  // Enable SPI
  SPCR = B00000000;
  SPCR = (1<<SPE);
}

byte ReadByte(void) {
  while(!(SPSR & (1<<SPIF))) ;
  return SPDR;
}

void WriteByte(byte value) {
  SPDR = value;
  while (!(SPSR & (1<<SPIF))) ;
  return;
}

That code won’t fly on the PIC processor.

yup exactly. Lefty, implementing a SPI slave with an arduino is of course possible, but it's not supported by the arduino libraries. If you want to do it then you have to refer to the datasheet for the '328 and write directly to the registers, a task that is normally hidden by the fluffy arduino libraries. The datasheet for the PIC32 MCU is unfortunately not as clear as the 328, was looking through it today and I can see no easy way of doing this yet (i.e. I can't just swap out the register names for the names of the corresponding registers in the PIC).

eriknyquist: yup exactly. Lefty, implementing a SPI slave with an arduino is of course possible, but it's not supported by the arduino libraries. If you want to do it then you have to refer to the datasheet for the '328 and write directly to the registers, a task that is normally hidden by the fluffy arduino libraries. The datasheet for the PIC32 MCU is unfortunately not as clear as the 328, was looking through it today and I can see no easy way of doing this yet (i.e. I can't just swap out the register names for the names of the corresponding registers in the PIC).

I guess I miss your point or complaint. The arduino supplied SPI library (SPI.h and SPI.cpp) is nothing but filled with AVR register names. So you want to use arduino SPI API or not? Or are you talking about some other arduino library/API ?

Lefty

retrolefty: I guess I miss your point or complaint. The arduino supplied SPI library (SPI.h and SPI.cpp) is nothing but filled with AVR register names. So you want to use arduino SPI API or not? Or are you talking about some other arduino library/API ?

The "chipKit UNO32" uses a 32-bit PIC processor rather than an ATmega. They implement the Arduino core libraries so in many cases you can write an Arduino sketch and have it run on the chipkit UNO32. You can't run any Arduino sketches that require direct register manipulation. Since the Arduino core SPI library only supports Master mode you can't write a Slave mode SPI sketch that will run on both an Arduino and a chipkit UNO32.

johnwasser:

retrolefty: I guess I miss your point or complaint. The arduino supplied SPI library (SPI.h and SPI.cpp) is nothing but filled with AVR register names. So you want to use arduino SPI API or not? Or are you talking about some other arduino library/API ?

The "chipKit UNO32" uses a 32-bit PIC processor rather than an ATmega. They implement the Arduino core libraries so in many cases you can write an Arduino sketch and have it run on the chipkit UNO32. You can't run any Arduino sketches that require direct register manipulation. Since the Arduino core SPI library only supports Master mode you can't write a Slave mode SPI sketch that will run on both an Arduino and a chipkit UNO32.

So his complaint should really be issued against the chipKit implementers of their "Arduino API like core"? I assume they have implemented PIC hardware serial commands that mimic the arduino hardware serial library functions that uses AVR registers? Why would they support a standard comm such as serial and not the standard SPI communications? My confusion is most based on his "Arduino API doesn't cover slave mode.....why arduino?? " comment. Arduino does support SPI slave mode for AVR chips, why is this a Arduino API fault?

Lefty

Yes, I don't really see the problem. To make the same code work on different chips you would need some sort of "glue" interface library that, inside, uses #ifdef to select the Arduino API call or the PIC API call.

When coding micro controllers, its not unreasonable to expect some of the code to be hardware specific. The differences are probably beyond just register names. Different chips work differently. Some macro definitions may be all you need to solve it though.