Multi SPI slave on a single teensy

lucamacavero

New member
Hi,

I need to test the interaction between a microcontroller that reads two sensors with SPI. The microcontroller behaves as a SPI master and the sensors are two slaves. Currently, in order to simulate the behaviour of the two sensors, I'm using two Arduinos, and it works fine. However, I'd like to save space by using a single board; I tried with Arduino with no success.

I'm aware that the teensy can be configured as a SPI slave. Is there any chance to configure both SPI interfaces provided as SPI slaves?

Thanks
Luca
 
Do you have two separate SPI buses, or are both sensors on one bus? If you have one SPI master and two SPI slaves, that means you have 1 each of SCK, MISO, MOSI, and 2 x CS, and you can program the Arduino to simulate both sensors based on which CS is asserted, right?
 
@joepasquariello you are right, I have both sensors on a single bus.
I have tried with a single Arduino, but something doesn't work in my implementation:

C++:
#define SCK_PIN   13  // D13 = pin19 = PortB.5
#define MISO_PIN  12  // D12 = pin18 = PortB.4
#define MOSI_PIN  11  // D11 = pin17 = PortB.3
#define SS1_PIN    8  // D8
#define SS2_PIN    7  // D7
#define SS        10  // D10 Common CS pin


void setup()
{
  Serial.begin (115200);    // set baud rate to 115200 for usart
  pinMode(SS1_PIN, INPUT_PULLUP);
  pinMode(SS2_PIN, INPUT_PULLUP);
  pinMode(SS, INPUT_PULLUP);
  pinMode(MISO_PIN, OUTPUT);
  pinMode(SCK_PIN, INPUT);

  SPCR |= _BV(SPE);        // turn on SPI in slave mode
  PCIFR  |= bit (PCIF0);   // clear any outstanding interrupts
  PCMSK0 |= B00000001;     // We activate the interrupts on pin D8
  PCMSK2 |= B10000000;     // We activate the interrupts on pin D
  PCICR |=  B00000101;     // Enables 1 interrupt on D8-13 (PCMSK0) and one on D0-7 (PCMSK2)
  Serial.println("ready");
}


void loop(){
}


// SENSOR 1
//Interrupt routine function for SS1
ISR(PCINT0_vect) 
{
  uint8_t i=100;
    while (digitalRead(SS1_PIN) != HIGH)
    {
        while (!(SPSR & (1 << SPIF)))
        { /** poll SPIF bit */
            /** if SS went high, give up */
            if (digitalRead(SS2_PIN) == HIGH) // this represents D10 common CS
            {
                return;
            }
        }
        // Write something on MISO
        SPDR = i;
        i--;
    }
}

// SENSOR 2
//Interrupt routine function for SS2
ISR(PCINT2_vect)
{
    uint8_t i=1;
    while (digitalRead(SS2_PIN) != HIGH)
    {
        /* As one byte has been completely shifted, the end of transmission flag, SPIF is set.
        We wait for the flag to be set. */
        while (!(SPSR & (1 << SPIF)))
        {
            if (digitalRead(SS2_PIN) == HIGH) // this represents D10 common CS
            {
                return;
            }
        }
        // Write something on MISO
        SPDR = i;
        i++;
    }
}

Basically PIN 10 is the "common" CS, while PINs 7 and 8 are connected to two different CS.
1716281425199.png


I'm not totally sure about the implementation, but this is working one time out of 5/6 transactions.

Thank you,
Luca
 
Back
Top