Subversion Repositories Code-Repo

Rev

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

#include <xc.h>
#include <plib.h>
#include "defines.h"
#include "TIMER4.h"

static TIMER4_DATA *timer_data_ptr;

void TIMER4_Init(TIMER4_DATA *data, void (*callback)(void), unsigned int time_us) {
    if (data != NULL) // if ptr is null, use existing data
        timer_data_ptr = data;

    timer_data_ptr->callback_function = callback;

    INTDisableInterrupts();

    T4CON = 0x0;

    // PR5 is 16 bits wide, so we need to determine what pre-scaler to use
    int time;
    if (time_us < 13107) {
        time = 5 * time_us;
        T4CONSET = 0x0040;         // Prescaler at 1:16
    } else if (time_us < 26214) {
        time = 2.5 * time_us;
        T4CONSET = 0x0050;         // Prescaler at 1:32
    } else if (time_us < 52428) {
        time = 1.25 * time_us;
        T4CONSET = 0x0060;         // Prescaler at 1:64
    } else { // Minimum time_us of 209712
        time = 0.3125 * time_us;
        T4CONSET = 0x0070;         // Prescaler at 1:256
    }

    Nop();
    TMR4 = 0x0;             // Clear timer register
    PR4 = time;             // Load period register
    IPC4SET = 0x00000011;   // Set priority level = 4, sub-priority level = 1
    IFS0CLR = 0x00010000;   // Clear timer interrupt flag
    IEC0SET = 0x00010000;   // Enable timer interrupt

    INTEnableInterrupts();
}

void TIMER4_Start(void) {
    T4CONSET = 0x8000; // Start timer
}

void TIMER4_Stop(void) {
    T4CONCLR = 0x8000; // Stop timer
}

void __ISR(_TIMER_4_VECTOR, ipl4) __TIMER_4_Interrupt_Handler(void) {
    // Call the saved callback function
    (*timer_data_ptr->callback_function)();

    IFS0CLR = 0x00010000; // Clear the timer interrupt flag
}