cancel
Showing results for 
Search instead for 
Did you mean: 

BCD Calendar and Binary mode (mix mode) alarm is not working in STM32WL55

digidhamu
Associate III

Basically, my requirement is to run RTC to monitor actual date and time for various schedules to actuate the devices. Note that RTC configuration is provided via LoRaWAN downlink and timestamp after LoRaWAN join.

Hence, I would need mix mode to run both BCD calendar for clock and binary mode for LoRaWAN stack timer server.

However, I could not get alarm working with free running BCD calendar and binary mode (mix mode) in STM32WL55. But I could see working if I configure only free running BCD calendar or binary mode separately. Attached the configuration for the reference to advise.

Is there any example program on mix mode alarm operation?

1 ACCEPTED SOLUTION

Accepted Solutions
Ghofrane GSOURI
ST Employee

Hello @digidhamu​ 

First let me thank you for posting .

It sounds like you are trying to use a mix of BCD calendar mode and binary mode for the RTC in the STM32WL55 microcontroller, and you are having trouble getting the alarm to work in this configuration.

Mixing BCD calendar mode and binary mode can be a bit tricky, as they use different representations for time and date information. In BCD calendar mode, the time and date are stored in BCD format, which represents each digit of the time or date as a separate binary number. In binary mode, the time and date are stored as a single binary number, with the least significant digits representing the units and the most significant digits representing the higher-order values (e.g. seconds, minutes, hours, etc.).

To use both BCD calendar mode and binary mode together, you will need to ensure that you are correctly converting between the two formats when necessary. For example, if you are setting the alarm using binary mode, you will need to convert the binary representation of the alarm time to BCD format before writing it to the RTC registers. Similarly, if you are reading the current time from the RTC in BCD calendar mode, you will need to convert the BCD representation to binary mode before using it in your application.

Example To convert a binary representation of the time to BCD format, you can use a series of bit shifts and bit masks to extract the individual digits from the binary number and convert them to BCD. Here's an example of how this could be done in C:

// Convert a binary time value to BCD format
uint32_t binary_time = 0x123456;  // Binary time value to convert
uint32_t bcd_time = 0;  // BCD time value
 
// Extract each digit from the binary time value and convert it to BCD
bcd_time |= (((binary_time >> 20) & 0xF) << 20);
bcd_time |= (((binary_time >> 16) & 0xF) << 16);
bcd_time |= (((binary_time >> 12) & 0xF) << 12);
bcd_time |= (((binary_time >> 8) & 0xF) << 8);
bcd_time |= (((binary_time >> 4) & 0xF) << 4);
bcd_time |= ((binary_time & 0xF) << 0);
 
// bcd_time now contains the BCD representation of the binary time value

In this example, binary_time is the binary representation of the time, and bcd_time is the resulting BCD representation. The bit shifts and bit masks are used to extract each digit of the binary time value and convert it to BCD.

Once you have the BCD representation of the alarm time, you can write it to the appropriate RTC registers to set the alarm. For example, on the STM32WL55, you can use the

RTC_ALRMBR_DU and RTC_ALRMBR_DT registers to set the alarm date, and the RTC_ALRMAR_SU and RTC_ALRMAR_ST registers to set the alarm time. Consult the STM32WL55 RM for more information on how to use these registers.

To convert a BCD time value to a binary representation, you can use a similar process as the one described above, but in reverse. Here is an example of how this can be done in C

// Convert a BCD time value to binary
uint32_t bcd_time = 0x123456;  // BCD time value to convert
uint32_t binary_time = 0;  // Binary time value
 
// Extract each digit from the BCD time value and convert it to binary
binary_time |= ((bcd_time >> 20) & 0xF) * 100000;
binary_time |= ((bcd_time >> 16) & 0xF) * 10000;
binary_time |= ((bcd_time >> 12) & 0xF) * 1000;
binary_time |= ((bcd_time >> 8) & 0xF) * 100;
binary_time |= ((bcd_time >> 4) & 0xF) * 10;
binary_time |= (bcd_time & 0xF);
 
// binary_time now contains the binary representation of the BCD time value

This code uses bit shifts and bit masks to extract each digit of the BCD time value and convert it to binary. The resulting binary time value is stored in the binary_time variable. For example, if bcd_time is 0x12, 0x34, 0x56 (which represents the time 12:34:56 in BCD), the resulting binary_time value will be 0x123456 in binary format .

Thx

Ghofrane

View solution in original post

5 REPLIES 5
Ghofrane GSOURI
ST Employee

Hello @digidhamu​ 

First let me thank you for posting .

It sounds like you are trying to use a mix of BCD calendar mode and binary mode for the RTC in the STM32WL55 microcontroller, and you are having trouble getting the alarm to work in this configuration.

Mixing BCD calendar mode and binary mode can be a bit tricky, as they use different representations for time and date information. In BCD calendar mode, the time and date are stored in BCD format, which represents each digit of the time or date as a separate binary number. In binary mode, the time and date are stored as a single binary number, with the least significant digits representing the units and the most significant digits representing the higher-order values (e.g. seconds, minutes, hours, etc.).

To use both BCD calendar mode and binary mode together, you will need to ensure that you are correctly converting between the two formats when necessary. For example, if you are setting the alarm using binary mode, you will need to convert the binary representation of the alarm time to BCD format before writing it to the RTC registers. Similarly, if you are reading the current time from the RTC in BCD calendar mode, you will need to convert the BCD representation to binary mode before using it in your application.

Example To convert a binary representation of the time to BCD format, you can use a series of bit shifts and bit masks to extract the individual digits from the binary number and convert them to BCD. Here's an example of how this could be done in C:

// Convert a binary time value to BCD format
uint32_t binary_time = 0x123456;  // Binary time value to convert
uint32_t bcd_time = 0;  // BCD time value
 
// Extract each digit from the binary time value and convert it to BCD
bcd_time |= (((binary_time >> 20) & 0xF) << 20);
bcd_time |= (((binary_time >> 16) & 0xF) << 16);
bcd_time |= (((binary_time >> 12) & 0xF) << 12);
bcd_time |= (((binary_time >> 8) & 0xF) << 8);
bcd_time |= (((binary_time >> 4) & 0xF) << 4);
bcd_time |= ((binary_time & 0xF) << 0);
 
// bcd_time now contains the BCD representation of the binary time value

In this example, binary_time is the binary representation of the time, and bcd_time is the resulting BCD representation. The bit shifts and bit masks are used to extract each digit of the binary time value and convert it to BCD.

Once you have the BCD representation of the alarm time, you can write it to the appropriate RTC registers to set the alarm. For example, on the STM32WL55, you can use the

RTC_ALRMBR_DU and RTC_ALRMBR_DT registers to set the alarm date, and the RTC_ALRMAR_SU and RTC_ALRMAR_ST registers to set the alarm time. Consult the STM32WL55 RM for more information on how to use these registers.

To convert a BCD time value to a binary representation, you can use a similar process as the one described above, but in reverse. Here is an example of how this can be done in C

// Convert a BCD time value to binary
uint32_t bcd_time = 0x123456;  // BCD time value to convert
uint32_t binary_time = 0;  // Binary time value
 
// Extract each digit from the BCD time value and convert it to binary
binary_time |= ((bcd_time >> 20) & 0xF) * 100000;
binary_time |= ((bcd_time >> 16) & 0xF) * 10000;
binary_time |= ((bcd_time >> 12) & 0xF) * 1000;
binary_time |= ((bcd_time >> 8) & 0xF) * 100;
binary_time |= ((bcd_time >> 4) & 0xF) * 10;
binary_time |= (bcd_time & 0xF);
 
// binary_time now contains the binary representation of the BCD time value

This code uses bit shifts and bit masks to extract each digit of the BCD time value and convert it to binary. The resulting binary time value is stored in the binary_time variable. For example, if bcd_time is 0x12, 0x34, 0x56 (which represents the time 12:34:56 in BCD), the resulting binary_time value will be 0x123456 in binary format .

Thx

Ghofrane

Great @Ghofrane GSOURI​ and thanks for this. Let me try this soon

Tried the same. Thanks for your support

Hello @Ghofrane GSOURI ,

I'm having the same problem as the one in question. My application runs in Binary mode and I need to have BCD mode because of the calendar. 

When I try to use mixed mode, my application seems to not run at all, and I think it is because of the alarm as suggested.

While I was looking through the "stm32wlxx_hal_rtc.c" library it seems that when it runs in mixed mode the code already make this conversion, but I'm not sure.

Anyway, if it doesn't convert itself, I had a doubt about where exaclty in the code I should apply your example, can you explain a little more?

Thanks in advance!

Roro1990
Associate II

Hi, 

I have a similar problem with LoraEndNode example, i changed RTC to Free running BCD and binary mode but when device try to connect to lorawan, it was halt in "MAC txDone".

Which RTC configuration did you use to avoid this problem? 

 

My RTC is configured as follow( i tried with several values for

hrtc.Init.AsynchPrediv and hrtc.Init.SynchPrediv but it is not working)

:

#define RTC_N_PREDIV_S 10

#define RTC_PREDIV_S ((1<<RTC_N_PREDIV_S)-1)

#define RTC_PREDIV_A ((1<<(15-RTC_N_PREDIV_S))-1)

 

hrtc.Instance = RTC;

hrtc.Init.HourFormat = RTC_HOURFORMAT_24;

hrtc.Init.AsynchPrediv = RTC_PREDIV_A;

hrtc.Init.SynchPrediv = RTC_PREDIV_S;

hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;

hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;

hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;

hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;

hrtc.Init.OutPutPullUp = RTC_OUTPUT_PULLUP_NONE;

hrtc.Init.BinMode = RTC_BINARY_MIX;

hrtc.Init.BinMixBcdU = RTC_BINARY_MIX_BCDU_0;