Master SPI on Mega88 not working

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

Hi all,

I am testing SPI master on my experimental board with this code

//Avrstudio 4.14.589
//Winavr 20071221
//f_osc=8MHz

#include              
#include          

#define ddr_spi    DDRB      
#define port_spi   PORTB     
#define pin_ss     PB6       
#define pin_mosi   PB3       
#define pin_miso   PB4       
#define pin_sck    PB5       


//---------------------------------------------------------------------------
void SPI_MasterInit(void)
{
   ddr_spi   = ((1<<pin_mosi)|(1<<pin_sck));    // MOSI, SCK = 1
   SPCR      = ((1<<SPE)|(1<<MSTR)|(1<<SPR0) | (1<<SPR1));  // Enable SPI, master, prescaler 128
}


//---------------------------------------------------------------------------
void SPI_MasterTransmit(char cData)
{
      SPDR =   cData;               // Load byte to output register
      while(!(SPSR&(1<<SPIF)));     // Wait for byte to be sent
}


//---------------------------------------------------------------------------
int main (void)
{   
   DDRC = 255;
   SPI_MasterInit();                

   while(1)                         
   {
      PORTC ^= 255;                 // Led
      _delay_ms(500);
      SPI_MasterTransmit('U');      
   }
} 

No slave is connected.

I see no activity on MOSI and CLK pins.
Led on portC does not blink.

When I comment line
while(!(SPSR&(1<<SPIF)));
the Led starts blinking.

I tested with m8 and m88 with the same result.

My question:
I think this master should send data even though no slave is connected.
Am I right?

Thanks

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

Looks like the standard SPI 'gotcha'...you need to set the /SS pin as an output in DDRB, even if you don't use it...

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

MartinM57 wrote:
Looks like the standard SPI 'gotcha'...you need to set the /SS pin as an output in DDRB, even if you don't use it...

I have tested with SS output low but did not help.

Thanks anyway.

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

Quote:
Looks like the standard SPI 'gotcha'...you need to set the /SS pin as an output in DDRB, even if you don't use it...

No,
1. There is no need for the CS to belong to a specific pin. In master mode the CS pin can be any output pin of the microcontroller.
2. There is also no need of CS existance in order for the MOSI and CLK to be functional.

The AVR SS pin is there to use it only in SPI Slave mode. This pin will make the sense to the slave whenever the SPI master talks to it.

Michael.

User of:
IAR Embedded Workbench C/C++ Compiler
Altium Designer

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

icarus1 wrote:
Quote:
No,
1. There is no need for the CS to belong to a specific pin. In master mode the CS pin can be any output pin of the microcontroller.

2. The AVR SS pin is there to use it only in SPI Slave mode. This pin will make the sense to the slave whenever the SPI master talks to it.

1. Agreed

2.Not to my understanding or experience, having suffered from exactly the OP's scenario.

We are talking about the specific SPI /SS pin on the AVR, which when the AVR is acting as a master, MUST be set as an output (or else the AVR goes into Slave mode and sends out no SPI signals).

But of course I might be have completely the wrong end of the stick...

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

Quote:
We are talking about the specific SPI /SS pin on the AVR, which when the AVR is acting as a master, MUST be set as an output (or else the AVR goes into Slave mode and sends out no SPI signals).

Martin, No. I am sure there is no need of using nor setting as output of the specific SPI/SS pin, while the SPI is set as master.

I am sure for this once because the datasheet says it and twice because I have test it. Altought I have used different uC to make the tests (AT90USB647), I believe that the mechanism is exactly the same.

Michael.

User of:
IAR Embedded Workbench C/C++ Compiler
Altium Designer

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

icarus1, for the Mega88 in question you are wrong. /SS can be an input but then it must stay high.

Quote:
If SS is configured as an input, it must be held high to ensure Master SPI operation.
This is a feature allowing multi master support (I wonder if anyone actually make use of it).
/Lars

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

icarus1 wrote:
Quote:
We are talking about the specific SPI /SS pin on the AVR, which when the AVR is acting as a master, MUST be set as an output (or else the AVR goes into Slave mode and sends out no SPI signals).

Martin, No. I am sure there is no need of using nor setting as output of the specific SPI/SS pin, while the SPI is set as master.

I am sure for this once because the datasheet says it and twice because I have test it. Altought I have used different uC to make the tests (AT90USB647), I believe that the mechanism is exactly the same.

The Atmega88 data sheet specifically says that when the SPI controller is in Master mode and the SS pin is set as input, it must be held high or it will be interpreted as an attempt by another master to send data to it, and revert to slave mode.

See page 167 of the Atmega48/88/168 data sheet.

kevin

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

Visovian wrote:
MartinM57 wrote:
Looks like the standard SPI 'gotcha'...you need to set the /SS pin as an output in DDRB, even if you don't use it...

I have tested with SS output low but did not help.

I have to apologize.
I had set SS => portb.6
instead SS => portb.2

Now it works. Problem really was in SS pin.
It is to be set either as output or as input high.

Thank you all for your help!!

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

Ok,

After all, everybody learned. I am sorry I was wrong.

Michael.

User of:
IAR Embedded Workbench C/C++ Compiler
Altium Designer

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

Dear MartinM57, thanks for the hint with defining the !SS even if it is not used. You saved me an evening :-)

 

Regards

Karel