Raspberry pi arduino SPI

Hi,
connecting rpi and arduino via spi
transmitting bytes from arduino after receiving byte(0xFE) from rpi. its working fine but im receiving like this. mention my mistake.
Thanks

AA
FE
AB
FE
FE
AC
FE
FE
FE
FE
AD
AE
FE
FE
AF
B0
FE
FE
FE
FE
FE
B1
FE
FE
FE
FE
FE
FE
FE
FE
B2

static const char *device = "/dev/spidev0.0";
static uint8_t mode;
static uint8_t bits = 8;
static uint32_t speed = 500000;
static uint16_t delay;

static void transfer(int fd)
{
	int ret;
	uint8_t tx[] = {0xFE};
	uint8_t rx[ARRAY_SIZE(tx)] = {0,};
	struct spi_ioc_transfer tr = {
		.tx_buf = (unsigned long)tx,
		.rx_buf = (unsigned long)rx,
		.len = ARRAY_SIZE(tx),
		.delay_usecs = delay,
		.speed_hz = speed,
		.bits_per_word = bits,
	};

	ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
	if (ret < 1)
		pabort("can't send spi message");

    
	for (ret = 0; ret < ARRAY_SIZE(rx); ret++) 
	{		
		printf("%.2X ", rx[ret]);
	}
	puts("");
  
}
.
.
.
while(1)
	{
	   transfer(fd);	
	   
	}

Arduino code:

#include <SPI.h>
#define st_byte 254

char buf [100];
char data[]= {0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0XB4};

volatile byte pos;
volatile boolean process_it;

void setup (void)
{
  Serial.begin (115200);   // debugging

  // have to send on master in, *slave out*
  pinMode(MISO, OUTPUT);
  
  // turn on SPI in slave mode
  SPCR |= _BV(SPE);
  
  // get ready for an interrupt 
  pos = 0;   // buffer empty
  process_it = false;

  // now turn on interrupts
  SPI.attachInterrupt();

}  // end of setup


// SPI interrupt routine
ISR (SPI_STC_vect)
{
byte c = SPDR;  // grab byte from SPI Data Register
  
  // add to buffer if room
  if (pos < sizeof buf)
    {
    buf [pos++] = c;
    
    // example: newline means time to process buffer
    if (c == 254)
      process_it = true;
      
    }  // end of room available
}  // end of interrupt routine SPI_STC_vect

// main loop - wait for flag set in interrupt routine
void loop (void)
{
  int i;
 
    if(process_it)
    {
         buf [pos] = 0;       
         Serial.println(data);
         for(i=0;i<sizeof data;i++)
         {
           SPI.transfer(data[i]);           
         }
         pos = 0;
         process_it = false;
    }  // end of flag set
    
}  // end of loop

spicode.c (3.86 KB)

spi_code.ino (762 Bytes)

Do you have a voltage converter between the two? The Raspberry Pi is a 3V device while the Arduino is a 5V.

Pylon means the IO Pins have a different voltage

These work really well! And are cheap.

venksbond:
i got converter, one thing i want ask while connecting wires is it need to connect the voltage pins to the level converter? Or MOSI,MISO and clk is enough?

Yes you need to connect level converters between all the wires connecting a Pi and an Arduino.

If you have at any time connected the signals from the arduino and Pi together you might have burnt out the GPIO pins on the Pi.
You need to check if the Pi is still working, use an oscilloscope to check this.

venksbond:
when i unplug miso cable i'm receiving 0x00 so its working i think. even im not receiving any other garbage value.

No that is not sufficient to say it is working.

yes you are right. now im getting garbage. i got this link to use (but it is I2C)level shifter https://dl.dropbox.com/u/4710119/mess/rasp_ard_i2c_bb_working.png. i cant understand why both 5v & 3.3v are used from pi to wiring and why resistor are need can u explain.
thanks

On that diagram the 5V from the Pi is being used to power the arduino. You must not plug in the USB lead while it is wired like this.
The resistors are pull ups required by the I2C interface. They are not needed on the Pi side because it already has a pull up on its I2C lines.

Your original post does not show garbage. That looks like a buffer overflow. Is that the output of the Pi or the Arduino?

I would not use this unless you have a terminating zero at the end of that array.

         Serial.println(data);

How big is the rx array?

	uint8_t tx[] = {0xFE};
	uint8_t rx[ARRAY_SIZE(tx)] = {0,};

the o/p in rpi. im transmitting 0xFE to arduino and receiving data(bytes) in RPI. serial.println for debugging purpose in arduino. rx array size defined in structure of 'tr' i.e .len tells how many bytes we transmit and receive.

Grumpy_Mike:
If you have at any time connected the signals from the arduino and Pi together you might have burnt out the GPIO pins on the Pi.
You need to check if the Pi is still working, use an oscilloscope to check this.

Its working fine for rasp clock speed @200khz transferring 10 bytes. when i increase clock speed >200khz data sequence is not fine. what is the maximum SPI clock speed for arduino can support?

what is the maximum SPI clock speed for arduino can support?

It is 8MHz.

Please do not delete your posts, it makes the thread disjointed. Even if you said things that you now know are not true please preserve a record for the benefit for those searching on this thread in future.

is it necessary to config setclockdivider when arduino act as slave?

No that only sets the clock output, so no need if it is a slave.

rpi sends -0xFE
arduino sends data[]={0xA1,0xA2,0xA3,0xA4,0xA5}

void loop (void)
{
    
      if(process_it)
      {
         buf [pos] = 0;  
        
        SPDR = data[i];
        i++;      if(i>9) i=0;
           
         pos = 0;
         process_it = false;
      } 
    
}

if i send one byte from rpi 0xFE arduino replies one byte 0xA1 and further bytes in data for next 0xFE

if i send 0xFE,0xFE from rpi arduino replies 0xA1,0xFE and further 0xA2,0xFE

then i changed code

void loop (void)
{
    
      if(process_it)
      {
         buf [pos] = 0;  
        
        SPDR = data[0];
        SPDR = data[1];
           
         pos = 0;
         process_it = false;
      } 
    
}

i got 0xA2,0xFE and same(0xA2,0xFE) for further 0xFE,0xFE from rpi. i think it replies whatever data kept last in SPDR register im getting that byte. why its not sending two bytes from data[]?

venksbond:
is it necessary to config setclockdivider when arduino act as slave?

SPI clock should then be limited to 4MHz (on the R-Pi side) as per the AtMega datasheet. AVR's need a minimum of 4 cycles (16MHz/4) to process inbound SPI data.