zephyr: drivers: rtc: nucleo_wb55rg: unable to setup RTC alarm callback after 1st exit from low-power mode
Describe the bug
I tried to implement Internal RTC using EVK ST Nucleo WB55RG, but always fail when set the RTC time with return error code -EIO.
This is my main code:
#include <zephyr/drivers/rtc.h>
#include <zephyr/sys/timeutil.h>
#include <zephyr/device.h>
static const struct device *rtcDev = DEVICE_DT_GET(DT_ALIAS(rtc));
int main(void)
{
struct rtc_time datetime_set;
time_t timer_set = (1707208172UL);
gmtime_r(&timer_set, (struct tm *)(&datetime_set));
printk("Time: %02d:%02d:%02d\n", datetime_set.tm_hour, datetime_set.tm_min, datetime_set.tm_sec);
printk("Date: %02d/%02d/%04d\n", datetime_set.tm_mday, datetime_set.tm_mon, datetime_set.tm_year);
int err = rtc_set_time(rtcDev, &datetime_set);
if(err == 0) {
printk("Success to set time\n");
} else {
printk("Fail to set time: %i\n", err);
}
struct rtc_time datetime_get;
err = rtc_get_time(rtcDev, &datetime_get);
if(err == 0) {
printk("Success to get time\n");
printk("%02d:%02d:%02d\n", datetime_get.tm_hour, datetime_get.tm_min, datetime_get.tm_sec);
printk("%02d/%02d/%04d\n", datetime_get.tm_mday, datetime_get.tm_mon, datetime_get.tm_year);
} else {
printk("Fail to get time: %i\n", err);
}
while (1) {
k_sleep(K_SECONDS(5));
}
return 0;
}
I create my own board with name stm32wb_sensor. Here is the dts file:
/ {
model = "STM32WB sensor board";
compatible = "st,stm32wb55rg-nucleo";
chosen {
zephyr,console = &usart1;
zephyr,shell-uart = &usart1;
zephyr,bt-mon-uart = &usart1;
zephyr,bt-c2h-uart = &usart1;
zephyr,sram = &sram0;
zephyr,flash = &flash0;
zephyr,code-partition = &slot0_partition;
};
aliases {
rtc = &rtc;
};
};
&rtc {
clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00000400>,
<&rcc STM32_SRC_LSI RTC_SEL(2)>;
status = "okay";
backup_regs {
status = "okay";
};
};
Here is the final RTC node on zephyr.dts file on build folder:
rtc: rtc@40002800 {
compatible = "st,stm32-rtc";
reg = < 0x40002800 0x400 >;
interrupts = < 0x29 0x0 >;
clocks = < &rcc 0x58 0x400 >, < &rcc 0x4 0x26890 >;
prescaler = < 0x8000 >;
status = "okay";
bbram: backup_regs {
compatible = "st,stm32-bbram";
st,backup-regs = < 0x14 >;
status = "okay";
};
};
Here is my prj.conf that related to RTC:
# RTC
CONFIG_RTC=y
My Observation
After digging down into the kernel driver, found out the -EIO is come from zephyr/drivers/rtc/rtc_ll_stm32.c on rtc_stm32_enter_initialization_mode function at line 87. I think LL_RTC_IsActiveFlag_INIT(RTC) never return true.
Aside from that, I found that rtc_stm32_init on the same file is never being called, even though it’s registered using macro DEVICE_DT_INST_DEFINE(0, &rtc_stm32_init, NULL, &rtc_data, &rtc_config, PRE_KERNEL_1, CONFIG_RTC_INIT_PRIORITY, &rtc_stm32_driver_api); I suppose rtc_stm32_init should be called at least once.
To Reproduce
Steps to reproduce the behavior:
- Create
docker_shell.sh
DOCKER_ARGS="--privileged \
--rm=true \
--user="$(id --user):$(id --group)" \
-e ZEPHYR_SDK_INSTALL_DIR=/opt/toolchains/zephyr-sdk-0.16.5 \
-e CCACHE_DIR=$(pwd)/.ccache \
-v $(pwd):$(pwd) \
-w $(pwd)"
DOCKER_IMAGE=zephyrprojectrtos/ci:v0.26.7
docker run $DOCKER_ARGS $DOCKER_IMAGE "$@"
./docker_shell.sh west build -b stm32wb_sensor --sysbuild <path_to_app>- See error (see below on logs)
Expected behavior
When calling rtc_set_time, I expect the return value to be 0, not -5 (EIO).
Impact It’s blocking my task.
Logs and console output
Time: 08:29:32
Date: 06/01/0124
Fail to set time: -5
Success to get time
00:00:01
01/00/0100
Environment (please complete the following information):
- OS: Host: Linux Ubuntu 18.04, Docker: zephyrprojectrtos/ci:v0.26.7
- Toolchain: Zephyr SDK v0.16.5
- Zephyr RTOS v3.5.0
I hope this information is complete enough to spark further idea. Any help or pointer to resolve the problem is pretty much appreciated. Thank you for your time and suggestion.
Krisna
About this issue
- Original URL
- State: closed
- Created 5 months ago
- Comments: 17 (8 by maintainers)
Commits related to this issue
- drivers: rtc: Fix RTC alarm when using both CONFIG_COUNTER and CONFIG_PM It is found that when we use CONFIG_COUNTER and CONFIG_PM concurrently, the RTC alarm callback can be used only once (in some ... — committed to krisnaresi/zephyr by krisnaresi 4 months ago
- drivers: rtc: Fix RTC alarm when using both CONFIG_COUNTER and CONFIG_PM It is found that when we use CONFIG_COUNTER and CONFIG_PM concurrently, the RTC alarm callback can be used only once (in some ... — committed to krisnaresi/zephyr by krisnaresi 4 months ago
- drivers: rtc: Fix RTC alarm when using both CONFIG_COUNTER and CONFIG_PM It is found that when we use CONFIG_COUNTER and CONFIG_PM concurrently, the RTC alarm callback can be used only once (in some ... — committed to krisnaresi/zephyr by krisnaresi 4 months ago
- drivers: rtc: Fix RTC alarm when using both CONFIG_COUNTER and CONFIG_PM It is found that when we use CONFIG_COUNTER and CONFIG_PM concurrently, the RTC alarm callback can be used only once (in some ... — committed to zephyrproject-rtos/zephyr by krisnaresi 4 months ago
- drivers: rtc: Fix RTC alarm when using both CONFIG_COUNTER and CONFIG_PM It is found that when we use CONFIG_COUNTER and CONFIG_PM concurrently, the RTC alarm callback can be used only once (in some ... — committed to ashiroji/zephyr by krisnaresi 4 months ago
- drivers: rtc: Fix RTC alarm when using both CONFIG_COUNTER and CONFIG_PM It is found that when we use CONFIG_COUNTER and CONFIG_PM concurrently, the RTC alarm callback can be used only once (in some ... — committed to comap-smart-home/zephyr by krisnaresi 4 months ago
Hi @ajarmouni-st, please find my PR on #70078. Any comment is welcome. Thanks.
I see, hopefully ST team can find generic solution in near future.
In my case, yes, the RTC callback can work accordingly with or without CONFIG_PM for Nucleo WB55RG. Sure, let me try to create PR for this one, will let you know once I create one.
Hi @ajarmouni-st, I look into this problem for several days, and found that
CONFIG_BT=yis irrelevant. Using yourprj.conf, I can only trigger callback one time. If you assign alarm after callback happen, it won’t work anymore.After do a lot of trial and error, I can resolve the problem by adding
LL_PWR_EnableBkUpAccesstortc_stm32_set_alarmfunction. I see that this function is to handleDBPbit onPWR control register 1:From the sentence above, I assume that every time CPU is going idle and power management goes suspend, RTC is goes to reset state, thus write protection is activated. By set the
DBPto disable write protection, we can once again register alarm callback. Here is the modified code forrtc_stm32_set_alarmfunction:Already test by enabling and disabling CONFIG_PM, it works properly. I’m not STM32 expert, so I’m open for any comment or discussion. Thanks.