Skip to content

Commit f058214

Browse files
committed
Introduced RTC library and configuration for Giga, H7, Opta, Nicla Sense and Nano 33 Ble.
1 parent 658a690 commit f058214

File tree

17 files changed

+860
-2
lines changed

17 files changed

+860
-2
lines changed

libraries/RTC/RTC.cpp

Lines changed: 491 additions & 0 deletions
Large diffs are not rendered by default.

libraries/RTC/RTC.h

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// RTC.h
2+
#pragma once
3+
4+
#include <zephyr/kernel.h>
5+
#include <zephyr/device.h>
6+
#include <zephyr/drivers/counter.h>
7+
#include <zephyr/drivers/rtc.h>
8+
#include <time.h>
9+
10+
// Alarm callback types
11+
typedef void (*RTCAlarmCallback)(void *user_data);
12+
typedef void (*RTCUpdateCallback)(void *user_data);
13+
14+
class ArduinoRTC {
15+
public:
16+
ArduinoRTC();
17+
bool begin();
18+
~ArduinoRTC();
19+
20+
/* setters */
21+
bool setDayOfMonth(int day);
22+
bool setMonthOfYear(int m);
23+
bool setYear(int year);
24+
bool setHour(int hour);
25+
bool setMinute(int minute);
26+
bool setSecond(int second);
27+
28+
/* Getters */
29+
int getDayOfMonth();
30+
int getMonth();
31+
int getYear();
32+
int getHour();
33+
int getMinutes();
34+
int getSeconds();
35+
36+
int setTime(int year, int month, int day, int hour, int minute, int second);
37+
int getTime(int &year, int &month, int &day, int &hour, int &minute, int &second);
38+
#if defined(ARDUINO_GIGA) || defined(ARDUINO_PORTENTA_H7) || defined(ARDUINO_OPTA)
39+
int setAlarm(int year, int month, int day, int hour, int minute, int second,
40+
RTCAlarmCallback cb = nullptr, void *user_data = nullptr);
41+
int cancelAlarm();
42+
#elif defined(ARDUINO_NANO33BLE) || defined(ARDUINO_NICLA_SENSE_ME)
43+
int setAlarm(int year, int month, int day, int hour, int minute, int second,
44+
void (*callback)(const struct device *dev, uint8_t chan_id, uint32_t ticks, void *user_data),
45+
void *cb_user_data);
46+
void cancelAlarm();
47+
#endif
48+
49+
#if defined(ARDUINO_GIGA) || defined(ARDUINO_PORTENTA_H7) || defined(ARDUINO_OPTA)
50+
// Optional APIs (only if supported)
51+
int getAlarm(int &year, int &month, int &day, int &hour, int &minute, int &second);
52+
bool isAlarmPending();
53+
int setUpdateCallback(RTCUpdateCallback cb, void *user_data);
54+
int setCalibration(int32_t calibration);
55+
int getCalibration(int32_t &calibration);
56+
#endif
57+
58+
59+
private:
60+
#if defined(ARDUINO_GIGA) || defined(ARDUINO_PORTENTA_H7) || defined(ARDUINO_OPTA)
61+
const struct device *rtc_dev;
62+
63+
static void alarmCallbackWrapper(const struct device *dev, uint16_t id, void *user_data);
64+
static void updateCallbackWrapper(const struct device *dev, void *user_data);
65+
66+
RTCAlarmCallback userAlarmCallback = nullptr;
67+
void *userAlarmCallbackData = nullptr;
68+
69+
RTCUpdateCallback userUpdateCallback = nullptr;
70+
void *userUpdateCallbackData = nullptr;
71+
72+
uint16_t alarmId = 0; // default to alarm ID 0
73+
#elif defined(ARDUINO_NANO33BLE) || defined(ARDUINO_NICLA_SENSE_ME)
74+
const struct device *counter_dev;
75+
time_t timeOffset;
76+
77+
// Alarm members
78+
struct counter_alarm_cfg alarm_cfg;
79+
void (*user_callback)(const struct device *dev, uint8_t chan_id, uint32_t ticks, void *user_data);
80+
void *user_data;
81+
82+
static void alarmHandler(const struct device *dev, uint8_t chan_id, uint32_t ticks, void *user_data);
83+
84+
time_t datetimeToEpoch(int year, int month, int day, int hour, int minute, int second);
85+
void epochToDatetime(time_t t, int &year, int &month, int &day, int &hour, int &minute, int &second);
86+
#endif
87+
};
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
* This sketch sets an alarm 10 seconds in the future and handles it via a callback.
3+
*/
4+
5+
#include "RTC.h"
6+
#include <stdio.h>
7+
8+
ArduinoRTC rtc;
9+
10+
char printBuffer[30]; // declare a buffer of large enough size for the message we want to display
11+
int year, month, day, hour, minute, second;
12+
13+
#if defined(ARDUINO_NICLA_SENSE_ME) || defined(ARDUINO_NANO33BLE)
14+
void onAlarm(const struct device *dev, uint8_t chan_id, uint32_t ticks, void *user_data) {
15+
char printBuffer[40];
16+
// Assuming user_data is a string or message you want to print
17+
sprintf(printBuffer, "Alarm went off! Message: %s\n", (char *)user_data);
18+
Serial.println(printBuffer);
19+
}
20+
#elif
21+
void onAlarm(void *user_data) {
22+
char printBuffer[40];
23+
sprintf(printBuffer, "Alarm went off! Message: %s\n", (char *)user_data);
24+
Serial.println(printBuffer);
25+
}
26+
#endif
27+
28+
void setup() {
29+
int ret = 0xDEADBEEFu; // Starting with a custom value for the return which will definitely lead to failure if not changed to zero (i.e. success) by the functions below
30+
char printBuffer[60];
31+
Serial.begin(115200);
32+
delay(1000);
33+
34+
if (!rtc.begin()) {
35+
Serial.println("RTC not ready\n");
36+
return;
37+
}
38+
39+
int year, month, day, hour, minute, second;
40+
ret = rtc.getTime(year, month, day, hour, minute, second);
41+
if(ret != 0)
42+
{
43+
rtc.setTime(2025, 10, 21, 12, 0, 0);
44+
}
45+
46+
sprintf(printBuffer, "Current Time: %04d-%02d-%02d %02d:%02d:%02d\n", year, month, day, hour, minute, second);
47+
Serial.println(printBuffer);
48+
49+
// Set alarm 10 seconds into the future
50+
second += 5;
51+
// Correct for minute rollover if necessary
52+
if (second >= 60) {
53+
second -= 60;
54+
minute += 1;
55+
}
56+
57+
// The method also allows for registering a function callback which will be called when the alarm sets off and a display message which will be shown in the console
58+
ret = rtc.setAlarm(year, month, day, hour, minute, second, onAlarm, (void *)"Wake up!!!");
59+
if (ret == 0) {
60+
sprintf(printBuffer, "Alarm set for: %02d:%02d:%02d\n", hour, minute, second);
61+
Serial.println(printBuffer);
62+
} else {
63+
sprintf(printBuffer, "Failed to set alarm (%d)\n", ret);
64+
Serial.println(printBuffer);
65+
}
66+
}
67+
68+
void loop() {
69+
char printBuffer[30]; // declare a buffer of large enough size for the message we want to display
70+
int y, m, d, h, min, s;
71+
int status = rtc.getTime(y, m, d, h, min, s);
72+
// Because the print() and println() functions do not support formatted output directly, we can use this trick to prepare a buffer with the string we want to show
73+
sprintf(printBuffer, "Time is: %04d-%02d-%02d %02d:%02d:%02d", y, m, d, h, min, s);
74+
Serial.println(printBuffer);
75+
delay(1000);
76+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#include "RTC.h"
2+
#include <stdio.h>
3+
4+
// Doesn't work on the Opta for some reason.
5+
6+
7+
ArduinoRTC rtc;
8+
9+
void setup() {
10+
char printBuffer[30];
11+
delay(1000);
12+
Serial.begin(115200);
13+
if (!rtc.begin()) {
14+
printf("RTC not ready\n");
15+
return;
16+
}
17+
18+
int calib = 0;
19+
if (rtc.getCalibration(calib) == 0) {
20+
sprintf(printBuffer, "Current calibration: %d\n", calib);
21+
Serial.println(printBuffer);
22+
} else {
23+
Serial.println("Failed to get calibration");
24+
}
25+
26+
// Apply a small positive calibration (e.g., +1)
27+
// This value is hardware-dependent, in a real application you should check the microcontroller's datasheet for the correct amount.
28+
int32_t new_calib = calib + 1;
29+
30+
if (rtc.setCalibration(new_calib) == 0) {
31+
sprintf(printBuffer, "Calibration updated to: %d\n", new_calib);
32+
Serial.println(printBuffer);
33+
} else {
34+
Serial.println("Failed to set calibration");
35+
}
36+
}
37+
38+
void loop() {
39+
delay(5000);
40+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#include "RTC.h"
2+
3+
ArduinoRTC rtc;
4+
5+
// 7-segment style representation for digits 0–9 and colon ":"
6+
const char* bigDigits[11][3] = {
7+
{" _ ", "| |", "|_|"}, // 0
8+
{" ", " |", " |"}, // 1
9+
{" _ ", " _|", "|_ "}, // 2
10+
{" _ ", " _|", " _|"}, // 3
11+
{" ", "|_|", " |"}, // 4
12+
{" _ ", "|_ ", " _|"}, // 5
13+
{" _ ", "|_ ", "|_|"}, // 6
14+
{" _ ", " |", " |"}, // 7
15+
{" _ ", "|_|", "|_|"}, // 8
16+
{" _ ", "|_|", " _|"}, // 9
17+
{" ", " . ", " . "} // colon ":"
18+
};
19+
20+
void printBigTime(int h, int m, int s) {
21+
// Format time as HH:MM:SS string
22+
char timeStr[9];
23+
memset(timeStr, 0, sizeof(timeStr));
24+
char bigDigitsPrint[40];
25+
memset(bigDigitsPrint, 0, sizeof(bigDigitsPrint));
26+
snprintf(timeStr, sizeof(timeStr), "%02d:%02d:%02d", h, m, s); // This (and further such manipulations) is necessary because Serial.print() does not support formatted output like printf()
27+
Serial.println(timeStr);
28+
29+
30+
// Print each of the 3 lines row by row
31+
for (int row = 0; row < 3; row++) {
32+
for (int i = 0; timeStr[i] != '\0'; i++) {
33+
char c = timeStr[i];
34+
if (c >= '0' && c <= '9') {
35+
sprintf(bigDigitsPrint, "%s ", bigDigits[c - '0'][row]);
36+
Serial.print(bigDigitsPrint);
37+
} else if (c == ':') {
38+
sprintf(bigDigitsPrint, "%s ", bigDigits[10][row]);
39+
Serial.print(bigDigitsPrint);
40+
} else {
41+
Serial.print(" "); // Space or unknown
42+
}
43+
}
44+
Serial.println();
45+
}
46+
Serial.println();
47+
}
48+
49+
void setup() {
50+
Serial.begin(115200);
51+
rtc.begin();
52+
bool status = rtc.setTime(2025, 9, 25, 7, 46, 0); // Initial time
53+
}
54+
55+
void loop() {
56+
int y, m, d, h, min, s;
57+
char printBuffer[60];
58+
int status = rtc.getTime(y, m, d, h, min, s);
59+
60+
// Clear screen (optional line, works on many terminals, tested on Tera Term. Does not take effect in Arduino IDE console unfortunately)
61+
Serial.println("\033[2J\033[H");
62+
63+
// Print date and time in plain format
64+
sprintf(printBuffer, "Date: %04d-%02d-%02d\n", y, m, d);
65+
Serial.println(printBuffer);
66+
Serial.println("Time:");
67+
68+
// Print time in big digits
69+
printBigTime(h, min, s);
70+
71+
delay(1000);
72+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#include "RTC.h"
2+
3+
ArduinoRTC rtc;
4+
5+
int year, month, day, hour, minute, second;
6+
int previousSecond = 0;
7+
char printBuffer[30]; // Allocate large enough buffer to hold the 28 characters of the output format "Time is: 2025-09-25 11:49:26"
8+
9+
void setup() {
10+
Serial.begin(115200);
11+
if (!rtc.begin()) {
12+
Serial.println("RTC not ready\n");
13+
return;
14+
}
15+
rtc.setTime(2025, 10, 21, 12, 0, 0);
16+
}
17+
18+
void loop() {
19+
rtc.getTime(year, month, day, hour, minute, second); // Read back time from hardware
20+
sprintf(printBuffer, "Time is: %04d-%02d-%02d %02d:%02d:%02d", year, month, day, hour, minute, second);
21+
Serial.println(printBuffer);
22+
delay(1000);
23+
}

variants/arduino_giga_r1_stm32h747xx_m7/arduino_giga_r1_stm32h747xx_m7.conf

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ CONFIG_DAC=y
2323
CONFIG_PWM=y
2424
CONFIG_I2C_TARGET=y
2525

26+
CONFIG_CLOCK_CONTROL=y
27+
CONFIG_RTC=y
28+
CONFIG_RTC_ALARM=y
29+
CONFIG_RTC_UPDATE=y
30+
CONFIG_RTC_CALIBRATION=y
31+
2632
CONFIG_ICACHE=y
2733
CONFIG_DCACHE=y
2834
CONFIG_CACHE_MANAGEMENT=y

variants/arduino_giga_r1_stm32h747xx_m7/arduino_giga_r1_stm32h747xx_m7.overlay

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,17 @@
2727
status = "okay";
2828
};
2929

30+
&rtc {
31+
status = "okay";
32+
label = "RTC_0";
33+
34+
clocks = <&rcc STM32_CLOCK_BUS_APB1 0x10000000>, /* RTCAPB */
35+
<&rcc STM32_SRC_LSE RTC_SEL(1)>; /* Use LSI instead of LSE */
36+
37+
alarms-count = <2>;
38+
alrm-exti-line = <17>;
39+
};
40+
3041
&i2c4 {
3142
status = "okay";
3243
gc2145: gc2145@3c {

variants/arduino_nano_33_ble_nrf52840_sense/arduino_nano_33_ble_nrf52840_sense.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ CONFIG_CDC_ACM_DTE_RATE_CALLBACK_SUPPORT=y
2525

2626
CONFIG_ADC=y
2727
CONFIG_PWM=y
28+
CONFIG_COUNTER=y
2829

2930
CONFIG_LLEXT_STORAGE_WRITABLE=n
3031
CONFIG_SHELL_STACK_SIZE=2048

variants/arduino_nano_33_ble_nrf52840_sense/arduino_nano_33_ble_nrf52840_sense.overlay

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,3 +273,8 @@
273273
clock-frequency = <I2C_BITRATE_FAST>;
274274
};
275275

276+
&rtc2 {
277+
status = "okay";
278+
clock-frequency = <32768>;
279+
prescaler = <1>; // Optional: sets the RTC tick to ~30.5 µs
280+
};

0 commit comments

Comments
 (0)