Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
253 lines
7.0 KiB
C
253 lines
7.0 KiB
C
// ____________________________
|
|
// ██▀▀█▀▀██▀▀▀▀▀▀▀█▀▀█ │ ▄▄ ▄▄ ▄▄
|
|
// ██ ▀ █▄ ▀██▄ ▀ ▄█ ▄▀▀ █ │ ██ ▀ ██ ▄█▀▄ ▄█▀▀ ██▄▀
|
|
// █ █ █ ▀▀ ▄█ █ █ ▀▄█ █▄ │ ▀█▄▀ ▀█▄ ▀█▄▀ ▀█▄▄ ██ █
|
|
// ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀────────┘
|
|
// by Guillaume 'Aoineko' Blanchard under CC BY-SA license
|
|
//─────────────────────────────────────────────────────────────────────────────
|
|
// Real-time clock module (RP-5C01)
|
|
//
|
|
// Réferences:
|
|
// - Ricoh RP/RF5C01A application manual
|
|
// - https://www.msx.org/wiki/Ricoh_RP-5C01
|
|
//─────────────────────────────────────────────────────────────────────────────
|
|
#include "clock.h"
|
|
|
|
#if (MSX_VERSION >= MSX_2)
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Write data in CMOS
|
|
void RTC_WriteRaw(u8 reg, u8* data, u8 num)
|
|
{
|
|
for (u8 i = 0; i < num; ++i)
|
|
{
|
|
RTC_Write(reg++, *data & 0xF);
|
|
RTC_Write(reg++, *data >> 4);
|
|
data++;
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Read data from CMOS
|
|
void RTC_ReadRaw(u8 reg, u8* data, u8 num)
|
|
{
|
|
for (u8 i = 0; i < num; ++i)
|
|
{
|
|
*data = RTC_Read(reg++);
|
|
*data |= RTC_Read(reg++) << 4;
|
|
data++;
|
|
}
|
|
}
|
|
|
|
#if (RTC_USE_CLOCK)
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Get current clock second counter (0-59)
|
|
u8 RTC_GetSecond()
|
|
{
|
|
RTC_SetMode(RTC_MODE_TIME);
|
|
u8 ret = RTC_Read(RTC_REG_TIME_SEC);
|
|
ret += 10 * RTC_Read(RTC_REG_TIME_10SEC);
|
|
return ret;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Get current clock minute counter (0-59)
|
|
u8 RTC_GetMinute()
|
|
{
|
|
RTC_SetMode(RTC_MODE_TIME);
|
|
u8 ret = RTC_Read(RTC_REG_TIME_MIN);
|
|
ret += 10 * RTC_Read(RTC_REG_TIME_10MIN);
|
|
return ret;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Get current clock hour counter (0-23)
|
|
u8 RTC_GetHour()
|
|
{
|
|
RTC_SetMode(RTC_MODE_TIME);
|
|
u8 ret = RTC_Read(RTC_REG_TIME_HOUR);
|
|
ret += 10 * RTC_Read(RTC_REG_TIME_10HOUR);
|
|
return ret;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Get current clock day-of-week counter (0-6)
|
|
u8 RTC_GetDayOfWeek()
|
|
{
|
|
RTC_SetMode(RTC_MODE_TIME);
|
|
return RTC_Read(RTC_REG_TIME_WEEKDAY);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Get current clock day counter (1-31)
|
|
u8 RTC_GetDay()
|
|
{
|
|
RTC_SetMode(RTC_MODE_TIME);
|
|
u8 ret = RTC_Read(RTC_REG_TIME_DAY);
|
|
ret += 10 * RTC_Read(RTC_REG_TIME_10DAY);
|
|
return ret;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Get current clock month counter (1-12)
|
|
u8 RTC_GetMonth()
|
|
{
|
|
RTC_SetMode(RTC_MODE_TIME);
|
|
u8 ret = RTC_Read(RTC_REG_TIME_MONTH);
|
|
ret += 10 * RTC_Read(RTC_REG_TIME_10MONTH);
|
|
return ret;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Get current clock year counter (0-99)
|
|
u8 RTC_GetYear()
|
|
{
|
|
RTC_SetMode(RTC_MODE_TIME);
|
|
u8 ret = RTC_Read(RTC_REG_TIME_YEAR);
|
|
ret += 10 * RTC_Read(RTC_REG_TIME_10YEAR);
|
|
return ret;
|
|
}
|
|
|
|
#if (RTC_USE_CLOCK_EXTRA)
|
|
|
|
const c8* g_RTC_DayOfWeek[] = {
|
|
"Sunday",
|
|
"Monday",
|
|
"Tuesday",
|
|
"Wednesday",
|
|
"Thursday",
|
|
"Friday",
|
|
"Saturday",
|
|
};
|
|
|
|
const c8* g_RTC_Month[] = {
|
|
"January",
|
|
"February",
|
|
"March",
|
|
"April",
|
|
"May",
|
|
"June",
|
|
"July",
|
|
"August",
|
|
"September",
|
|
"October",
|
|
"November",
|
|
"December",
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Get current clock day of week string
|
|
const c8* RTC_GetDayOfWeekString()
|
|
{
|
|
return g_RTC_DayOfWeek[RTC_GetDayOfWeek()];
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Get current clock month counter string
|
|
const c8* RTC_GetMonthString()
|
|
{
|
|
return g_RTC_Month[RTC_GetMonth() - 1];
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Get current clock 4-number year counter (1980-2079)
|
|
u16 RTC_GetYear4()
|
|
{
|
|
return 1980 + RTC_GetYear();
|
|
}
|
|
|
|
#endif // (RTC_USE_CLOCK_EXTRA)
|
|
#endif // (RTC_USE_CLOCK)
|
|
|
|
#if (RTC_USE_SAVEDATA)
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Save 6 bytes data to CMOS's block 3
|
|
void RTC_SaveData(u8* data)
|
|
{
|
|
RTC_SetMode(RTC_MODE_BLOCK_3);
|
|
RTC_Write(0, RTC_DATA_SAVE);
|
|
RTC_WriteRaw(1, data, 6);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Load 6 bytes data from CMOS's block 3
|
|
bool RTC_LoadData(u8* data)
|
|
{
|
|
RTC_SetMode(RTC_MODE_BLOCK_3);
|
|
if (RTC_Read(0) != RTC_DATA_SAVE) // Check data type
|
|
return FALSE;
|
|
RTC_ReadRaw(1, data, 6);
|
|
return TRUE;
|
|
}
|
|
|
|
#endif // (RTC_USE_SAVEDATA)
|
|
|
|
|
|
#if (defined(APPSIGN) && RTC_USE_SAVESIGNED)
|
|
|
|
extern const u32 g_AppSignature;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Save 6 bytes data to CMOS's block 3
|
|
void RTC_SaveDataSigned(u8* data)
|
|
{
|
|
// Write application signature
|
|
RTC_SetMode(RTC_MODE_BLOCK_1);
|
|
const u8* sign = (const u8*)&g_AppSignature;
|
|
// Signature 1st byte (company LSB)
|
|
RTC_Write(2, *sign & 0xF ); // 4 bits
|
|
RTC_Write(3, *sign >> 4 & 0x7 ); // 3 bits
|
|
sign++;
|
|
// Signature 2nd byte (company MSB)
|
|
RTC_Write(4, *sign & 0xF ); // 4 bits
|
|
RTC_Write(6, *sign >> 4 & 0x7 ); // 3 bits
|
|
sign++;
|
|
// Signature 4th byte (product LSB)
|
|
RTC_Write(5, *sign & 0x3 ); // 2 bits
|
|
RTC_Write(7, *sign >> 2 & 0xF ); // 4 bits
|
|
RTC_Write(8, *sign >> 6 & 0x3 ); // 2 bits
|
|
|
|
// Write data
|
|
RTC_SetMode(RTC_MODE_BLOCK_3);
|
|
RTC_Write(0, RTC_DATA_SIGNSAVE);
|
|
RTC_WriteRaw(1, data, 6);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Load 6 bytes data from CMOS's block 3
|
|
bool RTC_LoadDataSigned(u8* data)
|
|
{
|
|
// Check application signature
|
|
RTC_SetMode(RTC_MODE_BLOCK_1);
|
|
const u8* sign = (const u8*)&g_AppSignature;
|
|
// Signature 1st byte (company LSB)
|
|
u8 a = *sign & 0x7F;
|
|
u8 b = RTC_Read(2) + (RTC_Read(3) << 4);
|
|
if (a != b)
|
|
return FALSE;
|
|
// Signature 2nd byte (company MSB)
|
|
sign++;
|
|
a = *sign & 0x7F;
|
|
b = RTC_Read(4) + (RTC_Read(6) << 4);
|
|
if (a != b)
|
|
return FALSE;
|
|
// Signature 4th byte (product LSB)
|
|
sign++;
|
|
a = *sign;
|
|
b = RTC_Read(5) + (RTC_Read(7) << 2) + (RTC_Read(8) << 6);
|
|
if (a != b)
|
|
return FALSE;
|
|
|
|
// Load data
|
|
RTC_SetMode(RTC_MODE_BLOCK_3);
|
|
if (RTC_Read(0) != RTC_DATA_SIGNSAVE)
|
|
return FALSE;
|
|
RTC_ReadRaw(1, data, 6);
|
|
return TRUE;
|
|
}
|
|
|
|
#endif // (defined(APPSIGN) && RTC_USE_SAVESIGNED)
|
|
|
|
#endif // (MSX_VERSION >= MSX_2)
|