Calendar Bare-bone Driver

This Calendar bare-bone driver provides an interface to set and get current date and time, and also alarm functionality.

Refer Calendar Drivers for more detailed calendar basics.

Summary of the API's Functional Features

The API provides functions to:
  • Initialize and deinitialize the driver and associated hardware

  • Enable and disable calendar instance

  • Set time, date, and base year

  • Get current date and time

  • Set the software alarm timer with callback handler on the alarm event happen

Summary of Configuration Options

Below is the main Calendar parameters that can be configured in START. These parameters are used by the calendar_init function when initializing the driver and underlying hardware.
  • The clock source and the prescaler of counter hardware used by the calendar

Driver Implementation Description

The calendar driver implementation is based on a hardware counter which is configured to increase with one every second. The hardware may be RTC (Real-Time Counter) or RTT (Real-time Timer) depend on the device.

Concurrency

The Calendar driver is an interrupt driven driver. This means that the interrupt that triggers an alarm may occur during the process of adding or removing an alarm via the driver's API. In such case the interrupt processing is postponed until the alarm adding or removing is complete.

The alarm queue is not protected from the access by interrupts not used by the driver. Due to this it is not recommended to add or remove an alarm from such interrupts: in case if a higher priority interrupt supersedes the driver's interrupt. Adding or removing an alarm may cause unpredictable behavior of the driver.

Limitations

  • Only years divisible by 4 are leap year. This gives a correct result between the years 1901 to 2099

  • The driver is designed to work outside of an operating system environment. The software alarm queue is therefore processed in interrupt context, which may delay execution of other interrupts

  • If there are a lot of frequently called interrupts with a priority higher than the driver's one, it may cause a delay in the alarm's triggering

  • Changing the base year or setting current date or time does not shift the alarms' date and time accordingly or expires alarms

Example of Usage

The following shows a simple example of using the Calendar. The calendar must have been initialized by calendar_init. This initialization will configure the operation of the underlying hardware counter.

The example first sets the given date and time, then sets a repeat alarm timer on specific second match with a callback function.

Tip:
Take for example SAM D21. The RTC peripheral is used in counter mode and to be increased by one every second. Correct RTC clock settings can be configured in START:
  • Clock
    • Select OSCULP32K source as generic clock generator 1 input

    • Enable generic clock generator 1 with division 32 to get 1kHz output

  • Calendar driver (RTC)
    • Select generic clock generator 1 as RTC clock input

    • Set prescaler to 1024, then RTC get a 1Hz clock input

          static void alarm_cb(struct calendar_descriptor *const descr)
          {
            /* alarm expired */
          }
          void CALENDAR_0_example(void)
          {
            struct calendar_date date;
            struct calendar_time time;
            calendar_enable(&CALENDAR_0);
            date.year  = 2000;
            date.month = 12;
            date.day   = 31;
            time.hour = 12;
            time.min  = 59;
            time.sec  = 59;
            calendar_set_date(&CALENDAR_0, &date);
            calendar_set_time(&CALENDAR_0, &time);
            alarm.cal_alarm.datetime.time.sec = 4;
            alarm.cal_alarm.option            = CALENDAR_ALARM_MATCH_SEC;
            alarm.cal_alarm.mode              = REPEAT;
            calendar_set_alarm(&CALENDAR_0, &alarm, alarm_cb);
          }
        

Dependencies

  • This driver expects a counter to be increased by one every second to count date and time correctly

  • Each instance of the driver requires separate hardware timer