Subversion Repositories Code-Repo

Rev

Rev 264 | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include "defines.h"
#include "TIMER4.h"

static TIMER4_DATA *timer_data_ptr;

void TIMER4_Init(TIMER4_DATA *data, void (*callback_ms)(void),
        void (*callback_div)(void), uint32_t time_ms) {
    
    if (data != NULL) // if ptr is null, use existing data
        timer_data_ptr = data;

    // The first callback function will be executed every ms
    timer_data_ptr->callback_function_1 = callback_ms;
    // The second callback function will be executed at the multiplier specified
    timer_data_ptr->callback_function_2 = callback_div;
    timer_data_ptr->divider = time_ms;
    timer_data_ptr->count = 0;

    INTDisableInterrupts();

    T4CON = 0x0;

    // Set timer to trigger every millisecond
    uint16_t time = 5000;
    T4CONSET = 0x0040;         // Prescaler at 1:16

    Nop();
    TMR4 = 0x0;             // Clear timer register
    PR4 = time;             // Load period register
    IPC4SET = 0x00000005;   // Set priority level = 1, 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
    if (timer_data_ptr->callback_function_1 != NULL)
        (*timer_data_ptr->callback_function_1)();

    if (timer_data_ptr->divider != 0 && timer_data_ptr->callback_function_2 != NULL) {
        if (timer_data_ptr->count == timer_data_ptr->divider) {
            (*timer_data_ptr->callback_function_2)();
            timer_data_ptr->count = 0;
        } else {
            timer_data_ptr->count++;
        }
    }

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