Skip to content

Commit

Permalink
Add RTC to firmware
Browse files Browse the repository at this point in the history
  • Loading branch information
Kampi committed Aug 1, 2024
2 parents 3d1fe61 + 8384fc9 commit d1c2032
Show file tree
Hide file tree
Showing 13 changed files with 205 additions and 164 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
low-power-enable;
};
};

};

&uicr {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@
bias-pull-up;
};
};

};

&uicr {
Expand Down
4 changes: 2 additions & 2 deletions app/boards/arm/zswatch_nrf5340/zswatch_nrf5340_cpuapp_5.conf
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ CONFIG_NVS=y

CONFIG_DEBUG_COREDUMP_BACKEND_OTHER=y

#CONFIG_RTC=y
#CONFIG_RTC_UPDATE=y
CONFIG_RTC=y
CONFIG_RTC_UPDATE=y

CONFIG_MISC_ENABLE_SYSTEM_RESET=n # Implemented in nPM, hence not needed in FW

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@
bias-pull-up;
};
};

};

&uicr {
Expand Down Expand Up @@ -198,7 +197,7 @@
reg = <0x51>;
status = "okay";
clkout = <0>;
int-gpios = <&gpio1 13 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>;
int-gpios = <&gpio1 13 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
};

bmi270: bmi270@68 {
Expand Down
8 changes: 4 additions & 4 deletions app/patches/rv8263_rtc.patch
Original file line number Diff line number Diff line change
Expand Up @@ -404,10 +404,10 @@ index 0000000000..bb82ed7d9b
+ return err;
+ }
+
+ /* Return an error when the oscillator is stopped. */
+ if (regs[0] & RV8263_BM_OS) {
+ return -ECANCELED;
+ }
+ /* Clear the oscillator stop flag and return an error when the oscillator is stopped. */
+ if (regs[0] & RV8263_BM_OS) {
+ return -ENODATA;
+ }
+
+ timeptr->tm_sec = bcd2bin(regs[0] & SECONDS_BITS);
+ timeptr->tm_min = bcd2bin(regs[1] & MINUTES_BITS);
Expand Down
138 changes: 77 additions & 61 deletions app/src/events/zsw_periodic_event.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#include <zephyr/init.h>
#include <zephyr/kernel.h>
#include <zephyr/zbus/zbus.h>
#include <zephyr/logging/log.h>

#if CONFIG_RTC
#if CONFIG_RTC_UPDATE
#include <zephyr/drivers/rtc.h>
#endif

Expand All @@ -13,61 +14,22 @@
#define PERIODIC_MID_INTERVAL_MS 1000
#define PERIODIC_SLOW_INTERVAL_MS 10000

#if CONFIG_RTC
#if CONFIG_RTC_UPDATE
static const struct device *const rtc = DEVICE_DT_GET(DT_ALIAS(rtc));
#endif

ZBUS_CHAN_DECLARE(periodic_event_1s_chan);
ZBUS_CHAN_DECLARE(periodic_event_10s_chan);
ZBUS_CHAN_DECLARE(periodic_event_100ms_chan);

int zsw_periodic_chan_add_obs(const struct zbus_channel *chan, const struct zbus_observer *obs)
{
struct k_work_delayable *work = NULL;
int ret;

ret = zbus_chan_add_obs(chan, obs, K_MSEC(100));

if (ret != 0) {
return ret;
}

zbus_chan_claim(chan, K_FOREVER);
work = (struct k_work_delayable *)zbus_chan_user_data(chan);
__ASSERT(work != NULL, "Invalid channel");
if (!k_work_delayable_is_pending(work)) {
if (chan == &periodic_event_10s_chan) {
ret = k_work_reschedule(work, K_MSEC(PERIODIC_SLOW_INTERVAL_MS));
} else if (chan == &periodic_event_1s_chan) {
ret = k_work_reschedule(work, K_MSEC(PERIODIC_MID_INTERVAL_MS));
} else if (chan == &periodic_event_100ms_chan) {
ret = k_work_reschedule(work, K_MSEC(PERIODIC_FAST_INTERVAL_MS));
} else {
__ASSERT(false, "Unknown channel");
}
}
zbus_chan_finish(chan);

return ret;
}

int zsw_periodic_chan_rm_obs(const struct zbus_channel *chan, const struct zbus_observer *obs)
{
struct k_work_delayable *work = NULL;
int ret = zbus_chan_rm_obs(chan, obs, K_MSEC(100));
if (ret == 0 && sys_slist_is_empty(&chan->data->observers)) {
work = (struct k_work_delayable *)zbus_chan_user_data(chan);
__ASSERT(k_work_delayable_is_pending(work), "Periodic slow work is not pending");
ret = k_work_cancel_delayable(work);
}
return ret;
}
LOG_MODULE_REGISTER(zsw_periodic_event, LOG_LEVEL_INF);

static void handle_slow_timeout(struct k_work *item)
{
struct periodic_event evt = {
};
struct k_work_delayable *work = NULL;

zbus_chan_claim(&periodic_event_10s_chan, K_FOREVER);
work = (struct k_work_delayable *)zbus_chan_user_data(&periodic_event_10s_chan);
k_work_reschedule(work, K_MSEC(PERIODIC_SLOW_INTERVAL_MS));
Expand All @@ -76,34 +38,36 @@ static void handle_slow_timeout(struct k_work *item)
zbus_chan_pub(&periodic_event_10s_chan, &evt, K_MSEC(250));
}

//#if CONFIG_RTC
//void handle_mid_timeout(const struct device *dev, void *user_data)
//{
// struct periodic_event evt = {
// };
//
// zbus_chan_pub(&periodic_event_1s_chan, &evt, K_MSEC(250));
//}
//#else
#if CONFIG_RTC_UPDATE
static void handle_mid_timeout(const struct device *dev, void *user_data)
{
struct periodic_event evt = {
};

zbus_chan_pub(&periodic_event_1s_chan, &evt, K_MSEC(250));
}
#else
static void handle_mid_timeout(struct k_work *item)
{
struct periodic_event evt = {
};
struct k_work_delayable *work = NULL;

zbus_chan_claim(&periodic_event_1s_chan, K_FOREVER);
work = (struct k_work_delayable *)zbus_chan_user_data(&periodic_event_1s_chan);
k_work_reschedule(work, K_MSEC(PERIODIC_MID_INTERVAL_MS));
zbus_chan_finish(&periodic_event_1s_chan);

zbus_chan_pub(&periodic_event_1s_chan, &evt, K_MSEC(250));
}
//#endif
#endif

static void handle_fast_timeout(struct k_work *item)
{
struct periodic_event evt = {
};
struct k_work_delayable *work = NULL;

zbus_chan_claim(&periodic_event_100ms_chan, K_FOREVER);
work = (struct k_work_delayable *)zbus_chan_user_data(&periodic_event_100ms_chan);
k_work_reschedule(work, K_MSEC(PERIODIC_FAST_INTERVAL_MS));
Expand All @@ -112,23 +76,75 @@ static void handle_fast_timeout(struct k_work *item)
zbus_chan_pub(&periodic_event_100ms_chan, &evt, K_MSEC(250));
}

int zsw_periodic_chan_add_obs(const struct zbus_channel *chan, const struct zbus_observer *obs)
{
struct k_work_delayable *work = NULL;
int ret;

ret = zbus_chan_add_obs(chan, obs, K_MSEC(100));

if (ret != 0) {
return ret;
}

zbus_chan_claim(chan, K_FOREVER);
work = (struct k_work_delayable *)zbus_chan_user_data(chan);
__ASSERT(work != NULL, "Invalid channel");
if (!k_work_delayable_is_pending(work)) {
if (chan == &periodic_event_10s_chan) {
ret = k_work_reschedule(work, K_MSEC(PERIODIC_SLOW_INTERVAL_MS));
} else if (chan == &periodic_event_1s_chan) {
#ifdef CONFIG_RTC_UPDATE
rtc_update_set_callback(rtc, handle_mid_timeout, NULL);
#else
ret = k_work_reschedule(work, K_MSEC(PERIODIC_MID_INTERVAL_MS));
#endif
} else if (chan == &periodic_event_100ms_chan) {
ret = k_work_reschedule(work, K_MSEC(PERIODIC_FAST_INTERVAL_MS));
} else {
__ASSERT(false, "Unknown channel");
}
}
zbus_chan_finish(chan);

return ret;
}

int zsw_periodic_chan_rm_obs(const struct zbus_channel *chan, const struct zbus_observer *obs)
{
struct k_work_delayable *work = NULL;

int ret = zbus_chan_rm_obs(chan, obs, K_MSEC(100));
if (ret == 0 && sys_slist_is_empty(&chan->data->observers)) {
#if CONFIG_RTC_UPDATE
if (chan == &periodic_event_1s_chan) {
ret = rtc_update_set_callback(rtc, NULL, NULL);
} else
#endif
{
work = (struct k_work_delayable *)zbus_chan_user_data(chan);
__ASSERT(k_work_delayable_is_pending(work), "Periodic slow work is not pending");
ret = k_work_cancel_delayable(work);
}
}
return ret;
}

static int zsw_timer_init(void)
{
struct k_work_delayable *work = NULL;

work = (struct k_work_delayable *)zbus_chan_user_data(&periodic_event_10s_chan);
k_work_init_delayable(work, handle_slow_timeout);

//#if CONFIG_RTC
// if (!device_is_ready(rtc)) {
// return -EBUSY;
// }
//
// rtc_update_set_callback(rtc, handle_mid_timeout, NULL);
//#else
#if CONFIG_RTC_UPDATE
if (!device_is_ready(rtc)) {
return -EBUSY;
}
#else
work = (struct k_work_delayable *)zbus_chan_user_data(&periodic_event_1s_chan);
k_work_init_delayable(work, handle_mid_timeout);
//#endif
#endif

work = (struct k_work_delayable *)zbus_chan_user_data(&periodic_event_100ms_chan);
k_work_init_delayable(work, handle_fast_timeout);
Expand Down
10 changes: 5 additions & 5 deletions app/src/filesystem/zsw_filesystem.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@ static int lsdir(const char *path)
}

if (entry.type == FS_DIR_ENTRY_DIR) {
LOG_PRINTK("[DIR ] %s\n", entry.name);
LOG_DBG("[DIR ] %s\n", entry.name);
} else {
LOG_PRINTK("[FILE] %s (size = %zu)\n",
entry.name, entry.size);
LOG_DBG("[FILE] %s (size = %zu)\n",
entry.name, entry.size);
}
}

Expand All @@ -78,7 +78,7 @@ int zsw_filesystem_ls(void)

rc = fs_statvfs(mountpoint->mnt_point, &sbuf);
if (rc < 0) {
LOG_PRINTK("FAIL: statvfs: %d\n", rc);
LOG_ERR("FAIL: statvfs: %d\n", rc);
return -1;
}

Expand All @@ -90,7 +90,7 @@ int zsw_filesystem_ls(void)

rc = lsdir(mountpoint->mnt_point);
if (rc < 0) {
LOG_PRINTK("FAIL: lsdir %s: %d\n", mountpoint->mnt_point, rc);
LOG_ERR("FAIL: lsdir %s: %d\n", mountpoint->mnt_point, rc);
return -1;
}

Expand Down
Loading

0 comments on commit d1c2032

Please sign in to comment.