SPI master & slave simultaneously

I would like to find out if it is possible to program my 328p as both a SPI master and SPI slave within the same program.

It does not necessarily work as master and slave "at the same time".

Here's the scenario:

The microcontroller (slave) shall receive command from another master. Upon receiving the command, it shall access a EEPROM using SPI. I understand that in order to retrieve data from EEPROM, the microcontroller needs to become master.

Is the above scenario possible?

Thanks for reading

Yes, this is possible, I have just created something like that.

Use the hardware SPI pins (10,11,12,13) to put the atmega328 in spi slave mode

I use software SPI on another set of pins to interface with an SD card and a Nokia 5110 display

For using arduino in slave mode I recommend reading

by Nick Gammon (thanks Nick, your code helped a lot). For using software SPI you can use shiftOut

http://arduino.cc/en/tutorial/ShiftOut

If you want to speed things up, look into fastDigitalWrite and fastDigitalRead, and how to build software SPI functions with it. You can find all code in the standard SD card library of the latest arduino build,

/libraries/SD/utility/Sd2Card.cpp
/libraries/SD/utility/Sd2PinMap.cpp

Cheers,

Jack

Thanks jack. This is great help. Back to working on the codes :~

Software SPI on A0 (sck),A1 (miso), A2 (mosi)

// sw_spi.h
#include "Arduino.h"

#ifndef sw_spi_h
#define sw_spi_h

void nokia_spiSetup(void);
uint8_t nokia_spiRec(void);
void nokia_spiSend(uint8_t data);

#endif // sw_spi_h
// sw_spi.cpp
#include "Sd2PinMap.h"
#include "sw_spi.h"

#define SPI_SCK_PIN	A0 //14	// A0 PC0
#define	SPI_MISO_PIN	A1 //15      // A1 PC1
#define	SPI_MOSI_PIN	A2 //16	// A2 PC2

/** nop to tune soft SPI timing */
#define nop asm volatile ("nop\n\t")

#define  SPI_WAIT  {nop;}

void nokia_spiSetup(void)
{
  setPinMode(SPI_SCK_PIN,  OUTPUT);
  setPinMode(SPI_MISO_PIN, INPUT);
  setPinMode(SPI_MOSI_PIN, OUTPUT);
}


uint8_t nokia_spiRec(void)
{
  uint8_t data = 0;
  // no interrupts during byte receive - about 8 us
  cli();
  // output pin high - like sending 0XFF
  fastDigitalWrite(SPI_MOSI_PIN, HIGH);

  for (uint8_t i = 0; i < 8; i++) {
    fastDigitalWrite(SPI_SCK_PIN, HIGH);

    // adjust so SCK is nice
    nop;
    nop;

    data <<= 1;

    if (fastDigitalRead(SPI_MISO_PIN)) data |= 1;

    fastDigitalWrite(SPI_SCK_PIN, LOW);
  }
  // enable interrupts
  sei();
  return data;
}


void nokia_spiSend(uint8_t data)
{
  // no interrupts during byte send - about 8 us
  cli();
  for (uint8_t i = 0; i < 8; i++) {
    fastDigitalWrite(SPI_SCK_PIN, LOW);
    SPI_WAIT;

    fastDigitalWrite(SPI_MOSI_PIN, data & 0X80);
    SPI_WAIT;

    data <<= 1;

    fastDigitalWrite(SPI_SCK_PIN, HIGH);
    SPI_WAIT;
  }
  // hold SCK high for a few ns
  nop;
  nop;
  nop;
  nop;

  fastDigitalWrite(SPI_SCK_PIN, LOW);
  // enable interrupts
  sei();
}

The examples Nick provides for SPI slave mode are much tidier than mine.

Cheers,

Jack