mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-17 03:25:14 -04:00
Saturn: Use WDT for measuring elapsed time
This commit is contained in:
parent
af20525b18
commit
9c9626b502
@ -91,36 +91,31 @@ void DateTime_CurrentLocal(struct cc_datetime* t) {
|
||||
/*########################################################################################################################*
|
||||
*--------------------------------------------------------Stopwatch--------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
static volatile cc_uint32 overflow_count, wdt_overflows;
|
||||
#include "sh2_wdt.h"
|
||||
|
||||
static void wdt_handler(void) { wdt_overflows++; }
|
||||
static void ovf_handler(void) { overflow_count++; }
|
||||
static void Stopwatch_Init(void) {
|
||||
wdt_stop();
|
||||
|
||||
wdt_set_irq_number(CPU_INTC_INTERRUPT_WDT_ITI);
|
||||
wdt_set_irq_priority(15);
|
||||
cpu_intc_ihr_set(CPU_INTC_INTERRUPT_WDT_ITI, wdt_handler);
|
||||
|
||||
wdt_enable();
|
||||
}
|
||||
|
||||
cc_uint64 Stopwatch_Measure(void) {
|
||||
return cpu_frt_count_get() | (overflow_count << 16);
|
||||
return wdt_total_ticks();
|
||||
}
|
||||
|
||||
#define US_PER_SEC 1000000
|
||||
#define NTSC_320_CLOCK 26846588
|
||||
#define NTSC_320_CLOCK 26846587
|
||||
|
||||
cc_uint64 Stopwatch_ElapsedMicroseconds(cc_uint64 beg, cc_uint64 end) {
|
||||
if (end < beg) return 0;
|
||||
cc_uint64 delta = end - beg;
|
||||
|
||||
// TODO still wrong?? PAL detection ???
|
||||
return (delta * US_PER_SEC) / (NTSC_320_CLOCK / 128);
|
||||
}
|
||||
|
||||
static void Stopwatch_Init(void) {
|
||||
//cpu_frt_init(CPU_FRT_CLOCK_DIV_8);
|
||||
cpu_frt_init(CPU_FRT_CLOCK_DIV_128);
|
||||
cpu_frt_ovi_set(ovf_handler);
|
||||
cpu_frt_interrupt_priority_set(15);
|
||||
|
||||
//cpu_wdt_init(CPU_WDT_CLOCK_DIV_4096);
|
||||
//cpu_wdt_interrupt_priority_set(15);
|
||||
//cpu_wdt_timer_mode_set(CPU_WDT_MODE_INTERVAL, wdt_handler);
|
||||
//cpu_wdt_enable();
|
||||
return (delta * US_PER_SEC) / (NTSC_320_CLOCK / 1024);
|
||||
}
|
||||
|
||||
|
||||
|
73
src/saturn/sh2_wdt.h
Normal file
73
src/saturn/sh2_wdt.h
Normal file
@ -0,0 +1,73 @@
|
||||
static cc_uint32 wdt_overflows;
|
||||
|
||||
// Interrupt Priority Request A
|
||||
#define SH2_REG_IPRA ((volatile uint16_t *)0xFFFFFEE2)
|
||||
#define SH2_IPRA_WDT_NUM 4
|
||||
|
||||
// Vector Number Setting Register WDT
|
||||
#define SH2_REG_VCRWDT ((volatile uint16_t *)0xFFFFFEE4)
|
||||
#define SH2_VCRWDT_NUM 8
|
||||
|
||||
// Watchdog Timer Counter
|
||||
#define SH2_REG_WTCNT_R ((volatile uint8_t *)0xFFFFFE81)
|
||||
#define SH2_REG_WTCNT_W ((volatile uint16_t *)0xFFFFFE80)
|
||||
#define SH2_CMD_WTCNT(val) (0x5A00 | (uint8_t)(val))
|
||||
|
||||
// Watchdog Timer Control/Status Register
|
||||
#define SH2_REG_WTCSR_R ((volatile uint8_t *)0xFFFFFE80)
|
||||
#define SH2_REG_WTCSR_W ((volatile uint16_t *)0xFFFFFE80)
|
||||
#define SH2_CMD_WTCSR(val) (0xA500 | (uint8_t)(val))
|
||||
|
||||
#define SH2_WTCSR_CLOCK_DIV_2 0
|
||||
#define SH2_WTCSR_CLOCK_DIV_64 1
|
||||
#define SH2_WTCSR_CLOCK_DIV_128 2
|
||||
#define SH2_WTCSR_CLOCK_DIV_256 3
|
||||
#define SH2_WTCSR_CLOCK_DIV_512 4
|
||||
#define SH2_WTCSR_CLOCK_DIV_1024 5
|
||||
#define SH2_WTCSR_CLOCK_DIV_4096 6
|
||||
#define SH2_WTCSR_CLOCK_DIV_8192 7
|
||||
|
||||
#define SH2_WTCSR_ENA_FLG 0x20
|
||||
#define SH2_WTCSR_OVF_FLG 0x80
|
||||
|
||||
|
||||
static CC_INLINE void wdt_set_irq_number(int irq_num) {
|
||||
uint16_t vcrwdt = *SH2_REG_VCRWDT;
|
||||
vcrwdt &= ~( 0x7F << SH2_VCRWDT_NUM);
|
||||
vcrwdt |= (irq_num << SH2_VCRWDT_NUM);
|
||||
|
||||
*SH2_REG_VCRWDT = vcrwdt;
|
||||
}
|
||||
|
||||
static CC_INLINE void wdt_set_irq_priority(uint8_t pri) {
|
||||
uint16_t ipra = *SH2_REG_IPRA;
|
||||
ipra &= ~(0xF << SH2_IPRA_WDT_NUM);
|
||||
ipra |= (pri << SH2_IPRA_WDT_NUM);
|
||||
|
||||
*SH2_REG_IPRA = ipra;
|
||||
}
|
||||
|
||||
|
||||
static void __interrupt_handler wdt_handler(void) {
|
||||
uint8_t wtcr = *SH2_REG_WTCSR_R & ~SH2_WTCSR_OVF_FLG;
|
||||
|
||||
*SH2_REG_WTCSR_W = SH2_CMD_WTCSR(wtcr);
|
||||
wdt_overflows++;
|
||||
}
|
||||
|
||||
static CC_INLINE void wdt_stop(void) {
|
||||
*SH2_REG_WTCSR_W = SH2_CMD_WTCSR(SH2_WTCSR_CLOCK_DIV_1024);
|
||||
}
|
||||
|
||||
static CC_INLINE void wdt_enable(void) {
|
||||
uint8_t wtcr = *SH2_REG_WTCSR_R & ~SH2_WTCSR_OVF_FLG;
|
||||
wtcr |= SH2_WTCSR_ENA_FLG;
|
||||
// interval mode is 0 anyways
|
||||
|
||||
*SH2_REG_WTCNT_W = SH2_CMD_WTCNT(0);
|
||||
*SH2_REG_WTCSR_W = SH2_CMD_WTCSR(wtcr);
|
||||
}
|
||||
|
||||
static CC_INLINE uint32_t wdt_total_ticks(void) {
|
||||
return (*SH2_REG_WTCNT_R) | (wdt_overflows << 8);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user