1
\$\begingroup\$

I'm wondering what the best way to handle SPI transactions when using interrupts is.

I'm about to write my SPI interface code to an external flash part using a PIC. I'm going to use interrupts and I know that I'll get one after my byte is transferred, and after one is received. A typical 16 bit write transaction will look like this:

REGISTER_ADDRESS_BYTE | REGISTER_ADDRESS_BYTE | DATA_BYTE | DATA_BYTE | MAYBE_MORE_DATA_BYTES

Typically what I do is have a function like this pseudo code:

SendBytes(num_bytes, *ptr_to_bytes, address, init_true, callback_function_address);

Then in my SendBytes(...) I have a state machine with two static variables, one keeps track of the state, the other keeps track of the number of bytes sent. As interrupts come in I call SendBytes(...) again with init_false and step through my state machine for each byte of the transaction. When I'm all done I either stop or call the stored call_back_function.

My question is this a decent way to handle this, is there a better way using interrupts? I just made this up thinking about the problem but I assume others have had to handle this as well.

Nick Alexeev
38.9k17 gold badges104 silver badges248 bronze badges
asked Jan 10, 2015 at 19:03
\$\endgroup\$
4
  • \$\begingroup\$ Let me back up and ask you: why do you want to use interrupt for doing the SPI master? Polling for flags (without interrupt) is another option. Polling tends to be simpler, arguably. \$\endgroup\$ Commented Jan 10, 2015 at 19:54
  • \$\begingroup\$ I agree that polling is easier but I want to do other real time things while my spi command is running across my relatively slow spi bus. \$\endgroup\$ Commented Jan 10, 2015 at 20:47
  • 4
    \$\begingroup\$ It seems odd to use the same function to initiate transfers and to handle the interrupts. Wouldn't it be cleaner to have separate functions? \$\endgroup\$ Commented Jan 10, 2015 at 21:33
  • \$\begingroup\$ Sure I could use two functions, I'm more curious about the state machine and static variable for state approach though. \$\endgroup\$ Commented Jan 11, 2015 at 5:36

1 Answer 1

1
\$\begingroup\$

You didn't mention the PIC variant; SPI peripherals as well as interrupt controllers are different in different PICs. Here is an example of handling similar problem using PIC16:

https://github.com/felis/DMCI-XC8/blob/master/bsp.c#L91

It also shows state machine approach.

answered Jan 12, 2015 at 1:18
\$\endgroup\$
4
  • 3
    \$\begingroup\$ Can you sumarrize that a bit? Link - only answers die when the link dies. \$\endgroup\$ Commented Jan 12, 2015 at 1:29
  • \$\begingroup\$ summarize what? And what is wrong with a link? \$\endgroup\$ Commented Jan 12, 2015 at 1:54
  • 2
    \$\begingroup\$ Summarize your approach. What's wrong with links is that they can die, so a link should not be a the only piece of information in the answer. More about link-only answers in this post on meta.SE . \$\endgroup\$ Commented Jan 12, 2015 at 1:59
  • \$\begingroup\$ I have a queue which is consumed by an interrupt. When I put [the first] byte into [an empty] queue I set the interrupt [enable] flag. Actions in square brackets are architecture dependent, on some PICs it's better to disable the interrupt for the given peripheral (can't be done on PIC16). \$\endgroup\$ Commented Jan 12, 2015 at 2:24

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.