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
75 #ifdef F__ps2sdk_init_timer
80 if (&_ps2sdk_init_timer_impl)
82 _ps2sdk_init_timer_impl();
87 #ifdef F__ps2sdk_deinit_timer
92 if (&_ps2sdk_deinit_timer_impl)
94 _ps2sdk_deinit_timer_impl();
100 void SetT2(
volatile void *ptr, u32 val)
103 *((
volatile u32 *)ptr) = val;
109 void SetT2_COUNT(u32 val)
111 SetT2((
volatile void *)K_T2_COUNT, val);
116 void SetT2_MODE(u32 val)
118 SetT2((
volatile void *)K_T2_MODE, val);
123 void SetT2_COMP(u32 val)
125 SetT2((
volatile void *)K_T2_COMP, val);
136 if (g_Timer.intc_handler > 0)
140 g_Timer.timer_handled_count = 0;
141 g_Timer.timer_counter_used = 0;
142 g_Timer.timer_counter_total = 1;
143 g_Timer.current_handling_timer_id = -1;
144 memset(g_CounterBuf, 0,
sizeof(g_CounterBuf));
145 g_Timer.timer_counter_buf_free = &g_CounterBuf[0];
146 for (u32 i = 0; i < ((
sizeof(g_CounterBuf) /
sizeof(g_CounterBuf[0])) - 1); i += 1)
148 g_CounterBuf[i].timer_next = &g_CounterBuf[i + 1];
150 g_CounterBuf[(
sizeof(g_CounterBuf) /
sizeof(g_CounterBuf[0])) - 1].timer_next = NULL;
151 g_Timer.timer_counter_buf_alarm = NULL;
152 ForTimer_InitAlarm();
153 handler = AddIntcHandler2(INTC_TIM2, TimerHandler_callback, 0, NULL);
158 g_Timer.intc_handler = handler;
160 mode = ((*T2_MODE) & (~0x3)) | in_mode;
161 mode |= (1 << 9) | (1 << 8);
162 if ((mode & (1 << 7)) == 0)
165 mode |= (1 << 11) | (1 << 10);
170 EnableIntc(INTC_TIM2);
184 if (g_Timer.intc_handler < 0)
188 if (g_Timer.timer_counter_used != 0)
193 if (RemoveIntcHandler(INTC_TIM2, g_Timer.intc_handler) == 0)
195 DisableIntc(INTC_TIM2);
196 SetT2_MODE((1 << 11) | (1 << 10));
199 g_Timer.timer_handled_count = 0;
200 g_Timer.intc_handler = -1;
209 #ifdef F_GetTimerPreScaleFactor
210 s32 GetTimerPreScaleFactor(
void)
212 if (g_Timer.intc_handler < 0)
216 return (*T2_MODE) & 3;
220 #ifdef F_StartTimerSystemTime
232 if (((*T2_MODE) & (1 << 7)) != 0)
242 SetT2_MODE(((*T2_MODE) & (~((1 << 11) | (1 << 10)))) | (1 << 7));
243 SetNextComp(iGetTimerSystemTime());
253 #ifdef F_StopTimerSystemTime
265 if (((*T2_MODE) & (1 << 7)) != 0)
267 SetT2_MODE((*T2_MODE) & (~((1 << 11) | (1 << 10))));
286 #define CLOCKS_GAP 0x200 // For assuring the timer interrupt is triggered
287 void SetNextComp(u64 time_now)
289 u64 current_schedule, next_schedule;
290 counter_struct_t *timer_current;
292 if (g_Timer.current_handling_timer_id >= 0)
296 timer_current = g_Timer.timer_counter_buf_alarm;
297 if (timer_current == NULL)
300 SetT2_MODE((*T2_MODE) & (~(1 << 11)));
303 current_schedule = timer_current->timer_schedule + timer_current->timer_base_time - timer_current->timer_base_count;
304 timer_current = timer_current->timer_next;
307 while (timer_current != NULL)
309 next_schedule = timer_current->timer_schedule + timer_current->timer_base_time - timer_current->timer_base_count;
310 if (next_schedule < (current_schedule + CLOCKS_GAP))
312 current_schedule = next_schedule;
318 timer_current = timer_current->timer_next;
320 if (current_schedule < (time_now + CLOCKS_GAP))
322 SetT2_COMP((*T2_COUNT) + (CLOCKS_GAP >> (((*T2_MODE) & 3) << 2)));
323 SetT2_MODE((*T2_MODE) & (~(1 << 11)));
327 SetT2_MODE((*T2_MODE) & (~(1 << 11)));
328 SetT2_COMP(current_schedule >> (((*T2_MODE) & 3) << 2));
333 #ifdef F_InsertAlarm_ForTimer
334 void InsertAlarm_ForTimer(counter_struct_t *timer_link)
336 counter_struct_t *timer_current;
337 counter_struct_t *timer_next;
340 abs_cmp = timer_link->timer_schedule + timer_link->timer_base_time - timer_link->timer_base_count;
341 timer_current = NULL;
342 timer_next = g_Timer.timer_counter_buf_alarm;
343 while (timer_next != NULL)
345 u64 target_cmp = timer_next->timer_schedule + timer_next->timer_base_time - timer_next->timer_base_count;
346 if (abs_cmp < target_cmp)
350 timer_current = timer_next;
351 timer_next = timer_next->timer_next;
353 timer_link->timer_previous = timer_current;
354 timer_link->timer_next = timer_next;
355 if (timer_next != NULL)
357 timer_next->timer_previous = timer_link;
359 if (timer_current != NULL)
361 timer_current->timer_next = timer_link;
365 g_Timer.timer_counter_buf_alarm = timer_link;
370 #ifdef F_UnlinkAlarm_ForTimer
371 counter_struct_t *UnlinkAlarm_ForTimer(counter_struct_t *timer_unlink)
373 counter_struct_t *timer_next;
375 timer_next = timer_unlink->timer_next;
376 if (timer_unlink->timer_previous)
378 timer_unlink->timer_previous->timer_next = timer_next;
382 g_Timer.timer_counter_buf_alarm = timer_unlink->timer_next;
384 if (timer_next != NULL)
386 timer_next->timer_previous = timer_unlink->timer_previous;
388 timer_unlink->timer_previous = NULL;
393 #ifdef F_TimerHandler_callback
394 static inline u64 ApplyOverflow(
void)
396 u64 timer_system_time_now;
402 if ((mode & (1 << 11)) != 0)
404 g_Timer.timer_handled_count += 1;
405 SetT2_MODE(mode & (~(1 << 10)));
408 timer_system_time_now = (g_Timer.timer_handled_count << 16) | low;
409 timer_system_time_now = timer_system_time_now << ((mode & 3) << 2);
410 return timer_system_time_now;
413 s32 TimerHandler_callback(s32 cause,
void *arg,
void *addr)
415 counter_struct_t *timer_current;
416 counter_struct_t *timer_next;
420 u64 timer_schedule_next;
422 if (((*T2_MODE) & (1 << 10)) != 0)
424 timer_current = g_Timer.timer_counter_buf_alarm;
425 while (timer_current != NULL)
427 target_cmp = timer_current->timer_schedule + timer_current->timer_base_time - timer_current->timer_base_count;
428 abs_cmp = ApplyOverflow();
429 if (abs_cmp < target_cmp)
433 timer_next = UnlinkAlarm_ForTimer(timer_current);
434 timer_id = PTR_TO_TIMER_ID(timer_current);
435 g_Timer.current_handling_timer_id = timer_id;
436 SetGP(timer_current->gp_value);
437 timer_schedule_next = timer_current->callback_handler(
439 timer_current->timer_schedule,
440 (abs_cmp + timer_current->timer_base_count) - timer_current->timer_base_time,
441 timer_current->callback_handler_arg,
443 if (timer_schedule_next == 0)
445 timer_current->timer_mode &= ~TIMER_MODE_HANDLER;
447 else if (timer_schedule_next == (u64)-1)
449 timer_current->timer_next = g_Timer.timer_counter_buf_free;
450 g_Timer.timer_counter_buf_free = timer_current;
451 timer_current->timer_key = 0;
452 timer_current->timer_mode = 0;
453 g_Timer.timer_counter_used -= 1;
457 if (timer_schedule_next < 0x3999)
459 timer_schedule_next = 0x3999;
461 timer_current->timer_schedule += timer_schedule_next;
462 InsertAlarm_ForTimer(timer_current);
464 timer_current = timer_next;
467 g_Timer.current_handling_timer_id = -1;
468 SetNextComp(ApplyOverflow());
475 #ifdef F_iGetTimerSystemTime
484 u64 iGetTimerSystemTime(
void)
486 u64 timer_handled_count, timer_system_time_now;
491 timer_handled_count = g_Timer.timer_handled_count;
492 if ((mode & (1 << 11)) != 0)
494 timer_handled_count += 1;
497 timer_system_time_now = (timer_handled_count << 16) | low;
498 timer_system_time_now = timer_system_time_now << ((mode & 3) << 2);
499 return timer_system_time_now;
502 void _ps2sdk_init_timer_impl(
void)
505 StartTimerSystemTime();
508 void _ps2sdk_deinit_timer_impl(
void)
510 StopTimerSystemTime();
515 #ifdef F_GetTimerSystemTime
525 u64 GetTimerSystemTime(
void)
531 ret = iGetTimerSystemTime();
540 #ifdef F_iAllocTimerCounter
541 s32 iAllocTimerCounter(
void)
543 counter_struct_t *timer_current;
545 timer_current = g_Timer.timer_counter_buf_free;
546 if (timer_current == NULL)
550 g_Timer.timer_counter_buf_free = timer_current->timer_next;
551 g_Timer.timer_counter_used += 1;
552 timer_current->timer_mode = 0;
553 timer_current->callback_handler = NULL;
554 timer_current->timer_base_count = 0;
555 g_Timer.timer_counter_total += 1;
556 timer_current->timer_key = ((g_Timer.timer_counter_total << 1) & 0x3FE) | 1;
557 return PTR_TO_TIMER_ID(timer_current);
561 #ifdef F_AllocTimerCounter
562 s32 AllocTimerCounter(
void)
568 ret = iAllocTimerCounter();
577 #ifdef F_iFreeTimerCounter
578 s32 iFreeTimerCounter(s32
id)
580 counter_struct_t *timer_current;
582 timer_current = TIMER_ID_TO_PTR(
id);
583 if (!TIMER_ID_IS_VALID(
id))
587 if (g_Timer.current_handling_timer_id ==
id)
591 if ((timer_current->timer_mode & TIMER_MODE_HANDLER) != 0)
593 UnlinkAlarm_ForTimer(timer_current);
595 timer_current->timer_key = 0;
596 timer_current->timer_mode = 0;
597 timer_current->timer_next = g_Timer.timer_counter_buf_free;
598 g_Timer.timer_counter_buf_free = timer_current;
599 g_Timer.timer_counter_used -= 1;
604 #ifdef F_FreeTimerCounter
605 s32 FreeTimerCounter(s32
id)
611 ret = iFreeTimerCounter(
id);
620 #ifdef F_iGetTimerUsedUnusedCounters
621 s32 iGetTimerUsedUnusedCounters(u32 *used_counters, u32 *unused_counters)
623 if (g_Timer.intc_handler < 0)
627 if (used_counters != NULL)
629 *used_counters = g_Timer.timer_counter_used;
631 if (unused_counters != NULL)
633 *unused_counters = (
sizeof(g_CounterBuf) /
sizeof(g_CounterBuf[0])) - g_Timer.timer_counter_used;
639 #ifdef F_GetTimerUsedUnusedCounters
640 s32 GetTimerUsedUnusedCounters(u32 *used_counters, u32 *unused_counters)
646 ret = iGetTimerUsedUnusedCounters(used_counters, unused_counters);
655 #ifdef F_iStartTimerCounter
656 s32 iStartTimerCounter(s32
id)
658 counter_struct_t *timer_current;
659 u64 timer_system_time_now;
661 timer_current = TIMER_ID_TO_PTR(
id);
662 if (!TIMER_ID_IS_VALID(
id))
666 if (g_Timer.current_handling_timer_id ==
id)
670 if ((timer_current->timer_mode & TIMER_MODE_START) != 0)
674 timer_system_time_now = iGetTimerSystemTime();
675 timer_current->timer_base_time = timer_system_time_now;
676 timer_current->timer_mode |= TIMER_MODE_START;
677 if ((timer_current->timer_mode & TIMER_MODE_HANDLER) != 0)
679 InsertAlarm_ForTimer(timer_current);
680 SetNextComp(timer_system_time_now);
686 #ifdef F_StartTimerCounter
687 s32 StartTimerCounter(s32
id)
693 ret = iStartTimerCounter(
id);
702 #ifdef F_iStopTimerCounter
703 s32 iStopTimerCounter(s32
id)
705 counter_struct_t *timer_current;
706 u64 timer_system_time_now;
708 timer_current = TIMER_ID_TO_PTR(
id);
709 if (!TIMER_ID_IS_VALID(
id))
713 if (g_Timer.current_handling_timer_id ==
id)
717 if ((timer_current->timer_mode & TIMER_MODE_START) == 0)
721 timer_system_time_now = iGetTimerSystemTime();
722 timer_current->timer_base_count += timer_system_time_now - timer_current->timer_base_time;
723 timer_current->timer_mode &= ~TIMER_MODE_START;
724 if ((timer_current->timer_mode & TIMER_MODE_HANDLER) != 0)
726 UnlinkAlarm_ForTimer(timer_current);
727 SetNextComp(timer_system_time_now);
733 #ifdef F_StopTimerCounter
734 s32 StopTimerCounter(s32
id)
740 ret = iStopTimerCounter(
id);
749 #ifdef F_SetTimerCount
750 u64 SetTimerCount(s32
id, u64 timer_count)
752 counter_struct_t *timer_current;
755 u64 timer_system_time_now;
757 timer_current = TIMER_ID_TO_PTR(
id);
759 if ((!TIMER_ID_IS_VALID(
id)) || g_Timer.current_handling_timer_id ==
id)
767 ret = timer_current->timer_base_count;
768 if ((timer_current->timer_mode & TIMER_MODE_START) != 0)
770 timer_system_time_now = iGetTimerSystemTime();
771 ret += timer_system_time_now - timer_current->timer_base_time;
772 timer_current->timer_base_count = timer_count;
773 timer_current->timer_base_time = timer_system_time_now;
777 timer_current->timer_base_count = timer_count;
787 #ifdef F_iGetTimerBaseTime
788 u64 iGetTimerBaseTime(s32
id)
790 counter_struct_t *timer_current;
792 timer_current = TIMER_ID_TO_PTR(
id);
793 if (!TIMER_ID_IS_VALID(
id))
797 if ((timer_current->timer_mode & TIMER_MODE_START) == 0)
801 return timer_current->timer_base_time - timer_current->timer_base_count;
805 #ifdef F_GetTimerBaseTime
806 u64 GetTimerBaseTime(s32
id)
812 ret = iGetTimerBaseTime(
id);
821 #ifdef F_iGetTimerCount
822 u64 iGetTimerCount(s32
id)
825 counter_struct_t *timer_current;
827 timer_current = TIMER_ID_TO_PTR(
id);
828 if (!TIMER_ID_IS_VALID(
id))
832 ret = timer_current->timer_base_count;
833 if ((timer_current->timer_mode & TIMER_MODE_START) != 0)
835 ret += iGetTimerSystemTime() - timer_current->timer_base_time;
841 #ifdef F_GetTimerCount
842 u64 GetTimerCount(s32
id)
848 ret = iGetTimerCount(
id);
857 #ifdef F_iSetTimerHandler
858 s32 iSetTimerHandler(s32
id, u64 scheduled_time, timer_alarm_handler_t callback_handler,
void *arg)
860 counter_struct_t *timer_current;
862 timer_current = TIMER_ID_TO_PTR(
id);
863 if (!TIMER_ID_IS_VALID(
id))
867 if (g_Timer.current_handling_timer_id ==
id)
871 if ((timer_current->timer_mode & TIMER_MODE_HANDLER) != 0)
873 UnlinkAlarm_ForTimer(timer_current);
875 timer_current->callback_handler = callback_handler;
876 if (callback_handler == NULL)
878 timer_current->timer_mode &= ~TIMER_MODE_HANDLER;
882 timer_current->timer_schedule = scheduled_time;
883 timer_current->timer_mode |= TIMER_MODE_HANDLER;
884 timer_current->gp_value = GetGP();
885 timer_current->callback_handler_arg = arg;
886 if ((timer_current->timer_mode & TIMER_MODE_START) != 0)
888 InsertAlarm_ForTimer(timer_current);
891 SetNextComp(iGetTimerSystemTime());
896 #ifdef F_SetTimerHandler
897 s32 SetTimerHandler(s32
id, u64 scheduled_time, timer_alarm_handler_t callback_handler,
void *arg)
903 ret = iSetTimerHandler(
id, scheduled_time, callback_handler, arg);
912 #ifdef F_TimerBusClock2USec
913 void TimerBusClock2USec(u64 clocks, u32 *seconds_result, u32 *microseconds_result)
917 seconds = (u32)(clocks / kBUSCLK);
918 if (seconds_result != NULL)
920 *seconds_result = seconds;
922 if (microseconds_result != NULL)
924 *microseconds_result = (u32)(1000 * 1000 * (clocks - (((s64)(s32)((kBUSCLK * (u64)seconds) >> 32) << 32) | (u32)(kBUSCLK * seconds))) / kBUSCLK);
929 #ifdef F_TimerUSec2BusClock
930 u64 TimerUSec2BusClock(u32 seconds, u32 microseconds)
932 return (seconds * kBUSCLK) + (microseconds * (u64)kBUSCLK / (1000 * 1000));
936 #ifdef F_TimerBusClock2Freq
937 float TimerBusClock2Freq(s64 clocks)
939 return (
float)kBUSCLK / (float)clocks;
943 #ifdef F_TimerFreq2BusClock
944 u64 TimerFreq2BusClock(
float timer_frequency)
946 return (u64)((float)kBUSCLK / timer_frequency);