SPI slave echoes MOSI and ignores Slave output

Go To Last Post
10 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am implementing a slave sample with an Atmega328p through the Arduino platform. The device communicates with a linux board with SPI. '
The problem is that the Master sends data and after the first response all the data that the slave sends is an echo of the previous byte sent by the master.  

 

Here is what my scope giives me as output, which is also the same I get from my Master SPI on linux.

 

 

The code I am using for the Arduino is the following:

 


void setup (void)
{

  pinMode(MISO, OUTPUT);
  SPDR=0x90; //First data to send to master
  SPCR |= _BV(SPE);
  SPCR = (1 << SPE) | (1 << SPIE); // slave mode  and SPI interrupt
}  // end of setup

byte SPItransfer(byte value) {
  SPDR = value;
  while(!(SPSR & (1<<SPIF)));

}
volatile uint8_t count=0;
void loop (void)
{

}  // end of loop

// SPI interrupt routine
ISR (SPI_STC_vect)
{

  uint8_t buffer=SPDR;
  SPItransfer(count++);

}

From my test I see that the SPDR register is not being updated on the next calls of the ISR with my variable. Is there anything else that I missed?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

don't wait in the ISR()  i.e. :

  while(!(SPSR & (1<<SPIF)));

Get in, get out, don't wait.

 

Jim

 

Click Link: Get Free Stock: Retire early!

share.robinhood.com/jamesc3274

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I already tried removing it and it still just loads the first time to SPDR and then it echoes everything.
I changed the code for a more simplistic approach

volatile uint8_t count=0;
void setup (void)
{
        // have to send on master in, *slave out*
        pinMode(MISO, OUTPUT);

        // turn on SPI in slave mode
        SPCR |= _BV(SPE);
        
        // turn on interrupts
        SPCR |= _BV(SPIE);
        SPDR=0x50;
}  // end of setup

void loop (void)
{

}  // end of loop

// SPI interrupt routine
ISR (SPI_STC_vect)
{
        
        uint8_t buffer=SPDR;
        SPDR = count++;
}  

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Did you enable the interrupts ? Toggle a pin inside ISR and check if the interrupt is actually taken.

 

The fact that it echoes what it is receiving tells that nothing is actually written to the transmit buffer.

 

On a side note, I don't think you can make it to work properly without gaps between bytes coming from linux device. This is because lack of buffering.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What have you done with the slave select pin?

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 2

What's the chip/ slave select line doing? An SPI slave will always write out the previous byte it received for as long as the SS line is active (which is what it you're experiencing). This is by design and is what enables you to use SPI slave devices in a daisy chain configuration.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am not using the slave select line, since it will only communicate with the microcontroller.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

yudopplyr wrote:

I am not using the slave select line, since it will only communicate with the microcontroller.

 

Can you confirm that you have read the section in the datasheet which tells you what you must do to the /SS pin when using the SPI module as a slave?

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Without using the SS line, how do you expect your MCU - acting as an SPI slave - to know when the data on the bus is intended for your MCU or another device that might be connected to the bus? SPI allows for as many devices connected to the same SPI bus (SCK, MOSI, MISO) as you like via the slave select mechanism. Even in your setup where you only have 1 slave, your slave doesn't know nor care about this, so it still needs it's SS line to be handled properly. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

SOME SPI devices do not latch the data until the (usually) rising edge of the chip select. Yes, some to work OK with /CS tied low, but not all. YOU have to read the spec sheet for the slave device and determine what is needed for correct operation.

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net