25#include <etl/string.h>
26#include <etl/string_stream.h>
28#include <stm32_ll_pwr.h>
30static const struct device *rtc = DEVICE_DT_GET(DT_ALIAS(rtc));
34#if DT_NODE_EXISTS(DT_ALIAS(gnss))
35static const struct device *gnss_uart = DEVICE_DT_GET(DT_ALIAS(uartgnss));
38gnss_data_callback_wrapper(
const struct device *dev,
39 const struct gnss_data *data)
42 time_inst->gnss_data_cb(dev, data);
46GNSS_DATA_CALLBACK_DEFINE(DEVICE_DT_GET(DT_ALIAS(gnss)),
47 gnss_data_callback_wrapper);
57 struct rtc_time datetime_set;
60 if (data->info.fix_status != GNSS_FIX_STATUS_NO_FIX) {
61 m_gnss_received_fix =
true;
62 time_info.tm_hour = data->utc.hour;
63 time_info.tm_min = data->utc.minute;
64 time_info.tm_sec = data->utc.millisecond / 1000;
65 time_info.tm_mday = data->utc.month_day;
66 time_info.tm_mon = data->utc.month - 1;
67 time_info.tm_year = data->utc.century_year + 100;
68 time_info.tm_isdst = -1;
70 posix_epoch = timeutil_timegm(&time_info);
72 m_millis_since_epoch_gnss =
73 posix_epoch * 1000 + data->utc.millisecond % 1000;
74 m_last_gnss_update_uptime = k_uptime_get();
77 gmtime_r(&posix_epoch, rtc_time_to_tm(&datetime_set));
78 datetime_set.tm_nsec = (data->utc.millisecond % 1000) * 1000000;
79 rtc_set_time(m_rtc, &datetime_set);
86 LL_PWR_EnableBkUpAccess();
95 m_last_nmea_update_uptime = k_uptime_get();
113 struct rtc_time datetime_get;
114 int rtc_status = rtc_get_time(m_rtc, &datetime_get);
124 if (rtc_status == 0) {
125 t = timeutil_timegm(rtc_time_to_tm(&datetime_get)) * 1000 +
126 datetime_get.tm_nsec / 1000000;
132 if (m_gnss_received_fix) {
133 t = m_millis_since_epoch_gnss +
154 uint64_t ms_since_epoch;
156 time_t posix_epoch = ms_since_epoch / 1000;
157 gmtime_r(&posix_epoch, &t);
169 return k_uptime_get() & (~BIT64(63));
181 return m_last_gnss_update_uptime;
187 return m_last_nmea_update_uptime;
207 auto tt = mktime(&tmp);
208 auto ret = gmtime_r(&tt, &tmp);
209 if (ret ==
nullptr) {
213 struct rtc_time rtct = {.tm_sec = ret->tm_sec,
214 .tm_min = ret->tm_min,
215 .tm_hour = ret->tm_hour,
216 .tm_mday = ret->tm_mday,
217 .tm_mon = ret->tm_mon,
218 .tm_year = ret->tm_year,
219 .tm_wday = ret->tm_wday,
223 rtc_set_time(m_rtc, &rtct);
228 LL_PWR_EnableBkUpAccess();
244 : m_millis_since_epoch_gnss(0),
245 m_gnss_received_fix(false),
246 m_last_gnss_update_uptime(0),
247 m_last_nmea_update_uptime(0),
251 k_mutex_init(&m_mtx);
253#if DT_NODE_EXISTS(DT_ALIAS(gnss))
255 if (!device_is_ready(gnss_uart)) {
259 struct uart_config gnss_uart_cfg = {
260 .baudrate = CONFIG_GNSS_UART_BAUDRATE,
261 .parity = UART_CFG_PARITY_NONE,
262 .stop_bits = UART_CFG_STOP_BITS_1,
263 .data_bits = UART_CFG_DATA_BITS_8,
264 .flow_ctrl = UART_CFG_FLOW_CTRL_NONE,
267 int rc = uart_configure(gnss_uart, &gnss_uart_cfg);
270 err.assert_error<device_not_configured_exception>(__FILE__, __LINE__);
296 switch (granularity) {
298 bytes = strftime(s.data_end(), s.available(),
"%Y", &tm);
301 bytes = strftime(s.data_end(), s.available(),
"%Y-%m", &tm);
303 bytes = strftime(s.data_end(), s.available(),
"%F", &tm);
306 bytes = strftime(s.data_end(), s.available(),
"%FT%HZ", &tm);
309 bytes = strftime(s.data_end(), s.available(),
"%FT%H:%MZ", &tm);
312 bytes = strftime(s.data_end(), s.available(),
"%FT%TZ", &tm);
318 s.trim_to_terminator();
329 bytes = strftime(s.data_end(), s.available(),
"%F", &tm);
330 s.trim_to_terminator();
static error_handler & get_instance()
Singleton access to the error_handler subsystem.
Implements a scoped lock utilizing the Zephyr mutex.
Time and position information.
void set(const struct tm &t)
Sets the RTC time.
void gnss(struct gnss_data &data)
Retrieve latest GNSS information.
time_src get(uint64_t &t)
Gets the time in ms.
uint64_t uptime()
Gets the current system uptime in milliseconds.
uint64_t last_gnss_update_uptime()
Gets the system uptime (in milliseconds) at the time of the last GNSS fix.
uint64_t last_nmea_update_uptime()
size_t to_string(const struct tm &tm, etl::istring &s, time::time_granularity granularity) const
Return the string represantation of a struct tm time instance following the ISO-8601 paradigm....
time_granularity
Granularity of time represented as string.
void gnss_data_cb(const struct device *dev, const struct gnss_data *data)
time(time const &)=delete
time_src
Source of the reported time.
@ UPTIME
No RTC or GNSS time source. The uptime is used to track time.
@ GNSS_ONLY
No RTC installed, but there is time information from a GNSS fix.