Is it possible to use SPI in interrupt and 'regular' code

My sketch uses an interrupt which is called every 50 microseconds. In the interrupt function I use SPI (the hardware SPI pins from the atmega328) to read flash memory. I was wondering if it is possible to use the same SPI-pins in the regular loop() function to communicate with another device - say a DAC - or might there be interference between the two parts of my sketch ?

Jack

Read this before posting a programming question

My sketch ...

What sketch?

In principle I don't see a problem except possibly a timing one. 50 uS isn't that much. Also you would need to ensure that the interrupt doesn't occur while you are in the middle of accessing your DAC.

Thank you for your reply.

I understand your remark regarding "my sketch" but the question is of more general nature. Please let me rephrase it:

I make use of an interrupt function. This will interrupt 'regular' program execution. Now my program basically breaks down to assembler codes for the processor, and program execution can jump to the interrupt-function after finishing any of these assembler instructions. This could mean for example that program execution jumps to the interrupt in the middle of a Serial.println()-statement.

Is this correct ? Because then your answer regarding the timing issues is enough for me to work on.

I did some extensive testing with a scope on my interrupt, it absorbs about 50 % of cpu time; all SPI access up till now is done from within the interrupt to prevent timing issues. However... the coding would be shorter and simpler if I could also use it from loop(); I might fix timing issues or double usage with some flags.

I have written a library that may help you here. The library allows a selection of ways to provide atomic operation to your code.

The 'Protect' function in particular helps with a single operations that cannot be interrupted:

BlockType::Protect( Serial.PrintLn )( "My Text" );

Or an object that when created locally, will provide a 'critical section' until it goes out of scope:

void Foo(){

  //This code can be interrupted.

  BlockType b;

  //This code cannot.
}

CaptainJack:
I understand your remark regarding "my sketch" but the question is of more general nature.

Oh well, if we are talking generally ...

You can "guard" code by putting noInterrupts () ... interrupts () around it.

I presume you have working the need to set the appropriate SS lines, as you say it is more-or-less working.

This could mean for example that program execution jumps to the interrupt in the middle of a Serial.println()-statement.

Virtually anywhere. Some code is already guarded to make sure that variables are accessed atomically. You may also need to do that.

Just be aware that doing X when interrupts are off will defer X until interrupts are re-enabled. Plus a timer interrupt may be queued as well. You may be reducing the window of time in which X (plus timers etc.) are done so small that you run out of time.

Gentlemen,

Thank you very much for the reply. I will study both the link and the library in further detail. The explanation in the link was exactly what I was looking for. The code is working fully, I'm just going over it again to see if I can simplify things.

Cheers !

Jack

ps @nick: that is an awfully big collection of notes you've got there, very nice !