SPI in slave mode

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

I want to use the SPI in slave mode in my communication system. Chip is a 8515. I didn't find any information when the SPI interrupt flag (SPIF) is set in this case. Datasheet says that in master mode SPIF is set when SS is driven low...but is it the same when the slave mode is used?
Or can write the data into TX shift register and when the master sets SS low and starts clocking after the the bytes (TX and RX) are shifted the SPIF generates the interrupt?

thanks for your help, Daniel

admin's test signature
 

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

Hi Daniel,
the registers RX and TX are UART-registers, the SPI register is the SPDR(SPI-data-register).
Have a look page 42, SS pin functionality

Michael

admin's test signature
 

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

Hi Michael,
Thank you for your answer, but I wasn't talking about UART mode. The SPI in this AVR stuff has a data read register (buffer) that is loaded when received data is complete. So you have time to handle RX stuff during the next 8 bits are received. Unfortunately there is no TX buffer that can be filled in advance -- you have to use directly the output shift register.
Because I want to use the slave mode it's important to know when the interrupt (SPIF flag) occures to prepare new data to transmit. By the way, that is a very short time to do this -- the IAR compiler isn't able to implement useful interrupt functions (it does a lot of not needed moves) so this have to be done in assembler.
The AVR description only talks about master mode so I still don't know how to handle my TX data.
The slave mode is used because the communication master (StrongArm) uses DMA to transfer data -- in this environement it's not possible to use the AVR as a master.

thanks again, Daniel

admin's test signature
 

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

Daniel,

Michael wasn`t talking about UART mode either, just pointing out that when you were talking about TX and RX registers it sounded like *you* were... SPI doesn`t have RX/TX registers, just the single SPDR register which gets used for both incoming and outgoing data, so if you start talking about RX and TX, it sounds like you mean UART comms rather than SPI comms.

Anyway, in slave mode the SPIF bit is set once 8 bits have been shifted into SPDR, and if the SPIE bit in SPCR is set. Note that, in my copy of the 8515 datasheet at least, this is described immediately before the bit where it mentions the SS input in master mode. Once SPIF is set, you`re free to read/write SPDR. BTW, what sort of data rates are you looking at? We use the IAR compiler here, and I`ve never run into a problem doing interrupt driven SPI comms in master or slave mode on an 8MHz 8535, clocking the port at 500KHz (fcl/16).

As far as "not needed moves" go, I think you`ll find they are needed! The compiler only stores/loads registers that it uses within the ISR, and I don`t see how you could avoid doing the same in assembler - unless you don`t care about trashing their contents when you exit the ISR... Sure, you may be able to reduce the number of registers you use by rolling your own asm routine, but if you`re careful in the way you write your C (and in particular if you DON`T call any other functions from within the ISR), then you can get the register usage right down, with a corresponding drop in the number of store/load operations.

Chris

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

Hi Daniel,

you are right, the is no transmit buffer and you are unable to get an interrupt and put the next byte in the transmit shift register prior the last bit was sent.

So the only chance, the master must wait a certain time after every byte was received. Additional you must wait until any other interrupt was handled, since no different interrupt priority on the AVR.

One Example:
You have also enabled the interrupts INT0, timer1 capture, timer0 overflow. The maximum execution times of these are e.g. 50, 120, 200 cycle. Since all can occur simultaneous to your SPI transfer, but always handled prior it, your SPI can be delayed up to 50+120+200 = 270 cycle. Assuming further 30 cycle for the SPI interrupt itself, so the master must wait 300 cycle (= 75µs at 4MHz) until the next byte receive can be started.

There is no other way.
So SPI slave seems almost useless.

Peter

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

Hi Chris,

thank you for the answer. I suppose you mean 'when a serial transfer is complete, the SPIF is set.....' in the manual. I thougt that was only for the master mode -- but sure you are right, thanks for the hint!
Your question: we use 1.84 MHz serial clock (< 8MHz/4 spec). Because the StrongArm SPI -that is master- is controlled by DMA, the data stream is continual. In our hardware we use one first byte to select devices (the _SS for the AVR is generated this way, or for the DSPs the _CS lines are activated). Each second byte is filtered out for the AVR devices by hardware that means I have a pause of 4.4us to put data into SPDR. The read data register is no problem -- it's buffered. (For each device in this system we use a different protocol but always the same clock and data lines, so the AVRs are handled special with this pause bytes that are not needed when talking to a DSP).

I just started with this ATMEL AVRs and bought the IAR C-compiler. Using the latest version ICCAVR I had some problems because all samples are made for the older version ICCA90. Also the manual isn't optimal -- to find out how to use a register variable you will need a lot of phantasy. Of course this AVR stuff is fast, but in an interrupt routine I will have to use register vars -- 4.4us isn't a long time to fill 2 registers, isn't it?.
When I investigated the compiler generated code I saw that each register will be stored by Y-register, no PUSH or POP commands. OK, it's the same speed, but in assembler it's easier to do.

thanks again, good luck with your projects

Daniel

admin's test signature
 

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

Hi Peter,
...unfortunately I have to use slave mode --- but be sure, it's not possible to run other interrupts like timer stuff in this system. But I got the answer that the interrupt is generated in the end of a received byte (then the transmit shift register is empty too)..so I will try to do the best with this AVRs. In our (OK, OK, special system) the AVR's are handled different from other devices by hardware and a different protocol that filters out each 2nd byte, so I hope (...pffff...) the time is enough to fill the SPDR register immediately in the interrupt function.

thanks Daniel

admin's test signature
 

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

Hi Daniel,

sorry, but "I hope ..." was definitive not my programming style. My programming method was always "I'm sure ...".
Thus, why I count cycles if it was needed and always the maximum which possible (worst case conditions).

Peter

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

Hi Peter,

sure I will do it the same way as you do!
But at the moment I have no expierience with this compiler, It's absolutely necessary to count cycles in the interrupt function. I noticed that the AVR studio shows the time, so the control can be done in single step mode. (and this works fine also the additional cycles are considered when an external RAM is accessed).

admin's test signature