mirror of
https://github.com/rvtr/ctr_firmware.git
synced 2025-10-31 07:51:08 -04:00
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-09-30%20-%20paladin.7z/paladin/ctr_firmware@216 b871894f-2f95-9b40-918c-086798483c85
282 lines
8.4 KiB
C
282 lines
8.4 KiB
C
/*---------------------------------------------------------------------------*
|
||
Project: CtrBrom - libraries - OS
|
||
File: os_tick.c
|
||
|
||
Copyright 2008 Nintendo. All rights reserved.
|
||
|
||
These coded instructions, statements, and computer programs contain
|
||
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||
Company Ltd., and are protected by Federal copyright law. They may
|
||
not be disclosed to third parties or copied or duplicated in any form,
|
||
in whole or in part, without the prior written consent of Nintendo.
|
||
|
||
$Date:: $
|
||
$Rev$
|
||
$Author$
|
||
*---------------------------------------------------------------------------*/
|
||
#include <brom/os.h>
|
||
|
||
|
||
//----------------------------------------------------------------------
|
||
#ifdef SDK_ARM9
|
||
//---- timer interrupt mask (must be same number with OSi_TICK_TIMER)
|
||
#define OSi_TICK_IE_TIMER (OS_IE_TIMER0 << OSi_TICK_TIMER)
|
||
|
||
//---- timer control setting for tick
|
||
#define OSi_TICK_TIMERCONTROL ( REG_OS_TM0CNT_H_E_MASK | REG_OS_TM0CNT_H_I_MASK | OS_TIMER_PRESCALER_64 )
|
||
#ifdef OS_TICK_USE_2TIMERS
|
||
#define OSi_TICK_TIMERCONTROL_H ( REG_OS_TM1CNT_H_E_MASK | REG_OS_TM1CNT_H_I_MASK | REG_OS_TM1CNT_H_CH_MASK )
|
||
#endif // OS_TICK_USE_2TIMERS
|
||
#endif // SDK_ARM9
|
||
|
||
//---- flag for initialization tick
|
||
static u16 i_osUseTick = FALSE;
|
||
|
||
//---- tick counter
|
||
vu64 i_osTickCounter;
|
||
|
||
//---- flag for need to re-set timer
|
||
BOOL i_osNeedResetTimer = FALSE;
|
||
|
||
extern u16 i_osIsTimerReserved(int timerNum);
|
||
extern void i_osSetTimerReserved(int timerNum);
|
||
|
||
static void i_osCountUpTick(void);
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: osInitTick
|
||
|
||
Description: initialize 'tick system'
|
||
|
||
Arguments: None
|
||
|
||
Returns: None
|
||
*---------------------------------------------------------------------------*/
|
||
void osInitTick(void)
|
||
{
|
||
if (!i_osUseTick)
|
||
{
|
||
i_osUseTick = TRUE;
|
||
|
||
//---- disable timer interrupt
|
||
osDisableInterruptID(OSi_TICK_IE_TIMER_ID);
|
||
|
||
osInitInterrupt();
|
||
osInitTimer();
|
||
|
||
i_osTickCounter = 0;
|
||
|
||
//---- OS reserves OSi_TICK_TIMER timer
|
||
SDK_ASSERT(!i_osIsTimerReserved(OSi_TICK_TIMER));
|
||
i_osSetTimerReserved(OSi_TICK_TIMER);
|
||
|
||
#ifdef SDK_ARM11
|
||
osStopTimer(OSi_TICK_TIMER);
|
||
osEnableTimerReload(OSi_TICK_TIMER);
|
||
osStartTimer(OSi_TICK_TIMER, OS_TICK_LO_MASK, OS_TICK_PRESCALE);
|
||
#else // SDK_ARM9
|
||
//---- setting timer
|
||
osSetTimerControl(OSi_TICK_TIMER, 0);
|
||
#ifdef OS_TICK_USE_2TIMERS
|
||
osSetTimerControl(OSi_TICK_TIMER_H, 0);
|
||
osSetTimerCount(OSi_TICK_TIMER_H, (u16)0);
|
||
osSetTimerControl(OSi_TICK_TIMER_H, (u16)OSi_TICK_TIMERCONTROL_H);
|
||
#endif // OS_TICK_USE_2TIMERS
|
||
osSetTimerCount(OSi_TICK_TIMER, (u16)0);
|
||
osSetTimerControl(OSi_TICK_TIMER, (u16)OSi_TICK_TIMERCONTROL);
|
||
#endif // SDK_ARM9
|
||
|
||
//---- set interrupt callback
|
||
osSetInterruptHandler( OSi_TICK_IE_TIMER_ID, i_osCountUpTick );
|
||
|
||
//---- enable timer interrupt
|
||
osEnableInterruptID(OSi_TICK_IE_TIMER_ID);
|
||
|
||
//---- need to reset
|
||
i_osNeedResetTimer = FALSE;
|
||
}
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: osIsTickAvailable
|
||
|
||
Description: check tick system is available
|
||
|
||
Arguments: None
|
||
|
||
Returns: if available, TRUE.
|
||
*---------------------------------------------------------------------------*/
|
||
BOOL osIsTickAvailable(void)
|
||
{
|
||
return i_osUseTick;
|
||
}
|
||
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: i_osCountUpTick
|
||
|
||
Description: timer interrupt handle.
|
||
|
||
Arguments: None
|
||
|
||
Returns: None
|
||
*---------------------------------------------------------------------------*/
|
||
static void i_osCountUpTick(void)
|
||
{
|
||
i_osTickCounter++;
|
||
|
||
//---- setting for timer
|
||
if (i_osNeedResetTimer)
|
||
{
|
||
#ifdef SDK_ARM11
|
||
osStopTimer(OSi_TICK_TIMER);
|
||
osStartTimer(OSi_TICK_TIMER, OS_TICK_LO_MASK, OS_TICK_PRESCALE);
|
||
#else // SDK_ARM9
|
||
osSetTimerControl(OSi_TICK_TIMER, 0);
|
||
#ifdef OS_TICK_USE_2TIMERS
|
||
osSetTimerControl(OSi_TICK_TIMER_H, 0);
|
||
osSetTimerCount(OSi_TICK_TIMER_H, (u16)0);
|
||
osSetTimerControl(OSi_TICK_TIMER_H, (u16)OSi_TICK_TIMERCONTROL_H);
|
||
#endif // OS_TICK_USE_2TIMERS
|
||
osSetTimerCount((OSTimer)OSi_TICK_TIMER, (u16)0);
|
||
osSetTimerControl(OSi_TICK_TIMER, (u16)OSi_TICK_TIMERCONTROL);
|
||
#endif // SDK_ARM9
|
||
|
||
i_osNeedResetTimer = FALSE;
|
||
}
|
||
|
||
#ifdef OS_TICK_USE_2TIMERS
|
||
osIsInterruptPendingID((OSIntrID)(OSi_TICK_IE_TIMER_ID-1));
|
||
#endif // OS_TICK_USE_2TIMERS
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD>͂<EFBFBD><CD82><EFBFBD><EFBFBD>Ȃ<EFBFBD><C882>Ă<EFBFBD><C482>A<EFBFBD><41><EFBFBD><EFBFBD><EFBFBD>R<EFBFBD>[<5B><><EFBFBD>o<EFBFBD>b<EFBFBD>N<EFBFBD><4E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>邩<EFBFBD><E982A9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȃ<EFBFBD><C882>H
|
||
// //---- reset callback
|
||
// OSi_EnterTimerCallback(OSi_TICK_TIMER, (void (*)(void *))i_osCountUpTick, 0);
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: osGetTick
|
||
|
||
Description: get tick value
|
||
|
||
Arguments: None
|
||
|
||
Returns: tick value
|
||
*---------------------------------------------------------------------------*/
|
||
u64 osGetTick(void)
|
||
{
|
||
u32 countL;
|
||
u64 countH;
|
||
|
||
OSIntrMode prev = osDisableInterrupts();
|
||
SDK_ASSERT(i_osUseTick);
|
||
|
||
#ifndef OS_TICK_USE_2TIMERS
|
||
countL = osGetTimerCount(OSi_TICK_TIMER);
|
||
#else // OS_TICK_USE_2TIMERS
|
||
{
|
||
u32 countM;
|
||
|
||
countM = osGetTimerCount(OSi_TICK_TIMER_H);
|
||
countL = osGetTimerCount(OSi_TICK_TIMER);
|
||
if (osIsInterruptPendingID((OSIntrID)(OSi_TICK_IE_TIMER_ID-1)) &&
|
||
// OSi_TICK_TIMER<45>I<EFBFBD>[<5B>o<EFBFBD>[<5B>t<EFBFBD><74><EFBFBD>[<5B><EFBFBD>
|
||
!(countL & OS_TICK_LO_MSB)
|
||
)
|
||
{
|
||
countM++;
|
||
}
|
||
countL |= countM << 16;
|
||
}
|
||
#endif // OS_TICK_USE_2TIMERS
|
||
|
||
#ifdef SDK_ARM11
|
||
// ARM11<31>̓_<CD83>E<EFBFBD><45><EFBFBD>J<EFBFBD>E<EFBFBD><45><EFBFBD>^<5E>AARM9<4D>̓A<CD83>b<EFBFBD>v<EFBFBD>J<EFBFBD>E<EFBFBD><45><EFBFBD>^<5E>̈Ⴂ<CC88>͂<EFBFBD><CD82><EFBFBD><EFBFBD>ŕ<C595><E290B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
countL = OS_TICK_LO_MASK - countL;
|
||
#endif // SDK_ARM11
|
||
countH = i_osTickCounter;
|
||
|
||
//---- check if timer interrupt bit is on
|
||
if (osIsInterruptPendingID(OSi_TICK_IE_TIMER_ID) &&
|
||
// countL<74><4C>0xFFFFFFFF<46>Œ<EFBFBD><C592><EFBFBD><EFBFBD>Ɋ<EFBFBD><C98A>荞<EFBFBD>ݗv<DD97><76><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ꍇ<EFBFBD>̑<CC91>
|
||
!(countL & OS_TICK_LO_MSB)
|
||
)
|
||
{
|
||
countH++;
|
||
}
|
||
|
||
countH <<= OS_TICK_HI_SHIFT;
|
||
|
||
(void)osRestoreInterrupts(prev);
|
||
|
||
return countH | countL;
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: osGetTickLo
|
||
|
||
Description: get tick value (only u16 part)
|
||
|
||
Arguments: None
|
||
|
||
Returns: tick value (only u16 part)
|
||
*---------------------------------------------------------------------------*/
|
||
#ifndef OS_TICK_USE_2TIMERS
|
||
// OS_TICK_USE_2TIMERS <20>L<EFBFBD><4C><EFBFBD><EFBFBD><EFBFBD>͐<EFBFBD><CD90><EFBFBD><EFBFBD>l<EFBFBD><6C><EFBFBD>擾<EFBFBD>ł<EFBFBD><C582>Ȃ<EFBFBD>
|
||
OSTimerCount osGetTickLo(void)
|
||
{
|
||
SDK_ASSERT(OSi_UseTick);
|
||
return osGetTimerCount(OSi_TICK_TIMER);
|
||
}
|
||
#endif // OS_TICK_USE_2TIMERS
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: i_osSetTick
|
||
|
||
Description: set tick value
|
||
|
||
Arguments: count value of tick to be set
|
||
OS_TICK_USE_2TIMERS <20>L<EFBFBD><4C><EFBFBD><EFBFBD><EFBFBD><EFBFBD>LO<4C>^<5E>C<EFBFBD>}<7D>[<5B><>
|
||
<20>I<EFBFBD>[<5B>o<EFBFBD>[<5B>t<EFBFBD><74><EFBFBD>[<5B><>HI<48>^<5E>C<EFBFBD>}<7D>[<5B><><EFBFBD>J<EFBFBD>E<EFBFBD><45><EFBFBD>g<EFBFBD>A<EFBFBD>b<EFBFBD>v<EFBFBD><76><EFBFBD>邽<EFBFBD>߁A
|
||
count = 0 <20>ȊO<C88A>ł͐<C582><CD90><EFBFBD><EFBFBD>ɓ<EFBFBD><C993>삵<EFBFBD>Ȃ<EFBFBD>
|
||
|
||
Returns: None
|
||
*---------------------------------------------------------------------------*/
|
||
#ifndef OS_TICK_USE_2TIMERS
|
||
void i_osSetTick(u64 count)
|
||
{
|
||
OSIntrMode prev;
|
||
|
||
SDK_ASSERT(i_osUseTick);
|
||
prev = osDisableInterrupts();
|
||
|
||
i_osNeedResetTimer = TRUE;
|
||
|
||
i_osTickCounter = (u64)(count >> OS_TICK_HI_SHIFT);
|
||
|
||
#ifdef SDK_ARM11
|
||
osStopTimer(OSi_TICK_TIMER);
|
||
osClearInterruptPendingID(OSi_TICK_IE_TIMER_ID);
|
||
|
||
osStartTimer(OSi_TICK_TIMER, (u32)(count & OS_TICK_LO_MASK), OS_TICK_PRESCALE);
|
||
|
||
#else // SDK_ARM9
|
||
osSetTimerControl(OSi_TICK_TIMER, 0);
|
||
#ifdef OS_TICK_USE_2TIMERS
|
||
osSetTimerControl(OSi_TICK_TIMER_H, 0);
|
||
#endif // OS_TICK_USE_2TIMERS
|
||
osClearInterruptPendingID(OSi_TICK_IE_TIMER_ID);
|
||
|
||
#ifdef OS_TICK_USE_2TIMERS
|
||
osSetTimerCount(OSi_TICK_TIMER_H, (u16)0);
|
||
osSetTimerControl(OSi_TICK_TIMER_H, (u16)OSi_TICK_TIMERCONTROL_H);
|
||
#endif // OS_TICK_USE_2TIMERS
|
||
osSetTimerCount(OSi_TICK_TIMER, (u16)(count & OS_TICK_LO_MASK));
|
||
osSetTimerControl(OSi_TICK_TIMER, (u16)OSi_TICK_TIMERCONTROL);
|
||
|
||
#endif // SDK_ARM9
|
||
|
||
(void)osRestoreInterrupts(prev);
|
||
}
|
||
#endif // OS_TICK_USE_2TIMERS
|