0

It is possible to wake sensor nodes on external interrupts that are generated by peripheral sensors. The following explains how Contiki OS handles external interrupts. In case of the ATmega128RFA1 the external interrupts INT0 to INT4 are able to wake the MCU even from deep sleep.

user3071284
  • 6,955
  • 6
  • 43
  • 57
ralf htp
  • 9,149
  • 4
  • 22
  • 34

1 Answers1

2

an overview over processes and interupts in contiki is here:

https://github.com/contiki-os/contiki/wiki/Processes

http://de.slideshare.net/DingxinXu/contiki-introduction-iifrom-what-to-how

http://senstools.gforge.inria.fr/doku.php?id=os:contiki

contiki utilizes the ISR vectors of the MCU

this example is for ATmega128RFA1. the external interrupt is INT0 on PD0 (pin 25)

in the ISR the only action is to poll an associated contiki process. Internally this sends a poll request to the process. The process catches the poll request and then executes the calculations associated with the external interrupt. This proceeding prevents long lasting calculations in the ISR.

ISR :

ISR(INT0_vect)
{            

  process_poll(&extern_interupt_process);
  PRINTF("interrupt was triggered on INT0... \n");  

}

to enable the external interupts on INT0:

EIMSK = 0xb00000000; //disable interrupts before changing EICRA EICRA |= 0xb00000011; //EICRA 0000|0011 rising edge triggers interrupt int0 EIMSK |= 0xb00000001; // enable INT0 (datasheet p. 219 ff)

process :

PROCESS(extern_interupt_process, "external_interrupt_process");

PROCESS_THREAD(extern_interupt_process, ev, data)
{


  PROCESS_BEGIN();


  while(1) {

    PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL);

    // process data here 

           }


  PROCESS_END();

}

use autostart_process() to start the extern_interrupt_process or start it manually in contiki-main.c

if the sensor has an open collector output activate the internal pull-up resistor and set the interrupt control register to trigger an interrupt on low-level (see this: wiring a sensor with open collector output)

DDRD  &= 0xb00000000;   // PD0 as input
PORTD |= 0xb00000001;  // enable internal pull-up on PD0
EIMSK &= 0xb00000000; //disable interrupts before changing EICRA
EICRA &= 0xb00000000; //EICRA 0000|0000 low-level triggers interrupt on int0
EIMSK |= 0xb00000001; // enable INT0` (datasheet p. 219 ff)

http://en.wikipedia.org/wiki/Open collector

ralf htp
  • 9,149
  • 4
  • 22
  • 34
  • 1
    On some platforms you also need to clear some status register bits to avoid going back to sleep mode after the interrupt handler is executed. – kfx Nov 23 '15 at 12:33