I have a task where I should do SPI transactions in interrupt mode. Means I have to handle data in IRQ handler (both for tx and rx bytes). How should I approach? I have a arduino board (2560) and a CAN shield (seeed studio) with SPI interface.

Edit: From the website: https://www.arduino.cc/en/reference/SPI

With most SPI devices, after SPI.beginTransaction(), you will write the slave select pin LOW, call SPI.transfer() any number of times to transfer data, then write the SS pin HIGH, and finally call SPI.endTransaction()

My question is - the function SPI.transfer() is handled in what way? Are the bytes transfered/received in interrupt handler or by polling?

  • Which Arduino board? That could make a difference. – Delta_G Aug 27 at 3:48
  • There are a lot of libraries. Your question is very broad. There are even multiple SPI and I2C libraries. You need to narrow your question down. What library are you concerned about? What do you mean do a transaction "in interrupt mode"? Do you mean, during an interrupt? Or that the transaction should use interrupts? – Nick Gammon Aug 27 at 4:09
  • Your question is so broad I suggest you read How to ask a good question for Arduino Stack Exchange. The answer to "are these libraries interrupt based or polling based" is, briefly, "it depends". So you need to narrow down the question to get a useful answer. – Nick Gammon Aug 27 at 4:17
  • @Delta_G added in the question – MANI Aug 27 at 6:12
  • @NickGammon yes. I know there are lot of libraries. That is the problem. I have edited the question. And yes "the transaction should use interrupts". Tell me if I have to narrow it more. – MANI Aug 27 at 6:16

I have a lengthy reference question about SPI which may help you.

To transfer outwards you do not need to use an interrupt. Nor is it polled. The data is simply placed in the SPI register and the hardware clocks the data out at the defined SPI rate.

To transfer inwards you are just reading the register. However to know when you need to read it, you would probably put the reading inside an interrupt routine.

I suggest you read the link above, and then if you want, you might expand your question more.

The source for the SPI transfer which I think applies to the Atmega2560 is as follows:

// Write to the SPI bus (MOSI pin) and also receive (MISO pin)
  inline static uint8_t transfer(uint8_t data) {
    SPDR = data;
     * The following NOP introduces a small delay that can prevent the wait
     * loop form iterating when running at the maximum speed. This gives
     * about 10% more speed, even if it seems counter-intuitive. At lower
     * speeds it is unnoticed.
    asm volatile("nop");
    while (!(SPSR & _BV(SPIF))) ; // wait
    return SPDR;

You can see that there is brief polling (the "while" line) for the register which the processor maintains to show whether the transmission has ended. Then the register is read and returned. So yes, there is polling there.

Now if you use an interrupt (see link above) then you will know that the flag has been set, and therefore there will be no delay (in the polling).

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.