SPI start moment from slave -> master ????????

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

hallo, i hope someone can help me whit a SPI problem.  i check the things with a logic analyzer. i see on the MISO pin the data who's in the array (slave).

the only thing what is different then expected is the starting moment from putting the array on the MISO, that is random ????

 

maybe someone see what i do wrong,.......thanx.

 

MASTER

//*******************************17-8-2019 TEST PSI****************************
//**********************************MASTER**************************************

#define F_CPU 1000000UL // 1 MHz int osc
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>



int main(void)
{
	char data;

	DDRB |= (1<<PINB1)|(1<<PINB2)|(1<<PINB0);    // SCK, MOSI and SS as outputs
	DDRB &= ~(1<<PINB3);                 // MISO as input
	
	DDRC = 0b11111111;

	SPCR |= (1<<MSTR);               // Set as Master
	SPCR |= (1<<SPR0)|(1<<SPR1);     // divided clock by 128
	SPCR |= (1<<SPE);                // Enable SPI
	
	while(1)
	{

		_delay_ms(1);
		PORTC &= ~(1 << PINC5); // maakt C.5 laag
		
		SPDR = 0b01010101;                 // send the data
		while(!(SPSR & (1<<SPIF)));  // wait until transmission is complete
		
		PORTC |= (1 << PINC5); // maakt C.5 hoog

		
	}
					
}

SLAVE

//****************17-8-2019 TEST PSI*****************************************************
//*****************************SLAVE*********************************************

#define F_CPU 1000000UL // 1 MHz int osc

#include <avr/io.h>
#include <stdio.h>
#include <util/delay.h>

int testers [38] = {255, 0, 255, 0, 255, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,} ;

int bytenr;
int data;



int main(void)
{
    //       char data;

    DDRB &= ~((1<<PINB7)|(1<<PINB5)|(1<<PINB4));   // SCK, MOSI and SS as inputs
    DDRB |= (1<<PINB6);                    // MISO as output

    SPCR &= ~(1<<MSTR);                // Set as slave
    SPCR |= (1<<SPR0)|(1<<SPR1);       // divide clock by 128
    SPCR |= (1<<SPE);                  // Enable SPI

    while(1)
    {
        for (bytenr=0; bytenr<38; bytenr++)
        {        
            while(!(SPSR & (1<<SPIF)));    // wait until all data is received
            SPDR =  testers[bytenr];       
        }
    }
    
}



 

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

I don't see any chip select operation in the code or in the logic analyzer display.

 

With AVR spi, you have to handle chip select in code; it does not happen automatically.

 

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

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

i have a chip select (i thinkwink)

 

in the master code its PINC5,... that is connected to the SS (PINB4) (atmega 16).

on the LA display it is the blue line (SS_TSOP)

 

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

I don't see any activity on the blue line. I see where it is made low, then high in the master code, now. But the blue line (number 6 from top) shows no change. Do you have the right pin connected?

 

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

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

no its the bleu line on the bottem, its a litle bit strange.

the name is SS_TSOP

Last Edited: Sun. Aug 18, 2019 - 07:45 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

when i'am correct, then i interpret this part of the datasheet, that the transmission of the byte in the SPDR (from the master) is started as soon the SS is driven low. because the MOSI line is in sync whit the clock pulses.

am i wright whit that ?

 

from datasheet:

when pulling low the Slave Select SS pin of the desired Slave. Master and
Slave prepare the data to be sent in their respective Shift Registers, and the Master generates
the required clock pulses on the SCK line to interchange data

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

trixo wrote:
when i'am correct, then i interpret this part of the datasheet, that the transmission of the byte in the SPDR (from the master) is started as soon the SS is driven low

 

If you read a bit further it says :

 

When configured as a Master, the SPI interface has no automatic control of the SS line. This
must be handled by user software before communication can start. When this is done, writing a
byte to the SPI Data Register starts the SPI clock generato
r, and the hardware shifts the eight
bits into the Slave.

 

I don't know what it is with the timing that you think appears random, it looks pretty regular to me.

You haven't said which devices you are using.

Presumably master is different device to slave since you have diferent pins

Master

	DDRB |= (1<<PINB1)|(1<<PINB2)|(1<<PINB0);    // SCK, MOSI and SS as outputs

Slave

    DDRB &= ~((1<<PINB7)|(1<<PINB5)|(1<<PINB4));   // SCK, MOSI and SS as inputs

 

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

master: atmega 128

slave:    atmega 16A

 

i,am gonna check one thing on the hardware wright now.

 

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

what i don't understand exactly:

i expected that when the SS goes low, the first byte i gonna see on the MISO is 0x255 because that is the first byte in the array. than i expected to see the 2e that is 0x00 and than the third that is 0x255 and so on.

 

but now i see when the SS goes low: first a number of bytes with 0x00 (number of bytes is random) and then i see the first byte of the array en then the 2e and so on.

 

but i did a test:

when i changes in the slave this:

for (bytenr=0; bytenr<38; bytenr++)
{            
   while(!(SPSR & (1<<SPIF)));    // wait until all data is received              
   SPDR =  testers[bytenr];       // hurray, we now have our data
}

for

for (bytenr=0; bytenr<38; bytenr++)
{			
   while(!(SPSR & (1<<SPIF)));    // wait until all data is received	 
   SPDR = 0b11110000;
}

than its working so i expected. SS goes low and than comes on the first clock pulses the byte 0b11110000.

 

so now i,am thinking that it is not a SPI problem but some problem whit the array.

 

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

maybe i may kick this 1 time.

i hope someone see what is going wrong. 

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

I think the first byte returned by slave after slave is powered up will be whatever value happens to be in SPDR after power up, since you haven't written to SPDR yet.

After that, it should follow the values in the array.

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

This code seems backwards to me:

 for (bytenr=0; bytenr<38; bytenr++)
        {
            while(!(SPSR & (1<<SPIF)));    // wait until all data is received
            SPDR =  testers[bytenr];
        }

Normally you would write the data to data register and then wait for it to be sent.

Note comment is mis-leading as well, your sending data, not receiving it!!!

Jim

 

 

(Possum Lodge oath) Quando omni flunkus, moritati.

"I thought growing old would take longer"

 

Last Edited: Mon. Aug 19, 2019 - 07:58 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MrKendo wrote:

I think the first byte returned by slave after slave is powered up will be whatever value happens to be in SPDR after power up, since you haven't written to SPDR yet.

After that, it should follow the values in the array.

 

ok, but that wil give 1 bytes whit corrupt data. but in my case is the number of byte random (the bytes extra before the array are always 0x00)

 

edit: switching the 2 lines will like mrkendo says make no diference.

Last Edited: Tue. Aug 20, 2019 - 04:42 PM