[En-Nut-Discussion] SPI in IRQ

Klaus Kloos klaus.kloos at gmx.de
Thu Feb 16 12:04:28 CET 2012

Hello Harald

Thanks for your fast answer.

> On 16.02.2012 08:22, Klaus Kloos wrote:
>> So I tried to use the NutOS functions. (*spiBus1At91.bus_alloc) and (*spiBus1At91.bus_release) are called outside the IRQ,  (*spiBus1At91.bus_transfer) is called at IRQ time.
>> The transfer of the 3 bytes last ca. 12us using 10MHz SPI. It is working, but unreliable. Sometimes my device freezes.
> Probably. In general, it is not allowed to call API functions in
> interrupt context, except NutEventPostFromIrq(). As a special exception
> it is possible to use stdio functions on a polling device, usually devDebug.
ok, i was aware that this is not the right way. It was only a test and it gave me a 'near to working' result :-) My hope was to get bus-transfer() IRQ save somehow......
What is necessary to make a function IRQ save?

>> What are my possibilities? Is there a recommended way to solve such time-critical SPI-requests?
>> Can I get the Nut/OS functions IRQ save somehow?
> Nut/OS allows to use native interrupt handlers. For the AT91 you can use
> static void MySpiIrqHandler(void) __attribute__ ((naked));
> void MySpiIrqHandler(void)
> {
>    IRQ_ENTRY();
> ...your code here...
>    IRQ_EXIT();
> }
> In your main code you need to write the address of the handler into the
> related AIC service routine register.
> outr(AIC_SVR(SPI0_ID), (unsigned int) MySpiIrqHandler);
Interesting, this might give me back the 1us which I loose between an IRQ and the calling of my IRQ-routine using the NutOS way.

But that's not the main problem. How do I get the SPI-Value in my 30us slot? I see these ways:
Is there a way to generate a fast context-switch from IRQ to the thread which is allowed to call bus_transfer()? Can this be done reliable in ca. 10us?
Then I can use the NutOS SPI routines.

An other way is the read the data in the IRQ. But then I have to code a function like bus_transfer() by myself (?). Not a nice chance...

A simple solution would be working without an IRQ and do everything in a thread without allowing a context-switch. So the sam7 will freeze for up to 50ms (i have to read 1000 values).

> And...not to forget...it is always a good idea to check the datasheet. ;-)
Not that I have completely memorized it, but Ive read it several times. The problem seems clear. Im too slow.
There is also a 128kSPS variant of the chip available. Then the time slot is less than 8us. Im happy that Im not forced to solve this problem....

Greetings Klaus

More information about the En-Nut-Discussion mailing list