Skip to content

Commit 1579882

Browse files
committed
drivers: rtc: sample to test internal stm32u5 rtc
- set time - get time - wake up timer interrupt - AlarmA and AlarmB interrupts Signed-off-by: FAURANT Nicolas <[email protected]>
1 parent 9e7504b commit 1579882

File tree

6 files changed

+297
-0
lines changed

6 files changed

+297
-0
lines changed

samples/drivers/rtc/CMakeLists.txt

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
cmake_minimum_required(VERSION 3.20.0)
4+
5+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
6+
project(rtc)
7+
8+
target_sources(app PRIVATE src/main.c)

samples/drivers/rtc/README.rst

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
.. _rtc:
2+
3+
Real Time Clock driver sample
4+
#############################
5+
6+
Overview
7+
********
8+
9+
This sample demonstrates how to use the RTC driver API.
10+
11+
Sample output
12+
=============
13+
14+
In the main.c, select TEST_WUT to test Wake Up Timer or select TEST_ALARM to test AlarmA and AlarmB
15+
16+
If TEST_WUT is selected, 3 wake up timer callback messages are generated every 10s then every 5s.
17+
You should get a similar output as below with TEST_WUT:
18+
19+
.. code-block:: console
20+
21+
...
22+
epoch:1634826602 wd:2 2021/9/21 14:30:2
23+
epoch:1634826604 wd:2 2021/9/21 14:30:4
24+
epoch:1634826606 wd:2 2021/9/21 14:30:6
25+
epoch:1634826608 wd:2 2021/9/21 14:30:8
26+
wakeup_timer_callback: 1 epoch:1634826610 wd:2 2021/9/21 14:30:10
27+
epoch:1634826612 wd:2 2021/9/21 14:30:12
28+
epoch:1634826614 wd:2 2021/9/21 14:30:14
29+
epoch:1634826616 wd:2 2021/9/21 14:30:16
30+
epoch:1634826618 wd:2 2021/9/21 14:30:18
31+
wakeup_timer_callback: 2 epoch:1634826620 wd:2 2021/9/21 14:30:20
32+
epoch:1634826622 wd:2 2021/9/21 14:30:22
33+
epoch:1634826624 wd:2 2021/9/21 14:30:24
34+
epoch:1634826626 wd:2 2021/9/21 14:30:26
35+
epoch:1634826628 wd:2 2021/9/21 14:30:28
36+
wakeup_timer_callback: 3 epoch:1634826630 wd:2 2021/9/21 14:30:30
37+
...
38+
39+
40+
If TEST_ALARM is selected, only one AlarmB message is generated after 10s and AlarmA messsages are generated every 60s.
41+
You should get a similar output as below with TEST_ALARM:
42+
43+
.. code-block:: console
44+
45+
...
46+
epoch:1634826600 wd:2 2021/9/21 14:30:0
47+
epoch:1634826602 wd:2 2021/9/21 14:30:2
48+
epoch:1634826604 wd:2 2021/9/21 14:30:4
49+
epoch:1634826606 wd:2 2021/9/21 14:30:6
50+
epoch:1634826608 wd:2 2021/9/21 14:30:8
51+
alarmB_callback: 1 epoch:1634826610 wd:2 2021/9/21 14:30:10
52+
epoch:1634826612 wd:2 2021/9/21 14:30:12
53+
...
54+
epoch:1634826628 wd:2 2021/9/21 14:30:28
55+
alarmA_callback: 1 epoch:1634826630 wd:2 2021/9/21 14:30:30
56+
epoch:1634826632 wd:2 2021/9/21 14:30:32
57+
...
58+
epoch:1634826688 wd:2 2021/9/21 14:31:28
59+
alarmA_callback: 2 epoch:1634826690 wd:2 2021/9/21 14:31:30
60+
epoch:1634826692 wd:2 2021/9/21 14:31:32
61+
...
62+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
&rtc {
2+
interrupts = <2 7>;
3+
status = "okay";
4+
};

samples/drivers/rtc/prj.conf

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CONFIG_RTC=y
2+
CONFIG_RTC_STM32=y
3+
4+
#CONFIG_MAIN_STACK_SIZE=4096
5+
#CONFIG_IDLE_STACK_SIZE=4096
6+
#CONFIG_ISR_STACK_SIZE=4096
7+
8+
# Optimization
9+
#CONFIG_NO_OPTIMIZATIONS=y

samples/drivers/rtc/sample.yaml

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
sample:
2+
name: DACRTC driver sample
3+
tests:
4+
sample.drivers.rtc:
5+
tags: RTC
6+
platform_allow: |
7+
nucleo_u575zi_q b_u585i_iot02a
8+
depends_on: rtc
9+
harness: console
10+
harness_config:
11+
type: one_line
12+
regex:
13+
- "rtc."

samples/drivers/rtc/src/main.c

+201
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
/*
2+
* Copyright (c) 2021 LACROIX Group
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <drivers/rtc.h>
8+
#include <stdio.h>
9+
#include <zephyr.h>
10+
#include <sys/printk.h>
11+
12+
#include <time.h>
13+
#include <sys/timeutil.h>
14+
15+
const struct device *dev;
16+
17+
// Select Wake Up Timer test (Wut) or alarm test
18+
#define TEST_WUT 1
19+
#define TEST_ALARM 2
20+
#define TEST_TYPE TEST_ALARM
21+
22+
#if (TEST_TYPE == TEST_WUT)
23+
// Perform some stuff when wut interrupt occurs
24+
void wakeup_timer_callback(const struct device *dev)
25+
{
26+
struct tm date_time; // Date and time structure
27+
static int cnt;
28+
29+
cnt++;
30+
printk("wakeup_timer_callback: %i \t", cnt);
31+
rtc_get_time(dev, &date_time);
32+
33+
if (cnt == 3) {
34+
rtc_stop_wakeup_timer(dev, RTC_WUT0);
35+
cnt = 0;
36+
}
37+
}
38+
#endif // #if(TEST_TYPE == TEST_WUT)
39+
40+
#if (TEST_TYPE == TEST_ALARM)
41+
// Perform some stuff when alaram A interrupt occurs
42+
void alarmA_callback(const struct device *dev)
43+
{
44+
struct tm date_time; // Date and time structure
45+
static int cnt;
46+
47+
cnt++;
48+
printk("alarmA_callback: %i \t", cnt);
49+
rtc_get_time(dev, &date_time);
50+
}
51+
52+
// Perform some stuff when alaram B interrupt occurs
53+
void alarmB_callback(const struct device *dev)
54+
{
55+
struct tm date_time; // Date and time structure
56+
static int cnt;
57+
58+
cnt++;
59+
printk("alarmB_callback: %i \t", cnt);
60+
rtc_get_time(dev, &date_time);
61+
}
62+
#endif // #if(TEST_TYPE == TEST_ALARM)
63+
64+
void main(void)
65+
{
66+
int i_cnt = 0;
67+
int i_cnt_alarm = 0;
68+
int64_t time_epoch = 0; /* POSIX epoch time scale */
69+
70+
#if (TEST_TYPE == TEST_WUT)
71+
struct rtc_wakeup wut; /* Wake up timer structure */
72+
bool toggle_set = false;
73+
#endif /* #if(TEST_TYPE == TEST_WUT) */
74+
#if (TEST_TYPE == TEST_ALARM)
75+
struct rtc_alarm alarmA = { 0 };
76+
struct rtc_alarm alarmB = { 0 };
77+
#endif /* #if(TEST_TYPE == TEST_ALARM) */
78+
struct tm date_time; /* Date and time structure */
79+
80+
printk("RTC driver! %s\n", CONFIG_BOARD);
81+
82+
/* Init time */
83+
date_time.tm_year = 2021 - 1900; /* Year since 1900 */
84+
date_time.tm_mon = 9; /* month of year [0,11], where 0 = jan */
85+
date_time.tm_mday = 21; /* Day of month [1,31] */
86+
date_time.tm_hour = 14; /* Hour [0,23] */
87+
date_time.tm_min = 30; /* Minutes [0,59] */
88+
date_time.tm_sec = 0; /* Seconds [0,61] */
89+
date_time.tm_isdst = -1; /* Daylight savings flag: Is DST on? 1 = yes, 0 = no, -1 = unknown */
90+
date_time.tm_wday = 2; /* Day of week [0,6] (Sunday = 0) */
91+
// date_time.tm_yday = ; /* Day of year [0,365] */
92+
// t_of_day = mktime(&t);
93+
94+
#if (TEST_TYPE == TEST_WUT)
95+
/* Init rtc wake up timer */
96+
wut.period = 10000U; /* Wut period in milliseconds */
97+
wut.callback = wakeup_timer_callback;
98+
#endif /* #if(TEST_TYPE == TEST_WUT) */
99+
100+
#if (TEST_TYPE == TEST_ALARM)
101+
/* AlarmA is periodic and is generated every minute from 14h30min30s thanks to mask = RTC_ALARM_MASK_MIN */
102+
alarmA.alarm_time.tm_year = 2021 - 1900; /* Year since 1900 */
103+
alarmA.alarm_time.tm_mon = 9; /* month of year [0,11], where 0 = jan */
104+
alarmA.alarm_time.tm_mday = 21; /* Day of month [1,31] */
105+
alarmA.alarm_time.tm_hour = 14; /* Hour [0,23] */
106+
alarmA.alarm_time.tm_min = 30; /* Minutes [0,59] */
107+
alarmA.alarm_time.tm_sec = 30; /* Seconds [0,61] */
108+
alarmA.alarm_time.tm_isdst = -1; /* Daylight savings flag: Is DST on? 1 = yes, 0 = no, -1 = unknown */
109+
alarmA.alarm_time.tm_wday = 2; /* Day of week [0,6] (Sunday = 0) */
110+
// alarmA.alarm_time.tm_yday = ; /* Day of year [0,365] */
111+
alarmA.alarm_date_weekday_sel = RTC_ALARM_WEEKDAY_SEL;
112+
alarmA.alarm_mask = RTC_ALARM_MASK_MIN; // RTC_ALARM_MASK_SEC; // RTC_ALARM_MASK_NONE;
113+
alarmA.callback = alarmA_callback;
114+
115+
/* AlarmB is oneshoot on 14h30min10s thanks to mask = RTC_ALARM_MASK_NONE */
116+
alarmB.alarm_time.tm_year = 2021 - 1900; /* Year since 1900 */
117+
alarmB.alarm_time.tm_mon = 9; /* month of year [0,11], where 0 = jan */
118+
alarmB.alarm_time.tm_mday = 21; /* Day of month [1,31] */
119+
alarmB.alarm_time.tm_hour = 14; /* Hour [0,23] */
120+
alarmB.alarm_time.tm_min = 30; /* Minutes [0,59] */
121+
alarmB.alarm_time.tm_sec = 10; /* Seconds [0,61] */
122+
alarmA.alarm_time.tm_isdst = -1; /* Daylight savings flag: Is DST on? 1 = yes, 0 = no, -1 = unknown */
123+
alarmB.alarm_time.tm_wday = 2; /* Day of week [0,6] (Sunday = 0) */
124+
// alarmB.alarm_time.tm_yday = ; /* Day of year [0,365] */
125+
alarmB.alarm_date_weekday_sel = RTC_ALARM_WEEKDAY_SEL;
126+
alarmB.alarm_mask = RTC_ALARM_MASK_NONE; // RTC_ALARM_MASK_SEC; // RTC_ALARM_MASK_NONE;
127+
alarmB.callback = alarmB_callback;
128+
#endif /* #if(TEST_TYPE == TEST_ALARM) */
129+
130+
// dev = device_get_binding("CUSTOM_DRIVER");
131+
dev = device_get_binding("RTC_0");
132+
133+
__ASSERT(dev, "Failed to get device binding");
134+
135+
printk("device is %p, name is %s\n", dev, dev->name);
136+
137+
rtc_set_time(dev, date_time);
138+
rtc_get_time(dev, &date_time);
139+
140+
#if (TEST_TYPE == TEST_WUT)
141+
rtc_set_wakeup_timer(dev, wut, RTC_WUT0);
142+
rtc_start_wakeup_timer(dev, RTC_WUT0);
143+
#endif // #if(TEST_TYPE == TEST_WUT)
144+
145+
#if (TEST_TYPE == TEST_ALARM)
146+
rtc_set_alarm(dev, alarmA, RTC_ALARMA);
147+
rtc_set_alarm(dev, alarmB, RTC_ALARMB);
148+
rtc_start_alarm(dev, RTC_ALARMA);
149+
rtc_start_alarm(dev, RTC_ALARMB);
150+
#endif // #if(TEST_TYPE == TEST_ALARM)
151+
152+
// rtc_set_alarm(dev);
153+
// rtc_get_alarm(dev);
154+
// rtc_cancel_alarm(dev);
155+
// rtc_set_wakeup_timer(dev, 2048);
156+
157+
while (1) {
158+
rtc_get_time(dev, &date_time);
159+
160+
time_epoch = timeutil_timegm64(&date_time);
161+
printk("epoch:%ld wd:%i %i/%i/%i %i:%i:%i\n", (long) time_epoch, date_time.tm_wday,
162+
(1900 + date_time.tm_year), date_time.tm_mon, date_time.tm_mday,
163+
date_time.tm_hour, date_time.tm_min, date_time.tm_sec);
164+
165+
166+
k_msleep(2000);
167+
// k_msleep(25000);
168+
// printk("WakeUp counter: %d\n", i_cnt);
169+
// rtc_set_wakeup_timer(dev, 2048);
170+
i_cnt++;
171+
if (i_cnt == 25) {
172+
#if (TEST_TYPE == TEST_WUT)
173+
if (toggle_set == false) {
174+
wut.period = 10000U; // Wut period in milliseconds
175+
printk("rtc_set_wakeup_timer 10s\n");
176+
rtc_set_wakeup_timer(dev, wut, RTC_WUT0);
177+
toggle_set = true;
178+
} else {
179+
wut.period = 5000U; // Wut period in milliseconds
180+
printk("rtc_set_wakeup_timer 5s\n");
181+
rtc_set_wakeup_timer(dev, wut, RTC_WUT0);
182+
toggle_set = false;
183+
}
184+
185+
rtc_start_wakeup_timer(dev, RTC_WUT0);
186+
#endif // #if(TEST_TYPE == TEST_WUT)
187+
i_cnt = 0;
188+
}
189+
190+
i_cnt_alarm++;
191+
if (i_cnt_alarm == 80) {
192+
#if (TEST_TYPE == TEST_ALARM)
193+
rtc_stop_alarm(dev, RTC_ALARMA);
194+
printk("rtc_stop_alarm(dev, RTC_ALARMA)\n");
195+
rtc_stop_alarm(dev, RTC_ALARMB);
196+
printk("rtc_stop_alarm(dev, RTC_ALARMB)\n");
197+
#endif // #if(TEST_TYPE == TEST_ALARM)
198+
i_cnt_alarm = 0;
199+
}
200+
}
201+
}

0 commit comments

Comments
 (0)