Subversion Repositories Code-Repo

Rev

Blame | Last modification | View Log | RSS feed

#include "maindefs.h"
#include "uart.h"
#include "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
    IPR1bits.RC1IP = 1;     // USART1 RX interrupt
    IPR1bits.TX1IP = 1;     // USART1 TX interrupt
//    IPR3bits.RC2IP = 1; // USART2 RX interrupt
//    IPR1bits.SSPIP = 1; // I2C interrupt

    // Low priority interrupts
    
//    INTCON2bits.TMR0IP = 0; // Timer0 interrupt
//    IPR1bits.TMR1IP = 0;    // Timer1 interrupt
//    IPR2bits.TMR3IP = 0; // Timer 3 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 USART1 RX
    if (PIR1bits.RC1IF) {
        // Call the interrupt handler
        UART1_Recv_Interrupt_Handler();

        // Clear the interrupt flag
        PIR1bits.RC1IF = 0;

        return;
    }

    // Check to see if we have an interrupt on USART1 TX
    if (PIR1bits.TX1IF) {
        // Call the interrupt handler
        UART1_Send_Interrupt_Handler();
        
        // Clear the interrupt flag
        PIR1bits.TX1IF = 0;

        return;
    }
    
//    // 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_2_recv_interrupt_handler();
//
//        // Clear the interrupt flag
//        PIR3bits.RC2IF = 0;
//    }
    
//    // 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;
//    }
}

//----------------------------------------------------------------------------
// 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 ADC
//    if (PIR1bits.ADIF) {
//        // Call the interrupt handler
//        adc_interrupt_handler();
//
//        // Clear the interrupt flag
//        PIR1bits.ADIF = 0;
//    }
}