make the date/time registers writable
This commit is contained in:
parent
a1a6d0ddb8
commit
cb09bd414b
144
src/RTC.cpp
144
src/RTC.cpp
|
@ -85,6 +85,7 @@ void Reset()
|
||||||
|
|
||||||
CurCmd = 0;
|
CurCmd = 0;
|
||||||
|
|
||||||
|
MinuteCount = 0;
|
||||||
ResetRegisters();
|
ResetRegisters();
|
||||||
|
|
||||||
ClockCount = 0;
|
ClockCount = 0;
|
||||||
|
@ -137,7 +138,6 @@ void ResetRegisters()
|
||||||
ClockAdjust = 0;
|
ClockAdjust = 0;
|
||||||
FreeReg = 0;
|
FreeReg = 0;
|
||||||
|
|
||||||
MinuteCount = 0;
|
|
||||||
FOUT1 = 0;
|
FOUT1 = 0;
|
||||||
FOUT2 = 0;
|
FOUT2 = 0;
|
||||||
memset(AlarmDate1, 0, sizeof(AlarmDate1));
|
memset(AlarmDate1, 0, sizeof(AlarmDate1));
|
||||||
|
@ -145,6 +145,11 @@ void ResetRegisters()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
u8 BCD(u8 val)
|
||||||
|
{
|
||||||
|
return (val % 10) | ((val / 10) << 4);
|
||||||
|
}
|
||||||
|
|
||||||
u8 BCDIncrement(u8 val)
|
u8 BCDIncrement(u8 val)
|
||||||
{
|
{
|
||||||
val++;
|
val++;
|
||||||
|
@ -155,6 +160,18 @@ u8 BCDIncrement(u8 val)
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u8 BCDSanitize(u8 val, u8 vmin, u8 vmax)
|
||||||
|
{
|
||||||
|
if (val < vmin || val > vmax)
|
||||||
|
val = vmin;
|
||||||
|
else if ((val & 0x0F) >= 0x0A)
|
||||||
|
val = vmin;
|
||||||
|
else if ((val & 0xF0) >= 0xA0)
|
||||||
|
val = vmin;
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
u8 DaysInMonth()
|
u8 DaysInMonth()
|
||||||
{
|
{
|
||||||
u8 numdays;
|
u8 numdays;
|
||||||
|
@ -213,6 +230,15 @@ void CountMonth()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CheckEndOfMonth()
|
||||||
|
{
|
||||||
|
if (DateTime[2] > DaysInMonth())
|
||||||
|
{
|
||||||
|
DateTime[2] = 1;
|
||||||
|
CountMonth();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CountDay()
|
void CountDay()
|
||||||
{
|
{
|
||||||
// day-of-week counter
|
// day-of-week counter
|
||||||
|
@ -221,11 +247,7 @@ void CountDay()
|
||||||
|
|
||||||
// day counter
|
// day counter
|
||||||
DateTime[2] = BCDIncrement(DateTime[2]);
|
DateTime[2] = BCDIncrement(DateTime[2]);
|
||||||
if (DateTime[2] > DaysInMonth())
|
CheckEndOfMonth();
|
||||||
{
|
|
||||||
DateTime[2] = 1;
|
|
||||||
CountMonth();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CountHour()
|
void CountHour()
|
||||||
|
@ -309,11 +331,59 @@ void ClockTimer(u32 param)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
u8 BCD(u8 val)
|
void WriteDateTime(int num, u8 val)
|
||||||
{
|
{
|
||||||
return (val % 10) | ((val / 10) << 4);
|
switch (num)
|
||||||
}
|
{
|
||||||
|
case 1: // year
|
||||||
|
DateTime[0] = BCDSanitize(val, 0x00, 0x99);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2: // month
|
||||||
|
DateTime[1] = BCDSanitize(val & 0x1F, 0x01, 0x12);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3: // day
|
||||||
|
DateTime[2] = BCDSanitize(val & 0x3F, 0x01, 0x31);
|
||||||
|
CheckEndOfMonth();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4: // day of week
|
||||||
|
DateTime[3] = BCDSanitize(val & 0x07, 0x00, 0x06);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5: // hour
|
||||||
|
{
|
||||||
|
u8 hour = val & 0x3F;
|
||||||
|
u8 pm = val & 0x40;
|
||||||
|
|
||||||
|
if (StatusReg1 & (1<<1))
|
||||||
|
{
|
||||||
|
// 24-hour mode
|
||||||
|
|
||||||
|
hour = BCDSanitize(hour, 0x00, 0x23);
|
||||||
|
pm = (hour >= 0x12) ? 0x40 : 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 12-hour mode
|
||||||
|
|
||||||
|
hour = BCDSanitize(hour, 0x00, 0x11);
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime[4] = hour | pm;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 6: // minute
|
||||||
|
DateTime[5] = BCDSanitize(val & 0x7F, 0x00, 0x59);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 7: // second
|
||||||
|
DateTime[6] = BCDSanitize(val & 0x7F, 0x00, 0x59);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CmdRead()
|
void CmdRead()
|
||||||
{
|
{
|
||||||
|
@ -412,43 +482,67 @@ void CmdWrite(u8 val)
|
||||||
switch (CurCmd & 0x70)
|
switch (CurCmd & 0x70)
|
||||||
{
|
{
|
||||||
case 0x00:
|
case 0x00:
|
||||||
if (InputPos == 1) StatusReg1 = val & 0x0E;
|
if (InputPos == 1)
|
||||||
|
{
|
||||||
|
u8 oldval = StatusReg1;
|
||||||
|
|
||||||
|
if (val & (1<<0)) // reset
|
||||||
|
ResetRegisters();
|
||||||
|
|
||||||
|
StatusReg1 = (StatusReg1 & 0xF0) | (val & 0x0E);
|
||||||
|
|
||||||
|
if ((StatusReg1 ^ oldval) & (1<<1)) // AM/PM changed
|
||||||
|
WriteDateTime(5, DateTime[4]);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x40:
|
case 0x40:
|
||||||
if (InputPos == 1) StatusReg2 = val;
|
if (InputPos == 1)
|
||||||
if (StatusReg2 & 0x4F) Log(LogLevel::Debug, "RTC INTERRUPT ON: %02X\n", StatusReg2);
|
{
|
||||||
|
StatusReg2 = val;
|
||||||
|
if (StatusReg2 & 0x4F) Log(LogLevel::Debug, "RTC INTERRUPT ON: %02X\n", StatusReg2);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x20:
|
case 0x20:
|
||||||
// TODO: set time somehow??
|
if (InputPos <= 7)
|
||||||
|
WriteDateTime(InputPos, val);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x60:
|
case 0x60:
|
||||||
// same shit
|
if (InputPos <= 3)
|
||||||
|
WriteDateTime(InputPos+4, val);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x10:
|
case 0x10:
|
||||||
if (StatusReg2 & 0x04)
|
if (StatusReg2 & 0x04)
|
||||||
{
|
{
|
||||||
if (InputPos <= 3) Alarm1[InputPos-1] = val;
|
if (InputPos <= 3)
|
||||||
|
Alarm1[InputPos-1] = val;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (InputPos == 1) Alarm1[2] = val;
|
if (InputPos == 1)
|
||||||
|
Alarm1[2] = val;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x50:
|
case 0x50:
|
||||||
if (InputPos <= 3) Alarm2[InputPos-1] = val;
|
if (InputPos <= 3)
|
||||||
|
Alarm2[InputPos-1] = val;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x30:
|
case 0x30:
|
||||||
if (InputPos == 1) ClockAdjust = val;
|
if (InputPos == 1)
|
||||||
|
{
|
||||||
|
ClockAdjust = val;
|
||||||
|
Log(LogLevel::Debug, "RTC: CLOCK ADJUST = %02X\n", val);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x70:
|
case 0x70:
|
||||||
if (InputPos == 1) FreeReg = val;
|
if (InputPos == 1)
|
||||||
|
FreeReg = val;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -469,19 +563,23 @@ void CmdWrite(u8 val)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x40:
|
case 0x40:
|
||||||
if (InputPos == 1) FOUT1 = val;
|
if (InputPos == 1)
|
||||||
|
FOUT1 = val;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x20:
|
case 0x20:
|
||||||
if (InputPos == 1) FOUT2 = val;
|
if (InputPos == 1)
|
||||||
|
FOUT2 = val;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x10:
|
case 0x10:
|
||||||
if (InputPos <= 3) AlarmDate1[InputPos-1] = val;
|
if (InputPos <= 3)
|
||||||
|
AlarmDate1[InputPos-1] = val;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x50:
|
case 0x50:
|
||||||
if (InputPos <= 3) AlarmDate2[InputPos-1] = val;
|
if (InputPos <= 3)
|
||||||
|
AlarmDate2[InputPos-1] = val;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Reference in New Issue