Subversion Repositories Code-Repo

Rev

Rev 114 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include "maindefs.h"
#include "timers.h"
#include "msg_queues.h"
#include "uart.h"
#include "i2c.h"
#include "adc.h"
#include "interrupts.h"
#include "xbee.h"
#include "pin_interrupts.h"

//----------------------------------------------------------------------------
// Note: This code for processing interrupts is configured to allow for high and
//       low priority interrupts.  The high priority interrupt can interrupt the
//       the processing of a low priority interrupt.  However, only one of each type
//       can be processed at the same time.  It is possible to enable nesting of low
//       priority interrupts, but this code is not setup for that and this nesting 
//       is not enabled.

void interrupt_init() {
    // Peripheral interrupts can have their priority set to high or low
    // Decide on the priority of the enabled peripheral interrupts (0 is low, 1 is high)

    // High priority interrupts
    IPR3bits.RC2IP = 1; // USART2 RX interrupt
    IPR1bits.SSPIP = 1; // I2C interrupt

    // Low priority interrupts
    //    IPR1bits.RC1IP = 0;      // USART1 RX interrupt
    INTCON2bits.TMR0IP = 0; // Timer0 interrupt
    IPR1bits.TMR1IP = 0;    // Timer1 interrupt
    IPR2bits.TMR3IP = 0;    // Timer3 interrupt
    //    IPR1bits.ADIP = 0;      // ADC interupt
    INTCON2bits.RBIP = 0;   // Port B interrupt
    INTCON3bits.INT1IP = 0; // INT1 interrupt
    
    // Enable I2C interrupt
    PIE1bits.SSPIE = 1;
    // Enable Port B interrupt
    INTCONbits.RBIE = 1;
    // Enable interrupt for INT1
    INTCON3bits.INT1IE = 1;
}

void interrupt_enable() {
    // Peripheral interrupts can have their priority set to high or low.
    // Enable both high-priority interrupts and low-priority interrupts
    RCONbits.IPEN = 1;
    INTCONbits.GIEH = 1;
    INTCONbits.GIEL = 1;
}

int interrupt_in_high_interrupt_routine() {
    return (!INTCONbits.GIEH);
}

int interrupt_low_int_active() {
    return (!INTCONbits.GIEL);
}

int interrupt_in_low_interrupt_routine() {
    if (INTCONbits.GIEL == 1) {
        return (0);
    } else if (interrupt_in_high_interrupt_routine()) {
        return (0);
    } else {
        return (1);
    }
}

int interrupt_in_main_routine() {
    if ((!interrupt_in_low_interrupt_routine()) && (!interrupt_in_high_interrupt_routine())) {
        return (1);
    } else {
        return (0);
    }
}

// Set up the interrupt vectors
void InterruptHandlerHigh();
void InterruptHandlerLow();

#pragma code InterruptVectorLow = 0x18

void InterruptVectorLow(void) {
    _asm
    goto InterruptHandlerLow //jump to interrupt routine
            _endasm
}

#pragma code InterruptVectorHigh = 0x08

void InterruptVectorHigh(void) {
    _asm
    goto InterruptHandlerHigh //jump to interrupt routine
            _endasm
}

//----------------------------------------------------------------------------
// High priority interrupt routine
// this parcels out interrupts to individual handlers

#pragma code
#pragma interrupt InterruptHandlerHigh

void InterruptHandlerHigh() {
    // We need to check the interrupt flag of each enabled high-priority interrupt to
    //  see which device generated this interrupt.  Then we can call the correct handler.

    // Check to see if we have an interrupt on USART2 RX
    if (PIR3bits.RC2IF) {
        DBG_PRINT_INT("INT: UART2 RX\r\n");
        // Call the interrupt handler
        uart_recv_interrupt_handler();

        // Clear the interrupt flag
        PIR3bits.RC2IF = 0;
    }

//    // Nofity the xbee to stop sending serial data
//    xbee_set_RTS(1);

    // Check to see if we have an I2C interrupt
    if (PIR1bits.SSPIF) {
        DBG_PRINT_INT("INT: I2C\r\n");
        // Call the handler
        i2c_interrupt_handler();

        // Clear the interrupt flag
        PIR1bits.SSPIF = 0;
    }

//     //Notify xbee to resume sending serial data
//    xbee_set_RTS(0);

    // The *last* thing I do here is check to see if we can
    // allow the processor to go to sleep
    // This code *DEPENDS* on the code in messages.c being
    // initialized using "init_queues()" -- if you aren't using
    // this, then you shouldn't have this call here
    //    MQ_sleep_high_interrupt_if_okay();
}

//----------------------------------------------------------------------------
// Low priority interrupt routine
// this parcels out interrupts to individual handlers
#pragma code
#pragma interruptlow InterruptHandlerLow
// This works the same way as the "High" interrupt handler

void InterruptHandlerLow() {
    // Check to see if we have an interrupt on INT1
    if (INTCON3bits.INT1IF) {
        DBG_PRINT_INT("INT: INT1\r\n");
        int1_interrupt_handler();

        INTCON3bits.INT1IF = 0;
    }

    // Check to see if we have an interrupt on any port B inputs <4:7>
    if (INTCONbits.RBIF) {
        DBG_PRINT_INT("INT: Port B\r\n");
        port_b_int_interrupt_handler();

        INTCONbits.RBIF = 0;
    }
    
    // Check to see if we have an interrupt on timer 0
    if (INTCONbits.TMR0IF) {
        DBG_PRINT_INT("INT: Timer 0\r\n");
        // Call the handler
        timer0_interrupt_handler();

        // Clear this interrupt flag
        INTCONbits.TMR0IF = 0;
    }

    // Check to see if we have an interrupt on timer 1
    if (PIR1bits.TMR1IF) {
        // Call the interrupt handler
        timer1_interrupt_handler();

        // Clear the interrupt flag
        PIR1bits.TMR1IF = 0;
    }

    // Check to see if we have an interrupt on timer 3
    if (PIR2bits.TMR3IF) {
        DBG_PRINT_INT("INT: Timer 3\r\n");
        timer3_interrupt_handler();

        PIR2bits.TMR3IF = 0;
    }
    
//        // Check to see if we have an interrupt on USART1 RX
//        if (PIR1bits.RC1IF) {
//            // Call the interrupt handler
//            uart_recv_interrupt_handler();
//
//            // Clear the interrupt flag
//            PIR1bits.RC1IF = 0;
//        }

//        // Check to see if we have an interrupt on ADC
//        if (PIR1bits.ADIF) {
//            // Call the interrupt handler
//            adc_interrupt_handler();
//
//            // Clear the interrupt flag
//            PIR1bits.ADIF = 0;
//        }
}