mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2024-12-25 19:24:16 +01:00
port siirtc from pokeruby
This commit is contained in:
parent
a99e9a16c6
commit
452bbe41cf
1160
asm/librtc.s
1160
asm/librtc.s
File diff suppressed because it is too large
Load Diff
30
asm/m4a_1.s
30
asm/m4a_1.s
@ -302,7 +302,7 @@ _081DD044:
|
|||||||
ldrb r0, [r4, o_SoundChannel_type]
|
ldrb r0, [r4, o_SoundChannel_type]
|
||||||
tst r0, 0x30
|
tst r0, 0x30
|
||||||
beq _081DD068
|
beq _081DD068
|
||||||
bl sub_81DD264
|
bl sub_82DF49C
|
||||||
b _081DD228
|
b _081DD228
|
||||||
_081DD068:
|
_081DD068:
|
||||||
mov r10, r10, lsl 16
|
mov r10, r10, lsl 16
|
||||||
@ -465,8 +465,8 @@ _081DD25E:
|
|||||||
.pool
|
.pool
|
||||||
thumb_func_end SoundMainRAM
|
thumb_func_end SoundMainRAM
|
||||||
|
|
||||||
arm_func_start sub_81DD264
|
arm_func_start sub_82DF49C
|
||||||
sub_81DD264:
|
sub_82DF49C:
|
||||||
ldr r6, [r4, o_SoundChannel_wav]
|
ldr r6, [r4, o_SoundChannel_wav]
|
||||||
ldrb r0, [r4, o_SoundChannel_status]
|
ldrb r0, [r4, o_SoundChannel_status]
|
||||||
tst r0, 0x20
|
tst r0, 0x20
|
||||||
@ -505,10 +505,10 @@ _081DD2B4:
|
|||||||
ldrb r0, [r4, o_SoundChannel_type]
|
ldrb r0, [r4, o_SoundChannel_type]
|
||||||
tst r0, 0x10
|
tst r0, 0x10
|
||||||
bne _081DD3C0
|
bne _081DD3C0
|
||||||
bl sub_81DD520
|
bl sub_82DF758
|
||||||
mov r0, r1
|
mov r0, r1
|
||||||
add r3, r3, 0x1
|
add r3, r3, 0x1
|
||||||
bl sub_81DD520
|
bl sub_82DF758
|
||||||
sub r1, r1, r0
|
sub r1, r1, r0
|
||||||
_081DD308:
|
_081DD308:
|
||||||
ldr r6, [r5]
|
ldr r6, [r5]
|
||||||
@ -534,11 +534,11 @@ _081DD310:
|
|||||||
b _081DD364
|
b _081DD364
|
||||||
_081DD358:
|
_081DD358:
|
||||||
add r3, r3, lr
|
add r3, r3, lr
|
||||||
bl sub_81DD520
|
bl sub_82DF758
|
||||||
mov r0, r1
|
mov r0, r1
|
||||||
_081DD364:
|
_081DD364:
|
||||||
add r3, r3, 0x1
|
add r3, r3, 0x1
|
||||||
bl sub_81DD520
|
bl sub_82DF758
|
||||||
sub r1, r1, r0
|
sub r1, r1, r0
|
||||||
_081DD370:
|
_081DD370:
|
||||||
adds r5, r5, 0x40000000
|
adds r5, r5, 0x40000000
|
||||||
@ -565,10 +565,10 @@ _081DD3B0:
|
|||||||
b _081DD3B0
|
b _081DD3B0
|
||||||
_081DD3C0:
|
_081DD3C0:
|
||||||
sub r3, r3, 0x1
|
sub r3, r3, 0x1
|
||||||
bl sub_81DD520
|
bl sub_82DF758
|
||||||
mov r0, r1
|
mov r0, r1
|
||||||
sub r3, r3, 0x1
|
sub r3, r3, 0x1
|
||||||
bl sub_81DD520
|
bl sub_82DF758
|
||||||
sub r1, r1, r0
|
sub r1, r1, r0
|
||||||
_081DD3D8:
|
_081DD3D8:
|
||||||
ldr r6, [r5]
|
ldr r6, [r5]
|
||||||
@ -594,11 +594,11 @@ _081DD3E0:
|
|||||||
b _081DD434
|
b _081DD434
|
||||||
_081DD428:
|
_081DD428:
|
||||||
sub r3, r3, lr
|
sub r3, r3, lr
|
||||||
bl sub_81DD520
|
bl sub_82DF758
|
||||||
mov r0, r1
|
mov r0, r1
|
||||||
_081DD434:
|
_081DD434:
|
||||||
sub r3, r3, 0x1
|
sub r3, r3, 0x1
|
||||||
bl sub_81DD520
|
bl sub_82DF758
|
||||||
sub r1, r1, r0
|
sub r1, r1, r0
|
||||||
_081DD440:
|
_081DD440:
|
||||||
adds r5, r5, 0x40000000
|
adds r5, r5, 0x40000000
|
||||||
@ -663,10 +663,10 @@ _081DD4F4:
|
|||||||
str r7, [r5, 0x630]
|
str r7, [r5, 0x630]
|
||||||
str r6, [r5], 0x4
|
str r6, [r5], 0x4
|
||||||
pop {r8,r12,pc}
|
pop {r8,r12,pc}
|
||||||
arm_func_end sub_81DD264
|
arm_func_end sub_82DF49C
|
||||||
|
|
||||||
arm_func_start sub_81DD520
|
arm_func_start sub_82DF758
|
||||||
sub_81DD520:
|
sub_82DF758:
|
||||||
push {r0,r2,r5-r7,lr}
|
push {r0,r2,r5-r7,lr}
|
||||||
mov r0, r3, lsr 6
|
mov r0, r3, lsr 6
|
||||||
ldr r1, [r4, o_SoundChannel_xpi]
|
ldr r1, [r4, o_SoundChannel_xpi]
|
||||||
@ -704,7 +704,7 @@ _081DD594:
|
|||||||
ldrsb r1, [r5, r0]
|
ldrsb r1, [r5, r0]
|
||||||
pop {r0,r2,r5-r7,pc}
|
pop {r0,r2,r5-r7,pc}
|
||||||
.pool
|
.pool
|
||||||
arm_func_end sub_81DD520
|
arm_func_end sub_82DF758
|
||||||
|
|
||||||
thumb_func_start SoundMainBTM
|
thumb_func_start SoundMainBTM
|
||||||
SoundMainBTM:
|
SoundMainBTM:
|
||||||
|
@ -693,7 +693,7 @@ Reset: @ 80008F4
|
|||||||
ands r2, r1
|
ands r2, r1
|
||||||
strh r2, [r0, 0xA]
|
strh r2, [r0, 0xA]
|
||||||
ldrh r0, [r0, 0xA]
|
ldrh r0, [r0, 0xA]
|
||||||
bl RTC_SetReadOnly
|
bl SiiRtcProtect
|
||||||
movs r0, 0xFF
|
movs r0, 0xFF
|
||||||
bl SoftReset
|
bl SoftReset
|
||||||
pop {r4}
|
pop {r4}
|
||||||
|
10
asm/rtc.s
10
asm/rtc.s
@ -202,8 +202,8 @@ GameFreakRTC_Init: @ 802F21C
|
|||||||
movs r0, 0
|
movs r0, 0
|
||||||
strh r0, [r5]
|
strh r0, [r5]
|
||||||
bl GameFreakRTC_ClearIME
|
bl GameFreakRTC_ClearIME
|
||||||
bl RTC_SetReadWrite
|
bl SiiRtcUnprotect
|
||||||
bl RTC_Init
|
bl SiiRtcProbe
|
||||||
ldr r4, =gUnknown_03000DCC
|
ldr r4, =gUnknown_03000DCC
|
||||||
strb r0, [r4]
|
strb r0, [r4]
|
||||||
bl GameFreakRTC_RestoreIME
|
bl GameFreakRTC_RestoreIME
|
||||||
@ -281,7 +281,7 @@ GameFreakRTC_GetRTCDateTimeInternal: @ 802F2B8
|
|||||||
adds r4, r0, 0
|
adds r4, r0, 0
|
||||||
bl GameFreakRTC_ClearIME
|
bl GameFreakRTC_ClearIME
|
||||||
adds r0, r4, 0
|
adds r0, r4, 0
|
||||||
bl RTC_GetDateTime
|
bl SiiRtcGetDateTime
|
||||||
bl GameFreakRTC_RestoreIME
|
bl GameFreakRTC_RestoreIME
|
||||||
pop {r4}
|
pop {r4}
|
||||||
pop {r0}
|
pop {r0}
|
||||||
@ -295,7 +295,7 @@ GameFreakRTC_GetControlReg: @ 802F2D0
|
|||||||
adds r4, r0, 0
|
adds r4, r0, 0
|
||||||
bl GameFreakRTC_ClearIME
|
bl GameFreakRTC_ClearIME
|
||||||
adds r0, r4, 0
|
adds r0, r4, 0
|
||||||
bl RTC_GetControlReg
|
bl SiiRtcGetStatus
|
||||||
bl GameFreakRTC_RestoreIME
|
bl GameFreakRTC_RestoreIME
|
||||||
pop {r4}
|
pop {r4}
|
||||||
pop {r0}
|
pop {r0}
|
||||||
@ -452,7 +452,7 @@ _0802F3E6:
|
|||||||
GameFreakRTC_Reset: @ 802F3F8
|
GameFreakRTC_Reset: @ 802F3F8
|
||||||
push {lr}
|
push {lr}
|
||||||
bl GameFreakRTC_ClearIME
|
bl GameFreakRTC_ClearIME
|
||||||
bl RTC_Reset
|
bl SiiRtcReset
|
||||||
bl GameFreakRTC_RestoreIME
|
bl GameFreakRTC_RestoreIME
|
||||||
pop {r0}
|
pop {r0}
|
||||||
bx r0
|
bx r0
|
||||||
|
54
include/siirtc.h
Normal file
54
include/siirtc.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#ifndef GUARD_RTC_H
|
||||||
|
#define GUARD_RTC_H
|
||||||
|
|
||||||
|
#include "gba/gba.h"
|
||||||
|
|
||||||
|
#define SIIRTCINFO_INTFE 0x01 // frequency interrupt enable
|
||||||
|
#define SIIRTCINFO_INTME 0x02 // per-minute interrupt enable
|
||||||
|
#define SIIRTCINFO_INTAE 0x04 // alarm interrupt enable
|
||||||
|
#define SIIRTCINFO_24HOUR 0x40 // 0: 12-hour mode, 1: 24-hour mode
|
||||||
|
#define SIIRTCINFO_POWER 0x80 // power on or power failure occurred
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
MONTH_JAN = 1,
|
||||||
|
MONTH_FEB,
|
||||||
|
MONTH_MAR,
|
||||||
|
MONTH_APR,
|
||||||
|
MONTH_MAY,
|
||||||
|
MONTH_JUN,
|
||||||
|
MONTH_JUL,
|
||||||
|
MONTH_AUG,
|
||||||
|
MONTH_SEP,
|
||||||
|
MONTH_OCT,
|
||||||
|
MONTH_NOV,
|
||||||
|
MONTH_DEC
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SiiRtcInfo
|
||||||
|
{
|
||||||
|
u8 year;
|
||||||
|
u8 month;
|
||||||
|
u8 day;
|
||||||
|
u8 dayOfWeek;
|
||||||
|
u8 hour;
|
||||||
|
u8 minute;
|
||||||
|
u8 second;
|
||||||
|
u8 status;
|
||||||
|
u8 alarmHour;
|
||||||
|
u8 alarmMinute;
|
||||||
|
};
|
||||||
|
|
||||||
|
void SiiRtcUnprotect();
|
||||||
|
void SiiRtcProtect();
|
||||||
|
u8 SiiRtcProbe();
|
||||||
|
bool8 SiiRtcReset();
|
||||||
|
bool8 SiiRtcGetStatus(struct SiiRtcInfo *rtc);
|
||||||
|
bool8 SiiRtcSetStatus(struct SiiRtcInfo *rtc);
|
||||||
|
bool8 SiiRtcGetDateTime(struct SiiRtcInfo *rtc);
|
||||||
|
bool8 SiiRtcSetDateTime(struct SiiRtcInfo *rtc);
|
||||||
|
bool8 SiiRtcGetTime(struct SiiRtcInfo *rtc);
|
||||||
|
bool8 SiiRtcSetTime(struct SiiRtcInfo *rtc);
|
||||||
|
bool8 SiiRtcSetAlarm(struct SiiRtcInfo *rtc);
|
||||||
|
|
||||||
|
#endif // GUARD_RTC_H
|
@ -215,7 +215,7 @@ SECTIONS {
|
|||||||
src/agb_flash.o(.text);
|
src/agb_flash.o(.text);
|
||||||
src/agb_flash_1m.o(.text);
|
src/agb_flash_1m.o(.text);
|
||||||
src/agb_flash_mx.o(.text);
|
src/agb_flash_mx.o(.text);
|
||||||
asm/librtc.o(.text);
|
src/siirtc.o(.text);
|
||||||
asm/librfu.o(.text);
|
asm/librfu.o(.text);
|
||||||
asm/libagbsyscall.o(.text);
|
asm/libagbsyscall.o(.text);
|
||||||
tools/agbcc/lib/libgcc.a:_call_via_rX.o(.text);
|
tools/agbcc/lib/libgcc.a:_call_via_rX.o(.text);
|
||||||
@ -251,7 +251,7 @@ SECTIONS {
|
|||||||
src/agb_flash_1m.o(.rodata);
|
src/agb_flash_1m.o(.rodata);
|
||||||
src/agb_flash_mx.o(.rodata);
|
src/agb_flash_mx.o(.rodata);
|
||||||
src/agb_flash_le.o(.rodata);
|
src/agb_flash_le.o(.rodata);
|
||||||
data/librtc_rodata.o(.rodata);
|
src/siirtc.o(.rodata);
|
||||||
data/librfu_rodata.o(.rodata);
|
data/librfu_rodata.o(.rodata);
|
||||||
tools/agbcc/lib/libgcc.a:_divdi3.o(.rodata);
|
tools/agbcc/lib/libgcc.a:_divdi3.o(.rodata);
|
||||||
tools/agbcc/lib/libgcc.a:_udivdi3.o(.rodata);
|
tools/agbcc/lib/libgcc.a:_udivdi3.o(.rodata);
|
||||||
|
432
src/siirtc.c
Normal file
432
src/siirtc.c
Normal file
@ -0,0 +1,432 @@
|
|||||||
|
// Ruby/Sapphire/Emerald cartridges contain a Seiko Instruments Inc. (SII)
|
||||||
|
// S-3511A real-time clock (RTC). This library ("SIIRTC_V001") is for
|
||||||
|
// communicating with the RTC.
|
||||||
|
|
||||||
|
#include "gba/gba.h"
|
||||||
|
#include "siirtc.h"
|
||||||
|
|
||||||
|
#define STATUS_INTFE 0x02 // frequency interrupt enable
|
||||||
|
#define STATUS_INTME 0x08 // per-minute interrupt enable
|
||||||
|
#define STATUS_INTAE 0x20 // alarm interrupt enable
|
||||||
|
#define STATUS_24HOUR 0x40 // 0: 12-hour mode, 1: 24-hour mode
|
||||||
|
#define STATUS_POWER 0x80 // power on or power failure occurred
|
||||||
|
|
||||||
|
#define TEST_MODE 0x80 // flag in the "second" byte
|
||||||
|
|
||||||
|
#define ALARM_AM 0x00
|
||||||
|
#define ALARM_PM 0x80
|
||||||
|
|
||||||
|
#define OFFSET_YEAR offsetof(struct SiiRtcInfo, year)
|
||||||
|
#define OFFSET_MONTH offsetof(struct SiiRtcInfo, month)
|
||||||
|
#define OFFSET_DAY offsetof(struct SiiRtcInfo, day)
|
||||||
|
#define OFFSET_DAY_OF_WEEK offsetof(struct SiiRtcInfo, dayOfWeek)
|
||||||
|
#define OFFSET_HOUR offsetof(struct SiiRtcInfo, hour)
|
||||||
|
#define OFFSET_MINUTE offsetof(struct SiiRtcInfo, minute)
|
||||||
|
#define OFFSET_SECOND offsetof(struct SiiRtcInfo, second)
|
||||||
|
#define OFFSET_STATUS offsetof(struct SiiRtcInfo, status)
|
||||||
|
#define OFFSET_ALARM_HOUR offsetof(struct SiiRtcInfo, alarmHour)
|
||||||
|
#define OFFSET_ALARM_MINUTE offsetof(struct SiiRtcInfo, alarmMinute)
|
||||||
|
|
||||||
|
#define INFO_BUF(info, index) (*((u8 *)(info) + (index)))
|
||||||
|
|
||||||
|
#define DATETIME_BUF(info, index) INFO_BUF(info, OFFSET_YEAR + index)
|
||||||
|
#define DATETIME_BUF_LEN (OFFSET_SECOND - OFFSET_YEAR + 1)
|
||||||
|
|
||||||
|
#define TIME_BUF(info, index) INFO_BUF(info, OFFSET_HOUR + index)
|
||||||
|
#define TIME_BUF_LEN (OFFSET_SECOND - OFFSET_HOUR + 1)
|
||||||
|
|
||||||
|
#define WR 0 // command for writing data
|
||||||
|
#define RD 1 // command for reading data
|
||||||
|
|
||||||
|
#define CMD(n) (0x60 | (n << 1))
|
||||||
|
|
||||||
|
#define CMD_RESET CMD(0)
|
||||||
|
#define CMD_STATUS CMD(1)
|
||||||
|
#define CMD_DATETIME CMD(2)
|
||||||
|
#define CMD_TIME CMD(3)
|
||||||
|
#define CMD_ALARM CMD(4)
|
||||||
|
|
||||||
|
#define GPIO_PORT_DATA (*(vu16 *)0x80000C4)
|
||||||
|
#define GPIO_PORT_DIRECTION (*(vu16 *)0x80000C6)
|
||||||
|
#define GPIO_PORT_READ_ENABLE (*(vu16 *)0x80000C8)
|
||||||
|
|
||||||
|
extern vu16 GPIOPortDirection;
|
||||||
|
|
||||||
|
static u16 sDummy; // unused variable
|
||||||
|
static bool8 sLocked;
|
||||||
|
|
||||||
|
static int WriteCommand(u8 value);
|
||||||
|
static int WriteData(u8 value);
|
||||||
|
static u8 ReadData();
|
||||||
|
static void EnableGpioPortRead();
|
||||||
|
static void DisableGpioPortRead();
|
||||||
|
|
||||||
|
static const char AgbLibRtcVersion[] = "SIIRTC_V001";
|
||||||
|
|
||||||
|
void SiiRtcUnprotect()
|
||||||
|
{
|
||||||
|
EnableGpioPortRead();
|
||||||
|
sLocked = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SiiRtcProtect()
|
||||||
|
{
|
||||||
|
DisableGpioPortRead();
|
||||||
|
sLocked = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 SiiRtcProbe()
|
||||||
|
{
|
||||||
|
u8 errorCode;
|
||||||
|
struct SiiRtcInfo rtc;
|
||||||
|
|
||||||
|
if (!SiiRtcGetStatus(&rtc))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
errorCode = 0;
|
||||||
|
|
||||||
|
if ((rtc.status & (SIIRTCINFO_POWER | SIIRTCINFO_24HOUR)) == SIIRTCINFO_POWER
|
||||||
|
|| (rtc.status & (SIIRTCINFO_POWER | SIIRTCINFO_24HOUR)) == 0)
|
||||||
|
{
|
||||||
|
// The RTC is in 12-hour mode. Reset it and switch to 24-hour mode.
|
||||||
|
|
||||||
|
// Note that the conditions are redundant and equivalent to simply
|
||||||
|
// "(rtc.status & SIIRTCINFO_24HOUR) == 0". It's possible that this
|
||||||
|
// was also intended to handle resetting the clock after power failure
|
||||||
|
// but a mistake was made.
|
||||||
|
|
||||||
|
if (!SiiRtcReset())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
errorCode++;
|
||||||
|
}
|
||||||
|
|
||||||
|
SiiRtcGetTime(&rtc);
|
||||||
|
|
||||||
|
if (rtc.second & TEST_MODE)
|
||||||
|
{
|
||||||
|
// The RTC is in test mode. Reset it to leave test mode.
|
||||||
|
|
||||||
|
if (!SiiRtcReset())
|
||||||
|
return (errorCode << 4) & 0xF0;
|
||||||
|
|
||||||
|
errorCode++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (errorCode << 4) | 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool8 SiiRtcReset()
|
||||||
|
{
|
||||||
|
u8 result;
|
||||||
|
struct SiiRtcInfo rtc;
|
||||||
|
|
||||||
|
if (sLocked == TRUE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
sLocked = TRUE;
|
||||||
|
|
||||||
|
GPIO_PORT_DATA = 1;
|
||||||
|
GPIO_PORT_DATA = 5;
|
||||||
|
|
||||||
|
GPIO_PORT_DIRECTION = 7;
|
||||||
|
|
||||||
|
WriteCommand(CMD_RESET | WR);
|
||||||
|
|
||||||
|
GPIO_PORT_DATA = 1;
|
||||||
|
GPIO_PORT_DATA = 1;
|
||||||
|
|
||||||
|
sLocked = FALSE;
|
||||||
|
|
||||||
|
rtc.status = SIIRTCINFO_24HOUR;
|
||||||
|
|
||||||
|
result = SiiRtcSetStatus(&rtc);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool8 SiiRtcGetStatus(struct SiiRtcInfo *rtc)
|
||||||
|
{
|
||||||
|
u8 statusData;
|
||||||
|
|
||||||
|
if (sLocked == TRUE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
sLocked = TRUE;
|
||||||
|
|
||||||
|
GPIO_PORT_DATA = 1;
|
||||||
|
GPIO_PORT_DATA = 5;
|
||||||
|
|
||||||
|
GPIO_PORT_DIRECTION = 7;
|
||||||
|
|
||||||
|
WriteCommand(CMD_STATUS | RD);
|
||||||
|
|
||||||
|
GPIO_PORT_DIRECTION = 5;
|
||||||
|
|
||||||
|
statusData = ReadData();
|
||||||
|
|
||||||
|
rtc->status = (statusData & (STATUS_POWER | STATUS_24HOUR))
|
||||||
|
| ((statusData & STATUS_INTAE) >> 3)
|
||||||
|
| ((statusData & STATUS_INTME) >> 2)
|
||||||
|
| ((statusData & STATUS_INTFE) >> 1);
|
||||||
|
|
||||||
|
GPIO_PORT_DATA = 1;
|
||||||
|
GPIO_PORT_DATA = 1;
|
||||||
|
|
||||||
|
sLocked = FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool8 SiiRtcSetStatus(struct SiiRtcInfo *rtc)
|
||||||
|
{
|
||||||
|
u8 statusData;
|
||||||
|
|
||||||
|
if (sLocked == TRUE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
sLocked = TRUE;
|
||||||
|
|
||||||
|
GPIO_PORT_DATA = 1;
|
||||||
|
GPIO_PORT_DATA = 5;
|
||||||
|
|
||||||
|
statusData = STATUS_24HOUR
|
||||||
|
| ((rtc->status & SIIRTCINFO_INTAE) << 3)
|
||||||
|
| ((rtc->status & SIIRTCINFO_INTME) << 2)
|
||||||
|
| ((rtc->status & SIIRTCINFO_INTFE) << 1);
|
||||||
|
|
||||||
|
GPIO_PORT_DIRECTION = 7;
|
||||||
|
|
||||||
|
WriteCommand(CMD_STATUS | WR);
|
||||||
|
|
||||||
|
WriteData(statusData);
|
||||||
|
|
||||||
|
GPIO_PORT_DATA = 1;
|
||||||
|
GPIO_PORT_DATA = 1;
|
||||||
|
|
||||||
|
sLocked = FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool8 SiiRtcGetDateTime(struct SiiRtcInfo *rtc)
|
||||||
|
{
|
||||||
|
u8 i;
|
||||||
|
|
||||||
|
if (sLocked == TRUE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
sLocked = TRUE;
|
||||||
|
|
||||||
|
GPIO_PORT_DATA = 1;
|
||||||
|
GPIO_PORT_DATA = 5;
|
||||||
|
|
||||||
|
GPIO_PORT_DIRECTION = 7;
|
||||||
|
|
||||||
|
WriteCommand(CMD_DATETIME | RD);
|
||||||
|
|
||||||
|
GPIO_PORT_DIRECTION = 5;
|
||||||
|
|
||||||
|
for (i = 0; i < DATETIME_BUF_LEN; i++)
|
||||||
|
DATETIME_BUF(rtc, i) = ReadData();
|
||||||
|
|
||||||
|
INFO_BUF(rtc, OFFSET_HOUR) &= 0x7F;
|
||||||
|
|
||||||
|
GPIO_PORT_DATA = 1;
|
||||||
|
GPIO_PORT_DATA = 1;
|
||||||
|
|
||||||
|
sLocked = FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool8 SiiRtcSetDateTime(struct SiiRtcInfo *rtc)
|
||||||
|
{
|
||||||
|
u8 i;
|
||||||
|
|
||||||
|
if (sLocked == TRUE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
sLocked = TRUE;
|
||||||
|
|
||||||
|
GPIO_PORT_DATA = 1;
|
||||||
|
GPIO_PORT_DATA = 5;
|
||||||
|
|
||||||
|
GPIO_PORT_DIRECTION = 7;
|
||||||
|
|
||||||
|
WriteCommand(CMD_DATETIME | WR);
|
||||||
|
|
||||||
|
for (i = 0; i < DATETIME_BUF_LEN; i++)
|
||||||
|
WriteData(DATETIME_BUF(rtc, i));
|
||||||
|
|
||||||
|
GPIO_PORT_DATA = 1;
|
||||||
|
GPIO_PORT_DATA = 1;
|
||||||
|
|
||||||
|
sLocked = FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool8 SiiRtcGetTime(struct SiiRtcInfo *rtc)
|
||||||
|
{
|
||||||
|
u8 i;
|
||||||
|
|
||||||
|
if (sLocked == TRUE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
sLocked = TRUE;
|
||||||
|
|
||||||
|
GPIO_PORT_DATA = 1;
|
||||||
|
GPIO_PORT_DATA = 5;
|
||||||
|
|
||||||
|
GPIO_PORT_DIRECTION = 7;
|
||||||
|
|
||||||
|
WriteCommand(CMD_TIME | RD);
|
||||||
|
|
||||||
|
GPIO_PORT_DIRECTION = 5;
|
||||||
|
|
||||||
|
for (i = 0; i < TIME_BUF_LEN; i++)
|
||||||
|
TIME_BUF(rtc, i) = ReadData();
|
||||||
|
|
||||||
|
INFO_BUF(rtc, OFFSET_HOUR) &= 0x7F;
|
||||||
|
|
||||||
|
GPIO_PORT_DATA = 1;
|
||||||
|
GPIO_PORT_DATA = 1;
|
||||||
|
|
||||||
|
sLocked = FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool8 SiiRtcSetTime(struct SiiRtcInfo *rtc)
|
||||||
|
{
|
||||||
|
u8 i;
|
||||||
|
|
||||||
|
if (sLocked == TRUE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
sLocked = TRUE;
|
||||||
|
|
||||||
|
GPIO_PORT_DATA = 1;
|
||||||
|
GPIO_PORT_DATA = 5;
|
||||||
|
|
||||||
|
GPIO_PORT_DIRECTION = 7;
|
||||||
|
|
||||||
|
WriteCommand(CMD_TIME | WR);
|
||||||
|
|
||||||
|
for (i = 0; i < TIME_BUF_LEN; i++)
|
||||||
|
WriteData(TIME_BUF(rtc, i));
|
||||||
|
|
||||||
|
GPIO_PORT_DATA = 1;
|
||||||
|
GPIO_PORT_DATA = 1;
|
||||||
|
|
||||||
|
sLocked = FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool8 SiiRtcSetAlarm(struct SiiRtcInfo *rtc)
|
||||||
|
{
|
||||||
|
u8 i;
|
||||||
|
u8 alarmData[2];
|
||||||
|
|
||||||
|
if (sLocked == TRUE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
sLocked = TRUE;
|
||||||
|
|
||||||
|
// Decode BCD.
|
||||||
|
alarmData[0] = (rtc->alarmHour & 0xF) + 10 * ((rtc->alarmHour >> 4) & 0xF);
|
||||||
|
|
||||||
|
// The AM/PM flag must be set correctly even in 24-hour mode.
|
||||||
|
|
||||||
|
if (alarmData[0] < 12)
|
||||||
|
alarmData[0] = rtc->alarmHour | ALARM_AM;
|
||||||
|
else
|
||||||
|
alarmData[0] = rtc->alarmHour | ALARM_PM;
|
||||||
|
|
||||||
|
alarmData[1] = rtc->alarmMinute;
|
||||||
|
|
||||||
|
GPIO_PORT_DATA = 1;
|
||||||
|
GPIO_PORT_DATA = 5;
|
||||||
|
|
||||||
|
GPIOPortDirection = 7; // Why is this the only instance that uses a symbol?
|
||||||
|
|
||||||
|
WriteCommand(CMD_ALARM | WR);
|
||||||
|
|
||||||
|
for (i = 0; i < 2; i++)
|
||||||
|
WriteData(alarmData[i]);
|
||||||
|
|
||||||
|
GPIO_PORT_DATA = 1;
|
||||||
|
GPIO_PORT_DATA = 1;
|
||||||
|
|
||||||
|
sLocked = FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int WriteCommand(u8 value)
|
||||||
|
{
|
||||||
|
u8 i;
|
||||||
|
u8 temp;
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
temp = ((value >> (7 - i)) & 1);
|
||||||
|
GPIO_PORT_DATA = (temp << 1) | 4;
|
||||||
|
GPIO_PORT_DATA = (temp << 1) | 4;
|
||||||
|
GPIO_PORT_DATA = (temp << 1) | 4;
|
||||||
|
GPIO_PORT_DATA = (temp << 1) | 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
// control reaches end of non-void function
|
||||||
|
}
|
||||||
|
|
||||||
|
static int WriteData(u8 value)
|
||||||
|
{
|
||||||
|
u8 i;
|
||||||
|
u8 temp;
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
temp = ((value >> i) & 1);
|
||||||
|
GPIO_PORT_DATA = (temp << 1) | 4;
|
||||||
|
GPIO_PORT_DATA = (temp << 1) | 4;
|
||||||
|
GPIO_PORT_DATA = (temp << 1) | 4;
|
||||||
|
GPIO_PORT_DATA = (temp << 1) | 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
// control reaches end of non-void function
|
||||||
|
}
|
||||||
|
|
||||||
|
static u8 ReadData()
|
||||||
|
{
|
||||||
|
u8 i;
|
||||||
|
u8 temp;
|
||||||
|
u8 value;
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
GPIO_PORT_DATA = 4;
|
||||||
|
GPIO_PORT_DATA = 4;
|
||||||
|
GPIO_PORT_DATA = 4;
|
||||||
|
GPIO_PORT_DATA = 4;
|
||||||
|
GPIO_PORT_DATA = 4;
|
||||||
|
GPIO_PORT_DATA = 5;
|
||||||
|
|
||||||
|
temp = ((GPIO_PORT_DATA & 2) >> 1);
|
||||||
|
value = (value >> 1) | (temp << 7); // UB: accessing uninitialized var
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void EnableGpioPortRead()
|
||||||
|
{
|
||||||
|
GPIO_PORT_READ_ENABLE = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DisableGpioPortRead()
|
||||||
|
{
|
||||||
|
GPIO_PORT_READ_ENABLE = 0;
|
||||||
|
}
|
@ -497,11 +497,6 @@ gUnknown_03001300: @ 3001300
|
|||||||
.space 0x770
|
.space 0x770
|
||||||
|
|
||||||
.include "src/agb_flash.o"
|
.include "src/agb_flash.o"
|
||||||
|
.include "src/siirtc.o"
|
||||||
.space 0x2
|
|
||||||
|
|
||||||
gUnknown_03001A7E: @ 3001A7E
|
|
||||||
.space 0x2
|
|
||||||
|
|
||||||
.include "tools/agbcc/lib/libgcc.a:dp-bit.o"
|
.include "tools/agbcc/lib/libgcc.a:dp-bit.o"
|
||||||
.include "tools/agbcc/lib/libgcc.a:fp-bit.o"
|
.include "tools/agbcc/lib/libgcc.a:fp-bit.o"
|
||||||
|
Loading…
Reference in New Issue
Block a user