ctr_firmware/trunk/bootrom/build/libraries/os/ARM9/os_timer.c
nakasima 450a4db341 割り込みライブラリ追加。
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-09-30%20-%20paladin.7z/paladin/ctr_firmware@88 b871894f-2f95-9b40-918c-086798483c85
2008-12-09 05:28:05 +00:00

273 lines
8.9 KiB
C

/*---------------------------------------------------------------------------*
Project: CtrBrom - libraries - OS
File: os_timer.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>
void timer_handler(void);
//----------------------------------------------------------------------
#define REG_OS_TMCNT_H_E_MASK REG_OS_TM0CNT_H_E_MASK
#define REG_OS_TMCNT_H_I_MASK REG_OS_TM0CNT_H_I_MASK
#define REG_OS_TMCNT_H_CH_MASK REG_OS_TM1CNT_H_CH_MASK
//---- if OS reserved each timer, bit=1
static u8 i_osTimerReserved[OS_TIMER_NUM];
u8 i_osIsTimerReserved(int timerNum);
void i_osSetTimerReserved(int timerNum);
void i_osUnsetTimerReserved(int timerNum);
/*---------------------------------------------------------------------------*
Name: osInitTimer
Description: Initialize Timers
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
void osInitTimer( void )
{
static BOOL isInit;
if ( isInit == FALSE )
{
isInit = TRUE;
osInitInterrupt();
i_osStopTimer64();
{
OSIntrMask imask = 0xffffffff;
osSetInterruptHandler( OS_INTR_ID_TIMER1, timer_handler );
}
osEnableInterruptID( OS_INTR_ID_TIMER1 );
i_osStartTimer32( OS_TIMER32_01, (u32)i_osMSecToTick32( 1 ), OS_TIMER_PRESCALER_64 );
}
}
//================================================================================
/*---------------------------------------------------------------------------*
Name: i_osIsTimerReserved
Description: check if specified timer is reserved for OS
Arguments: timerNum : timerNo (0-3)
Returns: non-0 if reserved
*---------------------------------------------------------------------------*/
u8 i_osIsTimerReserved( int timer_id )
{
return i_osTimerReserved[timer_id];
}
/*---------------------------------------------------------------------------*
Name: i_osSetTimerReserved
Description: set specified timer to reserved for OS
Arguments: timerNum : timerNo (0-3)
Returns: None.
*---------------------------------------------------------------------------*/
void i_osSetTimerReserved( int timer_id )
{
i_osTimerReserved[timer_id] = TRUE;
}
/*---------------------------------------------------------------------------*
Name: i_osUnsetTimerReserved
Description: unset specified timer to reserved for OS
Arguments: timerNum : timerNo (0-3)
Returns: None.
*---------------------------------------------------------------------------*/
void i_osUnsetTimerReserved( int timer_id )
{
i_osTimerReserved[timer_id] = FALSE;
}
//================================================================================
/*---------------------------------------------------------------------------*
Name: i_osStartTimer
Description: set timer(s) and start
Arguments: id timerNo
count count value to be set to timer
preScale preScale
Returns: None
*---------------------------------------------------------------------------*/
//
// use 1 timer, 16bit counter, timer<id> interrupt occurs by overflow
//
void i_osStartTimer( OSTimer id, u16 count, OSTimerPrescaler preScale )
{
SDK_ASSERT(OS_TIMER_0 <= id && id <= OS_TIMER_3);
SDK_ASSERT(OS_TIMER_PRESCALER_1 <= preScale && preScale <= OS_TIMER_PRESCALER_1024);
//---- check if system reserved
SDK_ASSERT(!i_osIsTimerReserved(id));
i_osSetTimerCount(id, (u16)~count);
i_osSetTimerControl(id, (u16)(REG_OS_TMCNT_H_E_MASK | REG_OS_TMCNT_H_I_MASK | preScale));
}
//
// use 2 timers, 32bit counter, timer<id+1> interrupt occurs by overflow
//
void i_osStartTimer32( OSTimer32 id, u32 count, OSTimerPrescaler preScale )
{
SDK_ASSERT(OS_TIMER32_01 <= id && id <= OS_TIMER32_23);
SDK_ASSERT(OS_TIMER_PRESCALER_1 <= preScale && preScale <= OS_TIMER_PRESCALER_1024);
//---- check if system reserved
SDK_ASSERT(!i_osIsTimerReserved(id));
SDK_ASSERT(!i_osIsTimerReserved(id + 1));
i_osSetTimerCount((OSTimer)((int)id + 1), (u16)((~count >> 16) & 0xffff));
i_osSetTimerCount((OSTimer)id, (u16)(~count & 0xffff));
i_osSetTimerControl((OSTimer)((int)id + 1),
REG_OS_TMCNT_H_E_MASK | REG_OS_TMCNT_H_I_MASK | REG_OS_TMCNT_H_CH_MASK);
i_osSetTimerControl((OSTimer)id, (u16)(REG_OS_TMCNT_H_E_MASK | preScale));
}
//
// use 3 timers, 48bit counter, timer<id+2> interrupt occurs by overflow
//
void i_osStartTimer48( OSTimer48 id, u64 count, OSTimerPrescaler preScale )
{
SDK_ASSERT(OS_TIMER48_012 <= id && id <= OS_TIMER48_123);
SDK_ASSERT(OS_TIMER_PRESCALER_1 <= preScale && preScale <= OS_TIMER_PRESCALER_1024);
//---- check if system reserved
SDK_ASSERT(!i_osIsTimerReserved(id));
SDK_ASSERT(!i_osIsTimerReserved(id + 1));
SDK_ASSERT(!i_osIsTimerReserved(id + 2));
i_osSetTimerCount((OSTimer)((int)id + 2), (u16)((~count >> 32) & 0xffff));
i_osSetTimerCount((OSTimer)((int)id + 1), (u16)((~count >> 16) & 0xffff));
i_osSetTimerCount((OSTimer)id, (u16)(~count & 0xffff));
i_osSetTimerControl((OSTimer)((int)id + 2),
REG_OS_TMCNT_H_E_MASK | REG_OS_TMCNT_H_I_MASK | REG_OS_TMCNT_H_CH_MASK);
i_osSetTimerControl((OSTimer)((int)id + 1), REG_OS_TMCNT_H_E_MASK | REG_OS_TMCNT_H_CH_MASK);
i_osSetTimerControl((OSTimer)id, (u16)(REG_OS_TMCNT_H_E_MASK | preScale));
}
//
// use all 4 timers, 64bit counter, timer3 interrupt occurs by overflow
//
void i_osStartTimer64( u64 count, OSTimerPrescaler preScale )
{
SDK_ASSERT(OS_TIMER_PRESCALER_1 <= preScale && preScale <= OS_TIMER_PRESCALER_1024);
//---- check if system reserved
SDK_ASSERT(!i_osIsTimerReserved(OS_TIMER_0));
SDK_ASSERT(!i_osIsTimerReserved(OS_TIMER_1));
SDK_ASSERT(!i_osIsTimerReserved(OS_TIMER_2));
SDK_ASSERT(!i_osIsTimerReserved(OS_TIMER_3));
i_osSetTimerCount(OS_TIMER_3, (u16)((~count >> 48) & 0xffff));
i_osSetTimerCount(OS_TIMER_2, (u16)((~count >> 32) & 0xffff));
i_osSetTimerCount(OS_TIMER_1, (u16)((~count >> 16) & 0xffff));
i_osSetTimerCount(OS_TIMER_0, (u16)(~count & 0xffff));
i_osSetTimerControl(OS_TIMER_3,
REG_OS_TMCNT_H_E_MASK | REG_OS_TMCNT_H_I_MASK | REG_OS_TMCNT_H_CH_MASK);
i_osSetTimerControl(OS_TIMER_2, REG_OS_TMCNT_H_E_MASK | REG_OS_TMCNT_H_CH_MASK);
i_osSetTimerControl(OS_TIMER_1, REG_OS_TMCNT_H_E_MASK | REG_OS_TMCNT_H_CH_MASK);
i_osSetTimerControl(OS_TIMER_0, (u16)(REG_OS_TMCNT_H_E_MASK | preScale));
}
/*---------------------------------------------------------------------------*
Name: i_osStopTimer
Description: stop timer(s)
Arguments: id timerNo
Returns: None
*---------------------------------------------------------------------------*/
//
// stop a timer
//
void i_osStopTimer( OSTimer id )
{
SDK_ASSERT(OS_TIMER_0 <= id && id <= OS_TIMER_3);
//---- check if system reserved
SDK_ASSERT(!i_osIsTimerReserved(id));
i_osSetTimerControl(id, 0);
}
//
// stop 2 timers
//
void i_osStopTimer32( OSTimer32 id )
{
SDK_ASSERT(OS_TIMER32_01 <= id && id <= OS_TIMER32_23);
//---- check if system reserved
SDK_ASSERT(!i_osIsTimerReserved(id));
SDK_ASSERT(!i_osIsTimerReserved(id + 1));
i_osStopTimer((OSTimer)((int)id + 1));
i_osStopTimer((OSTimer)id);
}
//
// stop 3 timers
//
void i_osStopTimer48( OSTimer48 id )
{
SDK_ASSERT(OS_TIMER48_012 <= id && id <= OS_TIMER48_123);
//---- check if system reserved
SDK_ASSERT(!i_osIsTimerReserved(id));
SDK_ASSERT(!i_osIsTimerReserved(id + 1));
SDK_ASSERT(!i_osIsTimerReserved(id + 2));
i_osStopTimer((OSTimer)((int)id + 2));
i_osStopTimer((OSTimer)((int)id + 1));
i_osStopTimer((OSTimer)id);
}
//
// stop all 4 timers
//
void i_osStopTimer64( void )
{
//---- check if system reserved
SDK_ASSERT(!i_osIsTimerReserved(OS_TIMER_0));
SDK_ASSERT(!i_osIsTimerReserved(OS_TIMER_1));
SDK_ASSERT(!i_osIsTimerReserved(OS_TIMER_2));
SDK_ASSERT(!i_osIsTimerReserved(OS_TIMER_3));
i_osStopTimer(OS_TIMER_3);
i_osStopTimer(OS_TIMER_2);
i_osStopTimer(OS_TIMER_1);
i_osStopTimer(OS_TIMER_0);
}