Go Down

Topic: Update the Spi library from the playground (Read 1 time) previous topic - next topic

OpenSource

Jun 13, 2010, 04:49 pm Last Edit: Jun 13, 2010, 05:21 pm by OpenSource Reason: 1
Hello,

Lately I've started using the Spi library from the Arduino Playground to communicate between two arduino's using two nRF24L01+ transceiver modules.

http://www.arduino.cc/playground/Code/Spi

Because this library uses the Spi library I've downloaded it and started working with it. I interface between an Arduino Mega and an Arduino Duemilanove. I had a lot of problems at the start, this because both the boards use different digital pins for the SCK, MISO, MOSI and SS configuration.

Duemilanove:
pin 13      SCK         SPI clock      
pin 12      MISO         SPI master in, slave out
pin 11      MOSI         SPI master out, slave in
pin 10      SS         SPI slave select

Mega:
pin 52       SCK        SPI clock      
pin 50      MISO        SPI master in, slave out
pin 51      MOSI        SPI master out, slave in
pin 53      SS        SPI slave select

The Spi library uses the following pin configuration:
pin 13      SCK        SPI clock      
pin 12      MISO        SPI master in, slave out
pin 11      MOSI        SPI master out, slave in
pin 10      SS        SPI slave select

Now I needs to change the pins in the Spi.h file before I upload the sketch to the Mega or Duamilanove board.....

Maybe it's better to be able to config the pins in the setup of the arduino board. In this way you'll have much more flexibility :)

For example:

Code: [Select]
void setup(){
Spi.MISO(12); // This will config pin 12 as MISO
}


Or maybe be able to select a board when the library is inserted.

Code: [Select]
#include <Spi.h>

void setup(){
Spi(mega);
}


(I don't know if this is possible, my library programming skills are bad....)

The problem is I don't have the skills to update/modify this library and I don't know how updating normally works? Can users just update and upload it or do they need to have permission from the author of this library

Any users who know how to do this or have better suggestions?

Thanks in advance,

/me

OpenSource

#1
Jun 13, 2010, 10:19 pm Last Edit: Jun 13, 2010, 10:23 pm by OpenSource Reason: 1
Hello,

I've did a small modification on the library. I changed the name to SpiM.H and SpiM.cpp, but this is just temporarily for debugging purposes. All the changes are marked using this tag:

Code: [Select]

// Added to the original library


SpiM.h
Code: [Select]

#ifndef SpiM_h
#define SpiM_h

#include "WProgram.h"

#define SCK_PIN   13
#define MISO_PIN  12
#define MOSI_PIN  11
#define SS_PIN    10

class SPI
{
 public:
   SPI(void);
   void mode(byte);
     void SCK(int); // Added to the original library
     void MISO(int); // Added to the original library
     void MOSI(int); // Added to the original library
     void SS(int); // Added to the original library
   byte transfer(byte);
   byte transfer(byte, byte);
};

extern SPI Spi;

#endif



Please note, all the copyright stuff is left out in this example.

SpiM.cpp This is the actual modified part

Code: [Select]


#include "WProgram.h"
#include "SpiM.h"

//---------- constructor ----------------------------------------------------

SPI::SPI()
{
 // initialize the SPI pins
 pinMode(SCK_PIN, OUTPUT);
 pinMode(MOSI_PIN, OUTPUT);
 pinMode(MISO_PIN, INPUT);
 pinMode(SS_PIN, OUTPUT);

 // enable SPI Master, MSB, SPI mode 0, FOSC/4
 mode(0);
}

void SPI::SCK(int SCK_PIN_CHANGED) // Added to the original library
{
 // Change the SCK pin
 pinMode(SCK_PIN_CHANGED, OUTPUT);
}

void SPI::MOSI(int MOSI_PIN_CHANGED) // Added to the original library
{
 // Change the MOSI pin
 pinMode(MOSI_PIN_CHANGED, OUTPUT);
}

void SPI::MISO(int MISO_PIN_CHANGED) // Added to the original library
{
 // Change the MISO pin
 pinMode(MISO_PIN_CHANGED, OUTPUT);
}

void SPI::SS(int SS_PIN_CHANGED) // Added to the original library
{
 // Change the SS pin
 pinMode(SS_PIN_CHANGED, OUTPUT);
}

//------------------ mode ---------------------------------------------------

void SPI::mode(byte config)
{
 byte tmp;

 // enable SPI master with configuration byte specified
 SPCR = 0;
 SPCR = (config & 0x7F) | (1<<SPE) | (1<<MSTR);
 tmp = SPSR;
 tmp = SPDR;
}

//------------------ transfer -----------------------------------------------

byte SPI::transfer(byte value)
{
 SPDR = value;
 while (!(SPSR & (1<<SPIF))) ;
 return SPDR;
}

byte SPI::transfer(byte value, byte period)
{
 SPDR = value;
 if (period > 0) delayMicroseconds(period);
 while (!(SPSR & (1<<SPIF))) ;
 return SPDR;
}


//---------- preinstantiate SPI object --------------------------------------

SPI Spi = SPI();


Please note, all the copyright stuff is left out in this example.

The arduino sketch would become:

Arduino sketch example

Code: [Select]

#include <SpiM.h>

void setup(){
SpiM.SCK(52);
SpiM.MOSI(51);
SpiM.MISO(50);
SpiM.SS(51);
}

void loop(){
// code
}




This is just an attempt to modify the library, I would like to know from the code experts if this is the good way to go ( and if it actually works..)?

Thanks in advance,

/me :)

OpenSource

Based on some suggestions by Alexander (Immetic) the following changes to the header file will also do:

Code: [Select]


#if defined(__AVR_ATmega1280__)
 #define SCK_PIN   52
 #define MISO_PIN  50
 #define MOSI_PIN  51
 #define SS_PIN    53
#else  
 #define SCK_PIN   13
 #define MISO_PIN  12
 #define MOSI_PIN  11
 #define SS_PIN    10
#endif



Do all board except the Mega board use:

SCK_PIN   13
MISO_PIN  12
MOSI_PIN  11
SS_PIN    10

as Spi pins?

Cheers,

/me



Please your suggestions?

AlphaBeta


leppie

The pins for the ATMega328 is fixed. There is no point in exposing them to the user via a header file.

I suggest adding those internals to the source instead, else you end getting people changing the pins and wondering for ages why things do not work (like I did for ArduinoISP).

Also, I dont really see the point of adding pins, as the SPI library should be using the SPI registers directly, which in the case of the 328, is just those mentioned, but IMO they should not be used directly, else you would be doing software SPI and not using the hardware SPI.

Correct me if I am wrong.

Steve S

Sounds like a good idea to me.
The only reason for exposing the pins would be so that you know where to plug things in!

If the source is suitably #if'd, that eliminates the problem for everybody and allows future changes for things like ATMega1284Ps.

leppie

Quote
The only reason for exposing the pins would be so that you know where to plug things in!


That's why it should be in documentation or code comments. :)

I do see however the library uses the Arduino mapped pins to enable output on those pins. Whether that is needed (and I suspect not all pins require that), is another story.

buffler

I'll be trying to implement spi with two shaft encoder peripherals (LS7366R) for a two-axis drive system. To that end, and for other uses as well, I'll need two different SS pins. The peripherals are three-stated on the MISO line, dependent on the SS. So it would be better to be able to call the SS pin at the time of the spi function call. Otherwise, I guess it'll be fiddling around with some kind of self-developed subroutines...
Don

Go Up