The functions are mostly based on the RTC library of VS1005, but some modifications have been made. The major difference between VS1010 and VS1005 RTCs is that the VS1010 doesn't have a RAM, unlike the VS1005. This is somewhat remedied by using a 32-bit shifter register in the VS1010. If the RTC battery has been attached, the shifter register can be used to store a small amount of data while the device is otherwise powered down. Naturally the actual RTC counter is also functional with just the battery. The RTC also functions with only the 5V power. However, note that attaching or removing the battery can often cause the counter to lose it's value. Ideally the battery should be kept connected at all times.
This thread also includes a few programs which use the RTC. If you wish to see more detailed explanations for anything, take a look at the comments in the source code files.
The RTC has three interface registers. Two of them are 16-bit data registers, RTC_LOW and RTC_HIGH. The third is a 5-bit control and status register RTC_CF. The addresses, control bits and instructions have been defined in vs1010bRom.h. The first function in rtc.c is a small helper function, which is used to control the RTC_CF register.
Code: Select all
void StartAndWaitRtcReady(register u_int16 rtcCfBits) {
PERIP(RTC_CF) = rtcCfBits;
while (PERIP(RTC_CF));
}
Code: Select all
void WriteShifter(u_int32 data) {
PERIP(RTC_HIGH) = 0;
StartAndWaitRtcReady(RTC_CF_IBUSY);
PERIP(RTC_HIGH) = (u_int16)(data >> 16);
PERIP(RTC_LOW) = (u_int16)data;
StartAndWaitRtcReady(RTC_CF_DBUSY);
}
Code: Select all
u_int32 ReadShifter() {
u_int32 shifter;
StartAndWaitRtcReady(RTC_CF_RDBUSY);
shifter = (((u_int32)PERIP(RTC_HIGH)) << 16) | (u_int32)PERIP(RTC_LOW);
WriteShifter(shifter);
return shifter;
}
From here on, every function will begin with reading the shifter's value, and end with writing it back. Otherwise running the other operations would cause the data to be lost.
Code: Select all
unsigned long GetRtc(void) {
u_int32 shifter = ReadShifter();
u_int32 rtc;
PERIP(RTC_HIGH) = RTC_I_READRTC;
StartAndWaitRtcReady(RTC_CF_IBUSY);
StartAndWaitRtcReady(RTC_CF_RDBUSY);
rtc = (((u_int32)PERIP(RTC_HIGH)) << 16) | (u_int32)PERIP(RTC_LOW);
WriteShifter(shifter);
return rtc;
}
Code: Select all
u_int32 SetRtc(register u_int32 t) {
u_int32 shifter = ReadShifter();
PERIP(RTC_HIGH) = RTC_I_LOADRTC;
StartAndWaitRtcReady(RTC_CF_IBUSY);
PERIP(RTC_HIGH) = (u_int16)(t >> 16);
PERIP(RTC_LOW) = (u_int16)t;
StartAndWaitRtcReady(RTC_CF_DBUSY);
PERIP(RTC_CF) = RTC_CF_EXEC;
printf("Delay starts \n");
DelayL(10000000);
printf("Delay ends \n");
PERIP(RTC_CF) = 0;
WriteShifter(shifter);
return t;
}
Code: Select all
u_int16 GetRtc128(void) {
u_int32 shifter = ReadShifter();
u_int32 rtc128;
PERIP(RTC_HIGH) = RTC_I_DIV128;
StartAndWaitRtcReady(RTC_CF_IBUSY);
StartAndWaitRtcReady(RTC_CF_RDBUSY);
rtc128 = (PERIP(RTC_HIGH) >> 9) ^ 64;
WriteShifter(shifter);
return rtc128;
}
The rtc.h and rtc.c files are available for download below. There are also four small additional programs, which are each used for calling one of the rtc functions. WShifter and RShifter are for writing and reading shifter values, and RtcSet and RtcGet are for writing and reading the RTC counter values. The dlx.zip package includes all the .dlx files.