03.11.2014 Views

QDK-nano PIC24/dsPIC-C30 - Quantum Leaps

QDK-nano PIC24/dsPIC-C30 - Quantum Leaps

QDK-nano PIC24/dsPIC-C30 - Quantum Leaps

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<strong>QDK</strong>-<strong>nano</strong><br />

<strong>PIC24</strong>/<strong>dsPIC</strong>-<strong>C30</strong><br />

www.state-machine.com/pic<br />

3.2.3 Assigning/Changing Interrupt Priorities in Software<br />

Each ISR in <strong>PIC24</strong>/<strong>dsPIC</strong> runs at a pre-configured IPL level. The default IPL level assigned to all ISRs out<br />

of reset is 4. It is strongly recommended, however, to assign priority to each used interrupt explicitly<br />

before enabling the interrupt. For example, the highlighted code in Listing 4 shows assigning the priority<br />

to the Timer2 interrupt in function QF_onStartup():<br />

Listing 4: Configuring interrupts in function QF_onStartup() (file bsp.c)<br />

#define TIMER2_ISR_PRIO 4<br />

. . .<br />

void QF_onStartup(void) { /* entered with interrupts locked */<br />

T2CON = 0; /* Use Internal Osc (Fcy), 16 bit mode, prescaler = 1 */<br />

TMR2 = 0; /* Start counting from 0 and clear the prescaler count */<br />

PR2 = BSP_TMR2_PERIOD - 1; /* set the timer period */<br />

_T2IP = TIMER2_ISR_PRIO; /* set Timer 2 interrupt priority */<br />

_T2IF = 0; /* clear the interrupt for Timer 2 */<br />

_T2IE = 1; /* enable interrupt for Timer 2 */<br />

T2CONbits.TON = 1; /* start Timer 2 */<br />

}<br />

NOTE: All ISRs that call QP services must have priorities not exceeding 6 (1 through 6). Priority 7 is<br />

reserved for the NMI, as described in Section 5.<br />

3.3 QP Idle Loop Customization in QF_onIdle()<br />

The cooperative “vanilla” kernel can very easily detect the situation when no events are available, in<br />

which case QF_run() calls the QF_onIdle() callback. You can use QF_onIdle() to suspended the CPU<br />

to save power, if your CPU supports such a power-saving mode. Please note that QF_onIdle() is called<br />

repetitively from the event loop whenever the event loop has no more events to process, in which case<br />

only an interrupt can provide new events. The QF_onIdle() callback is called with interrupts locked,<br />

because the determination of the idle condition might change by any interrupt posting an event.<br />

The <strong>PIC24</strong>/<strong>dsPIC</strong> CPU supports several power-saving levels (consult the data sheets of particular<br />

<strong>PIC24</strong>/<strong>dsPIC</strong> devices for details). The following piece of code shows the QF_onIdle() callback that puts<br />

<strong>PIC24</strong>/<strong>dsPIC</strong> into the IDLE power-saving mode. Please note that <strong>PIC24</strong>/<strong>dsPIC</strong> architecture allows for an<br />

atomic setting the low-power mode and enabling interrupts at the same time.<br />

Listing 5: QF_onIdle() for the non-preemptive (“vanilla”) QP-<strong>nano</strong> port to <strong>PIC24</strong>/<strong>dsPIC</strong><br />

(1) void QF_onIdle(void) { /* entered with int locked, NOTE01 */<br />

(2) LED_ON (IDLE_LED); /* blink the IDLE LED, see NOTE02 */<br />

(3) LED_OFF(IDLE_LED);<br />

(4) #ifdef NDEBUG<br />

(5) __asm__ volatile("disi #0x0001");<br />

(6) Idle(); /* transition to Idle mode, see NOTE03 */<br />

#else<br />

(7) QF_INT_UNLOCK(dummy); /* unlock interrupts, see NOTE01 */<br />

#endif<br />

}<br />

Copyright © <strong>Quantum</strong> <strong>Leaps</strong>, LLC. All Rights Reserved.<br />

13 of 29

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!