21 #define TIMER_MODE_START 0x00000001
22 #define TIMER_MODE_HANDLER 0x00000002
33 timer_alarm_handler_t callback_handler;
35 void *callback_handler_arg;
41 vu64 timer_handled_count;
43 vu32 timer_counter_total;
44 vu32 timer_counter_used;
45 counter_struct_t *timer_counter_buf_free;
46 counter_struct_t *timer_counter_buf_alarm;
47 vs32 current_handling_timer_id;
50 #define PTR_TO_TIMER_ID(ptr_) ((s32)((((uiptr)(ptr_)) << 4) | ((ptr_)->timer_key)))
51 #define TIMER_ID_TO_PTR(id_) ((counter_struct_t *)((((uiptr)(id_)) >> 10) << 6))
52 #define TIMER_ID_IS_VALID(id_) ((TIMER_ID_TO_PTR(id_) != NULL) && ((siptr)(id_) >= 0) && (((uiptr)(id_) & 0x3FF) == ((TIMER_ID_TO_PTR(id_))->timer_key)))
55 extern void ForTimer_InitAlarm(
void);
57 extern void SetT2(
volatile void *ptr, u32 val);
58 extern void SetT2_COUNT(u32 val);
59 extern void SetT2_MODE(u32 val);
60 extern void SetT2_COMP(u32 val);
61 extern void InsertAlarm_ForTimer(counter_struct_t *timer_link);
62 extern counter_struct_t *UnlinkAlarm_ForTimer(counter_struct_t *timer_unlink);
63 extern s32 TimerHandler_callback(s32 cause,
void *arg,
void *addr);
65 #define COUNTER_COUNT 128
69 .timer_handled_count = 0,
71 .timer_counter_total = 1,
72 .timer_counter_used = 0,
73 .timer_counter_buf_free = NULL,
74 .timer_counter_buf_alarm = NULL,
75 .current_handling_timer_id = -1,
83 #ifdef F__ps2sdk_init_timer
88 if (&_ps2sdk_init_timer_impl)
90 _ps2sdk_init_timer_impl();
95 #ifdef F__ps2sdk_deinit_timer
100 if (&_ps2sdk_deinit_timer_impl)
102 _ps2sdk_deinit_timer_impl();
108 void SetT2(
volatile void *ptr, u32 val)
111 *((
volatile u32 *)ptr) = val;
117 void SetT2_COUNT(u32 val)
119 SetT2((
volatile void *)K_T2_COUNT, val);
124 void SetT2_MODE(u32 val)
126 SetT2((
volatile void *)K_T2_MODE, val);
131 void SetT2_COMP(u32 val)
133 SetT2((
volatile void *)K_T2_COMP, val);
144 if (g_Timer.intc_handler >= 0)
148 g_Timer.timer_handled_count = 0;
149 g_Timer.timer_counter_used = 0;
150 memset(g_CounterBuf, 0,
sizeof(g_CounterBuf));
151 g_Timer.timer_counter_buf_free = &g_CounterBuf[0];
152 for (u32 i = 0; i < ((
sizeof(g_CounterBuf) /
sizeof(g_CounterBuf[0])) - 1); i += 1)
154 g_CounterBuf[i].timer_next = &g_CounterBuf[i + 1];
156 g_CounterBuf[(
sizeof(g_CounterBuf) /
sizeof(g_CounterBuf[0])) - 1].timer_next = NULL;
157 ForTimer_InitAlarm();
158 handler = AddIntcHandler2(INTC_TIM2, TimerHandler_callback, 0, NULL);
163 g_Timer.intc_handler = handler;
165 mode = ((*T2_MODE) & (~0x3)) | in_mode;
166 mode |= (1 << 9) | (1 << 8);
167 if ((mode & (1 << 7)) == 0)
170 mode |= (1 << 11) | (1 << 10);
175 EnableIntc(INTC_TIM2);
189 if (g_Timer.intc_handler < 0)
193 if (g_Timer.timer_counter_used != 0)
198 if (RemoveIntcHandler(INTC_TIM2, g_Timer.intc_handler) == 0)
200 DisableIntc(INTC_TIM2);
201 SetT2_MODE((1 << 11) | (1 << 10));
204 g_Timer.timer_handled_count = 0;
205 g_Timer.intc_handler = -1;
214 #ifdef F_GetTimerPreScaleFactor
215 s32 GetTimerPreScaleFactor(
void)
217 if (g_Timer.intc_handler < 0)
221 return (*T2_MODE) & 3;
225 #ifdef F_StartTimerSystemTime
237 if (((*T2_MODE) & (1 << 7)) != 0)
247 SetT2_MODE(((*T2_MODE) & (~((1 << 11) | (1 << 10)))) | (1 << 7));
248 SetNextComp(iGetTimerSystemTime());
258 #ifdef F_StopTimerSystemTime
270 if (((*T2_MODE) & (1 << 7)) != 0)
272 SetT2_MODE((*T2_MODE) & (~((1 << 11) | (1 << 10))));
291 #define CLOCKS_GAP 0x200 // For assuring the timer interrupt is triggered
292 void SetNextComp(u64 time_now)
294 u64 current_schedule, next_schedule;
295 counter_struct_t *timer_current;
297 if (g_Timer.current_handling_timer_id >= 0)
301 timer_current = g_Timer.timer_counter_buf_alarm;
302 if (timer_current == NULL)
305 SetT2_MODE((*T2_MODE) & (~(1 << 11)));
308 current_schedule = timer_current->timer_schedule + timer_current->timer_base_time - timer_current->timer_base_count;
309 timer_current = timer_current->timer_next;
312 while (timer_current != NULL)
314 next_schedule = timer_current->timer_schedule + timer_current->timer_base_time - timer_current->timer_base_count;
315 if (next_schedule < (current_schedule + CLOCKS_GAP))
317 current_schedule = next_schedule;
323 timer_current = timer_current->timer_next;
325 if (current_schedule < (time_now + CLOCKS_GAP))
327 SetT2_COMP((*T2_COUNT) + (CLOCKS_GAP >> (((*T2_MODE) & 3) << 2)));
328 SetT2_MODE((*T2_MODE) & (~(1 << 11)));
332 SetT2_MODE((*T2_MODE) & (~(1 << 11)));
333 SetT2_COMP(current_schedule >> (((*T2_MODE) & 3) << 2));
338 #ifdef F_InsertAlarm_ForTimer
339 void InsertAlarm_ForTimer(counter_struct_t *timer_link)
341 counter_struct_t *timer_current;
342 counter_struct_t *timer_next;
345 abs_cmp = timer_link->timer_schedule + timer_link->timer_base_time - timer_link->timer_base_count;
346 timer_current = NULL;
347 timer_next = g_Timer.timer_counter_buf_alarm;
348 while (timer_next != NULL)
350 u64 target_cmp = timer_next->timer_schedule + timer_next->timer_base_time - timer_next->timer_base_count;
351 if (abs_cmp < target_cmp)
355 timer_current = timer_next;
356 timer_next = timer_next->timer_next;
358 timer_link->timer_previous = timer_current;
359 timer_link->timer_next = timer_next;
360 if (timer_next != NULL)
362 timer_next->timer_previous = timer_link;
364 if (timer_current != NULL)
366 timer_current->timer_next = timer_link;
370 g_Timer.timer_counter_buf_alarm = timer_link;
375 #ifdef F_UnlinkAlarm_ForTimer
376 counter_struct_t *UnlinkAlarm_ForTimer(counter_struct_t *timer_unlink)
378 counter_struct_t *timer_next;
380 timer_next = timer_unlink->timer_next;
381 if (timer_unlink->timer_previous)
383 timer_unlink->timer_previous->timer_next = timer_next;
387 g_Timer.timer_counter_buf_alarm = timer_unlink->timer_next;
389 if (timer_next != NULL)
391 timer_next->timer_previous = timer_unlink->timer_previous;
393 timer_unlink->timer_previous = NULL;
398 #ifdef F_TimerHandler_callback
399 static inline u64 ApplyOverflow(
void)
401 u64 timer_system_time_now;
407 if ((mode & (1 << 11)) != 0)
409 g_Timer.timer_handled_count += 1;
410 SetT2_MODE(mode & (~(1 << 10)));
413 timer_system_time_now = (g_Timer.timer_handled_count << 16) | low;
414 timer_system_time_now = timer_system_time_now << ((mode & 3) << 2);
415 return timer_system_time_now;
418 s32 TimerHandler_callback(s32 cause,
void *arg,
void *addr)
420 counter_struct_t *timer_current;
421 counter_struct_t *timer_next;
425 u64 timer_schedule_next;
427 if (((*T2_MODE) & (1 << 10)) != 0)
429 timer_current = g_Timer.timer_counter_buf_alarm;
430 while (timer_current != NULL)
432 target_cmp = timer_current->timer_schedule + timer_current->timer_base_time - timer_current->timer_base_count;
433 abs_cmp = ApplyOverflow();
434 if (abs_cmp < target_cmp)
438 timer_next = UnlinkAlarm_ForTimer(timer_current);
439 timer_id = PTR_TO_TIMER_ID(timer_current);
440 g_Timer.current_handling_timer_id = timer_id;
441 SetGP(timer_current->gp_value);
442 timer_schedule_next = timer_current->callback_handler(
444 timer_current->timer_schedule,
445 (abs_cmp + timer_current->timer_base_count) - timer_current->timer_base_time,
446 timer_current->callback_handler_arg,
448 if (timer_schedule_next == 0)
450 timer_current->timer_mode &= ~TIMER_MODE_HANDLER;
452 else if (timer_schedule_next == (u64)-1)
454 timer_current->timer_next = g_Timer.timer_counter_buf_free;
455 g_Timer.timer_counter_buf_free = timer_current;
456 timer_current->timer_key = 0;
457 timer_current->timer_mode = 0;
458 g_Timer.timer_counter_used -= 1;
462 if (timer_schedule_next < 0x3999)
464 timer_schedule_next = 0x3999;
466 timer_current->timer_schedule += timer_schedule_next;
467 InsertAlarm_ForTimer(timer_current);
469 timer_current = timer_next;
472 g_Timer.current_handling_timer_id = -1;
473 SetNextComp(ApplyOverflow());
480 #ifdef F_iGetTimerSystemTime
489 u64 iGetTimerSystemTime(
void)
491 u64 timer_handled_count, timer_system_time_now;
496 timer_handled_count = g_Timer.timer_handled_count;
497 if ((mode & (1 << 11)) != 0)
499 timer_handled_count += 1;
502 timer_system_time_now = (timer_handled_count << 16) | low;
503 timer_system_time_now = timer_system_time_now << ((mode & 3) << 2);
504 return timer_system_time_now;
507 void _ps2sdk_init_timer_impl(
void)
510 StartTimerSystemTime();
513 void _ps2sdk_deinit_timer_impl(
void)
515 StopTimerSystemTime();
520 #ifdef F_GetTimerSystemTime
530 u64 GetTimerSystemTime(
void)
536 ret = iGetTimerSystemTime();
545 #ifdef F_iAllocTimerCounter
546 s32 iAllocTimerCounter(
void)
548 counter_struct_t *timer_current;
550 timer_current = g_Timer.timer_counter_buf_free;
551 if (timer_current == NULL)
555 g_Timer.timer_counter_buf_free = timer_current->timer_next;
556 g_Timer.timer_counter_used += 1;
557 timer_current->timer_mode = 0;
558 timer_current->callback_handler = NULL;
559 timer_current->timer_base_count = 0;
560 g_Timer.timer_counter_total += 1;
561 timer_current->timer_key = ((g_Timer.timer_counter_total << 1) & 0x3FE) | 1;
562 return PTR_TO_TIMER_ID(timer_current);
566 #ifdef F_AllocTimerCounter
567 s32 AllocTimerCounter(
void)
573 ret = iAllocTimerCounter();
582 #ifdef F_iFreeTimerCounter
583 s32 iFreeTimerCounter(s32
id)
585 counter_struct_t *timer_current;
587 timer_current = TIMER_ID_TO_PTR(
id);
588 if (!TIMER_ID_IS_VALID(
id))
592 if (g_Timer.current_handling_timer_id ==
id)
596 if ((timer_current->timer_mode & TIMER_MODE_HANDLER) != 0)
598 UnlinkAlarm_ForTimer(timer_current);
600 timer_current->timer_key = 0;
601 timer_current->timer_mode = 0;
602 timer_current->timer_next = g_Timer.timer_counter_buf_free;
603 g_Timer.timer_counter_buf_free = timer_current;
604 g_Timer.timer_counter_used -= 1;
609 #ifdef F_FreeTimerCounter
610 s32 FreeTimerCounter(s32
id)
616 ret = iFreeTimerCounter(
id);
625 #ifdef F_iGetTimerUsedUnusedCounters
626 s32 iGetTimerUsedUnusedCounters(u32 *used_counters, u32 *unused_counters)
628 if (g_Timer.intc_handler < 0)
632 if (used_counters != NULL)
634 *used_counters = g_Timer.timer_counter_used;
636 if (unused_counters != NULL)
638 *unused_counters = (
sizeof(g_CounterBuf) /
sizeof(g_CounterBuf[0])) - g_Timer.timer_counter_used;
644 #ifdef F_GetTimerUsedUnusedCounters
645 s32 GetTimerUsedUnusedCounters(u32 *used_counters, u32 *unused_counters)
651 ret = iGetTimerUsedUnusedCounters(used_counters, unused_counters);
660 #ifdef F_iStartTimerCounter
661 s32 iStartTimerCounter(s32
id)
663 counter_struct_t *timer_current;
664 u64 timer_system_time_now;
666 timer_current = TIMER_ID_TO_PTR(
id);
667 if (!TIMER_ID_IS_VALID(
id))
671 if (g_Timer.current_handling_timer_id ==
id)
675 if ((timer_current->timer_mode & TIMER_MODE_START) != 0)
679 timer_system_time_now = iGetTimerSystemTime();
680 timer_current->timer_base_time = timer_system_time_now;
681 timer_current->timer_mode |= TIMER_MODE_START;
682 if ((timer_current->timer_mode & TIMER_MODE_HANDLER) != 0)
684 InsertAlarm_ForTimer(timer_current);
685 SetNextComp(timer_system_time_now);
691 #ifdef F_StartTimerCounter
692 s32 StartTimerCounter(s32
id)
698 ret = iStartTimerCounter(
id);
707 #ifdef F_iStopTimerCounter
708 s32 iStopTimerCounter(s32
id)
710 counter_struct_t *timer_current;
711 u64 timer_system_time_now;
713 timer_current = TIMER_ID_TO_PTR(
id);
714 if (!TIMER_ID_IS_VALID(
id))
718 if (g_Timer.current_handling_timer_id ==
id)
722 if ((timer_current->timer_mode & TIMER_MODE_START) == 0)
726 timer_system_time_now = iGetTimerSystemTime();
727 timer_current->timer_base_count += timer_system_time_now - timer_current->timer_base_time;
728 timer_current->timer_mode &= ~TIMER_MODE_START;
729 if ((timer_current->timer_mode & TIMER_MODE_HANDLER) != 0)
731 UnlinkAlarm_ForTimer(timer_current);
732 SetNextComp(timer_system_time_now);
738 #ifdef F_StopTimerCounter
739 s32 StopTimerCounter(s32
id)
745 ret = iStopTimerCounter(
id);
754 #ifdef F_SetTimerCount
755 u64 SetTimerCount(s32
id, u64 timer_count)
757 counter_struct_t *timer_current;
760 u64 timer_system_time_now;
762 timer_current = TIMER_ID_TO_PTR(
id);
764 if ((!TIMER_ID_IS_VALID(
id)) || g_Timer.current_handling_timer_id ==
id)
772 ret = timer_current->timer_base_count;
773 if ((timer_current->timer_mode & TIMER_MODE_START) != 0)
775 timer_system_time_now = iGetTimerSystemTime();
776 ret += timer_system_time_now - timer_current->timer_base_time;
777 timer_current->timer_base_count = timer_count;
778 timer_current->timer_base_time = timer_system_time_now;
782 timer_current->timer_base_count = timer_count;
792 #ifdef F_iGetTimerBaseTime
793 u64 iGetTimerBaseTime(s32
id)
795 counter_struct_t *timer_current;
797 timer_current = TIMER_ID_TO_PTR(
id);
798 if (!TIMER_ID_IS_VALID(
id))
802 if ((timer_current->timer_mode & TIMER_MODE_START) == 0)
806 return timer_current->timer_base_time - timer_current->timer_base_count;
810 #ifdef F_GetTimerBaseTime
811 u64 GetTimerBaseTime(s32
id)
817 ret = iGetTimerBaseTime(
id);
826 #ifdef F_iGetTimerCount
827 u64 iGetTimerCount(s32
id)
830 counter_struct_t *timer_current;
832 timer_current = TIMER_ID_TO_PTR(
id);
833 if (!TIMER_ID_IS_VALID(
id))
837 ret = timer_current->timer_base_count;
838 if ((timer_current->timer_mode & TIMER_MODE_START) != 0)
840 ret += iGetTimerSystemTime() - timer_current->timer_base_time;
846 #ifdef F_GetTimerCount
847 u64 GetTimerCount(s32
id)
853 ret = iGetTimerCount(
id);
862 #ifdef F_iSetTimerHandler
863 s32 iSetTimerHandler(s32
id, u64 scheduled_time, timer_alarm_handler_t callback_handler,
void *arg)
865 counter_struct_t *timer_current;
867 timer_current = TIMER_ID_TO_PTR(
id);
868 if (!TIMER_ID_IS_VALID(
id))
872 if (g_Timer.current_handling_timer_id ==
id)
876 if ((timer_current->timer_mode & TIMER_MODE_HANDLER) != 0)
878 UnlinkAlarm_ForTimer(timer_current);
880 timer_current->callback_handler = callback_handler;
881 if (callback_handler == NULL)
883 timer_current->timer_mode &= ~TIMER_MODE_HANDLER;
887 timer_current->timer_schedule = scheduled_time;
888 timer_current->timer_mode |= TIMER_MODE_HANDLER;
889 timer_current->gp_value = GetGP();
890 timer_current->callback_handler_arg = arg;
891 if ((timer_current->timer_mode & TIMER_MODE_START) != 0)
893 InsertAlarm_ForTimer(timer_current);
896 SetNextComp(iGetTimerSystemTime());
901 #ifdef F_SetTimerHandler
902 s32 SetTimerHandler(s32
id, u64 scheduled_time, timer_alarm_handler_t callback_handler,
void *arg)
908 ret = iSetTimerHandler(
id, scheduled_time, callback_handler, arg);
917 #ifdef F_TimerBusClock2USec
918 void TimerBusClock2USec(u64 clocks, u32 *seconds_result, u32 *microseconds_result)
922 seconds = (u32)(clocks / kBUSCLK);
923 if (seconds_result != NULL)
925 *seconds_result = seconds;
927 if (microseconds_result != NULL)
929 *microseconds_result = (u32)(1000 * 1000 * (clocks - (((s64)(s32)((kBUSCLK * (u64)seconds) >> 32) << 32) | (u32)(kBUSCLK * seconds))) / kBUSCLK);
934 #ifdef F_TimerUSec2BusClock
935 u64 TimerUSec2BusClock(u32 seconds, u32 microseconds)
937 return (seconds * kBUSCLK) + (microseconds * (u64)kBUSCLK / (1000 * 1000));
941 #ifdef F_TimerBusClock2Freq
942 float TimerBusClock2Freq(s64 clocks)
944 return (
float)kBUSCLK / (float)clocks;
948 #ifdef F_TimerFreq2BusClock
949 u64 TimerFreq2BusClock(
float timer_frequency)
951 return (u64)((float)kBUSCLK / timer_frequency);