Skip to main content
added 82 characters in body
Source Link
EmbeddedGuy
  • 558
  • 3
  • 15

The solution is to set the SECONDS alarm register to value of 0x5A (which is in 'RTC-language' same as saying 5-10, in other words one more than 59).

The solution is to set the SECONDS alarm register to value of 0x5A.

The solution is to set the SECONDS alarm register to value of 0x5A (which is in 'RTC-language' same as saying 5-10, in other words one more than 59).

added 1914 characters in body
Source Link
EmbeddedGuy
  • 558
  • 3
  • 15

Still, the fix is pointingI want to my original suspicion, that therehelp others to avoid sleepless nights when debugging this - I had to wait repeated hours to debug the hourly alarm.

There is aan apparent bug in the PIC RTCC module, which showssneaks up in a special case you need anany alarm at rounded time of xx:xx:00 seconds. It It seems that both PIC documentation and Errata are wrong.

Normally you would think to set the ALRMSEC register to 0x00. Errata says to fix the bug, set it to 0x0A. Unfortunately, neither works.

The solution is to set the SECONDS alarm register to 'weird' value of 0x5A. Then the code works, no matter if

Below I want every 1-minute or every 1-hour wake upsgive few examples clarifying this. Remember these basic steps before setting an alarm:

  • enable writing to RTC via RTCWREN register
  • disable alarms via ALRMEN register
  • set how many alarms you need via ALRMRPT register (if infinite, set it to 0xFF and later you must also set the CHIME bit in ALRMCON register)
  • set the desired alarm time in such a way, that minutes are 1_second_before_the_alarm, and the seconds are '1_second_after_the_alarm' (see below examples)
  • set the alarm desired frequency in ALRMCON register (upper bit must be set to enable the alarms)
  • avoid writing to RTC via RTCWREN register
  • clear interrupt flag before enabling interrupts

This single line made it workingThe 'secret' of the solution is in setting the value of the ALRMMIN and ALRMSEC registers:

ALRMSEC = 0x5A; // seconds *
 //* errorError in both MCU and ERRATA docsdocuments:
 (if* alarmIf needsthe toalarm shall occur at :00 seconds -> ErrataERRATA saidasks for 0x0A, but needsit has to be 0x5A!
 * 
 * EXAMPLES:
 *     For an alarm every minute on the minute, write       xx:xx:5A (HRS/MIN/SEC) // wakes at xx:00:00, xx:01:00, xx:02:00, xx:03:00, ...
 *     For an alarm every 10-minutes, write                 xx:09:5A (HRS/MIN/SEC) // wakes at xx:00:00, xx:10:00, xx:20:00, xx:30:00, ...
 *     For an alarm every hour on the hour, write           xx:59:5A (HRS/MIN/SEC) // wakes at x0:00:00, x1:00:00, x2:00:00, x3:00:00, ...
 *     For an alarm every hour at 01-minute, write          xx:00:5A (HRS/MIN/SEC) // wakes at x0:01:00, x1:01:00, x2:01:00, x3:01:00, ...
 * 
 * 0x5A is in BCD as five-ten (5-10), replacing the expected 5-9 (decimal "59" on the clock)
 * Likely the rollover mechanism in the PIC has this simple bug, that to get the rollover impulse the last digit needs ten instead of nine.
 */
ALRMMIN = 0x59; // minutes
ALRMSEC = 0x5A; // seconds

/*
 * Alarm control register
 */
ALRMCON = ALRMCTRL__REPEAT_INDEFINITELY | ALRMCTRL__EVERY_HOUR;

/*
 * Enable the alarm 
 */
ALRMCONbits.ALRMEN = 1;

Still, the fix is pointing to my original suspicion, that there is a bug in the PIC RTCC module, which shows in a special case you need an alarm at xx:xx:00 seconds. It seems that both PIC documentation and Errata are wrong.

The solution is to set the SECONDS alarm register to 'weird' value of 0x5A. Then the code works, no matter if I want every 1-minute or every 1-hour wake ups.

This single line made it working:

ALRMSEC = 0x5A; // seconds  // error in both MCU and ERRATA docs (if alarm needs to occur at 00 seconds - Errata said 0x0A, but needs 0x5A)

I want to help others to avoid sleepless nights when debugging this - I had to wait repeated hours to debug the hourly alarm.

There is an apparent bug in the PIC RTCC module, which sneaks up in a case you need any alarm at rounded time of xx:xx:00 seconds. It seems that both PIC documentation and Errata are wrong.

Normally you would think to set the ALRMSEC register to 0x00. Errata says to fix the bug, set it to 0x0A. Unfortunately, neither works.

The solution is to set the SECONDS alarm register to value of 0x5A.

Below I give few examples clarifying this. Remember these basic steps before setting an alarm:

  • enable writing to RTC via RTCWREN register
  • disable alarms via ALRMEN register
  • set how many alarms you need via ALRMRPT register (if infinite, set it to 0xFF and later you must also set the CHIME bit in ALRMCON register)
  • set the desired alarm time in such a way, that minutes are 1_second_before_the_alarm, and the seconds are '1_second_after_the_alarm' (see below examples)
  • set the alarm desired frequency in ALRMCON register (upper bit must be set to enable the alarms)
  • avoid writing to RTC via RTCWREN register
  • clear interrupt flag before enabling interrupts

The 'secret' of the solution is in setting the value of the ALRMMIN and ALRMSEC registers:

/*
 * Error in both MCU and ERRATA documents:
 * If the alarm shall occur at :00 seconds -> ERRATA asks for 0x0A, but it has to be 0x5A!
 * 
 * EXAMPLES:
 *     For an alarm every minute on the minute, write       xx:xx:5A (HRS/MIN/SEC) // wakes at xx:00:00, xx:01:00, xx:02:00, xx:03:00, ...
 *     For an alarm every 10-minutes, write                 xx:09:5A (HRS/MIN/SEC) // wakes at xx:00:00, xx:10:00, xx:20:00, xx:30:00, ...
 *     For an alarm every hour on the hour, write           xx:59:5A (HRS/MIN/SEC) // wakes at x0:00:00, x1:00:00, x2:00:00, x3:00:00, ...
 *     For an alarm every hour at 01-minute, write          xx:00:5A (HRS/MIN/SEC) // wakes at x0:01:00, x1:01:00, x2:01:00, x3:01:00, ...
 * 
 * 0x5A is in BCD as five-ten (5-10), replacing the expected 5-9 (decimal "59" on the clock)
 * Likely the rollover mechanism in the PIC has this simple bug, that to get the rollover impulse the last digit needs ten instead of nine.
 */
ALRMMIN = 0x59; // minutes
ALRMSEC = 0x5A; // seconds

/*
 * Alarm control register
 */
ALRMCON = ALRMCTRL__REPEAT_INDEFINITELY | ALRMCTRL__EVERY_HOUR;

/*
 * Enable the alarm 
 */
ALRMCONbits.ALRMEN = 1;
added 6 characters in body
Source Link
EmbeddedGuy
  • 558
  • 3
  • 15

While I am answering my own question, I must give big credit to @PaulGhobril, who led me to understand the code.

Still, the fix is pointing to my original suspicion, that there is a bug in the PIC RTCC module, which shows in a special case you need an alarm at xx:xx:00 seconds. It seems botthat both PIC documentation and Errata are wrong.

The solution is to set the SECONDS alarm register to 'weird' value of 0x5A. Then the code works, no matter if I want every 1-minute or every 1-hour wake ups.

This single line made it working:

ALRMSEC = 0x5A; // seconds  // error in both MCU and ERRATA docs (if alarm needs to occur at 00 seconds - Errata said 0x0A, but needs 0x5A)

```

While I am answering my own question, I must give big credit to @PaulGhobril, who led me to understand the code.

Still, the fix is pointing to my original suspicion, that there is a bug in the PIC RTCC module, which shows in a special case you need an alarm at xx:xx:00 seconds. It seems bot PIC documentation and Errata are wrong.

The solution is to set the SECONDS alarm register to 'weird' value of 0x5A. Then the code works, no matter if I want every 1-minute or every 1-hour wake ups.

This single line made it working:

ALRMSEC = 0x5A; // seconds  // error in both MCU and ERRATA docs (if alarm needs to occur at 00 seconds - Errata said 0x0A, but needs 0x5A)

```

While I am answering my own question, I must give big credit to @PaulGhobril, who led me to understand the code.

Still, the fix is pointing to my original suspicion, that there is a bug in the PIC RTCC module, which shows in a special case you need an alarm at xx:xx:00 seconds. It seems that both PIC documentation and Errata are wrong.

The solution is to set the SECONDS alarm register to 'weird' value of 0x5A. Then the code works, no matter if I want every 1-minute or every 1-hour wake ups.

This single line made it working:

ALRMSEC = 0x5A; // seconds  // error in both MCU and ERRATA docs (if alarm needs to occur at 00 seconds - Errata said 0x0A, but needs 0x5A)
Source Link
EmbeddedGuy
  • 558
  • 3
  • 15
Loading