3,36 → 3,31 |
|
static TIMER4_DATA *timer_data_ptr; |
|
void TIMER4_Init(TIMER4_DATA *data, void (*callback)(void), uint32_t time_us) { |
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; |
|
timer_data_ptr->callback_function = callback; |
// 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; |
|
// PR4 is 16 bits wide, so we need to determine what pre-scaler to use |
uint16_t 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 { |
time = 0.3125 * time_us; // Minimum time_us of 209712 |
T4CONSET = 0x0070; // Prescaler at 1:256 |
} |
// 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 = 0x0000000D; // Set priority level = 3, sub-priority level = 1 |
IPC4SET = 0x00000005; // Set priority level = 1, sub-priority level = 1 |
IFS0CLR = 0x00010000; // Clear timer interrupt flag |
IEC0SET = 0x00010000; // Enable timer interrupt |
|
49,7 → 44,16 |
|
void __ISR(_TIMER_4_VECTOR, ipl4) __TIMER_4_Interrupt_Handler(void) { |
// Call the saved callback function |
(*timer_data_ptr->callback_function)(); |
(*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 |
} |