Real-Time Clock

From WikiPrizm
Revision as of 19:14, 10 February 2015 by Gbl08ma (talk | contribs) (Add information on how the RTC is used by the OS)
Jump to navigationJump to search

The SH7305 core used on the Prizm has a Real-Time Clock (RTC) unit that is compatible with the one found on the SH7720. The RTC is used by the operating system, but by default there's no way for the user to see or set the date and time as kept by the unit. The RTC resets to a date sometime in 2010, every time the calculator has its power supply removed. The RTC always starts every time the calculator is booted.

The RTC hardware is made up of a large number of counters and a few timers. The RTC unit contains a 32.768kHz oscillator and a 128 Hz timer that provides an internal tick to all of the counters. The 128 Hz timer (from the prescaler), when it carries, increments the 64 Hz counter (R64CNT). Each counter, when carried, increments another counter, and so forth. The 128 Hz timer cannot be directly accessed, but the carries of it are shown in bit 0 of R64CNT.

The counters allow you to keep track of the hh:mm:ss dd/mm/yy (with leap year adjustments).

OS usage

The OS only appears to use the RTC for things like the backlight timeout, power-off timeout, intended human-perceptible delays like the Casio logo display as power-off screen, 3-pin communication timeouts and E-Con2 sample collection at specified intervals. Despite the existence of syscalls that operate on date and time values such as RTC_GetTime, the OS doesn't give the user the opportunity to see the current time and date, nor adjust them, possibly in an effort to simplify the user experience as such adjustment is not necessary for the use the OS makes of the RTC.

The OS appears to have no problems with add-in software reading and adjusting the RTC to their liking, making possible its use as a general timekeeping device.

Counters and Timers

R64CNT - 64-Hz counter

Address: 0xA413FEC0

Size: 8 bits

The RTC contains a 32.768kHz oscillator. The prescaler uses that to create a 128Hz timer that, when carries, increments this counter. See the example on how to reset this counter and the prescaler.

Bits

  • Bit 0 (R): 64 Hz counter
  • Bit 1 (R): 32 Hz counter
  • Bit 2 (R): 16 Hz counter
  • Bit 3 (R): 8 Hz counter
  • Bit 4 (R): 4 Hz counter
  • Bit 5 (R): 2 Hz counter
  • Bit 6 (R): 1 Hz counter
  • Bit 7 (R): Reserved and set to 0

Comments

Since the 128 Hz timer adds the carry to this counter, bit 0 will be 1 for 1/128s and 0 for 1/128s.

Examples

Time Delay

This is untested!

This causes a loss of precision in the RTC as the clock's 64 Hz timer is reset. Make sure to back up the time before running this!

void delay_bitmask(unsigned char mask)
{
  volatile unsigned char *R64CNT = 0x0xA413FEC0;
  volatile unsigned char *RCR2 = 0xA413FEDE;

  *RCR2 |= 0b10; // reset the prescaler and R64CNT - See RCR2 for more information
  while((*R64CNT & mask) == 0); // wait for rise
  while((*R64CNT & mask) == 1); // wait for fall
}
// Pass a bitfield to wait for that time.  For ex., 0b00100000 will wait for 0.5 seconds

RSECCNT - Second Counter

Address: 0xA413FEC2

Size: 8 bits

Bits

  • Bits 0 to 3 (R/W): Counts the one's place, digits 0 to 9. When this carries, the ten's place is incremented.
  • Bits 4 to 6 (R/W): Counts the ten's place, digits 0 to 5.
  • Bit 7 (R): Reserved and set to 0

Comments

As the above section states, this counter is a packed digit counter made to simplify the method of converting to characters. Write to this only after stopping the RTC.

Examples

Time Delay

This changes the stored time! Be careful when using!

void waitsecond(void)
{
  volatile unsigned char *RCR2 = 0xA413FEDE;
  volatile unsigned char *RSECCNT = 0xA413FEC2;

  *RCR2 ^= 0b11;
  *RSECCNT = 0;
  *RCR2 |= 0b1;

  while(*RSECCNT != 1);
}

RMINCNT - Minute Counter

Address: 0xA413FEC4

Size: 8 bits

Bits

  • Bits 0 to 3 (R/W): Counts the one's place, digits 0 to 9. When this carries, the ten's place is incremented.
  • Bits 4 to 6 (R/W): Counts the ten's place, digits 0 to 5.
  • Bit 7 (R): Reserved and set to 0

Comments

Same as the second counter. Write to this only after stopping the RTC.

RHRCNT - Hour Counter

Address: 0xA413FEC6

Size: 8 bits

Bits

  • Bits 0 to 3 (R/W): Counts the one's place, digits 0 to 9. When this carries, the ten's place is incremented.
  • Bits 4 to 5 (R/W): Counts the ten's place, digits 0 to 2.
  • Bits 6 to 7 (R): Reserved and set to 0

Comments

Same as the minute counter.

RWKCNT - Day of Week Counter

Address: 0xA413FEC8

Size: 8 bits

Bits

  • Bits 0 to 2 (R/W): Day of week as a 3 bit number from 0 to 6. See the comments.
  • Bits 3 to 7 (R): Reserved and set to 0

Comments

Note: You must set this when setting the clock! This register is not calculated depending on the day/month/year provided, this is simply a counter.

Make sure to stop the RTC before writing to this counter. The days of the week are specified below:

Days of week
Bit Day
000 Sunday
001 Monday
010 Tuesday
011 Wednesday
100 Thursday
101 Friday
110 Saturday
111 Reserved

RDAYCNT - Date Counter

Address: 0xA413FECA

Size: 8 bits

Bits

  • Bits 0 to 3 (R/W): Counts the one's place, digits 0 to 9. When this carries, the ten's place is incremented.
  • Bits 4 to 5 (R/W): Counts the ten's place, digits 0 to 2.
  • Bits 6 to 7 (R): Reserved and set to 0

Comments

The range of valid dates change due to the varying number of days per month. Days start at 1, not 0, for this counter. If a date is written out of range for the month, invalid operation will result. Make sure to stop the RTC before writing.

RMONCNT - Month Counter

Address: 0xA413FECC

Size: 8 bits

Bits

  • Bits 0 to 3 (R/W): Counts the one's place, digits 0 to 9. When this carries, the ten's place is incremented.
  • Bit 4 (R/W): Counts the ten's place, 0 or 1.
  • Bits 5 to 7 (R): Reserved and set to 0

Comments

The accepted range of values is 1 to 12. If a month is written out of range, invalid operation will result. Make sure to stop the RTC before writing.

RYRCNT - Year Counter

Address: 0xA413FECE

Size: 16 bits

Bits

  • Bits 0 to 3 (R/W): Counts the one's place of the year.
  • Bits 4 to 7 (R/W): Counts the ten's place of the year.
  • Bits 8 to 11 (R/W): Counts the hundred's place of the year.
  • Bits 12 to 15 (R/W): Counts the thousand's place of the year.

Comments

The accepted range of values is 0000 to 9999. If a year is written out of range, invalid operation will result. Make sure to stop the RTC before writing.

RCR2 - RTC Control Register 2

Address: 0xA413FEDE

Size: 8 bits

Bits

  • Bit 0 (R/W): Start bit. Set to start the hh:mm:ss dd/mm/yy counters. Reset to stop. This must be set to 0 if you are going to change any time counter. Note: R64CNT still operates as normal, carries are not added to RSECCNT.
  • Bit 1 (R/W): Resets the divider circuit (RTC prescaler and R64CNT). This bit always reads 0. Write 1 to reset.
  • Bit 2 (R/W): 30 second adjust. Rounds up the second counter if 30 or above. Rounds down if <29. This also resets the divider circuit (RTC prescaler and R64CNT). Set to round. Always reads 0.
  • Bit 3 (R/W): Set to halt the crystal oscillator for the RTC, reset to start.
  • Bits 4 to 6 (R/W): Specifies the period of interrupts. See comments.
  • Bit 7 (R/W): Set either manually or by the RTC. Causes an interrupt to trigger. Reset to acknowledge the interrupt. Bits 4 to 6 control the interrupt.

Comments

Bits 4 to 6 control the periodic interrupt as follows:

Interrupt Enable Flags
Bits Seconds until interrupt is fired
000 Interrupts disabled
001 1/256s
010 1/64s
011 1/16s
100 1/4s
101 1/2s
110 1 second
111 2 seconds

Examples

Below are outlines on how to use the RTC hardware.

Reading the time

This section highlights what will happen if a counter changes and how to handle it. Registers used below may not be documented!

  1. Disable the carry interrupt by resetting bit 4 of RCR1
  2. Clear the carry flag by resetting bit 7 of RCR1
  3. Read the counter register(s)
  4. If bit 7 of RCR1 is set, go to step 2

Setting the time

  1. Stop the clock and reset the divider circuits by using RCR2.
  2. Write to the counters as needed in any order
  3. Start the clock by setting bit 0 of RCR1